mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 04:53:31 +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 */
|
||||
};
|
||||
|
||||
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]))
|
||||
{
|
||||
@ -257,12 +257,15 @@ GpStatus get_hatch_data(HatchStyle hatchstyle, const char **result)
|
||||
/******************************************************************************
|
||||
* 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);
|
||||
|
||||
if(!brush) return InvalidParameter;
|
||||
|
||||
if(hatchstyle < HatchStyleMin || hatchstyle > HatchStyleMax)
|
||||
return InvalidParameter;
|
||||
|
||||
*brush = heap_alloc_zero(sizeof(GpHatch));
|
||||
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,
|
||||
wrap, line);
|
||||
|
||||
if (!rect || !rect->Width || !rect->Height)
|
||||
if (!rect || !line || wrap == WrapModeClamp)
|
||||
return InvalidParameter;
|
||||
|
||||
if (!rect->Width || !rect->Height)
|
||||
return OutOfMemory;
|
||||
|
||||
angle = fmodf(angle, 360);
|
||||
if (angle < 0)
|
||||
angle += 360;
|
||||
@ -951,7 +957,7 @@ GpStatus WINGDIPAPI GdipGetHatchForegroundColor(GpHatch *brush, ARGB *forecol)
|
||||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipGetHatchStyle(GpHatch *brush, HatchStyle *hatchstyle)
|
||||
GpStatus WINGDIPAPI GdipGetHatchStyle(GpHatch *brush, GpHatchStyle *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;
|
||||
}
|
||||
|
||||
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 codepage;
|
||||
WCHAR *ret;
|
||||
int len;
|
||||
|
||||
switch (GET_BE_WORD(name->platform_id))
|
||||
{
|
||||
case TT_PLATFORM_APPLE_UNICODE:
|
||||
case TT_PLATFORM_MICROSOFT:
|
||||
if (name_len >= len*sizeof(WCHAR))
|
||||
return NULL;
|
||||
ret = heap_alloc((name_len / 2 + 1) * sizeof(WCHAR));
|
||||
for (len = 0; len < name_len / 2; len++)
|
||||
ret[len] = (data[len * 2] << 8) | data[len * 2 + 1];
|
||||
ret[len] = 0;
|
||||
return ret;
|
||||
case TT_PLATFORM_MACINTOSH:
|
||||
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)
|
||||
return NULL;
|
||||
ret = heap_alloc(len * sizeof(WCHAR));
|
||||
len = MultiByteToWideChar( codepage, 0, (char *)data, name_len, ret, len - 1 );
|
||||
ret[len] = 0;
|
||||
return ret;
|
||||
}
|
||||
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();
|
||||
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)
|
||||
{
|
||||
WCHAR *ret;
|
||||
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),
|
||||
GET_BE_WORD(name_record->platform_id), GET_BE_WORD(name_record->language_id), debugstr_w( 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,
|
||||
GDIPCONST void* memory, INT length)
|
||||
{
|
||||
WCHAR buf[32], *name;
|
||||
WCHAR *name;
|
||||
DWORD count = 0;
|
||||
HANDLE font;
|
||||
GpStatus ret = Ok;
|
||||
TRACE("%p, %p, %d\n", fontCollection, memory, length);
|
||||
|
||||
if (!fontCollection || !memory || !length)
|
||||
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)
|
||||
return OutOfMemory;
|
||||
|
||||
font = AddFontMemResourceEx((void*)memory, length, NULL, &count);
|
||||
TRACE("%s: %p/%u\n", debugstr_w(name), font, count);
|
||||
if (!font || !count)
|
||||
return InvalidParameter;
|
||||
|
||||
if (count)
|
||||
ret = InvalidParameter;
|
||||
else
|
||||
{
|
||||
HDC hdc;
|
||||
LOGFONTW lfw;
|
||||
|
||||
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;
|
||||
lstrcpyW(lfw.lfFaceName, name);
|
||||
lfw.lfPitchAndFamily = 0;
|
||||
|
||||
if (!EnumFontFamiliesExW(hdc, &lfw, add_font_proc, (LPARAM)fontCollection, 0))
|
||||
{
|
||||
DeleteDC(hdc);
|
||||
return OutOfMemory;
|
||||
}
|
||||
ret = OutOfMemory;
|
||||
|
||||
DeleteDC(hdc);
|
||||
}
|
||||
return Ok;
|
||||
heap_free(name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -615,7 +615,7 @@
|
||||
615 stub GdipGetEffectParameterSize
|
||||
616 stub GdipGetEffectParameters
|
||||
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)
|
||||
620 stdcall GdipBitmapApplyEffect(ptr ptr ptr long 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_DrawPath(GpMetafile *metafile, GpPen *pen, 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,
|
||||
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;
|
||||
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)
|
||||
{
|
||||
@ -270,6 +271,7 @@ struct GpGraphics{
|
||||
INT origin_x, origin_y;
|
||||
INT gdi_transform_acquire_count, gdi_transform_save;
|
||||
GpMatrix gdi_transform;
|
||||
HRGN gdi_clip;
|
||||
/* For giving the caller an HDC when we technically can't: */
|
||||
HBITMAP temp_hbitmap;
|
||||
int temp_hbitmap_width;
|
||||
@ -284,7 +286,7 @@ struct GpBrush{
|
||||
|
||||
struct GpHatch{
|
||||
GpBrush brush;
|
||||
HatchStyle hatchstyle;
|
||||
GpHatchStyle hatchstyle;
|
||||
ARGB forecol;
|
||||
ARGB backcol;
|
||||
};
|
||||
@ -378,6 +380,38 @@ struct GpImage{
|
||||
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{
|
||||
GpImage image;
|
||||
GpRectF bounds;
|
||||
@ -411,6 +445,7 @@ struct GpMetafile{
|
||||
GpRegion *base_clip; /* clip region in device space for all metafile output */
|
||||
GpRegion *clip; /* clip region within the metafile */
|
||||
struct list containers;
|
||||
struct emfplus_object objtable[EmfPlusObjectTableSize];
|
||||
};
|
||||
|
||||
struct GpBitmap{
|
||||
@ -454,6 +489,12 @@ struct color_remap_table{
|
||||
ColorMap *colormap;
|
||||
};
|
||||
|
||||
enum imageattr_noop{
|
||||
IMAGEATTR_NOOP_UNDEFINED,
|
||||
IMAGEATTR_NOOP_SET,
|
||||
IMAGEATTR_NOOP_CLEAR,
|
||||
};
|
||||
|
||||
struct GpImageAttributes{
|
||||
WrapMode wrap;
|
||||
ARGB outside_color;
|
||||
@ -463,6 +504,7 @@ struct GpImageAttributes{
|
||||
struct color_remap_table colorremaptables[ColorAdjustTypeCount];
|
||||
BOOL gamma_enabled[ColorAdjustTypeCount];
|
||||
REAL gamma[ColorAdjustTypeCount];
|
||||
enum imageattr_noop noop[ColorAdjustTypeCount];
|
||||
};
|
||||
|
||||
struct GpFont{
|
||||
@ -535,6 +577,30 @@ struct GpRegion{
|
||||
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,
|
||||
GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -505,8 +509,6 @@ static GpStatus alpha_blend_pixels_hrgn(GpGraphics *graphics, INT dst_x, INT dst
|
||||
|
||||
save = SaveDC(graphics->hdc);
|
||||
|
||||
SetViewportOrgEx(graphics->hdc, 0, 0, NULL);
|
||||
|
||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
INT start_a, end_a, final_a;
|
||||
INT pos;
|
||||
|
||||
pos = (INT)(position * 255.0f + 0.5f);
|
||||
pos = gdip_round(position * 0xff);
|
||||
|
||||
start_a = ((start >> 24) & 0xff) * (pos ^ 0xff);
|
||||
end_a = ((end >> 24) & 0xff) * pos;
|
||||
@ -685,6 +676,11 @@ PixelFormat apply_image_attributes(const GpImageAttributes *attributes, LPBYTE d
|
||||
UINT x, y;
|
||||
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 ||
|
||||
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];
|
||||
}
|
||||
|
||||
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,
|
||||
UINT height, GpPointF *point, GDIPCONST GpImageAttributes *attributes,
|
||||
InterpolationMode interpolation, PixelOffsetMode offset_mode)
|
||||
@ -971,12 +962,12 @@ static ARGB resample_bitmap_pixel(GDIPCONST GpRect *src_rect, LPBYTE bits, UINT
|
||||
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);
|
||||
leftxf = floorf(point->X);
|
||||
leftx = (INT)leftxf;
|
||||
rightx = (INT)ceilf(point->X);
|
||||
topyf = floorf(point->Y);
|
||||
topy = (INT)topyf;
|
||||
bottomy = (INT)ceilf(point->Y);
|
||||
|
||||
if (leftx == rightx && topy == bottomy)
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
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));
|
||||
@ -2342,6 +2264,20 @@ GpStatus WINGDIPAPI GdipCreateFromHDC(HDC hdc, GpGraphics **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 retval;
|
||||
@ -2391,7 +2327,19 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra
|
||||
(*graphics)->busy = FALSE;
|
||||
(*graphics)->textcontrast = 4;
|
||||
list_init(&(*graphics)->containers);
|
||||
#ifdef __REACTOS__
|
||||
(*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);
|
||||
|
||||
@ -2406,6 +2354,7 @@ GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics)
|
||||
if(!*graphics) return OutOfMemory;
|
||||
|
||||
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){
|
||||
heap_free(*graphics);
|
||||
@ -2431,7 +2380,11 @@ GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics)
|
||||
(*graphics)->busy = FALSE;
|
||||
(*graphics)->textcontrast = 4;
|
||||
list_init(&(*graphics)->containers);
|
||||
#ifdef __REACTOS__
|
||||
(*graphics)->contid = GDIP_GET_NEW_CONTID_FOR(*graphics);
|
||||
#else
|
||||
(*graphics)->contid = 0;
|
||||
#endif
|
||||
|
||||
TRACE("<-- %p\n", *graphics);
|
||||
|
||||
@ -2516,6 +2469,8 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
|
||||
|
||||
GdipDeleteRegion(graphics->clip);
|
||||
|
||||
DeleteObject(graphics->gdi_clip);
|
||||
|
||||
/* 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
|
||||
* accessing freed memory. */
|
||||
@ -3151,10 +3106,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
|
||||
lockeddata.Scan0 = src_data;
|
||||
if (!do_resampling && bitmap->format == PixelFormat32bppPARGB)
|
||||
lockeddata.PixelFormat = apply_image_attributes(imageAttributes, NULL, 0, 0, 0, ColorAdjustTypeBitmap, bitmap->format);
|
||||
else if (imageAttributes != &defaultImageAttributes)
|
||||
lockeddata.PixelFormat = PixelFormat32bppARGB;
|
||||
else
|
||||
lockeddata.PixelFormat = PixelFormat32bppPARGB;
|
||||
lockeddata.PixelFormat = PixelFormat32bppARGB;
|
||||
|
||||
stat = GdipBitmapLockBits(bitmap, &src_area, ImageLockModeRead|ImageLockModeUserInputBuf,
|
||||
lockeddata.PixelFormat, &lockeddata);
|
||||
@ -3174,8 +3127,6 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
|
||||
|
||||
if (do_resampling)
|
||||
{
|
||||
REAL delta_xx, delta_xy, delta_yx, delta_yy;
|
||||
|
||||
/* 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));
|
||||
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_dy = dst_to_src_points[2].Y - dst_to_src_points[0].Y;
|
||||
|
||||
delta_yy = dst_area.top * y_dy;
|
||||
delta_yx = dst_area.top * y_dx;
|
||||
|
||||
for (y=dst_area.top; y<dst_area.bottom; y++)
|
||||
for (x=dst_area.left; x<dst_area.right; x++)
|
||||
{
|
||||
delta_xx = dst_area.left * x_dx;
|
||||
delta_xy = dst_area.left * x_dy;
|
||||
|
||||
for (x=dst_area.left; x<dst_area.right; x++)
|
||||
for (y=dst_area.top; y<dst_area.bottom; y++)
|
||||
{
|
||||
GpPointF src_pointf;
|
||||
ARGB *dst_color;
|
||||
|
||||
src_pointf.X = dst_to_src_points[0].X + delta_xx + delta_yx;
|
||||
src_pointf.Y = dst_to_src_points[0].Y + delta_xy + delta_yy;
|
||||
src_pointf.X = dst_to_src_points[0].X + x * x_dx + y * y_dx;
|
||||
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));
|
||||
|
||||
if (src_pointf.X >= srcx && src_pointf.X < srcx + srcwidth && src_pointf.Y >= srcy && src_pointf.Y < srcy+srcheight)
|
||||
{
|
||||
if (lockeddata.PixelFormat != PixelFormat32bppPARGB)
|
||||
*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);
|
||||
}
|
||||
*dst_color = resample_bitmap_pixel(&src_area, src_data, bitmap->width, bitmap->height, &src_pointf,
|
||||
imageAttributes, interpolation, offset_mode);
|
||||
else
|
||||
*dst_color = 0;
|
||||
|
||||
delta_xx += x_dx;
|
||||
delta_yx += y_dx;
|
||||
}
|
||||
|
||||
delta_xy += x_dy;
|
||||
delta_yy += y_dy;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -3322,9 +3255,9 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -3565,8 +3498,7 @@ static GpStatus GDI32_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *pat
|
||||
if (retval != Ok)
|
||||
goto end;
|
||||
|
||||
if (hrgn)
|
||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
|
||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
|
||||
|
||||
gdi_transform_acquire(graphics);
|
||||
|
||||
@ -3907,7 +3839,7 @@ static GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *
|
||||
points[1].X = pen->width;
|
||||
points[2].Y = pen->width;
|
||||
|
||||
stat = GdipTransformPoints(graphics, CoordinateSpaceDevice,
|
||||
stat = gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice,
|
||||
CoordinateSpaceWorld, points, 3);
|
||||
|
||||
if (stat != Ok)
|
||||
@ -3931,7 +3863,7 @@ static GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *
|
||||
stat = GdipCreateMatrix(&transform);
|
||||
|
||||
if (stat == Ok)
|
||||
stat = get_graphics_transform(graphics, CoordinateSpaceDevice,
|
||||
stat = get_graphics_transform(graphics, WineCoordinateSpaceGdiDevice,
|
||||
CoordinateSpaceWorld, transform);
|
||||
}
|
||||
else
|
||||
@ -3939,7 +3871,7 @@ static GpStatus SOFTWARE_GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *
|
||||
/* Set flatness based on the final coordinate space */
|
||||
GpMatrix t;
|
||||
|
||||
stat = get_graphics_transform(graphics, CoordinateSpaceDevice,
|
||||
stat = get_graphics_transform(graphics, WineCoordinateSpaceGdiDevice,
|
||||
CoordinateSpaceWorld, &t);
|
||||
|
||||
if (stat != Ok)
|
||||
@ -4254,8 +4186,7 @@ static GpStatus GDI32_GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath
|
||||
if (retval != Ok)
|
||||
goto end;
|
||||
|
||||
if (hrgn)
|
||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
|
||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_COPY);
|
||||
|
||||
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))
|
||||
return NotImplemented;
|
||||
|
||||
status = GdipGetRegionHRgn(region, graphics, &hrgn);
|
||||
if(status != Ok)
|
||||
return status;
|
||||
|
||||
save_state = SaveDC(graphics->hdc);
|
||||
EndPath(graphics->hdc);
|
||||
|
||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
|
||||
|
||||
DeleteObject(hrgn);
|
||||
|
||||
hrgn = NULL;
|
||||
status = get_clip_hrgn(graphics, &hrgn);
|
||||
|
||||
if (status != Ok)
|
||||
{
|
||||
RestoreDC(graphics->hdc, save_state);
|
||||
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);
|
||||
DeleteObject(hrgn);
|
||||
RestoreDC(graphics->hdc, save_state);
|
||||
return status;
|
||||
}
|
||||
|
||||
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
|
||||
DeleteObject(hrgn);
|
||||
|
||||
if (GetClipBox(graphics->hdc, &rc) != NULLREGION)
|
||||
{
|
||||
BeginPath(graphics->hdc);
|
||||
@ -5371,7 +5300,7 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
|
||||
pt[1].Y = 0.0;
|
||||
pt[2].X = 0.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)+
|
||||
(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)+
|
||||
@ -5400,9 +5329,13 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
|
||||
|
||||
args.regions = regions;
|
||||
|
||||
gdi_transform_acquire(graphics);
|
||||
|
||||
stat = gdip_format_string(hdc, string, length, font, &scaled_rect, stringFormat,
|
||||
(stringFormat->attr & StringFormatFlagsNoClip) != 0, measure_ranges_callback, &args);
|
||||
|
||||
gdi_transform_release(graphics);
|
||||
|
||||
SelectObject(hdc, oldfont);
|
||||
DeleteObject(gdifont);
|
||||
|
||||
@ -5490,7 +5423,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
|
||||
pt[1].Y = 0.0;
|
||||
pt[2].X = 0.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)+
|
||||
(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)+
|
||||
@ -5525,9 +5458,13 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
|
||||
args.linesfilled = &lines;
|
||||
lines = glyphs = 0;
|
||||
|
||||
gdi_transform_acquire(graphics);
|
||||
|
||||
gdip_format_string(hdc, string, length, font, &scaled_rect, format, TRUE,
|
||||
measure_string_callback, &args);
|
||||
|
||||
gdi_transform_release(graphics);
|
||||
|
||||
if (linesfilled) *linesfilled = lines;
|
||||
if (codepointsfitted) *codepointsfitted = glyphs;
|
||||
|
||||
@ -5657,7 +5594,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
|
||||
pt[1].Y = 0.0;
|
||||
pt[2].X = 0.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)+
|
||||
(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)+
|
||||
@ -5667,7 +5604,8 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
|
||||
rectcpy[1].Y = rectcpy[0].Y = rect->Y;
|
||||
rectcpy[2].X = rectcpy[1].X = rect->X + rect->Width;
|
||||
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 *= 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_height = rel_height;
|
||||
|
||||
gdi_transform_acquire(graphics);
|
||||
|
||||
GetTextMetricsW(hdc, &textmetric);
|
||||
args.ascent = textmetric.tmAscent / rel_height;
|
||||
|
||||
gdip_format_string(hdc, string, length, font, &scaled_rect, format, TRUE,
|
||||
draw_string_callback, &args);
|
||||
|
||||
gdi_transform_release(graphics);
|
||||
|
||||
DeleteObject(rgn);
|
||||
DeleteObject(gdifont);
|
||||
|
||||
@ -6311,6 +6253,7 @@ GpStatus WINGDIPAPI GdipSetClipHrgn(GpGraphics *graphics, HRGN hrgn, CombineMode
|
||||
{
|
||||
GpRegion *region;
|
||||
GpStatus status;
|
||||
GpMatrix transform;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", graphics, hrgn, mode);
|
||||
|
||||
@ -6320,14 +6263,21 @@ GpStatus WINGDIPAPI GdipSetClipHrgn(GpGraphics *graphics, HRGN hrgn, CombineMode
|
||||
if(graphics->busy)
|
||||
return ObjectBusy;
|
||||
|
||||
/* hrgn is already in device units */
|
||||
/* hrgn is in gdi32 device units */
|
||||
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;
|
||||
}
|
||||
|
||||
@ -6723,31 +6673,10 @@ GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region)
|
||||
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)
|
||||
{
|
||||
if (graphics->gdi_transform_acquire_count == 0 && graphics->hdc)
|
||||
{
|
||||
get_gdi_transform(graphics, &graphics->gdi_transform);
|
||||
graphics->gdi_transform_save = SaveDC(graphics->hdc);
|
||||
SetGraphicsMode(graphics->hdc, GM_COMPATIBLE);
|
||||
SetMapMode(graphics->hdc, MM_TEXT);
|
||||
@ -6762,7 +6691,7 @@ GpStatus gdi_transform_release(GpGraphics *graphics)
|
||||
{
|
||||
if (graphics->gdi_transform_acquire_count <= 0)
|
||||
{
|
||||
ERR("called without matching gdi_transform_acquire");
|
||||
ERR("called without matching gdi_transform_acquire\n");
|
||||
return GenericError;
|
||||
}
|
||||
if (graphics->gdi_transform_acquire_count == 1 && graphics->hdc)
|
||||
@ -6800,7 +6729,7 @@ GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_spac
|
||||
case WineCoordinateSpaceGdiDevice:
|
||||
{
|
||||
GpMatrix gdixform;
|
||||
get_gdi_transform(graphics, &gdixform);
|
||||
gdixform = graphics->gdi_transform;
|
||||
stat = GdipInvertMatrix(&gdixform);
|
||||
if (stat != Ok)
|
||||
break;
|
||||
@ -6841,9 +6770,7 @@ GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_spac
|
||||
/* else fall-through */
|
||||
case CoordinateSpaceDevice:
|
||||
{
|
||||
GpMatrix gdixform;
|
||||
get_gdi_transform(graphics, &gdixform);
|
||||
GdipMultiplyMatrix(matrix, &gdixform, MatrixOrderAppend);
|
||||
GdipMultiplyMatrix(matrix, &graphics->gdi_transform, MatrixOrderAppend);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -7015,7 +6942,7 @@ GpStatus WINGDIPAPI GdipMeasureDriverString(GpGraphics *graphics, GDIPCONST UINT
|
||||
GpMatrix xform = *matrix;
|
||||
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)+
|
||||
(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)+
|
||||
@ -7102,22 +7029,26 @@ static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT1
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
SelectObject(graphics->hdc, hfont);
|
||||
|
||||
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);
|
||||
|
||||
gdi_transform_release(graphics);
|
||||
|
||||
RestoreDC(graphics->hdc, save_state);
|
||||
|
||||
DeleteObject(hfont);
|
||||
@ -7165,7 +7096,8 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -7178,7 +7110,8 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
|
||||
|
||||
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);
|
||||
}
|
||||
@ -7318,10 +7251,14 @@ static GpStatus SOFTWARE_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UI
|
||||
|
||||
heap_free(text_mask);
|
||||
|
||||
gdi_transform_acquire(graphics);
|
||||
|
||||
/* draw the result */
|
||||
stat = alpha_blend_pixels(graphics, min_x, min_y, pixel_data, pixel_area.Width,
|
||||
pixel_area.Height, pixel_data_stride, PixelFormat32bppARGB);
|
||||
|
||||
gdi_transform_release(graphics);
|
||||
|
||||
heap_free(pixel_data);
|
||||
|
||||
return stat;
|
||||
|
@ -38,19 +38,13 @@ static const struct
|
||||
{
|
||||
{ &GUID_WICPixelFormatBlackWhite, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
|
||||
{ &GUID_WICPixelFormat1bppIndexed, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
|
||||
{ &GUID_WICPixelFormat4bppIndexed, PixelFormat4bppIndexed, WICBitmapPaletteTypeFixedHalftone8 },
|
||||
{ &GUID_WICPixelFormat8bppGray, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedGray256 },
|
||||
{ &GUID_WICPixelFormat8bppIndexed, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedHalftone256 },
|
||||
{ &GUID_WICPixelFormat16bppBGR555, PixelFormat16bppRGB555, WICBitmapPaletteTypeFixedHalftone256 },
|
||||
{ &GUID_WICPixelFormat24bppBGR, PixelFormat24bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||
{ &GUID_WICPixelFormat32bppBGR, PixelFormat32bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||
{ &GUID_WICPixelFormat48bppRGB, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||
{ &GUID_WICPixelFormat32bppBGRA, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||
{ &GUID_WICPixelFormat32bppPBGRA, PixelFormat32bppPARGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||
{ &GUID_WICPixelFormat32bppCMYK, PixelFormat32bppCMYK, WICBitmapPaletteTypeFixedHalftone256 },
|
||||
{ &GUID_WICPixelFormat32bppGrayFloat, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedGray256 },
|
||||
{ &GUID_WICPixelFormat64bppCMYK, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||
{ &GUID_WICPixelFormat64bppRGBA, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -2074,24 +2068,7 @@ static GpStatus free_image_data(GpImage *image)
|
||||
heap_free(((GpBitmap*)image)->prop_item);
|
||||
}
|
||||
else if (image->type == ImageTypeMetafile)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
METAFILE_Free((GpMetafile *)image);
|
||||
else
|
||||
{
|
||||
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,
|
||||
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;
|
||||
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)
|
||||
return InvalidParameter;
|
||||
@ -5595,111 +5572,3 @@ GpStatus WINGDIPAPI GdipBitmapGetHistogramSize(HistogramFormat format, UINT *num
|
||||
*num_of_entries = 256;
|
||||
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,
|
||||
ColorAdjustType type, BOOL enableFlag)
|
||||
{
|
||||
static int calls;
|
||||
|
||||
TRACE("(%p,%u,%i)\n", imageAttr, type, enableFlag);
|
||||
|
||||
if(!(calls++))
|
||||
FIXME("not implemented\n");
|
||||
if (type >= ColorAdjustTypeCount)
|
||||
return InvalidParameter;
|
||||
|
||||
return NotImplemented;
|
||||
imageAttr->noop[type] = enableFlag ? IMAGEATTR_NOOP_SET : IMAGEATTR_NOOP_CLEAR;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipSetImageAttributesOutputChannel(GpImageAttributes *imageAttr,
|
||||
@ -323,6 +323,7 @@ GpStatus WINGDIPAPI GdipResetImageAttributes(GpImageAttributes *imageAttr,
|
||||
GdipSetImageAttributesColorKeys(imageAttr, type, FALSE, 0, 0);
|
||||
GdipSetImageAttributesRemapTable(imageAttr, type, FALSE, 0, NULL);
|
||||
GdipSetImageAttributesGamma(imageAttr, type, FALSE, 0.0);
|
||||
imageAttr->noop[type] = IMAGEATTR_NOOP_UNDEFINED;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -64,12 +64,6 @@
|
||||
|
||||
#define FLAGS_INTPATH 0x4000
|
||||
|
||||
struct memory_buffer
|
||||
{
|
||||
const BYTE *buffer;
|
||||
INT size, pos;
|
||||
};
|
||||
|
||||
struct region_header
|
||||
{
|
||||
DWORD magic;
|
||||
@ -766,24 +760,6 @@ GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size,
|
||||
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)
|
||||
{
|
||||
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/fontsub # Synced to WineStaging-2.9
|
||||
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/hlink # Synced to WineStaging-2.9
|
||||
reactos/dll/win32/hnetcfg # Synced to WineStaging-2.9
|
||||
|
Loading…
Reference in New Issue
Block a user