mirror of
https://github.com/reactos/reactos.git
synced 2024-08-06 11:24:58 +00:00
[GDIPLUS] Sync with Wine Staging 2.9. CORE-13362
11fc5c0 gdiplus: Prefer using pre-multiplied ARGB data in the scaler. 17162a9 gdiplus: Remove ceilf/floorf calls from bilinear scaler. (v2) 6bade0c gdiplus: Change multiplications by additions in the x/y scaler loops. db49130 gdiplus: Change the order of x/y loops in the scaler. 9247b54 gdiplus: Set correct color space flags for grayscale images. 81ccd6b gdiplus: Force conversion of 8 bpp grayscale PNG images to 32 bpp BGRA. 4fe61f3 gdiplus: Ignore an externally set DC clipping region. a188922 gdiplus: Ignore an externally set DC origin. b8a8e1b gdiplus: Check SHADEBLENDCAPS only for printer devices. c2a4f19 gdiplus: Fix compilation on systems that don't support nameless unions. 29a55bc gdiplus: Use software mode to draw semi-transparent lines when necessary. c89de1d gdiplus: Use better naming for line alignment format field. 69b41e7 gdiplus: Fix generic string formats behavior. a3f0a59 gdiplus: Avoid infinite recursion in flatten_bezier(). 36c9ac3 gdiplus: Check for null in GdipGetFontHeight. 7f25431 gdiplus: Fix GdipCreateStreamOnFile spec file entry. 43e36d6 gdiplus: Simplify and standardize the heap_xxx() declarations. svn path=/trunk/; revision=74795
This commit is contained in:
parent
903c7855c9
commit
718178aa88
|
@ -543,6 +543,8 @@ GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont *font,
|
||||||
|
|
||||||
TRACE("%p %p %p\n", font, graphics, height);
|
TRACE("%p %p %p\n", font, graphics, height);
|
||||||
|
|
||||||
|
if (!font || !height) return InvalidParameter;
|
||||||
|
|
||||||
stat = GdipGetFontHeightGivenDPI(font, font->family->dpi, &font_height);
|
stat = GdipGetFontHeightGivenDPI(font, font->family->dpi, &font_height);
|
||||||
if (stat != Ok) return stat;
|
if (stat != Ok) return stat;
|
||||||
|
|
||||||
|
|
|
@ -46,11 +46,13 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
DisableThreadLibraryCalls( hinst );
|
DisableThreadLibraryCalls( hinst );
|
||||||
|
init_generic_string_formats();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
if (reserved) break;
|
if (reserved) break;
|
||||||
free_installed_fonts();
|
free_installed_fonts();
|
||||||
|
free_generic_string_formats();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -120,7 +120,7 @@
|
||||||
120 stdcall GdipCreateRegionRectI(ptr ptr)
|
120 stdcall GdipCreateRegionRectI(ptr ptr)
|
||||||
121 stdcall GdipCreateRegionRgnData(ptr long ptr)
|
121 stdcall GdipCreateRegionRgnData(ptr long ptr)
|
||||||
122 stdcall GdipCreateSolidFill(long ptr)
|
122 stdcall GdipCreateSolidFill(long ptr)
|
||||||
123 stdcall GdipCreateStreamOnFile(ptr long ptr)
|
123 stdcall GdipCreateStreamOnFile(wstr long ptr)
|
||||||
124 stdcall GdipCreateStringFormat(long long ptr)
|
124 stdcall GdipCreateStringFormat(long long ptr)
|
||||||
125 stdcall GdipCreateTexture2(ptr long float float float float ptr)
|
125 stdcall GdipCreateTexture2(ptr long float float float float ptr)
|
||||||
126 stdcall GdipCreateTexture2I(ptr long long long long long ptr)
|
126 stdcall GdipCreateTexture2I(ptr long long long long long ptr)
|
||||||
|
|
|
@ -56,22 +56,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
|
||||||
#define GIF_DISPOSE_RESTORE_TO_BKGND 2
|
#define GIF_DISPOSE_RESTORE_TO_BKGND 2
|
||||||
#define GIF_DISPOSE_RESTORE_TO_PREV 3
|
#define GIF_DISPOSE_RESTORE_TO_PREV 3
|
||||||
|
|
||||||
static void *heap_alloc(size_t len) __WINE_ALLOC_SIZE(1);
|
static inline void* __WINE_ALLOC_SIZE(1) heap_alloc(size_t size)
|
||||||
static inline void *heap_alloc(size_t len)
|
|
||||||
{
|
{
|
||||||
return HeapAlloc(GetProcessHeap(), 0, len);
|
return HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *heap_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1);
|
static inline void* __WINE_ALLOC_SIZE(1) heap_alloc_zero(size_t size)
|
||||||
static inline void *heap_alloc_zero(size_t len)
|
|
||||||
{
|
{
|
||||||
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
|
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *heap_realloc(void *mem, size_t len) __WINE_ALLOC_SIZE(2);
|
static inline void* __WINE_ALLOC_SIZE(2) heap_realloc(void *mem, size_t size)
|
||||||
static inline void *heap_realloc(void *mem, size_t len)
|
|
||||||
{
|
{
|
||||||
return HeapReAlloc(GetProcessHeap(), 0, mem, len);
|
return HeapReAlloc(GetProcessHeap(), 0, mem, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline BOOL heap_free(void *mem)
|
static inline BOOL heap_free(void *mem)
|
||||||
|
@ -452,6 +449,8 @@ struct GpFont{
|
||||||
Unit unit;
|
Unit unit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const struct GpStringFormat default_drawstring_format DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
struct GpStringFormat{
|
struct GpStringFormat{
|
||||||
INT attr;
|
INT attr;
|
||||||
LANGID lang;
|
LANGID lang;
|
||||||
|
@ -459,7 +458,7 @@ struct GpStringFormat{
|
||||||
StringAlignment align;
|
StringAlignment align;
|
||||||
StringTrimming trimming;
|
StringTrimming trimming;
|
||||||
HotkeyPrefix hkprefix;
|
HotkeyPrefix hkprefix;
|
||||||
StringAlignment vertalign;
|
StringAlignment line_align;
|
||||||
StringDigitSubstitute digitsub;
|
StringDigitSubstitute digitsub;
|
||||||
INT tabcount;
|
INT tabcount;
|
||||||
REAL firsttab;
|
REAL firsttab;
|
||||||
|
@ -469,6 +468,9 @@ struct GpStringFormat{
|
||||||
BOOL generic_typographic;
|
BOOL generic_typographic;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern void init_generic_string_formats(void) DECLSPEC_HIDDEN;
|
||||||
|
extern void free_generic_string_formats(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
struct GpFontCollection{
|
struct GpFontCollection{
|
||||||
GpFontFamily **FontFamilies;
|
GpFontFamily **FontFamilies;
|
||||||
INT count;
|
INT count;
|
||||||
|
|
|
@ -519,12 +519,23 @@ 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 = gdip_round(position * 0xff);
|
pos = (INT)(position * 255.0f + 0.5f);
|
||||||
|
|
||||||
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;
|
||||||
|
@ -926,6 +937,11 @@ 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)
|
||||||
|
@ -946,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;
|
||||||
|
|
||||||
leftxf = floorf(point->X);
|
leftx = (INT)point->X;
|
||||||
leftx = (INT)leftxf;
|
leftxf = (REAL)leftx;
|
||||||
rightx = (INT)ceilf(point->X);
|
rightx = positive_ceilf(point->X);
|
||||||
topyf = floorf(point->Y);
|
topy = (INT)point->Y;
|
||||||
topy = (INT)topyf;
|
topyf = (REAL)topy;
|
||||||
bottomy = (INT)ceilf(point->Y);
|
bottomy = positive_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,
|
||||||
|
@ -995,17 +1011,95 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL brush_can_fill_path(GpBrush *brush)
|
/* is_fill is TRUE if filling regions, FALSE for drawing primitives */
|
||||||
|
static BOOL brush_can_fill_path(GpBrush *brush, BOOL is_fill)
|
||||||
{
|
{
|
||||||
switch (brush->bt)
|
switch (brush->bt)
|
||||||
{
|
{
|
||||||
case BrushTypeSolidColor:
|
case BrushTypeSolidColor:
|
||||||
return TRUE;
|
{
|
||||||
|
if (is_fill)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* cannot draw semi-transparent colors */
|
||||||
|
return (((GpSolidFill*)brush)->color & 0xff000000) == 0xff000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
case BrushTypeHatchFill:
|
case BrushTypeHatchFill:
|
||||||
{
|
{
|
||||||
GpHatch *hatch = (GpHatch*)brush;
|
GpHatch *hatch = (GpHatch*)brush;
|
||||||
|
@ -3003,8 +3097,10 @@ 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
|
else if (imageAttributes != &defaultImageAttributes)
|
||||||
lockeddata.PixelFormat = PixelFormat32bppARGB;
|
lockeddata.PixelFormat = PixelFormat32bppARGB;
|
||||||
|
else
|
||||||
|
lockeddata.PixelFormat = PixelFormat32bppPARGB;
|
||||||
|
|
||||||
stat = GdipBitmapLockBits(bitmap, &src_area, ImageLockModeRead|ImageLockModeUserInputBuf,
|
stat = GdipBitmapLockBits(bitmap, &src_area, ImageLockModeRead|ImageLockModeUserInputBuf,
|
||||||
lockeddata.PixelFormat, &lockeddata);
|
lockeddata.PixelFormat, &lockeddata);
|
||||||
|
@ -3024,6 +3120,8 @@ 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)
|
||||||
|
@ -3041,24 +3139,42 @@ 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;
|
||||||
|
|
||||||
for (x=dst_area.left; x<dst_area.right; x++)
|
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 (y=dst_area.top; y<dst_area.bottom; y++)
|
delta_xx = dst_area.left * x_dx;
|
||||||
|
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 + x * x_dx + y * y_dx;
|
src_pointf.X = dst_to_src_points[0].X + delta_xx + delta_yx;
|
||||||
src_pointf.Y = dst_to_src_points[0].Y + x * x_dy + y * y_dy;
|
src_pointf.Y = dst_to_src_points[0].Y + delta_xy + delta_yy;
|
||||||
|
|
||||||
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,
|
{
|
||||||
imageAttributes, interpolation, offset_mode);
|
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);
|
||||||
|
}
|
||||||
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
|
||||||
|
@ -3784,7 +3900,7 @@ GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path)
|
||||||
if (path->pathdata.Count == 0)
|
if (path->pathdata.Count == 0)
|
||||||
return Ok;
|
return Ok;
|
||||||
|
|
||||||
if (!graphics->hdc)
|
if (!graphics->hdc || !brush_can_fill_path(pen->brush, FALSE))
|
||||||
retval = SOFTWARE_GdipDrawPath(graphics, pen, path);
|
retval = SOFTWARE_GdipDrawPath(graphics, pen, path);
|
||||||
else
|
else
|
||||||
retval = GDI32_GdipDrawPath(graphics, pen, path);
|
retval = GDI32_GdipDrawPath(graphics, pen, path);
|
||||||
|
@ -4034,7 +4150,7 @@ static GpStatus GDI32_GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath
|
||||||
GpStatus retval;
|
GpStatus retval;
|
||||||
HRGN hrgn=NULL;
|
HRGN hrgn=NULL;
|
||||||
|
|
||||||
if(!graphics->hdc || !brush_can_fill_path(brush))
|
if(!graphics->hdc || !brush_can_fill_path(brush, TRUE))
|
||||||
return NotImplemented;
|
return NotImplemented;
|
||||||
|
|
||||||
save_state = SaveDC(graphics->hdc);
|
save_state = SaveDC(graphics->hdc);
|
||||||
|
@ -4327,7 +4443,7 @@ static GpStatus GDI32_GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
|
||||||
HRGN hrgn;
|
HRGN hrgn;
|
||||||
RECT rc;
|
RECT rc;
|
||||||
|
|
||||||
if(!graphics->hdc || !brush_can_fill_path(brush))
|
if(!graphics->hdc || !brush_can_fill_path(brush, TRUE))
|
||||||
return NotImplemented;
|
return NotImplemented;
|
||||||
|
|
||||||
status = GdipGetRegionHRgn(region, graphics, &hrgn);
|
status = GdipGetRegionHRgn(region, graphics, &hrgn);
|
||||||
|
@ -4908,7 +5024,6 @@ GpStatus gdip_format_string(HDC hdc,
|
||||||
INT hotkeyprefix_count=0;
|
INT hotkeyprefix_count=0;
|
||||||
INT hotkeyprefix_pos=0, hotkeyprefix_end_pos=0;
|
INT hotkeyprefix_pos=0, hotkeyprefix_end_pos=0;
|
||||||
BOOL seen_prefix = FALSE;
|
BOOL seen_prefix = FALSE;
|
||||||
GpStringFormat *dyn_format=NULL;
|
|
||||||
|
|
||||||
if(length == -1) length = lstrlenW(string);
|
if(length == -1) length = lstrlenW(string);
|
||||||
|
|
||||||
|
@ -4916,15 +5031,7 @@ GpStatus gdip_format_string(HDC hdc,
|
||||||
if(!stringdup) return OutOfMemory;
|
if(!stringdup) return OutOfMemory;
|
||||||
|
|
||||||
if (!format)
|
if (!format)
|
||||||
{
|
format = &default_drawstring_format;
|
||||||
stat = GdipStringFormatGetGenericDefault(&dyn_format);
|
|
||||||
if (stat != Ok)
|
|
||||||
{
|
|
||||||
heap_free(stringdup);
|
|
||||||
return stat;
|
|
||||||
}
|
|
||||||
format = dyn_format;
|
|
||||||
}
|
|
||||||
|
|
||||||
nwidth = rect->Width;
|
nwidth = rect->Width;
|
||||||
nheight = rect->Height;
|
nheight = rect->Height;
|
||||||
|
@ -5074,7 +5181,6 @@ GpStatus gdip_format_string(HDC hdc,
|
||||||
|
|
||||||
heap_free(stringdup);
|
heap_free(stringdup);
|
||||||
heap_free(hotkeyprefix_offsets);
|
heap_free(hotkeyprefix_offsets);
|
||||||
GdipDeleteStringFormat(dyn_format);
|
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
@ -5426,19 +5532,19 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
|
||||||
|
|
||||||
/* Should be no need to explicitly test for StringAlignmentNear as
|
/* Should be no need to explicitly test for StringAlignmentNear as
|
||||||
* that is default behavior if no alignment is passed. */
|
* that is default behavior if no alignment is passed. */
|
||||||
if(format->vertalign != StringAlignmentNear){
|
if(format->line_align != StringAlignmentNear){
|
||||||
RectF bounds, in_rect = *rect;
|
RectF bounds, in_rect = *rect;
|
||||||
in_rect.Height = 0.0; /* avoid height clipping */
|
in_rect.Height = 0.0; /* avoid height clipping */
|
||||||
GdipMeasureString(graphics, string, length, font, &in_rect, format, &bounds, 0, 0);
|
GdipMeasureString(graphics, string, length, font, &in_rect, format, &bounds, 0, 0);
|
||||||
|
|
||||||
TRACE("bounds %s\n", debugstr_rectf(&bounds));
|
TRACE("bounds %s\n", debugstr_rectf(&bounds));
|
||||||
|
|
||||||
if(format->vertalign == StringAlignmentCenter)
|
if(format->line_align == StringAlignmentCenter)
|
||||||
offsety = (rect->Height - bounds.Height) / 2;
|
offsety = (rect->Height - bounds.Height) / 2;
|
||||||
else if(format->vertalign == StringAlignmentFar)
|
else if(format->line_align == StringAlignmentFar)
|
||||||
offsety = (rect->Height - bounds.Height);
|
offsety = (rect->Height - bounds.Height);
|
||||||
}
|
}
|
||||||
TRACE("vertical align %d, offsety %f\n", format->vertalign, offsety);
|
TRACE("line align %d, offsety %f\n", format->line_align, offsety);
|
||||||
}
|
}
|
||||||
|
|
||||||
save_state = SaveDC(hdc);
|
save_state = SaveDC(hdc);
|
||||||
|
|
|
@ -128,6 +128,10 @@ static BOOL flatten_bezier(path_list_node_t *start, REAL x2, REAL y2, REAL x3, R
|
||||||
mp[2].X = (mp[1].X + mp[3].X) / 2.0;
|
mp[2].X = (mp[1].X + mp[3].X) / 2.0;
|
||||||
mp[2].Y = (mp[1].Y + mp[3].Y) / 2.0;
|
mp[2].Y = (mp[1].Y + mp[3].Y) / 2.0;
|
||||||
|
|
||||||
|
if ((x2 == mp[0].X && y2 == mp[0].Y && x3 == mp[1].X && y3 == mp[1].Y) ||
|
||||||
|
(x2 == mp[3].X && y2 == mp[3].Y && x3 == mp[4].X && y3 == mp[4].Y))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
pt = end->pt;
|
pt = end->pt;
|
||||||
pt_st = start->pt;
|
pt_st = start->pt;
|
||||||
/* check flatness as a half of distance between middle point and a linearized path */
|
/* check flatness as a half of distance between middle point and a linearized path */
|
||||||
|
@ -1010,13 +1014,13 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
|
||||||
heap_free(backup);
|
heap_free(backup);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
if (format && format->vertalign == StringAlignmentCenter && layoutRect->Y + args.maxY < layoutRect->Height)
|
if (format && format->line_align == StringAlignmentCenter && layoutRect->Y + args.maxY < layoutRect->Height)
|
||||||
{
|
{
|
||||||
float inc = layoutRect->Height + layoutRect->Y - args.maxY;
|
float inc = layoutRect->Height + layoutRect->Y - args.maxY;
|
||||||
inc /= 2;
|
inc /= 2;
|
||||||
for (i = backup->pathdata.Count; i < path->pathdata.Count; ++i)
|
for (i = backup->pathdata.Count; i < path->pathdata.Count; ++i)
|
||||||
path->pathdata.Points[i].Y += inc;
|
path->pathdata.Points[i].Y += inc;
|
||||||
} else if (format && format->vertalign == StringAlignmentFar) {
|
} else if (format && format->line_align == StringAlignmentFar) {
|
||||||
float inc = layoutRect->Height + layoutRect->Y - args.maxY;
|
float inc = layoutRect->Height + layoutRect->Y - args.maxY;
|
||||||
for (i = backup->pathdata.Count; i < path->pathdata.Count; ++i)
|
for (i = backup->pathdata.Count; i < path->pathdata.Count; ++i)
|
||||||
path->pathdata.Points[i].Y += inc;
|
path->pathdata.Points[i].Y += inc;
|
||||||
|
|
|
@ -40,7 +40,6 @@ static const struct
|
||||||
{ &GUID_WICPixelFormat1bppIndexed, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
|
{ &GUID_WICPixelFormat1bppIndexed, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW },
|
||||||
{ &GUID_WICPixelFormat4bppIndexed, PixelFormat4bppIndexed, WICBitmapPaletteTypeFixedHalftone8 },
|
{ &GUID_WICPixelFormat4bppIndexed, PixelFormat4bppIndexed, WICBitmapPaletteTypeFixedHalftone8 },
|
||||||
{ &GUID_WICPixelFormat8bppGray, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedGray256 },
|
{ &GUID_WICPixelFormat8bppGray, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedGray256 },
|
||||||
{ &GUID_WICPixelFormat32bppGrayFloat, PixelFormat32bppARGB, 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 },
|
||||||
|
@ -49,6 +48,7 @@ static const struct
|
||||||
{ &GUID_WICPixelFormat32bppBGRA, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedHalftone256 },
|
{ &GUID_WICPixelFormat32bppBGRA, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||||
{ &GUID_WICPixelFormat32bppPBGRA, PixelFormat32bppPARGB, WICBitmapPaletteTypeFixedHalftone256 },
|
{ &GUID_WICPixelFormat32bppPBGRA, PixelFormat32bppPARGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||||
{ &GUID_WICPixelFormat32bppCMYK, PixelFormat32bppCMYK, WICBitmapPaletteTypeFixedHalftone256 },
|
{ &GUID_WICPixelFormat32bppCMYK, PixelFormat32bppCMYK, WICBitmapPaletteTypeFixedHalftone256 },
|
||||||
|
{ &GUID_WICPixelFormat32bppGrayFloat, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedGray256 },
|
||||||
{ &GUID_WICPixelFormat64bppCMYK, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
{ &GUID_WICPixelFormat64bppCMYK, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||||
{ &GUID_WICPixelFormat64bppRGBA, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
{ &GUID_WICPixelFormat64bppRGBA, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
|
|
|
@ -19,6 +19,47 @@
|
||||||
|
|
||||||
#include "gdiplus_private.h"
|
#include "gdiplus_private.h"
|
||||||
|
|
||||||
|
const GpStringFormat default_drawstring_format =
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
LANG_NEUTRAL,
|
||||||
|
LANG_NEUTRAL,
|
||||||
|
StringAlignmentNear,
|
||||||
|
StringTrimmingCharacter,
|
||||||
|
HotkeyPrefixNone,
|
||||||
|
StringAlignmentNear,
|
||||||
|
StringDigitSubstituteUser,
|
||||||
|
0,
|
||||||
|
0.0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
FALSE
|
||||||
|
};
|
||||||
|
|
||||||
|
static GpStringFormat generic_default_format;
|
||||||
|
static GpStringFormat generic_typographic_format;
|
||||||
|
|
||||||
|
void init_generic_string_formats(void)
|
||||||
|
{
|
||||||
|
memcpy(&generic_default_format, &default_drawstring_format, sizeof(generic_default_format));
|
||||||
|
|
||||||
|
memcpy(&generic_typographic_format, &default_drawstring_format, sizeof(generic_typographic_format));
|
||||||
|
generic_typographic_format.attr = StringFormatFlagsNoFitBlackBox | StringFormatFlagsLineLimit |
|
||||||
|
StringFormatFlagsNoClip;
|
||||||
|
generic_typographic_format.trimming = StringTrimmingNone;
|
||||||
|
generic_typographic_format.generic_typographic = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_generic_string_formats(void)
|
||||||
|
{
|
||||||
|
heap_free(generic_default_format.character_ranges);
|
||||||
|
heap_free(generic_default_format.tabs);
|
||||||
|
|
||||||
|
heap_free(generic_typographic_format.character_ranges);
|
||||||
|
heap_free(generic_typographic_format.tabs);
|
||||||
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipCreateStringFormat(INT attr, LANGID lang,
|
GpStatus WINGDIPAPI GdipCreateStringFormat(INT attr, LANGID lang,
|
||||||
GpStringFormat **format)
|
GpStringFormat **format)
|
||||||
{
|
{
|
||||||
|
@ -53,6 +94,9 @@ GpStatus WINGDIPAPI GdipDeleteStringFormat(GpStringFormat *format)
|
||||||
if(!format)
|
if(!format)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
|
if (format == &generic_default_format || format == &generic_typographic_format)
|
||||||
|
return Ok;
|
||||||
|
|
||||||
heap_free(format->character_ranges);
|
heap_free(format->character_ranges);
|
||||||
heap_free(format->tabs);
|
heap_free(format->tabs);
|
||||||
heap_free(format);
|
heap_free(format);
|
||||||
|
@ -62,17 +106,10 @@ GpStatus WINGDIPAPI GdipDeleteStringFormat(GpStringFormat *format)
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipStringFormatGetGenericDefault(GpStringFormat **format)
|
GpStatus WINGDIPAPI GdipStringFormatGetGenericDefault(GpStringFormat **format)
|
||||||
{
|
{
|
||||||
GpStatus stat;
|
|
||||||
|
|
||||||
if (!format)
|
if (!format)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
stat = GdipCreateStringFormat(0, LANG_NEUTRAL, format);
|
*format = &generic_default_format;
|
||||||
if(stat != Ok)
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
(*format)->align = StringAlignmentNear;
|
|
||||||
(*format)->vertalign = StringAlignmentNear;
|
|
||||||
|
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +165,7 @@ GpStatus WINGDIPAPI GdipGetStringFormatLineAlign(GpStringFormat *format,
|
||||||
if(!format || !align)
|
if(!format || !align)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
*align = format->vertalign;
|
*align = format->line_align;
|
||||||
|
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
@ -232,7 +269,7 @@ GpStatus WINGDIPAPI GdipSetStringFormatLineAlign(GpStringFormat *format,
|
||||||
if(!format)
|
if(!format)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
format->vertalign = align;
|
format->line_align = align;
|
||||||
|
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
@ -357,24 +394,10 @@ GpStatus WINGDIPAPI GdipCloneStringFormat(GDIPCONST GpStringFormat *format, GpSt
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipStringFormatGetGenericTypographic(GpStringFormat **format)
|
GpStatus WINGDIPAPI GdipStringFormatGetGenericTypographic(GpStringFormat **format)
|
||||||
{
|
{
|
||||||
GpStatus stat;
|
|
||||||
|
|
||||||
if(!format)
|
if(!format)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
stat = GdipCreateStringFormat(StringFormatFlagsNoFitBlackBox |
|
*format = &generic_typographic_format;
|
||||||
StringFormatFlagsLineLimit |
|
|
||||||
StringFormatFlagsNoClip, LANG_NEUTRAL, format);
|
|
||||||
if(stat != Ok)
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
(*format)->digitlang = LANG_NEUTRAL;
|
|
||||||
(*format)->digitsub = StringDigitSubstituteUser;
|
|
||||||
(*format)->trimming = StringTrimmingNone;
|
|
||||||
(*format)->hkprefix = HotkeyPrefixNone;
|
|
||||||
(*format)->align = StringAlignmentNear;
|
|
||||||
(*format)->vertalign = StringAlignmentNear;
|
|
||||||
(*format)->generic_typographic = TRUE;
|
|
||||||
|
|
||||||
TRACE("%p => %p\n", format, *format);
|
TRACE("%p => %p\n", format, *format);
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ reactos/dll/win32/dciman32 # Synced to WineStaging-1.9.11
|
||||||
reactos/dll/win32/faultrep # Synced to WineStaging-1.9.11
|
reactos/dll/win32/faultrep # Synced to WineStaging-1.9.11
|
||||||
reactos/dll/win32/fontsub # Synced to WineStaging-1.9.13
|
reactos/dll/win32/fontsub # Synced to WineStaging-1.9.13
|
||||||
reactos/dll/win32/fusion # Synced to WineStaging-1.9.23
|
reactos/dll/win32/fusion # Synced to WineStaging-1.9.23
|
||||||
reactos/dll/win32/gdiplus # Synced to WineStaging-2.2
|
reactos/dll/win32/gdiplus # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-2.2
|
reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-2.2
|
||||||
reactos/dll/win32/hlink # Synced to WineStaging-2.2
|
reactos/dll/win32/hlink # Synced to WineStaging-2.2
|
||||||
reactos/dll/win32/hnetcfg # Synced to WineStaging-1.9.16
|
reactos/dll/win32/hnetcfg # Synced to WineStaging-1.9.16
|
||||||
|
|
Loading…
Reference in a new issue