mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 21:13:30 +08:00
[GDIPLUS] Sync with Wine 3.0. CORE-14225
This commit is contained in:
parent
7a00f240c6
commit
007122e774
@ -243,7 +243,7 @@ static const char HatchBrushes[][8] = {
|
|||||||
{ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */
|
{ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */
|
||||||
};
|
};
|
||||||
|
|
||||||
GpStatus get_hatch_data(HatchStyle hatchstyle, const char **result)
|
GpStatus get_hatch_data(GpHatchStyle hatchstyle, const char **result)
|
||||||
{
|
{
|
||||||
if (hatchstyle < sizeof(HatchBrushes) / sizeof(HatchBrushes[0]))
|
if (hatchstyle < sizeof(HatchBrushes) / sizeof(HatchBrushes[0]))
|
||||||
{
|
{
|
||||||
@ -257,12 +257,15 @@ GpStatus get_hatch_data(HatchStyle hatchstyle, const char **result)
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* GdipCreateHatchBrush [GDIPLUS.@]
|
* GdipCreateHatchBrush [GDIPLUS.@]
|
||||||
*/
|
*/
|
||||||
GpStatus WINGDIPAPI GdipCreateHatchBrush(HatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush)
|
GpStatus WINGDIPAPI GdipCreateHatchBrush(GpHatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush)
|
||||||
{
|
{
|
||||||
TRACE("(%d, %d, %d, %p)\n", hatchstyle, forecol, backcol, brush);
|
TRACE("(%d, %d, %d, %p)\n", hatchstyle, forecol, backcol, brush);
|
||||||
|
|
||||||
if(!brush) return InvalidParameter;
|
if(!brush) return InvalidParameter;
|
||||||
|
|
||||||
|
if(hatchstyle < HatchStyleMin || hatchstyle > HatchStyleMax)
|
||||||
|
return InvalidParameter;
|
||||||
|
|
||||||
*brush = heap_alloc_zero(sizeof(GpHatch));
|
*brush = heap_alloc_zero(sizeof(GpHatch));
|
||||||
if (!*brush) return OutOfMemory;
|
if (!*brush) return OutOfMemory;
|
||||||
|
|
||||||
@ -491,9 +494,12 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect
|
|||||||
TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
|
TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
|
||||||
wrap, line);
|
wrap, line);
|
||||||
|
|
||||||
if (!rect || !rect->Width || !rect->Height)
|
if (!rect || !line || wrap == WrapModeClamp)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
|
if (!rect->Width || !rect->Height)
|
||||||
|
return OutOfMemory;
|
||||||
|
|
||||||
angle = fmodf(angle, 360);
|
angle = fmodf(angle, 360);
|
||||||
if (angle < 0)
|
if (angle < 0)
|
||||||
angle += 360;
|
angle += 360;
|
||||||
@ -951,7 +957,7 @@ GpStatus WINGDIPAPI GdipGetHatchForegroundColor(GpHatch *brush, ARGB *forecol)
|
|||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipGetHatchStyle(GpHatch *brush, HatchStyle *hatchstyle)
|
GpStatus WINGDIPAPI GdipGetHatchStyle(GpHatch *brush, GpHatchStyle *hatchstyle)
|
||||||
{
|
{
|
||||||
TRACE("(%p, %p)\n", brush, hatchstyle);
|
TRACE("(%p, %p)\n", brush, hatchstyle);
|
||||||
|
|
||||||
|
@ -1378,33 +1378,36 @@ static int match_name_table_language( const tt_name_record *name, LANGID lang )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WCHAR *copy_name_table_string( const tt_name_record *name, const BYTE *data, WCHAR *ret, DWORD len )
|
static WCHAR *copy_name_table_string( const tt_name_record *name, const BYTE *data )
|
||||||
{
|
{
|
||||||
WORD name_len = GET_BE_WORD(name->length);
|
WORD name_len = GET_BE_WORD(name->length);
|
||||||
WORD codepage;
|
WORD codepage;
|
||||||
|
WCHAR *ret;
|
||||||
|
int len;
|
||||||
|
|
||||||
switch (GET_BE_WORD(name->platform_id))
|
switch (GET_BE_WORD(name->platform_id))
|
||||||
{
|
{
|
||||||
case TT_PLATFORM_APPLE_UNICODE:
|
case TT_PLATFORM_APPLE_UNICODE:
|
||||||
case TT_PLATFORM_MICROSOFT:
|
case TT_PLATFORM_MICROSOFT:
|
||||||
if (name_len >= len*sizeof(WCHAR))
|
ret = heap_alloc((name_len / 2 + 1) * sizeof(WCHAR));
|
||||||
return NULL;
|
|
||||||
for (len = 0; len < name_len / 2; len++)
|
for (len = 0; len < name_len / 2; len++)
|
||||||
ret[len] = (data[len * 2] << 8) | data[len * 2 + 1];
|
ret[len] = (data[len * 2] << 8) | data[len * 2 + 1];
|
||||||
ret[len] = 0;
|
ret[len] = 0;
|
||||||
return ret;
|
return ret;
|
||||||
case TT_PLATFORM_MACINTOSH:
|
case TT_PLATFORM_MACINTOSH:
|
||||||
codepage = get_mac_code_page( name );
|
codepage = get_mac_code_page( name );
|
||||||
len = MultiByteToWideChar( codepage, 0, (char *)data, name_len, ret, len-1 );
|
len = MultiByteToWideChar( codepage, 0, (char *)data, name_len, NULL, 0 ) + 1;
|
||||||
if (!len)
|
if (!len)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
ret = heap_alloc(len * sizeof(WCHAR));
|
||||||
|
len = MultiByteToWideChar( codepage, 0, (char *)data, name_len, ret, len - 1 );
|
||||||
ret[len] = 0;
|
ret[len] = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WCHAR *load_ttf_name_id( const BYTE *mem, DWORD_PTR size, DWORD id, WCHAR *ret, DWORD len )
|
static WCHAR *load_ttf_name_id( const BYTE *mem, DWORD_PTR size, DWORD id )
|
||||||
{
|
{
|
||||||
LANGID lang = GetSystemDefaultLangID();
|
LANGID lang = GetSystemDefaultLangID();
|
||||||
const tt_header *header;
|
const tt_header *header;
|
||||||
@ -1465,8 +1468,9 @@ static WCHAR *load_ttf_name_id( const BYTE *mem, DWORD_PTR size, DWORD id, WCHAR
|
|||||||
|
|
||||||
if (best_lang)
|
if (best_lang)
|
||||||
{
|
{
|
||||||
|
WCHAR *ret;
|
||||||
name_record = (const tt_name_record*)(name_table + 1) + best_index;
|
name_record = (const tt_name_record*)(name_table + 1) + best_index;
|
||||||
ret = copy_name_table_string( name_record, mem+ofs+GET_BE_WORD(name_record->offset), ret, len );
|
ret = copy_name_table_string( name_record, mem+ofs+GET_BE_WORD(name_record->offset) );
|
||||||
TRACE( "name %u found platform %u lang %04x %s\n", GET_BE_WORD(name_record->name_id),
|
TRACE( "name %u found platform %u lang %04x %s\n", GET_BE_WORD(name_record->name_id),
|
||||||
GET_BE_WORD(name_record->platform_id), GET_BE_WORD(name_record->language_id), debugstr_w( ret ));
|
GET_BE_WORD(name_record->platform_id), GET_BE_WORD(name_record->language_id), debugstr_w( ret ));
|
||||||
return ret;
|
return ret;
|
||||||
@ -1482,43 +1486,45 @@ static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm, D
|
|||||||
GpStatus WINGDIPAPI GdipPrivateAddMemoryFont(GpFontCollection* fontCollection,
|
GpStatus WINGDIPAPI GdipPrivateAddMemoryFont(GpFontCollection* fontCollection,
|
||||||
GDIPCONST void* memory, INT length)
|
GDIPCONST void* memory, INT length)
|
||||||
{
|
{
|
||||||
WCHAR buf[32], *name;
|
WCHAR *name;
|
||||||
DWORD count = 0;
|
DWORD count = 0;
|
||||||
HANDLE font;
|
HANDLE font;
|
||||||
|
GpStatus ret = Ok;
|
||||||
TRACE("%p, %p, %d\n", fontCollection, memory, length);
|
TRACE("%p, %p, %d\n", fontCollection, memory, length);
|
||||||
|
|
||||||
if (!fontCollection || !memory || !length)
|
if (!fontCollection || !memory || !length)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
name = load_ttf_name_id(memory, length, NAME_ID_FULL_FONT_NAME, buf, sizeof(buf)/sizeof(*buf));
|
name = load_ttf_name_id(memory, length, NAME_ID_FULL_FONT_NAME);
|
||||||
if (!name)
|
if (!name)
|
||||||
return OutOfMemory;
|
return OutOfMemory;
|
||||||
|
|
||||||
font = AddFontMemResourceEx((void*)memory, length, NULL, &count);
|
font = AddFontMemResourceEx((void*)memory, length, NULL, &count);
|
||||||
TRACE("%s: %p/%u\n", debugstr_w(name), font, count);
|
TRACE("%s: %p/%u\n", debugstr_w(name), font, count);
|
||||||
if (!font || !count)
|
if (!font || !count)
|
||||||
return InvalidParameter;
|
ret = InvalidParameter;
|
||||||
|
else
|
||||||
if (count)
|
|
||||||
{
|
{
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
LOGFONTW lfw;
|
LOGFONTW lfw;
|
||||||
|
|
||||||
hdc = CreateCompatibleDC(0);
|
hdc = CreateCompatibleDC(0);
|
||||||
|
|
||||||
|
/* Truncate name if necessary, GDI32 can't deal with long names */
|
||||||
|
if(lstrlenW(name) > LF_FACESIZE - 1)
|
||||||
|
name[LF_FACESIZE - 1] = 0;
|
||||||
|
|
||||||
lfw.lfCharSet = DEFAULT_CHARSET;
|
lfw.lfCharSet = DEFAULT_CHARSET;
|
||||||
lstrcpyW(lfw.lfFaceName, name);
|
lstrcpyW(lfw.lfFaceName, name);
|
||||||
lfw.lfPitchAndFamily = 0;
|
lfw.lfPitchAndFamily = 0;
|
||||||
|
|
||||||
if (!EnumFontFamiliesExW(hdc, &lfw, add_font_proc, (LPARAM)fontCollection, 0))
|
if (!EnumFontFamiliesExW(hdc, &lfw, add_font_proc, (LPARAM)fontCollection, 0))
|
||||||
{
|
ret = OutOfMemory;
|
||||||
DeleteDC(hdc);
|
|
||||||
return OutOfMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeleteDC(hdc);
|
DeleteDC(hdc);
|
||||||
}
|
}
|
||||||
return Ok;
|
heap_free(name);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -615,7 +615,7 @@
|
|||||||
615 stub GdipGetEffectParameterSize
|
615 stub GdipGetEffectParameterSize
|
||||||
616 stub GdipGetEffectParameters
|
616 stub GdipGetEffectParameters
|
||||||
617 stdcall GdipSetEffectParameters(ptr ptr long)
|
617 stdcall GdipSetEffectParameters(ptr ptr long)
|
||||||
618 stdcall GdipInitializePalette(ptr long long long ptr)
|
618 stdcall -stub GdipInitializePalette(ptr long long long ptr)
|
||||||
619 stdcall GdipBitmapCreateApplyEffect(ptr long ptr ptr ptr ptr long ptr ptr)
|
619 stdcall GdipBitmapCreateApplyEffect(ptr long ptr ptr ptr ptr long ptr ptr)
|
||||||
620 stdcall GdipBitmapApplyEffect(ptr ptr ptr long ptr ptr)
|
620 stdcall GdipBitmapApplyEffect(ptr ptr ptr long ptr ptr)
|
||||||
621 stdcall GdipBitmapGetHistogram(ptr long long ptr ptr ptr ptr)
|
621 stdcall GdipBitmapGetHistogram(ptr long long ptr ptr ptr ptr)
|
||||||
|
@ -129,6 +129,7 @@ extern GpStatus METAFILE_DrawImagePointsRect(GpMetafile* metafile, GpImage *imag
|
|||||||
extern GpStatus METAFILE_AddSimpleProperty(GpMetafile *metafile, SHORT prop, SHORT val) DECLSPEC_HIDDEN;
|
extern GpStatus METAFILE_AddSimpleProperty(GpMetafile *metafile, SHORT prop, SHORT val) DECLSPEC_HIDDEN;
|
||||||
extern GpStatus METAFILE_DrawPath(GpMetafile *metafile, GpPen *pen, GpPath *path) DECLSPEC_HIDDEN;
|
extern GpStatus METAFILE_DrawPath(GpMetafile *metafile, GpPen *pen, GpPath *path) DECLSPEC_HIDDEN;
|
||||||
extern GpStatus METAFILE_FillPath(GpMetafile *metafile, GpBrush *brush, GpPath *path) DECLSPEC_HIDDEN;
|
extern GpStatus METAFILE_FillPath(GpMetafile *metafile, GpBrush *brush, GpPath *path) DECLSPEC_HIDDEN;
|
||||||
|
extern void METAFILE_Free(GpMetafile *metafile) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern void calc_curve_bezier(const GpPointF *pts, REAL tension, REAL *x1,
|
extern void calc_curve_bezier(const GpPointF *pts, REAL tension, REAL *x1,
|
||||||
REAL *y1, REAL *x2, REAL *y2) DECLSPEC_HIDDEN;
|
REAL *y1, REAL *x2, REAL *y2) DECLSPEC_HIDDEN;
|
||||||
@ -147,7 +148,7 @@ extern GpStatus trace_path(GpGraphics *graphics, GpPath *path) DECLSPEC_HIDDEN;
|
|||||||
typedef struct region_element region_element;
|
typedef struct region_element region_element;
|
||||||
extern void delete_element(region_element *element) DECLSPEC_HIDDEN;
|
extern void delete_element(region_element *element) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern GpStatus get_hatch_data(HatchStyle hatchstyle, const char **result) DECLSPEC_HIDDEN;
|
extern GpStatus get_hatch_data(GpHatchStyle hatchstyle, const char **result) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
static inline INT gdip_round(REAL x)
|
static inline INT gdip_round(REAL x)
|
||||||
{
|
{
|
||||||
@ -270,6 +271,7 @@ struct GpGraphics{
|
|||||||
INT origin_x, origin_y;
|
INT origin_x, origin_y;
|
||||||
INT gdi_transform_acquire_count, gdi_transform_save;
|
INT gdi_transform_acquire_count, gdi_transform_save;
|
||||||
GpMatrix gdi_transform;
|
GpMatrix gdi_transform;
|
||||||
|
HRGN gdi_clip;
|
||||||
/* For giving the caller an HDC when we technically can't: */
|
/* For giving the caller an HDC when we technically can't: */
|
||||||
HBITMAP temp_hbitmap;
|
HBITMAP temp_hbitmap;
|
||||||
int temp_hbitmap_width;
|
int temp_hbitmap_width;
|
||||||
@ -284,7 +286,7 @@ struct GpBrush{
|
|||||||
|
|
||||||
struct GpHatch{
|
struct GpHatch{
|
||||||
GpBrush brush;
|
GpBrush brush;
|
||||||
HatchStyle hatchstyle;
|
GpHatchStyle hatchstyle;
|
||||||
ARGB forecol;
|
ARGB forecol;
|
||||||
ARGB backcol;
|
ARGB backcol;
|
||||||
};
|
};
|
||||||
@ -378,6 +380,38 @@ struct GpImage{
|
|||||||
LONG busy;
|
LONG busy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define EmfPlusObjectTableSize 64
|
||||||
|
|
||||||
|
typedef enum EmfPlusObjectType
|
||||||
|
{
|
||||||
|
ObjectTypeInvalid,
|
||||||
|
ObjectTypeBrush,
|
||||||
|
ObjectTypePen,
|
||||||
|
ObjectTypePath,
|
||||||
|
ObjectTypeRegion,
|
||||||
|
ObjectTypeImage,
|
||||||
|
ObjectTypeFont,
|
||||||
|
ObjectTypeStringFormat,
|
||||||
|
ObjectTypeImageAttributes,
|
||||||
|
ObjectTypeCustomLineCap,
|
||||||
|
ObjectTypeMax = ObjectTypeCustomLineCap,
|
||||||
|
} EmfPlusObjectType;
|
||||||
|
|
||||||
|
/* Deserialized EmfPlusObject record. */
|
||||||
|
struct emfplus_object {
|
||||||
|
EmfPlusObjectType type;
|
||||||
|
union {
|
||||||
|
GpBrush *brush;
|
||||||
|
GpPen *pen;
|
||||||
|
GpPath *path;
|
||||||
|
GpRegion *region;
|
||||||
|
GpImage *image;
|
||||||
|
GpFont *font;
|
||||||
|
GpImageAttributes *image_attributes;
|
||||||
|
void *object;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
struct GpMetafile{
|
struct GpMetafile{
|
||||||
GpImage image;
|
GpImage image;
|
||||||
GpRectF bounds;
|
GpRectF bounds;
|
||||||
@ -411,6 +445,7 @@ struct GpMetafile{
|
|||||||
GpRegion *base_clip; /* clip region in device space for all metafile output */
|
GpRegion *base_clip; /* clip region in device space for all metafile output */
|
||||||
GpRegion *clip; /* clip region within the metafile */
|
GpRegion *clip; /* clip region within the metafile */
|
||||||
struct list containers;
|
struct list containers;
|
||||||
|
struct emfplus_object objtable[EmfPlusObjectTableSize];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GpBitmap{
|
struct GpBitmap{
|
||||||
@ -454,6 +489,12 @@ struct color_remap_table{
|
|||||||
ColorMap *colormap;
|
ColorMap *colormap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum imageattr_noop{
|
||||||
|
IMAGEATTR_NOOP_UNDEFINED,
|
||||||
|
IMAGEATTR_NOOP_SET,
|
||||||
|
IMAGEATTR_NOOP_CLEAR,
|
||||||
|
};
|
||||||
|
|
||||||
struct GpImageAttributes{
|
struct GpImageAttributes{
|
||||||
WrapMode wrap;
|
WrapMode wrap;
|
||||||
ARGB outside_color;
|
ARGB outside_color;
|
||||||
@ -463,6 +504,7 @@ struct GpImageAttributes{
|
|||||||
struct color_remap_table colorremaptables[ColorAdjustTypeCount];
|
struct color_remap_table colorremaptables[ColorAdjustTypeCount];
|
||||||
BOOL gamma_enabled[ColorAdjustTypeCount];
|
BOOL gamma_enabled[ColorAdjustTypeCount];
|
||||||
REAL gamma[ColorAdjustTypeCount];
|
REAL gamma[ColorAdjustTypeCount];
|
||||||
|
enum imageattr_noop noop[ColorAdjustTypeCount];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GpFont{
|
struct GpFont{
|
||||||
@ -535,6 +577,30 @@ struct GpRegion{
|
|||||||
region_element node;
|
region_element node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct memory_buffer
|
||||||
|
{
|
||||||
|
const BYTE *buffer;
|
||||||
|
INT size, pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void init_memory_buffer(struct memory_buffer *mbuf, const BYTE *buffer, INT size)
|
||||||
|
{
|
||||||
|
mbuf->buffer = buffer;
|
||||||
|
mbuf->size = size;
|
||||||
|
mbuf->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const void *buffer_read(struct memory_buffer *mbuf, INT size)
|
||||||
|
{
|
||||||
|
if (mbuf->size - mbuf->pos >= size)
|
||||||
|
{
|
||||||
|
const void *data = mbuf->buffer + mbuf->pos;
|
||||||
|
mbuf->pos += size;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
typedef GpStatus (*gdip_format_string_callback)(HDC hdc,
|
typedef GpStatus (*gdip_format_string_callback)(HDC hdc,
|
||||||
GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
|
GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
|
||||||
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
|
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
|
||||||
|
@ -302,13 +302,6 @@ static void round_points(POINT *pti, GpPointF *ptf, INT count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void transform_and_round_points(GpGraphics *graphics, POINT *pti,
|
|
||||||
GpPointF *ptf, INT count)
|
|
||||||
{
|
|
||||||
gdip_transform_points(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, count);
|
|
||||||
round_points(pti, ptf, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gdi_alpha_blend(GpGraphics *graphics, INT dst_x, INT dst_y, INT dst_width, INT dst_height,
|
static void gdi_alpha_blend(GpGraphics *graphics, INT dst_x, INT dst_y, INT dst_width, INT dst_height,
|
||||||
HDC hdc, INT src_x, INT src_y, INT src_width, INT src_height)
|
HDC hdc, INT src_x, INT src_y, INT src_width, INT src_height)
|
||||||
{
|
{
|
||||||
@ -355,6 +348,17 @@ static GpStatus get_clip_hrgn(GpGraphics *graphics, HRGN *hrgn)
|
|||||||
GdipDeleteRegion(rgn);
|
GdipDeleteRegion(rgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stat == Ok && graphics->gdi_clip)
|
||||||
|
{
|
||||||
|
if (*hrgn)
|
||||||
|
CombineRgn(*hrgn, *hrgn, graphics->gdi_clip, RGN_AND);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*hrgn = CreateRectRgn(0,0,0,0);
|
||||||
|
CombineRgn(*hrgn, graphics->gdi_clip, graphics->gdi_clip, RGN_COPY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,8 +509,6 @@ static GpStatus alpha_blend_pixels_hrgn(GpGraphics *graphics, INT dst_x, INT dst
|
|||||||
|
|
||||||
save = SaveDC(graphics->hdc);
|
save = SaveDC(graphics->hdc);
|
||||||
|
|
||||||
SetViewportOrgEx(graphics->hdc, 0, 0, NULL);
|
|
||||||
|
|
||||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
|
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
|
||||||
|
|
||||||
if (hregion)
|
if (hregion)
|
||||||
@ -529,23 +531,12 @@ static GpStatus alpha_blend_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
|
|||||||
return alpha_blend_pixels_hrgn(graphics, dst_x, dst_y, src, src_width, src_height, src_stride, NULL, fmt);
|
return alpha_blend_pixels_hrgn(graphics, dst_x, dst_y, src, src_width, src_height, src_stride, NULL, fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: start and end pixels must be in pre-multiplied ARGB format */
|
|
||||||
static inline ARGB blend_colors_premult(ARGB start, ARGB end, REAL position)
|
|
||||||
{
|
|
||||||
UINT pos = position * 255.0f + 0.5f;
|
|
||||||
return
|
|
||||||
(((((start >> 24) ) << 8) + (((end >> 24) ) - ((start >> 24) )) * pos) >> 8) << 24 |
|
|
||||||
(((((start >> 16) & 0xff) << 8) + (((end >> 16) & 0xff) - ((start >> 16) & 0xff)) * pos) >> 8) << 16 |
|
|
||||||
(((((start >> 8) & 0xff) << 8) + (((end >> 8) & 0xff) - ((start >> 8) & 0xff)) * pos) >> 8) << 8 |
|
|
||||||
(((((start ) & 0xff) << 8) + (((end ) & 0xff) - ((start ) & 0xff)) * pos) >> 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ARGB blend_colors(ARGB start, ARGB end, REAL position)
|
static ARGB blend_colors(ARGB start, ARGB end, REAL position)
|
||||||
{
|
{
|
||||||
INT start_a, end_a, final_a;
|
INT start_a, end_a, final_a;
|
||||||
INT pos;
|
INT pos;
|
||||||
|
|
||||||
pos = (INT)(position * 255.0f + 0.5f);
|
pos = gdip_round(position * 0xff);
|
||||||
|
|
||||||
start_a = ((start >> 24) & 0xff) * (pos ^ 0xff);
|
start_a = ((start >> 24) & 0xff) * (pos ^ 0xff);
|
||||||
end_a = ((end >> 24) & 0xff) * pos;
|
end_a = ((end >> 24) & 0xff) * pos;
|
||||||
@ -685,6 +676,11 @@ PixelFormat apply_image_attributes(const GpImageAttributes *attributes, LPBYTE d
|
|||||||
UINT x, y;
|
UINT x, y;
|
||||||
INT i;
|
INT i;
|
||||||
|
|
||||||
|
if ((attributes->noop[type] == IMAGEATTR_NOOP_UNDEFINED &&
|
||||||
|
attributes->noop[ColorAdjustTypeDefault] == IMAGEATTR_NOOP_SET) ||
|
||||||
|
(attributes->noop[type] == IMAGEATTR_NOOP_SET))
|
||||||
|
return fmt;
|
||||||
|
|
||||||
if (attributes->colorkeys[type].enabled ||
|
if (attributes->colorkeys[type].enabled ||
|
||||||
attributes->colorkeys[ColorAdjustTypeDefault].enabled)
|
attributes->colorkeys[ColorAdjustTypeDefault].enabled)
|
||||||
{
|
{
|
||||||
@ -946,11 +942,6 @@ static ARGB sample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT wi
|
|||||||
return ((DWORD*)(bits))[(x - src_rect->X) + (y - src_rect->Y) * src_rect->Width];
|
return ((DWORD*)(bits))[(x - src_rect->X) + (y - src_rect->Y) * src_rect->Width];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int positive_ceilf(float f)
|
|
||||||
{
|
|
||||||
return f - (int)f > 0.0f ? f + 1.0f : f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ARGB resample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT width,
|
static ARGB resample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT width,
|
||||||
UINT height, GpPointF *point, GDIPCONST GpImageAttributes *attributes,
|
UINT height, GpPointF *point, GDIPCONST GpImageAttributes *attributes,
|
||||||
InterpolationMode interpolation, PixelOffsetMode offset_mode)
|
InterpolationMode interpolation, PixelOffsetMode offset_mode)
|
||||||
@ -971,12 +962,12 @@ static ARGB resample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT
|
|||||||
ARGB top, bottom;
|
ARGB top, bottom;
|
||||||
float x_offset;
|
float x_offset;
|
||||||
|
|
||||||
leftx = (INT)point->X;
|
leftxf = floorf(point->X);
|
||||||
leftxf = (REAL)leftx;
|
leftx = (INT)leftxf;
|
||||||
rightx = positive_ceilf(point->X);
|
rightx = (INT)ceilf(point->X);
|
||||||
topy = (INT)point->Y;
|
topyf = floorf(point->Y);
|
||||||
topyf = (REAL)topy;
|
topy = (INT)topyf;
|
||||||
bottomy = positive_ceilf(point->Y);
|
bottomy = (INT)ceilf(point->Y);
|
||||||
|
|
||||||
if (leftx == rightx && topy == bottomy)
|
if (leftx == rightx && topy == bottomy)
|
||||||
return sample_bitmap_pixel(src_rect, bits, width, height,
|
return sample_bitmap_pixel(src_rect, bits, width, height,
|
||||||
@ -1020,75 +1011,6 @@ static ARGB resample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ARGB resample_bitmap_pixel_premult(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT width,
|
|
||||||
UINT height, GpPointF *point, GDIPCONST GpImageAttributes *attributes,
|
|
||||||
InterpolationMode interpolation, PixelOffsetMode offset_mode)
|
|
||||||
{
|
|
||||||
static int fixme;
|
|
||||||
|
|
||||||
switch (interpolation)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
if (!fixme++)
|
|
||||||
FIXME("Unimplemented interpolation %i\n", interpolation);
|
|
||||||
/* fall-through */
|
|
||||||
case InterpolationModeBilinear:
|
|
||||||
{
|
|
||||||
REAL leftxf, topyf;
|
|
||||||
INT leftx, rightx, topy, bottomy;
|
|
||||||
ARGB topleft, topright, bottomleft, bottomright;
|
|
||||||
ARGB top, bottom;
|
|
||||||
float x_offset;
|
|
||||||
|
|
||||||
leftx = (INT)point->X;
|
|
||||||
leftxf = (REAL)leftx;
|
|
||||||
rightx = positive_ceilf(point->X);
|
|
||||||
topy = (INT)point->Y;
|
|
||||||
topyf = (REAL)topy;
|
|
||||||
bottomy = positive_ceilf(point->Y);
|
|
||||||
|
|
||||||
if (leftx == rightx && topy == bottomy)
|
|
||||||
return sample_bitmap_pixel(src_rect, bits, width, height,
|
|
||||||
leftx, topy, attributes);
|
|
||||||
|
|
||||||
topleft = sample_bitmap_pixel(src_rect, bits, width, height,
|
|
||||||
leftx, topy, attributes);
|
|
||||||
topright = sample_bitmap_pixel(src_rect, bits, width, height,
|
|
||||||
rightx, topy, attributes);
|
|
||||||
bottomleft = sample_bitmap_pixel(src_rect, bits, width, height,
|
|
||||||
leftx, bottomy, attributes);
|
|
||||||
bottomright = sample_bitmap_pixel(src_rect, bits, width, height,
|
|
||||||
rightx, bottomy, attributes);
|
|
||||||
|
|
||||||
x_offset = point->X - leftxf;
|
|
||||||
top = blend_colors_premult(topleft, topright, x_offset);
|
|
||||||
bottom = blend_colors_premult(bottomleft, bottomright, x_offset);
|
|
||||||
|
|
||||||
return blend_colors_premult(top, bottom, point->Y - topyf);
|
|
||||||
}
|
|
||||||
case InterpolationModeNearestNeighbor:
|
|
||||||
{
|
|
||||||
FLOAT pixel_offset;
|
|
||||||
switch (offset_mode)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case PixelOffsetModeNone:
|
|
||||||
case PixelOffsetModeHighSpeed:
|
|
||||||
pixel_offset = 0.5;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PixelOffsetModeHalf:
|
|
||||||
case PixelOffsetModeHighQuality:
|
|
||||||
pixel_offset = 0.0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return sample_bitmap_pixel(src_rect, bits, width, height,
|
|
||||||
floorf(point->X + pixel_offset), point->Y + pixel_offset, attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static REAL intersect_line_scanline(const GpPointF *p1, const GpPointF *p2, REAL y)
|
static REAL intersect_line_scanline(const GpPointF *p1, const GpPointF *p2, REAL y)
|
||||||
{
|
{
|
||||||
return (p1->X - p2->X) * (p2->Y - y) / (p2->Y - p1->Y) + p2->X;
|
return (p1->X - p2->X) * (p2->Y - y) / (p2->Y - p1->Y) + p2->X;
|
||||||
@ -2312,7 +2234,7 @@ static void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font,
|
|||||||
GdipTransformMatrixPoints(&xform, pt, 3);
|
GdipTransformMatrixPoints(&xform, pt, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, pt, 3);
|
||||||
angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
|
angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
|
||||||
rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
|
rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
|
||||||
(pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
|
(pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
|
||||||
@ -2342,6 +2264,20 @@ GpStatus WINGDIPAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics)
|
|||||||
return GdipCreateFromHDC2(hdc, NULL, graphics);
|
return GdipCreateFromHDC2(hdc, NULL, graphics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void get_gdi_transform(GpGraphics *graphics, GpMatrix *matrix)
|
||||||
|
{
|
||||||
|
XFORM xform;
|
||||||
|
|
||||||
|
if (graphics->hdc == NULL)
|
||||||
|
{
|
||||||
|
GdipSetMatrixElements(matrix, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetTransform(graphics->hdc, 0x204, &xform);
|
||||||
|
GdipSetMatrixElements(matrix, xform.eM11, xform.eM12, xform.eM21, xform.eM22, xform.eDx, xform.eDy);
|
||||||
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **graphics)
|
GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **graphics)
|
||||||
{
|
{
|
||||||
GpStatus retval;
|
GpStatus retval;
|
||||||
@ -2391,7 +2327,19 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra
|
|||||||
(*graphics)->busy = FALSE;
|
(*graphics)->busy = FALSE;
|
||||||
(*graphics)->textcontrast = 4;
|
(*graphics)->textcontrast = 4;
|
||||||
list_init(&(*graphics)->containers);
|
list_init(&(*graphics)->containers);
|
||||||
|
#ifdef __REACTOS__
|
||||||
(*graphics)->contid = GDIP_GET_NEW_CONTID_FOR(*graphics);
|
(*graphics)->contid = GDIP_GET_NEW_CONTID_FOR(*graphics);
|
||||||
|
#else
|
||||||
|
(*graphics)->contid = 0;
|
||||||
|
#endif
|
||||||
|
get_gdi_transform(*graphics, &(*graphics)->gdi_transform);
|
||||||
|
|
||||||
|
(*graphics)->gdi_clip = CreateRectRgn(0,0,0,0);
|
||||||
|
if (!GetClipRgn(hdc, (*graphics)->gdi_clip))
|
||||||
|
{
|
||||||
|
DeleteObject((*graphics)->gdi_clip);
|
||||||
|
(*graphics)->gdi_clip = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("<-- %p\n", *graphics);
|
TRACE("<-- %p\n", *graphics);
|
||||||
|
|
||||||
@ -2406,6 +2354,7 @@ GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics)
|
|||||||
if(!*graphics) return OutOfMemory;
|
if(!*graphics) return OutOfMemory;
|
||||||
|
|
||||||
GdipSetMatrixElements(&(*graphics)->worldtrans, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
GdipSetMatrixElements(&(*graphics)->worldtrans, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||||
|
GdipSetMatrixElements(&(*graphics)->gdi_transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||||
|
|
||||||
if((retval = GdipCreateRegion(&(*graphics)->clip)) != Ok){
|
if((retval = GdipCreateRegion(&(*graphics)->clip)) != Ok){
|
||||||
heap_free(*graphics);
|
heap_free(*graphics);
|
||||||
@ -2431,7 +2380,11 @@ GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics)
|
|||||||
(*graphics)->busy = FALSE;
|
(*graphics)->busy = FALSE;
|
||||||
(*graphics)->textcontrast = 4;
|
(*graphics)->textcontrast = 4;
|
||||||
list_init(&(*graphics)->containers);
|
list_init(&(*graphics)->containers);
|
||||||
|
#ifdef __REACTOS__
|
||||||
(*graphics)->contid = GDIP_GET_NEW_CONTID_FOR(*graphics);
|
(*graphics)->contid = GDIP_GET_NEW_CONTID_FOR(*graphics);
|
||||||
|
#else
|
||||||
|
(*graphics)->contid = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
TRACE("<-- %p\n", *graphics);
|
TRACE("<-- %p\n", *graphics);
|
||||||
|
|
||||||
@ -2516,6 +2469,8 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
|
|||||||
|
|
||||||
GdipDeleteRegion(graphics->clip);
|
GdipDeleteRegion(graphics->clip);
|
||||||
|
|
||||||
|
DeleteObject(graphics->gdi_clip);
|
||||||
|
|
||||||
/* Native returns ObjectBusy on the second free, instead of crashing as we'd
|
/* Native returns ObjectBusy on the second free, instead of crashing as we'd
|
||||||
* do otherwise, but we can't have that in the test suite because it means
|
* do otherwise, but we can't have that in the test suite because it means
|
||||||
* accessing freed memory. */
|
* accessing freed memory. */
|
||||||
@ -3151,10 +3106,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
|
|||||||
lockeddata.Scan0 = src_data;
|
lockeddata.Scan0 = src_data;
|
||||||
if (!do_resampling && bitmap->format == PixelFormat32bppPARGB)
|
if (!do_resampling && bitmap->format == PixelFormat32bppPARGB)
|
||||||
lockeddata.PixelFormat = apply_image_attributes(imageAttributes, NULL, 0, 0, 0, ColorAdjustTypeBitmap, bitmap->format);
|
lockeddata.PixelFormat = apply_image_attributes(imageAttributes, NULL, 0, 0, 0, ColorAdjustTypeBitmap, bitmap->format);
|
||||||
else if (imageAttributes != &defaultImageAttributes)
|
|
||||||
lockeddata.PixelFormat = PixelFormat32bppARGB;
|
|
||||||
else
|
else
|
||||||
lockeddata.PixelFormat = PixelFormat32bppPARGB;
|
lockeddata.PixelFormat = PixelFormat32bppARGB;
|
||||||
|
|
||||||
stat = GdipBitmapLockBits(bitmap, &src_area, ImageLockModeRead|ImageLockModeUserInputBuf,
|
stat = GdipBitmapLockBits(bitmap, &src_area, ImageLockModeRead|ImageLockModeUserInputBuf,
|
||||||
lockeddata.PixelFormat, &lockeddata);
|
lockeddata.PixelFormat, &lockeddata);
|
||||||
@ -3174,8 +3127,6 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
|
|||||||
|
|
||||||
if (do_resampling)
|
if (do_resampling)
|
||||||
{
|
{
|
||||||
REAL delta_xx, delta_xy, delta_yx, delta_yy;
|
|
||||||
|
|
||||||
/* Transform the bits as needed to the destination. */
|
/* Transform the bits as needed to the destination. */
|
||||||
dst_data = dst_dyn_data = heap_alloc_zero(sizeof(ARGB) * (dst_area.right - dst_area.left) * (dst_area.bottom - dst_area.top));
|
dst_data = dst_dyn_data = heap_alloc_zero(sizeof(ARGB) * (dst_area.right - dst_area.left) * (dst_area.bottom - dst_area.top));
|
||||||
if (!dst_data)
|
if (!dst_data)
|
||||||
@ -3193,42 +3144,24 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
|
|||||||
y_dx = dst_to_src_points[2].X - dst_to_src_points[0].X;
|
y_dx = dst_to_src_points[2].X - dst_to_src_points[0].X;
|
||||||
y_dy = dst_to_src_points[2].Y - dst_to_src_points[0].Y;
|
y_dy = dst_to_src_points[2].Y - dst_to_src_points[0].Y;
|
||||||
|
|
||||||
delta_yy = dst_area.top * y_dy;
|
for (x=dst_area.left; x<dst_area.right; x++)
|
||||||
delta_yx = dst_area.top * y_dx;
|
|
||||||
|
|
||||||
for (y=dst_area.top; y<dst_area.bottom; y++)
|
|
||||||
{
|
{
|
||||||
delta_xx = dst_area.left * x_dx;
|
for (y=dst_area.top; y<dst_area.bottom; y++)
|
||||||
delta_xy = dst_area.left * x_dy;
|
|
||||||
|
|
||||||
for (x=dst_area.left; x<dst_area.right; x++)
|
|
||||||
{
|
{
|
||||||
GpPointF src_pointf;
|
GpPointF src_pointf;
|
||||||
ARGB *dst_color;
|
ARGB *dst_color;
|
||||||
|
|
||||||
src_pointf.X = dst_to_src_points[0].X + delta_xx + delta_yx;
|
src_pointf.X = dst_to_src_points[0].X + x * x_dx + y * y_dx;
|
||||||
src_pointf.Y = dst_to_src_points[0].Y + delta_xy + delta_yy;
|
src_pointf.Y = dst_to_src_points[0].Y + x * x_dy + y * y_dy;
|
||||||
|
|
||||||
dst_color = (ARGB*)(dst_data + dst_stride * (y - dst_area.top) + sizeof(ARGB) * (x - dst_area.left));
|
dst_color = (ARGB*)(dst_data + dst_stride * (y - dst_area.top) + sizeof(ARGB) * (x - dst_area.left));
|
||||||
|
|
||||||
if (src_pointf.X >= srcx && src_pointf.X < srcx + srcwidth && src_pointf.Y >= srcy && src_pointf.Y < srcy+srcheight)
|
if (src_pointf.X >= srcx && src_pointf.X < srcx + srcwidth && src_pointf.Y >= srcy && src_pointf.Y < srcy+srcheight)
|
||||||
{
|
*dst_color = resample_bitmap_pixel(&src_area, src_data, bitmap->width, bitmap->height, &src_pointf,
|
||||||
if (lockeddata.PixelFormat != PixelFormat32bppPARGB)
|
imageAttributes, interpolation, offset_mode);
|
||||||
*dst_color = resample_bitmap_pixel(&src_area, src_data, bitmap->width, bitmap->height, &src_pointf,
|
|
||||||
imageAttributes, interpolation, offset_mode);
|
|
||||||
else
|
|
||||||
*dst_color = resample_bitmap_pixel_premult(&src_area, src_data, bitmap->width, bitmap->height, &src_pointf,
|
|
||||||
imageAttributes, interpolation, offset_mode);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
*dst_color = 0;
|
*dst_color = 0;
|
||||||
|
|
||||||
delta_xx += x_dx;
|
|
||||||
delta_yx += y_dx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delta_xy += x_dy;
|
|
||||||
delta_yy += y_dy;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3322,9 +3255,9 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
|
|||||||
|
|
||||||
stat = get_clip_hrgn(graphics, &hrgn);
|
stat = get_clip_hrgn(graphics, &hrgn);
|
||||||
|
|
||||||
if (stat == Ok && hrgn)
|
if (stat == Ok)
|
||||||
{
|
{
|
||||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
|
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
|
||||||
DeleteObject(hrgn);
|
DeleteObject(hrgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3565,8 +3498,7 @@ static GpStatus GDI32_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *pat
|
|||||||
if (retval != Ok)
|
if (retval != Ok)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (hrgn)
|
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
|
||||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
|
|
||||||
|
|
||||||
gdi_transform_acquire(graphics);
|
gdi_transform_acquire(graphics);
|
||||||
|
|
||||||
@ -3907,7 +3839,7 @@ static GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *
|
|||||||
points[1].X = pen->width;
|
points[1].X = pen->width;
|
||||||
points[2].Y = pen->width;
|
points[2].Y = pen->width;
|
||||||
|
|
||||||
stat = GdipTransformPoints(graphics, CoordinateSpaceDevice,
|
stat = gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice,
|
||||||
CoordinateSpaceWorld, points, 3);
|
CoordinateSpaceWorld, points, 3);
|
||||||
|
|
||||||
if (stat != Ok)
|
if (stat != Ok)
|
||||||
@ -3931,7 +3863,7 @@ static GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *
|
|||||||
stat = GdipCreateMatrix(&transform);
|
stat = GdipCreateMatrix(&transform);
|
||||||
|
|
||||||
if (stat == Ok)
|
if (stat == Ok)
|
||||||
stat = get_graphics_transform(graphics, CoordinateSpaceDevice,
|
stat = get_graphics_transform(graphics, WineCoordinateSpaceGdiDevice,
|
||||||
CoordinateSpaceWorld, transform);
|
CoordinateSpaceWorld, transform);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3939,7 +3871,7 @@ static GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *
|
|||||||
/* Set flatness based on the final coordinate space */
|
/* Set flatness based on the final coordinate space */
|
||||||
GpMatrix t;
|
GpMatrix t;
|
||||||
|
|
||||||
stat = get_graphics_transform(graphics, CoordinateSpaceDevice,
|
stat = get_graphics_transform(graphics, WineCoordinateSpaceGdiDevice,
|
||||||
CoordinateSpaceWorld, &t);
|
CoordinateSpaceWorld, &t);
|
||||||
|
|
||||||
if (stat != Ok)
|
if (stat != Ok)
|
||||||
@ -4254,8 +4186,7 @@ static GpStatus GDI32_GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath
|
|||||||
if (retval != Ok)
|
if (retval != Ok)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (hrgn)
|
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
|
||||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
|
|
||||||
|
|
||||||
gdi_transform_acquire(graphics);
|
gdi_transform_acquire(graphics);
|
||||||
|
|
||||||
@ -4542,32 +4473,30 @@ static GpStatus GDI32_GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
|
|||||||
if(!graphics->hdc || !brush_can_fill_path(brush, TRUE))
|
if(!graphics->hdc || !brush_can_fill_path(brush, TRUE))
|
||||||
return NotImplemented;
|
return NotImplemented;
|
||||||
|
|
||||||
status = GdipGetRegionHRgn(region, graphics, &hrgn);
|
|
||||||
if(status != Ok)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
save_state = SaveDC(graphics->hdc);
|
save_state = SaveDC(graphics->hdc);
|
||||||
EndPath(graphics->hdc);
|
EndPath(graphics->hdc);
|
||||||
|
|
||||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
|
|
||||||
|
|
||||||
DeleteObject(hrgn);
|
|
||||||
|
|
||||||
hrgn = NULL;
|
hrgn = NULL;
|
||||||
status = get_clip_hrgn(graphics, &hrgn);
|
status = get_clip_hrgn(graphics, &hrgn);
|
||||||
|
|
||||||
if (status != Ok)
|
if (status != Ok)
|
||||||
{
|
{
|
||||||
RestoreDC(graphics->hdc, save_state);
|
RestoreDC(graphics->hdc, save_state);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hrgn)
|
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
|
||||||
|
DeleteObject(hrgn);
|
||||||
|
|
||||||
|
status = GdipGetRegionHRgn(region, graphics, &hrgn);
|
||||||
|
if (status != Ok)
|
||||||
{
|
{
|
||||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
|
RestoreDC(graphics->hdc, save_state);
|
||||||
DeleteObject(hrgn);
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
|
||||||
|
DeleteObject(hrgn);
|
||||||
|
|
||||||
if (GetClipBox(graphics->hdc, &rc) != NULLREGION)
|
if (GetClipBox(graphics->hdc, &rc) != NULLREGION)
|
||||||
{
|
{
|
||||||
BeginPath(graphics->hdc);
|
BeginPath(graphics->hdc);
|
||||||
@ -5371,7 +5300,7 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
|
|||||||
pt[1].Y = 0.0;
|
pt[1].Y = 0.0;
|
||||||
pt[2].X = 0.0;
|
pt[2].X = 0.0;
|
||||||
pt[2].Y = 1.0;
|
pt[2].Y = 1.0;
|
||||||
GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, pt, 3);
|
||||||
args.rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
|
args.rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
|
||||||
(pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
|
(pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
|
||||||
args.rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
|
args.rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
|
||||||
@ -5400,9 +5329,13 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
|
|||||||
|
|
||||||
args.regions = regions;
|
args.regions = regions;
|
||||||
|
|
||||||
|
gdi_transform_acquire(graphics);
|
||||||
|
|
||||||
stat = gdip_format_string(hdc, string, length, font, &scaled_rect, stringFormat,
|
stat = gdip_format_string(hdc, string, length, font, &scaled_rect, stringFormat,
|
||||||
(stringFormat->attr & StringFormatFlagsNoClip) != 0, measure_ranges_callback, &args);
|
(stringFormat->attr & StringFormatFlagsNoClip) != 0, measure_ranges_callback, &args);
|
||||||
|
|
||||||
|
gdi_transform_release(graphics);
|
||||||
|
|
||||||
SelectObject(hdc, oldfont);
|
SelectObject(hdc, oldfont);
|
||||||
DeleteObject(gdifont);
|
DeleteObject(gdifont);
|
||||||
|
|
||||||
@ -5490,7 +5423,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
|
|||||||
pt[1].Y = 0.0;
|
pt[1].Y = 0.0;
|
||||||
pt[2].X = 0.0;
|
pt[2].X = 0.0;
|
||||||
pt[2].Y = 1.0;
|
pt[2].Y = 1.0;
|
||||||
GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, pt, 3);
|
||||||
args.rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
|
args.rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
|
||||||
(pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
|
(pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
|
||||||
args.rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
|
args.rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
|
||||||
@ -5525,9 +5458,13 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
|
|||||||
args.linesfilled = &lines;
|
args.linesfilled = &lines;
|
||||||
lines = glyphs = 0;
|
lines = glyphs = 0;
|
||||||
|
|
||||||
|
gdi_transform_acquire(graphics);
|
||||||
|
|
||||||
gdip_format_string(hdc, string, length, font, &scaled_rect, format, TRUE,
|
gdip_format_string(hdc, string, length, font, &scaled_rect, format, TRUE,
|
||||||
measure_string_callback, &args);
|
measure_string_callback, &args);
|
||||||
|
|
||||||
|
gdi_transform_release(graphics);
|
||||||
|
|
||||||
if (linesfilled) *linesfilled = lines;
|
if (linesfilled) *linesfilled = lines;
|
||||||
if (codepointsfitted) *codepointsfitted = glyphs;
|
if (codepointsfitted) *codepointsfitted = glyphs;
|
||||||
|
|
||||||
@ -5657,7 +5594,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
|
|||||||
pt[1].Y = 0.0;
|
pt[1].Y = 0.0;
|
||||||
pt[2].X = 0.0;
|
pt[2].X = 0.0;
|
||||||
pt[2].Y = 1.0;
|
pt[2].Y = 1.0;
|
||||||
GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, pt, 3);
|
||||||
rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
|
rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
|
||||||
(pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
|
(pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
|
||||||
rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
|
rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
|
||||||
@ -5667,7 +5604,8 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
|
|||||||
rectcpy[1].Y = rectcpy[0].Y = rect->Y;
|
rectcpy[1].Y = rectcpy[0].Y = rect->Y;
|
||||||
rectcpy[2].X = rectcpy[1].X = rect->X + rect->Width;
|
rectcpy[2].X = rectcpy[1].X = rect->X + rect->Width;
|
||||||
rectcpy[3].Y = rectcpy[2].Y = rect->Y + rect->Height;
|
rectcpy[3].Y = rectcpy[2].Y = rect->Y + rect->Height;
|
||||||
transform_and_round_points(graphics, corners, rectcpy, 4);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, rectcpy, 4);
|
||||||
|
round_points(corners, rectcpy, 4);
|
||||||
|
|
||||||
margin_x = (format && format->generic_typographic) ? 0.0 : font->emSize / 6.0;
|
margin_x = (format && format->generic_typographic) ? 0.0 : font->emSize / 6.0;
|
||||||
margin_x *= units_scale(font->unit, graphics->unit, graphics->xres);
|
margin_x *= units_scale(font->unit, graphics->unit, graphics->xres);
|
||||||
@ -5706,12 +5644,16 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
|
|||||||
args.rel_width = rel_width;
|
args.rel_width = rel_width;
|
||||||
args.rel_height = rel_height;
|
args.rel_height = rel_height;
|
||||||
|
|
||||||
|
gdi_transform_acquire(graphics);
|
||||||
|
|
||||||
GetTextMetricsW(hdc, &textmetric);
|
GetTextMetricsW(hdc, &textmetric);
|
||||||
args.ascent = textmetric.tmAscent / rel_height;
|
args.ascent = textmetric.tmAscent / rel_height;
|
||||||
|
|
||||||
gdip_format_string(hdc, string, length, font, &scaled_rect, format, TRUE,
|
gdip_format_string(hdc, string, length, font, &scaled_rect, format, TRUE,
|
||||||
draw_string_callback, &args);
|
draw_string_callback, &args);
|
||||||
|
|
||||||
|
gdi_transform_release(graphics);
|
||||||
|
|
||||||
DeleteObject(rgn);
|
DeleteObject(rgn);
|
||||||
DeleteObject(gdifont);
|
DeleteObject(gdifont);
|
||||||
|
|
||||||
@ -6311,6 +6253,7 @@ GpStatus WINGDIPAPI GdipSetClipHrgn(GpGraphics *graphics, HRGN hrgn, CombineMode
|
|||||||
{
|
{
|
||||||
GpRegion *region;
|
GpRegion *region;
|
||||||
GpStatus status;
|
GpStatus status;
|
||||||
|
GpMatrix transform;
|
||||||
|
|
||||||
TRACE("(%p, %p, %d)\n", graphics, hrgn, mode);
|
TRACE("(%p, %p, %d)\n", graphics, hrgn, mode);
|
||||||
|
|
||||||
@ -6320,14 +6263,21 @@ GpStatus WINGDIPAPI GdipSetClipHrgn(GpGraphics *graphics, HRGN hrgn, CombineMode
|
|||||||
if(graphics->busy)
|
if(graphics->busy)
|
||||||
return ObjectBusy;
|
return ObjectBusy;
|
||||||
|
|
||||||
/* hrgn is already in device units */
|
/* hrgn is in gdi32 device units */
|
||||||
status = GdipCreateRegionHrgn(hrgn, ®ion);
|
status = GdipCreateRegionHrgn(hrgn, ®ion);
|
||||||
if(status != Ok)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = GdipCombineRegionRegion(graphics->clip, region, mode);
|
if (status == Ok)
|
||||||
|
{
|
||||||
|
status = get_graphics_transform(graphics, CoordinateSpaceDevice, WineCoordinateSpaceGdiDevice, &transform);
|
||||||
|
|
||||||
GdipDeleteRegion(region);
|
if (status == Ok)
|
||||||
|
status = GdipTransformRegion(region, &transform);
|
||||||
|
|
||||||
|
if (status == Ok)
|
||||||
|
status = GdipCombineRegionRegion(graphics->clip, region, mode);
|
||||||
|
|
||||||
|
GdipDeleteRegion(region);
|
||||||
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6723,31 +6673,10 @@ GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region)
|
|||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_gdi_transform(GpGraphics *graphics, GpMatrix *matrix)
|
|
||||||
{
|
|
||||||
XFORM xform;
|
|
||||||
|
|
||||||
if (graphics->hdc == NULL)
|
|
||||||
{
|
|
||||||
GdipSetMatrixElements(matrix, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (graphics->gdi_transform_acquire_count)
|
|
||||||
{
|
|
||||||
*matrix = graphics->gdi_transform;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetTransform(graphics->hdc, 0x204, &xform);
|
|
||||||
GdipSetMatrixElements(matrix, xform.eM11, xform.eM12, xform.eM21, xform.eM22, xform.eDx, xform.eDy);
|
|
||||||
}
|
|
||||||
|
|
||||||
GpStatus gdi_transform_acquire(GpGraphics *graphics)
|
GpStatus gdi_transform_acquire(GpGraphics *graphics)
|
||||||
{
|
{
|
||||||
if (graphics->gdi_transform_acquire_count == 0 && graphics->hdc)
|
if (graphics->gdi_transform_acquire_count == 0 && graphics->hdc)
|
||||||
{
|
{
|
||||||
get_gdi_transform(graphics, &graphics->gdi_transform);
|
|
||||||
graphics->gdi_transform_save = SaveDC(graphics->hdc);
|
graphics->gdi_transform_save = SaveDC(graphics->hdc);
|
||||||
SetGraphicsMode(graphics->hdc, GM_COMPATIBLE);
|
SetGraphicsMode(graphics->hdc, GM_COMPATIBLE);
|
||||||
SetMapMode(graphics->hdc, MM_TEXT);
|
SetMapMode(graphics->hdc, MM_TEXT);
|
||||||
@ -6762,7 +6691,7 @@ GpStatus gdi_transform_release(GpGraphics *graphics)
|
|||||||
{
|
{
|
||||||
if (graphics->gdi_transform_acquire_count <= 0)
|
if (graphics->gdi_transform_acquire_count <= 0)
|
||||||
{
|
{
|
||||||
ERR("called without matching gdi_transform_acquire");
|
ERR("called without matching gdi_transform_acquire\n");
|
||||||
return GenericError;
|
return GenericError;
|
||||||
}
|
}
|
||||||
if (graphics->gdi_transform_acquire_count == 1 && graphics->hdc)
|
if (graphics->gdi_transform_acquire_count == 1 && graphics->hdc)
|
||||||
@ -6800,7 +6729,7 @@ GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_spac
|
|||||||
case WineCoordinateSpaceGdiDevice:
|
case WineCoordinateSpaceGdiDevice:
|
||||||
{
|
{
|
||||||
GpMatrix gdixform;
|
GpMatrix gdixform;
|
||||||
get_gdi_transform(graphics, &gdixform);
|
gdixform = graphics->gdi_transform;
|
||||||
stat = GdipInvertMatrix(&gdixform);
|
stat = GdipInvertMatrix(&gdixform);
|
||||||
if (stat != Ok)
|
if (stat != Ok)
|
||||||
break;
|
break;
|
||||||
@ -6841,9 +6770,7 @@ GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_spac
|
|||||||
/* else fall-through */
|
/* else fall-through */
|
||||||
case CoordinateSpaceDevice:
|
case CoordinateSpaceDevice:
|
||||||
{
|
{
|
||||||
GpMatrix gdixform;
|
GdipMultiplyMatrix(matrix, &graphics->gdi_transform, MatrixOrderAppend);
|
||||||
get_gdi_transform(graphics, &gdixform);
|
|
||||||
GdipMultiplyMatrix(matrix, &gdixform, MatrixOrderAppend);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7015,7 +6942,7 @@ GpStatus WINGDIPAPI GdipMeasureDriverString(GpGraphics *graphics, GDIPCONST UINT
|
|||||||
GpMatrix xform = *matrix;
|
GpMatrix xform = *matrix;
|
||||||
GdipTransformMatrixPoints(&xform, pt, 3);
|
GdipTransformMatrixPoints(&xform, pt, 3);
|
||||||
}
|
}
|
||||||
GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, pt, 3);
|
||||||
rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
|
rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
|
||||||
(pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
|
(pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
|
||||||
rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
|
rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
|
||||||
@ -7102,22 +7029,26 @@ static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT1
|
|||||||
|
|
||||||
status = get_clip_hrgn(graphics, &hrgn);
|
status = get_clip_hrgn(graphics, &hrgn);
|
||||||
|
|
||||||
if (status == Ok && hrgn)
|
if (status == Ok)
|
||||||
{
|
{
|
||||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
|
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
|
||||||
DeleteObject(hrgn);
|
DeleteObject(hrgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
pt = positions[0];
|
pt = positions[0];
|
||||||
GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &pt, 1);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, &pt, 1);
|
||||||
|
|
||||||
get_font_hfont(graphics, font, format, &hfont, matrix);
|
get_font_hfont(graphics, font, format, &hfont, matrix);
|
||||||
SelectObject(graphics->hdc, hfont);
|
SelectObject(graphics->hdc, hfont);
|
||||||
|
|
||||||
SetTextAlign(graphics->hdc, TA_BASELINE|TA_LEFT);
|
SetTextAlign(graphics->hdc, TA_BASELINE|TA_LEFT);
|
||||||
|
|
||||||
|
gdi_transform_acquire(graphics);
|
||||||
|
|
||||||
ExtTextOutW(graphics->hdc, gdip_round(pt.X), gdip_round(pt.Y), eto_flags, NULL, text, length, NULL);
|
ExtTextOutW(graphics->hdc, gdip_round(pt.X), gdip_round(pt.Y), eto_flags, NULL, text, length, NULL);
|
||||||
|
|
||||||
|
gdi_transform_release(graphics);
|
||||||
|
|
||||||
RestoreDC(graphics->hdc, save_state);
|
RestoreDC(graphics->hdc, save_state);
|
||||||
|
|
||||||
DeleteObject(hfont);
|
DeleteObject(hfont);
|
||||||
@ -7165,7 +7096,8 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
|
|||||||
{
|
{
|
||||||
real_position = positions[0];
|
real_position = positions[0];
|
||||||
|
|
||||||
transform_and_round_points(graphics, pti, &real_position, 1);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, &real_position, 1);
|
||||||
|
round_points(pti, &real_position, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -7178,7 +7110,8 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
|
|||||||
|
|
||||||
memcpy(real_positions, positions, sizeof(PointF) * length);
|
memcpy(real_positions, positions, sizeof(PointF) * length);
|
||||||
|
|
||||||
transform_and_round_points(graphics, pti, real_positions, length);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, real_positions, length);
|
||||||
|
round_points(pti, real_positions, length);
|
||||||
|
|
||||||
heap_free(real_positions);
|
heap_free(real_positions);
|
||||||
}
|
}
|
||||||
@ -7318,10 +7251,14 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
|
|||||||
|
|
||||||
heap_free(text_mask);
|
heap_free(text_mask);
|
||||||
|
|
||||||
|
gdi_transform_acquire(graphics);
|
||||||
|
|
||||||
/* draw the result */
|
/* draw the result */
|
||||||
stat = alpha_blend_pixels(graphics, min_x, min_y, pixel_data, pixel_area.Width,
|
stat = alpha_blend_pixels(graphics, min_x, min_y, pixel_data, pixel_area.Width,
|
||||||
pixel_area.Height, pixel_data_stride, PixelFormat32bppARGB);
|
pixel_area.Height, pixel_data_stride, PixelFormat32bppARGB);
|
||||||
|
|
||||||
|
gdi_transform_release(graphics);
|
||||||
|
|
||||||
heap_free(pixel_data);
|
heap_free(pixel_data);
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
|
@ -38,19 +38,13 @@ static const struct
|
|||||||
{
|
{
|
||||||
{ &GUID_WICPixelFormatBlackWhite, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
|
{ &GUID_WICPixelFormatBlackWhite, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
|
||||||
{ &GUID_WICPixelFormat1bppIndexed, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
|
{ &GUID_WICPixelFormat1bppIndexed, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
|
||||||
{ &GUID_WICPixelFormat4bppIndexed, PixelFormat4bppIndexed, WICBitmapPaletteTypeFixedHalftone8 },
|
|
||||||
{ &GUID_WICPixelFormat8bppGray, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedGray256 },
|
{ &GUID_WICPixelFormat8bppGray, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedGray256 },
|
||||||
{ &GUID_WICPixelFormat8bppIndexed, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedHalftone256 },
|
{ &GUID_WICPixelFormat8bppIndexed, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedHalftone256 },
|
||||||
{ &GUID_WICPixelFormat16bppBGR555, PixelFormat16bppRGB555, WICBitmapPaletteTypeFixedHalftone256 },
|
{ &GUID_WICPixelFormat16bppBGR555, PixelFormat16bppRGB555, WICBitmapPaletteTypeFixedHalftone256 },
|
||||||
{ &GUID_WICPixelFormat24bppBGR, PixelFormat24bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
{ &GUID_WICPixelFormat24bppBGR, PixelFormat24bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||||
{ &GUID_WICPixelFormat32bppBGR, PixelFormat32bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
{ &GUID_WICPixelFormat32bppBGR, PixelFormat32bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||||
{ &GUID_WICPixelFormat48bppRGB, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
|
||||||
{ &GUID_WICPixelFormat32bppBGRA, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedHalftone256 },
|
{ &GUID_WICPixelFormat32bppBGRA, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||||
{ &GUID_WICPixelFormat32bppPBGRA, PixelFormat32bppPARGB, WICBitmapPaletteTypeFixedHalftone256 },
|
{ &GUID_WICPixelFormat32bppPBGRA, PixelFormat32bppPARGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||||
{ &GUID_WICPixelFormat32bppCMYK, PixelFormat32bppCMYK, WICBitmapPaletteTypeFixedHalftone256 },
|
|
||||||
{ &GUID_WICPixelFormat32bppGrayFloat, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedGray256 },
|
|
||||||
{ &GUID_WICPixelFormat64bppCMYK, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
|
||||||
{ &GUID_WICPixelFormat64bppRGBA, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2074,24 +2068,7 @@ static GpStatus free_image_data(GpImage *image)
|
|||||||
heap_free(((GpBitmap*)image)->prop_item);
|
heap_free(((GpBitmap*)image)->prop_item);
|
||||||
}
|
}
|
||||||
else if (image->type == ImageTypeMetafile)
|
else if (image->type == ImageTypeMetafile)
|
||||||
{
|
METAFILE_Free((GpMetafile *)image);
|
||||||
GpMetafile *metafile = (GpMetafile*)image;
|
|
||||||
heap_free(metafile->comment_data);
|
|
||||||
DeleteEnhMetaFile(CloseEnhMetaFile(metafile->record_dc));
|
|
||||||
if (!metafile->preserve_hemf)
|
|
||||||
DeleteEnhMetaFile(metafile->hemf);
|
|
||||||
if (metafile->record_graphics)
|
|
||||||
{
|
|
||||||
WARN("metafile closed while recording\n");
|
|
||||||
/* not sure what to do here; for now just prevent the graphics from functioning or using this object */
|
|
||||||
metafile->record_graphics->image = NULL;
|
|
||||||
metafile->record_graphics->busy = TRUE;
|
|
||||||
}
|
|
||||||
if (metafile->record_stream)
|
|
||||||
{
|
|
||||||
IStream_Release(metafile->record_stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WARN("invalid image: %p\n", image);
|
WARN("invalid image: %p\n", image);
|
||||||
@ -4568,7 +4545,7 @@ static GpStatus encode_image_jpeg(GpImage *image, IStream* stream,
|
|||||||
static GpStatus encode_image_gif(GpImage *image, IStream* stream,
|
static GpStatus encode_image_gif(GpImage *image, IStream* stream,
|
||||||
GDIPCONST EncoderParameters* params)
|
GDIPCONST EncoderParameters* params)
|
||||||
{
|
{
|
||||||
return encode_image_wic(image, stream, &GUID_ContainerFormatGif, params);
|
return encode_image_wic(image, stream, &CLSID_WICGifEncoder, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -4581,7 +4558,7 @@ GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream* stream,
|
|||||||
encode_image_func encode_image;
|
encode_image_func encode_image;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
TRACE("%p %p %s %p\n", image, stream, wine_dbgstr_guid(clsid), params);
|
TRACE("%p %p %p %p\n", image, stream, clsid, params);
|
||||||
|
|
||||||
if(!image || !stream)
|
if(!image || !stream)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
@ -5595,111 +5572,3 @@ GpStatus WINGDIPAPI GdipBitmapGetHistogramSize(HistogramFormat format, UINT *num
|
|||||||
*num_of_entries = 256;
|
*num_of_entries = 256;
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GpStatus create_optimal_palette(ColorPalette *palette, INT desired,
|
|
||||||
BOOL transparent, GpBitmap *bitmap)
|
|
||||||
{
|
|
||||||
GpStatus status;
|
|
||||||
BitmapData data;
|
|
||||||
HRESULT hr;
|
|
||||||
IWICImagingFactory *factory;
|
|
||||||
IWICPalette *wic_palette;
|
|
||||||
|
|
||||||
if (!bitmap) return InvalidParameter;
|
|
||||||
if (palette->Count < desired) return GenericError;
|
|
||||||
|
|
||||||
status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &data);
|
|
||||||
if (status != Ok) return status;
|
|
||||||
|
|
||||||
hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory);
|
|
||||||
if (hr != S_OK)
|
|
||||||
{
|
|
||||||
GdipBitmapUnlockBits(bitmap, &data);
|
|
||||||
return hresult_to_status(hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = IWICImagingFactory_CreatePalette(factory, &wic_palette);
|
|
||||||
if (hr == S_OK)
|
|
||||||
{
|
|
||||||
IWICBitmap *bitmap;
|
|
||||||
|
|
||||||
/* PixelFormat24bppRGB actually stores the bitmap bits as BGR. */
|
|
||||||
hr = IWICImagingFactory_CreateBitmapFromMemory(factory, data.Width, data.Height,
|
|
||||||
&GUID_WICPixelFormat24bppBGR, data.Stride, data.Stride * data.Width, data.Scan0, &bitmap);
|
|
||||||
if (hr == S_OK)
|
|
||||||
{
|
|
||||||
hr = IWICPalette_InitializeFromBitmap(wic_palette, (IWICBitmapSource *)bitmap, desired, transparent);
|
|
||||||
if (hr == S_OK)
|
|
||||||
{
|
|
||||||
palette->Flags = 0;
|
|
||||||
IWICPalette_GetColorCount(wic_palette, &palette->Count);
|
|
||||||
IWICPalette_GetColors(wic_palette, palette->Count, palette->Entries, &palette->Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
IWICBitmap_Release(bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
IWICPalette_Release(wic_palette);
|
|
||||||
}
|
|
||||||
|
|
||||||
IWICImagingFactory_Release(factory);
|
|
||||||
GdipBitmapUnlockBits(bitmap, &data);
|
|
||||||
|
|
||||||
return hresult_to_status(hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* GdipInitializePalette [GDIPLUS.@]
|
|
||||||
*/
|
|
||||||
GpStatus WINGDIPAPI GdipInitializePalette(ColorPalette *palette,
|
|
||||||
PaletteType type, INT desired, BOOL transparent, GpBitmap *bitmap)
|
|
||||||
{
|
|
||||||
TRACE("(%p,%d,%d,%d,%p)\n", palette, type, desired, transparent, bitmap);
|
|
||||||
|
|
||||||
if (!palette) return InvalidParameter;
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case PaletteTypeCustom:
|
|
||||||
return Ok;
|
|
||||||
|
|
||||||
case PaletteTypeOptimal:
|
|
||||||
return create_optimal_palette(palette, desired, transparent, bitmap);
|
|
||||||
|
|
||||||
/* WIC palette type enumeration matches these gdiplus enums */
|
|
||||||
case PaletteTypeFixedBW:
|
|
||||||
case PaletteTypeFixedHalftone8:
|
|
||||||
case PaletteTypeFixedHalftone27:
|
|
||||||
case PaletteTypeFixedHalftone64:
|
|
||||||
case PaletteTypeFixedHalftone125:
|
|
||||||
case PaletteTypeFixedHalftone216:
|
|
||||||
case PaletteTypeFixedHalftone252:
|
|
||||||
case PaletteTypeFixedHalftone256:
|
|
||||||
{
|
|
||||||
ColorPalette *wic_palette;
|
|
||||||
GpStatus status = Ok;
|
|
||||||
|
|
||||||
wic_palette = get_palette(NULL, type);
|
|
||||||
if (!wic_palette) return OutOfMemory;
|
|
||||||
|
|
||||||
if (palette->Count >= wic_palette->Count)
|
|
||||||
{
|
|
||||||
palette->Flags = wic_palette->Flags;
|
|
||||||
palette->Count = wic_palette->Count;
|
|
||||||
memcpy(palette->Entries, wic_palette->Entries, wic_palette->Count * sizeof(wic_palette->Entries[0]));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
status = GenericError;
|
|
||||||
|
|
||||||
heap_free(wic_palette);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
FIXME("unknown palette type %d\n", type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return InvalidParameter;
|
|
||||||
}
|
|
||||||
|
@ -209,14 +209,14 @@ GpStatus WINGDIPAPI GdipSetImageAttributesGamma(GpImageAttributes *imageAttr,
|
|||||||
GpStatus WINGDIPAPI GdipSetImageAttributesNoOp(GpImageAttributes *imageAttr,
|
GpStatus WINGDIPAPI GdipSetImageAttributesNoOp(GpImageAttributes *imageAttr,
|
||||||
ColorAdjustType type, BOOL enableFlag)
|
ColorAdjustType type, BOOL enableFlag)
|
||||||
{
|
{
|
||||||
static int calls;
|
|
||||||
|
|
||||||
TRACE("(%p,%u,%i)\n", imageAttr, type, enableFlag);
|
TRACE("(%p,%u,%i)\n", imageAttr, type, enableFlag);
|
||||||
|
|
||||||
if(!(calls++))
|
if (type >= ColorAdjustTypeCount)
|
||||||
FIXME("not implemented\n");
|
return InvalidParameter;
|
||||||
|
|
||||||
return NotImplemented;
|
imageAttr->noop[type] = enableFlag ? IMAGEATTR_NOOP_SET : IMAGEATTR_NOOP_CLEAR;
|
||||||
|
|
||||||
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipSetImageAttributesOutputChannel(GpImageAttributes *imageAttr,
|
GpStatus WINGDIPAPI GdipSetImageAttributesOutputChannel(GpImageAttributes *imageAttr,
|
||||||
@ -323,6 +323,7 @@ GpStatus WINGDIPAPI GdipResetImageAttributes(GpImageAttributes *imageAttr,
|
|||||||
GdipSetImageAttributesColorKeys(imageAttr, type, FALSE, 0, 0);
|
GdipSetImageAttributesColorKeys(imageAttr, type, FALSE, 0, 0);
|
||||||
GdipSetImageAttributesRemapTable(imageAttr, type, FALSE, 0, NULL);
|
GdipSetImageAttributesRemapTable(imageAttr, type, FALSE, 0, NULL);
|
||||||
GdipSetImageAttributesGamma(imageAttr, type, FALSE, 0.0);
|
GdipSetImageAttributesGamma(imageAttr, type, FALSE, 0.0);
|
||||||
|
imageAttr->noop[type] = IMAGEATTR_NOOP_UNDEFINED;
|
||||||
|
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -64,12 +64,6 @@
|
|||||||
|
|
||||||
#define FLAGS_INTPATH 0x4000
|
#define FLAGS_INTPATH 0x4000
|
||||||
|
|
||||||
struct memory_buffer
|
|
||||||
{
|
|
||||||
const BYTE *buffer;
|
|
||||||
INT size, pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct region_header
|
struct region_header
|
||||||
{
|
{
|
||||||
DWORD magic;
|
DWORD magic;
|
||||||
@ -766,24 +760,6 @@ GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size,
|
|||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void init_memory_buffer(struct memory_buffer *mbuf, const BYTE *buffer, INT size)
|
|
||||||
{
|
|
||||||
mbuf->buffer = buffer;
|
|
||||||
mbuf->size = size;
|
|
||||||
mbuf->pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const void *buffer_read(struct memory_buffer *mbuf, INT size)
|
|
||||||
{
|
|
||||||
if (mbuf->size - mbuf->pos >= size)
|
|
||||||
{
|
|
||||||
const void *data = mbuf->buffer + mbuf->pos;
|
|
||||||
mbuf->pos += size;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, region_element *node, INT *count)
|
static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, region_element *node, INT *count)
|
||||||
{
|
{
|
||||||
GpStatus status;
|
GpStatus status;
|
||||||
|
@ -68,7 +68,7 @@ reactos/dll/win32/dciman32 # Synced to WineStaging-2.9
|
|||||||
reactos/dll/win32/faultrep # Synced to WineStaging-2.9
|
reactos/dll/win32/faultrep # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/fontsub # Synced to WineStaging-2.9
|
reactos/dll/win32/fontsub # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/fusion # Synced to Wine-3.0
|
reactos/dll/win32/fusion # Synced to Wine-3.0
|
||||||
reactos/dll/win32/gdiplus # Synced to WineStaging-2.16
|
reactos/dll/win32/gdiplus # Synced to Wine-3.0
|
||||||
reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-2.9
|
reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/hlink # Synced to WineStaging-2.9
|
reactos/dll/win32/hlink # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/hnetcfg # Synced to WineStaging-2.9
|
reactos/dll/win32/hnetcfg # Synced to WineStaging-2.9
|
||||||
|
Loading…
Reference in New Issue
Block a user