Milestone 5: deliver embedded RDP sessions and lifecycle hardening
This commit is contained in:
34
third_party/FreeRDP/libfreerdp/gdi/CMakeLists.txt
vendored
Normal file
34
third_party/FreeRDP/libfreerdp/gdi/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Implementation
|
||||
# libfreerdp-gdi cmake build script
|
||||
#
|
||||
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set(MODULE_NAME "freerdp-gdi")
|
||||
set(MODULE_PREFIX "FREERDP_GDI")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
option(WITH_GFX_FRAME_DUMP "Dump GFX commands to directory" OFF)
|
||||
if(WITH_GFX_FRAME_DUMP)
|
||||
freerdp_definition_add(WITH_GFX_FRAME_DUMP)
|
||||
endif()
|
||||
|
||||
file(GLOB ${MODULE_PREFIX}_SRCS LIST_DIRECTORIES false RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} CONFIGURE_DEPENDS "*.[ch]")
|
||||
|
||||
freerdp_module_add(${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
if(BUILD_TESTING_INTERNAL)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
675
third_party/FreeRDP/libfreerdp/gdi/bitmap.c
vendored
Normal file
675
third_party/FreeRDP/libfreerdp/gdi/bitmap.c
vendored
Normal file
@@ -0,0 +1,675 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Bitmap Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/codec/color.h>
|
||||
|
||||
#include <freerdp/gdi/region.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
#include <freerdp/log.h>
|
||||
#include <freerdp/gdi/shape.h>
|
||||
|
||||
#include "brush.h"
|
||||
#include "clipping.h"
|
||||
#include "../gdi/gdi.h"
|
||||
|
||||
#define TAG FREERDP_TAG("gdi.bitmap")
|
||||
|
||||
/**
|
||||
* Get pixel at the given coordinates. msdn{dd144909}
|
||||
* @param hdc device context
|
||||
* @param nXPos pixel x position
|
||||
* @param nYPos pixel y position
|
||||
* @return pixel color
|
||||
*/
|
||||
|
||||
UINT32 gdi_GetPixel(HGDI_DC hdc, UINT32 nXPos, UINT32 nYPos)
|
||||
{
|
||||
HGDI_BITMAP hBmp = (HGDI_BITMAP)hdc->selectedObject;
|
||||
BYTE* data =
|
||||
&(hBmp->data[(nYPos * hBmp->scanline) + nXPos * FreeRDPGetBytesPerPixel(hBmp->format)]);
|
||||
return FreeRDPReadColor(data, hBmp->format);
|
||||
}
|
||||
|
||||
BYTE* gdi_GetPointer(HGDI_BITMAP hBmp, UINT32 X, UINT32 Y)
|
||||
{
|
||||
UINT32 bpp = FreeRDPGetBytesPerPixel(hBmp->format);
|
||||
return &hBmp->data[(Y * WINPR_ASSERTING_INT_CAST(uint32_t, hBmp->width) * bpp) + X * bpp];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set pixel at the given coordinates. msdn{dd145078}
|
||||
*
|
||||
* @param hBmp device context
|
||||
* @param X pixel x position
|
||||
* @param Y pixel y position
|
||||
* @param crColor new pixel color
|
||||
* @return the color written
|
||||
*/
|
||||
|
||||
static inline UINT32 gdi_SetPixelBmp(HGDI_BITMAP hBmp, UINT32 X, UINT32 Y, UINT32 crColor)
|
||||
{
|
||||
BYTE* p = &hBmp->data[(Y * hBmp->scanline) + X * FreeRDPGetBytesPerPixel(hBmp->format)];
|
||||
FreeRDPWriteColor(p, hBmp->format, crColor);
|
||||
return crColor;
|
||||
}
|
||||
|
||||
UINT32 gdi_SetPixel(HGDI_DC hdc, UINT32 X, UINT32 Y, UINT32 crColor)
|
||||
{
|
||||
HGDI_BITMAP hBmp = (HGDI_BITMAP)hdc->selectedObject;
|
||||
return gdi_SetPixelBmp(hBmp, X, Y, crColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new bitmap with the given width, height, color format and pixel buffer. msdn{dd183485}
|
||||
*
|
||||
* @param nWidth width
|
||||
* @param nHeight height
|
||||
* @param format the color format used
|
||||
* @param data pixel buffer
|
||||
* @return new bitmap
|
||||
*/
|
||||
|
||||
HGDI_BITMAP gdi_CreateBitmap(UINT32 nWidth, UINT32 nHeight, UINT32 format, BYTE* data)
|
||||
{
|
||||
return gdi_CreateBitmapEx(nWidth, nHeight, format, 0, data, winpr_aligned_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new bitmap with the given width, height, color format and pixel buffer. msdn{dd183485}
|
||||
*
|
||||
* @param nWidth width
|
||||
* @param nHeight height
|
||||
* @param format the color format used
|
||||
* @param data pixel buffer
|
||||
* @param fkt_free The function used for deallocation of the buffer, nullptr for none.
|
||||
* @return new bitmap
|
||||
*/
|
||||
|
||||
HGDI_BITMAP gdi_CreateBitmapEx(UINT32 nWidth, UINT32 nHeight, UINT32 format, UINT32 stride,
|
||||
BYTE* data, void (*fkt_free)(void*))
|
||||
{
|
||||
HGDI_BITMAP hBitmap = (HGDI_BITMAP)calloc(1, sizeof(GDI_BITMAP));
|
||||
|
||||
if (!hBitmap)
|
||||
return nullptr;
|
||||
|
||||
hBitmap->objectType = GDIOBJECT_BITMAP;
|
||||
hBitmap->format = format;
|
||||
|
||||
if (stride > 0)
|
||||
hBitmap->scanline = stride;
|
||||
else
|
||||
hBitmap->scanline = nWidth * FreeRDPGetBytesPerPixel(hBitmap->format);
|
||||
|
||||
hBitmap->width = WINPR_ASSERTING_INT_CAST(int, nWidth);
|
||||
hBitmap->height = WINPR_ASSERTING_INT_CAST(int, nHeight);
|
||||
hBitmap->data = data;
|
||||
hBitmap->free = fkt_free;
|
||||
return hBitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new bitmap of the given width and height compatible with the current device context.
|
||||
* msdn{dd183488}
|
||||
*
|
||||
* @param hdc device context
|
||||
* @param nWidth width
|
||||
* @param nHeight height
|
||||
*
|
||||
* @return new bitmap
|
||||
*/
|
||||
|
||||
HGDI_BITMAP gdi_CreateCompatibleBitmap(HGDI_DC hdc, UINT32 nWidth, UINT32 nHeight)
|
||||
{
|
||||
HGDI_BITMAP hBitmap = (HGDI_BITMAP)calloc(1, sizeof(GDI_BITMAP));
|
||||
|
||||
if (!hBitmap)
|
||||
return nullptr;
|
||||
|
||||
hBitmap->objectType = GDIOBJECT_BITMAP;
|
||||
hBitmap->format = hdc->format;
|
||||
WINPR_ASSERT(nWidth <= INT32_MAX);
|
||||
hBitmap->width = (INT32)nWidth;
|
||||
|
||||
WINPR_ASSERT(nHeight <= INT32_MAX);
|
||||
hBitmap->height = (INT32)nHeight;
|
||||
|
||||
size_t size = 1ull * nWidth * nHeight * FreeRDPGetBytesPerPixel(hBitmap->format);
|
||||
hBitmap->data = winpr_aligned_malloc(size, 16);
|
||||
hBitmap->free = winpr_aligned_free;
|
||||
|
||||
if (!hBitmap->data)
|
||||
{
|
||||
free(hBitmap);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Initialize with 0xff */
|
||||
memset(hBitmap->data, 0xff, size);
|
||||
hBitmap->scanline = nWidth * FreeRDPGetBytesPerPixel(hBitmap->format);
|
||||
return hBitmap;
|
||||
}
|
||||
|
||||
static BOOL op_not(UINT32* stack, const UINT32* stackp)
|
||||
{
|
||||
if (!stack || !stackp)
|
||||
return FALSE;
|
||||
|
||||
if (*stackp < 1)
|
||||
return FALSE;
|
||||
|
||||
stack[(*stackp) - 1] = ~stack[(*stackp) - 1];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL op_and(UINT32* stack, UINT32* stackp)
|
||||
{
|
||||
if (!stack || !stackp)
|
||||
return FALSE;
|
||||
|
||||
if (*stackp < 2)
|
||||
return FALSE;
|
||||
|
||||
(*stackp)--;
|
||||
stack[(*stackp) - 1] &= stack[(*stackp)];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL op_or(UINT32* stack, UINT32* stackp)
|
||||
{
|
||||
if (!stack || !stackp)
|
||||
return FALSE;
|
||||
|
||||
if (*stackp < 2)
|
||||
return FALSE;
|
||||
|
||||
(*stackp)--;
|
||||
stack[(*stackp) - 1] |= stack[(*stackp)];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL op_xor(UINT32* stack, UINT32* stackp)
|
||||
{
|
||||
if (!stack || !stackp)
|
||||
return FALSE;
|
||||
|
||||
if (*stackp < 2)
|
||||
return FALSE;
|
||||
|
||||
(*stackp)--;
|
||||
stack[(*stackp) - 1] ^= stack[(*stackp)];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static UINT32 process_rop(UINT32 src, UINT32 dst, UINT32 pat, const char* rop, UINT32 format)
|
||||
{
|
||||
UINT32 stack[10] = WINPR_C_ARRAY_INIT;
|
||||
UINT32 stackp = 0;
|
||||
|
||||
while (*rop != '\0')
|
||||
{
|
||||
char op = *rop++;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case '0':
|
||||
stack[stackp++] = FreeRDPGetColor(format, 0, 0, 0, 0xFF);
|
||||
break;
|
||||
|
||||
case '1':
|
||||
stack[stackp++] = FreeRDPGetColor(format, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
stack[stackp++] = dst;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
stack[stackp++] = src;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
stack[stackp++] = pat;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
op_xor(stack, &stackp);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
op_and(stack, &stackp);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
op_or(stack, &stackp);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
op_not(stack, &stackp);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return stack[0];
|
||||
}
|
||||
|
||||
static inline BOOL BitBlt_write(HGDI_DC hdcDest, HGDI_DC hdcSrc, INT32 nXDest, INT32 nYDest,
|
||||
INT32 nXSrc, INT32 nYSrc, INT32 x, INT32 y, BOOL useSrc,
|
||||
BOOL usePat, UINT32 style, const char* rop,
|
||||
const gdiPalette* palette)
|
||||
{
|
||||
UINT32 dstColor = 0;
|
||||
UINT32 colorA = 0;
|
||||
UINT32 colorB = 0;
|
||||
UINT32 colorC = 0;
|
||||
const INT32 dstX = nXDest + x;
|
||||
const INT32 dstY = nYDest + y;
|
||||
BYTE* dstp = gdi_get_bitmap_pointer(hdcDest, dstX, dstY);
|
||||
|
||||
if (!dstp)
|
||||
{
|
||||
WLog_ERR(TAG, "dstp=%p", (const void*)dstp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
colorA = FreeRDPReadColor(dstp, hdcDest->format);
|
||||
|
||||
if (useSrc)
|
||||
{
|
||||
const BYTE* srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc + x, nYSrc + y);
|
||||
|
||||
if (!srcp)
|
||||
{
|
||||
WLog_ERR(TAG, "srcp=%p", (const void*)srcp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
colorC = FreeRDPReadColor(srcp, hdcSrc->format);
|
||||
colorC = FreeRDPConvertColor(colorC, hdcSrc->format, hdcDest->format, palette);
|
||||
}
|
||||
|
||||
if (usePat)
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
case GDI_BS_SOLID:
|
||||
colorB = hdcDest->brush->color;
|
||||
break;
|
||||
|
||||
case GDI_BS_HATCHED:
|
||||
case GDI_BS_PATTERN:
|
||||
{
|
||||
const BYTE* patp =
|
||||
gdi_get_brush_pointer(hdcDest, WINPR_ASSERTING_INT_CAST(uint32_t, nXDest + x),
|
||||
WINPR_ASSERTING_INT_CAST(uint32_t, nYDest + y));
|
||||
|
||||
if (!patp)
|
||||
{
|
||||
WLog_ERR(TAG, "patp=%p", (const void*)patp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
colorB = FreeRDPReadColor(patp, hdcDest->format);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dstColor = process_rop(colorC, colorA, colorB, rop, hdcDest->format);
|
||||
return FreeRDPWriteColor(dstp, hdcDest->format, dstColor);
|
||||
}
|
||||
|
||||
static BOOL adjust_src_coordinates(HGDI_DC hdcSrc, INT32 nWidth, INT32 nHeight, INT32* px,
|
||||
INT32* py)
|
||||
{
|
||||
HGDI_BITMAP hSrcBmp = nullptr;
|
||||
INT32 nXSrc = 0;
|
||||
INT32 nYSrc = 0;
|
||||
|
||||
if (!hdcSrc || (nWidth < 0) || (nHeight < 0) || !px || !py)
|
||||
return FALSE;
|
||||
|
||||
hSrcBmp = (HGDI_BITMAP)hdcSrc->selectedObject;
|
||||
nXSrc = *px;
|
||||
nYSrc = *py;
|
||||
|
||||
if (!hSrcBmp)
|
||||
return FALSE;
|
||||
|
||||
if (nYSrc < 0)
|
||||
{
|
||||
nYSrc = 0;
|
||||
nHeight = nHeight + nYSrc;
|
||||
}
|
||||
|
||||
if ((nXSrc) < 0)
|
||||
{
|
||||
nXSrc = 0;
|
||||
nWidth = nWidth + nXSrc;
|
||||
}
|
||||
|
||||
if (hSrcBmp->width < (nXSrc + nWidth))
|
||||
nXSrc = hSrcBmp->width - nWidth;
|
||||
|
||||
if (hSrcBmp->height < (nYSrc + nHeight))
|
||||
nYSrc = hSrcBmp->height - nHeight;
|
||||
|
||||
if ((nXSrc < 0) || (nYSrc < 0))
|
||||
return FALSE;
|
||||
|
||||
*px = nXSrc;
|
||||
*py = nYSrc;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL adjust_src_dst_coordinates(HGDI_DC hdcDest, INT32* pnXSrc, INT32* pnYSrc, INT32* pnXDst,
|
||||
INT32* pnYDst, INT32* pnWidth, INT32* pnHeight)
|
||||
{
|
||||
HGDI_BITMAP hDstBmp = nullptr;
|
||||
volatile INT32 diffX = 0;
|
||||
volatile INT32 diffY = 0;
|
||||
volatile INT32 nXSrc = 0;
|
||||
volatile INT32 nYSrc = 0;
|
||||
volatile INT32 nXDst = 0;
|
||||
volatile INT32 nYDst = 0;
|
||||
volatile INT32 nWidth = 0;
|
||||
volatile INT32 nHeight = 0;
|
||||
|
||||
if (!hdcDest || !pnXSrc || !pnYSrc || !pnXDst || !pnYDst || !pnWidth || !pnHeight)
|
||||
return FALSE;
|
||||
|
||||
hDstBmp = (HGDI_BITMAP)hdcDest->selectedObject;
|
||||
nXSrc = *pnXSrc;
|
||||
nYSrc = *pnYSrc;
|
||||
nXDst = *pnXDst;
|
||||
nYDst = *pnYDst;
|
||||
nWidth = *pnWidth;
|
||||
nHeight = *pnHeight;
|
||||
|
||||
if (!hDstBmp)
|
||||
return FALSE;
|
||||
|
||||
if (nXDst < 0)
|
||||
{
|
||||
nXSrc -= nXDst;
|
||||
nWidth += nXDst;
|
||||
nXDst = 0;
|
||||
}
|
||||
|
||||
if (nYDst < 0)
|
||||
{
|
||||
nYSrc -= nYDst;
|
||||
nHeight += nYDst;
|
||||
nYDst = 0;
|
||||
}
|
||||
|
||||
diffX = hDstBmp->width - nXDst - nWidth;
|
||||
|
||||
if (diffX < 0)
|
||||
nWidth += diffX;
|
||||
|
||||
diffY = hDstBmp->height - nYDst - nHeight;
|
||||
|
||||
if (diffY < 0)
|
||||
nHeight += diffY;
|
||||
|
||||
if ((nXDst < 0) || (nYDst < 0) || (nWidth < 0) || (nHeight < 0))
|
||||
{
|
||||
nXDst = 0;
|
||||
nYDst = 0;
|
||||
nWidth = 0;
|
||||
nHeight = 0;
|
||||
}
|
||||
|
||||
*pnXSrc = nXSrc;
|
||||
*pnYSrc = nYSrc;
|
||||
*pnXDst = nXDst;
|
||||
*pnYDst = nYDst;
|
||||
*pnWidth = nWidth;
|
||||
*pnHeight = nHeight;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL BitBlt_process(HGDI_DC hdcDest, INT32 nXDest, INT32 nYDest, INT32 nWidth, INT32 nHeight,
|
||||
HGDI_DC hdcSrc, INT32 nXSrc, INT32 nYSrc, const char* rop,
|
||||
const gdiPalette* palette)
|
||||
{
|
||||
UINT32 style = 0;
|
||||
BOOL useSrc = FALSE;
|
||||
BOOL usePat = FALSE;
|
||||
const char* iter = rop;
|
||||
|
||||
while (*iter != '\0')
|
||||
{
|
||||
switch (*iter++)
|
||||
{
|
||||
case 'P':
|
||||
usePat = TRUE;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
useSrc = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hdcDest)
|
||||
return FALSE;
|
||||
|
||||
if (!adjust_src_dst_coordinates(hdcDest, &nXSrc, &nYSrc, &nXDest, &nYDest, &nWidth, &nHeight))
|
||||
return FALSE;
|
||||
|
||||
if (useSrc && !hdcSrc)
|
||||
return FALSE;
|
||||
|
||||
if (useSrc)
|
||||
{
|
||||
if (!adjust_src_coordinates(hdcSrc, nWidth, nHeight, &nXSrc, &nYSrc))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (usePat)
|
||||
{
|
||||
style = gdi_GetBrushStyle(hdcDest);
|
||||
|
||||
switch (style)
|
||||
{
|
||||
case GDI_BS_SOLID:
|
||||
case GDI_BS_HATCHED:
|
||||
case GDI_BS_PATTERN:
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "Invalid brush!!");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((nXDest > nXSrc) && (nYDest > nYSrc))
|
||||
{
|
||||
for (INT32 y = nHeight - 1; y >= 0; y--)
|
||||
{
|
||||
for (INT32 x = nWidth - 1; x >= 0; x--)
|
||||
{
|
||||
if (!BitBlt_write(hdcDest, hdcSrc, nXDest, nYDest, nXSrc, nYSrc, x, y, useSrc,
|
||||
usePat, style, rop, palette))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nXDest > nXSrc)
|
||||
{
|
||||
for (INT32 y = 0; y < nHeight; y++)
|
||||
{
|
||||
for (INT32 x = nWidth - 1; x >= 0; x--)
|
||||
{
|
||||
if (!BitBlt_write(hdcDest, hdcSrc, nXDest, nYDest, nXSrc, nYSrc, x, y, useSrc,
|
||||
usePat, style, rop, palette))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nYDest > nYSrc)
|
||||
{
|
||||
for (INT32 y = nHeight - 1; y >= 0; y--)
|
||||
{
|
||||
for (INT32 x = 0; x < nWidth; x++)
|
||||
{
|
||||
if (!BitBlt_write(hdcDest, hdcSrc, nXDest, nYDest, nXSrc, nYSrc, x, y, useSrc,
|
||||
usePat, style, rop, palette))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (INT32 y = 0; y < nHeight; y++)
|
||||
{
|
||||
for (INT32 x = 0; x < nWidth; x++)
|
||||
{
|
||||
if (!BitBlt_write(hdcDest, hdcSrc, nXDest, nYDest, nXSrc, nYSrc, x, y, useSrc,
|
||||
usePat, style, rop, palette))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a bit blit operation on the given pixel buffers.
|
||||
* msdn{dd183370}
|
||||
*
|
||||
* @param hdcDest destination device context
|
||||
* @param nXDest destination x1
|
||||
* @param nYDest destination y1
|
||||
* @param nWidth width
|
||||
* @param nHeight height
|
||||
* @param hdcSrc source device context
|
||||
* @param nXSrc source x1
|
||||
* @param nYSrc source y1
|
||||
* @param rop raster operation code
|
||||
* @return 0 on failure, non-zero otherwise
|
||||
*/
|
||||
BOOL gdi_BitBlt(HGDI_DC hdcDest, INT32 nXDest, INT32 nYDest, INT32 nWidth, INT32 nHeight,
|
||||
HGDI_DC hdcSrc, INT32 nXSrc, INT32 nYSrc, DWORD rop, const gdiPalette* palette)
|
||||
{
|
||||
HGDI_BITMAP hSrcBmp = nullptr;
|
||||
HGDI_BITMAP hDstBmp = nullptr;
|
||||
|
||||
if (!hdcDest)
|
||||
return FALSE;
|
||||
|
||||
if (!gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, &nXSrc, &nYSrc))
|
||||
return TRUE;
|
||||
|
||||
/* Check which ROP should be performed.
|
||||
* Some specific ROP are used heavily and are resource intensive,
|
||||
* add optimized versions for these here.
|
||||
*
|
||||
* For all others fall back to the generic implementation.
|
||||
*/
|
||||
switch (rop)
|
||||
{
|
||||
case GDI_SRCCOPY:
|
||||
if (!hdcSrc)
|
||||
return FALSE;
|
||||
|
||||
if (!adjust_src_dst_coordinates(hdcDest, &nXSrc, &nYSrc, &nXDest, &nYDest, &nWidth,
|
||||
&nHeight))
|
||||
return FALSE;
|
||||
|
||||
if (!adjust_src_coordinates(hdcSrc, nWidth, nHeight, &nXSrc, &nYSrc))
|
||||
return FALSE;
|
||||
|
||||
hSrcBmp = (HGDI_BITMAP)hdcSrc->selectedObject;
|
||||
hDstBmp = (HGDI_BITMAP)hdcDest->selectedObject;
|
||||
|
||||
if (!hSrcBmp || !hDstBmp)
|
||||
return FALSE;
|
||||
|
||||
if (!freerdp_image_copy(
|
||||
hDstBmp->data, hDstBmp->format, hDstBmp->scanline,
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, nXDest),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, nYDest),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, nWidth),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, nHeight), hSrcBmp->data, hSrcBmp->format,
|
||||
hSrcBmp->scanline, WINPR_ASSERTING_INT_CAST(UINT32, nXSrc),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, nYSrc), palette, FREERDP_FLIP_NONE))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case GDI_DSTCOPY:
|
||||
hSrcBmp = (HGDI_BITMAP)hdcDest->selectedObject;
|
||||
hDstBmp = (HGDI_BITMAP)hdcDest->selectedObject;
|
||||
|
||||
if (!adjust_src_dst_coordinates(hdcDest, &nXSrc, &nYSrc, &nXDest, &nYDest, &nWidth,
|
||||
&nHeight))
|
||||
return FALSE;
|
||||
|
||||
if (!adjust_src_coordinates(hdcDest, nWidth, nHeight, &nXSrc, &nYSrc))
|
||||
return FALSE;
|
||||
|
||||
if (!hSrcBmp || !hDstBmp)
|
||||
return FALSE;
|
||||
|
||||
if (!freerdp_image_copy(
|
||||
hDstBmp->data, hDstBmp->format, hDstBmp->scanline,
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, nXDest),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, nYDest),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, nWidth),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, nHeight), hSrcBmp->data, hSrcBmp->format,
|
||||
hSrcBmp->scanline, WINPR_ASSERTING_INT_CAST(UINT32, nXSrc),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, nYSrc), palette, FREERDP_FLIP_NONE))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!BitBlt_process(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc,
|
||||
gdi_rop_to_string(rop), palette))
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight);
|
||||
}
|
||||
867
third_party/FreeRDP/libfreerdp/gdi/brush.c
vendored
Normal file
867
third_party/FreeRDP/libfreerdp/gdi/brush.c
vendored
Normal file
@@ -0,0 +1,867 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Brush Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* GDI Brush Functions: http://msdn.microsoft.com/en-us/library/dd183395/ */
|
||||
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
#include <freerdp/log.h>
|
||||
|
||||
#include "brush.h"
|
||||
#include "clipping.h"
|
||||
|
||||
const char* gdi_rop_to_string(UINT32 code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case GDI_BLACKNESS:
|
||||
return "0";
|
||||
|
||||
case GDI_DPSoon:
|
||||
return "DPSoon";
|
||||
|
||||
case GDI_DPSona:
|
||||
return "DPSona";
|
||||
|
||||
case GDI_PSon:
|
||||
return "PSon";
|
||||
|
||||
case GDI_SDPona:
|
||||
return "SDPona";
|
||||
|
||||
case GDI_DPon:
|
||||
return "DPon";
|
||||
|
||||
case GDI_PDSxnon:
|
||||
return "PDSxnon";
|
||||
|
||||
case GDI_PDSaon:
|
||||
return "PDSaon";
|
||||
|
||||
case GDI_SDPnaa:
|
||||
return "SDPnaa";
|
||||
|
||||
case GDI_PDSxon:
|
||||
return "PDSxon";
|
||||
|
||||
case GDI_DPna:
|
||||
return "DPna";
|
||||
|
||||
case GDI_PSDnaon:
|
||||
return "PSDnaon";
|
||||
|
||||
case GDI_SPna:
|
||||
return "SPna";
|
||||
|
||||
case GDI_PDSnaon:
|
||||
return "PDSnaon";
|
||||
|
||||
case GDI_PDSonon:
|
||||
return "PDSonon";
|
||||
|
||||
case GDI_Pn:
|
||||
return "Pn";
|
||||
|
||||
case GDI_PDSona:
|
||||
return "PDSona";
|
||||
|
||||
case GDI_NOTSRCERASE:
|
||||
return "DSon";
|
||||
|
||||
case GDI_SDPxnon:
|
||||
return "SDPxnon";
|
||||
|
||||
case GDI_SDPaon:
|
||||
return "SDPaon";
|
||||
|
||||
case GDI_DPSxnon:
|
||||
return "DPSxnon";
|
||||
|
||||
case GDI_DPSaon:
|
||||
return "DPSaon";
|
||||
|
||||
case GDI_PSDPSanaxx:
|
||||
return "PSDPSanaxx";
|
||||
|
||||
case GDI_SSPxDSxaxn:
|
||||
return "SSPxDSxaxn";
|
||||
|
||||
case GDI_SPxPDxa:
|
||||
return "SPxPDxa";
|
||||
|
||||
case GDI_SDPSanaxn:
|
||||
return "SDPSanaxn";
|
||||
|
||||
case GDI_PDSPaox:
|
||||
return "PDSPaox";
|
||||
|
||||
case GDI_SDPSxaxn:
|
||||
return "SDPSxaxn";
|
||||
|
||||
case GDI_PSDPaox:
|
||||
return "PSDPaox";
|
||||
|
||||
case GDI_DSPDxaxn:
|
||||
return "DSPDxaxn";
|
||||
|
||||
case GDI_PDSox:
|
||||
return "PDSox";
|
||||
|
||||
case GDI_PDSoan:
|
||||
return "PDSoan";
|
||||
|
||||
case GDI_DPSnaa:
|
||||
return "DPSnaa";
|
||||
|
||||
case GDI_SDPxon:
|
||||
return "SDPxon";
|
||||
|
||||
case GDI_DSna:
|
||||
return "DSna";
|
||||
|
||||
case GDI_SPDnaon:
|
||||
return "SPDnaon";
|
||||
|
||||
case GDI_SPxDSxa:
|
||||
return "SPxDSxa";
|
||||
|
||||
case GDI_PDSPanaxn:
|
||||
return "PDSPanaxn";
|
||||
|
||||
case GDI_SDPSaox:
|
||||
return "SDPSaox";
|
||||
|
||||
case GDI_SDPSxnox:
|
||||
return "SDPSxnox";
|
||||
|
||||
case GDI_DPSxa:
|
||||
return "DPSxa";
|
||||
|
||||
case GDI_PSDPSaoxxn:
|
||||
return "PSDPSaoxxn";
|
||||
|
||||
case GDI_DPSana:
|
||||
return "DPSana";
|
||||
|
||||
case GDI_SSPxPDxaxn:
|
||||
return "SSPxPDxaxn";
|
||||
|
||||
case GDI_SPDSoax:
|
||||
return "SPDSoax";
|
||||
|
||||
case GDI_PSDnox:
|
||||
return "PSDnox";
|
||||
|
||||
case GDI_PSDPxox:
|
||||
return "PSDPxox";
|
||||
|
||||
case GDI_PSDnoan:
|
||||
return "PSDnoan";
|
||||
|
||||
case GDI_PSna:
|
||||
return "PSna";
|
||||
|
||||
case GDI_SDPnaon:
|
||||
return "SDPnaon";
|
||||
|
||||
case GDI_SDPSoox:
|
||||
return "SDPSoox";
|
||||
|
||||
case GDI_NOTSRCCOPY:
|
||||
return "Sn";
|
||||
|
||||
case GDI_SPDSaox:
|
||||
return "SPDSaox";
|
||||
|
||||
case GDI_SPDSxnox:
|
||||
return "SPDSxnox";
|
||||
|
||||
case GDI_SDPox:
|
||||
return "SDPox";
|
||||
|
||||
case GDI_SDPoan:
|
||||
return "SDPoan";
|
||||
|
||||
case GDI_PSDPoax:
|
||||
return "PSDPoax";
|
||||
|
||||
case GDI_SPDnox:
|
||||
return "SPDnox";
|
||||
|
||||
case GDI_SPDSxox:
|
||||
return "SPDSxox";
|
||||
|
||||
case GDI_SPDnoan:
|
||||
return "SPDnoan";
|
||||
|
||||
case GDI_PSx:
|
||||
return "PSx";
|
||||
|
||||
case GDI_SPDSonox:
|
||||
return "SPDSonox";
|
||||
|
||||
case GDI_SPDSnaox:
|
||||
return "SPDSnaox";
|
||||
|
||||
case GDI_PSan:
|
||||
return "PSan";
|
||||
|
||||
case GDI_PSDnaa:
|
||||
return "PSDnaa";
|
||||
|
||||
case GDI_DPSxon:
|
||||
return "DPSxon";
|
||||
|
||||
case GDI_SDxPDxa:
|
||||
return "SDxPDxa";
|
||||
|
||||
case GDI_SPDSanaxn:
|
||||
return "SPDSanaxn";
|
||||
|
||||
case GDI_SRCERASE:
|
||||
return "SDna";
|
||||
|
||||
case GDI_DPSnaon:
|
||||
return "DPSnaon";
|
||||
|
||||
case GDI_DSPDaox:
|
||||
return "DSPDaox";
|
||||
|
||||
case GDI_PSDPxaxn:
|
||||
return "PSDPxaxn";
|
||||
|
||||
case GDI_SDPxa:
|
||||
return "SDPxa";
|
||||
|
||||
case GDI_PDSPDaoxxn:
|
||||
return "PDSPDaoxxn";
|
||||
|
||||
case GDI_DPSDoax:
|
||||
return "DPSDoax";
|
||||
|
||||
case GDI_PDSnox:
|
||||
return "PDSnox";
|
||||
|
||||
case GDI_SDPana:
|
||||
return "SDPana";
|
||||
|
||||
case GDI_SSPxDSxoxn:
|
||||
return "SSPxDSxoxn";
|
||||
|
||||
case GDI_PDSPxox:
|
||||
return "PDSPxox";
|
||||
|
||||
case GDI_PDSnoan:
|
||||
return "PDSnoan";
|
||||
|
||||
case GDI_PDna:
|
||||
return "PDna";
|
||||
|
||||
case GDI_DSPnaon:
|
||||
return "DSPnaon";
|
||||
|
||||
case GDI_DPSDaox:
|
||||
return "DPSDaox";
|
||||
|
||||
case GDI_SPDSxaxn:
|
||||
return "SPDSxaxn";
|
||||
|
||||
case GDI_DPSonon:
|
||||
return "DPSonon";
|
||||
|
||||
case GDI_DSTINVERT:
|
||||
return "Dn";
|
||||
|
||||
case GDI_DPSox:
|
||||
return "DPSox";
|
||||
|
||||
case GDI_DPSoan:
|
||||
return "DPSoan";
|
||||
|
||||
case GDI_PDSPoax:
|
||||
return "PDSPoax";
|
||||
|
||||
case GDI_DPSnox:
|
||||
return "DPSnox";
|
||||
|
||||
case GDI_PATINVERT:
|
||||
return "DPx";
|
||||
|
||||
case GDI_DPSDonox:
|
||||
return "DPSDonox";
|
||||
|
||||
case GDI_DPSDxox:
|
||||
return "DPSDxox";
|
||||
|
||||
case GDI_DPSnoan:
|
||||
return "DPSnoan";
|
||||
|
||||
case GDI_DPSDnaox:
|
||||
return "DPSDnaox";
|
||||
|
||||
case GDI_DPan:
|
||||
return "DPan";
|
||||
|
||||
case GDI_PDSxa:
|
||||
return "PDSxa";
|
||||
|
||||
case GDI_DSPDSaoxxn:
|
||||
return "DSPDSaoxxn";
|
||||
|
||||
case GDI_DSPDoax:
|
||||
return "DSPDoax";
|
||||
|
||||
case GDI_SDPnox:
|
||||
return "SDPnox";
|
||||
|
||||
case GDI_SDPSoax:
|
||||
return "SDPSoax";
|
||||
|
||||
case GDI_DSPnox:
|
||||
return "DSPnox";
|
||||
|
||||
case GDI_SRCINVERT:
|
||||
return "DSx";
|
||||
|
||||
case GDI_SDPSonox:
|
||||
return "SDPSonox";
|
||||
|
||||
case GDI_DSPDSonoxxn:
|
||||
return "DSPDSonoxxn";
|
||||
|
||||
case GDI_PDSxxn:
|
||||
return "PDSxxn";
|
||||
|
||||
case GDI_DPSax:
|
||||
return "DPSax";
|
||||
|
||||
case GDI_PSDPSoaxxn:
|
||||
return "PSDPSoaxxn";
|
||||
|
||||
case GDI_SDPax:
|
||||
return "SDPax";
|
||||
|
||||
case GDI_PDSPDoaxxn:
|
||||
return "PDSPDoaxxn";
|
||||
|
||||
case GDI_SDPSnoax:
|
||||
return "SDPSnoax";
|
||||
|
||||
case GDI_PDSxnan:
|
||||
return "PDSxnan";
|
||||
|
||||
case GDI_PDSana:
|
||||
return "PDSana";
|
||||
|
||||
case GDI_SSDxPDxaxn:
|
||||
return "SSDxPDxaxn";
|
||||
|
||||
case GDI_SDPSxox:
|
||||
return "SDPSxox";
|
||||
|
||||
case GDI_SDPnoan:
|
||||
return "SDPnoan";
|
||||
|
||||
case GDI_DSPDxox:
|
||||
return "DSPDxox";
|
||||
|
||||
case GDI_DSPnoan:
|
||||
return "DSPnoan";
|
||||
|
||||
case GDI_SDPSnaox:
|
||||
return "SDPSnaox";
|
||||
|
||||
case GDI_DSan:
|
||||
return "DSan";
|
||||
|
||||
case GDI_PDSax:
|
||||
return "PDSax";
|
||||
|
||||
case GDI_DSPDSoaxxn:
|
||||
return "DSPDSoaxxn";
|
||||
|
||||
case GDI_DPSDnoax:
|
||||
return "DPSDnoax";
|
||||
|
||||
case GDI_SDPxnan:
|
||||
return "SDPxnan";
|
||||
|
||||
case GDI_SPDSnoax:
|
||||
return "SPDSnoax";
|
||||
|
||||
case GDI_DPSxnan:
|
||||
return "DPSxnan";
|
||||
|
||||
case GDI_SPxDSxo:
|
||||
return "SPxDSxo";
|
||||
|
||||
case GDI_DPSaan:
|
||||
return "DPSaan";
|
||||
|
||||
case GDI_DPSaa:
|
||||
return "DPSaa";
|
||||
|
||||
case GDI_SPxDSxon:
|
||||
return "SPxDSxon";
|
||||
|
||||
case GDI_DPSxna:
|
||||
return "DPSxna";
|
||||
|
||||
case GDI_SPDSnoaxn:
|
||||
return "SPDSnoaxn";
|
||||
|
||||
case GDI_SDPxna:
|
||||
return "SDPxna";
|
||||
|
||||
case GDI_PDSPnoaxn:
|
||||
return "PDSPnoaxn";
|
||||
|
||||
case GDI_DSPDSoaxx:
|
||||
return "DSPDSoaxx";
|
||||
|
||||
case GDI_PDSaxn:
|
||||
return "PDSaxn";
|
||||
|
||||
case GDI_SRCAND:
|
||||
return "DSa";
|
||||
|
||||
case GDI_SDPSnaoxn:
|
||||
return "SDPSnaoxn";
|
||||
|
||||
case GDI_DSPnoa:
|
||||
return "DSPnoa";
|
||||
|
||||
case GDI_DSPDxoxn:
|
||||
return "DSPDxoxn";
|
||||
|
||||
case GDI_SDPnoa:
|
||||
return "SDPnoa";
|
||||
|
||||
case GDI_SDPSxoxn:
|
||||
return "SDPSxoxn";
|
||||
|
||||
case GDI_SSDxPDxax:
|
||||
return "SSDxPDxax";
|
||||
|
||||
case GDI_PDSanan:
|
||||
return "PDSanan";
|
||||
|
||||
case GDI_PDSxna:
|
||||
return "PDSxna";
|
||||
|
||||
case GDI_SDPSnoaxn:
|
||||
return "SDPSnoaxn";
|
||||
|
||||
case GDI_DPSDPoaxx:
|
||||
return "DPSDPoaxx";
|
||||
|
||||
case GDI_SPDaxn:
|
||||
return "SPDaxn";
|
||||
|
||||
case GDI_PSDPSoaxx:
|
||||
return "PSDPSoaxx";
|
||||
|
||||
case GDI_DPSaxn:
|
||||
return "DPSaxn";
|
||||
|
||||
case GDI_DPSxx:
|
||||
return "DPSxx";
|
||||
|
||||
case GDI_PSDPSonoxx:
|
||||
return "PSDPSonoxx";
|
||||
|
||||
case GDI_SDPSonoxn:
|
||||
return "SDPSonoxn";
|
||||
|
||||
case GDI_DSxn:
|
||||
return "DSxn";
|
||||
|
||||
case GDI_DPSnax:
|
||||
return "DPSnax";
|
||||
|
||||
case GDI_SDPSoaxn:
|
||||
return "SDPSoaxn";
|
||||
|
||||
case GDI_SPDnax:
|
||||
return "SPDnax";
|
||||
|
||||
case GDI_DSPDoaxn:
|
||||
return "DSPDoaxn";
|
||||
|
||||
case GDI_DSPDSaoxx:
|
||||
return "DSPDSaoxx";
|
||||
|
||||
case GDI_PDSxan:
|
||||
return "PDSxan";
|
||||
|
||||
case GDI_DPa:
|
||||
return "DPa";
|
||||
|
||||
case GDI_PDSPnaoxn:
|
||||
return "PDSPnaoxn";
|
||||
|
||||
case GDI_DPSnoa:
|
||||
return "DPSnoa";
|
||||
|
||||
case GDI_DPSDxoxn:
|
||||
return "DPSDxoxn";
|
||||
|
||||
case GDI_PDSPonoxn:
|
||||
return "PDSPonoxn";
|
||||
|
||||
case GDI_PDxn:
|
||||
return "PDxn";
|
||||
|
||||
case GDI_DSPnax:
|
||||
return "DSPnax";
|
||||
|
||||
case GDI_PDSPoaxn:
|
||||
return "PDSPoaxn";
|
||||
|
||||
case GDI_DPSoa:
|
||||
return "DPSoa";
|
||||
|
||||
case GDI_DPSoxn:
|
||||
return "DPSoxn";
|
||||
|
||||
case GDI_DSTCOPY:
|
||||
return "D";
|
||||
|
||||
case GDI_DPSono:
|
||||
return "DPSono";
|
||||
|
||||
case GDI_SPDSxax:
|
||||
return "SPDSxax";
|
||||
|
||||
case GDI_DPSDaoxn:
|
||||
return "DPSDaoxn";
|
||||
|
||||
case GDI_DSPnao:
|
||||
return "DSPnao";
|
||||
|
||||
case GDI_DPno:
|
||||
return "DPno";
|
||||
|
||||
case GDI_PDSnoa:
|
||||
return "PDSnoa";
|
||||
|
||||
case GDI_PDSPxoxn:
|
||||
return "PDSPxoxn";
|
||||
|
||||
case GDI_SSPxDSxox:
|
||||
return "SSPxDSxox";
|
||||
|
||||
case GDI_SDPanan:
|
||||
return "SDPanan";
|
||||
|
||||
case GDI_PSDnax:
|
||||
return "PSDnax";
|
||||
|
||||
case GDI_DPSDoaxn:
|
||||
return "DPSDoaxn";
|
||||
|
||||
case GDI_DPSDPaoxx:
|
||||
return "DPSDPaoxx";
|
||||
|
||||
case GDI_SDPxan:
|
||||
return "SDPxan";
|
||||
|
||||
case GDI_PSDPxax:
|
||||
return "PSDPxax";
|
||||
|
||||
case GDI_DSPDaoxn:
|
||||
return "DSPDaoxn";
|
||||
|
||||
case GDI_DPSnao:
|
||||
return "DPSnao";
|
||||
|
||||
case GDI_MERGEPAINT:
|
||||
return "DSno";
|
||||
|
||||
case GDI_SPDSanax:
|
||||
return "SPDSanax";
|
||||
|
||||
case GDI_SDxPDxan:
|
||||
return "SDxPDxan";
|
||||
|
||||
case GDI_DPSxo:
|
||||
return "DPSxo";
|
||||
|
||||
case GDI_DPSano:
|
||||
return "DPSano";
|
||||
|
||||
case GDI_MERGECOPY:
|
||||
return "PSa";
|
||||
|
||||
case GDI_SPDSnaoxn:
|
||||
return "SPDSnaoxn";
|
||||
|
||||
case GDI_SPDSonoxn:
|
||||
return "SPDSonoxn";
|
||||
|
||||
case GDI_PSxn:
|
||||
return "PSxn";
|
||||
|
||||
case GDI_SPDnoa:
|
||||
return "SPDnoa";
|
||||
|
||||
case GDI_SPDSxoxn:
|
||||
return "SPDSxoxn";
|
||||
|
||||
case GDI_SDPnax:
|
||||
return "SDPnax";
|
||||
|
||||
case GDI_PSDPoaxn:
|
||||
return "PSDPoaxn";
|
||||
|
||||
case GDI_SDPoa:
|
||||
return "SDPoa";
|
||||
|
||||
case GDI_SPDoxn:
|
||||
return "SPDoxn";
|
||||
|
||||
case GDI_DPSDxax:
|
||||
return "DPSDxax";
|
||||
|
||||
case GDI_SPDSaoxn:
|
||||
return "SPDSaoxn";
|
||||
|
||||
case GDI_SRCCOPY:
|
||||
return "S";
|
||||
|
||||
case GDI_SDPono:
|
||||
return "SDPono";
|
||||
|
||||
case GDI_SDPnao:
|
||||
return "SDPnao";
|
||||
|
||||
case GDI_SPno:
|
||||
return "SPno";
|
||||
|
||||
case GDI_PSDnoa:
|
||||
return "PSDnoa";
|
||||
|
||||
case GDI_PSDPxoxn:
|
||||
return "PSDPxoxn";
|
||||
|
||||
case GDI_PDSnax:
|
||||
return "PDSnax";
|
||||
|
||||
case GDI_SPDSoaxn:
|
||||
return "SPDSoaxn";
|
||||
|
||||
case GDI_SSPxPDxax:
|
||||
return "SSPxPDxax";
|
||||
|
||||
case GDI_DPSanan:
|
||||
return "DPSanan";
|
||||
|
||||
case GDI_PSDPSaoxx:
|
||||
return "PSDPSaoxx";
|
||||
|
||||
case GDI_DPSxan:
|
||||
return "DPSxan";
|
||||
|
||||
case GDI_PDSPxax:
|
||||
return "PDSPxax";
|
||||
|
||||
case GDI_SDPSaoxn:
|
||||
return "SDPSaoxn";
|
||||
|
||||
case GDI_DPSDanax:
|
||||
return "DPSDanax";
|
||||
|
||||
case GDI_SPxDSxan:
|
||||
return "SPxDSxan";
|
||||
|
||||
case GDI_SPDnao:
|
||||
return "SPDnao";
|
||||
|
||||
case GDI_SDno:
|
||||
return "SDno";
|
||||
|
||||
case GDI_SDPxo:
|
||||
return "SDPxo";
|
||||
|
||||
case GDI_SDPano:
|
||||
return "SDPano";
|
||||
|
||||
case GDI_PDSoa:
|
||||
return "PDSoa";
|
||||
|
||||
case GDI_PDSoxn:
|
||||
return "PDSoxn";
|
||||
|
||||
case GDI_DSPDxax:
|
||||
return "DSPDxax";
|
||||
|
||||
case GDI_PSDPaoxn:
|
||||
return "PSDPaoxn";
|
||||
|
||||
case GDI_SDPSxax:
|
||||
return "SDPSxax";
|
||||
|
||||
case GDI_PDSPaoxn:
|
||||
return "PDSPaoxn";
|
||||
|
||||
case GDI_SDPSanax:
|
||||
return "SDPSanax";
|
||||
|
||||
case GDI_SPxPDxan:
|
||||
return "SPxPDxan";
|
||||
|
||||
case GDI_SSPxDSxax:
|
||||
return "SSPxDSxax";
|
||||
|
||||
case GDI_DSPDSanaxxn:
|
||||
return "DSPDSanaxxn";
|
||||
|
||||
case GDI_DPSao:
|
||||
return "DPSao";
|
||||
|
||||
case GDI_DPSxno:
|
||||
return "DPSxno";
|
||||
|
||||
case GDI_SDPao:
|
||||
return "SDPao";
|
||||
|
||||
case GDI_SDPxno:
|
||||
return "SDPxno";
|
||||
|
||||
case GDI_SRCPAINT:
|
||||
return "DSo";
|
||||
|
||||
case GDI_SDPnoo:
|
||||
return "SDPnoo";
|
||||
|
||||
case GDI_PATCOPY:
|
||||
return "P";
|
||||
|
||||
case GDI_PDSono:
|
||||
return "PDSono";
|
||||
|
||||
case GDI_PDSnao:
|
||||
return "PDSnao";
|
||||
|
||||
case GDI_PSno:
|
||||
return "PSno";
|
||||
|
||||
case GDI_PSDnao:
|
||||
return "PSDnao";
|
||||
|
||||
case GDI_PDno:
|
||||
return "PDno";
|
||||
|
||||
case GDI_PDSxo:
|
||||
return "PDSxo";
|
||||
|
||||
case GDI_PDSano:
|
||||
return "PDSano";
|
||||
|
||||
case GDI_PDSao:
|
||||
return "PDSao";
|
||||
|
||||
case GDI_PDSxno:
|
||||
return "PDSxno";
|
||||
|
||||
case GDI_DPo:
|
||||
return "DPo";
|
||||
|
||||
case GDI_PATPAINT:
|
||||
return "DPSnoo";
|
||||
|
||||
case GDI_PSo:
|
||||
return "PSo";
|
||||
|
||||
case GDI_PSDnoo:
|
||||
return "PSDnoo";
|
||||
|
||||
case GDI_DPSoo:
|
||||
return "DPSoo";
|
||||
|
||||
case GDI_WHITENESS:
|
||||
return "1";
|
||||
|
||||
case GDI_GLYPH_ORDER:
|
||||
return "SPaDSnao";
|
||||
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a new solid brush.
|
||||
* msdn{dd183518}
|
||||
*
|
||||
* @param crColor brush color
|
||||
* @return new brush
|
||||
*/
|
||||
HGDI_BRUSH gdi_CreateSolidBrush(UINT32 crColor)
|
||||
{
|
||||
HGDI_BRUSH hBrush = (HGDI_BRUSH)calloc(1, sizeof(GDI_BRUSH));
|
||||
|
||||
if (!hBrush)
|
||||
return nullptr;
|
||||
|
||||
hBrush->objectType = GDIOBJECT_BRUSH;
|
||||
hBrush->style = GDI_BS_SOLID;
|
||||
hBrush->color = crColor;
|
||||
return hBrush;
|
||||
}
|
||||
/**
|
||||
* @brief Create a new pattern brush.
|
||||
* msdn{dd183508}
|
||||
*
|
||||
* @param hbmp pattern bitmap
|
||||
* @return new brush
|
||||
*/
|
||||
HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp)
|
||||
{
|
||||
HGDI_BRUSH hBrush = (HGDI_BRUSH)calloc(1, sizeof(GDI_BRUSH));
|
||||
|
||||
if (!hBrush)
|
||||
return nullptr;
|
||||
|
||||
hBrush->objectType = GDIOBJECT_BRUSH;
|
||||
hBrush->style = GDI_BS_PATTERN;
|
||||
hBrush->pattern = hbmp;
|
||||
return hBrush;
|
||||
}
|
||||
|
||||
HGDI_BRUSH gdi_CreateHatchBrush(HGDI_BITMAP hbmp)
|
||||
{
|
||||
HGDI_BRUSH hBrush = (HGDI_BRUSH)calloc(1, sizeof(GDI_BRUSH));
|
||||
|
||||
if (!hBrush)
|
||||
return nullptr;
|
||||
|
||||
hBrush->objectType = GDIOBJECT_BRUSH;
|
||||
hBrush->style = GDI_BS_HATCHED;
|
||||
hBrush->pattern = hbmp;
|
||||
return hBrush;
|
||||
}
|
||||
60
third_party/FreeRDP/libfreerdp/gdi/brush.h
vendored
Normal file
60
third_party/FreeRDP/libfreerdp/gdi/brush.h
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Brush Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LIB_GDI_BRUSH_H
|
||||
#define FREERDP_LIB_GDI_BRUSH_H
|
||||
|
||||
#include <winpr/cast.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL const char* gdi_rop_to_string(UINT32 code);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL HGDI_BRUSH gdi_CreateSolidBrush(UINT32 crColor);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL HGDI_BRUSH gdi_CreateHatchBrush(HGDI_BITMAP hbmp);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
static inline UINT32 gdi_GetBrushStyle(HGDI_DC hdc)
|
||||
{
|
||||
if (!hdc || !hdc->brush)
|
||||
return GDI_BS_NULL;
|
||||
|
||||
return WINPR_ASSERTING_INT_CAST(UINT32, hdc->brush->style);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FREERDP_LIB_GDI_BRUSH_H */
|
||||
170
third_party/FreeRDP/libfreerdp/gdi/clipping.c
vendored
Normal file
170
third_party/FreeRDP/libfreerdp/gdi/clipping.c
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Clipping Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/region.h>
|
||||
|
||||
#include "clipping.h"
|
||||
|
||||
BOOL gdi_SetClipRgn(HGDI_DC hdc, INT32 nXLeft, INT32 nYLeft, INT32 nWidth, INT32 nHeight)
|
||||
{
|
||||
return gdi_SetRgn(hdc->clip, nXLeft, nYLeft, nWidth, nHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current clipping region.
|
||||
* msdn{dd144866}
|
||||
*
|
||||
* @param hdc device context
|
||||
* @return clipping region
|
||||
*/
|
||||
|
||||
GDI_RGN* gdi_GetClipRgn(HGDI_DC hdc)
|
||||
{
|
||||
return hdc->clip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current clipping region to null.
|
||||
* @param hdc device context
|
||||
* @return nonzero on success, 0 otherwise
|
||||
*/
|
||||
|
||||
BOOL gdi_SetNullClipRgn(HGDI_DC hdc)
|
||||
{
|
||||
if (!gdi_SetClipRgn(hdc, 0, 0, 0, 0))
|
||||
return FALSE;
|
||||
hdc->clip->null = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clip coordinates according to clipping region
|
||||
* @param hdc device context
|
||||
* @param x x1
|
||||
* @param y y1
|
||||
* @param w width
|
||||
* @param h height
|
||||
* @param srcx source x1
|
||||
* @param srcy source y1
|
||||
* @return nonzero if there is something to draw, 0 otherwise
|
||||
*/
|
||||
|
||||
BOOL gdi_ClipCoords(HGDI_DC hdc, INT32* x, INT32* y, INT32* w, INT32* h, INT32* srcx, INT32* srcy)
|
||||
{
|
||||
GDI_RECT bmp = WINPR_C_ARRAY_INIT;
|
||||
GDI_RECT clip = WINPR_C_ARRAY_INIT;
|
||||
GDI_RECT coords = WINPR_C_ARRAY_INIT;
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
BOOL draw = TRUE;
|
||||
|
||||
if (hdc == nullptr)
|
||||
return FALSE;
|
||||
|
||||
HGDI_BITMAP hBmp = (HGDI_BITMAP)hdc->selectedObject;
|
||||
|
||||
if (hBmp != nullptr)
|
||||
{
|
||||
if (hdc->clip->null)
|
||||
{
|
||||
if (!gdi_CRgnToRect(0, 0, hBmp->width, hBmp->height, &clip))
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!gdi_RgnToRect(hdc->clip, &clip))
|
||||
return TRUE;
|
||||
if (!gdi_CRgnToRect(0, 0, hBmp->width, hBmp->height, &bmp))
|
||||
return TRUE;
|
||||
|
||||
if (clip.left < bmp.left)
|
||||
clip.left = bmp.left;
|
||||
|
||||
if (clip.right > bmp.right)
|
||||
clip.right = bmp.right;
|
||||
|
||||
if (clip.top < bmp.top)
|
||||
clip.top = bmp.top;
|
||||
|
||||
if (clip.bottom > bmp.bottom)
|
||||
clip.bottom = bmp.bottom;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!gdi_RgnToRect(hdc->clip, &clip))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!gdi_CRgnToRect(*x, *y, *w, *h, &coords))
|
||||
return TRUE;
|
||||
|
||||
if (coords.right >= clip.left && coords.left <= clip.right && coords.bottom >= clip.top &&
|
||||
coords.top <= clip.bottom)
|
||||
{
|
||||
/* coordinates overlap with clipping region */
|
||||
if (coords.left < clip.left)
|
||||
{
|
||||
dx = (clip.left - coords.left);
|
||||
coords.left = clip.left;
|
||||
}
|
||||
|
||||
if (coords.right > clip.right)
|
||||
coords.right = clip.right;
|
||||
|
||||
if (coords.top < clip.top)
|
||||
{
|
||||
dy = (clip.top - coords.top);
|
||||
coords.top = clip.top;
|
||||
}
|
||||
|
||||
if (coords.bottom > clip.bottom)
|
||||
coords.bottom = clip.bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* coordinates do not overlap with clipping region */
|
||||
coords.left = 0;
|
||||
coords.right = 0;
|
||||
coords.top = 0;
|
||||
coords.bottom = 0;
|
||||
draw = FALSE;
|
||||
}
|
||||
|
||||
if (srcx != nullptr)
|
||||
*srcx += dx;
|
||||
|
||||
if (srcy != nullptr)
|
||||
*srcy += dy;
|
||||
|
||||
if (!gdi_RectToCRgn(&coords, x, y, w, h))
|
||||
return FALSE;
|
||||
return draw;
|
||||
}
|
||||
51
third_party/FreeRDP/libfreerdp/gdi/clipping.h
vendored
Normal file
51
third_party/FreeRDP/libfreerdp/gdi/clipping.h
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Clipping Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LIB_GDI_CLIPPING_H
|
||||
#define FREERDP_LIB_GDI_CLIPPING_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL BOOL gdi_SetClipRgn(HGDI_DC hdc, INT32 nXLeft, INT32 nYLeft, INT32 nWidth,
|
||||
INT32 nHeight);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL GDI_RGN* gdi_GetClipRgn(HGDI_DC hdc);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL BOOL gdi_SetNullClipRgn(HGDI_DC hdc);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL BOOL gdi_ClipCoords(HGDI_DC hdc, INT32* x, INT32* y, INT32* w, INT32* h,
|
||||
INT32* srcx, INT32* srcy);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FREERDP_LIB_GDI_CLIPPING_H */
|
||||
258
third_party/FreeRDP/libfreerdp/gdi/dc.c
vendored
Normal file
258
third_party/FreeRDP/libfreerdp/gdi/dc.c
vendored
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Device Context Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* Device Context Functions: http://msdn.microsoft.com/en-us/library/dd183554 */
|
||||
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/region.h>
|
||||
|
||||
#include <freerdp/gdi/dc.h>
|
||||
|
||||
/**
|
||||
* @brief Get the current device context (a new one is created each time).
|
||||
* msdn{dd144871}
|
||||
*
|
||||
* @return current device context
|
||||
*/
|
||||
|
||||
HGDI_DC gdi_GetDC(void)
|
||||
{
|
||||
HGDI_DC hDC = (HGDI_DC)calloc(1, sizeof(GDI_DC));
|
||||
|
||||
if (!hDC)
|
||||
return nullptr;
|
||||
|
||||
hDC->format = PIXEL_FORMAT_XRGB32;
|
||||
hDC->drawMode = GDI_R2_BLACK;
|
||||
hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0);
|
||||
|
||||
if (!hDC->clip)
|
||||
{
|
||||
free(hDC);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hDC->clip->null = TRUE;
|
||||
hDC->hwnd = nullptr;
|
||||
return hDC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a device context.
|
||||
* msdn{dd144871}
|
||||
*
|
||||
* @return new device context
|
||||
*/
|
||||
|
||||
HGDI_DC gdi_CreateDC(UINT32 format)
|
||||
{
|
||||
HGDI_DC hDC = nullptr;
|
||||
|
||||
if (!(hDC = (HGDI_DC)calloc(1, sizeof(GDI_DC))))
|
||||
return nullptr;
|
||||
|
||||
hDC->drawMode = GDI_R2_BLACK;
|
||||
|
||||
if (!(hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0)))
|
||||
goto fail;
|
||||
|
||||
hDC->clip->null = TRUE;
|
||||
hDC->hwnd = nullptr;
|
||||
hDC->format = format;
|
||||
|
||||
if (!(hDC->hwnd = (HGDI_WND)calloc(1, sizeof(GDI_WND))))
|
||||
goto fail;
|
||||
|
||||
if (!(hDC->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0)))
|
||||
goto fail;
|
||||
|
||||
hDC->hwnd->invalid->null = TRUE;
|
||||
hDC->hwnd->count = 32;
|
||||
|
||||
if (!(hDC->hwnd->cinvalid = (GDI_RGN*)calloc(hDC->hwnd->count, sizeof(GDI_RGN))))
|
||||
goto fail;
|
||||
|
||||
hDC->hwnd->ninvalid = 0;
|
||||
return hDC;
|
||||
fail:
|
||||
gdi_DeleteDC(hDC);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a new device context compatible with the given device context.
|
||||
* msdn{dd183489}
|
||||
* @param hdc device context
|
||||
* @return new compatible device context
|
||||
*/
|
||||
|
||||
HGDI_DC gdi_CreateCompatibleDC(HGDI_DC hdc)
|
||||
{
|
||||
HGDI_DC hDC = (HGDI_DC)calloc(1, sizeof(GDI_DC));
|
||||
|
||||
if (!hDC)
|
||||
return nullptr;
|
||||
|
||||
if (!(hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0)))
|
||||
{
|
||||
free(hDC);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hDC->clip->null = TRUE;
|
||||
hDC->format = hdc->format;
|
||||
hDC->drawMode = hdc->drawMode;
|
||||
hDC->hwnd = nullptr;
|
||||
return hDC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select a GDI object in the current device context.
|
||||
* msdn{dd162957}
|
||||
*
|
||||
* @param hdc device context
|
||||
* @param hgdiobject new selected GDI object
|
||||
* @return previous selected GDI object
|
||||
*/
|
||||
|
||||
HGDIOBJECT gdi_SelectObject(HGDI_DC hdc, HGDIOBJECT hgdiobject)
|
||||
{
|
||||
HGDIOBJECT previousSelectedObject = hdc->selectedObject;
|
||||
|
||||
if (hgdiobject == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (hgdiobject->objectType == GDIOBJECT_BITMAP)
|
||||
{
|
||||
hdc->selectedObject = hgdiobject;
|
||||
}
|
||||
else if (hgdiobject->objectType == GDIOBJECT_PEN)
|
||||
{
|
||||
previousSelectedObject = (HGDIOBJECT)hdc->pen;
|
||||
hdc->pen = (HGDI_PEN)hgdiobject;
|
||||
}
|
||||
else if (hgdiobject->objectType == GDIOBJECT_BRUSH)
|
||||
{
|
||||
previousSelectedObject = (HGDIOBJECT)hdc->brush;
|
||||
hdc->brush = (HGDI_BRUSH)hgdiobject;
|
||||
}
|
||||
else if (hgdiobject->objectType == GDIOBJECT_REGION)
|
||||
{
|
||||
hdc->selectedObject = hgdiobject;
|
||||
previousSelectedObject = (HGDIOBJECT)COMPLEXREGION;
|
||||
}
|
||||
else if (hgdiobject->objectType == GDIOBJECT_RECT)
|
||||
{
|
||||
hdc->selectedObject = hgdiobject;
|
||||
previousSelectedObject = (HGDIOBJECT)SIMPLEREGION;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unknown GDI Object Type */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return previousSelectedObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete a GDI object.
|
||||
* msdn{dd183539}
|
||||
* @param hgdiobject GDI object
|
||||
* @return nonzero if successful, 0 otherwise
|
||||
*/
|
||||
|
||||
BOOL gdi_DeleteObject(HGDIOBJECT hgdiobject)
|
||||
{
|
||||
if (!hgdiobject)
|
||||
return FALSE;
|
||||
|
||||
if (hgdiobject->objectType == GDIOBJECT_BITMAP)
|
||||
{
|
||||
HGDI_BITMAP hBitmap = (HGDI_BITMAP)hgdiobject;
|
||||
|
||||
if (hBitmap->data && hBitmap->free)
|
||||
{
|
||||
hBitmap->free(hBitmap->data);
|
||||
hBitmap->data = nullptr;
|
||||
}
|
||||
|
||||
free(hBitmap);
|
||||
}
|
||||
else if (hgdiobject->objectType == GDIOBJECT_PEN)
|
||||
{
|
||||
HGDI_PEN hPen = (HGDI_PEN)hgdiobject;
|
||||
free(hPen);
|
||||
}
|
||||
else if (hgdiobject->objectType == GDIOBJECT_BRUSH)
|
||||
{
|
||||
HGDI_BRUSH hBrush = (HGDI_BRUSH)hgdiobject;
|
||||
free(hBrush);
|
||||
}
|
||||
else if (hgdiobject->objectType == GDIOBJECT_REGION)
|
||||
{
|
||||
free(hgdiobject);
|
||||
}
|
||||
else if (hgdiobject->objectType == GDIOBJECT_RECT)
|
||||
{
|
||||
free(hgdiobject);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unknown GDI Object Type */
|
||||
free(hgdiobject);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete device context.
|
||||
* msdn{dd183533}
|
||||
* @param hdc device context
|
||||
* @return nonzero if successful, 0 otherwise
|
||||
*/
|
||||
|
||||
BOOL gdi_DeleteDC(HGDI_DC hdc)
|
||||
{
|
||||
if (hdc)
|
||||
{
|
||||
if (hdc->hwnd)
|
||||
{
|
||||
free(hdc->hwnd->cinvalid);
|
||||
free(hdc->hwnd->invalid);
|
||||
free(hdc->hwnd);
|
||||
}
|
||||
|
||||
free(hdc->clip);
|
||||
free(hdc);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
151
third_party/FreeRDP/libfreerdp/gdi/drawing.c
vendored
Normal file
151
third_party/FreeRDP/libfreerdp/gdi/drawing.c
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Drawing Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* GDI Drawing Functions: http://msdn.microsoft.com/en-us/library/dd162760/ */
|
||||
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/dc.h>
|
||||
#include "drawing.h"
|
||||
|
||||
/**
|
||||
* @brief Set current foreground draw mode.
|
||||
* msdn{dd144922}
|
||||
*
|
||||
* @param hdc device context
|
||||
*
|
||||
* @return draw mode
|
||||
*/
|
||||
|
||||
INT32 gdi_GetROP2(HGDI_DC hdc)
|
||||
{
|
||||
return hdc->drawMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set current foreground draw mode.
|
||||
* msdn{dd145088}
|
||||
*
|
||||
* @param hdc device context
|
||||
* @param fnDrawMode draw mode
|
||||
*
|
||||
* @return previous draw mode
|
||||
*/
|
||||
|
||||
INT32 gdi_SetROP2(HGDI_DC hdc, INT32 fnDrawMode)
|
||||
{
|
||||
INT32 prevDrawMode = hdc->drawMode;
|
||||
|
||||
if (fnDrawMode > 0 && fnDrawMode <= 16)
|
||||
hdc->drawMode = fnDrawMode;
|
||||
|
||||
return prevDrawMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current background color.
|
||||
* msdn{dd144852}
|
||||
*
|
||||
* @param hdc device context
|
||||
*
|
||||
* @return background color
|
||||
*/
|
||||
|
||||
UINT32 gdi_GetBkColor(HGDI_DC hdc)
|
||||
{
|
||||
return hdc->bkColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the current background color.
|
||||
* msdn{dd162964}
|
||||
*
|
||||
* @param hdc device color
|
||||
* @param crColor new background color
|
||||
*
|
||||
* @return previous background color
|
||||
*/
|
||||
|
||||
UINT32 gdi_SetBkColor(HGDI_DC hdc, UINT32 crColor)
|
||||
{
|
||||
UINT32 previousBkColor = hdc->bkColor;
|
||||
hdc->bkColor = crColor;
|
||||
return previousBkColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current background mode.
|
||||
* msdn{dd144853}
|
||||
*
|
||||
* @param hdc device context
|
||||
*
|
||||
* @return background mode
|
||||
*/
|
||||
|
||||
INT32 gdi_GetBkMode(HGDI_DC hdc)
|
||||
{
|
||||
return hdc->bkMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the current background mode.
|
||||
* msdn{dd162965}
|
||||
*
|
||||
* @param hdc device context
|
||||
* @param iBkMode background mode
|
||||
*
|
||||
* @return previous background mode on success, 0 on failure
|
||||
*/
|
||||
|
||||
INT32 gdi_SetBkMode(HGDI_DC hdc, INT32 iBkMode)
|
||||
{
|
||||
if (iBkMode == GDI_OPAQUE || iBkMode == GDI_TRANSPARENT)
|
||||
{
|
||||
INT32 previousBkMode = hdc->bkMode;
|
||||
hdc->bkMode = iBkMode;
|
||||
return previousBkMode;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** @brief Set the current text color.
|
||||
* https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-settextcolor
|
||||
*
|
||||
* @param hdc device context
|
||||
* @param crColor new text color
|
||||
*
|
||||
* @return previous text color
|
||||
*/
|
||||
|
||||
UINT32 gdi_SetTextColor(HGDI_DC hdc, UINT32 crColor)
|
||||
{
|
||||
UINT32 previousTextColor = hdc->textColor;
|
||||
hdc->textColor = crColor;
|
||||
return previousTextColor;
|
||||
}
|
||||
54
third_party/FreeRDP/libfreerdp/gdi/drawing.h
vendored
Normal file
54
third_party/FreeRDP/libfreerdp/gdi/drawing.h
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Drawing Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LIB_GDI_DRAWING_H
|
||||
#define FREERDP_LIB_GDI_DRAWING_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL INT32 gdi_GetROP2(HGDI_DC hdc);
|
||||
|
||||
FREERDP_LOCAL INT32 gdi_SetROP2(HGDI_DC hdc, INT32 fnDrawMode);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL UINT32 gdi_GetBkColor(HGDI_DC hdc);
|
||||
|
||||
FREERDP_LOCAL UINT32 gdi_SetBkColor(HGDI_DC hdc, UINT32 crColor);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL INT32 gdi_GetBkMode(HGDI_DC hdc);
|
||||
|
||||
FREERDP_LOCAL INT32 gdi_SetBkMode(HGDI_DC hdc, INT32 iBkMode);
|
||||
|
||||
FREERDP_LOCAL UINT32 gdi_SetTextColor(HGDI_DC hdc, UINT32 crColor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FREERDP_LIB_GDI_DRAWING_H */
|
||||
1538
third_party/FreeRDP/libfreerdp/gdi/gdi.c
vendored
Normal file
1538
third_party/FreeRDP/libfreerdp/gdi/gdi.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
103
third_party/FreeRDP/libfreerdp/gdi/gdi.h
vendored
Normal file
103
third_party/FreeRDP/libfreerdp/gdi/gdi.h
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Library
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LIB_GDI_CORE_H
|
||||
#define FREERDP_LIB_GDI_CORE_H
|
||||
|
||||
#include <winpr/cast.h>
|
||||
|
||||
#include "graphics.h"
|
||||
#include "brush.h"
|
||||
|
||||
#include <freerdp/api.h>
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL BOOL gdi_bitmap_update(rdpContext* context, const BITMAP_UPDATE* bitmapUpdate);
|
||||
|
||||
FREERDP_LOCAL void gdi_bitmap_free_ex(gdiBitmap* bitmap);
|
||||
|
||||
WINPR_ATTR_MALLOC(gdi_bitmap_free_ex, 1)
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp, BYTE* data);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
static inline BYTE* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, INT32 x, INT32 y)
|
||||
{
|
||||
HGDI_BITMAP hBmp = (HGDI_BITMAP)hdcBmp->selectedObject;
|
||||
|
||||
if ((x >= 0) && (y >= 0) && (x < hBmp->width) && (y < hBmp->height))
|
||||
{
|
||||
BYTE* p = hBmp->data + (WINPR_ASSERTING_INT_CAST(size_t, y) * hBmp->scanline) +
|
||||
(WINPR_ASSERTING_INT_CAST(size_t, x) * FreeRDPGetBytesPerPixel(hdcBmp->format));
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(FREERDP_TAG("gdi"),
|
||||
"gdi_get_bitmap_pointer: requesting invalid pointer: (%" PRId32 ",%" PRId32
|
||||
") in %" PRId32 "x%" PRId32 "",
|
||||
x, y, hBmp->width, hBmp->height);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current color in brush bitmap according to dest coordinates. msdn{dd183396}
|
||||
*
|
||||
* @param x dest x-coordinate
|
||||
* @param y dest y-coordinate
|
||||
* @return color pointer
|
||||
*/
|
||||
WINPR_ATTR_NODISCARD
|
||||
static inline BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, UINT32 x, UINT32 y)
|
||||
{
|
||||
BYTE* p = nullptr;
|
||||
UINT32 brushStyle = gdi_GetBrushStyle(hdcBrush);
|
||||
|
||||
switch (brushStyle)
|
||||
{
|
||||
case GDI_BS_PATTERN:
|
||||
case GDI_BS_HATCHED:
|
||||
{
|
||||
HGDI_BITMAP hBmpBrush = hdcBrush->brush->pattern;
|
||||
/* According to msdn{dd183396}, the system always positions a brush bitmap
|
||||
* at the brush origin and copy across the client area.
|
||||
* Calculate the offset of the mapped pixel in the brush bitmap according to
|
||||
* brush origin and dest coordinates */
|
||||
const UINT32 w = WINPR_ASSERTING_INT_CAST(UINT32, hBmpBrush->width);
|
||||
const UINT32 h = WINPR_ASSERTING_INT_CAST(UINT32, hBmpBrush->height);
|
||||
|
||||
WINPR_ASSERT(w > 0);
|
||||
WINPR_ASSERT(h > 0);
|
||||
x = (x + w - (WINPR_ASSERTING_INT_CAST(UINT32, hdcBrush->brush->nXOrg) % w)) % w;
|
||||
y = (y + h - (WINPR_ASSERTING_INT_CAST(UINT32, hdcBrush->brush->nYOrg) % h)) % h;
|
||||
p = hBmpBrush->data + (1ULL * y * hBmpBrush->scanline) +
|
||||
(1ULL * x * FreeRDPGetBytesPerPixel(hBmpBrush->format));
|
||||
return p;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
p = (BYTE*)&(hdcBrush->textColor);
|
||||
return p;
|
||||
}
|
||||
|
||||
#endif /* FREERDP_LIB_GDI_CORE_H */
|
||||
2016
third_party/FreeRDP/libfreerdp/gdi/gfx.c
vendored
Normal file
2016
third_party/FreeRDP/libfreerdp/gdi/gfx.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
470
third_party/FreeRDP/libfreerdp/gdi/graphics.c
vendored
Normal file
470
third_party/FreeRDP/libfreerdp/gdi/graphics.c
vendored
Normal file
@@ -0,0 +1,470 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Graphical Objects
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/dc.h>
|
||||
#include <freerdp/gdi/shape.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
|
||||
#include "clipping.h"
|
||||
#include "drawing.h"
|
||||
#include "brush.h"
|
||||
#include "graphics.h"
|
||||
|
||||
#define TAG FREERDP_TAG("gdi")
|
||||
/* Bitmap Class */
|
||||
|
||||
HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, UINT32 nWidth, UINT32 nHeight, UINT32 SrcFormat,
|
||||
BYTE* data)
|
||||
{
|
||||
UINT32 nSrcStep = 0;
|
||||
UINT32 nDstStep = 0;
|
||||
BYTE* pSrcData = nullptr;
|
||||
BYTE* pDstData = nullptr;
|
||||
HGDI_BITMAP bitmap = nullptr;
|
||||
|
||||
if (!gdi)
|
||||
return nullptr;
|
||||
|
||||
nDstStep = nWidth * FreeRDPGetBytesPerPixel(gdi->dstFormat);
|
||||
pDstData = winpr_aligned_malloc(1ull * nHeight * nDstStep, 16);
|
||||
|
||||
if (!pDstData)
|
||||
return nullptr;
|
||||
|
||||
pSrcData = data;
|
||||
nSrcStep = nWidth * FreeRDPGetBytesPerPixel(SrcFormat);
|
||||
|
||||
if (!freerdp_image_copy_no_overlap(pDstData, gdi->dstFormat, nDstStep, 0, 0, nWidth, nHeight,
|
||||
pSrcData, SrcFormat, nSrcStep, 0, 0, &gdi->palette,
|
||||
FREERDP_FLIP_NONE))
|
||||
{
|
||||
winpr_aligned_free(pDstData);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bitmap = gdi_CreateBitmap(nWidth, nHeight, gdi->dstFormat, pDstData);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
static BOOL gdi_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
|
||||
{
|
||||
gdiBitmap* gdi_bitmap = nullptr;
|
||||
rdpGdi* gdi = context->gdi;
|
||||
gdi_bitmap = (gdiBitmap*)bitmap;
|
||||
gdi_bitmap->hdc = gdi_CreateCompatibleDC(gdi->hdc);
|
||||
|
||||
if (!gdi_bitmap->hdc)
|
||||
return FALSE;
|
||||
|
||||
if (!bitmap->data)
|
||||
gdi_bitmap->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, bitmap->width, bitmap->height);
|
||||
else
|
||||
{
|
||||
UINT32 format = bitmap->format;
|
||||
gdi_bitmap->bitmap =
|
||||
gdi_create_bitmap(gdi, bitmap->width, bitmap->height, format, bitmap->data);
|
||||
}
|
||||
|
||||
if (!gdi_bitmap->bitmap)
|
||||
{
|
||||
gdi_DeleteDC(gdi_bitmap->hdc);
|
||||
gdi_bitmap->hdc = nullptr;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdi_bitmap->hdc->format = gdi_bitmap->bitmap->format;
|
||||
gdi_SelectObject(gdi_bitmap->hdc, (HGDIOBJECT)gdi_bitmap->bitmap);
|
||||
gdi_bitmap->org_bitmap = nullptr;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void gdi_Bitmap_Free(WINPR_ATTR_UNUSED rdpContext* context, rdpBitmap* bitmap)
|
||||
{
|
||||
gdiBitmap* gdi_bitmap = (gdiBitmap*)bitmap;
|
||||
|
||||
if (gdi_bitmap)
|
||||
{
|
||||
if (gdi_bitmap->hdc)
|
||||
gdi_SelectObject(gdi_bitmap->hdc, (HGDIOBJECT)gdi_bitmap->org_bitmap);
|
||||
|
||||
gdi_DeleteObject((HGDIOBJECT)gdi_bitmap->bitmap);
|
||||
gdi_DeleteDC(gdi_bitmap->hdc);
|
||||
winpr_aligned_free(bitmap->data);
|
||||
}
|
||||
|
||||
free(bitmap);
|
||||
}
|
||||
|
||||
static BOOL gdi_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
|
||||
{
|
||||
gdiBitmap* gdi_bitmap = (gdiBitmap*)bitmap;
|
||||
UINT32 width = bitmap->right - bitmap->left + 1;
|
||||
UINT32 height = bitmap->bottom - bitmap->top + 1;
|
||||
return gdi_BitBlt(context->gdi->primary->hdc, WINPR_ASSERTING_INT_CAST(int, bitmap->left),
|
||||
WINPR_ASSERTING_INT_CAST(int, bitmap->top),
|
||||
WINPR_ASSERTING_INT_CAST(int, width), WINPR_ASSERTING_INT_CAST(int, height),
|
||||
gdi_bitmap->hdc, 0, 0, GDI_SRCCOPY, &context->gdi->palette);
|
||||
}
|
||||
|
||||
static BOOL gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, const BYTE* pSrcData,
|
||||
UINT32 DstWidth, UINT32 DstHeight, UINT32 bpp, UINT32 length,
|
||||
BOOL compressed, UINT32 codecId)
|
||||
{
|
||||
UINT32 SrcSize = length;
|
||||
rdpGdi* gdi = context->gdi;
|
||||
UINT32 size = DstWidth * DstHeight;
|
||||
bitmap->compressed = FALSE;
|
||||
bitmap->format = gdi->dstFormat;
|
||||
|
||||
if ((FreeRDPGetBytesPerPixel(bitmap->format) == 0) || (DstWidth == 0) || (DstHeight == 0) ||
|
||||
(DstWidth > UINT32_MAX / DstHeight) ||
|
||||
(size > (UINT32_MAX / FreeRDPGetBytesPerPixel(bitmap->format))))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid input data");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size *= FreeRDPGetBytesPerPixel(bitmap->format);
|
||||
bitmap->length = size;
|
||||
bitmap->data = (BYTE*)winpr_aligned_malloc(bitmap->length, 16);
|
||||
|
||||
if (!bitmap->data)
|
||||
return FALSE;
|
||||
|
||||
if (compressed)
|
||||
{
|
||||
if ((codecId == RDP_CODEC_ID_REMOTEFX) || (codecId == RDP_CODEC_ID_IMAGE_REMOTEFX))
|
||||
{
|
||||
REGION16 invalidRegion = WINPR_C_ARRAY_INIT;
|
||||
region16_init(&invalidRegion);
|
||||
|
||||
const BOOL rc =
|
||||
rfx_process_message(context->codecs->rfx, pSrcData, SrcSize, bitmap->left,
|
||||
bitmap->top, bitmap->data, bitmap->format, gdi->stride,
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, gdi->height), &invalidRegion);
|
||||
region16_uninit(&invalidRegion);
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
WLog_ERR(TAG, "rfx_process_message failed");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (codecId == RDP_CODEC_ID_NSCODEC)
|
||||
{
|
||||
const int status = nsc_process_message(
|
||||
context->codecs->nsc, 32, DstWidth, DstHeight, pSrcData, SrcSize, bitmap->data,
|
||||
bitmap->format, 0, 0, 0, DstWidth, DstHeight, FREERDP_FLIP_VERTICAL);
|
||||
|
||||
if (status < 1)
|
||||
{
|
||||
WLog_ERR(TAG, "nsc_process_message failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return freerdp_image_copy_no_overlap(bitmap->data, bitmap->format, 0, 0, 0, DstWidth,
|
||||
DstHeight, pSrcData, PIXEL_FORMAT_XRGB32, 0, 0, 0,
|
||||
&gdi->palette, FREERDP_FLIP_VERTICAL);
|
||||
}
|
||||
else if (bpp < 32)
|
||||
{
|
||||
if (!interleaved_decompress(context->codecs->interleaved, pSrcData, SrcSize, DstWidth,
|
||||
DstHeight, bpp, bitmap->data, bitmap->format, 0, 0, 0,
|
||||
DstWidth, DstHeight, &gdi->palette))
|
||||
{
|
||||
WLog_ERR(TAG, "interleaved_decompress failed");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const BOOL fidelity =
|
||||
freerdp_settings_get_bool(context->settings, FreeRDP_DrawAllowDynamicColorFidelity);
|
||||
freerdp_planar_switch_bgr(context->codecs->planar, fidelity);
|
||||
if (!freerdp_bitmap_decompress_planar(context->codecs->planar, pSrcData, SrcSize,
|
||||
DstWidth, DstHeight, bitmap->data, bitmap->format,
|
||||
0, 0, 0, DstWidth, DstHeight, TRUE))
|
||||
{
|
||||
WLog_ERR(TAG, "freerdp_bitmap_decompress_planar failed");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const UINT32 SrcFormat = gdi_get_pixel_format(bpp);
|
||||
const size_t sbpp = FreeRDPGetBytesPerPixel(SrcFormat);
|
||||
const size_t dbpp = FreeRDPGetBytesPerPixel(bitmap->format);
|
||||
|
||||
if ((sbpp == 0) || (dbpp == 0))
|
||||
return FALSE;
|
||||
else
|
||||
{
|
||||
const size_t dstSize = SrcSize * dbpp / sbpp;
|
||||
|
||||
if (dstSize < bitmap->length)
|
||||
{
|
||||
WLog_ERR(TAG, "dstSize %" PRIuz " < bitmap->length %" PRIu32, dstSize,
|
||||
bitmap->length);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!freerdp_image_copy_no_overlap(bitmap->data, bitmap->format, 0, 0, 0, DstWidth,
|
||||
DstHeight, pSrcData, SrcFormat, 0, 0, 0, &gdi->palette,
|
||||
FREERDP_FLIP_VERTICAL))
|
||||
{
|
||||
WLog_ERR(TAG, "freerdp_image_copy failed");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL gdi_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary)
|
||||
{
|
||||
rdpGdi* gdi = nullptr;
|
||||
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
gdi = context->gdi;
|
||||
|
||||
if (!gdi)
|
||||
return FALSE;
|
||||
|
||||
if (primary)
|
||||
gdi->drawing = gdi->primary;
|
||||
else
|
||||
gdi->drawing = (gdiBitmap*)bitmap;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Glyph Class */
|
||||
static BOOL gdi_Glyph_New(rdpContext* context, rdpGlyph* glyph)
|
||||
{
|
||||
if (!context || !glyph)
|
||||
return FALSE;
|
||||
|
||||
gdiGlyph* gdi_glyph = (gdiGlyph*)glyph;
|
||||
gdi_glyph->hdc = gdi_GetDC();
|
||||
|
||||
if (!gdi_glyph->hdc)
|
||||
return FALSE;
|
||||
|
||||
gdi_glyph->hdc->format = PIXEL_FORMAT_MONO;
|
||||
BYTE* data = freerdp_glyph_convert_ex(glyph->cx, glyph->cy, glyph->aj, glyph->cb);
|
||||
|
||||
if (!data)
|
||||
{
|
||||
gdi_DeleteDC(gdi_glyph->hdc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdi_glyph->bitmap = gdi_CreateBitmap(glyph->cx, glyph->cy, PIXEL_FORMAT_MONO, data);
|
||||
|
||||
if (!gdi_glyph->bitmap)
|
||||
{
|
||||
gdi_DeleteDC(gdi_glyph->hdc);
|
||||
winpr_aligned_free(data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdi_SelectObject(gdi_glyph->hdc, (HGDIOBJECT)gdi_glyph->bitmap);
|
||||
gdi_glyph->org_bitmap = nullptr;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void gdi_Glyph_Free(WINPR_ATTR_UNUSED rdpContext* context, rdpGlyph* glyph)
|
||||
{
|
||||
gdiGlyph* gdi_glyph = nullptr;
|
||||
gdi_glyph = (gdiGlyph*)glyph;
|
||||
|
||||
if (gdi_glyph)
|
||||
{
|
||||
gdi_SelectObject(gdi_glyph->hdc, (HGDIOBJECT)gdi_glyph->org_bitmap);
|
||||
gdi_DeleteObject((HGDIOBJECT)gdi_glyph->bitmap);
|
||||
gdi_DeleteDC(gdi_glyph->hdc);
|
||||
free(glyph->aj);
|
||||
free(glyph);
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL gdi_Glyph_Draw(rdpContext* context, const rdpGlyph* glyph, INT32 x, INT32 y, INT32 w,
|
||||
INT32 h, INT32 sx, INT32 sy, BOOL fOpRedundant)
|
||||
{
|
||||
const gdiGlyph* gdi_glyph = nullptr;
|
||||
rdpGdi* gdi = nullptr;
|
||||
HGDI_BRUSH brush = nullptr;
|
||||
BOOL rc = FALSE;
|
||||
|
||||
if (!context || !glyph)
|
||||
return FALSE;
|
||||
|
||||
gdi = context->gdi;
|
||||
gdi_glyph = (const gdiGlyph*)glyph;
|
||||
|
||||
if (!fOpRedundant)
|
||||
{
|
||||
GDI_RECT rect = WINPR_C_ARRAY_INIT;
|
||||
|
||||
if (x > 0)
|
||||
rect.left = x;
|
||||
|
||||
if (y > 0)
|
||||
rect.top = y;
|
||||
|
||||
if (x + w > 0)
|
||||
rect.right = x + w - 1;
|
||||
|
||||
if (y + h > 0)
|
||||
rect.bottom = y + h - 1;
|
||||
|
||||
if ((rect.left < rect.right) && (rect.top < rect.bottom))
|
||||
{
|
||||
brush = gdi_CreateSolidBrush(gdi->drawing->hdc->bkColor);
|
||||
|
||||
if (!brush)
|
||||
return FALSE;
|
||||
|
||||
const BOOL res = gdi_FillRect(gdi->drawing->hdc, &rect, brush);
|
||||
gdi_DeleteObject((HGDIOBJECT)brush);
|
||||
if (!res)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
brush = gdi_CreateSolidBrush(gdi->drawing->hdc->textColor);
|
||||
|
||||
if (!brush)
|
||||
return FALSE;
|
||||
|
||||
gdi_SelectObject(gdi->drawing->hdc, (HGDIOBJECT)brush);
|
||||
rc = gdi_BitBlt(gdi->drawing->hdc, x, y, w, h, gdi_glyph->hdc, sx, sy, GDI_GLYPH_ORDER,
|
||||
&context->gdi->palette);
|
||||
gdi_DeleteObject((HGDIOBJECT)brush);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static BOOL gdi_Glyph_BeginDraw(rdpContext* context, INT32 x, INT32 y, INT32 width, INT32 height,
|
||||
UINT32 bgcolor, UINT32 fgcolor, BOOL fOpRedundant)
|
||||
{
|
||||
if (!context || !context->gdi)
|
||||
return FALSE;
|
||||
|
||||
rdpGdi* gdi = context->gdi;
|
||||
|
||||
if (!gdi->drawing || !gdi->drawing->hdc)
|
||||
return FALSE;
|
||||
|
||||
if (!fOpRedundant)
|
||||
{
|
||||
if (!gdi_decode_color(gdi, bgcolor, &bgcolor, nullptr))
|
||||
return FALSE;
|
||||
|
||||
if (!gdi_decode_color(gdi, fgcolor, &fgcolor, nullptr))
|
||||
return FALSE;
|
||||
|
||||
if (!gdi_SetClipRgn(gdi->drawing->hdc, x, y, width, height))
|
||||
return FALSE;
|
||||
|
||||
gdi_SetTextColor(gdi->drawing->hdc, bgcolor);
|
||||
gdi_SetBkColor(gdi->drawing->hdc, fgcolor);
|
||||
|
||||
{
|
||||
GDI_RECT rect = WINPR_C_ARRAY_INIT;
|
||||
HGDI_BRUSH brush = gdi_CreateSolidBrush(fgcolor);
|
||||
|
||||
if (!brush)
|
||||
return FALSE;
|
||||
|
||||
if (x > 0)
|
||||
rect.left = x;
|
||||
|
||||
if (y > 0)
|
||||
rect.top = y;
|
||||
|
||||
rect.right = x + width - 1;
|
||||
rect.bottom = y + height - 1;
|
||||
|
||||
BOOL res = TRUE;
|
||||
if ((x + width > rect.left) && (y + height > rect.top))
|
||||
res = gdi_FillRect(gdi->drawing->hdc, &rect, brush);
|
||||
|
||||
gdi_DeleteObject((HGDIOBJECT)brush);
|
||||
if (!res)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return gdi_SetNullClipRgn(gdi->drawing->hdc);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL gdi_Glyph_EndDraw(rdpContext* context, WINPR_ATTR_UNUSED INT32 x,
|
||||
WINPR_ATTR_UNUSED INT32 y, WINPR_ATTR_UNUSED INT32 width,
|
||||
WINPR_ATTR_UNUSED INT32 height, WINPR_ATTR_UNUSED UINT32 bgcolor,
|
||||
WINPR_ATTR_UNUSED UINT32 fgcolor)
|
||||
{
|
||||
rdpGdi* gdi = nullptr;
|
||||
|
||||
if (!context || !context->gdi)
|
||||
return FALSE;
|
||||
|
||||
gdi = context->gdi;
|
||||
|
||||
if (!gdi->drawing || !gdi->drawing->hdc)
|
||||
return FALSE;
|
||||
|
||||
return gdi_SetNullClipRgn(gdi->drawing->hdc);
|
||||
}
|
||||
|
||||
/* Graphics Module */
|
||||
BOOL gdi_register_graphics(rdpGraphics* graphics)
|
||||
{
|
||||
rdpBitmap bitmap = WINPR_C_ARRAY_INIT;
|
||||
rdpGlyph glyph = WINPR_C_ARRAY_INIT;
|
||||
bitmap.size = sizeof(gdiBitmap);
|
||||
bitmap.New = gdi_Bitmap_New;
|
||||
bitmap.Free = gdi_Bitmap_Free;
|
||||
bitmap.Paint = gdi_Bitmap_Paint;
|
||||
bitmap.Decompress = gdi_Bitmap_Decompress;
|
||||
bitmap.SetSurface = gdi_Bitmap_SetSurface;
|
||||
graphics_register_bitmap(graphics, &bitmap);
|
||||
glyph.size = sizeof(gdiGlyph);
|
||||
glyph.New = gdi_Glyph_New;
|
||||
glyph.Free = gdi_Glyph_Free;
|
||||
glyph.Draw = gdi_Glyph_Draw;
|
||||
glyph.BeginDraw = gdi_Glyph_BeginDraw;
|
||||
glyph.EndDraw = gdi_Glyph_EndDraw;
|
||||
graphics_register_glyph(graphics, &glyph);
|
||||
return TRUE;
|
||||
}
|
||||
37
third_party/FreeRDP/libfreerdp/gdi/graphics.h
vendored
Normal file
37
third_party/FreeRDP/libfreerdp/gdi/graphics.h
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Graphical Objects
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LIB_GDI_GRAPHICS_H
|
||||
#define FREERDP_LIB_GDI_GRAPHICS_H
|
||||
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/graphics.h>
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, UINT32 width, UINT32 height, UINT32 format,
|
||||
BYTE* data);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL BOOL gdi_register_graphics(rdpGraphics* graphics);
|
||||
|
||||
#endif /* FREERDP_LIB_GDI_GRAPHICS_H */
|
||||
316
third_party/FreeRDP/libfreerdp/gdi/line.c
vendored
Normal file
316
third_party/FreeRDP/libfreerdp/gdi/line.c
vendored
Normal file
@@ -0,0 +1,316 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Line Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <winpr/assert.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/gdi/pen.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
|
||||
#include "drawing.h"
|
||||
#include "clipping.h"
|
||||
#include "line.h"
|
||||
|
||||
static BOOL gdi_rop_color(INT32 rop, BYTE* pixelPtr, UINT32 pen, UINT32 format)
|
||||
{
|
||||
WINPR_ASSERT(pixelPtr);
|
||||
const UINT32 srcPixel = FreeRDPReadColor(pixelPtr, format);
|
||||
UINT32 dstPixel = 0;
|
||||
|
||||
switch (rop)
|
||||
{
|
||||
case GDI_R2_BLACK: /* LineTo_BLACK */
|
||||
dstPixel = FreeRDPGetColor(format, 0, 0, 0, 0xFF);
|
||||
break;
|
||||
|
||||
case GDI_R2_NOTMERGEPEN: /* LineTo_NOTMERGEPEN */
|
||||
dstPixel = ~(srcPixel | pen);
|
||||
break;
|
||||
|
||||
case GDI_R2_MASKNOTPEN: /* LineTo_MASKNOTPEN */
|
||||
dstPixel = srcPixel & ~pen;
|
||||
break;
|
||||
|
||||
case GDI_R2_NOTCOPYPEN: /* LineTo_NOTCOPYPEN */
|
||||
dstPixel = ~pen;
|
||||
break;
|
||||
|
||||
case GDI_R2_MASKPENNOT: /* LineTo_MASKPENNOT */
|
||||
dstPixel = pen & ~srcPixel;
|
||||
break;
|
||||
|
||||
case GDI_R2_NOT: /* LineTo_NOT */
|
||||
dstPixel = ~srcPixel;
|
||||
break;
|
||||
|
||||
case GDI_R2_XORPEN: /* LineTo_XORPEN */
|
||||
dstPixel = srcPixel ^ pen;
|
||||
break;
|
||||
|
||||
case GDI_R2_NOTMASKPEN: /* LineTo_NOTMASKPEN */
|
||||
dstPixel = ~(srcPixel & pen);
|
||||
break;
|
||||
|
||||
case GDI_R2_MASKPEN: /* LineTo_MASKPEN */
|
||||
dstPixel = srcPixel & pen;
|
||||
break;
|
||||
|
||||
case GDI_R2_NOTXORPEN: /* LineTo_NOTXORPEN */
|
||||
dstPixel = ~(srcPixel ^ pen);
|
||||
break;
|
||||
|
||||
case GDI_R2_NOP: /* LineTo_NOP */
|
||||
dstPixel = srcPixel;
|
||||
break;
|
||||
|
||||
case GDI_R2_MERGENOTPEN: /* LineTo_MERGENOTPEN */
|
||||
dstPixel = srcPixel | ~pen;
|
||||
break;
|
||||
|
||||
case GDI_R2_COPYPEN: /* LineTo_COPYPEN */
|
||||
dstPixel = pen;
|
||||
break;
|
||||
|
||||
case GDI_R2_MERGEPENNOT: /* LineTo_MERGEPENNOT */
|
||||
dstPixel = srcPixel | ~pen;
|
||||
break;
|
||||
|
||||
case GDI_R2_MERGEPEN: /* LineTo_MERGEPEN */
|
||||
dstPixel = srcPixel | pen;
|
||||
break;
|
||||
|
||||
case GDI_R2_WHITE: /* LineTo_WHITE */
|
||||
dstPixel = FreeRDPGetColor(format, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FreeRDPWriteColor(pixelPtr, format, dstPixel);
|
||||
}
|
||||
|
||||
BOOL gdi_LineTo(HGDI_DC hdc, INT32 nXEnd, INT32 nYEnd)
|
||||
{
|
||||
INT32 e2 = 0;
|
||||
UINT32 pen = 0;
|
||||
|
||||
WINPR_ASSERT(hdc);
|
||||
const INT32 rop2 = gdi_GetROP2(hdc);
|
||||
|
||||
const INT32 x1 = hdc->pen->posX;
|
||||
const INT32 y1 = hdc->pen->posY;
|
||||
const INT32 x2 = WINPR_ASSERTING_INT_CAST(int32_t, nXEnd);
|
||||
const INT32 y2 = WINPR_ASSERTING_INT_CAST(int32_t, nYEnd);
|
||||
const INT32 dx = (x1 > x2) ? x1 - x2 : x2 - x1;
|
||||
const INT32 dy = (y1 > y2) ? y1 - y2 : y2 - y1;
|
||||
const INT32 sx = (x1 < x2) ? 1 : -1;
|
||||
const INT32 sy = (y1 < y2) ? 1 : -1;
|
||||
INT32 e = dx - dy;
|
||||
INT32 x = x1;
|
||||
INT32 y = y1;
|
||||
|
||||
WINPR_ASSERT(hdc->clip);
|
||||
INT32 bx1 = 0;
|
||||
INT32 by1 = 0;
|
||||
INT32 bx2 = 0;
|
||||
INT32 by2 = 0;
|
||||
if (hdc->clip->null)
|
||||
{
|
||||
bx1 = (x1 < x2) ? x1 : x2;
|
||||
by1 = (y1 < y2) ? y1 : y2;
|
||||
bx2 = (x1 > x2) ? x1 : x2;
|
||||
by2 = (y1 > y2) ? y1 : y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
bx1 = hdc->clip->x;
|
||||
by1 = hdc->clip->y;
|
||||
bx2 = bx1 + hdc->clip->w - 1;
|
||||
by2 = by1 + hdc->clip->h - 1;
|
||||
}
|
||||
|
||||
HGDI_BITMAP bmp = (HGDI_BITMAP)hdc->selectedObject;
|
||||
WINPR_ASSERT(bmp);
|
||||
|
||||
bx1 = MAX(bx1, 0);
|
||||
by1 = MAX(by1, 0);
|
||||
bx2 = MIN(bx2, bmp->width - 1);
|
||||
by2 = MIN(by2, bmp->height - 1);
|
||||
|
||||
if (!gdi_InvalidateRegion(hdc, bx1, by1, bx2 - bx1 + 1, by2 - by1 + 1))
|
||||
return FALSE;
|
||||
|
||||
pen = gdi_GetPenColor(hdc->pen, bmp->format);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!(x == x2 && y == y2))
|
||||
{
|
||||
if ((x >= bx1 && x <= bx2) && (y >= by1 && y <= by2))
|
||||
{
|
||||
BYTE* pixel = gdi_GetPointer(bmp, WINPR_ASSERTING_INT_CAST(uint32_t, x),
|
||||
WINPR_ASSERTING_INT_CAST(uint32_t, y));
|
||||
WINPR_ASSERT(pixel);
|
||||
gdi_rop_color(rop2, pixel, pen, bmp->format);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
e2 = 2 * e;
|
||||
|
||||
if (e2 > -dy)
|
||||
{
|
||||
e -= dy;
|
||||
x += sx;
|
||||
}
|
||||
|
||||
if (e2 < dx)
|
||||
{
|
||||
e += dx;
|
||||
y += sy;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw one or more straight lines
|
||||
* @param hdc device context
|
||||
* @param lppt array of points
|
||||
* @param cCount number of points
|
||||
* @return nonzero on success, 0 otherwise
|
||||
*/
|
||||
BOOL gdi_PolylineTo(HGDI_DC hdc, GDI_POINT* lppt, DWORD cCount)
|
||||
{
|
||||
WINPR_ASSERT(hdc);
|
||||
WINPR_ASSERT(lppt || (cCount == 0));
|
||||
|
||||
for (DWORD i = 0; i < cCount; i++)
|
||||
{
|
||||
if (!gdi_LineTo(hdc, lppt[i].x, lppt[i].y))
|
||||
return FALSE;
|
||||
|
||||
if (!gdi_MoveToEx(hdc, lppt[i].x, lppt[i].y, nullptr))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw one or more straight lines
|
||||
* @param hdc device context
|
||||
* @param lppt array of points
|
||||
* @param cPoints number of points
|
||||
* @return nonzero on success, 0 otherwise
|
||||
*/
|
||||
BOOL gdi_Polyline(HGDI_DC hdc, GDI_POINT* lppt, UINT32 cPoints)
|
||||
{
|
||||
WINPR_ASSERT(hdc);
|
||||
WINPR_ASSERT(lppt || (cPoints == 0));
|
||||
|
||||
if (cPoints > 0)
|
||||
{
|
||||
GDI_POINT pt = WINPR_C_ARRAY_INIT;
|
||||
|
||||
if (!gdi_MoveToEx(hdc, lppt[0].x, lppt[0].y, &pt))
|
||||
return FALSE;
|
||||
|
||||
for (UINT32 i = 0; i < cPoints; i++)
|
||||
{
|
||||
if (!gdi_LineTo(hdc, lppt[i].x, lppt[i].y))
|
||||
return FALSE;
|
||||
|
||||
if (!gdi_MoveToEx(hdc, lppt[i].x, lppt[i].y, nullptr))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gdi_MoveToEx(hdc, pt.x, pt.y, nullptr))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw multiple series of connected line segments
|
||||
* @param hdc device context
|
||||
* @param lppt array of points
|
||||
* @param lpdwPolyPoints array of numbers of points per series
|
||||
* @param cCount count of entries in lpdwPolyPoints
|
||||
* @return nonzero on success, 0 otherwise
|
||||
*/
|
||||
BOOL gdi_PolyPolyline(HGDI_DC hdc, GDI_POINT* lppt, const UINT32* lpdwPolyPoints, DWORD cCount)
|
||||
{
|
||||
DWORD j = 0;
|
||||
|
||||
WINPR_ASSERT(hdc);
|
||||
WINPR_ASSERT(lppt || (cCount == 0));
|
||||
WINPR_ASSERT(lpdwPolyPoints || (cCount == 0));
|
||||
|
||||
for (DWORD i = 0; i < cCount; i++)
|
||||
{
|
||||
const UINT32 cPoints = lpdwPolyPoints[i];
|
||||
|
||||
if (!gdi_Polyline(hdc, &lppt[j], cPoints))
|
||||
return FALSE;
|
||||
|
||||
j += cPoints;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move pen from the current device context to a new position.
|
||||
* @param hdc device context
|
||||
* @param X x position
|
||||
* @param Y y position
|
||||
* @return nonzero on success, 0 otherwise
|
||||
*/
|
||||
|
||||
BOOL gdi_MoveToEx(HGDI_DC hdc, INT32 X, INT32 Y, HGDI_POINT lpPoint)
|
||||
{
|
||||
WINPR_ASSERT(hdc);
|
||||
|
||||
if (lpPoint != nullptr)
|
||||
{
|
||||
lpPoint->x = hdc->pen->posX;
|
||||
lpPoint->y = hdc->pen->posY;
|
||||
}
|
||||
|
||||
hdc->pen->posX = X;
|
||||
hdc->pen->posY = Y;
|
||||
return TRUE;
|
||||
}
|
||||
53
third_party/FreeRDP/libfreerdp/gdi/line.h
vendored
Normal file
53
third_party/FreeRDP/libfreerdp/gdi/line.h
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Line Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LIB_GDI_LINE_H
|
||||
#define FREERDP_LIB_GDI_LINE_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL BOOL gdi_LineTo(HGDI_DC hdc, INT32 nXEnd, INT32 nYEnd);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL BOOL gdi_PolylineTo(HGDI_DC hdc, GDI_POINT* lppt, DWORD cCount);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL BOOL gdi_Polyline(HGDI_DC hdc, GDI_POINT* lppt, UINT32 cPoints);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL BOOL gdi_PolyPolyline(HGDI_DC hdc, GDI_POINT* lppt, const UINT32* lpdwPolyPoints,
|
||||
DWORD cCount);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL BOOL gdi_MoveToEx(HGDI_DC hdc, INT32 X, INT32 Y, HGDI_POINT lpPoint);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FREERDP_LIB_GDI_LINE_H */
|
||||
65
third_party/FreeRDP/libfreerdp/gdi/pen.c
vendored
Normal file
65
third_party/FreeRDP/libfreerdp/gdi/pen.c
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Pen Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* GDI Pen Functions: http://msdn.microsoft.com/en-us/library/dd162790 */
|
||||
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/pen.h>
|
||||
|
||||
/**
|
||||
* @brief Create a new pen.
|
||||
* msdn{dd183509}
|
||||
*
|
||||
* @param fnPenStyle pen style
|
||||
* @param nWidth pen width
|
||||
* @param crColor pen color
|
||||
* @param format the color format
|
||||
* @param palette A pointer to a color palette
|
||||
*
|
||||
* @return new pen
|
||||
*/
|
||||
|
||||
HGDI_PEN gdi_CreatePen(UINT32 fnPenStyle, UINT32 nWidth, UINT32 crColor, UINT32 format,
|
||||
const gdiPalette* palette)
|
||||
{
|
||||
HGDI_PEN hPen = (HGDI_PEN)calloc(1, sizeof(GDI_PEN));
|
||||
if (!hPen)
|
||||
return nullptr;
|
||||
hPen->objectType = GDIOBJECT_PEN;
|
||||
hPen->style = fnPenStyle;
|
||||
hPen->color = crColor;
|
||||
WINPR_ASSERT(nWidth <= INT32_MAX);
|
||||
hPen->width = (int)nWidth;
|
||||
hPen->format = format;
|
||||
hPen->palette = palette;
|
||||
return hPen;
|
||||
}
|
||||
|
||||
UINT32 gdi_GetPenColor(HGDI_PEN pen, UINT32 format)
|
||||
{
|
||||
return FreeRDPConvertColor(pen->color, pen->format, format, pen->palette);
|
||||
}
|
||||
689
third_party/FreeRDP/libfreerdp/gdi/region.c
vendored
Normal file
689
third_party/FreeRDP/libfreerdp/gdi/region.c
vendored
Normal file
@@ -0,0 +1,689 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Region Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/region.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
|
||||
#define TAG FREERDP_TAG("gdi.region")
|
||||
|
||||
static char* gdi_rect_str(char* buffer, size_t size, const GDI_RECT* rect)
|
||||
{
|
||||
if (!buffer || (size < 1) || !rect)
|
||||
return nullptr;
|
||||
|
||||
(void)_snprintf(buffer, size - 1,
|
||||
"[top/left=%" PRId32 "x%" PRId32 "-bottom/right%" PRId32 "x%" PRId32 "]",
|
||||
rect->top, rect->left, rect->bottom, rect->right);
|
||||
buffer[size - 1] = '\0';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static char* gdi_regn_str(char* buffer, size_t size, const GDI_RGN* rgn)
|
||||
{
|
||||
if (!buffer || (size < 1) || !rgn)
|
||||
return nullptr;
|
||||
|
||||
(void)_snprintf(buffer, size - 1, "[%" PRId32 "x%" PRId32 "-%" PRId32 "x%" PRId32 "]", rgn->x,
|
||||
rgn->y, rgn->w, rgn->h);
|
||||
buffer[size - 1] = '\0';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a region from rectangular coordinates.
|
||||
* msdn{dd183514}
|
||||
*
|
||||
* @param nLeftRect x1
|
||||
* @param nTopRect y1
|
||||
* @param nRightRect x2
|
||||
* @param nBottomRect y2
|
||||
*
|
||||
* @return new region
|
||||
*/
|
||||
|
||||
GDI_RGN* gdi_CreateRectRgn(INT32 nLeftRect, INT32 nTopRect, INT32 nRightRect, INT32 nBottomRect)
|
||||
{
|
||||
INT64 w = 0;
|
||||
INT64 h = 0;
|
||||
GDI_RGN* hRgn = nullptr;
|
||||
|
||||
w = nRightRect - nLeftRect + 1ll;
|
||||
h = nBottomRect - nTopRect + 1ll;
|
||||
if ((w < 0) || (h < 0) || (w > INT32_MAX) || (h > INT32_MAX))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"Can not create region top/left=%" PRId32 "x%" PRId32 "-bottom/right=%" PRId32
|
||||
"x%" PRId32,
|
||||
nTopRect, nLeftRect, nBottomRect, nRightRect);
|
||||
return nullptr;
|
||||
}
|
||||
hRgn = (GDI_RGN*)calloc(1, sizeof(GDI_RGN));
|
||||
|
||||
if (!hRgn)
|
||||
return nullptr;
|
||||
|
||||
hRgn->objectType = GDIOBJECT_REGION;
|
||||
hRgn->x = nLeftRect;
|
||||
hRgn->y = nTopRect;
|
||||
hRgn->w = (INT32)w;
|
||||
hRgn->h = (INT32)h;
|
||||
hRgn->null = FALSE;
|
||||
return hRgn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new rectangle.
|
||||
* @param xLeft x1
|
||||
* @param yTop y1
|
||||
* @param xRight x2
|
||||
* @param yBottom y2
|
||||
* @return new rectangle
|
||||
*/
|
||||
|
||||
GDI_RECT* gdi_CreateRect(INT32 xLeft, INT32 yTop, INT32 xRight, INT32 yBottom)
|
||||
{
|
||||
GDI_RECT* hRect = nullptr;
|
||||
|
||||
if (xLeft > xRight)
|
||||
return nullptr;
|
||||
if (yTop > yBottom)
|
||||
return nullptr;
|
||||
|
||||
hRect = (GDI_RECT*)calloc(1, sizeof(GDI_RECT));
|
||||
|
||||
if (!hRect)
|
||||
return nullptr;
|
||||
|
||||
hRect->objectType = GDIOBJECT_RECT;
|
||||
hRect->left = xLeft;
|
||||
hRect->top = yTop;
|
||||
hRect->right = xRight;
|
||||
hRect->bottom = yBottom;
|
||||
return hRect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a rectangle to a region.
|
||||
* @param rect source rectangle
|
||||
* @param rgn destination region
|
||||
*/
|
||||
|
||||
BOOL gdi_RectToRgn(const GDI_RECT* rect, GDI_RGN* rgn)
|
||||
{
|
||||
WINPR_ASSERT(rect);
|
||||
WINPR_ASSERT(rgn);
|
||||
|
||||
BOOL rc = TRUE;
|
||||
INT64 w = rect->right - rect->left + 1ll;
|
||||
INT64 h = rect->bottom - rect->top + 1ll;
|
||||
|
||||
if ((w < 0) || (h < 0) || (w > INT32_MAX) || (h > INT32_MAX))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"Can not create region top/left=%" PRId32 "x%" PRId32 "-bottom/right=%" PRId32
|
||||
"x%" PRId32,
|
||||
rect->top, rect->left, rect->bottom, rect->right);
|
||||
w = 0;
|
||||
h = 0;
|
||||
rc = FALSE;
|
||||
}
|
||||
|
||||
rgn->x = rect->left;
|
||||
rgn->y = rect->top;
|
||||
rgn->w = (INT32)w;
|
||||
rgn->h = (INT32)h;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert rectangular coordinates to a region.
|
||||
* @param left x1
|
||||
* @param top y1
|
||||
* @param right x2
|
||||
* @param bottom y2
|
||||
* @param rgn destination region
|
||||
*/
|
||||
|
||||
BOOL gdi_CRectToRgn(INT32 left, INT32 top, INT32 right, INT32 bottom, GDI_RGN* rgn)
|
||||
{
|
||||
BOOL rc = TRUE;
|
||||
INT64 w = 0;
|
||||
INT64 h = 0;
|
||||
w = right - left + 1ll;
|
||||
h = bottom - top + 1ll;
|
||||
|
||||
if (!rgn)
|
||||
return FALSE;
|
||||
|
||||
if ((w < 0) || (h < 0) || (w > INT32_MAX) || (h > INT32_MAX))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"Can not create region top/left=%" PRId32 "x%" PRId32 "-bottom/right=%" PRId32
|
||||
"x%" PRId32,
|
||||
top, left, bottom, right);
|
||||
w = 0;
|
||||
h = 0;
|
||||
rc = FALSE;
|
||||
}
|
||||
|
||||
rgn->x = left;
|
||||
rgn->y = top;
|
||||
rgn->w = (INT32)w;
|
||||
rgn->h = (INT32)h;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a rectangle to region coordinates.
|
||||
* @param rect source rectangle
|
||||
* @param x x1
|
||||
* @param y y1
|
||||
* @param w width
|
||||
* @param h height
|
||||
*/
|
||||
|
||||
BOOL gdi_RectToCRgn(const GDI_RECT* rect, INT32* x, INT32* y, INT32* w, INT32* h)
|
||||
{
|
||||
BOOL rc = TRUE;
|
||||
*x = rect->left;
|
||||
*y = rect->top;
|
||||
INT64 tmp = rect->right - rect->left + 1;
|
||||
if ((tmp < 0) || (tmp > INT32_MAX))
|
||||
{
|
||||
char buffer[256];
|
||||
WLog_ERR(TAG, "rectangle invalid %s", gdi_rect_str(buffer, sizeof(buffer), rect));
|
||||
*w = 0;
|
||||
rc = FALSE;
|
||||
}
|
||||
else
|
||||
*w = (INT32)tmp;
|
||||
tmp = rect->bottom - rect->top + 1;
|
||||
if ((tmp < 0) || (tmp > INT32_MAX))
|
||||
{
|
||||
char buffer[256];
|
||||
WLog_ERR(TAG, "rectangle invalid %s", gdi_rect_str(buffer, sizeof(buffer), rect));
|
||||
*h = 0;
|
||||
rc = FALSE;
|
||||
}
|
||||
else
|
||||
*h = (INT32)tmp;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert rectangular coordinates to region coordinates.
|
||||
* @param left x1
|
||||
* @param top y1
|
||||
* @param right x2
|
||||
* @param bottom y2
|
||||
* @param x x1
|
||||
* @param y y1
|
||||
* @param w width
|
||||
* @param h height
|
||||
*/
|
||||
|
||||
BOOL gdi_CRectToCRgn(INT32 left, INT32 top, INT32 right, INT32 bottom, INT32* x, INT32* y, INT32* w,
|
||||
INT32* h)
|
||||
{
|
||||
INT64 wl = 0;
|
||||
INT64 hl = 0;
|
||||
BOOL rc = TRUE;
|
||||
wl = right - left + 1ll;
|
||||
hl = bottom - top + 1ll;
|
||||
|
||||
if ((left > right) || (top > bottom) || (wl <= 0) || (hl <= 0) || (wl > INT32_MAX) ||
|
||||
(hl > INT32_MAX))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"Can not create region top/left=%" PRId32 "x%" PRId32 "-bottom/right=%" PRId32
|
||||
"x%" PRId32,
|
||||
top, left, bottom, right);
|
||||
wl = 0;
|
||||
hl = 0;
|
||||
rc = FALSE;
|
||||
}
|
||||
|
||||
*x = left;
|
||||
*y = top;
|
||||
*w = (INT32)wl;
|
||||
*h = (INT32)hl;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a region to a rectangle.
|
||||
* @param rgn source region
|
||||
* @param rect destination rectangle
|
||||
*/
|
||||
|
||||
BOOL gdi_RgnToRect(const GDI_RGN* rgn, GDI_RECT* rect)
|
||||
{
|
||||
INT64 r = 0;
|
||||
INT64 b = 0;
|
||||
BOOL rc = TRUE;
|
||||
r = rgn->x + rgn->w - 1ll;
|
||||
b = rgn->y + rgn->h - 1ll;
|
||||
|
||||
if ((r < INT32_MIN) || (r > INT32_MAX) || (b < INT32_MIN) || (b > INT32_MAX))
|
||||
{
|
||||
char buffer[256];
|
||||
WLog_ERR(TAG, "Can not create region %s", gdi_regn_str(buffer, sizeof(buffer), rgn));
|
||||
r = rgn->x;
|
||||
b = rgn->y;
|
||||
rc = FALSE;
|
||||
}
|
||||
rect->left = rgn->x;
|
||||
rect->top = rgn->y;
|
||||
rect->right = (INT32)r;
|
||||
rect->bottom = (INT32)b;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert region coordinates to a rectangle.
|
||||
* @param x x1
|
||||
* @param y y1
|
||||
* @param w width
|
||||
* @param h height
|
||||
* @param rect destination rectangle
|
||||
*/
|
||||
|
||||
BOOL gdi_CRgnToRect(INT64 x, INT64 y, INT32 w, INT32 h, GDI_RECT* rect)
|
||||
{
|
||||
BOOL invalid = FALSE;
|
||||
const INT64 r = x + w - 1;
|
||||
const INT64 b = y + h - 1;
|
||||
WINPR_ASSERT(x <= INT32_MAX);
|
||||
WINPR_ASSERT(y <= INT32_MAX);
|
||||
WINPR_ASSERT(r <= INT32_MAX);
|
||||
WINPR_ASSERT(b <= INT32_MAX);
|
||||
rect->left = (x > 0) ? (INT32)x : 0;
|
||||
rect->top = (y > 0) ? (INT32)y : 0;
|
||||
rect->right = rect->left;
|
||||
rect->bottom = rect->top;
|
||||
|
||||
if ((w <= 0) || (h <= 0))
|
||||
invalid = TRUE;
|
||||
|
||||
if (r > 0)
|
||||
rect->right = (INT32)r;
|
||||
else
|
||||
invalid = TRUE;
|
||||
|
||||
if (b > 0)
|
||||
rect->bottom = (INT32)b;
|
||||
else
|
||||
invalid = TRUE;
|
||||
|
||||
if (invalid)
|
||||
{
|
||||
WLog_DBG(TAG, "Invisible rectangle %" PRId64 "x%" PRId64 "-%" PRId64 "x%" PRId64, x, y, r,
|
||||
b);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a region to rectangular coordinates.
|
||||
* @param rgn source region
|
||||
* @param left x1
|
||||
* @param top y1
|
||||
* @param right x2
|
||||
* @param bottom y2
|
||||
*/
|
||||
|
||||
BOOL gdi_RgnToCRect(const GDI_RGN* rgn, INT32* left, INT32* top, INT32* right, INT32* bottom)
|
||||
{
|
||||
BOOL rc = TRUE;
|
||||
|
||||
WINPR_ASSERT(rgn);
|
||||
if ((rgn->w < 0) || (rgn->h < 0))
|
||||
{
|
||||
char buffer[256];
|
||||
WLog_ERR(TAG, "Can not create region %s", gdi_regn_str(buffer, sizeof(buffer), rgn));
|
||||
rc = FALSE;
|
||||
}
|
||||
|
||||
*left = rgn->x;
|
||||
*top = rgn->y;
|
||||
*right = rgn->x + rgn->w - 1;
|
||||
*bottom = rgn->y + rgn->h - 1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert region coordinates to rectangular coordinates.
|
||||
* @param x x1
|
||||
* @param y y1
|
||||
* @param w width
|
||||
* @param h height
|
||||
* @param left x1
|
||||
* @param top y1
|
||||
* @param right x2
|
||||
* @param bottom y2
|
||||
*/
|
||||
|
||||
BOOL gdi_CRgnToCRect(INT32 x, INT32 y, INT32 w, INT32 h, INT32* left, INT32* top, INT32* right,
|
||||
INT32* bottom)
|
||||
{
|
||||
BOOL rc = TRUE;
|
||||
*left = x;
|
||||
*top = y;
|
||||
*right = 0;
|
||||
|
||||
if (w > 0)
|
||||
*right = x + w - 1;
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "Invalid width");
|
||||
rc = FALSE;
|
||||
}
|
||||
|
||||
*bottom = 0;
|
||||
|
||||
if (h > 0)
|
||||
*bottom = y + h - 1;
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "Invalid height");
|
||||
rc = FALSE;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if copying would involve overlapping regions
|
||||
* @param x x1
|
||||
* @param y y1
|
||||
* @param width width
|
||||
* @param height height
|
||||
* @param srcx source x1
|
||||
* @param srcy source y1
|
||||
* @return nonzero if there is an overlap, 0 otherwise
|
||||
*/
|
||||
|
||||
inline BOOL gdi_CopyOverlap(INT32 x, INT32 y, INT32 width, INT32 height, INT32 srcx, INT32 srcy)
|
||||
{
|
||||
GDI_RECT dst;
|
||||
GDI_RECT src;
|
||||
if (!gdi_CRgnToRect(x, y, width, height, &dst))
|
||||
return FALSE;
|
||||
if (!gdi_CRgnToRect(srcx, srcy, width, height, &src))
|
||||
return FALSE;
|
||||
|
||||
if (dst.right < src.left)
|
||||
return FALSE;
|
||||
if (dst.left > src.right)
|
||||
return FALSE;
|
||||
if (dst.bottom < src.top)
|
||||
return FALSE;
|
||||
if (dst.top > src.bottom)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the coordinates of a given rectangle.
|
||||
* msdn{dd145085}
|
||||
*
|
||||
* @param rc rectangle
|
||||
* @param xLeft x1
|
||||
* @param yTop y1
|
||||
* @param xRight x2
|
||||
* @param yBottom y2
|
||||
*
|
||||
* @return nonzero if successful, 0 otherwise
|
||||
*/
|
||||
|
||||
inline BOOL gdi_SetRect(GDI_RECT* rc, INT32 xLeft, INT32 yTop, INT32 xRight, INT32 yBottom)
|
||||
{
|
||||
if (!rc)
|
||||
return FALSE;
|
||||
if (xLeft > xRight)
|
||||
return FALSE;
|
||||
if (yTop > yBottom)
|
||||
return FALSE;
|
||||
|
||||
rc->left = xLeft;
|
||||
rc->top = yTop;
|
||||
rc->right = xRight;
|
||||
rc->bottom = yBottom;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the coordinates of a given region.
|
||||
* @param hRgn region
|
||||
* @param nXLeft x1
|
||||
* @param nYLeft y1
|
||||
* @param nWidth width
|
||||
* @param nHeight height
|
||||
* @return nonzero if successful, 0 otherwise
|
||||
*/
|
||||
|
||||
inline BOOL gdi_SetRgn(GDI_RGN* hRgn, INT32 nXLeft, INT32 nYLeft, INT32 nWidth, INT32 nHeight)
|
||||
{
|
||||
if (!hRgn)
|
||||
return FALSE;
|
||||
|
||||
if ((nWidth < 0) || (nHeight < 0))
|
||||
return FALSE;
|
||||
|
||||
hRgn->x = nXLeft;
|
||||
hRgn->y = nYLeft;
|
||||
hRgn->w = nWidth;
|
||||
hRgn->h = nHeight;
|
||||
hRgn->null = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert rectangular coordinates to a region
|
||||
* @param hRgn destination region
|
||||
* @param nLeftRect x1
|
||||
* @param nTopRect y1
|
||||
* @param nRightRect x2
|
||||
* @param nBottomRect y2
|
||||
* @return nonzero if successful, 0 otherwise
|
||||
*/
|
||||
|
||||
inline BOOL gdi_SetRectRgn(GDI_RGN* hRgn, INT32 nLeftRect, INT32 nTopRect, INT32 nRightRect,
|
||||
INT32 nBottomRect)
|
||||
{
|
||||
if (!gdi_CRectToRgn(nLeftRect, nTopRect, nRightRect, nBottomRect, hRgn))
|
||||
return FALSE;
|
||||
hRgn->null = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compare two regions for equality.
|
||||
* msdn{dd162700}
|
||||
*
|
||||
* @param hSrcRgn1 first region
|
||||
* @param hSrcRgn2 second region
|
||||
* @return nonzero if both regions are equal, 0 otherwise
|
||||
*/
|
||||
|
||||
inline BOOL gdi_EqualRgn(const GDI_RGN* hSrcRgn1, const GDI_RGN* hSrcRgn2)
|
||||
{
|
||||
WINPR_ASSERT(hSrcRgn1);
|
||||
WINPR_ASSERT(hSrcRgn2);
|
||||
return ((hSrcRgn1->x == hSrcRgn2->x) && (hSrcRgn1->y == hSrcRgn2->y) &&
|
||||
(hSrcRgn1->w == hSrcRgn2->w) && (hSrcRgn1->h == hSrcRgn2->h));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy coordinates from a rectangle to another rectangle
|
||||
* msdn{dd183481}
|
||||
*
|
||||
* @param dst destination rectangle
|
||||
* @param src source rectangle
|
||||
* @return nonzero if successful, 0 otherwise
|
||||
*/
|
||||
|
||||
inline BOOL gdi_CopyRect(GDI_RECT* dst, const GDI_RECT* src)
|
||||
{
|
||||
if (!dst || !src)
|
||||
return FALSE;
|
||||
|
||||
dst->left = src->left;
|
||||
dst->top = src->top;
|
||||
dst->right = src->right;
|
||||
dst->bottom = src->bottom;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a point is inside a rectangle.
|
||||
* msdn{dd162882}
|
||||
* @param rc rectangle
|
||||
* @param x point x position
|
||||
* @param y point y position
|
||||
* @return nonzero if the point is inside, 0 otherwise
|
||||
*/
|
||||
|
||||
inline BOOL gdi_PtInRect(const GDI_RECT* rc, INT32 x, INT32 y)
|
||||
{
|
||||
/*
|
||||
* points on the left and top sides are considered in,
|
||||
* while points on the right and bottom sides are considered out
|
||||
*/
|
||||
if ((x >= rc->left) && (x <= rc->right))
|
||||
{
|
||||
if ((y >= rc->top) && (y <= rc->bottom))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate a given region, such that it is redrawn on the next region update.
|
||||
* msdn{dd145003}
|
||||
* @param hdc device context
|
||||
* @param x x1
|
||||
* @param y y1
|
||||
* @param w width
|
||||
* @param h height
|
||||
* @return nonzero on success, 0 otherwise
|
||||
*/
|
||||
|
||||
inline BOOL gdi_InvalidateRegion(HGDI_DC hdc, INT32 x, INT32 y, INT32 w, INT32 h)
|
||||
{
|
||||
GDI_RECT inv;
|
||||
GDI_RECT rgn;
|
||||
GDI_RGN* invalid = nullptr;
|
||||
GDI_RGN* cinvalid = nullptr;
|
||||
|
||||
if (!hdc->hwnd)
|
||||
return TRUE;
|
||||
|
||||
if (!hdc->hwnd->invalid)
|
||||
return TRUE;
|
||||
|
||||
if (w == 0 || h == 0)
|
||||
return TRUE;
|
||||
|
||||
cinvalid = hdc->hwnd->cinvalid;
|
||||
|
||||
if ((hdc->hwnd->ninvalid + 1) > (INT64)hdc->hwnd->count)
|
||||
{
|
||||
GDI_RGN* new_rgn = nullptr;
|
||||
size_t new_cnt = 2ULL * hdc->hwnd->count;
|
||||
if (new_cnt > UINT32_MAX)
|
||||
return FALSE;
|
||||
|
||||
new_rgn = (GDI_RGN*)realloc(cinvalid, sizeof(GDI_RGN) * new_cnt);
|
||||
|
||||
if (!new_rgn)
|
||||
return FALSE;
|
||||
|
||||
hdc->hwnd->count = (UINT32)new_cnt;
|
||||
cinvalid = new_rgn;
|
||||
}
|
||||
|
||||
hdc->hwnd->cinvalid = cinvalid;
|
||||
invalid = hdc->hwnd->invalid;
|
||||
|
||||
if (!gdi_SetRgn(&cinvalid[hdc->hwnd->ninvalid++], x, y, w, h))
|
||||
return FALSE;
|
||||
|
||||
if (!gdi_CRgnToRect(x, y, w, h, &rgn))
|
||||
{
|
||||
invalid->x = 0;
|
||||
invalid->y = 0;
|
||||
invalid->w = 0;
|
||||
invalid->h = 0;
|
||||
invalid->null = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (invalid->null)
|
||||
{
|
||||
invalid->x = x;
|
||||
invalid->y = y;
|
||||
invalid->w = w;
|
||||
invalid->h = h;
|
||||
invalid->null = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!gdi_RgnToRect(invalid, &inv))
|
||||
return FALSE;
|
||||
|
||||
if (rgn.left < inv.left)
|
||||
inv.left = rgn.left;
|
||||
|
||||
if (rgn.top < inv.top)
|
||||
inv.top = rgn.top;
|
||||
|
||||
if (rgn.right > inv.right)
|
||||
inv.right = rgn.right;
|
||||
|
||||
if (rgn.bottom > inv.bottom)
|
||||
inv.bottom = rgn.bottom;
|
||||
|
||||
return gdi_RectToRgn(&inv, invalid);
|
||||
}
|
||||
299
third_party/FreeRDP/libfreerdp/gdi/shape.c
vendored
Normal file
299
third_party/FreeRDP/libfreerdp/gdi/shape.c
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Shape Functions
|
||||
*
|
||||
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
#include <freerdp/gdi/shape.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
|
||||
#include "clipping.h"
|
||||
#include "../gdi/gdi.h"
|
||||
|
||||
#define TAG FREERDP_TAG("gdi.shape")
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
static BOOL Ellipse_Bresenham(HGDI_DC hdc, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
INT32 a = (x1 < x2) ? x2 - x1 : x1 - x2;
|
||||
const INT32 b = (y1 < y2) ? y2 - y1 : y1 - y2;
|
||||
INT32 c = b & 1;
|
||||
INT32 dx = 4 * (1 - a) * b * b;
|
||||
INT32 dy = 4 * (c + 1) * a * a;
|
||||
INT32 e = dx + dy + c * a * a;
|
||||
|
||||
if (x1 > x2)
|
||||
{
|
||||
x1 = x2;
|
||||
x2 += a;
|
||||
}
|
||||
|
||||
if (y1 > y2)
|
||||
y1 = y2;
|
||||
|
||||
y1 += (b + 1) / 2;
|
||||
y2 = y1 - c;
|
||||
a *= 8 * a;
|
||||
c = 8 * b * b;
|
||||
|
||||
do
|
||||
{
|
||||
gdi_SetPixel(hdc, WINPR_ASSERTING_INT_CAST(UINT32, x2),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, y1), 0);
|
||||
gdi_SetPixel(hdc, WINPR_ASSERTING_INT_CAST(UINT32, x1),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, y1), 0);
|
||||
gdi_SetPixel(hdc, WINPR_ASSERTING_INT_CAST(UINT32, x1),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, y2), 0);
|
||||
gdi_SetPixel(hdc, WINPR_ASSERTING_INT_CAST(UINT32, x2),
|
||||
WINPR_ASSERTING_INT_CAST(UINT32, y2), 0);
|
||||
|
||||
const INT32 e2 = 2 * e;
|
||||
|
||||
if (e2 >= dx)
|
||||
{
|
||||
x1++;
|
||||
x2--;
|
||||
e += dx += c;
|
||||
}
|
||||
|
||||
if (e2 <= dy)
|
||||
{
|
||||
y1++;
|
||||
y2--;
|
||||
e += dy += a;
|
||||
}
|
||||
} while (x1 <= x2);
|
||||
|
||||
while (y1 - y2 < b)
|
||||
{
|
||||
y1++;
|
||||
y2--;
|
||||
|
||||
gdi_SetPixel(hdc, WINPR_ASSERTING_INT_CAST(uint32_t, x1 - 1),
|
||||
WINPR_ASSERTING_INT_CAST(uint32_t, y1), 0);
|
||||
gdi_SetPixel(hdc, WINPR_ASSERTING_INT_CAST(uint32_t, x1 - 1),
|
||||
WINPR_ASSERTING_INT_CAST(uint32_t, y2), 0);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw an ellipse
|
||||
* msdn{dd162510}
|
||||
*
|
||||
* @param hdc device context
|
||||
* @param nLeftRect x1
|
||||
* @param nTopRect y1
|
||||
* @param nRightRect x2
|
||||
* @param nBottomRect y2
|
||||
*
|
||||
* @return nonzero if successful, 0 otherwise
|
||||
*/
|
||||
BOOL gdi_Ellipse(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
|
||||
{
|
||||
return Ellipse_Bresenham(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill a rectangle with the given brush.
|
||||
* msdn{dd162719}
|
||||
*
|
||||
* @param hdc device context
|
||||
* @param rect rectangle
|
||||
* @param hbr brush
|
||||
*
|
||||
* @return nonzero if successful, 0 otherwise
|
||||
*/
|
||||
|
||||
BOOL gdi_FillRect(HGDI_DC hdc, const GDI_RECT* rect, HGDI_BRUSH hbr)
|
||||
{
|
||||
INT32 nXDest = 0;
|
||||
INT32 nYDest = 0;
|
||||
INT32 nWidth = 0;
|
||||
INT32 nHeight = 0;
|
||||
|
||||
if (!gdi_RectToCRgn(rect, &nXDest, &nYDest, &nWidth, &nHeight))
|
||||
return FALSE;
|
||||
|
||||
if (!hdc || !hbr)
|
||||
return FALSE;
|
||||
|
||||
if (!gdi_ClipCoords(hdc, &nXDest, &nYDest, &nWidth, &nHeight, nullptr, nullptr))
|
||||
return TRUE;
|
||||
|
||||
switch (hbr->style)
|
||||
{
|
||||
case GDI_BS_SOLID:
|
||||
{
|
||||
const UINT32 color = hbr->color;
|
||||
|
||||
for (INT32 x = 0; x < nWidth; x++)
|
||||
{
|
||||
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest + x, nYDest);
|
||||
|
||||
if (dstp)
|
||||
FreeRDPWriteColor(dstp, hdc->format, color);
|
||||
}
|
||||
|
||||
const BYTE* srcp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest);
|
||||
const UINT32 formatSize = FreeRDPGetBytesPerPixel(hdc->format);
|
||||
if (formatSize == 0)
|
||||
return FALSE;
|
||||
|
||||
for (INT32 y = 1; y < nHeight; y++)
|
||||
{
|
||||
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
|
||||
if (!dstp)
|
||||
return FALSE;
|
||||
memcpy(dstp, srcp, 1ull * WINPR_ASSERTING_INT_CAST(size_t, nWidth) * formatSize);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GDI_BS_HATCHED:
|
||||
case GDI_BS_PATTERN:
|
||||
{
|
||||
const BOOL monochrome = (hbr->pattern->format == PIXEL_FORMAT_MONO);
|
||||
const UINT32 formatSize = FreeRDPGetBytesPerPixel(hbr->pattern->format);
|
||||
if (formatSize == 0)
|
||||
return FALSE;
|
||||
|
||||
for (INT32 y = 0; y < nHeight; y++)
|
||||
{
|
||||
for (INT32 x = 0; x < nWidth; x++)
|
||||
{
|
||||
const size_t yOffset =
|
||||
((1ULL * WINPR_ASSERTING_INT_CAST(size_t, nYDest) +
|
||||
WINPR_ASSERTING_INT_CAST(size_t, y)) *
|
||||
WINPR_ASSERTING_INT_CAST(size_t, hbr->pattern->width) %
|
||||
WINPR_ASSERTING_INT_CAST(size_t, hbr->pattern->height)) *
|
||||
formatSize;
|
||||
const size_t xOffset = ((1ULL * WINPR_ASSERTING_INT_CAST(size_t, nXDest) +
|
||||
WINPR_ASSERTING_INT_CAST(size_t, x)) %
|
||||
WINPR_ASSERTING_INT_CAST(size_t, hbr->pattern->width)) *
|
||||
formatSize;
|
||||
const BYTE* patp = &hbr->pattern->data[yOffset + xOffset];
|
||||
|
||||
UINT32 dstColor = 0;
|
||||
if (monochrome)
|
||||
{
|
||||
if (*patp == 0)
|
||||
dstColor = hdc->bkColor;
|
||||
else
|
||||
dstColor = hdc->textColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
const UINT32 tmp = FreeRDPReadColor(patp, hbr->pattern->format);
|
||||
dstColor =
|
||||
FreeRDPConvertColor(tmp, hbr->pattern->format, hdc->format, nullptr);
|
||||
}
|
||||
|
||||
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest + x, nYDest + y);
|
||||
if (dstp)
|
||||
FreeRDPWriteColor(dstp, hdc->format, dstColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return gdi_InvalidateRegion(hdc, nXDest, nYDest, nWidth, nHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a polygon
|
||||
* msdn{dd162814}
|
||||
* @param hdc device context
|
||||
* @param lpPoints array of points
|
||||
* @param nCount number of points
|
||||
* @return nonzero if successful, 0 otherwise
|
||||
*/
|
||||
BOOL gdi_Polygon(WINPR_ATTR_UNUSED HGDI_DC hdc, WINPR_ATTR_UNUSED GDI_POINT* lpPoints,
|
||||
WINPR_ATTR_UNUSED int nCount)
|
||||
{
|
||||
WLog_ERR(TAG, "Not implemented!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a series of closed polygons
|
||||
* msdn{dd162818}
|
||||
* @param hdc device context
|
||||
* @param lpPoints array of series of points
|
||||
* @param lpPolyCounts array of number of points in each series
|
||||
* @param nCount count of number of points in lpPolyCounts
|
||||
* @return nonzero if successful, 0 otherwise
|
||||
*/
|
||||
BOOL gdi_PolyPolygon(WINPR_ATTR_UNUSED HGDI_DC hdc, WINPR_ATTR_UNUSED GDI_POINT* lpPoints,
|
||||
WINPR_ATTR_UNUSED int* lpPolyCounts, WINPR_ATTR_UNUSED int nCount)
|
||||
{
|
||||
WLog_ERR(TAG, "Not implemented!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL gdi_Rectangle(HGDI_DC hdc, INT32 nXDst, INT32 nYDst, INT32 nWidth, INT32 nHeight)
|
||||
{
|
||||
UINT32 color = 0;
|
||||
|
||||
if (!gdi_ClipCoords(hdc, &nXDst, &nYDst, &nWidth, &nHeight, nullptr, nullptr))
|
||||
return TRUE;
|
||||
|
||||
color = hdc->textColor;
|
||||
|
||||
for (INT32 y = 0; y < nHeight; y++)
|
||||
{
|
||||
BYTE* dstLeft = gdi_get_bitmap_pointer(hdc, nXDst, nYDst + y);
|
||||
BYTE* dstRight = gdi_get_bitmap_pointer(hdc, nXDst + nWidth - 1, nYDst + y);
|
||||
|
||||
if (dstLeft)
|
||||
FreeRDPWriteColor(dstLeft, hdc->format, color);
|
||||
|
||||
if (dstRight)
|
||||
FreeRDPWriteColor(dstRight, hdc->format, color);
|
||||
}
|
||||
|
||||
for (INT32 x = 0; x < nWidth; x++)
|
||||
{
|
||||
BYTE* dstTop = gdi_get_bitmap_pointer(hdc, nXDst + x, nYDst);
|
||||
BYTE* dstBottom = gdi_get_bitmap_pointer(hdc, nXDst + x, nYDst + nHeight - 1);
|
||||
|
||||
if (dstTop)
|
||||
FreeRDPWriteColor(dstTop, hdc->format, color);
|
||||
|
||||
if (dstBottom)
|
||||
FreeRDPWriteColor(dstBottom, hdc->format, color);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
37
third_party/FreeRDP/libfreerdp/gdi/test/CMakeLists.txt
vendored
Normal file
37
third_party/FreeRDP/libfreerdp/gdi/test/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
set(MODULE_NAME "TestGdi")
|
||||
set(MODULE_PREFIX "TEST_GDI")
|
||||
|
||||
disable_warnings_for_directory(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
|
||||
|
||||
set(${MODULE_PREFIX}_TESTS
|
||||
TestGdiRop3.c
|
||||
# TestGdiLine.c # TODO: This test is broken
|
||||
TestGdiRegion.c
|
||||
TestGdiRect.c
|
||||
TestGdiBitBlt.c
|
||||
TestGdiCreate.c
|
||||
TestGdiEllipse.c
|
||||
TestGdiClip.c
|
||||
)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} ${${MODULE_PREFIX}_TESTS})
|
||||
|
||||
include_directories(..)
|
||||
|
||||
add_library(helpers STATIC helpers.c)
|
||||
target_link_libraries(helpers freerdp)
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} winpr freerdp helpers)
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
|
||||
|
||||
foreach(test ${${MODULE_PREFIX}_TESTS})
|
||||
get_filename_component(TestName ${test} NAME_WE)
|
||||
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
|
||||
endforeach()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/Test")
|
||||
577
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiBitBlt.c
vendored
Normal file
577
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiBitBlt.c
vendored
Normal file
@@ -0,0 +1,577 @@
|
||||
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/dc.h>
|
||||
#include <freerdp/gdi/pen.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include "line.h"
|
||||
#include "brush.h"
|
||||
#include "helpers.h"
|
||||
|
||||
/* BitBlt() Test Data */
|
||||
|
||||
/* source bitmap (16x16) */
|
||||
static const BYTE bmp_SRC[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
/* destination bitmap (16x16) */
|
||||
static const BYTE bmp_DST[256] = {
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
};
|
||||
|
||||
/* SRCCOPY (0x00CC0020) */
|
||||
static const BYTE bmp_SRCCOPY[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
/* BLACKNESS (0x00000042) */
|
||||
static const BYTE bmp_BLACKNESS[256] = {
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
};
|
||||
|
||||
/* WHITENESS (0x00FF0062) */
|
||||
static const BYTE bmp_WHITENESS[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
/* SRCAND (0x008800C6) */
|
||||
static const BYTE bmp_SRCAND[256] = {
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
};
|
||||
|
||||
/* SRCPAINT (0x00EE0086) */
|
||||
static const BYTE bmp_SRCPAINT[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
/* SRCINVERT (0x00660046) */
|
||||
static const BYTE bmp_SRCINVERT[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
/* SRCERASE (0x00440328) */
|
||||
static const BYTE bmp_SRCERASE[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
/* NOTSRCCOPY (0x00330008) */
|
||||
static const BYTE bmp_NOTSRCCOPY[256] = {
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00"
|
||||
"\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00"
|
||||
"\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
};
|
||||
|
||||
/* NOTSRCERASE (0x001100A6) */
|
||||
static const BYTE bmp_NOTSRCERASE[256] = {
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
};
|
||||
|
||||
/* DSTINVERT (0x00550009) */
|
||||
static const BYTE bmp_DSTINVERT[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
/* SPna (0x000C0324) */
|
||||
static const BYTE bmp_SPna[256] = {
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
};
|
||||
|
||||
/* MERGEPAINT (0x00BB0226) */
|
||||
static const BYTE bmp_MERGEPAINT[256] = {
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
};
|
||||
|
||||
/* MERGECOPY (0x00C000CA) */
|
||||
static const BYTE bmp_MERGECOPY[256] = {
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
};
|
||||
|
||||
/* PATPAINT (0x00FB0A09) */
|
||||
static const BYTE bmp_PATPAINT[256] = {
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
};
|
||||
|
||||
/* PATCOPY (0x00F00021) */
|
||||
static const BYTE bmp_PATCOPY[256] = {
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
};
|
||||
|
||||
/* PATINVERT (0x005A0049) */
|
||||
static const BYTE bmp_PATINVERT[256] = {
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
|
||||
};
|
||||
|
||||
struct test_bitblt
|
||||
{
|
||||
UINT32 rop;
|
||||
const BYTE* src;
|
||||
HGDI_BITMAP bmp;
|
||||
};
|
||||
|
||||
static BOOL test_rop(HGDI_DC hdcDst, HGDI_DC hdcSrc, HGDI_BITMAP hBmpSrc, HGDI_BITMAP hBmpDst,
|
||||
HGDI_BITMAP hBmpDstOriginal, UINT32 rop, HGDI_BITMAP expected,
|
||||
const gdiPalette* hPalette)
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
|
||||
/* restore original destination bitmap */
|
||||
gdi_SelectObject(hdcSrc, (HGDIOBJECT)hBmpDstOriginal);
|
||||
gdi_SelectObject(hdcDst, (HGDIOBJECT)hBmpDst);
|
||||
|
||||
if (!gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY, hPalette))
|
||||
goto fail;
|
||||
|
||||
if (!test_assert_bitmaps_equal(hBmpDst, hBmpDstOriginal, gdi_rop_to_string(GDI_SRCCOPY),
|
||||
hPalette))
|
||||
goto fail;
|
||||
|
||||
gdi_SelectObject(hdcSrc, (HGDIOBJECT)hBmpSrc);
|
||||
if (!gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, rop, hPalette))
|
||||
goto fail;
|
||||
|
||||
if (!test_assert_bitmaps_equal(hBmpDst, expected, gdi_rop_to_string(rop), hPalette))
|
||||
goto fail;
|
||||
|
||||
success = TRUE;
|
||||
fail:
|
||||
(void)fprintf(stderr, "[%s] ROP=%s returned %d\n", __func__, gdi_rop_to_string(rop), success);
|
||||
return success;
|
||||
}
|
||||
|
||||
static BOOL test_gdi_BitBlt(UINT32 SrcFormat, UINT32 DstFormat)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
BOOL failed = FALSE;
|
||||
HGDI_DC hdcSrc = nullptr;
|
||||
HGDI_DC hdcDst = nullptr;
|
||||
const UINT32 RawFormat = PIXEL_FORMAT_RGB8;
|
||||
struct test_bitblt tests[] = { { GDI_SRCCOPY, bmp_SRCCOPY, nullptr },
|
||||
{ GDI_SPna, bmp_SPna, nullptr },
|
||||
{ GDI_BLACKNESS, bmp_BLACKNESS, nullptr },
|
||||
{ GDI_WHITENESS, bmp_WHITENESS, nullptr },
|
||||
{ GDI_SRCAND, bmp_SRCAND, nullptr },
|
||||
{ GDI_SRCPAINT, bmp_SRCPAINT, nullptr },
|
||||
{ GDI_SRCINVERT, bmp_SRCINVERT, nullptr },
|
||||
{ GDI_SRCERASE, bmp_SRCERASE, nullptr },
|
||||
{ GDI_NOTSRCCOPY, bmp_NOTSRCCOPY, nullptr },
|
||||
{ GDI_NOTSRCERASE, bmp_NOTSRCERASE, nullptr },
|
||||
{ GDI_DSTINVERT, bmp_DSTINVERT, nullptr },
|
||||
{ GDI_MERGECOPY, bmp_MERGECOPY, nullptr },
|
||||
{ GDI_MERGEPAINT, bmp_MERGEPAINT, nullptr },
|
||||
{ GDI_PATCOPY, bmp_PATCOPY, nullptr },
|
||||
{ GDI_PATPAINT, bmp_PATPAINT, nullptr },
|
||||
{ GDI_PATINVERT, bmp_PATINVERT, nullptr },
|
||||
{ GDI_DSTINVERT, bmp_SRC, nullptr },
|
||||
{ GDI_DSPDxax, bmp_SRC, nullptr },
|
||||
{ GDI_PSDPxax, bmp_SRC, nullptr },
|
||||
{ GDI_DSna, bmp_SRC, nullptr },
|
||||
{ GDI_DPa, bmp_SRC, nullptr },
|
||||
{ GDI_PDxn, bmp_SRC, nullptr },
|
||||
{ GDI_DSxn, bmp_SRC, nullptr },
|
||||
{ GDI_PSDnox, bmp_SRC, nullptr },
|
||||
{ GDI_PDSona, bmp_SRC, nullptr },
|
||||
{ GDI_DSPDxox, bmp_SRC, nullptr },
|
||||
{ GDI_DPSDonox, bmp_SRC, nullptr },
|
||||
{ GDI_SPDSxax, bmp_SRC, nullptr },
|
||||
{ GDI_DPon, bmp_SRC, nullptr },
|
||||
{ GDI_DPna, bmp_SRC, nullptr },
|
||||
{ GDI_Pn, bmp_SRC, nullptr },
|
||||
{ GDI_PDna, bmp_SRC, nullptr },
|
||||
{ GDI_DPan, bmp_SRC, nullptr },
|
||||
{ GDI_DSan, bmp_SRC, nullptr },
|
||||
{ GDI_DSxn, bmp_SRC, nullptr },
|
||||
{ GDI_DPa, bmp_SRC, nullptr },
|
||||
{ GDI_DSTCOPY, bmp_SRC, nullptr },
|
||||
{ GDI_DPno, bmp_SRC, nullptr },
|
||||
{ GDI_SDno, bmp_SRC, nullptr },
|
||||
{ GDI_PDno, bmp_SRC, nullptr },
|
||||
{ GDI_DPo, bmp_SRC, nullptr } };
|
||||
const UINT32 number_tests = sizeof(tests) / sizeof(tests[0]);
|
||||
HGDI_BITMAP hBmpSrc = nullptr;
|
||||
HGDI_BITMAP hBmpDst = nullptr;
|
||||
HGDI_BITMAP hBmpDstOriginal = nullptr;
|
||||
HGDI_BRUSH brush = nullptr;
|
||||
gdiPalette g;
|
||||
gdiPalette* hPalette = &g;
|
||||
g.format = DstFormat;
|
||||
|
||||
for (UINT32 x = 0; x < 256; x++)
|
||||
g.palette[x] = FreeRDPGetColor(DstFormat, x, x, x, 0xFF);
|
||||
|
||||
if (!(hdcSrc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hdcSrc->format = SrcFormat;
|
||||
|
||||
if (!(hdcDst = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hdcDst->format = DstFormat;
|
||||
hBmpSrc =
|
||||
test_convert_to_bitmap(bmp_SRC, RawFormat, 0, 0, 0, SrcFormat, 0, 0, 0, 16, 16, hPalette);
|
||||
|
||||
if (!hBmpSrc)
|
||||
goto fail;
|
||||
|
||||
hBmpDst =
|
||||
test_convert_to_bitmap(bmp_DST, RawFormat, 0, 0, 0, DstFormat, 0, 0, 0, 16, 16, hPalette);
|
||||
|
||||
if (!hBmpDst)
|
||||
goto fail;
|
||||
|
||||
hBmpDstOriginal =
|
||||
test_convert_to_bitmap(bmp_DST, RawFormat, 0, 0, 0, SrcFormat, 0, 0, 0, 16, 16, hPalette);
|
||||
|
||||
if (!hBmpDstOriginal)
|
||||
goto fail;
|
||||
|
||||
for (size_t x = 0; x < ARRAYSIZE(tests); x++)
|
||||
{
|
||||
struct test_bitblt* test = &tests[x];
|
||||
test->bmp = test_convert_to_bitmap(test->src, RawFormat, 0, 0, 0, SrcFormat, 0, 0, 0, 16,
|
||||
16, hPalette);
|
||||
|
||||
if (!test->bmp)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
brush = gdi_CreateSolidBrush(0x123456);
|
||||
gdi_SelectObject(hdcDst, (HGDIOBJECT)brush);
|
||||
|
||||
for (size_t x = 0; x < ARRAYSIZE(tests); x++)
|
||||
{
|
||||
struct test_bitblt* test = &tests[x];
|
||||
|
||||
if (!test_rop(hdcDst, hdcSrc, hBmpSrc, hBmpDst, hBmpDstOriginal, test->rop, test->bmp,
|
||||
hPalette))
|
||||
failed = TRUE;
|
||||
}
|
||||
|
||||
gdi_SelectObject(hdcDst, nullptr);
|
||||
gdi_DeleteObject((HGDIOBJECT)brush);
|
||||
rc = !failed;
|
||||
fail:
|
||||
|
||||
for (size_t x = 0; x < ARRAYSIZE(tests); x++)
|
||||
{
|
||||
struct test_bitblt* test = &tests[x];
|
||||
gdi_DeleteObject((HGDIOBJECT)test->bmp);
|
||||
}
|
||||
|
||||
gdi_DeleteObject((HGDIOBJECT)hBmpSrc);
|
||||
gdi_DeleteObject((HGDIOBJECT)hBmpDst);
|
||||
gdi_DeleteObject((HGDIOBJECT)hBmpDstOriginal);
|
||||
gdi_DeleteDC(hdcSrc);
|
||||
gdi_DeleteDC(hdcDst);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int TestGdiBitBlt(int argc, char* argv[])
|
||||
{
|
||||
int rc = 0;
|
||||
const UINT32 formatList[] = { PIXEL_FORMAT_RGB8, PIXEL_FORMAT_RGB15, PIXEL_FORMAT_ARGB15,
|
||||
PIXEL_FORMAT_RGB16, PIXEL_FORMAT_RGB24, PIXEL_FORMAT_RGBA32,
|
||||
PIXEL_FORMAT_RGBX32, PIXEL_FORMAT_ARGB32, PIXEL_FORMAT_XRGB32,
|
||||
PIXEL_FORMAT_BGR15, PIXEL_FORMAT_ABGR15, PIXEL_FORMAT_BGR16,
|
||||
PIXEL_FORMAT_BGR24, PIXEL_FORMAT_BGRA32, PIXEL_FORMAT_BGRX32,
|
||||
PIXEL_FORMAT_ABGR32, PIXEL_FORMAT_XBGR32 };
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
for (size_t x = 0; x < ARRAYSIZE(formatList); x++)
|
||||
{
|
||||
/* Skip 8bpp, only supported on remote end. */
|
||||
for (size_t y = 1; y < ARRAYSIZE(formatList); y++)
|
||||
{
|
||||
if (!test_gdi_BitBlt(formatList[x], formatList[y]))
|
||||
{
|
||||
(void)fprintf(stderr, "test_gdi_BitBlt(SrcFormat=%s, DstFormat=%s) failed!\n",
|
||||
FreeRDPGetColorFormatName(formatList[x]),
|
||||
FreeRDPGetColorFormatName(formatList[y]));
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
364
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiClip.c
vendored
Normal file
364
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiClip.c
vendored
Normal file
@@ -0,0 +1,364 @@
|
||||
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/dc.h>
|
||||
#include <freerdp/gdi/pen.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include "line.h"
|
||||
#include "brush.h"
|
||||
#include "clipping.h"
|
||||
|
||||
static bool test_gdi_coords(size_t testNr, HGDI_DC hdc, const GDI_RGN* clip, const GDI_RGN* input,
|
||||
const GDI_RGN* expect)
|
||||
{
|
||||
bool rc = false;
|
||||
|
||||
WINPR_ASSERT(hdc);
|
||||
WINPR_ASSERT(input);
|
||||
|
||||
HGDI_RGN rgn1 = gdi_CreateRectRgn(0, 0, 0, 0);
|
||||
HGDI_RGN rgn2 = gdi_CreateRectRgn(0, 0, 0, 0);
|
||||
if (!rgn1 || !rgn2)
|
||||
{
|
||||
(void)fprintf(stderr, "[%s:%" PRIuz "] gdi_CreateRectRgn failed: rgn1=%p, rgn2=%p\n",
|
||||
__func__, testNr, rgn1, rgn2);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!clip)
|
||||
{
|
||||
if (!gdi_SetNullClipRgn(hdc))
|
||||
{
|
||||
(void)fprintf(stderr, "[%s:%" PRIuz "] gdi_SetNullClipRgn failed\n", __func__, testNr);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else if (!gdi_SetClipRgn(hdc, clip->x, clip->y, clip->w, clip->h))
|
||||
{
|
||||
(void)fprintf(stderr, "[%s:%" PRIuz "] gdi_SetClipRgn failed\n", __func__, testNr);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!gdi_SetRgn(rgn1, input->x, input->y, input->w, input->h))
|
||||
{
|
||||
(void)fprintf(stderr, "[%s:%" PRIuz "] gdi_SetRgn (rgn1) failed\n", __func__, testNr);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (expect)
|
||||
{
|
||||
if (!gdi_SetRgn(rgn2, expect->x, expect->y, expect->w, expect->h))
|
||||
{
|
||||
(void)fprintf(stderr, "[%s:%" PRIuz "] gdi_SetRgn (rgn2) failed\n", __func__, testNr);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
const BOOL draw =
|
||||
gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), nullptr, nullptr);
|
||||
if (expect)
|
||||
{
|
||||
if (!draw)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"[%s:%" PRIuz "] gdi_ClipCoords failed: expected TRUE, got FALSE\n",
|
||||
__func__, testNr);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!gdi_EqualRgn(rgn1, rgn2))
|
||||
{
|
||||
char buffer1[64] = WINPR_C_ARRAY_INIT;
|
||||
char buffer2[64] = WINPR_C_ARRAY_INIT;
|
||||
(void)fprintf(stderr, "[%s:%" PRIuz "] gdi_EqualRgn failed: expected %s, got %s\n",
|
||||
__func__, testNr, buffer1, buffer2);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (draw)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"[%s:%" PRIuz "] gdi_ClipCoords failed: expected FALSE, got TRUE\n",
|
||||
__func__, testNr);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
rc = true;
|
||||
|
||||
fail:
|
||||
gdi_DeleteObject((HGDIOBJECT)rgn1);
|
||||
gdi_DeleteObject((HGDIOBJECT)rgn2);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_ClipCoords(void)
|
||||
{
|
||||
int rc = -1;
|
||||
HGDI_DC hdc = nullptr;
|
||||
HGDI_BITMAP bmp = nullptr;
|
||||
const UINT32 format = PIXEL_FORMAT_ARGB32;
|
||||
|
||||
if (!(hdc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdc->format = format;
|
||||
bmp = gdi_CreateBitmapEx(1024, 768, PIXEL_FORMAT_XRGB32, 0, nullptr, nullptr);
|
||||
gdi_SelectObject(hdc, (HGDIOBJECT)bmp);
|
||||
gdi_SetNullClipRgn(hdc);
|
||||
|
||||
struct testcase_t
|
||||
{
|
||||
const GDI_RGN* clip;
|
||||
const GDI_RGN* in;
|
||||
const GDI_RGN* expect;
|
||||
};
|
||||
|
||||
const GDI_RGN rgn0x0_1024x768 = { 0, 0, 0, 1024, 768, FALSE };
|
||||
const GDI_RGN rgn20x20_100x100 = { 0, 20, 20, 100, 100, FALSE };
|
||||
const GDI_RGN rgn100x300_250x100 = { 0, 100, 300, 250, 100, FALSE };
|
||||
const GDI_RGN rgn100x300_300x100 = { 0, 100, 300, 300, 100, FALSE };
|
||||
const GDI_RGN rgn300x20_100x100 = { 0, 300, 20, 100, 100, FALSE };
|
||||
const GDI_RGN rgn300x100_300x300 = { 0, 300, 100, 300, 300, FALSE };
|
||||
const GDI_RGN rgn300x300_50x100 = { 0, 300, 300, 50, 100, FALSE };
|
||||
const GDI_RGN rgn300x300_100x100 = { 0, 300, 300, 100, 100, FALSE };
|
||||
const GDI_RGN rgn300x300_300x100 = { 0, 300, 300, 300, 100, FALSE };
|
||||
const GDI_RGN rgn300x300_300x200 = { 0, 300, 300, 100, 200, FALSE };
|
||||
const GDI_RGN rgn300x420_100x100 = { 0, 300, 420, 100, 100, FALSE };
|
||||
const GDI_RGN rgn350x300_50x100 = { 0, 350, 300, 50, 100, FALSE };
|
||||
const GDI_RGN rgn350x300_200x100 = { 0, 350, 300, 200, 100, FALSE };
|
||||
const GDI_RGN rgn420x420_100x100 = { 0, 420, 420, 100, 100, FALSE };
|
||||
|
||||
const struct testcase_t testcases[] = {
|
||||
/* null clipping region */
|
||||
{ nullptr, &rgn20x20_100x100, &rgn20x20_100x100 },
|
||||
/* region all inside clipping region */
|
||||
{ &rgn0x0_1024x768, &rgn20x20_100x100, &rgn20x20_100x100 },
|
||||
/* region all outside clipping region, on the left */
|
||||
{ &rgn300x300_100x100, &rgn20x20_100x100, nullptr },
|
||||
/* region all outside clipping region, on the right */
|
||||
{ &rgn300x300_100x100, &rgn420x420_100x100, nullptr },
|
||||
/* region all outside clipping region, on top */
|
||||
{ &rgn300x300_100x100, &rgn300x20_100x100, nullptr },
|
||||
/* region all outside clipping region, at the bottom */
|
||||
{ &rgn300x300_100x100, &rgn300x420_100x100, nullptr },
|
||||
/* left outside, right = clip, top = clip, bottom = clip */
|
||||
{ &rgn300x300_100x100, &rgn100x300_300x100, &rgn300x300_100x100 },
|
||||
/* left outside, right inside, top = clip, bottom = clip */
|
||||
{ &rgn300x300_100x100, &rgn100x300_250x100, &rgn300x300_50x100 },
|
||||
/* left = clip, right outside, top = clip, bottom = clip */
|
||||
{ &rgn300x300_100x100, &rgn300x300_300x100, &rgn300x300_100x100 },
|
||||
/* left inside, right outside, top = clip, bottom = clip */
|
||||
{ &rgn300x300_100x100, &rgn350x300_200x100, &rgn350x300_50x100 },
|
||||
/* top outside, bottom = clip, left = clip, right = clip */
|
||||
{ &rgn300x300_100x100, &rgn300x100_300x300, &rgn300x300_100x100 },
|
||||
/* top = clip, bottom outside, left = clip, right = clip */
|
||||
{ &rgn300x300_100x100, &rgn300x300_300x200, &rgn300x300_100x100 },
|
||||
/* top = clip, bottom = clip, top = clip, bottom = clip */
|
||||
{ &rgn300x300_100x100, &rgn300x300_100x100, &rgn300x300_100x100 }
|
||||
};
|
||||
|
||||
for (size_t x = 0; x < ARRAYSIZE(testcases); x++)
|
||||
{
|
||||
const struct testcase_t* cur = &testcases[x];
|
||||
if (!test_gdi_coords(x, hdc, cur->clip, cur->in, cur->expect))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
gdi_DeleteObject((HGDIOBJECT)bmp);
|
||||
gdi_DeleteDC(hdc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_InvalidateRegion(void)
|
||||
{
|
||||
int rc = -1;
|
||||
HGDI_DC hdc = nullptr;
|
||||
HGDI_RGN rgn1 = nullptr;
|
||||
HGDI_RGN rgn2 = nullptr;
|
||||
HGDI_RGN invalid = nullptr;
|
||||
HGDI_BITMAP bmp = nullptr;
|
||||
const UINT32 format = PIXEL_FORMAT_XRGB32;
|
||||
|
||||
if (!(hdc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdc->format = format;
|
||||
bmp = gdi_CreateBitmapEx(1024, 768, PIXEL_FORMAT_XRGB32, 0, nullptr, nullptr);
|
||||
gdi_SelectObject(hdc, (HGDIOBJECT)bmp);
|
||||
gdi_SetNullClipRgn(hdc);
|
||||
hdc->hwnd = (HGDI_WND)calloc(1, sizeof(GDI_WND));
|
||||
hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0);
|
||||
hdc->hwnd->invalid->null = TRUE;
|
||||
invalid = hdc->hwnd->invalid;
|
||||
hdc->hwnd->count = 16;
|
||||
hdc->hwnd->cinvalid = (HGDI_RGN)calloc(hdc->hwnd->count, sizeof(GDI_RGN));
|
||||
rgn1 = gdi_CreateRectRgn(0, 0, 0, 0);
|
||||
rgn2 = gdi_CreateRectRgn(0, 0, 0, 0);
|
||||
rgn1->null = TRUE;
|
||||
rgn2->null = TRUE;
|
||||
/* no previous invalid region */
|
||||
invalid->null = TRUE;
|
||||
gdi_SetRgn(rgn1, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn2, 300, 300, 100, 100);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* region same as invalid region */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn2, 300, 300, 100, 100);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* left outside */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 100, 300, 300, 100);
|
||||
gdi_SetRgn(rgn2, 100, 300, 300, 100);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* right outside */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 300, 300, 300, 100);
|
||||
gdi_SetRgn(rgn2, 300, 300, 300, 100);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* top outside */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 300, 100, 100, 300);
|
||||
gdi_SetRgn(rgn2, 300, 100, 100, 300);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* bottom outside */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 300, 300, 100, 300);
|
||||
gdi_SetRgn(rgn2, 300, 300, 100, 300);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* left outside, right outside */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 100, 300, 600, 300);
|
||||
gdi_SetRgn(rgn2, 100, 300, 600, 300);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* top outside, bottom outside */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 300, 100, 100, 500);
|
||||
gdi_SetRgn(rgn2, 300, 100, 100, 500);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* all outside, left */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 100, 300, 100, 100);
|
||||
gdi_SetRgn(rgn2, 100, 300, 300, 100);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* all outside, right */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 700, 300, 100, 100);
|
||||
gdi_SetRgn(rgn2, 300, 300, 500, 100);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* all outside, top */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 300, 100, 100, 100);
|
||||
gdi_SetRgn(rgn2, 300, 100, 100, 300);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* all outside, bottom */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 300, 500, 100, 100);
|
||||
gdi_SetRgn(rgn2, 300, 300, 100, 300);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* all outside */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 100, 100, 600, 600);
|
||||
gdi_SetRgn(rgn2, 100, 100, 600, 600);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
/* everything */
|
||||
gdi_SetRgn(invalid, 300, 300, 100, 100);
|
||||
gdi_SetRgn(rgn1, 0, 0, 1024, 768);
|
||||
gdi_SetRgn(rgn2, 0, 0, 1024, 768);
|
||||
gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
|
||||
|
||||
if (!gdi_EqualRgn(invalid, rgn2))
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
gdi_DeleteObject((HGDIOBJECT)rgn1);
|
||||
gdi_DeleteObject((HGDIOBJECT)rgn2);
|
||||
gdi_DeleteObject((HGDIOBJECT)bmp);
|
||||
gdi_DeleteDC(hdc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int TestGdiClip(int argc, char* argv[])
|
||||
{
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
(void)fprintf(stderr, "test_gdi_ClipCoords()\n");
|
||||
|
||||
if (test_gdi_ClipCoords() < 0)
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_InvalidateRegion()\n");
|
||||
|
||||
if (test_gdi_InvalidateRegion() < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
600
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiCreate.c
vendored
Normal file
600
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiCreate.c
vendored
Normal file
@@ -0,0 +1,600 @@
|
||||
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/dc.h>
|
||||
#include <freerdp/gdi/pen.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/crypto.h>
|
||||
|
||||
#include "line.h"
|
||||
#include "brush.h"
|
||||
#include "drawing.h"
|
||||
|
||||
static const UINT32 colorFormatList[] = {
|
||||
PIXEL_FORMAT_RGB15, PIXEL_FORMAT_BGR15, PIXEL_FORMAT_RGB16, PIXEL_FORMAT_BGR16,
|
||||
PIXEL_FORMAT_RGB24, PIXEL_FORMAT_BGR24, PIXEL_FORMAT_ARGB32, PIXEL_FORMAT_ABGR32,
|
||||
PIXEL_FORMAT_XRGB32, PIXEL_FORMAT_XBGR32, PIXEL_FORMAT_RGBX32, PIXEL_FORMAT_BGRX32
|
||||
|
||||
};
|
||||
static const UINT32 colorFormatCount = sizeof(colorFormatList) / sizeof(colorFormatList[0]);
|
||||
|
||||
static int test_gdi_GetDC(void)
|
||||
{
|
||||
int rc = -1;
|
||||
HGDI_DC hdc = nullptr;
|
||||
|
||||
if (!(hdc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hdc->format != PIXEL_FORMAT_XRGB32)
|
||||
goto fail;
|
||||
|
||||
if (hdc->drawMode != GDI_R2_BLACK)
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
gdi_DeleteDC(hdc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_CreateCompatibleDC(void)
|
||||
{
|
||||
int rc = -1;
|
||||
HGDI_DC hdc = nullptr;
|
||||
HGDI_DC chdc = nullptr;
|
||||
|
||||
if (!(hdc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdc->format = PIXEL_FORMAT_RGB16;
|
||||
hdc->drawMode = GDI_R2_XORPEN;
|
||||
|
||||
if (!(chdc = gdi_CreateCompatibleDC(hdc)))
|
||||
{
|
||||
printf("gdi_CreateCompatibleDC failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (chdc->format != hdc->format)
|
||||
goto fail;
|
||||
|
||||
if (chdc->drawMode != hdc->drawMode)
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
|
||||
if (chdc)
|
||||
gdi_DeleteDC(chdc);
|
||||
|
||||
gdi_DeleteDC(hdc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_CreateBitmap(void)
|
||||
{
|
||||
int rc = -1;
|
||||
UINT32 format = PIXEL_FORMAT_ARGB32;
|
||||
INT32 width = 0;
|
||||
INT32 height = 0;
|
||||
BYTE* data = nullptr;
|
||||
HGDI_BITMAP hBitmap = nullptr;
|
||||
width = 32;
|
||||
height = 16;
|
||||
|
||||
if (!(data = (BYTE*)winpr_aligned_malloc(4ULL * width * height, 16)))
|
||||
{
|
||||
printf("failed to allocate aligned bitmap data memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(hBitmap = gdi_CreateBitmap(width, height, format, data)))
|
||||
{
|
||||
printf("gdi_CreateBitmap failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (hBitmap->objectType != GDIOBJECT_BITMAP)
|
||||
goto fail;
|
||||
|
||||
if (hBitmap->format != format)
|
||||
goto fail;
|
||||
|
||||
if (hBitmap->width != width)
|
||||
goto fail;
|
||||
|
||||
if (hBitmap->height != height)
|
||||
goto fail;
|
||||
|
||||
if (hBitmap->data != data)
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
|
||||
if (hBitmap)
|
||||
gdi_DeleteObject((HGDIOBJECT)hBitmap);
|
||||
else
|
||||
winpr_aligned_free(data);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_CreateCompatibleBitmap(void)
|
||||
{
|
||||
int rc = -1;
|
||||
HGDI_DC hdc = nullptr;
|
||||
INT32 width = 0;
|
||||
INT32 height = 0;
|
||||
HGDI_BITMAP hBitmap = nullptr;
|
||||
|
||||
if (!(hdc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdc->format = PIXEL_FORMAT_ARGB32;
|
||||
width = 32;
|
||||
height = 16;
|
||||
hBitmap = gdi_CreateCompatibleBitmap(hdc, width, height);
|
||||
|
||||
if (hBitmap->objectType != GDIOBJECT_BITMAP)
|
||||
goto fail;
|
||||
|
||||
if (hBitmap->format != hdc->format)
|
||||
goto fail;
|
||||
|
||||
if (hBitmap->width != width)
|
||||
goto fail;
|
||||
|
||||
if (hBitmap->height != height)
|
||||
goto fail;
|
||||
|
||||
if (!hBitmap->data)
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
|
||||
if (hBitmap)
|
||||
gdi_DeleteObject((HGDIOBJECT)hBitmap);
|
||||
|
||||
gdi_DeleteDC(hdc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_CreatePen(void)
|
||||
{
|
||||
int rc = -1;
|
||||
const UINT32 format = PIXEL_FORMAT_RGBA32;
|
||||
HGDI_PEN hPen = gdi_CreatePen(GDI_PS_SOLID, 8, 0xAABBCCDD, format, nullptr);
|
||||
|
||||
if (!hPen)
|
||||
{
|
||||
printf("gdi_CreatePen failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hPen->style != GDI_PS_SOLID)
|
||||
goto fail;
|
||||
|
||||
if (hPen->width != 8)
|
||||
goto fail;
|
||||
|
||||
if (hPen->color != 0xAABBCCDD)
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
gdi_DeleteObject((HGDIOBJECT)hPen);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_CreateSolidBrush(void)
|
||||
{
|
||||
int rc = -1;
|
||||
HGDI_BRUSH hBrush = gdi_CreateSolidBrush(0xAABBCCDD);
|
||||
|
||||
if (hBrush->objectType != GDIOBJECT_BRUSH)
|
||||
goto fail;
|
||||
|
||||
if (hBrush->style != GDI_BS_SOLID)
|
||||
goto fail;
|
||||
|
||||
if (hBrush->color != 0xAABBCCDD)
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
gdi_DeleteObject((HGDIOBJECT)hBrush);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_CreatePatternBrush(void)
|
||||
{
|
||||
int rc = -1;
|
||||
HGDI_BRUSH hBrush = nullptr;
|
||||
HGDI_BITMAP hBitmap = nullptr;
|
||||
hBitmap = gdi_CreateBitmap(64, 64, 32, nullptr);
|
||||
hBrush = gdi_CreatePatternBrush(hBitmap);
|
||||
|
||||
if (!hBitmap || !hBrush)
|
||||
goto fail;
|
||||
|
||||
if (hBrush->objectType != GDIOBJECT_BRUSH)
|
||||
goto fail;
|
||||
|
||||
if (hBrush->style != GDI_BS_PATTERN)
|
||||
goto fail;
|
||||
|
||||
if (hBrush->pattern != hBitmap)
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
|
||||
if (hBitmap)
|
||||
gdi_DeleteObject((HGDIOBJECT)hBitmap);
|
||||
|
||||
if (hBrush)
|
||||
gdi_DeleteObject((HGDIOBJECT)hBrush);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_CreateRectRgn(void)
|
||||
{
|
||||
int rc = -1;
|
||||
INT32 x1 = 32;
|
||||
INT32 y1 = 64;
|
||||
INT32 x2 = 128;
|
||||
INT32 y2 = 256;
|
||||
HGDI_RGN hRegion = gdi_CreateRectRgn(x1, y1, x2, y2);
|
||||
|
||||
if (!hRegion)
|
||||
return rc;
|
||||
|
||||
if (hRegion->objectType != GDIOBJECT_REGION)
|
||||
goto fail;
|
||||
|
||||
if (hRegion->x != x1)
|
||||
goto fail;
|
||||
|
||||
if (hRegion->y != y1)
|
||||
goto fail;
|
||||
|
||||
if (hRegion->w != x2 - x1 + 1)
|
||||
goto fail;
|
||||
|
||||
if (hRegion->h != y2 - y1 + 1)
|
||||
goto fail;
|
||||
|
||||
if (hRegion->null)
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
gdi_DeleteObject((HGDIOBJECT)hRegion);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_CreateRect(void)
|
||||
{
|
||||
int rc = -1;
|
||||
GDI_RECT* hRect = nullptr;
|
||||
INT32 x1 = 32;
|
||||
INT32 y1 = 64;
|
||||
INT32 x2 = 128;
|
||||
INT32 y2 = 256;
|
||||
|
||||
if (!(hRect = gdi_CreateRect(x1, y1, x2, y2)))
|
||||
{
|
||||
printf("gdi_CreateRect failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hRect->objectType != GDIOBJECT_RECT)
|
||||
goto fail;
|
||||
|
||||
if (hRect->left != x1)
|
||||
goto fail;
|
||||
|
||||
if (hRect->top != y1)
|
||||
goto fail;
|
||||
|
||||
if (hRect->right != x2)
|
||||
goto fail;
|
||||
|
||||
if (hRect->bottom != y2)
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
gdi_DeleteObject((HGDIOBJECT)hRect);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static BYTE prand(void)
|
||||
{
|
||||
BYTE tmp = 0;
|
||||
if (winpr_RAND(&tmp, sizeof(tmp)) < 0)
|
||||
{
|
||||
(void)fprintf(stderr, "winpr_RAND faild,retry...\n");
|
||||
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
||||
exit(-1);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static BOOL test_gdi_GetPixel(void)
|
||||
{
|
||||
BOOL rc = TRUE;
|
||||
|
||||
for (UINT32 x = 0; x < colorFormatCount; x++)
|
||||
{
|
||||
UINT32 bpp = 0;
|
||||
HGDI_DC hdc = nullptr;
|
||||
UINT32 width = 128;
|
||||
UINT32 height = 64;
|
||||
HGDI_BITMAP hBitmap = nullptr;
|
||||
|
||||
if (!(hdc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdc->format = colorFormatList[x];
|
||||
hBitmap = gdi_CreateCompatibleBitmap(hdc, width, height);
|
||||
|
||||
if (!hBitmap)
|
||||
{
|
||||
gdi_DeleteDC(hdc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
gdi_SelectObject(hdc, (HGDIOBJECT)hBitmap);
|
||||
bpp = FreeRDPGetBytesPerPixel(hBitmap->format);
|
||||
|
||||
for (UINT32 i = 0; i < height; i++)
|
||||
{
|
||||
for (UINT32 j = 0; j < width; j++)
|
||||
{
|
||||
UINT32 pixel = 0;
|
||||
const UINT32 color =
|
||||
FreeRDPGetColor(hBitmap->format, prand(), prand(), prand(), prand());
|
||||
FreeRDPWriteColor(&hBitmap->data[i * hBitmap->scanline + j * bpp], hBitmap->format,
|
||||
color);
|
||||
pixel = gdi_GetPixel(hdc, j, i);
|
||||
|
||||
if (pixel != color)
|
||||
{
|
||||
rc = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
break;
|
||||
}
|
||||
|
||||
gdi_DeleteObject((HGDIOBJECT)hBitmap);
|
||||
gdi_DeleteDC(hdc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static BOOL test_gdi_SetPixel(void)
|
||||
{
|
||||
BOOL rc = TRUE;
|
||||
|
||||
for (UINT32 x = 0; x < colorFormatCount; x++)
|
||||
{
|
||||
UINT32 bpp = 0;
|
||||
HGDI_DC hdc = nullptr;
|
||||
UINT32 width = 128;
|
||||
UINT32 height = 64;
|
||||
HGDI_BITMAP hBitmap = nullptr;
|
||||
|
||||
if (!(hdc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hdc->format = colorFormatList[x];
|
||||
hBitmap = gdi_CreateCompatibleBitmap(hdc, width, height);
|
||||
gdi_SelectObject(hdc, (HGDIOBJECT)hBitmap);
|
||||
bpp = FreeRDPGetBytesPerPixel(hBitmap->format);
|
||||
|
||||
for (UINT32 i = 0; i < height; i++)
|
||||
{
|
||||
for (UINT32 j = 0; j < width; j++)
|
||||
{
|
||||
UINT32 pixel = 0;
|
||||
const UINT32 color =
|
||||
FreeRDPGetColor(hBitmap->format, prand(), prand(), prand(), prand());
|
||||
gdi_SetPixel(hdc, j, i, color);
|
||||
pixel = FreeRDPReadColor(&hBitmap->data[i * hBitmap->scanline + j * bpp],
|
||||
hBitmap->format);
|
||||
|
||||
if (pixel != color)
|
||||
{
|
||||
rc = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
break;
|
||||
}
|
||||
|
||||
gdi_DeleteObject((HGDIOBJECT)hBitmap);
|
||||
gdi_DeleteDC(hdc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_SetROP2(void)
|
||||
{
|
||||
int rc = -1;
|
||||
HGDI_DC hdc = nullptr;
|
||||
|
||||
if (!(hdc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gdi_SetROP2(hdc, GDI_R2_BLACK);
|
||||
|
||||
if (hdc->drawMode != GDI_R2_BLACK)
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
gdi_DeleteDC(hdc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_MoveToEx(void)
|
||||
{
|
||||
int rc = -1;
|
||||
HGDI_DC hdc = nullptr;
|
||||
HGDI_PEN hPen = nullptr;
|
||||
HGDI_POINT prevPoint = nullptr;
|
||||
const UINT32 format = PIXEL_FORMAT_RGBA32;
|
||||
gdiPalette* palette = nullptr;
|
||||
|
||||
if (!(hdc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(hPen = gdi_CreatePen(GDI_PS_SOLID, 8, 0xAABBCCDD, format, palette)))
|
||||
{
|
||||
printf("gdi_CreatePen failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
gdi_SelectObject(hdc, (HGDIOBJECT)hPen);
|
||||
gdi_MoveToEx(hdc, 128, 256, nullptr);
|
||||
|
||||
if (hdc->pen->posX != 128)
|
||||
goto fail;
|
||||
|
||||
if (hdc->pen->posY != 256)
|
||||
goto fail;
|
||||
|
||||
prevPoint = (HGDI_POINT)malloc(sizeof(GDI_POINT));
|
||||
ZeroMemory(prevPoint, sizeof(GDI_POINT));
|
||||
gdi_MoveToEx(hdc, 64, 128, prevPoint);
|
||||
|
||||
if (prevPoint->x != 128)
|
||||
goto fail;
|
||||
|
||||
if (prevPoint->y != 256)
|
||||
goto fail;
|
||||
|
||||
if (hdc->pen->posX != 64)
|
||||
goto fail;
|
||||
|
||||
if (hdc->pen->posY != 128)
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
|
||||
if (hPen)
|
||||
gdi_DeleteObject((HGDIOBJECT)hPen);
|
||||
|
||||
free(prevPoint);
|
||||
gdi_DeleteDC(hdc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int TestGdiCreate(int argc, char* argv[])
|
||||
{
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
(void)fprintf(stderr, "test_gdi_GetDC()\n");
|
||||
|
||||
if (test_gdi_GetDC() < 0)
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_CreateCompatibleDC()\n");
|
||||
|
||||
if (test_gdi_CreateCompatibleDC() < 0)
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_CreateBitmap()\n");
|
||||
|
||||
if (test_gdi_CreateBitmap() < 0)
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_CreateCompatibleBitmap()\n");
|
||||
|
||||
if (test_gdi_CreateCompatibleBitmap() < 0)
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_CreatePen()\n");
|
||||
|
||||
if (test_gdi_CreatePen() < 0)
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_CreateSolidBrush()\n");
|
||||
|
||||
if (test_gdi_CreateSolidBrush() < 0)
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_CreatePatternBrush()\n");
|
||||
|
||||
if (test_gdi_CreatePatternBrush() < 0)
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_CreateRectRgn()\n");
|
||||
|
||||
if (test_gdi_CreateRectRgn() < 0)
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_CreateRect()\n");
|
||||
|
||||
if (test_gdi_CreateRect() < 0)
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_GetPixel()\n");
|
||||
|
||||
if (!test_gdi_GetPixel())
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_SetPixel()\n");
|
||||
|
||||
if (!test_gdi_SetPixel())
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_SetROP2()\n");
|
||||
|
||||
if (test_gdi_SetROP2() < 0)
|
||||
return -1;
|
||||
|
||||
(void)fprintf(stderr, "test_gdi_MoveToEx()\n");
|
||||
|
||||
if (test_gdi_MoveToEx() < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
169
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiEllipse.c
vendored
Normal file
169
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiEllipse.c
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/dc.h>
|
||||
#include <freerdp/gdi/pen.h>
|
||||
#include <freerdp/gdi/shape.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include "line.h"
|
||||
#include "brush.h"
|
||||
#include "clipping.h"
|
||||
#include "helpers.h"
|
||||
|
||||
/* Ellipse() Test Data */
|
||||
|
||||
static const BYTE ellipse_case_1[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE ellipse_case_2[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE ellipse_case_3[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
|
||||
"\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
int TestGdiEllipse(int argc, char* argv[])
|
||||
{
|
||||
int rc = -1;
|
||||
const UINT32 RawFormat = PIXEL_FORMAT_RGB8;
|
||||
const UINT32 colorFormats[] = { PIXEL_FORMAT_RGB15, PIXEL_FORMAT_ARGB15, PIXEL_FORMAT_RGB16,
|
||||
PIXEL_FORMAT_RGB24, PIXEL_FORMAT_ARGB32, PIXEL_FORMAT_XRGB32,
|
||||
PIXEL_FORMAT_RGBA32, PIXEL_FORMAT_RGBX32, PIXEL_FORMAT_BGR15,
|
||||
PIXEL_FORMAT_ABGR15, PIXEL_FORMAT_BGR16, PIXEL_FORMAT_BGR24,
|
||||
PIXEL_FORMAT_ABGR32, PIXEL_FORMAT_XBGR32, PIXEL_FORMAT_BGRA32,
|
||||
PIXEL_FORMAT_BGRX32 };
|
||||
const UINT32 number_formats = sizeof(colorFormats) / sizeof(colorFormats[0]);
|
||||
gdiPalette g;
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
for (UINT32 i = 0; i < number_formats; i++)
|
||||
{
|
||||
HGDI_DC hdc = nullptr;
|
||||
HGDI_PEN pen = nullptr;
|
||||
HGDI_BITMAP hBmp = nullptr;
|
||||
HGDI_BITMAP hBmp_Ellipse_1 = nullptr;
|
||||
HGDI_BITMAP hBmp_Ellipse_2 = nullptr;
|
||||
HGDI_BITMAP hBmp_Ellipse_3 = nullptr;
|
||||
const UINT32 format = colorFormats[i];
|
||||
gdiPalette* hPalette = &g;
|
||||
g.format = format;
|
||||
|
||||
for (UINT32 j = 0; j < 256; j++)
|
||||
g.palette[i] = FreeRDPGetColor(format, j, j, j, 0xFF);
|
||||
|
||||
rc = -1;
|
||||
|
||||
if (!(hdc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hdc->format = format;
|
||||
gdi_SetNullClipRgn(hdc);
|
||||
|
||||
if (!(pen = gdi_CreatePen(1, 1, 0, format, hPalette)))
|
||||
{
|
||||
printf("gdi_CreatePen failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
gdi_SelectObject(hdc, (HGDIOBJECT)pen);
|
||||
hBmp = gdi_CreateCompatibleBitmap(hdc, 16, 16);
|
||||
gdi_SelectObject(hdc, (HGDIOBJECT)hBmp);
|
||||
hBmp_Ellipse_1 = test_convert_to_bitmap(ellipse_case_1, RawFormat, 0, 0, 0, format, 0, 0, 0,
|
||||
16, 16, hPalette);
|
||||
|
||||
if (!hBmp_Ellipse_1)
|
||||
goto fail;
|
||||
|
||||
hBmp_Ellipse_2 = test_convert_to_bitmap(ellipse_case_2, RawFormat, 0, 0, 0, format, 0, 0, 0,
|
||||
16, 16, hPalette);
|
||||
|
||||
if (!hBmp_Ellipse_2)
|
||||
goto fail;
|
||||
|
||||
hBmp_Ellipse_3 = test_convert_to_bitmap(ellipse_case_3, RawFormat, 0, 0, 0, format, 0, 0, 0,
|
||||
16, 16, hPalette);
|
||||
|
||||
if (!hBmp_Ellipse_3)
|
||||
goto fail;
|
||||
|
||||
/* Test Case 1: (0,0) -> (16, 16) */
|
||||
if (!gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS, hPalette))
|
||||
{
|
||||
printf("gdi_BitBlt failed (line #%u)\n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!gdi_Ellipse(hdc, 0, 0, 15, 15))
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
gdi_DeleteObject((HGDIOBJECT)hBmp_Ellipse_1);
|
||||
gdi_DeleteObject((HGDIOBJECT)hBmp_Ellipse_2);
|
||||
gdi_DeleteObject((HGDIOBJECT)hBmp_Ellipse_3);
|
||||
gdi_DeleteObject((HGDIOBJECT)hBmp);
|
||||
gdi_DeleteObject((HGDIOBJECT)pen);
|
||||
gdi_DeleteDC(hdc);
|
||||
|
||||
if (rc != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
724
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiLine.c
vendored
Normal file
724
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiLine.c
vendored
Normal file
@@ -0,0 +1,724 @@
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/dc.h>
|
||||
#include <freerdp/gdi/pen.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include "line.h"
|
||||
#include "brush.h"
|
||||
#include "clipping.h"
|
||||
#include "drawing.h"
|
||||
|
||||
#include "helpers.h"
|
||||
|
||||
/* LineTo() Test Data */
|
||||
static const BYTE line_to_case_1[256] = {
|
||||
"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_case_2[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
|
||||
};
|
||||
|
||||
static const BYTE line_to_case_3[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_case_4[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_case_5[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_case_6[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_case_7[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_case_8[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_case_9[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_case_10[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_case_11[256] = {
|
||||
"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
|
||||
};
|
||||
|
||||
static const BYTE* line_to_case[] = { line_to_case_1, line_to_case_2, line_to_case_3,
|
||||
line_to_case_4, line_to_case_5, line_to_case_6,
|
||||
line_to_case_7, line_to_case_8, line_to_case_9,
|
||||
line_to_case_10, line_to_case_11 };
|
||||
|
||||
static const BYTE line_to_R2_BLACK[256] = {
|
||||
"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_NOTMERGEPEN[256] = {
|
||||
"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_MASKNOTPEN[256] = {
|
||||
"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_NOTCOPYPEN[256] = {
|
||||
"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_MASKPENNOT[256] = {
|
||||
"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_NOT[256] = {
|
||||
"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_XORPEN[256] = {
|
||||
"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_NOTMASKPEN[256] = {
|
||||
"\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_MASKPEN[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_NOTXORPEN[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_NOP[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_MERGENOTPEN[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_COPYPEN[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_MERGEPENNOT[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_MERGEPEN[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
static const BYTE line_to_R2_WHITE[256] = {
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||
};
|
||||
|
||||
#define LINTETO_NUMBER 11
|
||||
struct ropMap
|
||||
{
|
||||
UINT32 rop;
|
||||
HGDI_BITMAP bmp;
|
||||
const BYTE* src;
|
||||
};
|
||||
|
||||
static BOOL test_line(HGDI_DC hdc, const gdiPalette* hPalette, UINT32 mX, UINT32 mY, UINT32 lX,
|
||||
UINT32 lY, HGDI_BITMAP hBmp, HGDI_BITMAP hOrgBmp, UINT32 cX, UINT32 cY,
|
||||
UINT32 cW, UINT32 cH)
|
||||
{
|
||||
if (!gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS, hPalette))
|
||||
return FALSE;
|
||||
|
||||
if ((cX > 0) || (cY > 0) || (cW > 0) || (cH > 0))
|
||||
gdi_SetClipRgn(hdc, cX, cY, cW, cH);
|
||||
|
||||
gdi_MoveToEx(hdc, mX, mY, nullptr);
|
||||
gdi_LineTo(hdc, lX, lY);
|
||||
|
||||
if (!test_assert_bitmaps_equal(hBmp, hOrgBmp, "Case 10", hPalette))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int TestGdiLine(int argc, char* argv[])
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
const UINT32 RawFormat = PIXEL_FORMAT_RGB8;
|
||||
const UINT32 colorFormats[] = { PIXEL_FORMAT_RGB15, PIXEL_FORMAT_ARGB15, PIXEL_FORMAT_RGB16,
|
||||
PIXEL_FORMAT_RGB24, PIXEL_FORMAT_ARGB32, PIXEL_FORMAT_XRGB32,
|
||||
PIXEL_FORMAT_RGBA32, PIXEL_FORMAT_RGBX32, PIXEL_FORMAT_BGR15,
|
||||
PIXEL_FORMAT_ABGR15, PIXEL_FORMAT_BGR16, PIXEL_FORMAT_BGR24,
|
||||
PIXEL_FORMAT_ABGR32, PIXEL_FORMAT_XBGR32, PIXEL_FORMAT_BGRA32,
|
||||
PIXEL_FORMAT_BGRX32 };
|
||||
const size_t number_formats = sizeof(colorFormats) / sizeof(colorFormats[0]);
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
for (size_t ifmt = 0; ifmt < number_formats; ifmt++)
|
||||
{
|
||||
gdiPalette g = WINPR_C_ARRAY_INIT;
|
||||
HGDI_DC hdc = nullptr;
|
||||
HGDI_PEN pen = nullptr;
|
||||
HGDI_BITMAP hBmp = nullptr;
|
||||
struct ropMap rop_map[] = { { GDI_R2_BLACK, nullptr, line_to_R2_BLACK },
|
||||
{ GDI_R2_NOTMERGEPEN, nullptr, line_to_R2_NOTMERGEPEN },
|
||||
{ GDI_R2_MASKNOTPEN, nullptr, line_to_R2_MASKNOTPEN },
|
||||
{ GDI_R2_NOTCOPYPEN, nullptr, line_to_R2_NOTCOPYPEN },
|
||||
{ GDI_R2_MASKPENNOT, nullptr, line_to_R2_MASKPENNOT },
|
||||
{ GDI_R2_NOT, nullptr, line_to_R2_NOT },
|
||||
{ GDI_R2_XORPEN, nullptr, line_to_R2_XORPEN },
|
||||
{ GDI_R2_NOTMASKPEN, nullptr, line_to_R2_NOTMASKPEN },
|
||||
{ GDI_R2_MASKPEN, nullptr, line_to_R2_MASKPEN },
|
||||
{ GDI_R2_NOTXORPEN, nullptr, line_to_R2_NOTXORPEN },
|
||||
{ GDI_R2_NOP, nullptr, line_to_R2_NOP },
|
||||
{ GDI_R2_MERGENOTPEN, nullptr, line_to_R2_MERGENOTPEN },
|
||||
{ GDI_R2_COPYPEN, nullptr, line_to_R2_COPYPEN },
|
||||
{ GDI_R2_MERGEPENNOT, nullptr, line_to_R2_MERGEPENNOT },
|
||||
{ GDI_R2_MERGEPEN, nullptr, line_to_R2_MERGEPEN },
|
||||
{ GDI_R2_WHITE, nullptr, line_to_R2_WHITE } };
|
||||
const size_t map_size = sizeof(rop_map) / sizeof(rop_map[0]);
|
||||
HGDI_BITMAP hBmp_LineTo[LINTETO_NUMBER] = { nullptr };
|
||||
gdiPalette* hPalette = &g;
|
||||
UINT32 penColor = 0;
|
||||
const UINT32 format = colorFormats[ifmt];
|
||||
g.format = format;
|
||||
|
||||
for (unsigned x = 0; x < 256; x++)
|
||||
g.palette[x] = FreeRDPGetColor(format, x, x, x, 0xFF);
|
||||
|
||||
rc = -1;
|
||||
|
||||
if (!(hdc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hdc->format = format;
|
||||
gdi_SetNullClipRgn(hdc);
|
||||
penColor = FreeRDPGetColor(format, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
|
||||
if (!(pen = gdi_CreatePen(1, 1, penColor, format, hPalette)))
|
||||
{
|
||||
printf("gdi_CreatePen failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
gdi_SelectObject(hdc, (HGDIOBJECT)pen);
|
||||
hBmp = gdi_CreateCompatibleBitmap(hdc, 16, 16);
|
||||
gdi_SelectObject(hdc, (HGDIOBJECT)hBmp);
|
||||
|
||||
for (UINT32 x = 0; x < LINTETO_NUMBER; x++)
|
||||
{
|
||||
hBmp_LineTo[x] = test_convert_to_bitmap(line_to_case[x], RawFormat, 0, 0, 0, format, 0,
|
||||
0, 0, 16, 16, hPalette);
|
||||
|
||||
if (!hBmp_LineTo[x])
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (UINT32 x = 0; x < map_size; x++)
|
||||
{
|
||||
rop_map[x].bmp = test_convert_to_bitmap(rop_map[x].src, RawFormat, 0, 0, 0, format, 0,
|
||||
0, 0, 16, 16, hPalette);
|
||||
|
||||
if (!rop_map[x].bmp)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!test_line(hdc, hPalette, 0, 0, 15, 15, hBmp, hBmp_LineTo[0], 0, 0, 16, 16))
|
||||
goto fail;
|
||||
|
||||
if (!test_line(hdc, hPalette, 15, 15, 0, 0, hBmp, hBmp_LineTo[1], 0, 0, 16, 16))
|
||||
goto fail;
|
||||
|
||||
if (!test_line(hdc, hPalette, 15, 0, 0, 15, hBmp, hBmp_LineTo[2], 0, 0, 16, 16))
|
||||
goto fail;
|
||||
|
||||
if (!test_line(hdc, hPalette, 0, 15, 15, 0, hBmp, hBmp_LineTo[3], 0, 0, 16, 16))
|
||||
goto fail;
|
||||
|
||||
if (!test_line(hdc, hPalette, 0, 8, 15, 8, hBmp, hBmp_LineTo[4], 0, 0, 16, 16))
|
||||
goto fail;
|
||||
|
||||
if (!test_line(hdc, hPalette, 15, 8, 0, 8, hBmp, hBmp_LineTo[5], 0, 0, 16, 16))
|
||||
goto fail;
|
||||
|
||||
if (!test_line(hdc, hPalette, 8, 0, 8, 15, hBmp, hBmp_LineTo[6], 0, 0, 16, 16))
|
||||
goto fail;
|
||||
|
||||
if (!test_line(hdc, hPalette, 8, 15, 8, 0, hBmp, hBmp_LineTo[7], 0, 0, 16, 16))
|
||||
goto fail;
|
||||
|
||||
if (!test_line(hdc, hPalette, 4, 4, 12, 12, hBmp, hBmp_LineTo[8], 0, 0, 16, 16))
|
||||
goto fail;
|
||||
|
||||
if (!test_line(hdc, hPalette, 0, 0, 16, 16, hBmp, hBmp_LineTo[9], 5, 5, 8, 8))
|
||||
goto fail;
|
||||
|
||||
if (!test_line(hdc, hPalette, 0, 0, 26, 26, hBmp, hBmp_LineTo[10], 0, 0, 16, 16))
|
||||
goto fail;
|
||||
|
||||
for (UINT32 x = 0; x < map_size; x++)
|
||||
{
|
||||
char name[1024] = WINPR_C_ARRAY_INIT;
|
||||
_snprintf(name, sizeof(name), "%s [%s]", gdi_rop_to_string(rop_map[x].rop),
|
||||
FreeRDPGetColorFormatName(hdc->format));
|
||||
|
||||
/* Test Case 13: (0,0) -> (16,16), R2_NOTMERGEPEN */
|
||||
if (!gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS, hPalette))
|
||||
{
|
||||
printf("gdi_BitBlt failed (line #%u)\n", __LINE__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
gdi_SetClipRgn(hdc, 0, 0, 16, 16);
|
||||
gdi_MoveToEx(hdc, 0, 0, nullptr);
|
||||
gdi_SetROP2(hdc, rop_map[x].rop);
|
||||
gdi_LineTo(hdc, 16, 16);
|
||||
|
||||
if (!test_assert_bitmaps_equal(hBmp, rop_map[x].bmp, name, hPalette))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
|
||||
for (UINT32 x = 0; x < LINTETO_NUMBER; x++)
|
||||
gdi_DeleteObject((HGDIOBJECT)hBmp_LineTo[x]);
|
||||
|
||||
for (UINT32 x = 0; x < map_size; x++)
|
||||
gdi_DeleteObject((HGDIOBJECT)rop_map[x].bmp);
|
||||
|
||||
gdi_DeleteObject((HGDIOBJECT)hBmp);
|
||||
gdi_DeleteObject((HGDIOBJECT)pen);
|
||||
gdi_DeleteDC(hdc);
|
||||
|
||||
if (rc != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
175
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiRect.c
vendored
Normal file
175
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiRect.c
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/dc.h>
|
||||
#include <freerdp/gdi/pen.h>
|
||||
#include <freerdp/gdi/shape.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include "line.h"
|
||||
#include "brush.h"
|
||||
#include "clipping.h"
|
||||
|
||||
static int test_gdi_PtInRect(void)
|
||||
{
|
||||
int rc = -1;
|
||||
GDI_RECT* hRect = nullptr;
|
||||
UINT32 left = 20;
|
||||
UINT32 top = 40;
|
||||
UINT32 right = 60;
|
||||
UINT32 bottom = 80;
|
||||
|
||||
if (!(hRect = gdi_CreateRect(
|
||||
WINPR_ASSERTING_INT_CAST(int, left), WINPR_ASSERTING_INT_CAST(int, top),
|
||||
WINPR_ASSERTING_INT_CAST(int, right), WINPR_ASSERTING_INT_CAST(int, bottom))))
|
||||
{
|
||||
printf("gdi_CreateRect failed\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (gdi_PtInRect(hRect, 0, 0))
|
||||
goto fail;
|
||||
|
||||
if (gdi_PtInRect(hRect, 500, 500))
|
||||
goto fail;
|
||||
|
||||
if (gdi_PtInRect(hRect, 40, 100))
|
||||
goto fail;
|
||||
|
||||
if (gdi_PtInRect(hRect, 10, 40))
|
||||
goto fail;
|
||||
|
||||
if (!gdi_PtInRect(hRect, 30, 50))
|
||||
goto fail;
|
||||
|
||||
if (!gdi_PtInRect(hRect, WINPR_ASSERTING_INT_CAST(int, left),
|
||||
WINPR_ASSERTING_INT_CAST(int, top)))
|
||||
goto fail;
|
||||
|
||||
if (!gdi_PtInRect(hRect, WINPR_ASSERTING_INT_CAST(int, right),
|
||||
WINPR_ASSERTING_INT_CAST(int, bottom)))
|
||||
goto fail;
|
||||
|
||||
if (!gdi_PtInRect(hRect, WINPR_ASSERTING_INT_CAST(int, right), 60))
|
||||
goto fail;
|
||||
|
||||
if (!gdi_PtInRect(hRect, 40, WINPR_ASSERTING_INT_CAST(int, bottom)))
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
gdi_DeleteObject((HGDIOBJECT)hRect);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_gdi_FillRect(void)
|
||||
{
|
||||
int rc = -1;
|
||||
HGDI_DC hdc = nullptr;
|
||||
GDI_RECT* hRect = nullptr;
|
||||
HGDI_BRUSH hBrush = nullptr;
|
||||
HGDI_BITMAP hBitmap = nullptr;
|
||||
UINT32 color = 0;
|
||||
UINT32 pixel = 0;
|
||||
UINT32 rawPixel = 0;
|
||||
UINT32 badPixels = 0;
|
||||
UINT32 goodPixels = 0;
|
||||
UINT32 width = 200;
|
||||
UINT32 height = 300;
|
||||
UINT32 left = 20;
|
||||
UINT32 top = 40;
|
||||
UINT32 right = 60;
|
||||
UINT32 bottom = 80;
|
||||
|
||||
if (!(hdc = gdi_GetDC()))
|
||||
{
|
||||
printf("failed to get gdi device context\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hdc->format = PIXEL_FORMAT_XRGB32;
|
||||
|
||||
if (!(hRect = gdi_CreateRect(
|
||||
WINPR_ASSERTING_INT_CAST(int, left), WINPR_ASSERTING_INT_CAST(int, top),
|
||||
WINPR_ASSERTING_INT_CAST(int, right), WINPR_ASSERTING_INT_CAST(int, bottom))))
|
||||
{
|
||||
printf("gdi_CreateRect failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hBitmap = gdi_CreateCompatibleBitmap(hdc, width, height);
|
||||
ZeroMemory(hBitmap->data, 1ULL * width * height * FreeRDPGetBytesPerPixel(hdc->format));
|
||||
gdi_SelectObject(hdc, (HGDIOBJECT)hBitmap);
|
||||
color = FreeRDPGetColor(PIXEL_FORMAT_ARGB32, 0xAA, 0xBB, 0xCC, 0xFF);
|
||||
hBrush = gdi_CreateSolidBrush(color);
|
||||
gdi_FillRect(hdc, hRect, hBrush);
|
||||
badPixels = 0;
|
||||
goodPixels = 0;
|
||||
|
||||
for (UINT32 x = 0; x < width; x++)
|
||||
{
|
||||
for (UINT32 y = 0; y < height; y++)
|
||||
{
|
||||
rawPixel = gdi_GetPixel(hdc, x, y);
|
||||
pixel = FreeRDPConvertColor(rawPixel, hdc->format, PIXEL_FORMAT_ARGB32, nullptr);
|
||||
|
||||
if (gdi_PtInRect(hRect, WINPR_ASSERTING_INT_CAST(int, x),
|
||||
WINPR_ASSERTING_INT_CAST(int, y)))
|
||||
{
|
||||
if (pixel == color)
|
||||
{
|
||||
goodPixels++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("actual:%08" PRIX32 " expected:%08" PRIX32 "\n", gdi_GetPixel(hdc, x, y),
|
||||
color);
|
||||
badPixels++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pixel == color)
|
||||
{
|
||||
badPixels++;
|
||||
}
|
||||
else
|
||||
{
|
||||
goodPixels++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (goodPixels != width * height)
|
||||
goto fail;
|
||||
|
||||
if (badPixels != 0)
|
||||
goto fail;
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
gdi_DeleteObject((HGDIOBJECT)hBrush);
|
||||
gdi_DeleteObject((HGDIOBJECT)hBitmap);
|
||||
gdi_DeleteObject((HGDIOBJECT)hRect);
|
||||
gdi_DeleteDC(hdc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int TestGdiRect(int argc, char* argv[])
|
||||
{
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
if (test_gdi_PtInRect() < 0)
|
||||
return -1;
|
||||
|
||||
if (test_gdi_FillRect() < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
256
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiRegion.c
vendored
Normal file
256
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiRegion.c
vendored
Normal file
@@ -0,0 +1,256 @@
|
||||
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
|
||||
#include <freerdp/gdi/dc.h>
|
||||
#include <freerdp/gdi/pen.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include "helpers.h"
|
||||
|
||||
int TestGdiRegion(int argc, char* argv[])
|
||||
{
|
||||
int rc = -1;
|
||||
INT32 x = 0;
|
||||
INT32 y = 0;
|
||||
INT32 w = 0;
|
||||
INT32 h = 0;
|
||||
INT32 l = 0;
|
||||
INT32 r = 0;
|
||||
INT32 t = 0;
|
||||
INT32 b = 0;
|
||||
HGDI_RGN rgn1 = nullptr;
|
||||
HGDI_RGN rgn2 = nullptr;
|
||||
GDI_RECT* rect1 = nullptr;
|
||||
GDI_RECT* rect2 = nullptr;
|
||||
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
rgn1 = gdi_CreateRectRgn(111, 2, 65, 77);
|
||||
rect1 = gdi_CreateRect(2311, 11, 42, 17);
|
||||
if (rgn1 || rect1)
|
||||
goto fail;
|
||||
rgn1 = gdi_CreateRectRgn(1, 2, 65, 77);
|
||||
rgn2 = gdi_CreateRectRgn(11, 2, 65, 77);
|
||||
rect1 = gdi_CreateRect(23, 11, 42, 17);
|
||||
rect2 = gdi_CreateRect(23, 11, 42, 17);
|
||||
if (!rgn1 || !rgn2 || !rect1 || !rect2)
|
||||
goto fail;
|
||||
|
||||
if (!gdi_RectToRgn(rect1, rgn1))
|
||||
goto fail;
|
||||
if (rgn1->x != rect1->left)
|
||||
goto fail;
|
||||
if (rgn1->y != rect1->top)
|
||||
goto fail;
|
||||
if (rgn1->w != (rect1->right - rect1->left + 1))
|
||||
goto fail;
|
||||
if (rgn1->h != (rect1->bottom - rect1->top + 1))
|
||||
goto fail;
|
||||
|
||||
if (gdi_CRectToRgn(1123, 111, 333, 444, rgn2))
|
||||
goto fail;
|
||||
if (gdi_CRectToRgn(123, 1111, 333, 444, rgn2))
|
||||
goto fail;
|
||||
if (!gdi_CRectToRgn(123, 111, 333, 444, rgn2))
|
||||
goto fail;
|
||||
if (rgn2->x != 123)
|
||||
goto fail;
|
||||
if (rgn2->y != 111)
|
||||
goto fail;
|
||||
if (rgn2->w != (333 - 123 + 1))
|
||||
goto fail;
|
||||
if (rgn2->h != (444 - 111 + 1))
|
||||
goto fail;
|
||||
|
||||
if (!gdi_RectToCRgn(rect1, &x, &y, &w, &h))
|
||||
goto fail;
|
||||
if (rect1->left != x)
|
||||
goto fail;
|
||||
if (rect1->top != y)
|
||||
goto fail;
|
||||
if (rect1->right != (x + w - 1))
|
||||
goto fail;
|
||||
if (rect1->bottom != (y + h - 1))
|
||||
goto fail;
|
||||
|
||||
w = 23;
|
||||
h = 42;
|
||||
if (gdi_CRectToCRgn(1, 2, 0, 4, &x, &y, &w, &h))
|
||||
goto fail;
|
||||
if ((w != 0) || (h != 0))
|
||||
goto fail;
|
||||
w = 23;
|
||||
h = 42;
|
||||
if (gdi_CRectToCRgn(1, 2, 3, 1, &x, &y, &w, &h))
|
||||
goto fail;
|
||||
if ((w != 0) || (h != 0))
|
||||
goto fail;
|
||||
w = 23;
|
||||
h = 42;
|
||||
if (!gdi_CRectToCRgn(1, 2, 3, 4, &x, &y, &w, &h))
|
||||
goto fail;
|
||||
if (x != 1)
|
||||
goto fail;
|
||||
if (y != 2)
|
||||
goto fail;
|
||||
if (w != (3 - 1 + 1))
|
||||
goto fail;
|
||||
if (h != (4 - 2 + 1))
|
||||
goto fail;
|
||||
|
||||
if (!gdi_RgnToRect(rgn1, rect2))
|
||||
goto fail;
|
||||
|
||||
if (rgn1->x != rect2->left)
|
||||
goto fail;
|
||||
if (rgn1->y != rect2->top)
|
||||
goto fail;
|
||||
if (rgn1->w != (rect2->right - rect2->left + 1))
|
||||
goto fail;
|
||||
if (rgn1->h != (rect2->bottom - rect2->top + 1))
|
||||
goto fail;
|
||||
|
||||
if (gdi_CRgnToRect(1, 2, 0, 4, rect2))
|
||||
goto fail;
|
||||
if (gdi_CRgnToRect(1, 2, -1, 4, rect2))
|
||||
goto fail;
|
||||
if (gdi_CRgnToRect(1, 2, 3, 0, rect2))
|
||||
goto fail;
|
||||
if (gdi_CRgnToRect(1, 2, 3, -1, rect2))
|
||||
goto fail;
|
||||
if (!gdi_CRgnToRect(1, 2, 3, 4, rect2))
|
||||
goto fail;
|
||||
if (rect2->left != 1)
|
||||
goto fail;
|
||||
if (rect2->right != (1 + 3 - 1))
|
||||
goto fail;
|
||||
if (rect2->top != 2)
|
||||
goto fail;
|
||||
if (rect2->bottom != (2 + 4 - 1))
|
||||
goto fail;
|
||||
|
||||
if (!gdi_RgnToCRect(rgn1, &l, &t, &r, &b))
|
||||
goto fail;
|
||||
if (rgn1->x != l)
|
||||
goto fail;
|
||||
if (rgn1->y != t)
|
||||
goto fail;
|
||||
if (rgn1->w != (r - l + 1))
|
||||
goto fail;
|
||||
if (rgn1->h != (b - t + 1))
|
||||
goto fail;
|
||||
|
||||
if (gdi_CRgnToCRect(1, 2, -1, 4, &l, &t, &r, &b))
|
||||
goto fail;
|
||||
if (gdi_CRgnToCRect(1, 2, 0, 4, &l, &t, &r, &b))
|
||||
goto fail;
|
||||
if (gdi_CRgnToCRect(1, 2, 3, -1, &l, &t, &r, &b))
|
||||
goto fail;
|
||||
if (gdi_CRgnToCRect(1, 2, 3, -0, &l, &t, &r, &b))
|
||||
goto fail;
|
||||
if (!gdi_CRgnToCRect(1, 2, 3, 4, &l, &t, &r, &b))
|
||||
goto fail;
|
||||
if (l != 1)
|
||||
goto fail;
|
||||
if (t != 2)
|
||||
goto fail;
|
||||
if (r != (1 + 3 - 1))
|
||||
goto fail;
|
||||
if (b != 2 + 4 - 1)
|
||||
goto fail;
|
||||
|
||||
if (gdi_CopyOverlap(1, 2, 5, 3, -5, 3))
|
||||
goto fail;
|
||||
if (gdi_CopyOverlap(1, 2, 5, 3, 3, -2))
|
||||
goto fail;
|
||||
if (!gdi_CopyOverlap(1, 2, 5, 3, 2, 3))
|
||||
goto fail;
|
||||
|
||||
if (gdi_SetRect(rect2, -4, 500, 66, -5))
|
||||
goto fail;
|
||||
if (gdi_SetRect(rect2, -4, -500, -66, -5))
|
||||
goto fail;
|
||||
if (!gdi_SetRect(rect2, -4, 500, 66, 754))
|
||||
goto fail;
|
||||
|
||||
if (gdi_SetRgn(nullptr, -23, -42, 33, 99))
|
||||
goto fail;
|
||||
if (gdi_SetRgn(rgn2, -23, -42, -33, 99))
|
||||
goto fail;
|
||||
if (gdi_SetRgn(rgn2, -23, -42, 33, -99))
|
||||
goto fail;
|
||||
if (!gdi_SetRgn(rgn2, -23, -42, 33, 99))
|
||||
goto fail;
|
||||
if (rgn2->x != -23)
|
||||
goto fail;
|
||||
if (rgn2->y != -42)
|
||||
goto fail;
|
||||
if (rgn2->w != 33)
|
||||
goto fail;
|
||||
if (rgn2->h != 99)
|
||||
goto fail;
|
||||
if (rgn2->null)
|
||||
goto fail;
|
||||
|
||||
if (gdi_SetRectRgn(nullptr, 33, 22, 44, 33))
|
||||
goto fail;
|
||||
if (gdi_SetRectRgn(rgn1, 331, 22, 44, 33))
|
||||
goto fail;
|
||||
if (gdi_SetRectRgn(rgn1, 33, 122, 44, 33))
|
||||
goto fail;
|
||||
if (!gdi_SetRectRgn(rgn1, 33, 22, 44, 33))
|
||||
goto fail;
|
||||
if (rgn1->x != 33)
|
||||
goto fail;
|
||||
if (rgn1->y != 22)
|
||||
goto fail;
|
||||
if (rgn1->w != (44 - 33 + 1))
|
||||
goto fail;
|
||||
if (rgn1->h != (33 - 22 + 1))
|
||||
goto fail;
|
||||
|
||||
if (gdi_EqualRgn(rgn1, rgn2))
|
||||
goto fail;
|
||||
if (!gdi_EqualRgn(rgn1, rgn1))
|
||||
goto fail;
|
||||
|
||||
if (gdi_CopyRect(rect1, nullptr))
|
||||
goto fail;
|
||||
if (gdi_CopyRect(nullptr, rect1))
|
||||
goto fail;
|
||||
if (gdi_CopyRect(nullptr, nullptr))
|
||||
goto fail;
|
||||
if (!gdi_CopyRect(rect1, rect2))
|
||||
goto fail;
|
||||
|
||||
if (rect1->left != rect2->left)
|
||||
goto fail;
|
||||
if (rect1->top != rect2->top)
|
||||
goto fail;
|
||||
if (rect1->right != rect2->right)
|
||||
goto fail;
|
||||
if (rect1->bottom != rect2->bottom)
|
||||
goto fail;
|
||||
|
||||
if (gdi_PtInRect(rect1, -23, 550))
|
||||
goto fail;
|
||||
if (gdi_PtInRect(rect1, 2, 3))
|
||||
goto fail;
|
||||
if (!gdi_PtInRect(rect1, 2, 550))
|
||||
goto fail;
|
||||
|
||||
// BOOL gdi_InvalidateRegion(HGDI_DC hdc, INT32 x, INT32 y, INT32 w, INT32 h);
|
||||
|
||||
rc = 0;
|
||||
fail:
|
||||
free(rgn1);
|
||||
free(rgn2);
|
||||
free(rect1);
|
||||
free(rect2);
|
||||
return rc;
|
||||
}
|
||||
219
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiRop3.c
vendored
Normal file
219
third_party/FreeRDP/libfreerdp/gdi/test/TestGdiRop3.c
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
/**
|
||||
* Ternary Raster Operations:
|
||||
* See "Windows Graphics Programming: Win32 GDI and DirectDraw", chapter 11. Advanced Bitmap
|
||||
* Graphics
|
||||
*
|
||||
* Operators:
|
||||
*
|
||||
* AND & a
|
||||
* OR | o
|
||||
* NOT ~ n
|
||||
* XOR ^ x
|
||||
*
|
||||
* Operands:
|
||||
*
|
||||
* Pen/Brush P
|
||||
* Destination D
|
||||
* Source S
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Raster operation which returns P if S is 1 or D otherwise:
|
||||
* (rop_S & rop_P) | (~rop_S & rop_D); -> 0xE2 (0x00E20746)
|
||||
*
|
||||
* Postfix notation: DSPDxax
|
||||
* Infix notation: D^(S&(P^D))), (S&P)|(~S&D)
|
||||
*
|
||||
* DSPDxax using D^(S&(P^D)):
|
||||
*
|
||||
* mov eax, P // P
|
||||
* xor eax, D // P^D
|
||||
* and eax, S // S&(P^D)
|
||||
* xor eax, D // D^(S&(P^D))
|
||||
* mov D, eax // write result
|
||||
*
|
||||
* DSPDxax using (S&P)|(~S&D):
|
||||
*
|
||||
* mov eax, S // S
|
||||
* and eax, P // S&P
|
||||
* mov ebx, S // S
|
||||
* not ebx // ~S
|
||||
* and ebx, D // ~D&D
|
||||
* or eax, ebx // (S&P)|(~S&D)
|
||||
* mov D, eax // write result
|
||||
*
|
||||
* Raster operation lower word encoding:
|
||||
*
|
||||
* _______________________________________________________________________________
|
||||
* | | | | | | | | | | | | | | | | |
|
||||
* | Op5 | Op4 | Op3 | Op2 | Op1 | Not| Parse String | Offset |
|
||||
* |____|____|____|____|____|____|____|____|____|____|____|____|____|____|____|____|
|
||||
* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
||||
*
|
||||
* Operator:
|
||||
* 0: NOT
|
||||
* 1: XOR
|
||||
* 2: OR
|
||||
* 3: AND
|
||||
*
|
||||
* Parse String:
|
||||
* 0: SPDDDDDD
|
||||
* 1: SPDSPDSP
|
||||
* 2: SDPSDPSD
|
||||
* 3: DDDDDDDD
|
||||
* 4: DDDDDDDD
|
||||
* 5: S+SP-DSS
|
||||
* 6: S+SP-PDS
|
||||
* 7: S+SD-PDS
|
||||
*
|
||||
* The lower word for 0x00E20746 is 0x0746 (00000111 01000110)
|
||||
*
|
||||
* 00 Op5 (NOT, n)
|
||||
* 00 Op4 (NOT, n)
|
||||
* 01 Op3 (XOR, x)
|
||||
* 11 Op2 (AND, a)
|
||||
* 01 Op1 (XOR, x)
|
||||
* 0 Not (unused)
|
||||
* 001 String (SPDSPDSP)
|
||||
* 10 Offset (2)
|
||||
*
|
||||
* We shift SPDSPDSP to the left by 2: DSPDSPSP
|
||||
*
|
||||
* We have 5 operators: 3 binary operators and the last two are unary operators,
|
||||
* so only four operands are needed. The parse string is truncated to reflect
|
||||
* the number of operands we need: DSPD
|
||||
*
|
||||
* The operator string (from Op1 to Op5) is xaxnn, which can be simplified to xax
|
||||
*
|
||||
* The complete string representing the operation is DSPDxax
|
||||
*
|
||||
*/
|
||||
|
||||
static char* gdi_convert_postfix_to_infix(const char* postfix)
|
||||
{
|
||||
BOOL unary = 0;
|
||||
size_t al = 0;
|
||||
size_t bl = 0;
|
||||
wStack* stack = Stack_New(FALSE);
|
||||
size_t length = strlen(postfix);
|
||||
|
||||
for (size_t i = 0; i < length; i++)
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
if ((postfix[i] == 'P') || (postfix[i] == 'D') || (postfix[i] == 'S'))
|
||||
{
|
||||
/* token is an operand, push on the stack */
|
||||
char* a = malloc(2);
|
||||
if (!a)
|
||||
goto end;
|
||||
a[0] = postfix[i];
|
||||
a[1] = '\0';
|
||||
// printf("Operand: %s\n", a);
|
||||
Stack_Push(stack, a);
|
||||
}
|
||||
else
|
||||
{
|
||||
char* a = nullptr;
|
||||
char* b = nullptr;
|
||||
|
||||
/* token is an operator */
|
||||
unary = FALSE;
|
||||
char* c = malloc(2);
|
||||
if (!c)
|
||||
goto fail;
|
||||
c[0] = postfix[i];
|
||||
c[1] = '\0';
|
||||
|
||||
if (c[0] == 'a')
|
||||
{
|
||||
c[0] = '&';
|
||||
}
|
||||
else if (c[0] == 'o')
|
||||
{
|
||||
c[0] = '|';
|
||||
}
|
||||
else if (c[0] == 'n')
|
||||
{
|
||||
c[0] = '~';
|
||||
unary = TRUE;
|
||||
}
|
||||
else if (c[0] == 'x')
|
||||
{
|
||||
c[0] = '^';
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("invalid operator: %c\n", c[0]);
|
||||
}
|
||||
|
||||
// printf("Operator: %s\n", c);
|
||||
a = (char*)Stack_Pop(stack);
|
||||
if (!a)
|
||||
goto fail;
|
||||
|
||||
if (!unary)
|
||||
b = (char*)Stack_Pop(stack);
|
||||
|
||||
al = strlen(a);
|
||||
|
||||
if (b)
|
||||
bl = strlen(b);
|
||||
|
||||
size_t cl = 1;
|
||||
size_t dl = al + bl + cl + 3;
|
||||
char* d = malloc(dl + 1);
|
||||
if (!d)
|
||||
goto fail;
|
||||
|
||||
(void)sprintf_s(d, dl, "(%s%s%s)", b ? b : "", c, a);
|
||||
Stack_Push(stack, d);
|
||||
|
||||
success = TRUE;
|
||||
fail:
|
||||
free(a);
|
||||
free(b);
|
||||
free(c);
|
||||
if (!success)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
char* d = (char*)Stack_Pop(stack);
|
||||
Stack_Free(stack);
|
||||
return d;
|
||||
|
||||
end:
|
||||
Stack_Free(stack);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static const char* test_ROP3[] = { "DSPDxax", "PSDPxax", "SPna", "DSna", "DPa",
|
||||
"PDxn", "DSxn", "PSDnox", "PDSona", "DSPDxox",
|
||||
"DPSDonox", "SPDSxax", "DPon", "DPna", "Pn",
|
||||
"PDna", "DPan", "DSan", "DSxn", "DPa",
|
||||
"D", "DPno", "SDno", "PDno", "DPo" };
|
||||
|
||||
int TestGdiRop3(int argc, char* argv[])
|
||||
{
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
|
||||
for (size_t index = 0; index < sizeof(test_ROP3) / sizeof(test_ROP3[0]); index++)
|
||||
{
|
||||
const char* postfix = test_ROP3[index];
|
||||
char* infix = gdi_convert_postfix_to_infix(postfix);
|
||||
|
||||
if (!infix)
|
||||
return -1;
|
||||
|
||||
printf("%s\t\t%s\n", postfix, infix);
|
||||
free(infix);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
141
third_party/FreeRDP/libfreerdp/gdi/test/helpers.c
vendored
Normal file
141
third_party/FreeRDP/libfreerdp/gdi/test/helpers.c
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Library Tests
|
||||
*
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "helpers.h"
|
||||
|
||||
HGDI_BITMAP test_convert_to_bitmap(const BYTE* src, UINT32 SrcFormat, UINT32 SrcStride, UINT32 xSrc,
|
||||
UINT32 ySrc, UINT32 DstFormat, UINT32 DstStride, UINT32 xDst,
|
||||
UINT32 yDst, UINT32 nWidth, UINT32 nHeight,
|
||||
const gdiPalette* hPalette)
|
||||
{
|
||||
HGDI_BITMAP bmp = nullptr;
|
||||
BYTE* data = nullptr;
|
||||
|
||||
if (DstStride == 0)
|
||||
DstStride = nWidth * FreeRDPGetBytesPerPixel(DstFormat);
|
||||
|
||||
data = winpr_aligned_malloc(1ULL * DstStride * nHeight, 16);
|
||||
|
||||
if (!data)
|
||||
return nullptr;
|
||||
|
||||
if (!freerdp_image_copy(data, DstFormat, DstStride, xDst, yDst, nWidth, nHeight, src, SrcFormat,
|
||||
SrcStride, xSrc, ySrc, hPalette, FREERDP_FLIP_NONE))
|
||||
{
|
||||
winpr_aligned_free(data);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bmp = gdi_CreateBitmap(nWidth, nHeight, DstFormat, data);
|
||||
|
||||
if (!bmp)
|
||||
{
|
||||
winpr_aligned_free(data);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
static void test_dump_data(unsigned char* p, size_t len, size_t width, const char* name)
|
||||
{
|
||||
unsigned char* line = p;
|
||||
const size_t stride = (width > 0) ? len / width : 1;
|
||||
size_t offset = 0;
|
||||
printf("\n%s[%" PRIuz "][%" PRIuz "]:\n", name, stride, width);
|
||||
|
||||
while (offset < len)
|
||||
{
|
||||
size_t i = 0;
|
||||
printf("%04" PRIxz " ", offset);
|
||||
size_t thisline = len - offset;
|
||||
|
||||
if (thisline > width)
|
||||
thisline = width;
|
||||
|
||||
for (; i < thisline; i++)
|
||||
printf("%02x ", line[i]);
|
||||
|
||||
for (; i < width; i++)
|
||||
printf(" ");
|
||||
|
||||
printf("\n");
|
||||
offset += thisline;
|
||||
line += thisline;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
(void)fflush(stdout);
|
||||
}
|
||||
|
||||
void test_dump_bitmap(HGDI_BITMAP hBmp, const char* name)
|
||||
{
|
||||
const size_t stride =
|
||||
WINPR_ASSERTING_INT_CAST(size_t, hBmp->width) * FreeRDPGetBytesPerPixel(hBmp->format);
|
||||
test_dump_data(hBmp->data, stride * WINPR_ASSERTING_INT_CAST(uint32_t, hBmp->height), stride,
|
||||
name);
|
||||
}
|
||||
|
||||
static BOOL CompareBitmaps(HGDI_BITMAP hBmp1, HGDI_BITMAP hBmp2, const gdiPalette* palette)
|
||||
{
|
||||
const BYTE* p1 = hBmp1->data;
|
||||
const BYTE* p2 = hBmp2->data;
|
||||
const UINT32 minw = WINPR_ASSERTING_INT_CAST(
|
||||
uint32_t, (hBmp1->width < hBmp2->width) ? hBmp1->width : hBmp2->width);
|
||||
const UINT32 minh = WINPR_ASSERTING_INT_CAST(
|
||||
uint32_t, (hBmp1->height < hBmp2->height) ? hBmp1->height : hBmp2->height);
|
||||
|
||||
for (UINT32 y = 0; y < minh; y++)
|
||||
{
|
||||
for (UINT32 x = 0; x < minw; x++)
|
||||
{
|
||||
UINT32 colorA = FreeRDPReadColor(p1, hBmp1->format);
|
||||
UINT32 colorB = FreeRDPReadColor(p2, hBmp2->format);
|
||||
p1 += FreeRDPGetBytesPerPixel(hBmp1->format);
|
||||
p2 += FreeRDPGetBytesPerPixel(hBmp2->format);
|
||||
|
||||
if (hBmp1->format != hBmp2->format)
|
||||
colorB = FreeRDPConvertColor(colorB, hBmp2->format, hBmp1->format, palette);
|
||||
|
||||
if (colorA != colorB)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL test_assert_bitmaps_equal(HGDI_BITMAP hBmpActual, HGDI_BITMAP hBmpExpected, const char* name,
|
||||
const gdiPalette* palette)
|
||||
{
|
||||
BOOL bitmapsEqual = CompareBitmaps(hBmpActual, hBmpExpected, palette);
|
||||
|
||||
if (!bitmapsEqual)
|
||||
{
|
||||
printf("Testing ROP %s [%s|%s]\n", name, FreeRDPGetColorFormatName(hBmpActual->format),
|
||||
FreeRDPGetColorFormatName(hBmpExpected->format));
|
||||
test_dump_bitmap(hBmpActual, "Actual");
|
||||
test_dump_bitmap(hBmpExpected, "Expected");
|
||||
(void)fflush(stdout);
|
||||
(void)fflush(stderr);
|
||||
return TRUE; // TODO: Fix test cases
|
||||
}
|
||||
|
||||
return bitmapsEqual;
|
||||
}
|
||||
43
third_party/FreeRDP/libfreerdp/gdi/test/helpers.h
vendored
Normal file
43
third_party/FreeRDP/libfreerdp/gdi/test/helpers.h
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* GDI Library Tests
|
||||
*
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2016 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef GDI_TEST_HELPERS_H
|
||||
#define GDI_TEST_HELPERS_H
|
||||
|
||||
#include <freerdp/codec/color.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL
|
||||
HGDI_BITMAP test_convert_to_bitmap(const BYTE* src, UINT32 SrcFormat, UINT32 SrcStride, UINT32 xSrc,
|
||||
UINT32 ySrc, UINT32 DstFormat, UINT32 DstStride, UINT32 xDst,
|
||||
UINT32 yDst, UINT32 nWidth, UINT32 nHeight,
|
||||
|
||||
const gdiPalette* hPalette);
|
||||
|
||||
FREERDP_LOCAL
|
||||
void test_dump_bitmap(HGDI_BITMAP hBmp, const char* name);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL
|
||||
BOOL test_assert_bitmaps_equal(HGDI_BITMAP hBmpActual, HGDI_BITMAP hBmpExpected, const char* name,
|
||||
const gdiPalette* palette);
|
||||
|
||||
#endif /* __GDI_CORE_H */
|
||||
193
third_party/FreeRDP/libfreerdp/gdi/video.c
vendored
Normal file
193
third_party/FreeRDP/libfreerdp/gdi/video.c
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Video Optimized Remoting Virtual Channel Extension for X11
|
||||
*
|
||||
* Copyright 2017 David Fort <contact@hardening-consulting.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "../core/update.h"
|
||||
|
||||
#include <winpr/assert.h>
|
||||
|
||||
#include <freerdp/client/geometry.h>
|
||||
#include <freerdp/client/video.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/gdi/video.h>
|
||||
#include <freerdp/gdi/region.h>
|
||||
|
||||
void gdi_video_geometry_init(rdpGdi* gdi, GeometryClientContext* geom)
|
||||
{
|
||||
WINPR_ASSERT(gdi);
|
||||
WINPR_ASSERT(geom);
|
||||
|
||||
gdi->geometry = geom;
|
||||
|
||||
if (gdi->video)
|
||||
{
|
||||
VideoClientContext* video = gdi->video;
|
||||
|
||||
WINPR_ASSERT(video);
|
||||
WINPR_ASSERT(video->setGeometry);
|
||||
video->setGeometry(video, gdi->geometry);
|
||||
}
|
||||
}
|
||||
|
||||
void gdi_video_geometry_uninit(rdpGdi* gdi, GeometryClientContext* geom)
|
||||
{
|
||||
WINPR_ASSERT(gdi);
|
||||
WINPR_ASSERT(geom);
|
||||
WINPR_UNUSED(gdi);
|
||||
WINPR_UNUSED(geom);
|
||||
}
|
||||
|
||||
static VideoSurface* gdiVideoCreateSurface(WINPR_ATTR_UNUSED VideoClientContext* video, UINT32 x,
|
||||
UINT32 y, UINT32 width, UINT32 height)
|
||||
{
|
||||
return VideoClient_CreateCommonContext(sizeof(VideoSurface), x, y, width, height);
|
||||
}
|
||||
|
||||
static BOOL gdiVideoShowSurface(VideoClientContext* video, const VideoSurface* surface,
|
||||
UINT32 destinationWidth, UINT32 destinationHeight)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
rdpGdi* gdi = nullptr;
|
||||
rdpUpdate* update = nullptr;
|
||||
|
||||
WINPR_ASSERT(video);
|
||||
WINPR_ASSERT(surface);
|
||||
|
||||
gdi = (rdpGdi*)video->custom;
|
||||
WINPR_ASSERT(gdi);
|
||||
WINPR_ASSERT(gdi->context);
|
||||
|
||||
update = gdi->context->update;
|
||||
WINPR_ASSERT(update);
|
||||
|
||||
if (!update_begin_paint(update))
|
||||
goto fail;
|
||||
|
||||
if ((gdi->width < 0) || (gdi->height < 0))
|
||||
goto fail;
|
||||
|
||||
{
|
||||
const UINT32 nXSrc = surface->x;
|
||||
const UINT32 nYSrc = surface->y;
|
||||
const UINT32 nXDst = nXSrc;
|
||||
const UINT32 nYDst = nYSrc;
|
||||
const UINT32 width = (destinationWidth + surface->x < (UINT32)gdi->width)
|
||||
? destinationWidth
|
||||
: (UINT32)gdi->width - surface->x;
|
||||
const UINT32 height = (destinationHeight + surface->y < (UINT32)gdi->height)
|
||||
? destinationHeight
|
||||
: (UINT32)gdi->height - surface->y;
|
||||
|
||||
WINPR_ASSERT(gdi->primary_buffer);
|
||||
WINPR_ASSERT(gdi->primary);
|
||||
WINPR_ASSERT(gdi->primary->hdc);
|
||||
|
||||
if (!freerdp_image_scale(gdi->primary_buffer, gdi->primary->hdc->format, gdi->stride, nXDst,
|
||||
nYDst, width, height, surface->data, surface->format,
|
||||
surface->scanline, 0, 0, surface->w, surface->h))
|
||||
goto fail;
|
||||
|
||||
if ((nXDst > INT32_MAX) || (nYDst > INT32_MAX) || (width > INT32_MAX) ||
|
||||
(height > INT32_MAX))
|
||||
goto fail;
|
||||
|
||||
rc = gdi_InvalidateRegion(gdi->primary->hdc, (INT32)nXDst, (INT32)nYDst, (INT32)width,
|
||||
(INT32)height);
|
||||
}
|
||||
fail:
|
||||
|
||||
if (!update_end_paint(update))
|
||||
return FALSE;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static BOOL gdiVideoDeleteSurface(VideoClientContext* video, VideoSurface* surface)
|
||||
{
|
||||
WINPR_UNUSED(video);
|
||||
VideoClient_DestroyCommonContext(surface);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void gdi_video_control_init(rdpGdi* gdi, VideoClientContext* video)
|
||||
{
|
||||
WINPR_ASSERT(gdi);
|
||||
WINPR_ASSERT(video);
|
||||
|
||||
gdi->video = video;
|
||||
video->custom = gdi;
|
||||
video->createSurface = gdiVideoCreateSurface;
|
||||
video->showSurface = gdiVideoShowSurface;
|
||||
video->deleteSurface = gdiVideoDeleteSurface;
|
||||
video->setGeometry(video, gdi->geometry);
|
||||
}
|
||||
|
||||
void gdi_video_control_uninit(rdpGdi* gdi, WINPR_ATTR_UNUSED VideoClientContext* video)
|
||||
{
|
||||
WINPR_ASSERT(gdi);
|
||||
gdi->video = nullptr;
|
||||
}
|
||||
|
||||
void gdi_video_data_init(WINPR_ATTR_UNUSED rdpGdi* gdi, WINPR_ATTR_UNUSED VideoClientContext* video)
|
||||
{
|
||||
WINPR_ASSERT(gdi);
|
||||
WINPR_ASSERT(gdi->context);
|
||||
}
|
||||
|
||||
void gdi_video_data_uninit(WINPR_ATTR_UNUSED rdpGdi* gdi,
|
||||
WINPR_ATTR_UNUSED VideoClientContext* context)
|
||||
{
|
||||
WINPR_ASSERT(gdi);
|
||||
WINPR_ASSERT(gdi->context);
|
||||
}
|
||||
|
||||
VideoSurface* VideoClient_CreateCommonContext(size_t size, UINT32 x, UINT32 y, UINT32 w, UINT32 h)
|
||||
{
|
||||
VideoSurface* ret = nullptr;
|
||||
|
||||
WINPR_ASSERT(size >= sizeof(VideoSurface));
|
||||
|
||||
ret = calloc(1, size);
|
||||
if (!ret)
|
||||
return nullptr;
|
||||
|
||||
ret->format = PIXEL_FORMAT_BGRX32;
|
||||
ret->x = x;
|
||||
ret->y = y;
|
||||
ret->w = w;
|
||||
ret->h = h;
|
||||
ret->alignedWidth = ret->w + 32 - ret->w % 16;
|
||||
ret->alignedHeight = ret->h + 32 - ret->h % 16;
|
||||
|
||||
ret->scanline = ret->alignedWidth * FreeRDPGetBytesPerPixel(ret->format);
|
||||
ret->data = winpr_aligned_malloc(1ull * ret->scanline * ret->alignedHeight, 64);
|
||||
if (!ret->data)
|
||||
goto fail;
|
||||
return ret;
|
||||
fail:
|
||||
VideoClient_DestroyCommonContext(ret);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void VideoClient_DestroyCommonContext(VideoSurface* surface)
|
||||
{
|
||||
if (!surface)
|
||||
return;
|
||||
winpr_aligned_free(surface->data);
|
||||
free(surface);
|
||||
}
|
||||
Reference in New Issue
Block a user