mirror of
https://github.com/reactos/reactos.git
synced 2024-06-25 23:41:35 +00:00
[WINESYNC] Sync gdiplus to Wine 7abca97
This commit is contained in:
parent
68a8619b7b
commit
49389438a3
|
@ -96,7 +96,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
|||
*clone = heap_alloc_zero(sizeof(GpPathGradient));
|
||||
if (!*clone) return OutOfMemory;
|
||||
|
||||
src = (GpPathGradient*) brush,
|
||||
src = (GpPathGradient*) brush;
|
||||
dest = (GpPathGradient*) *clone;
|
||||
|
||||
memcpy(dest, src, sizeof(GpPathGradient));
|
||||
|
@ -226,40 +226,65 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
|||
return Ok;
|
||||
}
|
||||
|
||||
static const char HatchBrushes[][8] = {
|
||||
{ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HatchStyleHorizontal */
|
||||
{ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleVertical */
|
||||
{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HatchStyleForwardDiagonal */
|
||||
{ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HatchStyleBackwardDiagonal */
|
||||
{ 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleCross */
|
||||
{ 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }, /* HatchStyleDiagonalCross */
|
||||
/* The first 8 items per entry are bitmaps for each row of the hatch style.
|
||||
* The 9th item of the entry is a flag indicating anti-aliasing. */
|
||||
static const unsigned char HatchBrushes[][9] = {
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff }, /* HatchStyleHorizontal */
|
||||
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, /* HatchStyleVertical */
|
||||
{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, TRUE }, /* HatchStyleForwardDiagonal */
|
||||
{ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, TRUE }, /* HatchStyleBackwardDiagonal */
|
||||
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xff }, /* HatchStyleCross */
|
||||
{ 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81, TRUE }, /* HatchStyleDiagonalCross */
|
||||
{ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80 }, /* HatchStyle05Percent */
|
||||
{ 0x00, 0x02, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88 }, /* HatchStyle10Percent */
|
||||
{ 0x00, 0x22, 0x00, 0xcc, 0x00, 0x22, 0x00, 0xcc }, /* HatchStyle20Percent */
|
||||
{ 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc }, /* HatchStyle25Percent */
|
||||
{ 0x00, 0xcc, 0x04, 0xcc, 0x00, 0xcc, 0x40, 0xcc }, /* HatchStyle30Percent */
|
||||
{ 0x44, 0xcc, 0x22, 0xcc, 0x44, 0xcc, 0x22, 0xcc }, /* HatchStyle40Percent */
|
||||
{ 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc }, /* HatchStyle50Percent */
|
||||
{ 0x55, 0xcd, 0x55, 0xee, 0x55, 0xdc, 0x55, 0xee }, /* HatchStyle60Percent */
|
||||
{ 0x55, 0xdd, 0x55, 0xff, 0x55, 0xdd, 0x55, 0xff }, /* HatchStyle70Percent */
|
||||
{ 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff }, /* HatchStyle75Percent */
|
||||
{ 0x55, 0xff, 0x59, 0xff, 0x55, 0xff, 0x99, 0xff }, /* HatchStyle80Percent */
|
||||
{ 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xfd, 0xff }, /* HatchStyle90Percent */
|
||||
{ 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00, 0x80 }, /* HatchStyle10Percent */
|
||||
{ 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88 }, /* HatchStyle20Percent */
|
||||
{ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88 }, /* HatchStyle25Percent */
|
||||
{ 0x11, 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa }, /* HatchStyle30Percent */
|
||||
{ 0x15, 0xaa, 0x55, 0xaa, 0x51, 0xaa, 0x55, 0xaa }, /* HatchStyle40Percent */
|
||||
{ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa }, /* HatchStyle50Percent */
|
||||
{ 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee }, /* HatchStyle60Percent */
|
||||
{ 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77 }, /* HatchStyle70Percent */
|
||||
{ 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff, 0x77 }, /* HatchStyle75Percent */
|
||||
{ 0xff, 0xfe, 0xff, 0xef, 0xff, 0xfe, 0xff, 0xef }, /* HatchStyle80Percent */
|
||||
{ 0x7f, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff }, /* HatchStyle90Percent */
|
||||
{ 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 }, /* HatchStyleLightDownwardDiagonal */
|
||||
{ 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }, /* HatchStyleLightUpwardDiagonal */
|
||||
{ 0x99, 0x33, 0x66, 0xcc, 0x99, 0x33, 0x66, 0xcc }, /* HatchStyleDarkDownwardDiagonal */
|
||||
{ 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 }, /* HatchStyleDarkUpwardDiagonal */
|
||||
{ 0xc1, 0x83, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0 }, /* HatchStyleWideDownwardDiagonal */
|
||||
{ 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x83, 0xc1 }, /* HatchStyleWideUpwardDiagonal */
|
||||
{ 0x99, 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33 }, /* HatchStyleDarkUpwardDiagonal */
|
||||
{ 0x83, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xc1 }, /* HatchStyleWideDownwardDiagonal */
|
||||
{ 0xc1, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x83 }, /* HatchStyleWideUpwardDiagonal */
|
||||
{ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }, /* HatchStyleLightVertical */
|
||||
{ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }, /* HatchStyleLightHorizontal */
|
||||
{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, /* HatchStyleNarrowVertical */
|
||||
{ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 }, /* HatchStyleNarrowVertical */
|
||||
{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, /* HatchStyleNarrowHorizontal */
|
||||
{ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }, /* HatchStyleDarkVertical */
|
||||
{ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */
|
||||
{ 0x00, 0x00, 0x11, 0x22, 0x44, 0x88, 0x00, 0x00 }, /* HatchStyleDashedDownwardDiagonal */
|
||||
{ 0x00, 0x00, 0x88, 0x44, 0x22, 0x11, 0x00, 0x00 }, /* HatchStyleDashedUpwardDiagonal */
|
||||
{ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0 }, /* HatchStyleDashedHorizontal */
|
||||
{ 0x08, 0x08, 0x08, 0x08, 0x80, 0x80, 0x80, 0x80 }, /* HatchStyleDashedVertical */
|
||||
{ 0x04, 0x20, 0x01, 0x10, 0x02, 0x40, 0x08, 0x80 }, /* HatchStyleSmallConfetti */
|
||||
{ 0x8d, 0x0c, 0xc0, 0xd8, 0x1b, 0x03, 0x30, 0xb1 }, /* HatchStyleLargeConfetti */
|
||||
{ 0x18, 0x24, 0x42, 0x81, 0x18, 0x24, 0x42, 0x81 }, /* HatchStyleZigZag */
|
||||
{ 0xc0, 0x25, 0x18, 0x00, 0xc0, 0x25, 0x18, 0x00 }, /* HatchStyleWave */
|
||||
{ 0x81, 0x42, 0x24, 0x18, 0x08, 0x04, 0x02, 0x01 }, /* HatchStyleDiagonalBrick */
|
||||
{ 0x08, 0x08, 0x08, 0xff, 0x80, 0x80, 0x80, 0xff }, /* HatchStyleHorizontalBrick */
|
||||
{ 0x51, 0x22, 0x14, 0x88, 0x45, 0x22, 0x54, 0x88 }, /* HatchStyleWeave */
|
||||
{ 0xf0, 0xf0, 0xf0, 0xf0, 0x55, 0xaa, 0x55, 0xaa }, /* HatchStylePlaid */
|
||||
{ 0x80, 0x01, 0x80, 0x00, 0x10, 0x08, 0x10, 0x00 }, /* HatchStyleDivot */
|
||||
{ 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xaa }, /* HatchStyleDottedGrid */
|
||||
{ 0x00, 0x22, 0x00, 0x08, 0x00, 0x22, 0x00, 0x80 }, /* HatchStyleDottedDiamond */
|
||||
{ 0x01, 0x01, 0x02, 0x0c, 0x30, 0x48, 0x84, 0x03 }, /* HatchStyleShingle */
|
||||
{ 0x99, 0xff, 0x66, 0xff, 0x99, 0xff, 0x66, 0xff }, /* HatchStyleTrellis */
|
||||
{ 0xf8, 0xf8, 0x98, 0x77, 0x8f, 0x8f, 0x89, 0x77 }, /* HatchStyleSphere */
|
||||
{ 0x88, 0x88, 0x88, 0xff, 0x88, 0x88, 0x88, 0xff }, /* HatchStyleSmallGrid */
|
||||
{ 0x99, 0x66, 0x66, 0x99, 0x99, 0x66, 0x66, 0x99 }, /* HatchStyleSmallCheckerBoard */
|
||||
{ 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0 }, /* HatchStyleLargeCheckerBoard */
|
||||
{ 0x01, 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82 }, /* HatchStyleOutlinedDiamond */
|
||||
{ 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10 }, /* HatchStyleSolidDiamond */
|
||||
};
|
||||
|
||||
GpStatus get_hatch_data(GpHatchStyle hatchstyle, const char **result)
|
||||
GpStatus get_hatch_data(GpHatchStyle hatchstyle, const unsigned char **result)
|
||||
{
|
||||
if (hatchstyle < ARRAY_SIZE(HatchBrushes))
|
||||
{
|
||||
|
@ -275,7 +300,7 @@ GpStatus get_hatch_data(GpHatchStyle hatchstyle, const char **result)
|
|||
*/
|
||||
GpStatus WINGDIPAPI GdipCreateHatchBrush(GpHatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush)
|
||||
{
|
||||
TRACE("(%d, %d, %d, %p)\n", hatchstyle, forecol, backcol, brush);
|
||||
TRACE("(%d, %ld, %ld, %p)\n", hatchstyle, forecol, backcol, brush);
|
||||
|
||||
if(!brush) return InvalidParameter;
|
||||
|
||||
|
@ -376,7 +401,7 @@ GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint,
|
|||
GpStatus stat;
|
||||
GpRectF rect;
|
||||
|
||||
TRACE("(%s, %s, %x, %x, %d, %p)\n", debugstr_pointf(startpoint),
|
||||
TRACE("(%s, %s, %lx, %lx, %d, %p)\n", debugstr_pointf(startpoint),
|
||||
debugstr_pointf(endpoint), startcolor, endcolor, wrap, line);
|
||||
|
||||
if(!line || !startpoint || !endpoint || wrap == WrapModeClamp)
|
||||
|
@ -419,7 +444,7 @@ GpStatus WINGDIPAPI GdipCreateLineBrushI(GDIPCONST GpPoint* startpoint,
|
|||
GpPointF stF;
|
||||
GpPointF endF;
|
||||
|
||||
TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint, endpoint,
|
||||
TRACE("(%p, %p, %lx, %lx, %d, %p)\n", startpoint, endpoint,
|
||||
startcolor, endcolor, wrap, line);
|
||||
|
||||
if(!startpoint || !endpoint)
|
||||
|
@ -439,7 +464,7 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRect(GDIPCONST GpRectF* rect,
|
|||
{
|
||||
float angle;
|
||||
|
||||
TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
|
||||
TRACE("(%s, %lx, %lx, %d, %d, %p)\n", debugstr_rectf(rect), startcolor, endcolor, mode,
|
||||
wrap, line);
|
||||
|
||||
if(!line || !rect)
|
||||
|
@ -472,14 +497,10 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectI(GDIPCONST GpRect* rect,
|
|||
{
|
||||
GpRectF rectF;
|
||||
|
||||
TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
|
||||
TRACE("(%p, %lx, %lx, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
|
||||
wrap, line);
|
||||
|
||||
rectF.X = (REAL) rect->X;
|
||||
rectF.Y = (REAL) rect->Y;
|
||||
rectF.Width = (REAL) rect->Width;
|
||||
rectF.Height = (REAL) rect->Height;
|
||||
|
||||
set_rect(&rectF, rect->X, rect->Y, rect->Width, rect->Height);
|
||||
return GdipCreateLineBrushFromRect(&rectF, startcolor, endcolor, mode, wrap, line);
|
||||
}
|
||||
|
||||
|
@ -495,7 +516,7 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect
|
|||
REAL sin_angle, cos_angle, sin_cos_angle;
|
||||
GpPointF start, end;
|
||||
|
||||
TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
|
||||
TRACE("(%s, %lx, %lx, %.2f, %d, %d, %p)\n", debugstr_rectf(rect), startcolor, endcolor, angle, isAngleScalable,
|
||||
wrap, line);
|
||||
|
||||
if (!rect || !line || wrap == WrapModeClamp)
|
||||
|
@ -594,7 +615,7 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect
|
|||
ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
|
||||
GpLineGradient **line)
|
||||
{
|
||||
TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
|
||||
TRACE("(%p, %lx, %lx, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable,
|
||||
wrap, line);
|
||||
|
||||
return GdipCreateLineBrushFromRectI(rect, startcolor, endcolor, LinearGradientModeForwardDiagonal,
|
||||
|
@ -603,7 +624,8 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect
|
|||
|
||||
static GpStatus create_path_gradient(GpPath *path, ARGB centercolor, GpPathGradient **grad)
|
||||
{
|
||||
GpRectF bounds;
|
||||
INT i;
|
||||
REAL sum_x = 0, sum_y = 0;
|
||||
|
||||
if(!path || !grad)
|
||||
return InvalidParameter;
|
||||
|
@ -611,8 +633,6 @@ static GpStatus create_path_gradient(GpPath *path, ARGB centercolor, GpPathGradi
|
|||
if (path->pathdata.Count < 2)
|
||||
return OutOfMemory;
|
||||
|
||||
GdipGetPathWorldBounds(path, &bounds, NULL, NULL);
|
||||
|
||||
*grad = heap_alloc_zero(sizeof(GpPathGradient));
|
||||
if (!*grad)
|
||||
{
|
||||
|
@ -642,9 +662,14 @@ static GpStatus create_path_gradient(GpPath *path, ARGB centercolor, GpPathGradi
|
|||
(*grad)->centercolor = centercolor;
|
||||
(*grad)->wrap = WrapModeClamp;
|
||||
(*grad)->gamma = FALSE;
|
||||
/* FIXME: this should be set to the "centroid" of the path by default */
|
||||
(*grad)->center.X = bounds.X + bounds.Width / 2;
|
||||
(*grad)->center.Y = bounds.Y + bounds.Height / 2;
|
||||
for (i=0; i<path->pathdata.Count; i++)
|
||||
{
|
||||
sum_x += path->pathdata.Points[i].X;
|
||||
sum_y += path->pathdata.Points[i].Y;
|
||||
}
|
||||
(*grad)->center.X = sum_x / path->pathdata.Count;
|
||||
(*grad)->center.Y = sum_y / path->pathdata.Count;
|
||||
|
||||
(*grad)->focus.X = 0.0;
|
||||
(*grad)->focus.Y = 0.0;
|
||||
(*grad)->surroundcolors[0] = 0xffffffff;
|
||||
|
@ -756,7 +781,7 @@ GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
|
|||
*/
|
||||
GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf)
|
||||
{
|
||||
TRACE("(%x, %p)\n", color, sf);
|
||||
TRACE("(%lx, %p)\n", color, sf);
|
||||
|
||||
if(!sf) return InvalidParameter;
|
||||
|
||||
|
@ -1656,7 +1681,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientPresetBlendCount(GpPathGradient *brush,
|
|||
GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad,
|
||||
ARGB argb)
|
||||
{
|
||||
TRACE("(%p, %x)\n", grad, argb);
|
||||
TRACE("(%p, %lx)\n", grad, argb);
|
||||
|
||||
if(!grad || grad->brush.bt != BrushTypePathGradient)
|
||||
return InvalidParameter;
|
||||
|
@ -1924,7 +1949,7 @@ GpStatus WINGDIPAPI GdipTranslatePathGradientTransform(GpPathGradient *grad,
|
|||
|
||||
GpStatus WINGDIPAPI GdipSetSolidFillColor(GpSolidFill *sf, ARGB argb)
|
||||
{
|
||||
TRACE("(%p, %x)\n", sf, argb);
|
||||
TRACE("(%p, %lx)\n", sf, argb);
|
||||
|
||||
if(!sf)
|
||||
return InvalidParameter;
|
||||
|
@ -1969,7 +1994,7 @@ GpStatus WINGDIPAPI GdipSetTextureWrapMode(GpTexture *brush, GpWrapMode wrapmode
|
|||
GpStatus WINGDIPAPI GdipSetLineColors(GpLineGradient *brush, ARGB color1,
|
||||
ARGB color2)
|
||||
{
|
||||
TRACE("(%p, %x, %x)\n", brush, color1, color2);
|
||||
TRACE("(%p, %lx, %lx)\n", brush, color1, color2);
|
||||
|
||||
if(!brush || brush->brush.bt != BrushTypeLinearGradient)
|
||||
return InvalidParameter;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "winnls.h"
|
||||
#include "winreg.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL (gdiplus);
|
||||
|
||||
|
@ -107,7 +106,7 @@ typedef struct
|
|||
#define GET_BE_DWORD(x) (x)
|
||||
#else
|
||||
#define GET_BE_WORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
|
||||
#define GET_BE_DWORD(x) MAKELONG(GET_BE_WORD(HIWORD(x)), GET_BE_WORD(LOWORD(x)));
|
||||
#define GET_BE_DWORD(x) MAKELONG(GET_BE_WORD(HIWORD(x)), GET_BE_WORD(LOWORD(x)))
|
||||
#endif
|
||||
|
||||
#define MS_MAKE_TAG(ch0, ch1, ch2, ch3) \
|
||||
|
@ -116,10 +115,17 @@ typedef struct
|
|||
#define MS_OS2_TAG MS_MAKE_TAG('O','S','/','2')
|
||||
#define MS_HHEA_TAG MS_MAKE_TAG('h','h','e','a')
|
||||
|
||||
static GpStatus clone_font_family(const GpFontFamily *, GpFontFamily **);
|
||||
|
||||
static GpFontCollection installedFontCollection = {0};
|
||||
|
||||
static CRITICAL_SECTION font_cs;
|
||||
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
{
|
||||
0, 0, &font_cs,
|
||||
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": font_cs") }
|
||||
};
|
||||
static CRITICAL_SECTION font_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
/*******************************************************************************
|
||||
* GdipCreateFont [GDIPLUS.@]
|
||||
*
|
||||
|
@ -162,7 +168,7 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
|
|||
stat = GdipGetFamilyName(fontFamily, lfw.lfFaceName, LANG_NEUTRAL);
|
||||
if (stat != Ok) return stat;
|
||||
|
||||
lfw.lfHeight = -units_to_pixels(emSize, unit, fontFamily->dpi);
|
||||
lfw.lfHeight = -units_to_pixels(emSize, unit, fontFamily->dpi, FALSE);
|
||||
lfw.lfWeight = style & FontStyleBold ? FW_BOLD : FW_REGULAR;
|
||||
lfw.lfItalic = style & FontStyleItalic;
|
||||
lfw.lfUnderline = style & FontStyleUnderline;
|
||||
|
@ -184,13 +190,7 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
|
|||
(*font)->unit = unit;
|
||||
(*font)->emSize = emSize;
|
||||
(*font)->otm = otm;
|
||||
|
||||
stat = clone_font_family(fontFamily, &(*font)->family);
|
||||
if (stat != Ok)
|
||||
{
|
||||
heap_free(*font);
|
||||
return stat;
|
||||
}
|
||||
GdipCloneFontFamily((GpFontFamily*)fontFamily, &(*font)->family);
|
||||
|
||||
TRACE("<-- %p\n", *font);
|
||||
|
||||
|
@ -228,7 +228,7 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
|
|||
if (!*font) return OutOfMemory;
|
||||
|
||||
(*font)->unit = UnitWorld;
|
||||
(*font)->emSize = otm.otmTextMetrics.tmAscent;
|
||||
(*font)->emSize = otm.otmTextMetrics.tmHeight - otm.otmTextMetrics.tmInternalLeading;
|
||||
(*font)->otm = otm;
|
||||
|
||||
stat = GdipCreateFontFamilyFromName(facename, NULL, &(*font)->family);
|
||||
|
@ -354,7 +354,7 @@ GpStatus WINGDIPAPI GdipGetFontSize(GpFont *font, REAL *size)
|
|||
if (!(font && size)) return InvalidParameter;
|
||||
|
||||
*size = get_font_size(font);
|
||||
TRACE("%s,%d => %f\n", debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *size);
|
||||
TRACE("%s,%ld => %f\n", debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *size);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -398,7 +398,7 @@ GpStatus WINGDIPAPI GdipGetFontStyle(GpFont *font, INT *style)
|
|||
return InvalidParameter;
|
||||
|
||||
*style = get_font_style(font);
|
||||
TRACE("%s,%d => %d\n", debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *style);
|
||||
TRACE("%s,%ld => %d\n", debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *style);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -421,7 +421,7 @@ GpStatus WINGDIPAPI GdipGetFontUnit(GpFont *font, Unit *unit)
|
|||
if (!(font && unit)) return InvalidParameter;
|
||||
|
||||
*unit = font->unit;
|
||||
TRACE("%s,%d => %d\n", debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *unit);
|
||||
TRACE("%s,%ld => %d\n", debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *unit);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -467,16 +467,16 @@ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics, LOGFONTW
|
|||
|
||||
if (font->unit == UnitPixel || font->unit == UnitWorld)
|
||||
{
|
||||
height = units_to_pixels(font->emSize, graphics->unit, graphics->yres);
|
||||
height = units_to_pixels(font->emSize, graphics->unit, graphics->yres, graphics->printer_display);
|
||||
if (graphics->unit != UnitDisplay)
|
||||
GdipScaleMatrix(&matrix, graphics->scale, graphics->scale, MatrixOrderAppend);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (graphics->unit == UnitDisplay || graphics->unit == UnitPixel)
|
||||
height = units_to_pixels(font->emSize, font->unit, graphics->xres);
|
||||
height = units_to_pixels(font->emSize, font->unit, graphics->xres, graphics->printer_display);
|
||||
else
|
||||
height = units_to_pixels(font->emSize, font->unit, graphics->yres);
|
||||
height = units_to_pixels(font->emSize, font->unit, graphics->yres, graphics->printer_display);
|
||||
}
|
||||
|
||||
pt[0].X = 0.0;
|
||||
|
@ -507,9 +507,9 @@ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics, LOGFONTW
|
|||
lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
lf->lfQuality = DEFAULT_QUALITY;
|
||||
lf->lfPitchAndFamily = 0;
|
||||
strcpyW(lf->lfFaceName, font->family->FamilyName);
|
||||
lstrcpyW(lf->lfFaceName, font->family->FamilyName);
|
||||
|
||||
TRACE("=> %s,%d\n", debugstr_w(lf->lfFaceName), lf->lfHeight);
|
||||
TRACE("=> %s,%ld\n", debugstr_w(lf->lfFaceName), lf->lfHeight);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -519,8 +519,6 @@ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics, LOGFONTW
|
|||
*/
|
||||
GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont)
|
||||
{
|
||||
GpStatus stat;
|
||||
|
||||
TRACE("(%p, %p)\n", font, cloneFont);
|
||||
|
||||
if(!font || !cloneFont)
|
||||
|
@ -530,10 +528,7 @@ GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont)
|
|||
if(!*cloneFont) return OutOfMemory;
|
||||
|
||||
**cloneFont = *font;
|
||||
stat = GdipCloneFontFamily(font->family, &(*cloneFont)->family);
|
||||
if (stat != Ok) heap_free(*cloneFont);
|
||||
|
||||
return stat;
|
||||
return Ok;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -566,7 +561,7 @@ GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont *font,
|
|||
if (!graphics)
|
||||
{
|
||||
*height = font_height;
|
||||
TRACE("%s,%d => %f\n",
|
||||
TRACE("%s,%ld => %f\n",
|
||||
debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *height);
|
||||
return Ok;
|
||||
}
|
||||
|
@ -574,9 +569,9 @@ GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont *font,
|
|||
stat = GdipGetDpiY((GpGraphics *)graphics, &dpi);
|
||||
if (stat != Ok) return stat;
|
||||
|
||||
*height = pixels_to_units(font_height, graphics->unit, dpi);
|
||||
*height = pixels_to_units(font_height, graphics->unit, dpi, graphics->printer_display);
|
||||
|
||||
TRACE("%s,%d(unit %d) => %f\n",
|
||||
TRACE("%s,%ld(unit %d) => %f\n",
|
||||
debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, graphics->unit, *height);
|
||||
return Ok;
|
||||
}
|
||||
|
@ -608,7 +603,7 @@ GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi,
|
|||
TRACE("%p (%s), %f, %p\n", font,
|
||||
debugstr_w(font->family->FamilyName), dpi, height);
|
||||
|
||||
font_size = units_to_pixels(get_font_size(font), font->unit, dpi);
|
||||
font_size = units_to_pixels(get_font_size(font), font->unit, dpi, FALSE);
|
||||
style = get_font_style(font);
|
||||
stat = GdipGetLineSpacing(font->family, style, &line_spacing);
|
||||
if (stat != Ok) return stat;
|
||||
|
@ -617,7 +612,7 @@ GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi,
|
|||
|
||||
*height = (REAL)line_spacing * font_size / (REAL)em_height;
|
||||
|
||||
TRACE("%s,%d => %f\n",
|
||||
TRACE("%s,%ld => %f\n",
|
||||
debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *height);
|
||||
|
||||
return Ok;
|
||||
|
@ -700,29 +695,6 @@ static BOOL get_font_metrics(HDC hdc, struct font_metrics *fm)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static GpStatus find_installed_font(const WCHAR *name, struct font_metrics *fm)
|
||||
{
|
||||
LOGFONTW lf;
|
||||
HDC hdc = CreateCompatibleDC(0);
|
||||
GpStatus ret = FontFamilyNotFound;
|
||||
|
||||
if(!EnumFontFamiliesW(hdc, name, is_font_installed_proc, (LPARAM)&lf))
|
||||
{
|
||||
HFONT hfont, old_font;
|
||||
|
||||
strcpyW(fm->facename, lf.lfFaceName);
|
||||
|
||||
hfont = CreateFontIndirectW(&lf);
|
||||
old_font = SelectObject(hdc, hfont);
|
||||
ret = get_font_metrics(hdc, fm) ? Ok : NotTrueTypeFont;
|
||||
SelectObject(hdc, old_font);
|
||||
DeleteObject(hfont);
|
||||
}
|
||||
|
||||
DeleteDC(hdc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* GdipCreateFontFamilyFromName [GDIPLUS.@]
|
||||
*
|
||||
|
@ -744,48 +716,44 @@ static GpStatus find_installed_font(const WCHAR *name, struct font_metrics *fm)
|
|||
*/
|
||||
|
||||
GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
|
||||
GpFontCollection *fontCollection,
|
||||
GpFontFamily **FontFamily)
|
||||
GpFontCollection *collection,
|
||||
GpFontFamily **family)
|
||||
{
|
||||
GpStatus stat;
|
||||
GpFontFamily* ffamily;
|
||||
struct font_metrics fm;
|
||||
HDC hdc;
|
||||
LOGFONTW lf;
|
||||
GpStatus status;
|
||||
int i;
|
||||
|
||||
TRACE("%s, %p %p\n", debugstr_w(name), fontCollection, FontFamily);
|
||||
TRACE("%s, %p %p\n", debugstr_w(name), collection, family);
|
||||
|
||||
if (!(name && FontFamily))
|
||||
if (!name || !family)
|
||||
return InvalidParameter;
|
||||
if (fontCollection)
|
||||
FIXME("No support for FontCollections yet!\n");
|
||||
|
||||
stat = find_installed_font(name, &fm);
|
||||
if (stat != Ok) return stat;
|
||||
if (!collection)
|
||||
{
|
||||
status = GdipNewInstalledFontCollection(&collection);
|
||||
if (status != Ok) return status;
|
||||
}
|
||||
|
||||
ffamily = heap_alloc_zero(sizeof (GpFontFamily));
|
||||
if (!ffamily) return OutOfMemory;
|
||||
status = FontFamilyNotFound;
|
||||
|
||||
lstrcpyW(ffamily->FamilyName, fm.facename);
|
||||
ffamily->em_height = fm.em_height;
|
||||
ffamily->ascent = fm.ascent;
|
||||
ffamily->descent = fm.descent;
|
||||
ffamily->line_spacing = fm.line_spacing;
|
||||
ffamily->dpi = fm.dpi;
|
||||
hdc = CreateCompatibleDC(0);
|
||||
|
||||
*FontFamily = ffamily;
|
||||
if (!EnumFontFamiliesW(hdc, name, is_font_installed_proc, (LPARAM)&lf))
|
||||
{
|
||||
for (i = 0; i < collection->count; i++)
|
||||
{
|
||||
if (!wcsicmp(lf.lfFaceName, collection->FontFamilies[i]->FamilyName))
|
||||
{
|
||||
status = GdipCloneFontFamily(collection->FontFamilies[i], family);
|
||||
TRACE("<-- %p\n", *family);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("<-- %p\n", ffamily);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
static GpStatus clone_font_family(const GpFontFamily *family, GpFontFamily **clone)
|
||||
{
|
||||
*clone = heap_alloc_zero(sizeof(GpFontFamily));
|
||||
if (!*clone) return OutOfMemory;
|
||||
|
||||
**clone = *family;
|
||||
|
||||
return Ok;
|
||||
DeleteDC(hdc);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -800,19 +768,17 @@ static GpStatus clone_font_family(const GpFontFamily *family, GpFontFamily **clo
|
|||
* RETURNS
|
||||
* SUCCESS: Ok
|
||||
*/
|
||||
GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily* FontFamily, GpFontFamily** clonedFontFamily)
|
||||
GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily *family, GpFontFamily **clone)
|
||||
{
|
||||
GpStatus status;
|
||||
if (!family || !clone)
|
||||
return InvalidParameter;
|
||||
|
||||
if (!(FontFamily && clonedFontFamily)) return InvalidParameter;
|
||||
TRACE("%p (%s), %p\n", family, debugstr_w(family->FamilyName), clone);
|
||||
|
||||
TRACE("%p (%s), %p\n", FontFamily,
|
||||
debugstr_w(FontFamily->FamilyName), clonedFontFamily);
|
||||
*clone = family;
|
||||
|
||||
status = clone_font_family(FontFamily, clonedFontFamily);
|
||||
if (status != Ok) return status;
|
||||
|
||||
TRACE("<-- %p\n", *clonedFontFamily);
|
||||
if (!family->installed)
|
||||
InterlockedIncrement(&family->ref);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -832,17 +798,20 @@ GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily* FontFamily, GpFontFamily**
|
|||
* FAILURE: InvalidParameter if family is NULL
|
||||
*
|
||||
* NOTES
|
||||
* If name is a NULL ptr, then both XP and Vista will crash (so we do as well)
|
||||
* If name is NULL, XP and Vista crash but not Windows 7+
|
||||
*/
|
||||
GpStatus WINGDIPAPI GdipGetFamilyName (GDIPCONST GpFontFamily *family,
|
||||
WCHAR *name, LANGID language)
|
||||
{
|
||||
static int lang_fixme;
|
||||
|
||||
TRACE("%p, %p, %d\n", family, name, language);
|
||||
|
||||
if (family == NULL)
|
||||
return InvalidParameter;
|
||||
|
||||
TRACE("%p, %p, %d\n", family, name, language);
|
||||
if (name == NULL)
|
||||
return Ok;
|
||||
|
||||
if (language != LANG_NEUTRAL && !lang_fixme++)
|
||||
FIXME("No support for handling of multiple languages!\n");
|
||||
|
@ -870,9 +839,11 @@ GpStatus WINGDIPAPI GdipDeleteFontFamily(GpFontFamily *FontFamily)
|
|||
{
|
||||
if (!FontFamily)
|
||||
return InvalidParameter;
|
||||
TRACE("Deleting %p (%s)\n", FontFamily, debugstr_w(FontFamily->FamilyName));
|
||||
|
||||
heap_free (FontFamily);
|
||||
if (!FontFamily->installed && !InterlockedDecrement(&FontFamily->ref))
|
||||
{
|
||||
heap_free(FontFamily);
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -1009,16 +980,14 @@ GpStatus WINGDIPAPI GdipIsStyleAvailable(GDIPCONST GpFontFamily* family,
|
|||
*/
|
||||
GpStatus WINGDIPAPI GdipGetGenericFontFamilyMonospace(GpFontFamily **nativeFamily)
|
||||
{
|
||||
static const WCHAR CourierNew[] = {'C','o','u','r','i','e','r',' ','N','e','w','\0'};
|
||||
static const WCHAR LiberationMono[] = {'L','i','b','e','r','a','t','i','o','n',' ','M','o','n','o','\0'};
|
||||
GpStatus stat;
|
||||
|
||||
if (nativeFamily == NULL) return InvalidParameter;
|
||||
|
||||
stat = GdipCreateFontFamilyFromName(CourierNew, NULL, nativeFamily);
|
||||
stat = GdipCreateFontFamilyFromName(L"Courier New", NULL, nativeFamily);
|
||||
|
||||
if (stat == FontFamilyNotFound)
|
||||
stat = GdipCreateFontFamilyFromName(LiberationMono, NULL, nativeFamily);
|
||||
stat = GdipCreateFontFamilyFromName(L"Liberation Mono", NULL, nativeFamily);
|
||||
|
||||
if (stat == FontFamilyNotFound)
|
||||
ERR("Missing 'Courier New' font\n");
|
||||
|
@ -1040,18 +1009,16 @@ GpStatus WINGDIPAPI GdipGetGenericFontFamilyMonospace(GpFontFamily **nativeFamil
|
|||
*/
|
||||
GpStatus WINGDIPAPI GdipGetGenericFontFamilySerif(GpFontFamily **nativeFamily)
|
||||
{
|
||||
static const WCHAR TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
|
||||
static const WCHAR LiberationSerif[] = {'L','i','b','e','r','a','t','i','o','n',' ','S','e','r','i','f','\0'};
|
||||
GpStatus stat;
|
||||
|
||||
TRACE("(%p)\n", nativeFamily);
|
||||
|
||||
if (nativeFamily == NULL) return InvalidParameter;
|
||||
|
||||
stat = GdipCreateFontFamilyFromName(TimesNewRoman, NULL, nativeFamily);
|
||||
stat = GdipCreateFontFamilyFromName(L"Times New Roman", NULL, nativeFamily);
|
||||
|
||||
if (stat == FontFamilyNotFound)
|
||||
stat = GdipCreateFontFamilyFromName(LiberationSerif, NULL, nativeFamily);
|
||||
stat = GdipCreateFontFamilyFromName(L"Liberation Serif", NULL, nativeFamily);
|
||||
|
||||
if (stat == FontFamilyNotFound)
|
||||
ERR("Missing 'Times New Roman' font\n");
|
||||
|
@ -1074,24 +1041,22 @@ GpStatus WINGDIPAPI GdipGetGenericFontFamilySerif(GpFontFamily **nativeFamily)
|
|||
GpStatus WINGDIPAPI GdipGetGenericFontFamilySansSerif(GpFontFamily **nativeFamily)
|
||||
{
|
||||
GpStatus stat;
|
||||
static const WCHAR MicrosoftSansSerif[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
|
||||
static const WCHAR Tahoma[] = {'T','a','h','o','m','a','\0'};
|
||||
|
||||
TRACE("(%p)\n", nativeFamily);
|
||||
|
||||
if (nativeFamily == NULL) return InvalidParameter;
|
||||
|
||||
stat = GdipCreateFontFamilyFromName(MicrosoftSansSerif, NULL, nativeFamily);
|
||||
stat = GdipCreateFontFamilyFromName(L"Microsoft Sans Serif", NULL, nativeFamily);
|
||||
|
||||
if (stat == FontFamilyNotFound)
|
||||
/* FIXME: Microsoft Sans Serif is not installed on Wine. */
|
||||
stat = GdipCreateFontFamilyFromName(Tahoma, NULL, nativeFamily);
|
||||
stat = GdipCreateFontFamilyFromName(L"Tahoma", NULL, nativeFamily);
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* GdipGetGenericFontFamilySansSerif [GDIPLUS.@]
|
||||
* GdipNewPrivateFontCollection [GDIPLUS.@]
|
||||
*/
|
||||
GpStatus WINGDIPAPI GdipNewPrivateFontCollection(GpFontCollection** fontCollection)
|
||||
{
|
||||
|
@ -1124,7 +1089,7 @@ GpStatus WINGDIPAPI GdipDeletePrivateFontCollection(GpFontCollection **fontColle
|
|||
if (!fontCollection)
|
||||
return InvalidParameter;
|
||||
|
||||
for (i = 0; i < (*fontCollection)->count; i++) heap_free((*fontCollection)->FontFamilies[i]);
|
||||
for (i = 0; i < (*fontCollection)->count; i++) GdipDeleteFontFamily((*fontCollection)->FontFamilies[i]);
|
||||
heap_free((*fontCollection)->FontFamilies);
|
||||
heap_free(*fontCollection);
|
||||
|
||||
|
@ -1185,14 +1150,16 @@ GpStatus WINGDIPAPI GdipPrivateAddFontFile(GpFontCollection *collection, GDIPCON
|
|||
#define NAME_ID_FULL_FONT_NAME 4
|
||||
|
||||
typedef struct {
|
||||
USHORT major_version;
|
||||
USHORT minor_version;
|
||||
ULONG version;
|
||||
USHORT tables_no;
|
||||
USHORT search_range;
|
||||
USHORT entry_selector;
|
||||
USHORT range_shift;
|
||||
} tt_header;
|
||||
|
||||
#define TT_HEADER_VERSION_1 0x00010000
|
||||
#define TT_HEADER_VERSION_CFF 0x4f54544f
|
||||
|
||||
typedef struct {
|
||||
char tag[4]; /* table name */
|
||||
ULONG check_sum; /* Check sum */
|
||||
|
@ -1437,7 +1404,8 @@ static WCHAR *load_ttf_name_id( const BYTE *mem, DWORD_PTR size, DWORD id )
|
|||
header = (const tt_header*)mem;
|
||||
count = GET_BE_WORD(header->tables_no);
|
||||
|
||||
if (GET_BE_WORD(header->major_version) != 1 || GET_BE_WORD(header->minor_version) != 0)
|
||||
if (GET_BE_DWORD(header->version) != TT_HEADER_VERSION_1 &&
|
||||
GET_BE_DWORD(header->version) != TT_HEADER_VERSION_CFF)
|
||||
return NULL;
|
||||
|
||||
pos = sizeof(*header);
|
||||
|
@ -1499,6 +1467,7 @@ struct add_font_param
|
|||
GpFontCollection *collection;
|
||||
BOOL is_system;
|
||||
GpStatus stat;
|
||||
HDC hdc;
|
||||
};
|
||||
|
||||
static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm, DWORD type, LPARAM lParam);
|
||||
|
@ -1523,16 +1492,15 @@ GpStatus WINGDIPAPI GdipPrivateAddMemoryFont(GpFontCollection* fontCollection,
|
|||
return OutOfMemory;
|
||||
|
||||
font = AddFontMemResourceEx((void*)memory, length, NULL, &count);
|
||||
TRACE("%s: %p/%u\n", debugstr_w(name), font, count);
|
||||
TRACE("%s: %p/%lu\n", debugstr_w(name), font, count);
|
||||
if (!font || !count)
|
||||
ret = InvalidParameter;
|
||||
else
|
||||
{
|
||||
struct add_font_param param;
|
||||
HDC hdc;
|
||||
LOGFONTW lfw;
|
||||
|
||||
hdc = CreateCompatibleDC(0);
|
||||
param.hdc = CreateCompatibleDC(0);
|
||||
|
||||
/* Truncate name if necessary, GDI32 can't deal with long names */
|
||||
if(lstrlenW(name) > LF_FACESIZE - 1)
|
||||
|
@ -1544,10 +1512,10 @@ GpStatus WINGDIPAPI GdipPrivateAddMemoryFont(GpFontCollection* fontCollection,
|
|||
|
||||
param.collection = fontCollection;
|
||||
param.is_system = FALSE;
|
||||
if (!EnumFontFamiliesExW(hdc, &lfw, add_font_proc, (LPARAM)¶m, 0))
|
||||
if (!EnumFontFamiliesExW(param.hdc, &lfw, add_font_proc, (LPARAM)¶m, 0))
|
||||
ret = param.stat;
|
||||
|
||||
DeleteDC(hdc);
|
||||
DeleteDC(param.hdc);
|
||||
}
|
||||
heap_free(name);
|
||||
return ret;
|
||||
|
@ -1576,7 +1544,6 @@ GpStatus WINGDIPAPI GdipGetFontCollectionFamilyList(
|
|||
GpFontFamily* gpfamilies[], INT* numFound)
|
||||
{
|
||||
INT i;
|
||||
GpStatus stat=Ok;
|
||||
|
||||
TRACE("%p, %d, %p, %p\n", fontCollection, numSought, gpfamilies, numFound);
|
||||
|
||||
|
@ -1585,31 +1552,25 @@ GpStatus WINGDIPAPI GdipGetFontCollectionFamilyList(
|
|||
|
||||
memset(gpfamilies, 0, sizeof(*gpfamilies) * numSought);
|
||||
|
||||
for (i = 0; i < numSought && i < fontCollection->count && stat == Ok; i++)
|
||||
for (i = 0; i < numSought && i < fontCollection->count; i++)
|
||||
{
|
||||
stat = GdipCloneFontFamily(fontCollection->FontFamilies[i], &gpfamilies[i]);
|
||||
/* caller is responsible for cloning these if it keeps references */
|
||||
gpfamilies[i] = fontCollection->FontFamilies[i];
|
||||
}
|
||||
|
||||
if (stat == Ok)
|
||||
*numFound = i;
|
||||
else
|
||||
{
|
||||
int numToFree=i;
|
||||
for (i=0; i<numToFree; i++)
|
||||
{
|
||||
GdipDeleteFontFamily(gpfamilies[i]);
|
||||
gpfamilies[i] = NULL;
|
||||
}
|
||||
}
|
||||
*numFound = i;
|
||||
|
||||
return stat;
|
||||
return Ok;
|
||||
}
|
||||
|
||||
void free_installed_fonts(void)
|
||||
{
|
||||
while (installedFontCollection.count)
|
||||
GdipDeleteFontFamily(installedFontCollection.FontFamilies[--installedFontCollection.count]);
|
||||
INT i;
|
||||
|
||||
for (i = 0; i < installedFontCollection.count; i++)
|
||||
heap_free(installedFontCollection.FontFamilies[i]);
|
||||
heap_free(installedFontCollection.FontFamilies);
|
||||
|
||||
installedFontCollection.FontFamilies = NULL;
|
||||
installedFontCollection.allocated = 0;
|
||||
}
|
||||
|
@ -1619,8 +1580,9 @@ static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm,
|
|||
{
|
||||
struct add_font_param *param = (struct add_font_param *)lParam;
|
||||
GpFontCollection *fonts = param->collection;
|
||||
GpFontFamily* family;
|
||||
GpStatus stat;
|
||||
GpFontFamily *family;
|
||||
HFONT hfont, old_hfont;
|
||||
struct font_metrics fm;
|
||||
int i;
|
||||
|
||||
param->stat = Ok;
|
||||
|
@ -1632,7 +1594,7 @@ static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm,
|
|||
if (lfw->lfFaceName[0] == '@')
|
||||
return 1;
|
||||
|
||||
if (fonts->count && strcmpiW(lfw->lfFaceName, fonts->FontFamilies[fonts->count-1]->FamilyName) == 0)
|
||||
if (fonts->count && wcsicmp(lfw->lfFaceName, fonts->FontFamilies[fonts->count-1]->FamilyName) == 0)
|
||||
return 1;
|
||||
|
||||
if (fonts->allocated == fonts->count)
|
||||
|
@ -1652,25 +1614,52 @@ static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm,
|
|||
fonts->allocated = new_alloc_count;
|
||||
}
|
||||
|
||||
if ((stat = GdipCreateFontFamilyFromName(lfw->lfFaceName, NULL, &family)) != Ok)
|
||||
family = heap_alloc(sizeof(*family));
|
||||
if (!family)
|
||||
{
|
||||
WARN("Failed to create font family for %s, status %d.\n", debugstr_w(lfw->lfFaceName), stat);
|
||||
if (param->is_system)
|
||||
return 1;
|
||||
param->stat = stat;
|
||||
|
||||
param->stat = OutOfMemory;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* skip duplicates */
|
||||
for (i=0; i<fonts->count; i++)
|
||||
{
|
||||
if (strcmpiW(family->FamilyName, fonts->FontFamilies[i]->FamilyName) == 0)
|
||||
if (wcsicmp(lfw->lfFaceName, fonts->FontFamilies[i]->FamilyName) == 0)
|
||||
{
|
||||
GdipDeleteFontFamily(family);
|
||||
heap_free(family);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
hfont = CreateFontIndirectW(lfw);
|
||||
old_hfont = SelectObject(param->hdc, hfont);
|
||||
|
||||
if (!get_font_metrics(param->hdc, &fm))
|
||||
{
|
||||
SelectObject(param->hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
|
||||
heap_free(family);
|
||||
param->stat = OutOfMemory;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SelectObject(param->hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
|
||||
family->em_height = fm.em_height;
|
||||
family->ascent = fm.ascent;
|
||||
family->descent = fm.descent;
|
||||
family->line_spacing = fm.line_spacing;
|
||||
family->dpi = fm.dpi;
|
||||
family->installed = param->is_system;
|
||||
family->ref = 1;
|
||||
|
||||
lstrcpyW(family->FamilyName, lfw->lfFaceName);
|
||||
|
||||
fonts->FontFamilies[fonts->count++] = family;
|
||||
|
||||
return 1;
|
||||
|
@ -1684,13 +1673,13 @@ GpStatus WINGDIPAPI GdipNewInstalledFontCollection(
|
|||
if (!fontCollection)
|
||||
return InvalidParameter;
|
||||
|
||||
EnterCriticalSection( &font_cs );
|
||||
if (installedFontCollection.count == 0)
|
||||
{
|
||||
struct add_font_param param;
|
||||
HDC hdc;
|
||||
LOGFONTW lfw;
|
||||
|
||||
hdc = CreateCompatibleDC(0);
|
||||
param.hdc = CreateCompatibleDC(0);
|
||||
|
||||
lfw.lfCharSet = DEFAULT_CHARSET;
|
||||
lfw.lfFaceName[0] = 0;
|
||||
|
@ -1698,15 +1687,17 @@ GpStatus WINGDIPAPI GdipNewInstalledFontCollection(
|
|||
|
||||
param.collection = &installedFontCollection;
|
||||
param.is_system = TRUE;
|
||||
if (!EnumFontFamiliesExW(hdc, &lfw, add_font_proc, (LPARAM)¶m, 0))
|
||||
if (!EnumFontFamiliesExW(param.hdc, &lfw, add_font_proc, (LPARAM)¶m, 0))
|
||||
{
|
||||
free_installed_fonts();
|
||||
DeleteDC(hdc);
|
||||
DeleteDC(param.hdc);
|
||||
LeaveCriticalSection( &font_cs );
|
||||
return param.stat;
|
||||
}
|
||||
|
||||
DeleteDC(hdc);
|
||||
DeleteDC(param.hdc);
|
||||
}
|
||||
LeaveCriticalSection( &font_cs );
|
||||
|
||||
*fontCollection = &installedFontCollection;
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ static Status WINAPI NotificationHook(ULONG_PTR *token)
|
|||
|
||||
static void WINAPI NotificationUnhook(ULONG_PTR token)
|
||||
{
|
||||
TRACE("%ld\n", token);
|
||||
TRACE("%Id\n", token);
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
|
@ -57,7 +57,7 @@ static void WINAPI NotificationUnhook(ULONG_PTR token)
|
|||
*/
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
|
||||
{
|
||||
TRACE("(%p, %d, %p)\n", hinst, reason, reserved);
|
||||
TRACE("(%p, %ld, %p)\n", hinst, reason, reserved);
|
||||
|
||||
switch(reason)
|
||||
{
|
||||
|
@ -115,7 +115,7 @@ GpStatus WINAPI GdiplusNotificationHook(ULONG_PTR *token)
|
|||
|
||||
void WINAPI GdiplusNotificationUnhook(ULONG_PTR token)
|
||||
{
|
||||
FIXME("%ld\n", token);
|
||||
FIXME("%Id\n", token);
|
||||
NotificationUnhook(token);
|
||||
}
|
||||
|
||||
|
@ -202,54 +202,54 @@ static void add_arc_part(GpPointF * pt, REAL x1, REAL y1, REAL x2, REAL y2,
|
|||
* adjusts the angles so that when we stretch the points they will end in the
|
||||
* right place. This is only complicated because atan and atan2 do not behave
|
||||
* conveniently. */
|
||||
static void unstretch_angle(REAL * angle, REAL rad_x, REAL rad_y)
|
||||
static REAL unstretch_angle(REAL angle, REAL dia_x, REAL dia_y)
|
||||
{
|
||||
REAL stretched;
|
||||
INT revs_off;
|
||||
|
||||
*angle = deg2rad(*angle);
|
||||
if(fabs(cos(angle)) < 0.00001 || fabs(sin(angle)) < 0.00001)
|
||||
return angle;
|
||||
|
||||
if(fabs(cos(*angle)) < 0.00001 || fabs(sin(*angle)) < 0.00001)
|
||||
return;
|
||||
|
||||
stretched = gdiplus_atan2(sin(*angle) / fabs(rad_y), cos(*angle) / fabs(rad_x));
|
||||
revs_off = gdip_round(*angle / (2.0 * M_PI)) - gdip_round(stretched / (2.0 * M_PI));
|
||||
stretched = gdiplus_atan2(sin(angle) / fabs(dia_y), cos(angle) / fabs(dia_x));
|
||||
revs_off = gdip_round(angle / (2.0 * M_PI)) - gdip_round(stretched / (2.0 * M_PI));
|
||||
stretched += ((REAL)revs_off) * M_PI * 2.0;
|
||||
*angle = stretched;
|
||||
return stretched;
|
||||
}
|
||||
|
||||
/* Stores the bezier points that correspond to the arc in points. If points is
|
||||
* null, just return the number of points needed to represent the arc. */
|
||||
INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2,
|
||||
REAL startAngle, REAL sweepAngle)
|
||||
INT arc2polybezier(GpPointF * points, REAL left, REAL top, REAL width, REAL height,
|
||||
REAL start_angle, REAL sweep_angle)
|
||||
{
|
||||
INT i;
|
||||
REAL end_angle, start_angle, endAngle;
|
||||
REAL partial_end_angle, end_angle;
|
||||
|
||||
endAngle = startAngle + sweepAngle;
|
||||
unstretch_angle(&startAngle, x2 / 2.0, y2 / 2.0);
|
||||
unstretch_angle(&endAngle, x2 / 2.0, y2 / 2.0);
|
||||
end_angle = deg2rad(start_angle + sweep_angle);
|
||||
start_angle = deg2rad(start_angle);
|
||||
|
||||
/* start_angle and end_angle are the iterative variables */
|
||||
start_angle = startAngle;
|
||||
if (width != height)
|
||||
{
|
||||
start_angle = unstretch_angle(start_angle, width, height);
|
||||
end_angle = unstretch_angle(end_angle, width, height);
|
||||
}
|
||||
|
||||
for(i = 0; i < MAX_ARC_PTS - 1; i += 3){
|
||||
/* check if we've overshot the end angle */
|
||||
if( sweepAngle > 0.0 )
|
||||
if( sweep_angle > 0.0 )
|
||||
{
|
||||
if (start_angle >= endAngle) break;
|
||||
end_angle = min(start_angle + M_PI_2, endAngle);
|
||||
if (start_angle >= end_angle) break;
|
||||
partial_end_angle = min(start_angle + M_PI_2, end_angle);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (start_angle <= endAngle) break;
|
||||
end_angle = max(start_angle - M_PI_2, endAngle);
|
||||
if (start_angle <= end_angle) break;
|
||||
partial_end_angle = max(start_angle - M_PI_2, end_angle);
|
||||
}
|
||||
|
||||
if (points)
|
||||
add_arc_part(&points[i], x1, y1, x2, y2, start_angle, end_angle, i == 0);
|
||||
add_arc_part(&points[i], left, top, width, height, start_angle, partial_end_angle, i == 0);
|
||||
|
||||
start_angle += M_PI_2 * (sweepAngle < 0.0 ? -1.0 : 1.0);
|
||||
start_angle = partial_end_angle;
|
||||
}
|
||||
|
||||
if (i == 0) return 0;
|
||||
|
@ -324,14 +324,18 @@ GpStatus hresult_to_status(HRESULT res)
|
|||
}
|
||||
|
||||
/* converts a given unit to its value in pixels */
|
||||
REAL units_to_pixels(REAL units, GpUnit unit, REAL dpi)
|
||||
REAL units_to_pixels(REAL units, GpUnit unit, REAL dpi, BOOL printer_display)
|
||||
{
|
||||
switch (unit)
|
||||
{
|
||||
case UnitPixel:
|
||||
case UnitWorld:
|
||||
case UnitDisplay:
|
||||
return units;
|
||||
case UnitDisplay:
|
||||
if (printer_display)
|
||||
return units * dpi / 100.0;
|
||||
else
|
||||
return units;
|
||||
case UnitPoint:
|
||||
return units * dpi / point_per_inch;
|
||||
case UnitInch:
|
||||
|
@ -347,14 +351,18 @@ REAL units_to_pixels(REAL units, GpUnit unit, REAL dpi)
|
|||
}
|
||||
|
||||
/* converts value in pixels to a given unit */
|
||||
REAL pixels_to_units(REAL pixels, GpUnit unit, REAL dpi)
|
||||
REAL pixels_to_units(REAL pixels, GpUnit unit, REAL dpi, BOOL printer_display)
|
||||
{
|
||||
switch (unit)
|
||||
{
|
||||
case UnitPixel:
|
||||
case UnitWorld:
|
||||
case UnitDisplay:
|
||||
return pixels;
|
||||
case UnitDisplay:
|
||||
if (printer_display)
|
||||
return pixels * 100.0 / dpi;
|
||||
else
|
||||
return pixels;
|
||||
case UnitPoint:
|
||||
return pixels * point_per_inch / dpi;
|
||||
case UnitInch:
|
||||
|
@ -369,10 +377,10 @@ REAL pixels_to_units(REAL pixels, GpUnit unit, REAL dpi)
|
|||
}
|
||||
}
|
||||
|
||||
REAL units_scale(GpUnit from, GpUnit to, REAL dpi)
|
||||
REAL units_scale(GpUnit from, GpUnit to, REAL dpi, BOOL printer_display)
|
||||
{
|
||||
REAL pixels = units_to_pixels(1.0, from, dpi);
|
||||
return pixels_to_units(pixels, to, dpi);
|
||||
REAL pixels = units_to_pixels(1.0, from, dpi, printer_display);
|
||||
return pixels_to_units(pixels, to, dpi, printer_display);
|
||||
}
|
||||
|
||||
/* Calculates Bezier points from cardinal spline points. */
|
||||
|
|
|
@ -18,6 +18,15 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define WINE_FILEDESCRIPTION_STR "Wine gdiplus"
|
||||
#define WINE_FILENAME_STR "gdiplus.dll"
|
||||
#define WINE_FILEVERSION 6,1,7601,17514
|
||||
#define WINE_FILEVERSION_STR "6.1.7601.17514"
|
||||
#define WINE_PRODUCTVERSION 6,1,7601,17514
|
||||
#define WINE_PRODUCTVERSION_STR "6.1.7601.17514"
|
||||
|
||||
#include "wine/wine_common_ver.rc"
|
||||
|
||||
/* @makedep: gdiplus.manifest */
|
||||
WINE_MANIFEST 24 gdiplus.manifest
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
100 stdcall GdipCreateMatrix3I(ptr ptr ptr)
|
||||
101 stdcall GdipCreateMatrix(ptr)
|
||||
102 stdcall GdipCreateMetafileFromEmf(ptr long ptr)
|
||||
103 stdcall GdipCreateMetafileFromFile(ptr ptr)
|
||||
103 stdcall GdipCreateMetafileFromFile(wstr ptr)
|
||||
104 stdcall GdipCreateMetafileFromStream(ptr ptr)
|
||||
105 stdcall GdipCreateMetafileFromWmf(ptr long ptr ptr)
|
||||
106 stdcall GdipCreateMetafileFromWmfFile(wstr ptr ptr)
|
||||
|
@ -200,8 +200,8 @@
|
|||
200 stub GdipEnumerateMetafileSrcRectDestPointI
|
||||
201 stdcall GdipEnumerateMetafileSrcRectDestPoints(ptr ptr ptr long ptr long ptr ptr ptr)
|
||||
202 stub GdipEnumerateMetafileSrcRectDestPointsI
|
||||
203 stub GdipEnumerateMetafileSrcRectDestRect
|
||||
204 stub GdipEnumerateMetafileSrcRectDestRectI
|
||||
203 stdcall GdipEnumerateMetafileSrcRectDestRect(ptr ptr ptr ptr long ptr ptr ptr)
|
||||
204 stdcall GdipEnumerateMetafileSrcRectDestRectI(ptr ptr ptr ptr long ptr ptr ptr)
|
||||
205 stdcall GdipFillClosedCurve2(ptr ptr ptr long float long)
|
||||
206 stdcall GdipFillClosedCurve2I(ptr ptr ptr long float long)
|
||||
207 stdcall GdipFillClosedCurve(ptr ptr ptr long)
|
||||
|
@ -298,7 +298,7 @@
|
|||
298 stdcall GdipGetLogFontA(ptr ptr ptr)
|
||||
299 stdcall GdipGetLogFontW(ptr ptr ptr)
|
||||
300 stdcall GdipGetMatrixElements(ptr ptr)
|
||||
301 stub GdipGetMetafileDownLevelRasterizationLimit
|
||||
301 stdcall GdipGetMetafileDownLevelRasterizationLimit(ptr ptr)
|
||||
302 stdcall GdipGetMetafileHeaderFromEmf(ptr ptr)
|
||||
303 stdcall GdipGetMetafileHeaderFromFile(wstr ptr)
|
||||
304 stdcall GdipGetMetafileHeaderFromMetafile(ptr ptr)
|
||||
|
@ -451,7 +451,7 @@
|
|||
451 stdcall GdipRecordMetafileFileNameI(wstr long long ptr long wstr ptr)
|
||||
452 stdcall GdipRecordMetafileI(long long ptr long wstr ptr)
|
||||
453 stdcall GdipRecordMetafileStream(ptr long long ptr long wstr ptr)
|
||||
454 stub GdipRecordMetafileStreamI
|
||||
454 stdcall GdipRecordMetafileStreamI(ptr long long ptr long wstr ptr)
|
||||
455 stdcall GdipReleaseDC(ptr ptr)
|
||||
456 stdcall GdipRemovePropertyItem(ptr long)
|
||||
457 stdcall GdipResetClip(ptr)
|
||||
|
@ -472,7 +472,7 @@
|
|||
472 stdcall GdipRotateTextureTransform(ptr float long)
|
||||
473 stdcall GdipRotateWorldTransform(ptr float long)
|
||||
474 stdcall GdipSaveAdd(ptr ptr)
|
||||
475 stub GdipSaveAddImage
|
||||
475 stdcall GdipSaveAddImage(ptr ptr ptr)
|
||||
476 stdcall GdipSaveGraphics(ptr ptr)
|
||||
477 stdcall GdipSaveImageToFile(ptr wstr ptr ptr)
|
||||
478 stdcall GdipSaveImageToStream(ptr ptr ptr ptr)
|
||||
|
@ -506,7 +506,7 @@
|
|||
506 stdcall GdipSetImageAttributesGamma(ptr long long float)
|
||||
507 stdcall GdipSetImageAttributesNoOp(ptr long long)
|
||||
508 stdcall GdipSetImageAttributesOutputChannel(ptr long long long)
|
||||
509 stdcall GdipSetImageAttributesOutputChannelColorProfile(ptr long long ptr)
|
||||
509 stdcall GdipSetImageAttributesOutputChannelColorProfile(ptr long long wstr)
|
||||
510 stdcall GdipSetImageAttributesRemapTable(ptr long long long ptr)
|
||||
511 stdcall GdipSetImageAttributesThreshold(ptr long long float)
|
||||
512 stdcall GdipSetImageAttributesToIdentity(ptr long)
|
||||
|
@ -624,7 +624,7 @@
|
|||
624 stdcall GdipImageSetAbort(ptr ptr)
|
||||
625 stdcall GdipGraphicsSetAbort(ptr ptr)
|
||||
626 stub GdipDrawImageFX
|
||||
627 stdcall GdipConvertToEmfPlus(ptr ptr ptr long ptr ptr)
|
||||
628 stdcall GdipConvertToEmfPlusToFile(ptr ptr ptr ptr long ptr ptr)
|
||||
627 stdcall GdipConvertToEmfPlus(ptr ptr ptr long wstr ptr)
|
||||
628 stdcall GdipConvertToEmfPlusToFile(ptr ptr ptr wstr long wstr ptr)
|
||||
629 stub GdipConvertToEmfPlusToStream
|
||||
630 stub GdipPlayTSClientRecord
|
||||
|
|
|
@ -57,9 +57,9 @@ extern INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2,
|
|||
REAL startAngle, REAL sweepAngle) DECLSPEC_HIDDEN;
|
||||
extern REAL gdiplus_atan2(REAL dy, REAL dx) DECLSPEC_HIDDEN;
|
||||
extern GpStatus hresult_to_status(HRESULT res) DECLSPEC_HIDDEN;
|
||||
extern REAL units_to_pixels(REAL units, GpUnit unit, REAL dpi) DECLSPEC_HIDDEN;
|
||||
extern REAL pixels_to_units(REAL pixels, GpUnit unit, REAL dpi) DECLSPEC_HIDDEN;
|
||||
extern REAL units_scale(GpUnit from, GpUnit to, REAL dpi) DECLSPEC_HIDDEN;
|
||||
extern REAL units_to_pixels(REAL units, GpUnit unit, REAL dpi, BOOL printer_display) DECLSPEC_HIDDEN;
|
||||
extern REAL pixels_to_units(REAL pixels, GpUnit unit, REAL dpi, BOOL printer_display) DECLSPEC_HIDDEN;
|
||||
extern REAL units_scale(GpUnit from, GpUnit to, REAL dpi, BOOL printer_display) DECLSPEC_HIDDEN;
|
||||
|
||||
#define WineCoordinateSpaceGdiDevice ((GpCoordinateSpace)4)
|
||||
|
||||
|
@ -72,6 +72,7 @@ extern GpStatus gdip_transform_points(GpGraphics *graphics, GpCoordinateSpace ds
|
|||
|
||||
extern GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) DECLSPEC_HIDDEN;
|
||||
extern GpStatus encode_image_png(GpImage *image, IStream* stream, GDIPCONST EncoderParameters* params) DECLSPEC_HIDDEN;
|
||||
extern GpStatus terminate_encoder_wic(GpImage *image) DECLSPEC_HIDDEN;
|
||||
|
||||
extern GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **result) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc) DECLSPEC_HIDDEN;
|
||||
|
@ -103,7 +104,23 @@ 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 GpStatus METAFILE_DrawDriverString(GpMetafile *metafile, GDIPCONST UINT16 *text, INT length,
|
||||
GDIPCONST GpFont *font, GDIPCONST GpStringFormat *format, GDIPCONST GpBrush *brush,
|
||||
GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_FillRegion(GpMetafile* metafile, GpBrush* brush,
|
||||
GpRegion* region) DECLSPEC_HIDDEN;
|
||||
extern void METAFILE_Free(GpMetafile *metafile) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_DrawEllipse(GpMetafile *metafile, GpPen *pen, GpRectF *rect) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_FillEllipse(GpMetafile *metafile, GpBrush *brush, GpRectF *rect) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_DrawRectangles(GpMetafile *metafile, GpPen *pen, const GpRectF *rects, INT count) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_FillPie(GpMetafile *metafile, GpBrush *brush, const GpRectF *rect,
|
||||
REAL startAngle, REAL sweepAngle) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_DrawArc(GpMetafile *metafile, GpPen *pen, const GpRectF *rect,
|
||||
REAL startAngle, REAL sweepAngle) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_OffsetClip(GpMetafile *metafile, REAL dx, REAL dy) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_ResetClip(GpMetafile *metafile) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_SetClipPath(GpMetafile *metafile, GpPath *path, CombineMode mode) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_SetRenderingOrigin(GpMetafile *metafile, INT x, INT y) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void calc_curve_bezier(const GpPointF *pts, REAL tension, REAL *x1,
|
||||
REAL *y1, REAL *x2, REAL *y2) DECLSPEC_HIDDEN;
|
||||
|
@ -122,7 +139,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(GpHatchStyle hatchstyle, const char **result) DECLSPEC_HIDDEN;
|
||||
extern GpStatus get_hatch_data(GpHatchStyle hatchstyle, const unsigned char **result) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline INT gdip_round(REAL x)
|
||||
{
|
||||
|
@ -190,8 +207,8 @@ extern void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height,
|
|||
BYTE *dst_bits, INT dst_stride, const BYTE *src_bits, INT src_stride) DECLSPEC_HIDDEN;
|
||||
|
||||
extern GpStatus convert_pixels(INT width, INT height,
|
||||
INT dst_stride, BYTE *dst_bits, PixelFormat dst_format,
|
||||
INT src_stride, const BYTE *src_bits, PixelFormat src_format, ColorPalette *palette) DECLSPEC_HIDDEN;
|
||||
INT dst_stride, BYTE *dst_bits, PixelFormat dst_format, ColorPalette *dst_palette,
|
||||
INT src_stride, const BYTE *src_bits, PixelFormat src_format, ColorPalette *src_palette) DECLSPEC_HIDDEN;
|
||||
|
||||
extern PixelFormat apply_image_attributes(const GpImageAttributes *attributes, LPBYTE data,
|
||||
UINT width, UINT height, INT stride, ColorAdjustType type, PixelFormat fmt) DECLSPEC_HIDDEN;
|
||||
|
@ -225,6 +242,7 @@ struct GpGraphics{
|
|||
HWND hwnd;
|
||||
BOOL owndc;
|
||||
BOOL alpha_hdc;
|
||||
BOOL printer_display;
|
||||
GpImage *image;
|
||||
ImageType image_type;
|
||||
SmoothingMode smoothing;
|
||||
|
@ -346,6 +364,7 @@ struct GpAdjustableArrowCap{
|
|||
|
||||
struct GpImage{
|
||||
IWICBitmapDecoder *decoder;
|
||||
IWICBitmapEncoder *encoder;
|
||||
ImageType type;
|
||||
GUID format;
|
||||
UINT flags;
|
||||
|
@ -405,6 +424,10 @@ struct GpMetafile{
|
|||
BOOL auto_frame; /* If true, determine the frame automatically */
|
||||
GpPointF auto_frame_min, auto_frame_max;
|
||||
DWORD next_object_id;
|
||||
UINT limit_dpi;
|
||||
BOOL printer_display;
|
||||
REAL logical_dpix;
|
||||
REAL logical_dpiy;
|
||||
|
||||
/* playback */
|
||||
GpGraphics *playback_graphics;
|
||||
|
@ -413,7 +436,6 @@ struct GpMetafile{
|
|||
GpRectF src_rect;
|
||||
HANDLETABLE *handle_table;
|
||||
int handle_count;
|
||||
XFORM gdiworldtransform;
|
||||
GpMatrix *world_transform;
|
||||
GpUnit page_unit;
|
||||
REAL page_scale;
|
||||
|
@ -521,6 +543,8 @@ struct GpFontFamily{
|
|||
WCHAR FamilyName[LF_FACESIZE];
|
||||
UINT16 em_height, ascent, descent, line_spacing; /* in font units */
|
||||
int dpi;
|
||||
BOOL installed;
|
||||
LONG ref;
|
||||
};
|
||||
|
||||
/* internal use */
|
||||
|
@ -602,4 +626,12 @@ static inline void image_unlock(GpImage *image, BOOL unlock)
|
|||
if (unlock) image->busy = 0;
|
||||
}
|
||||
|
||||
static inline void set_rect(GpRectF *rect, REAL x, REAL y, REAL width, REAL height)
|
||||
{
|
||||
rect->X = x;
|
||||
rect->Y = y;
|
||||
rect->Width = width;
|
||||
rect->Height = height;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -166,6 +166,52 @@ static BOOL flatten_bezier(path_list_node_t *start, REAL x2, REAL y2, REAL x3, R
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* GdipAddPath* helper
|
||||
*
|
||||
* Several GdipAddPath functions are expected to add onto an open figure.
|
||||
* So if the first point being added is an exact match to the last point
|
||||
* of the existing line, that point should not be added.
|
||||
*
|
||||
* Parameters:
|
||||
* path : path to which points should be added
|
||||
* points : array of points to add
|
||||
* count : number of points to add (at least 1)
|
||||
* type : type of the points being added
|
||||
*
|
||||
* Return value:
|
||||
* OutOfMemory : out of memory, could not lengthen path
|
||||
* Ok : success
|
||||
*/
|
||||
static GpStatus extend_current_figure(GpPath *path, GDIPCONST PointF *points, INT count, BYTE type)
|
||||
{
|
||||
INT insert_index = path->pathdata.Count;
|
||||
BYTE first_point_type = (path->newfigure ? PathPointTypeStart : PathPointTypeLine);
|
||||
|
||||
if(!path->newfigure &&
|
||||
path->pathdata.Points[insert_index-1].X == points[0].X &&
|
||||
path->pathdata.Points[insert_index-1].Y == points[0].Y)
|
||||
{
|
||||
points++;
|
||||
count--;
|
||||
first_point_type = type;
|
||||
}
|
||||
|
||||
if(!count)
|
||||
return Ok;
|
||||
|
||||
if(!lengthen_path(path, count))
|
||||
return OutOfMemory;
|
||||
|
||||
memcpy(path->pathdata.Points + insert_index, points, sizeof(GpPointF)*count);
|
||||
path->pathdata.Types[insert_index] = first_point_type;
|
||||
memset(path->pathdata.Types + insert_index + 1, type, count - 1);
|
||||
|
||||
path->newfigure = FALSE;
|
||||
path->pathdata.Count += count;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* GdipAddPathArc [GDIPLUS.1]
|
||||
*
|
||||
|
@ -195,7 +241,9 @@ static BOOL flatten_bezier(path_list_node_t *start, REAL x2, REAL y2, REAL x3, R
|
|||
GpStatus WINGDIPAPI GdipAddPathArc(GpPath *path, REAL x1, REAL y1, REAL x2,
|
||||
REAL y2, REAL startAngle, REAL sweepAngle)
|
||||
{
|
||||
INT count, old_count, i;
|
||||
GpPointF *points;
|
||||
GpStatus status;
|
||||
INT count;
|
||||
|
||||
TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n",
|
||||
path, x1, y1, x2, y2, startAngle, sweepAngle);
|
||||
|
@ -204,26 +252,19 @@ GpStatus WINGDIPAPI GdipAddPathArc(GpPath *path, REAL x1, REAL y1, REAL x2,
|
|||
return InvalidParameter;
|
||||
|
||||
count = arc2polybezier(NULL, x1, y1, x2, y2, startAngle, sweepAngle);
|
||||
|
||||
if(count == 0)
|
||||
return Ok;
|
||||
if(!lengthen_path(path, count))
|
||||
|
||||
points = heap_alloc_zero(sizeof(GpPointF)*count);
|
||||
if(!points)
|
||||
return OutOfMemory;
|
||||
|
||||
old_count = path->pathdata.Count;
|
||||
arc2polybezier(&path->pathdata.Points[old_count], x1, y1, x2, y2,
|
||||
startAngle, sweepAngle);
|
||||
arc2polybezier(points, x1, y1, x2, y2, startAngle, sweepAngle);
|
||||
|
||||
for(i = 0; i < count; i++){
|
||||
path->pathdata.Types[old_count + i] = PathPointTypeBezier;
|
||||
}
|
||||
status = extend_current_figure(path, points, count, PathPointTypeBezier);
|
||||
|
||||
path->pathdata.Types[old_count] =
|
||||
(path->newfigure ? PathPointTypeStart : PathPointTypeLine);
|
||||
path->newfigure = FALSE;
|
||||
path->pathdata.Count += count;
|
||||
|
||||
return Ok;
|
||||
heap_free(points);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -243,7 +284,7 @@ GpStatus WINGDIPAPI GdipAddPathArcI(GpPath *path, INT x1, INT y1, INT x2,
|
|||
GpStatus WINGDIPAPI GdipAddPathBezier(GpPath *path, REAL x1, REAL y1, REAL x2,
|
||||
REAL y2, REAL x3, REAL y3, REAL x4, REAL y4)
|
||||
{
|
||||
INT old_count;
|
||||
PointF points[4];
|
||||
|
||||
TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n",
|
||||
path, x1, y1, x2, y2, x3, y3, x4, y4);
|
||||
|
@ -251,30 +292,16 @@ GpStatus WINGDIPAPI GdipAddPathBezier(GpPath *path, REAL x1, REAL y1, REAL x2,
|
|||
if(!path)
|
||||
return InvalidParameter;
|
||||
|
||||
if(!lengthen_path(path, 4))
|
||||
return OutOfMemory;
|
||||
points[0].X = x1;
|
||||
points[0].Y = y1;
|
||||
points[1].X = x2;
|
||||
points[1].Y = y2;
|
||||
points[2].X = x3;
|
||||
points[2].Y = y3;
|
||||
points[3].X = x4;
|
||||
points[3].Y = y4;
|
||||
|
||||
old_count = path->pathdata.Count;
|
||||
|
||||
path->pathdata.Points[old_count].X = x1;
|
||||
path->pathdata.Points[old_count].Y = y1;
|
||||
path->pathdata.Points[old_count + 1].X = x2;
|
||||
path->pathdata.Points[old_count + 1].Y = y2;
|
||||
path->pathdata.Points[old_count + 2].X = x3;
|
||||
path->pathdata.Points[old_count + 2].Y = y3;
|
||||
path->pathdata.Points[old_count + 3].X = x4;
|
||||
path->pathdata.Points[old_count + 3].Y = y4;
|
||||
|
||||
path->pathdata.Types[old_count] =
|
||||
(path->newfigure ? PathPointTypeStart : PathPointTypeLine);
|
||||
path->pathdata.Types[old_count + 1] = PathPointTypeBezier;
|
||||
path->pathdata.Types[old_count + 2] = PathPointTypeBezier;
|
||||
path->pathdata.Types[old_count + 3] = PathPointTypeBezier;
|
||||
|
||||
path->newfigure = FALSE;
|
||||
path->pathdata.Count += 4;
|
||||
|
||||
return Ok;
|
||||
return extend_current_figure(path, points, 4, PathPointTypeBezier);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipAddPathBezierI(GpPath *path, INT x1, INT y1, INT x2,
|
||||
|
@ -290,30 +317,12 @@ GpStatus WINGDIPAPI GdipAddPathBezierI(GpPath *path, INT x1, INT y1, INT x2,
|
|||
GpStatus WINGDIPAPI GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points,
|
||||
INT count)
|
||||
{
|
||||
INT i, old_count;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", path, points, count);
|
||||
|
||||
if(!path || !points || ((count - 1) % 3))
|
||||
return InvalidParameter;
|
||||
|
||||
if(!lengthen_path(path, count))
|
||||
return OutOfMemory;
|
||||
|
||||
old_count = path->pathdata.Count;
|
||||
|
||||
for(i = 0; i < count; i++){
|
||||
path->pathdata.Points[old_count + i].X = points[i].X;
|
||||
path->pathdata.Points[old_count + i].Y = points[i].Y;
|
||||
path->pathdata.Types[old_count + i] = PathPointTypeBezier;
|
||||
}
|
||||
|
||||
path->pathdata.Types[old_count] =
|
||||
(path->newfigure ? PathPointTypeStart : PathPointTypeLine);
|
||||
path->newfigure = FALSE;
|
||||
path->pathdata.Count += count;
|
||||
|
||||
return Ok;
|
||||
return extend_current_figure(path, points, count, PathPointTypeBezier);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipAddPathBeziersI(GpPath *path, GDIPCONST GpPoint *points,
|
||||
|
@ -415,7 +424,7 @@ GpStatus WINGDIPAPI GdipAddPathClosedCurve2(GpPath *path, GDIPCONST GpPointF *po
|
|||
pt[len_pt-1].X = pt[0].X;
|
||||
pt[len_pt-1].Y = pt[0].Y;
|
||||
|
||||
stat = GdipAddPathBeziers(path, pt, len_pt);
|
||||
stat = extend_current_figure(path, pt, len_pt, PathPointTypeBezier);
|
||||
|
||||
/* close figure */
|
||||
if(stat == Ok){
|
||||
|
@ -523,7 +532,7 @@ GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points,
|
|||
pt[len_pt-1].X = points[count-1].X;
|
||||
pt[len_pt-1].Y = points[count-1].Y;
|
||||
|
||||
stat = GdipAddPathBeziers(path, pt, len_pt);
|
||||
stat = extend_current_figure(path, pt, len_pt, PathPointTypeBezier);
|
||||
|
||||
heap_free(pt);
|
||||
|
||||
|
@ -623,32 +632,12 @@ GpStatus WINGDIPAPI GdipAddPathEllipseI(GpPath *path, INT x, INT y, INT width,
|
|||
GpStatus WINGDIPAPI GdipAddPathLine2(GpPath *path, GDIPCONST GpPointF *points,
|
||||
INT count)
|
||||
{
|
||||
INT i, old_count;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", path, points, count);
|
||||
|
||||
if(!path || !points)
|
||||
if(!path || !points || count < 1)
|
||||
return InvalidParameter;
|
||||
|
||||
if(!lengthen_path(path, count))
|
||||
return OutOfMemory;
|
||||
|
||||
old_count = path->pathdata.Count;
|
||||
|
||||
for(i = 0; i < count; i++){
|
||||
path->pathdata.Points[old_count + i].X = points[i].X;
|
||||
path->pathdata.Points[old_count + i].Y = points[i].Y;
|
||||
path->pathdata.Types[old_count + i] = PathPointTypeLine;
|
||||
}
|
||||
|
||||
if(path->newfigure){
|
||||
path->pathdata.Types[old_count] = PathPointTypeStart;
|
||||
path->newfigure = FALSE;
|
||||
}
|
||||
|
||||
path->pathdata.Count += count;
|
||||
|
||||
return Ok;
|
||||
return extend_current_figure(path, points, count, PathPointTypeLine);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipAddPathLine2I(GpPath *path, GDIPCONST GpPoint *points, INT count)
|
||||
|
@ -703,31 +692,19 @@ GpStatus WINGDIPAPI GdipAddPathLine2I(GpPath *path, GDIPCONST GpPoint *points, I
|
|||
*/
|
||||
GpStatus WINGDIPAPI GdipAddPathLine(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2)
|
||||
{
|
||||
INT old_count;
|
||||
PointF points[2];
|
||||
|
||||
TRACE("(%p, %.2f, %.2f, %.2f, %.2f)\n", path, x1, y1, x2, y2);
|
||||
|
||||
if(!path)
|
||||
return InvalidParameter;
|
||||
|
||||
if(!lengthen_path(path, 2))
|
||||
return OutOfMemory;
|
||||
points[0].X = x1;
|
||||
points[0].Y = y1;
|
||||
points[1].X = x2;
|
||||
points[1].Y = y2;
|
||||
|
||||
old_count = path->pathdata.Count;
|
||||
|
||||
path->pathdata.Points[old_count].X = x1;
|
||||
path->pathdata.Points[old_count].Y = y1;
|
||||
path->pathdata.Points[old_count + 1].X = x2;
|
||||
path->pathdata.Points[old_count + 1].Y = y2;
|
||||
|
||||
path->pathdata.Types[old_count] =
|
||||
(path->newfigure ? PathPointTypeStart : PathPointTypeLine);
|
||||
path->pathdata.Types[old_count + 1] = PathPointTypeLine;
|
||||
|
||||
path->newfigure = FALSE;
|
||||
path->pathdata.Count += 2;
|
||||
|
||||
return Ok;
|
||||
return extend_current_figure(path, points, 2, PathPointTypeLine);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -1088,13 +1065,13 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
|
|||
heap_free(backup);
|
||||
return status;
|
||||
}
|
||||
if (format && format->line_align == StringAlignmentCenter && layoutRect->Y + args.maxY < layoutRect->Height)
|
||||
if (format->line_align == StringAlignmentCenter && layoutRect->Y + args.maxY < layoutRect->Height)
|
||||
{
|
||||
float inc = layoutRect->Height + layoutRect->Y - args.maxY;
|
||||
inc /= 2;
|
||||
for (i = backup->pathdata.Count; i < path->pathdata.Count; ++i)
|
||||
path->pathdata.Points[i].Y += inc;
|
||||
} else if (format && format->line_align == StringAlignmentFar) {
|
||||
} else if (format->line_align == StringAlignmentFar) {
|
||||
float inc = layoutRect->Height + layoutRect->Y - args.maxY;
|
||||
for (i = backup->pathdata.Count; i < path->pathdata.Count; ++i)
|
||||
path->pathdata.Points[i].Y += inc;
|
||||
|
@ -1103,19 +1080,16 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
|
|||
return status;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipAddPathStringI(GpPath* path, GDIPCONST WCHAR* string, INT length, GDIPCONST GpFontFamily* family, INT style, REAL emSize, GDIPCONST Rect* layoutRect, GDIPCONST GpStringFormat* format)
|
||||
GpStatus WINGDIPAPI GdipAddPathStringI(GpPath* path, GDIPCONST WCHAR* string, INT length, GDIPCONST GpFontFamily* family,
|
||||
INT style, REAL emSize, GDIPCONST Rect* layoutRect, GDIPCONST GpStringFormat* format)
|
||||
{
|
||||
if (layoutRect)
|
||||
{
|
||||
RectF layoutRectF = {
|
||||
(REAL)layoutRect->X,
|
||||
(REAL)layoutRect->Y,
|
||||
(REAL)layoutRect->Width,
|
||||
(REAL)layoutRect->Height
|
||||
};
|
||||
return GdipAddPathString(path, string, length, family, style, emSize, &layoutRectF, format);
|
||||
}
|
||||
return InvalidParameter;
|
||||
RectF rect;
|
||||
|
||||
if (!layoutRect)
|
||||
return InvalidParameter;
|
||||
|
||||
set_rect(&rect, layoutRect->X, layoutRect->Y, layoutRect->Width, layoutRect->Height);
|
||||
return GdipAddPathString(path, string, length, family, style, emSize, &rect, format);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -1213,14 +1187,37 @@ GpStatus WINGDIPAPI GdipCreatePath(GpFillMode fill, GpPath **path)
|
|||
GpStatus WINGDIPAPI GdipCreatePath2(GDIPCONST GpPointF* points,
|
||||
GDIPCONST BYTE* types, INT count, GpFillMode fill, GpPath **path)
|
||||
{
|
||||
int i;
|
||||
|
||||
TRACE("(%p, %p, %d, %d, %p)\n", points, types, count, fill, path);
|
||||
|
||||
if(!path)
|
||||
if(!points || !types || !path)
|
||||
return InvalidParameter;
|
||||
|
||||
if(count <= 0) {
|
||||
*path = NULL;
|
||||
return OutOfMemory;
|
||||
}
|
||||
|
||||
*path = heap_alloc_zero(sizeof(GpPath));
|
||||
if(!*path) return OutOfMemory;
|
||||
|
||||
if(count > 1 && (types[count-1] & PathPointTypePathTypeMask) == PathPointTypeStart)
|
||||
count = 0;
|
||||
|
||||
for(i = 1; i < count; i++) {
|
||||
if((types[i] & PathPointTypePathTypeMask) == PathPointTypeBezier) {
|
||||
if(i+2 < count &&
|
||||
(types[i+1] & PathPointTypePathTypeMask) == PathPointTypeBezier &&
|
||||
(types[i+2] & PathPointTypePathTypeMask) == PathPointTypeBezier)
|
||||
i += 2;
|
||||
else {
|
||||
count = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(*path)->pathdata.Points = heap_alloc_zero(count * sizeof(PointF));
|
||||
(*path)->pathdata.Types = heap_alloc_zero(count);
|
||||
|
||||
|
@ -1233,6 +1230,8 @@ GpStatus WINGDIPAPI GdipCreatePath2(GDIPCONST GpPointF* points,
|
|||
|
||||
memcpy((*path)->pathdata.Points, points, count * sizeof(PointF));
|
||||
memcpy((*path)->pathdata.Types, types, count);
|
||||
if(count > 0)
|
||||
(*path)->pathdata.Types[0] = PathPointTypeStart;
|
||||
(*path)->pathdata.Count = count;
|
||||
(*path)->datalen = count;
|
||||
|
||||
|
@ -1804,12 +1803,12 @@ GpStatus WINGDIPAPI GdipWarpPath(GpPath *path, GpMatrix* matrix,
|
|||
}
|
||||
|
||||
static void add_bevel_point(const GpPointF *endpoint, const GpPointF *nextpoint,
|
||||
GpPen *pen, int right_side, path_list_node_t **last_point)
|
||||
REAL pen_width, int right_side, path_list_node_t **last_point)
|
||||
{
|
||||
REAL segment_dy = nextpoint->Y-endpoint->Y;
|
||||
REAL segment_dx = nextpoint->X-endpoint->X;
|
||||
REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
|
||||
REAL distance = pen->width/2.0;
|
||||
REAL distance = pen_width / 2.0;
|
||||
REAL bevel_dx, bevel_dy;
|
||||
|
||||
if (segment_length == 0.0)
|
||||
|
@ -1835,7 +1834,7 @@ static void add_bevel_point(const GpPointF *endpoint, const GpPointF *nextpoint,
|
|||
}
|
||||
|
||||
static void widen_joint(const GpPointF *p1, const GpPointF *p2, const GpPointF *p3,
|
||||
GpPen* pen, path_list_node_t **last_point)
|
||||
GpPen* pen, REAL pen_width, path_list_node_t **last_point)
|
||||
{
|
||||
switch (pen->join)
|
||||
{
|
||||
|
@ -1843,7 +1842,7 @@ static void widen_joint(const GpPointF *p1, const GpPointF *p2, const GpPointF *
|
|||
case LineJoinMiterClipped:
|
||||
if ((p2->X - p1->X) * (p3->Y - p1->Y) > (p2->Y - p1->Y) * (p3->X - p1->X))
|
||||
{
|
||||
float distance = pen->width/2.0;
|
||||
float distance = pen_width / 2.0;
|
||||
float length_0 = sqrtf((p2->X-p1->X)*(p2->X-p1->X)+(p2->Y-p1->Y)*(p2->Y-p1->Y));
|
||||
float length_1 = sqrtf((p3->X-p2->X)*(p3->X-p2->X)+(p3->Y-p2->Y)*(p3->Y-p2->Y));
|
||||
float dx0 = distance * (p2->X - p1->X) / length_0;
|
||||
|
@ -1870,14 +1869,14 @@ static void widen_joint(const GpPointF *p1, const GpPointF *p2, const GpPointF *
|
|||
/* else fall-through */
|
||||
default:
|
||||
case LineJoinBevel:
|
||||
add_bevel_point(p2, p1, pen, 1, last_point);
|
||||
add_bevel_point(p2, p3, pen, 0, last_point);
|
||||
add_bevel_point(p2, p1, pen_width, 1, last_point);
|
||||
add_bevel_point(p2, p3, pen_width, 0, last_point);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint,
|
||||
GpPen *pen, GpLineCap cap, GpCustomLineCap *custom, int add_first_points,
|
||||
REAL pen_width, GpLineCap cap, GpCustomLineCap *custom, int add_first_points,
|
||||
int add_last_point, path_list_node_t **last_point)
|
||||
{
|
||||
switch (cap)
|
||||
|
@ -1885,16 +1884,16 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint,
|
|||
default:
|
||||
case LineCapFlat:
|
||||
if (add_first_points)
|
||||
add_bevel_point(endpoint, nextpoint, pen, 1, last_point);
|
||||
add_bevel_point(endpoint, nextpoint, pen_width, 1, last_point);
|
||||
if (add_last_point)
|
||||
add_bevel_point(endpoint, nextpoint, pen, 0, last_point);
|
||||
add_bevel_point(endpoint, nextpoint, pen_width, 0, last_point);
|
||||
break;
|
||||
case LineCapSquare:
|
||||
{
|
||||
REAL segment_dy = nextpoint->Y-endpoint->Y;
|
||||
REAL segment_dx = nextpoint->X-endpoint->X;
|
||||
REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
|
||||
REAL distance = pen->width/2.0;
|
||||
REAL distance = pen_width / 2.0;
|
||||
REAL bevel_dx, bevel_dy;
|
||||
REAL extend_dx, extend_dy;
|
||||
|
||||
|
@ -1919,7 +1918,7 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint,
|
|||
REAL segment_dy = nextpoint->Y-endpoint->Y;
|
||||
REAL segment_dx = nextpoint->X-endpoint->X;
|
||||
REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
|
||||
REAL distance = pen->width/2.0;
|
||||
REAL distance = pen_width / 2.0;
|
||||
REAL dx, dy, dx2, dy2;
|
||||
const REAL control_point_distance = 0.5522847498307935; /* 4/3 * (sqrt(2) - 1) */
|
||||
|
||||
|
@ -1955,6 +1954,8 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint,
|
|||
*last_point = add_path_list_node(*last_point, endpoint->X - dy,
|
||||
endpoint->Y + dx, PathPointTypeBezier);
|
||||
}
|
||||
else if (add_last_point)
|
||||
add_bevel_point(endpoint, nextpoint, pen_width, 0, last_point);
|
||||
break;
|
||||
}
|
||||
case LineCapTriangle:
|
||||
|
@ -1962,79 +1963,193 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint,
|
|||
REAL segment_dy = nextpoint->Y-endpoint->Y;
|
||||
REAL segment_dx = nextpoint->X-endpoint->X;
|
||||
REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
|
||||
REAL distance = pen->width/2.0;
|
||||
REAL distance = pen_width / 2.0;
|
||||
REAL dx, dy;
|
||||
|
||||
dx = distance * segment_dx / segment_length;
|
||||
dy = distance * segment_dy / segment_length;
|
||||
|
||||
if (add_first_points) {
|
||||
add_bevel_point(endpoint, nextpoint, pen, 1, last_point);
|
||||
add_bevel_point(endpoint, nextpoint, pen_width, 1, last_point);
|
||||
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X - dx,
|
||||
endpoint->Y - dy, PathPointTypeLine);
|
||||
}
|
||||
if (add_last_point)
|
||||
add_bevel_point(endpoint, nextpoint, pen, 0, last_point);
|
||||
if (add_first_points || add_last_point)
|
||||
add_bevel_point(endpoint, nextpoint, pen_width, 0, last_point);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void widen_open_figure(const GpPointF *points, GpPen *pen, int start, int end,
|
||||
GpLineCap start_cap, GpCustomLineCap *start_custom, GpLineCap end_cap,
|
||||
GpCustomLineCap *end_custom, path_list_node_t **last_point)
|
||||
static void add_anchor(const GpPointF *endpoint, const GpPointF *nextpoint,
|
||||
REAL pen_width, GpLineCap cap, GpCustomLineCap *custom, path_list_node_t **last_point)
|
||||
{
|
||||
switch (cap)
|
||||
{
|
||||
default:
|
||||
case LineCapNoAnchor:
|
||||
return;
|
||||
case LineCapSquareAnchor:
|
||||
{
|
||||
REAL segment_dy = nextpoint->Y-endpoint->Y;
|
||||
REAL segment_dx = nextpoint->X-endpoint->X;
|
||||
REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
|
||||
REAL distance = pen_width / sqrtf(2.0);
|
||||
REAL par_dx, par_dy;
|
||||
REAL perp_dx, perp_dy;
|
||||
|
||||
par_dx = -distance * segment_dx / segment_length;
|
||||
par_dy = -distance * segment_dy / segment_length;
|
||||
|
||||
perp_dx = -distance * segment_dy / segment_length;
|
||||
perp_dy = distance * segment_dx / segment_length;
|
||||
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X - par_dx - perp_dx,
|
||||
endpoint->Y - par_dy - perp_dy, PathPointTypeStart);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X - par_dx + perp_dx,
|
||||
endpoint->Y - par_dy + perp_dy, PathPointTypeLine);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + par_dx + perp_dx,
|
||||
endpoint->Y + par_dy + perp_dy, PathPointTypeLine);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + par_dx - perp_dx,
|
||||
endpoint->Y + par_dy - perp_dy, PathPointTypeLine);
|
||||
break;
|
||||
}
|
||||
case LineCapRoundAnchor:
|
||||
{
|
||||
REAL segment_dy = nextpoint->Y-endpoint->Y;
|
||||
REAL segment_dx = nextpoint->X-endpoint->X;
|
||||
REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
|
||||
REAL dx, dy, dx2, dy2;
|
||||
const REAL control_point_distance = 0.55228475; /* 4/3 * (sqrt(2) - 1) */
|
||||
|
||||
dx = -pen_width * segment_dx / segment_length;
|
||||
dy = -pen_width * segment_dy / segment_length;
|
||||
|
||||
dx2 = dx * control_point_distance;
|
||||
dy2 = dy * control_point_distance;
|
||||
|
||||
/* starting point */
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + dy,
|
||||
endpoint->Y - dx, PathPointTypeStart);
|
||||
|
||||
/* first 90-degree arc */
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + dy + dx2,
|
||||
endpoint->Y - dx + dy2, PathPointTypeBezier);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + dx + dy2,
|
||||
endpoint->Y + dy - dx2, PathPointTypeBezier);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + dx,
|
||||
endpoint->Y + dy, PathPointTypeBezier);
|
||||
|
||||
/* second 90-degree arc */
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + dx - dy2,
|
||||
endpoint->Y + dy + dx2, PathPointTypeBezier);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X - dy + dx2,
|
||||
endpoint->Y + dx + dy2, PathPointTypeBezier);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X - dy,
|
||||
endpoint->Y + dx, PathPointTypeBezier);
|
||||
|
||||
/* third 90-degree arc */
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X - dy - dx2,
|
||||
endpoint->Y + dx - dy2, PathPointTypeBezier);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X - dx - dy2,
|
||||
endpoint->Y - dy + dx2, PathPointTypeBezier);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X - dx,
|
||||
endpoint->Y - dy, PathPointTypeBezier);
|
||||
|
||||
/* fourth 90-degree arc */
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X - dx + dy2,
|
||||
endpoint->Y - dy - dx2, PathPointTypeBezier);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + dy - dx2,
|
||||
endpoint->Y - dx - dy2, PathPointTypeBezier);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + dy,
|
||||
endpoint->Y - dx, PathPointTypeBezier);
|
||||
|
||||
break;
|
||||
}
|
||||
case LineCapDiamondAnchor:
|
||||
{
|
||||
REAL segment_dy = nextpoint->Y-endpoint->Y;
|
||||
REAL segment_dx = nextpoint->X-endpoint->X;
|
||||
REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
|
||||
REAL par_dx, par_dy;
|
||||
REAL perp_dx, perp_dy;
|
||||
|
||||
par_dx = -pen_width * segment_dx / segment_length;
|
||||
par_dy = -pen_width * segment_dy / segment_length;
|
||||
|
||||
perp_dx = -pen_width * segment_dy / segment_length;
|
||||
perp_dy = pen_width * segment_dx / segment_length;
|
||||
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + par_dx,
|
||||
endpoint->Y + par_dy, PathPointTypeStart);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X - perp_dx,
|
||||
endpoint->Y - perp_dy, PathPointTypeLine);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X - par_dx,
|
||||
endpoint->Y - par_dy, PathPointTypeLine);
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + perp_dx,
|
||||
endpoint->Y + perp_dy, PathPointTypeLine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
(*last_point)->type |= PathPointTypeCloseSubpath;
|
||||
}
|
||||
|
||||
static void widen_open_figure(const GpPointF *points, int start, int end,
|
||||
GpPen *pen, REAL pen_width, GpLineCap start_cap, GpCustomLineCap *start_custom,
|
||||
GpLineCap end_cap, GpCustomLineCap *end_custom, path_list_node_t **last_point)
|
||||
{
|
||||
int i;
|
||||
path_list_node_t *prev_point;
|
||||
|
||||
if (end <= start)
|
||||
if (end <= start || pen_width == 0.0)
|
||||
return;
|
||||
|
||||
prev_point = *last_point;
|
||||
|
||||
widen_cap(&points[start], &points[start+1],
|
||||
pen, start_cap, start_custom, FALSE, TRUE, last_point);
|
||||
pen_width, start_cap, start_custom, FALSE, TRUE, last_point);
|
||||
|
||||
for (i=start+1; i<end; i++)
|
||||
widen_joint(&points[i-1], &points[i],
|
||||
&points[i+1], pen, last_point);
|
||||
widen_joint(&points[i-1], &points[i], &points[i+1],
|
||||
pen, pen_width, last_point);
|
||||
|
||||
widen_cap(&points[end], &points[end-1],
|
||||
pen, end_cap, end_custom, TRUE, TRUE, last_point);
|
||||
pen_width, end_cap, end_custom, TRUE, TRUE, last_point);
|
||||
|
||||
for (i=end-1; i>start; i--)
|
||||
widen_joint(&points[i+1], &points[i],
|
||||
&points[i-1], pen, last_point);
|
||||
widen_joint(&points[i+1], &points[i], &points[i-1],
|
||||
pen, pen_width, last_point);
|
||||
|
||||
widen_cap(&points[start], &points[start+1],
|
||||
pen, start_cap, start_custom, TRUE, FALSE, last_point);
|
||||
pen_width, start_cap, start_custom, TRUE, FALSE, last_point);
|
||||
|
||||
prev_point->next->type = PathPointTypeStart;
|
||||
(*last_point)->type |= PathPointTypeCloseSubpath;
|
||||
}
|
||||
|
||||
static void widen_closed_figure(GpPath *path, GpPen *pen, int start, int end,
|
||||
path_list_node_t **last_point)
|
||||
static void widen_closed_figure(GpPath *path, int start, int end,
|
||||
GpPen *pen, REAL pen_width, path_list_node_t **last_point)
|
||||
{
|
||||
int i;
|
||||
path_list_node_t *prev_point;
|
||||
|
||||
if (end <= start)
|
||||
if (end <= start || pen_width == 0.0)
|
||||
return;
|
||||
|
||||
/* left outline */
|
||||
prev_point = *last_point;
|
||||
|
||||
widen_joint(&path->pathdata.Points[end], &path->pathdata.Points[start],
|
||||
&path->pathdata.Points[start+1], pen, last_point);
|
||||
&path->pathdata.Points[start+1], pen, pen_width, last_point);
|
||||
|
||||
for (i=start+1; i<end; i++)
|
||||
widen_joint(&path->pathdata.Points[i-1], &path->pathdata.Points[i],
|
||||
&path->pathdata.Points[i+1], pen, last_point);
|
||||
&path->pathdata.Points[i+1], pen, pen_width, last_point);
|
||||
|
||||
widen_joint(&path->pathdata.Points[end-1], &path->pathdata.Points[end],
|
||||
&path->pathdata.Points[start], pen, last_point);
|
||||
&path->pathdata.Points[start], pen, pen_width, last_point);
|
||||
|
||||
prev_point->next->type = PathPointTypeStart;
|
||||
(*last_point)->type |= PathPointTypeCloseSubpath;
|
||||
|
@ -2043,21 +2158,21 @@ static void widen_closed_figure(GpPath *path, GpPen *pen, int start, int end,
|
|||
prev_point = *last_point;
|
||||
|
||||
widen_joint(&path->pathdata.Points[start], &path->pathdata.Points[end],
|
||||
&path->pathdata.Points[end-1], pen, last_point);
|
||||
&path->pathdata.Points[end-1], pen, pen_width, last_point);
|
||||
|
||||
for (i=end-1; i>start; i--)
|
||||
widen_joint(&path->pathdata.Points[i+1], &path->pathdata.Points[i],
|
||||
&path->pathdata.Points[i-1], pen, last_point);
|
||||
&path->pathdata.Points[i-1], pen, pen_width, last_point);
|
||||
|
||||
widen_joint(&path->pathdata.Points[start+1], &path->pathdata.Points[start],
|
||||
&path->pathdata.Points[end], pen, last_point);
|
||||
&path->pathdata.Points[end], pen, pen_width, last_point);
|
||||
|
||||
prev_point->next->type = PathPointTypeStart;
|
||||
(*last_point)->type |= PathPointTypeCloseSubpath;
|
||||
}
|
||||
|
||||
static void widen_dashed_figure(GpPath *path, GpPen *pen, int start, int end,
|
||||
int closed, path_list_node_t **last_point)
|
||||
static void widen_dashed_figure(GpPath *path, int start, int end, int closed,
|
||||
GpPen *pen, REAL pen_width, path_list_node_t **last_point)
|
||||
{
|
||||
int i, j;
|
||||
REAL dash_pos=0.0;
|
||||
|
@ -2074,7 +2189,7 @@ static void widen_dashed_figure(GpPath *path, GpPen *pen, int start, int end,
|
|||
int draw_start_cap=0;
|
||||
static const REAL dash_dot_dot[6] = { 3.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
|
||||
|
||||
if (end <= start)
|
||||
if (end <= start || pen_width == 0.0)
|
||||
return;
|
||||
|
||||
switch (pen->dash)
|
||||
|
@ -2151,7 +2266,7 @@ static void widen_dashed_figure(GpPath *path, GpPen *pen, int start, int end,
|
|||
tmp_points[num_tmp_points].X = path->pathdata.Points[i].X + segment_dx * segment_pos / segment_length;
|
||||
tmp_points[num_tmp_points].Y = path->pathdata.Points[i].Y + segment_dy * segment_pos / segment_length;
|
||||
|
||||
widen_open_figure(tmp_points, pen, 0, num_tmp_points,
|
||||
widen_open_figure(tmp_points, 0, num_tmp_points, pen, pen_width,
|
||||
draw_start_cap ? pen->startcap : LineCapFlat, pen->customstart,
|
||||
LineCapFlat, NULL, last_point);
|
||||
draw_start_cap = 0;
|
||||
|
@ -2185,7 +2300,7 @@ static void widen_dashed_figure(GpPath *path, GpPen *pen, int start, int end,
|
|||
if (dash_index % 2 == 0 && num_tmp_points != 0)
|
||||
{
|
||||
/* last dash overflows last segment */
|
||||
widen_open_figure(tmp_points, pen, 0, num_tmp_points-1,
|
||||
widen_open_figure(tmp_points, 0, num_tmp_points-1, pen, pen_width,
|
||||
draw_start_cap ? pen->startcap : LineCapFlat, pen->customstart,
|
||||
closed ? LineCapFlat : pen->endcap, pen->customend, last_point);
|
||||
}
|
||||
|
@ -2201,7 +2316,6 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix,
|
|||
GpStatus status;
|
||||
path_list_node_t *points=NULL, *last_point=NULL;
|
||||
int i, subpath_start=0, new_length;
|
||||
BYTE type;
|
||||
|
||||
TRACE("(%p,%p,%p,%0.2f)\n", path, pen, matrix, flatness);
|
||||
|
||||
|
@ -2221,12 +2335,16 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix,
|
|||
|
||||
if (status == Ok)
|
||||
{
|
||||
REAL anchor_pen_width = max(pen->width, 2.0);
|
||||
REAL pen_width = (pen->unit == UnitWorld) ? max(pen->width, 1.0) : pen->width;
|
||||
BYTE *types = flat_path->pathdata.Types;
|
||||
|
||||
last_point = points;
|
||||
|
||||
if (pen->endcap > LineCapTriangle)
|
||||
if (pen->endcap > LineCapDiamondAnchor)
|
||||
FIXME("unimplemented end cap %x\n", pen->endcap);
|
||||
|
||||
if (pen->startcap > LineCapTriangle)
|
||||
if (pen->startcap > LineCapDiamondAnchor)
|
||||
FIXME("unimplemented start cap %x\n", pen->startcap);
|
||||
|
||||
if (pen->dashcap != DashCapFlat)
|
||||
|
@ -2240,25 +2358,46 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix,
|
|||
|
||||
for (i=0; i < flat_path->pathdata.Count; i++)
|
||||
{
|
||||
type = flat_path->pathdata.Types[i];
|
||||
|
||||
if ((type&PathPointTypePathTypeMask) == PathPointTypeStart)
|
||||
if ((types[i]&PathPointTypePathTypeMask) == PathPointTypeStart)
|
||||
subpath_start = i;
|
||||
|
||||
if ((type&PathPointTypeCloseSubpath) == PathPointTypeCloseSubpath)
|
||||
if ((types[i]&PathPointTypeCloseSubpath) == PathPointTypeCloseSubpath)
|
||||
{
|
||||
if (pen->dash != DashStyleSolid)
|
||||
widen_dashed_figure(flat_path, pen, subpath_start, i, 1, &last_point);
|
||||
widen_dashed_figure(flat_path, subpath_start, i, 1, pen, pen_width, &last_point);
|
||||
else
|
||||
widen_closed_figure(flat_path, pen, subpath_start, i, &last_point);
|
||||
widen_closed_figure(flat_path, subpath_start, i, pen, pen_width, &last_point);
|
||||
}
|
||||
else if (i == flat_path->pathdata.Count-1 ||
|
||||
(flat_path->pathdata.Types[i+1]&PathPointTypePathTypeMask) == PathPointTypeStart)
|
||||
(types[i+1]&PathPointTypePathTypeMask) == PathPointTypeStart)
|
||||
{
|
||||
if (pen->dash != DashStyleSolid)
|
||||
widen_dashed_figure(flat_path, pen, subpath_start, i, 0, &last_point);
|
||||
widen_dashed_figure(flat_path, subpath_start, i, 0, pen, pen_width, &last_point);
|
||||
else
|
||||
widen_open_figure(flat_path->pathdata.Points, pen, subpath_start, i, pen->startcap, pen->customstart, pen->endcap, pen->customend, &last_point);
|
||||
widen_open_figure(flat_path->pathdata.Points, subpath_start, i, pen, pen_width, pen->startcap, pen->customstart, pen->endcap, pen->customend, &last_point);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i < flat_path->pathdata.Count; i++)
|
||||
{
|
||||
if ((types[i]&PathPointTypeCloseSubpath) == PathPointTypeCloseSubpath)
|
||||
continue;
|
||||
|
||||
if ((types[i]&PathPointTypePathTypeMask) == PathPointTypeStart)
|
||||
subpath_start = i;
|
||||
|
||||
if (i == flat_path->pathdata.Count-1 ||
|
||||
(types[i+1]&PathPointTypePathTypeMask) == PathPointTypeStart)
|
||||
{
|
||||
if (pen->startcap & LineCapAnchorMask)
|
||||
add_anchor(&flat_path->pathdata.Points[subpath_start],
|
||||
&flat_path->pathdata.Points[subpath_start+1],
|
||||
anchor_pen_width, pen->startcap, pen->customstart, &last_point);
|
||||
|
||||
if (pen->endcap & LineCapAnchorMask)
|
||||
add_anchor(&flat_path->pathdata.Points[i],
|
||||
&flat_path->pathdata.Points[i-1],
|
||||
anchor_pen_width, pen->endcap, pen->customend, &last_point);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2405,12 +2544,8 @@ GpStatus WINGDIPAPI GdipAddPathRectanglesI(GpPath *path, GDIPCONST GpRect *rects
|
|||
|
||||
rectsF = heap_alloc_zero(sizeof(GpRectF)*count);
|
||||
|
||||
for(i = 0;i < count;i++){
|
||||
rectsF[i].X = (REAL)rects[i].X;
|
||||
rectsF[i].Y = (REAL)rects[i].Y;
|
||||
rectsF[i].Width = (REAL)rects[i].Width;
|
||||
rectsF[i].Height = (REAL)rects[i].Height;
|
||||
}
|
||||
for(i = 0;i < count;i++)
|
||||
set_rect(&rectsF[i], rects[i].X, rects[i].Y, rects[i].Width, rects[i].Height);
|
||||
|
||||
retstat = GdipAddPathRectangles(path, rectsF, count);
|
||||
heap_free(rectsF);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -129,7 +129,7 @@ GpStatus WINGDIPAPI GdipGetImageAttributesAdjustedPalette(GpImageAttributes *ima
|
|||
GpStatus WINGDIPAPI GdipSetImageAttributesColorKeys(GpImageAttributes *imageattr,
|
||||
ColorAdjustType type, BOOL enableFlag, ARGB colorLow, ARGB colorHigh)
|
||||
{
|
||||
TRACE("(%p,%u,%i,%08x,%08x)\n", imageattr, type, enableFlag, colorLow, colorHigh);
|
||||
TRACE("(%p,%u,%i,%08lx,%08lx)\n", imageattr, type, enableFlag, colorLow, colorHigh);
|
||||
|
||||
if(!imageattr || type >= ColorAdjustTypeCount)
|
||||
return InvalidParameter;
|
||||
|
@ -176,7 +176,7 @@ GpStatus WINGDIPAPI GdipSetImageAttributesColorMatrix(GpImageAttributes *imageat
|
|||
GpStatus WINGDIPAPI GdipSetImageAttributesWrapMode(GpImageAttributes *imageAttr,
|
||||
WrapMode wrap, ARGB argb, BOOL clamp)
|
||||
{
|
||||
TRACE("(%p,%u,%08x,%i)\n", imageAttr, wrap, argb, clamp);
|
||||
TRACE("(%p,%u,%08lx,%i)\n", imageAttr, wrap, argb, clamp);
|
||||
|
||||
if(!imageAttr || wrap > WrapModeClamp)
|
||||
return InvalidParameter;
|
||||
|
|
|
@ -86,7 +86,8 @@ GpStatus WINGDIPAPI GdipCreateMatrix3(GDIPCONST GpRectF *rect,
|
|||
GDIPCONST GpPointF *pt, GpMatrix **matrix)
|
||||
{
|
||||
REAL m11, m12, m21, m22, dx, dy;
|
||||
TRACE("(%p, %p, %p)\n", rect, pt, matrix);
|
||||
|
||||
TRACE("(%s, %p, %p)\n", debugstr_rectf(rect), pt, matrix);
|
||||
|
||||
if(!matrix || !pt)
|
||||
return InvalidParameter;
|
||||
|
@ -110,10 +111,7 @@ GpStatus WINGDIPAPI GdipCreateMatrix3I(GDIPCONST GpRect *rect, GDIPCONST GpPoint
|
|||
|
||||
TRACE("(%p, %p, %p)\n", rect, pt, matrix);
|
||||
|
||||
rectF.X = (REAL)rect->X;
|
||||
rectF.Y = (REAL)rect->Y;
|
||||
rectF.Width = (REAL)rect->Width;
|
||||
rectF.Height = (REAL)rect->Height;
|
||||
set_rect(&rectF, rect->X, rect->Y, rect->Width, rect->Height);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
ptF[i].X = (REAL)pt[i].X;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -139,7 +139,7 @@ GpStatus WINGDIPAPI GdipCreatePen1(ARGB color, REAL width, GpUnit unit,
|
|||
GpBrush *brush;
|
||||
GpStatus status;
|
||||
|
||||
TRACE("(%x, %.2f, %d, %p)\n", color, width, unit, pen);
|
||||
TRACE("(%lx, %.2f, %d, %p)\n", color, width, unit, pen);
|
||||
|
||||
GdipCreateSolidFill(color, (GpSolidFill **)(&brush));
|
||||
status = GdipCreatePen2(brush, width, unit, pen);
|
||||
|
@ -512,7 +512,7 @@ GpStatus WINGDIPAPI GdipSetPenBrushFill(GpPen *pen, GpBrush *brush)
|
|||
|
||||
GpStatus WINGDIPAPI GdipSetPenColor(GpPen *pen, ARGB argb)
|
||||
{
|
||||
TRACE("(%p, %x)\n", pen, argb);
|
||||
TRACE("(%p, %lx)\n", pen, argb);
|
||||
|
||||
if(!pen)
|
||||
return InvalidParameter;
|
||||
|
@ -598,13 +598,10 @@ GpStatus WINGDIPAPI GdipSetPenDashArray(GpPen *pen, GDIPCONST REAL *dash,
|
|||
|
||||
for(i = 0; i < count; i++){
|
||||
sum += dash[i];
|
||||
if(dash[i] < 0.0)
|
||||
if(dash[i] <= 0.0)
|
||||
return InvalidParameter;
|
||||
}
|
||||
|
||||
if(sum == 0.0 && count)
|
||||
return InvalidParameter;
|
||||
|
||||
heap_free(pen->dashes);
|
||||
pen->dashes = NULL;
|
||||
|
||||
|
|
|
@ -332,11 +332,7 @@ GpStatus WINGDIPAPI GdipCombineRegionRectI(GpRegion *region,
|
|||
if (!rect)
|
||||
return InvalidParameter;
|
||||
|
||||
rectf.X = (REAL)rect->X;
|
||||
rectf.Y = (REAL)rect->Y;
|
||||
rectf.Height = (REAL)rect->Height;
|
||||
rectf.Width = (REAL)rect->Width;
|
||||
|
||||
set_rect(&rectf, rect->X, rect->Y, rect->Width, rect->Height);
|
||||
return GdipCombineRegionRect(region, &rectf, mode);
|
||||
}
|
||||
|
||||
|
@ -461,7 +457,7 @@ GpStatus WINGDIPAPI GdipCreateRegionRect(GDIPCONST GpRectF *rect,
|
|||
{
|
||||
GpStatus stat;
|
||||
|
||||
TRACE("%p, %p\n", rect, region);
|
||||
TRACE("%s, %p\n", debugstr_rectf(rect), region);
|
||||
|
||||
if (!(rect && region))
|
||||
return InvalidParameter;
|
||||
|
@ -492,11 +488,7 @@ GpStatus WINGDIPAPI GdipCreateRegionRectI(GDIPCONST GpRect *rect,
|
|||
|
||||
TRACE("%p, %p\n", rect, region);
|
||||
|
||||
rectf.X = (REAL)rect->X;
|
||||
rectf.Y = (REAL)rect->Y;
|
||||
rectf.Width = (REAL)rect->Width;
|
||||
rectf.Height = (REAL)rect->Height;
|
||||
|
||||
set_rect(&rectf, rect->X, rect->Y, rect->Width, rect->Height);
|
||||
return GdipCreateRegionRect(&rectf, region);
|
||||
}
|
||||
|
||||
|
@ -780,7 +772,7 @@ static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, regio
|
|||
type = buffer_read(mbuf, sizeof(*type));
|
||||
if (!type) return Ok;
|
||||
|
||||
TRACE("type %#x\n", *type);
|
||||
TRACE("type %#lx\n", *type);
|
||||
|
||||
node->type = *type;
|
||||
|
||||
|
@ -852,7 +844,7 @@ static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, regio
|
|||
}
|
||||
if (!VALID_MAGIC(path_header->magic))
|
||||
{
|
||||
ERR("invalid path header magic %#x\n", path_header->magic);
|
||||
ERR("invalid path header magic %#lx\n", path_header->magic);
|
||||
return InvalidParameter;
|
||||
}
|
||||
|
||||
|
@ -874,7 +866,7 @@ static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, regio
|
|||
path->pathdata.Count = path_header->count;
|
||||
|
||||
if (path_header->flags & ~FLAGS_INTPATH)
|
||||
FIXME("unhandled path flags %#x\n", path_header->flags);
|
||||
FIXME("unhandled path flags %#lx\n", path_header->flags);
|
||||
|
||||
if (path_header->flags & FLAGS_INTPATH)
|
||||
{
|
||||
|
@ -884,7 +876,7 @@ static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, regio
|
|||
pt = buffer_read(mbuf, sizeof(*pt) * path_header->count);
|
||||
if (!pt)
|
||||
{
|
||||
ERR("failed to read packed %u path points\n", path_header->count);
|
||||
ERR("failed to read packed %lu path points\n", path_header->count);
|
||||
return InvalidParameter;
|
||||
}
|
||||
|
||||
|
@ -901,7 +893,7 @@ static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, regio
|
|||
ptf = buffer_read(mbuf, sizeof(*ptf) * path_header->count);
|
||||
if (!ptf)
|
||||
{
|
||||
ERR("failed to read %u path points\n", path_header->count);
|
||||
ERR("failed to read %lu path points\n", path_header->count);
|
||||
return InvalidParameter;
|
||||
}
|
||||
memcpy(path->pathdata.Points, ptf, sizeof(*ptf) * path_header->count);
|
||||
|
@ -910,7 +902,7 @@ static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, regio
|
|||
types = buffer_read(mbuf, path_header->count);
|
||||
if (!types)
|
||||
{
|
||||
ERR("failed to read %u path types\n", path_header->count);
|
||||
ERR("failed to read %lu path types\n", path_header->count);
|
||||
return InvalidParameter;
|
||||
}
|
||||
memcpy(path->pathdata.Types, types, path_header->count);
|
||||
|
@ -918,7 +910,7 @@ static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, regio
|
|||
{
|
||||
if (!buffer_read(mbuf, 4 - (path_header->count & 3)))
|
||||
{
|
||||
ERR("failed to read rounding %u bytes\n", 4 - (path_header->count & 3));
|
||||
ERR("failed to read rounding %lu bytes\n", 4 - (path_header->count & 3));
|
||||
return InvalidParameter;
|
||||
}
|
||||
}
|
||||
|
@ -933,7 +925,7 @@ static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, regio
|
|||
return Ok;
|
||||
|
||||
default:
|
||||
FIXME("element type %#x is not supported\n", *type);
|
||||
FIXME("element type %#lx is not supported\n", *type);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1182,7 +1174,7 @@ static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *grap
|
|||
return Ok;
|
||||
}
|
||||
default:
|
||||
FIXME("GdipGetRegionHRgn unimplemented for region type=%x\n", element->type);
|
||||
FIXME("GdipGetRegionHRgn unimplemented for region type=%lx\n", element->type);
|
||||
*hrgn = NULL;
|
||||
return NotImplemented;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ dll/win32/dwmapi # Synced to Wine-8.14
|
|||
dll/win32/faultrep # Synced to WineStaging-4.18
|
||||
dll/win32/fontsub # Synced to WineStaging-2.9
|
||||
dll/win32/fusion # Synced to WineStaging-4.18
|
||||
dll/win32/gdiplus # Synced to WineStaging-4.0
|
||||
dll/win32/gdiplus # Synced to Wine 7abca9742a9410447636e0222e36d214449c90dd
|
||||
dll/win32/hhctrl.ocx # Synced to WineStaging-4.18
|
||||
dll/win32/hlink # Synced to WineStaging-4.18
|
||||
dll/win32/hnetcfg # Synced to WineStaging-4.18
|
||||
|
|
|
@ -346,6 +346,45 @@ enum ImageFlags
|
|||
ImageFlagsCaching = 0x00020000
|
||||
};
|
||||
|
||||
enum EncoderParameterValueType {
|
||||
EncoderParameterValueTypeByte = 1,
|
||||
EncoderParameterValueTypeASCII = 2,
|
||||
EncoderParameterValueTypeShort = 3,
|
||||
EncoderParameterValueTypeLong = 4,
|
||||
EncoderParameterValueTypeRational = 5,
|
||||
EncoderParameterValueTypeLongRange = 6,
|
||||
EncoderParameterValueTypeUndefined = 7,
|
||||
EncoderParameterValueTypeRationalRange = 8,
|
||||
EncoderParameterValueTypePointer = 9
|
||||
};
|
||||
|
||||
enum EncoderValue {
|
||||
EncoderValueColorTypeCMYK = 0,
|
||||
EncoderValueColorTypeYCCK = 1,
|
||||
EncoderValueCompressionLZW = 2,
|
||||
EncoderValueCompressionCCITT3 = 3,
|
||||
EncoderValueCompressionCCITT4 = 4,
|
||||
EncoderValueCompressionRle = 5,
|
||||
EncoderValueCompressionNone = 6,
|
||||
EncoderValueScanMethodInterlaced = 7,
|
||||
EncoderValueScanMethodNonInterlaced = 8,
|
||||
EncoderValueVersionGif87 = 9,
|
||||
EncoderValueVersionGif89 = 10,
|
||||
EncoderValueRenderProgressive = 11,
|
||||
EncoderValueRenderNonProgressive = 12,
|
||||
EncoderValueTransformRotate90 = 13,
|
||||
EncoderValueTransformRotate180 = 14,
|
||||
EncoderValueTransformRotate270 = 15,
|
||||
EncoderValueTransformFlipHorizontal = 16,
|
||||
EncoderValueTransformFlipVertical = 17,
|
||||
EncoderValueMultiFrame = 18,
|
||||
EncoderValueLastFrame = 19,
|
||||
EncoderValueFlush = 20,
|
||||
EncoderValueFrameDimensionTime = 21,
|
||||
EncoderValueFrameDimensionResolution = 22,
|
||||
EncoderValueFrameDimensionPage = 23
|
||||
};
|
||||
|
||||
enum CombineMode
|
||||
{
|
||||
CombineModeReplace,
|
||||
|
|
|
@ -611,6 +611,8 @@ extern "C"
|
|||
GpStatus WINGDIPAPI
|
||||
GdipSaveAdd(GpImage *, GDIPCONST EncoderParameters *);
|
||||
GpStatus WINGDIPAPI
|
||||
GdipSaveAddImage(GpImage*,GpImage*,GDIPCONST EncoderParameters*);
|
||||
GpStatus WINGDIPAPI
|
||||
GdipSaveGraphics(GpGraphics *, GraphicsState *);
|
||||
GpStatus WINGDIPAPI
|
||||
GdipScaleWorldTransform(GpGraphics *, REAL, REAL, GpMatrixOrder);
|
||||
|
|
|
@ -35,6 +35,8 @@ DEFINE_GUID(FrameDimensionTime, 0x6aedbd6d, 0x3fb5, 0x418a, 0x83, 0xa6, 0x7f, 0x
|
|||
DEFINE_GUID(FrameDimensionPage, 0x7462dc86, 0x6180, 0x4c7e, 0x8e, 0x3f, 0xee, 0x73, 0x33, 0xa7, 0xa4, 0x83);
|
||||
DEFINE_GUID(FrameDimensionResolution, 0x84236f7b, 0x3bd3, 0x428f, 0x8d, 0xab, 0x4e, 0xa1, 0x43, 0x9c, 0xa3, 0x15);
|
||||
|
||||
DEFINE_GUID(EncoderSaveFlag, 0x292266fc, 0xac40, 0x47bf, 0x8c, 0xfc, 0xa8, 0x5b, 0x89, 0xa6, 0x55, 0xde);
|
||||
|
||||
enum ImageLockMode
|
||||
{
|
||||
ImageLockModeRead = 1,
|
||||
|
|
5
sdk/tools/winesync/gdiplus.cfg
Normal file
5
sdk/tools/winesync/gdiplus.cfg
Normal file
|
@ -0,0 +1,5 @@
|
|||
directories:
|
||||
dlls/gdiplus: dll/win32/gdiplus
|
||||
files: null
|
||||
tags:
|
||||
wine: 7abca9742a9410447636e0222e36d214449c90dd
|
Loading…
Reference in a new issue