mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
[GDIPLUS]
* Sync with Wine 1.5.19. [PSDK] * Update some headers. svn path=/trunk/; revision=57882
This commit is contained in:
parent
3552b8c127
commit
d4f934e3be
15 changed files with 2482 additions and 998 deletions
|
@ -105,13 +105,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
|||
return stat;
|
||||
}
|
||||
|
||||
stat = GdipCloneMatrix(src->transform, &dest->transform);
|
||||
|
||||
if(stat != Ok){
|
||||
GdipDeletePath(dest->path);
|
||||
GdipFree(dest);
|
||||
return stat;
|
||||
}
|
||||
dest->transform = src->transform;
|
||||
|
||||
/* blending */
|
||||
count = src->blendcount;
|
||||
|
@ -129,7 +123,6 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
|||
if(!dest->blendfac || !dest->blendpos || !dest->surroundcolors ||
|
||||
(pcount && (!dest->pblendcolor || !dest->pblendpos))){
|
||||
GdipDeletePath(dest->path);
|
||||
GdipDeleteMatrix(dest->transform);
|
||||
GdipFree(dest->blendfac);
|
||||
GdipFree(dest->blendpos);
|
||||
GdipFree(dest->surroundcolors);
|
||||
|
@ -211,7 +204,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
|||
|
||||
if (stat == Ok)
|
||||
{
|
||||
memcpy(new_texture->transform, texture->transform, sizeof(GpMatrix));
|
||||
new_texture->transform = texture->transform;
|
||||
*clone = (GpBrush*)new_texture;
|
||||
}
|
||||
else
|
||||
|
@ -539,7 +532,6 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect
|
|||
static GpStatus create_path_gradient(GpPath *path, ARGB centercolor, GpPathGradient **grad)
|
||||
{
|
||||
GpRectF bounds;
|
||||
GpStatus stat;
|
||||
|
||||
if(!path || !grad)
|
||||
return InvalidParameter;
|
||||
|
@ -555,18 +547,12 @@ static GpStatus create_path_gradient(GpPath *path, ARGB centercolor, GpPathGradi
|
|||
return OutOfMemory;
|
||||
}
|
||||
|
||||
stat = GdipCreateMatrix(&(*grad)->transform);
|
||||
if (stat != Ok)
|
||||
{
|
||||
GdipFree(*grad);
|
||||
return stat;
|
||||
}
|
||||
GdipSetMatrixElements(&(*grad)->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||
|
||||
(*grad)->blendfac = GdipAlloc(sizeof(REAL));
|
||||
(*grad)->blendpos = GdipAlloc(sizeof(REAL));
|
||||
(*grad)->surroundcolors = GdipAlloc(sizeof(ARGB));
|
||||
if(!(*grad)->blendfac || !(*grad)->blendpos || !(*grad)->surroundcolors){
|
||||
GdipDeleteMatrix((*grad)->transform);
|
||||
GdipFree((*grad)->blendfac);
|
||||
GdipFree((*grad)->blendpos);
|
||||
GdipFree((*grad)->surroundcolors);
|
||||
|
@ -819,9 +805,7 @@ GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
if((status = GdipCreateMatrix(&(*texture)->transform)) != Ok){
|
||||
goto exit;
|
||||
}
|
||||
GdipSetMatrixElements(&(*texture)->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||
|
||||
if (imageattr)
|
||||
{
|
||||
|
@ -848,7 +832,6 @@ exit:
|
|||
{
|
||||
if (*texture)
|
||||
{
|
||||
GdipDeleteMatrix((*texture)->transform);
|
||||
GdipDisposeImageAttributes((*texture)->imageattributes);
|
||||
GdipFree(*texture);
|
||||
*texture = NULL;
|
||||
|
@ -947,7 +930,6 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
|
|||
{
|
||||
case BrushTypePathGradient:
|
||||
GdipDeletePath(((GpPathGradient*) brush)->path);
|
||||
GdipDeleteMatrix(((GpPathGradient*) brush)->transform);
|
||||
GdipFree(((GpPathGradient*) brush)->blendfac);
|
||||
GdipFree(((GpPathGradient*) brush)->blendpos);
|
||||
GdipFree(((GpPathGradient*) brush)->surroundcolors);
|
||||
|
@ -961,7 +943,6 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
|
|||
GdipFree(((GpLineGradient*)brush)->pblendpos);
|
||||
break;
|
||||
case BrushTypeTextureFill:
|
||||
GdipDeleteMatrix(((GpTexture*)brush)->transform);
|
||||
GdipDisposeImage(((GpTexture*)brush)->image);
|
||||
GdipDisposeImageAttributes(((GpTexture*)brush)->imageattributes);
|
||||
GdipFree(((GpTexture*)brush)->bitmap_bits);
|
||||
|
@ -1059,8 +1040,8 @@ GpStatus WINGDIPAPI GdipGetPathGradientCenterPointI(GpPathGradient *grad,
|
|||
ret = GdipGetPathGradientCenterPoint(grad,&ptf);
|
||||
|
||||
if(ret == Ok){
|
||||
point->X = roundr(ptf.X);
|
||||
point->Y = roundr(ptf.Y);
|
||||
point->X = gdip_round(ptf.X);
|
||||
point->Y = gdip_round(ptf.Y);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -1158,10 +1139,10 @@ GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect
|
|||
stat = GdipGetPathGradientRect(brush, &rectf);
|
||||
if(stat != Ok) return stat;
|
||||
|
||||
rect->X = roundr(rectf.X);
|
||||
rect->Y = roundr(rectf.Y);
|
||||
rect->Width = roundr(rectf.Width);
|
||||
rect->Height = roundr(rectf.Height);
|
||||
rect->X = gdip_round(rectf.X);
|
||||
rect->Y = gdip_round(rectf.Y);
|
||||
rect->Width = gdip_round(rectf.Width);
|
||||
rect->Height = gdip_round(rectf.Height);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -1253,7 +1234,7 @@ GpStatus WINGDIPAPI GdipGetTextureTransform(GpTexture *brush, GpMatrix *matrix)
|
|||
if(!brush || !matrix)
|
||||
return InvalidParameter;
|
||||
|
||||
memcpy(matrix, brush->transform, sizeof(GpMatrix));
|
||||
*matrix = brush->transform;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -1284,7 +1265,7 @@ GpStatus WINGDIPAPI GdipMultiplyTextureTransform(GpTexture* brush,
|
|||
if(!brush || !matrix)
|
||||
return InvalidParameter;
|
||||
|
||||
return GdipMultiplyMatrix(brush->transform, matrix, order);
|
||||
return GdipMultiplyMatrix(&brush->transform, matrix, order);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -1297,7 +1278,7 @@ GpStatus WINGDIPAPI GdipResetTextureTransform(GpTexture* brush)
|
|||
if(!brush)
|
||||
return InvalidParameter;
|
||||
|
||||
return GdipSetMatrixElements(brush->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||
return GdipSetMatrixElements(&brush->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -1311,7 +1292,7 @@ GpStatus WINGDIPAPI GdipScaleTextureTransform(GpTexture* brush,
|
|||
if(!brush)
|
||||
return InvalidParameter;
|
||||
|
||||
return GdipScaleMatrix(brush->transform, sx, sy, order);
|
||||
return GdipScaleMatrix(&brush->transform, sx, sy, order);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient *brush,
|
||||
|
@ -1785,7 +1766,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientTransform(GpPathGradient *grad,
|
|||
if (!grad || !matrix)
|
||||
return InvalidParameter;
|
||||
|
||||
memcpy(grad->transform, matrix, sizeof(GpMatrix));
|
||||
grad->transform = *matrix;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -1798,7 +1779,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientTransform(GpPathGradient *grad,
|
|||
if (!grad || !matrix)
|
||||
return InvalidParameter;
|
||||
|
||||
memcpy(matrix, grad->transform, sizeof(GpMatrix));
|
||||
*matrix = grad->transform;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -1811,7 +1792,7 @@ GpStatus WINGDIPAPI GdipMultiplyPathGradientTransform(GpPathGradient *grad,
|
|||
if (!grad)
|
||||
return InvalidParameter;
|
||||
|
||||
return GdipMultiplyMatrix(grad->transform, matrix, order);
|
||||
return GdipMultiplyMatrix(&grad->transform, matrix, order);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipResetPathGradientTransform(GpPathGradient *grad)
|
||||
|
@ -1821,7 +1802,7 @@ GpStatus WINGDIPAPI GdipResetPathGradientTransform(GpPathGradient *grad)
|
|||
if (!grad)
|
||||
return InvalidParameter;
|
||||
|
||||
return GdipSetMatrixElements(grad->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||
return GdipSetMatrixElements(&grad->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipRotatePathGradientTransform(GpPathGradient *grad,
|
||||
|
@ -1832,7 +1813,7 @@ GpStatus WINGDIPAPI GdipRotatePathGradientTransform(GpPathGradient *grad,
|
|||
if (!grad)
|
||||
return InvalidParameter;
|
||||
|
||||
return GdipRotateMatrix(grad->transform, angle, order);
|
||||
return GdipRotateMatrix(&grad->transform, angle, order);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipScalePathGradientTransform(GpPathGradient *grad,
|
||||
|
@ -1843,7 +1824,7 @@ GpStatus WINGDIPAPI GdipScalePathGradientTransform(GpPathGradient *grad,
|
|||
if (!grad)
|
||||
return InvalidParameter;
|
||||
|
||||
return GdipScaleMatrix(grad->transform, sx, sy, order);
|
||||
return GdipScaleMatrix(&grad->transform, sx, sy, order);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipTranslatePathGradientTransform(GpPathGradient *grad,
|
||||
|
@ -1854,7 +1835,7 @@ GpStatus WINGDIPAPI GdipTranslatePathGradientTransform(GpPathGradient *grad,
|
|||
if (!grad)
|
||||
return InvalidParameter;
|
||||
|
||||
return GdipTranslateMatrix(grad->transform, dx, dy, order);
|
||||
return GdipTranslateMatrix(&grad->transform, dx, dy, order);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipSetSolidFillColor(GpSolidFill *sf, ARGB argb)
|
||||
|
@ -1879,7 +1860,7 @@ GpStatus WINGDIPAPI GdipSetTextureTransform(GpTexture *texture,
|
|||
if(!texture || !matrix)
|
||||
return InvalidParameter;
|
||||
|
||||
memcpy(texture->transform, matrix, sizeof(GpMatrix));
|
||||
texture->transform = *matrix;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -1939,7 +1920,7 @@ GpStatus WINGDIPAPI GdipRotateTextureTransform(GpTexture* brush, REAL angle,
|
|||
if(!brush)
|
||||
return InvalidParameter;
|
||||
|
||||
return GdipRotateMatrix(brush->transform, angle, order);
|
||||
return GdipRotateMatrix(&brush->transform, angle, order);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus,
|
||||
|
@ -2125,7 +2106,7 @@ GpStatus WINGDIPAPI GdipTranslateTextureTransform(GpTexture* brush, REAL dx, REA
|
|||
if(!brush)
|
||||
return InvalidParameter;
|
||||
|
||||
return GdipTranslateMatrix(brush->transform, dx, dy, order);
|
||||
return GdipTranslateMatrix(&brush->transform, dx, dy, order);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipGetLineRect(GpLineGradient *brush, GpRectF *rect)
|
||||
|
@ -2153,10 +2134,10 @@ GpStatus WINGDIPAPI GdipGetLineRectI(GpLineGradient *brush, GpRect *rect)
|
|||
ret = GdipGetLineRect(brush, &rectF);
|
||||
|
||||
if(ret == Ok){
|
||||
rect->X = roundr(rectF.X);
|
||||
rect->Y = roundr(rectF.Y);
|
||||
rect->Width = roundr(rectF.Width);
|
||||
rect->Height = roundr(rectF.Height);
|
||||
rect->X = gdip_round(rectF.X);
|
||||
rect->Y = gdip_round(rectF.Y);
|
||||
rect->Width = gdip_round(rectF.Width);
|
||||
rect->Height = gdip_round(rectF.Height);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -116,41 +116,10 @@ typedef struct
|
|||
#define MS_OS2_TAG MS_MAKE_TAG('O','S','/','2')
|
||||
#define MS_HHEA_TAG MS_MAKE_TAG('h','h','e','a')
|
||||
|
||||
static const REAL mm_per_inch = 25.4;
|
||||
static const REAL inch_per_point = 1.0/72.0;
|
||||
static GpStatus clone_font_family(const GpFontFamily *, GpFontFamily **);
|
||||
|
||||
static GpFontCollection installedFontCollection = {0};
|
||||
|
||||
static LONG em_size_to_pixel(REAL em_size, Unit unit, LONG dpi)
|
||||
{
|
||||
switch (unit)
|
||||
{
|
||||
default:
|
||||
FIXME("Unhandled unit type: %d\n", unit);
|
||||
return 0;
|
||||
|
||||
case UnitPixel:
|
||||
case UnitWorld:
|
||||
/* FIXME: Figure out when World != Pixel */
|
||||
return em_size;
|
||||
case UnitDisplay:
|
||||
FIXME("Unknown behavior for UnitDisplay! Please report!\n");
|
||||
/* FIXME: Figure out how this works...
|
||||
* MSDN says that if "DISPLAY" is a monitor, then pixel should be
|
||||
* used. That's not what I got. Tests on Windows revealed no output,
|
||||
* and the tests in tests/font crash windows */
|
||||
return 0;
|
||||
case UnitPoint:
|
||||
return em_size * dpi * inch_per_point;
|
||||
case UnitInch:
|
||||
return em_size * dpi;
|
||||
case UnitDocument:
|
||||
return em_size * dpi / 300.0; /* Per MSDN */
|
||||
case UnitMillimeter:
|
||||
return em_size * dpi / mm_per_inch;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* GdipCreateFont [GDIPLUS.@]
|
||||
*
|
||||
|
@ -193,7 +162,7 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
|
|||
stat = GdipGetFamilyName(fontFamily, lfw.lfFaceName, LANG_NEUTRAL);
|
||||
if (stat != Ok) return stat;
|
||||
|
||||
lfw.lfHeight = -em_size_to_pixel(emSize, unit, fontFamily->dpi);
|
||||
lfw.lfHeight = -units_to_pixels(emSize, unit, fontFamily->dpi);
|
||||
lfw.lfWeight = style & FontStyleBold ? FW_BOLD : FW_REGULAR;
|
||||
lfw.lfItalic = style & FontStyleItalic;
|
||||
lfw.lfUnderline = style & FontStyleUnderline;
|
||||
|
@ -216,7 +185,7 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
|
|||
(*font)->emSize = emSize;
|
||||
(*font)->otm = otm;
|
||||
|
||||
stat = GdipCloneFontFamily((GpFontFamily *)fontFamily, &(*font)->family);
|
||||
stat = clone_font_family(fontFamily, &(*font)->family);
|
||||
if (stat != Ok)
|
||||
{
|
||||
GdipFree(*font);
|
||||
|
@ -236,6 +205,7 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
|
|||
{
|
||||
HFONT hfont, oldfont;
|
||||
OUTLINETEXTMETRICW otm;
|
||||
WCHAR facename[LF_FACESIZE];
|
||||
GpStatus stat;
|
||||
int ret;
|
||||
|
||||
|
@ -248,6 +218,7 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
|
|||
oldfont = SelectObject(hdc, hfont);
|
||||
otm.otmSize = sizeof(otm);
|
||||
ret = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
|
||||
GetTextFaceW(hdc, LF_FACESIZE, facename);
|
||||
SelectObject(hdc, oldfont);
|
||||
DeleteObject(hfont);
|
||||
|
||||
|
@ -260,7 +231,7 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
|
|||
(*font)->emSize = otm.otmTextMetrics.tmAscent;
|
||||
(*font)->otm = otm;
|
||||
|
||||
stat = GdipCreateFontFamilyFromName(logfont->lfFaceName, NULL, &(*font)->family);
|
||||
stat = GdipCreateFontFamilyFromName(facename, NULL, &(*font)->family);
|
||||
if (stat != Ok)
|
||||
{
|
||||
GdipFree(*font);
|
||||
|
@ -355,6 +326,11 @@ GpStatus WINGDIPAPI GdipGetFamily(GpFont *font, GpFontFamily **family)
|
|||
return GdipCloneFontFamily(font->family, family);
|
||||
}
|
||||
|
||||
static REAL get_font_size(const GpFont *font)
|
||||
{
|
||||
return font->emSize;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GdipGetFontSize [GDIPLUS.@]
|
||||
*
|
||||
|
@ -377,12 +353,30 @@ GpStatus WINGDIPAPI GdipGetFontSize(GpFont *font, REAL *size)
|
|||
|
||||
if (!(font && size)) return InvalidParameter;
|
||||
|
||||
*size = font->emSize;
|
||||
*size = get_font_size(font);
|
||||
TRACE("%s,%d => %f\n", debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *size);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
static INT get_font_style(const GpFont *font)
|
||||
{
|
||||
INT style;
|
||||
|
||||
if (font->otm.otmTextMetrics.tmWeight > FW_REGULAR)
|
||||
style = FontStyleBold;
|
||||
else
|
||||
style = FontStyleRegular;
|
||||
if (font->otm.otmTextMetrics.tmItalic)
|
||||
style |= FontStyleItalic;
|
||||
if (font->otm.otmTextMetrics.tmUnderlined)
|
||||
style |= FontStyleUnderline;
|
||||
if (font->otm.otmTextMetrics.tmStruckOut)
|
||||
style |= FontStyleStrikeout;
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* GdipGetFontStyle [GDIPLUS.@]
|
||||
*
|
||||
|
@ -403,16 +397,8 @@ GpStatus WINGDIPAPI GdipGetFontStyle(GpFont *font, INT *style)
|
|||
if (!(font && style))
|
||||
return InvalidParameter;
|
||||
|
||||
if (font->otm.otmTextMetrics.tmWeight > FW_REGULAR)
|
||||
*style = FontStyleBold;
|
||||
else
|
||||
*style = FontStyleRegular;
|
||||
if (font->otm.otmTextMetrics.tmItalic)
|
||||
*style |= FontStyleItalic;
|
||||
if (font->otm.otmTextMetrics.tmUnderlined)
|
||||
*style |= FontStyleUnderline;
|
||||
if (font->otm.otmTextMetrics.tmStruckOut)
|
||||
*style |= FontStyleStrikeout;
|
||||
*style = get_font_style(font);
|
||||
TRACE("%s,%d => %d\n", debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *style);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -466,31 +452,64 @@ GpStatus WINGDIPAPI GdipGetLogFontA(GpFont *font, GpGraphics *graphics,
|
|||
/*******************************************************************************
|
||||
* GdipGetLogFontW [GDIPLUS.@]
|
||||
*/
|
||||
GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics,
|
||||
LOGFONTW *lfw)
|
||||
GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics, LOGFONTW *lf)
|
||||
{
|
||||
TRACE("(%p, %p, %p)\n", font, graphics, lfw);
|
||||
REAL angle, rel_height, height;
|
||||
GpMatrix matrix;
|
||||
GpPointF pt[3];
|
||||
|
||||
/* FIXME: use graphics */
|
||||
if(!font || !graphics || !lfw)
|
||||
TRACE("(%p, %p, %p)\n", font, graphics, lf);
|
||||
|
||||
if (!font || !graphics || !lf)
|
||||
return InvalidParameter;
|
||||
|
||||
lfw->lfHeight = -font->otm.otmTextMetrics.tmAscent;
|
||||
lfw->lfWidth = 0;
|
||||
lfw->lfEscapement = 0;
|
||||
lfw->lfOrientation = 0;
|
||||
lfw->lfWeight = font->otm.otmTextMetrics.tmWeight;
|
||||
lfw->lfItalic = font->otm.otmTextMetrics.tmItalic ? 1 : 0;
|
||||
lfw->lfUnderline = font->otm.otmTextMetrics.tmUnderlined ? 1 : 0;
|
||||
lfw->lfStrikeOut = font->otm.otmTextMetrics.tmStruckOut ? 1 : 0;
|
||||
lfw->lfCharSet = font->otm.otmTextMetrics.tmCharSet;
|
||||
lfw->lfOutPrecision = OUT_DEFAULT_PRECIS;
|
||||
lfw->lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
lfw->lfQuality = DEFAULT_QUALITY;
|
||||
lfw->lfPitchAndFamily = 0;
|
||||
strcpyW(lfw->lfFaceName, font->family->FamilyName);
|
||||
matrix = graphics->worldtrans;
|
||||
|
||||
TRACE("=> %s,%d\n", debugstr_w(lfw->lfFaceName), lfw->lfHeight);
|
||||
if (font->unit == UnitPixel)
|
||||
{
|
||||
height = units_to_pixels(font->emSize, graphics->unit, graphics->yres);
|
||||
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);
|
||||
else
|
||||
height = units_to_pixels(font->emSize, font->unit, graphics->yres);
|
||||
}
|
||||
|
||||
pt[0].X = 0.0;
|
||||
pt[0].Y = 0.0;
|
||||
pt[1].X = 1.0;
|
||||
pt[1].Y = 0.0;
|
||||
pt[2].X = 0.0;
|
||||
pt[2].Y = 1.0;
|
||||
GdipTransformMatrixPoints(&matrix, pt, 3);
|
||||
angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
|
||||
rel_height = sqrt((pt[2].Y - pt[0].Y) * (pt[2].Y - pt[0].Y)+
|
||||
(pt[2].X - pt[0].X) * (pt[2].X - pt[0].X));
|
||||
|
||||
lf->lfHeight = -gdip_round(height * rel_height);
|
||||
lf->lfWidth = 0;
|
||||
lf->lfEscapement = lf->lfOrientation = gdip_round((angle / M_PI) * 1800.0);
|
||||
if (lf->lfEscapement < 0)
|
||||
{
|
||||
lf->lfEscapement += 3600;
|
||||
lf->lfOrientation += 3600;
|
||||
}
|
||||
lf->lfWeight = font->otm.otmTextMetrics.tmWeight;
|
||||
lf->lfItalic = font->otm.otmTextMetrics.tmItalic ? 1 : 0;
|
||||
lf->lfUnderline = font->otm.otmTextMetrics.tmUnderlined ? 1 : 0;
|
||||
lf->lfStrikeOut = font->otm.otmTextMetrics.tmStruckOut ? 1 : 0;
|
||||
lf->lfCharSet = font->otm.otmTextMetrics.tmCharSet;
|
||||
lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
|
||||
lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
lf->lfQuality = DEFAULT_QUALITY;
|
||||
lf->lfPitchAndFamily = 0;
|
||||
strcpyW(lf->lfFaceName, font->family->FamilyName);
|
||||
|
||||
TRACE("=> %s,%d\n", debugstr_w(lf->lfFaceName), lf->lfHeight);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -535,18 +554,29 @@ GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont *font,
|
|||
{
|
||||
REAL dpi;
|
||||
GpStatus stat;
|
||||
REAL font_height;
|
||||
|
||||
TRACE("%p %p %p\n", font, graphics, height);
|
||||
|
||||
if (graphics)
|
||||
{
|
||||
stat = GdipGetDpiY((GpGraphics*)graphics, &dpi);
|
||||
if (stat != Ok) return stat;
|
||||
}
|
||||
else
|
||||
dpi = font->family->dpi;
|
||||
stat = GdipGetFontHeightGivenDPI(font, font->family->dpi, &font_height);
|
||||
if (stat != Ok) return stat;
|
||||
|
||||
return GdipGetFontHeightGivenDPI(font, dpi, height);
|
||||
if (!graphics)
|
||||
{
|
||||
*height = font_height;
|
||||
TRACE("%s,%d => %f\n",
|
||||
debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *height);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
stat = GdipGetDpiY((GpGraphics *)graphics, &dpi);
|
||||
if (stat != Ok) return stat;
|
||||
|
||||
*height = pixels_to_units(font_height, graphics->unit, dpi);
|
||||
|
||||
TRACE("%s,%d(unit %d) => %f\n",
|
||||
debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, graphics->unit, *height);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -569,49 +599,24 @@ GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi,
|
|||
GpStatus stat;
|
||||
INT style;
|
||||
UINT16 line_spacing, em_height;
|
||||
REAL font_height, font_size;
|
||||
REAL font_size;
|
||||
|
||||
if (!font || !height) return InvalidParameter;
|
||||
|
||||
TRACE("%p (%s), %f, %p\n", font,
|
||||
debugstr_w(font->family->FamilyName), dpi, height);
|
||||
|
||||
stat = GdipGetFontSize((GpFont *)font, &font_size);
|
||||
if (stat != Ok) return stat;
|
||||
stat = GdipGetFontStyle((GpFont *)font, &style);
|
||||
if (stat != Ok) return stat;
|
||||
font_size = units_to_pixels(get_font_size(font), font->unit, dpi);
|
||||
style = get_font_style(font);
|
||||
stat = GdipGetLineSpacing(font->family, style, &line_spacing);
|
||||
if (stat != Ok) return stat;
|
||||
stat = GdipGetEmHeight(font->family, style, &em_height);
|
||||
if (stat != Ok) return stat;
|
||||
|
||||
font_height = (REAL)line_spacing * font_size / (REAL)em_height;
|
||||
*height = (REAL)line_spacing * font_size / (REAL)em_height;
|
||||
|
||||
switch (font->unit)
|
||||
{
|
||||
case UnitPixel:
|
||||
case UnitWorld:
|
||||
*height = font_height;
|
||||
break;
|
||||
case UnitPoint:
|
||||
*height = font_height * dpi * inch_per_point;
|
||||
break;
|
||||
case UnitInch:
|
||||
*height = font_height * dpi;
|
||||
break;
|
||||
case UnitDocument:
|
||||
*height = font_height * (dpi / 300.0);
|
||||
break;
|
||||
case UnitMillimeter:
|
||||
*height = font_height * (dpi / mm_per_inch);
|
||||
break;
|
||||
default:
|
||||
FIXME("Unhandled unit type: %d\n", font->unit);
|
||||
return NotImplemented;
|
||||
}
|
||||
|
||||
TRACE("%s,%d(unit %d) => %f\n",
|
||||
debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, font->unit, *height);
|
||||
TRACE("%s,%d => %f\n",
|
||||
debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *height);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -625,7 +630,7 @@ GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi,
|
|||
static INT CALLBACK is_font_installed_proc(const LOGFONTW *elf,
|
||||
const TEXTMETRICW *ntm, DWORD type, LPARAM lParam)
|
||||
{
|
||||
if (type != TRUETYPE_FONTTYPE)
|
||||
if (type & RASTER_FONTTYPE)
|
||||
return 1;
|
||||
|
||||
*(LOGFONTW *)lParam = *elf;
|
||||
|
@ -635,6 +640,7 @@ static INT CALLBACK is_font_installed_proc(const LOGFONTW *elf,
|
|||
|
||||
struct font_metrics
|
||||
{
|
||||
WCHAR facename[LF_FACESIZE];
|
||||
UINT16 em_height, ascent, descent, line_spacing; /* in font units */
|
||||
int dpi;
|
||||
};
|
||||
|
@ -650,6 +656,8 @@ static BOOL get_font_metrics(HDC hdc, struct font_metrics *fm)
|
|||
otm.otmSize = sizeof(otm);
|
||||
if (!GetOutlineTextMetricsW(hdc, otm.otmSize, &otm)) return FALSE;
|
||||
|
||||
GetTextFaceW(hdc, LF_FACESIZE, fm->facename);
|
||||
|
||||
fm->em_height = otm.otmEMSquare;
|
||||
fm->dpi = GetDeviceCaps(hdc, LOGPIXELSY);
|
||||
|
||||
|
@ -750,7 +758,7 @@ GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
|
|||
ffamily = GdipAlloc(sizeof (GpFontFamily));
|
||||
if (!ffamily) return OutOfMemory;
|
||||
|
||||
lstrcpynW(ffamily->FamilyName, name, LF_FACESIZE);
|
||||
lstrcpyW(ffamily->FamilyName, fm.facename);
|
||||
ffamily->em_height = fm.em_height;
|
||||
ffamily->ascent = fm.ascent;
|
||||
ffamily->descent = fm.descent;
|
||||
|
@ -764,6 +772,16 @@ GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
|
|||
return Ok;
|
||||
}
|
||||
|
||||
static GpStatus clone_font_family(const GpFontFamily *family, GpFontFamily **clone)
|
||||
{
|
||||
*clone = GdipAlloc(sizeof(GpFontFamily));
|
||||
if (!*clone) return OutOfMemory;
|
||||
|
||||
**clone = *family;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* GdipCloneFontFamily [GDIPLUS.@]
|
||||
*
|
||||
|
@ -778,16 +796,15 @@ GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
|
|||
*/
|
||||
GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily* FontFamily, GpFontFamily** clonedFontFamily)
|
||||
{
|
||||
GpStatus status;
|
||||
|
||||
if (!(FontFamily && clonedFontFamily)) return InvalidParameter;
|
||||
|
||||
TRACE("%p (%s), %p\n", FontFamily,
|
||||
debugstr_w(FontFamily->FamilyName), clonedFontFamily);
|
||||
|
||||
*clonedFontFamily = GdipAlloc(sizeof(GpFontFamily));
|
||||
if (!*clonedFontFamily) return OutOfMemory;
|
||||
|
||||
**clonedFontFamily = *FontFamily;
|
||||
lstrcpyW((*clonedFontFamily)->FamilyName, FontFamily->FamilyName);
|
||||
status = clone_font_family(FontFamily, clonedFontFamily);
|
||||
if (status != Ok) return status;
|
||||
|
||||
TRACE("<-- %p\n", *clonedFontFamily);
|
||||
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
|
||||
|
||||
static const REAL mm_per_inch = 25.4;
|
||||
static const REAL point_per_inch = 72.0;
|
||||
|
||||
static Status WINAPI NotificationHook(ULONG_PTR *token)
|
||||
{
|
||||
TRACE("%p\n", token);
|
||||
|
@ -207,7 +210,7 @@ static void unstretch_angle(REAL * angle, REAL rad_x, REAL rad_y)
|
|||
return;
|
||||
|
||||
stretched = gdiplus_atan2(sin(*angle) / fabs(rad_y), cos(*angle) / fabs(rad_x));
|
||||
revs_off = roundr(*angle / (2.0 * M_PI)) - roundr(stretched / (2.0 * M_PI));
|
||||
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;
|
||||
}
|
||||
|
@ -318,28 +321,57 @@ GpStatus hresult_to_status(HRESULT res)
|
|||
}
|
||||
|
||||
/* converts a given unit to its value in pixels */
|
||||
REAL convert_unit(REAL logpixels, GpUnit unit)
|
||||
REAL units_to_pixels(REAL units, GpUnit unit, REAL dpi)
|
||||
{
|
||||
switch(unit)
|
||||
switch (unit)
|
||||
{
|
||||
case UnitInch:
|
||||
return logpixels;
|
||||
case UnitPoint:
|
||||
return logpixels / 72.0;
|
||||
case UnitDocument:
|
||||
return logpixels / 300.0;
|
||||
case UnitMillimeter:
|
||||
return logpixels / 25.4;
|
||||
case UnitWorld:
|
||||
ERR("cannot convert UnitWorld\n");
|
||||
return 0.0;
|
||||
case UnitPixel:
|
||||
case UnitDisplay:
|
||||
default:
|
||||
return 1.0;
|
||||
case UnitPixel:
|
||||
case UnitWorld:
|
||||
case UnitDisplay:
|
||||
return units;
|
||||
case UnitPoint:
|
||||
return units * dpi / point_per_inch;
|
||||
case UnitInch:
|
||||
return units * dpi;
|
||||
case UnitDocument:
|
||||
return units * dpi / 300.0; /* Per MSDN */
|
||||
case UnitMillimeter:
|
||||
return units * dpi / mm_per_inch;
|
||||
default:
|
||||
FIXME("Unhandled unit type: %d\n", unit);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* converts value in pixels to a given unit */
|
||||
REAL pixels_to_units(REAL pixels, GpUnit unit, REAL dpi)
|
||||
{
|
||||
switch (unit)
|
||||
{
|
||||
case UnitPixel:
|
||||
case UnitWorld:
|
||||
case UnitDisplay:
|
||||
return pixels;
|
||||
case UnitPoint:
|
||||
return pixels * point_per_inch / dpi;
|
||||
case UnitInch:
|
||||
return pixels / dpi;
|
||||
case UnitDocument:
|
||||
return pixels * 300.0 / dpi;
|
||||
case UnitMillimeter:
|
||||
return pixels * mm_per_inch / dpi;
|
||||
default:
|
||||
FIXME("Unhandled unit type: %d\n", unit);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
REAL units_scale(GpUnit from, GpUnit to, REAL dpi)
|
||||
{
|
||||
REAL pixels = units_to_pixels(1.0, from, dpi);
|
||||
return pixels_to_units(pixels, to, dpi);
|
||||
}
|
||||
|
||||
/* Calculates Bezier points from cardinal spline points. */
|
||||
void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1,
|
||||
REAL *y1, REAL *x2, REAL *y2)
|
||||
|
@ -362,8 +394,8 @@ void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj,
|
|||
REAL tension, REAL *x, REAL *y)
|
||||
{
|
||||
/* tangent at endpoints is the line from the endpoint to the adjacent point */
|
||||
*x = roundr(tension * (xadj - xend) + xend);
|
||||
*y = roundr(tension * (yadj - yend) + yend);
|
||||
*x = gdip_round(tension * (xadj - xend) + xend);
|
||||
*y = gdip_round(tension * (yadj - yend) + yend);
|
||||
}
|
||||
|
||||
/* make sure path has enough space for len more points */
|
||||
|
|
|
@ -471,10 +471,10 @@
|
|||
471 stdcall GdipRotatePenTransform(ptr float long)
|
||||
472 stdcall GdipRotateTextureTransform(ptr float long)
|
||||
473 stdcall GdipRotateWorldTransform(ptr float long)
|
||||
474 stub GdipSaveAdd
|
||||
474 stdcall GdipSaveAdd(ptr ptr)
|
||||
475 stub GdipSaveAddImage
|
||||
476 stdcall GdipSaveGraphics(ptr ptr)
|
||||
477 stdcall GdipSaveImageToFile(ptr ptr ptr ptr)
|
||||
477 stdcall GdipSaveImageToFile(ptr wstr ptr ptr)
|
||||
478 stdcall GdipSaveImageToStream(ptr ptr ptr ptr)
|
||||
479 stdcall GdipScaleLineTransform(ptr float float long)
|
||||
480 stdcall GdipScaleMatrix(ptr float float long)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "objbase.h"
|
||||
#include "ocidl.h"
|
||||
#include "wincodecsdk.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
#include "gdiplus.h"
|
||||
|
@ -47,7 +48,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 convert_unit(REAL logpixels, GpUnit unit) 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 GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) DECLSPEC_HIDDEN;
|
||||
|
||||
|
@ -55,6 +58,7 @@ extern GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **r
|
|||
extern GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_ReleaseDC(GpMetafile* metafile, HDC hdc) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile) DECLSPEC_HIDDEN;
|
||||
extern MetafileType METAFILE_GetEmfType(HENHMETAFILE hemf) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1,
|
||||
REAL *y1, REAL *x2, REAL *y2) DECLSPEC_HIDDEN;
|
||||
|
@ -63,8 +67,6 @@ extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj,
|
|||
|
||||
extern void free_installed_fonts(void) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font, HFONT *hfont) DECLSPEC_HIDDEN;
|
||||
|
||||
extern BOOL lengthen_path(GpPath *path, INT len) DECLSPEC_HIDDEN;
|
||||
|
||||
extern GpStatus trace_path(GpGraphics *graphics, GpPath *path) DECLSPEC_HIDDEN;
|
||||
|
@ -74,7 +76,7 @@ extern void delete_element(region_element *element) DECLSPEC_HIDDEN;
|
|||
|
||||
extern GpStatus get_hatch_data(HatchStyle hatchstyle, const char **result) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline INT roundr(REAL x)
|
||||
static inline INT gdip_round(REAL x)
|
||||
{
|
||||
return (INT) floorf(x + 0.5);
|
||||
}
|
||||
|
@ -121,7 +123,11 @@ extern void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height,
|
|||
|
||||
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, ARGB *src_palette) DECLSPEC_HIDDEN;
|
||||
INT src_stride, const BYTE *src_bits, PixelFormat src_format, ColorPalette *palette) DECLSPEC_HIDDEN;
|
||||
|
||||
struct GpMatrix{
|
||||
REAL matrix[6];
|
||||
};
|
||||
|
||||
struct GpPen{
|
||||
UINT style;
|
||||
|
@ -146,6 +152,7 @@ struct GpGraphics{
|
|||
HDC hdc;
|
||||
HWND hwnd;
|
||||
BOOL owndc;
|
||||
BOOL alpha_hdc;
|
||||
GpImage *image;
|
||||
SmoothingMode smoothing;
|
||||
CompositingQuality compqual;
|
||||
|
@ -155,7 +162,8 @@ struct GpGraphics{
|
|||
TextRenderingHint texthint;
|
||||
GpUnit unit; /* page unit */
|
||||
REAL scale; /* page scale */
|
||||
GpMatrix * worldtrans; /* world transform */
|
||||
REAL xres, yres;
|
||||
GpMatrix worldtrans; /* world transform */
|
||||
BOOL busy; /* hdc handle obtained by GdipGetDC */
|
||||
GpRegion *clip;
|
||||
UINT textcontrast; /* not used yet. get/set only */
|
||||
|
@ -202,7 +210,7 @@ struct GpPathGradient{
|
|||
ARGB* pblendcolor; /* preset blend colors */
|
||||
REAL* pblendpos; /* preset blend positions */
|
||||
INT pblendcount;
|
||||
GpMatrix *transform;
|
||||
GpMatrix transform;
|
||||
};
|
||||
|
||||
struct GpLineGradient{
|
||||
|
@ -224,7 +232,7 @@ struct GpLineGradient{
|
|||
|
||||
struct GpTexture{
|
||||
GpBrush brush;
|
||||
GpMatrix *transform;
|
||||
GpMatrix transform;
|
||||
GpImage *image;
|
||||
GpImageAttributes *imageattributes;
|
||||
BYTE *bitmap_bits; /* image bits converted to ARGB and run through imageattributes */
|
||||
|
@ -237,10 +245,6 @@ struct GpPath{
|
|||
INT datalen; /* size of the arrays in pathdata */
|
||||
};
|
||||
|
||||
struct GpMatrix{
|
||||
REAL matrix[6];
|
||||
};
|
||||
|
||||
struct GpPathIterator{
|
||||
GpPathData pathdata;
|
||||
INT subpath_pos; /* for NextSubpath methods */
|
||||
|
@ -262,14 +266,13 @@ struct GpAdustableArrowCap{
|
|||
};
|
||||
|
||||
struct GpImage{
|
||||
IPicture* picture;
|
||||
IPicture *picture;
|
||||
IStream *stream; /* source stream */
|
||||
ImageType type;
|
||||
GUID format;
|
||||
UINT flags;
|
||||
UINT palette_flags;
|
||||
UINT palette_count;
|
||||
UINT palette_size;
|
||||
ARGB *palette_entries;
|
||||
UINT frame_count, current_frame;
|
||||
ColorPalette *palette;
|
||||
REAL xres, yres;
|
||||
};
|
||||
|
||||
|
@ -279,6 +282,7 @@ struct GpMetafile{
|
|||
GpUnit unit;
|
||||
MetafileType metafile_type;
|
||||
HENHMETAFILE hemf;
|
||||
int preserve_hemf; /* if true, hemf belongs to the app and should not be deleted */
|
||||
|
||||
/* recording */
|
||||
HDC record_dc;
|
||||
|
@ -309,6 +313,9 @@ struct GpBitmap{
|
|||
INT stride; /* stride of bits if this is a DIB */
|
||||
BYTE *own_bits; /* image bits that need to be freed with this object */
|
||||
INT lockx, locky; /* X and Y coordinates of the rect when a bitmap is locked for writing. */
|
||||
IWICMetadataReader *metadata_reader; /* NULL if there is no metadata */
|
||||
UINT prop_count;
|
||||
PropertyItem *prop_item; /* cached image properties */
|
||||
};
|
||||
|
||||
struct GpCachedBitmap{
|
||||
|
@ -366,6 +373,7 @@ struct GpStringFormat{
|
|||
REAL *tabs;
|
||||
CharacterRange *character_ranges;
|
||||
INT range_count;
|
||||
BOOL generic_typographic;
|
||||
};
|
||||
|
||||
struct GpFontCollection{
|
||||
|
@ -436,4 +444,6 @@ GpStatus gdip_format_string(HDC hdc,
|
|||
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
|
||||
gdip_format_string_callback callback, void *user_data) DECLSPEC_HIDDEN;
|
||||
|
||||
void get_log_fontW(const GpFont *, GpGraphics *, LOGFONTW *) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -155,7 +155,7 @@ static BOOL flatten_bezier(path_list_node_t *start, REAL x2, REAL y2, REAL x3, R
|
|||
if(!(node = add_path_list_node(start, mp[2].X, mp[2].Y, PathPointTypeLine)))
|
||||
return FALSE;
|
||||
|
||||
/* do the same with halfs */
|
||||
/* do the same with halves */
|
||||
flatten_bezier(start, mp[0].X, mp[0].Y, mp[1].X, mp[1].Y, node, flatness);
|
||||
flatten_bezier(node, mp[3].X, mp[3].Y, mp[4].X, mp[4].Y, end, flatness);
|
||||
|
||||
|
@ -840,7 +840,9 @@ static float fromfixedpoint(const FIXED v)
|
|||
struct format_string_args
|
||||
{
|
||||
GpPath *path;
|
||||
UINT maxY;
|
||||
float maxY;
|
||||
float scale;
|
||||
float ascent;
|
||||
};
|
||||
|
||||
static GpStatus format_string_callback(HDC dc,
|
||||
|
@ -853,20 +855,22 @@ static GpStatus format_string_callback(HDC dc,
|
|||
struct format_string_args *args = priv;
|
||||
GpPath *path = args->path;
|
||||
GpStatus status = Ok;
|
||||
float x = bounds->X;
|
||||
float y = bounds->Y;
|
||||
float x = rect->X + (bounds->X - rect->X) * args->scale;
|
||||
float y = rect->Y + (bounds->Y - rect->Y) * args->scale;
|
||||
int i;
|
||||
|
||||
if (underlined_index_count)
|
||||
FIXME("hotkey underlines not drawn yet\n");
|
||||
|
||||
if (y + bounds->Height * args->scale > args->maxY)
|
||||
args->maxY = y + bounds->Height * args->scale;
|
||||
|
||||
for (i = index; i < length; ++i)
|
||||
{
|
||||
GLYPHMETRICS gm;
|
||||
TTPOLYGONHEADER *ph = NULL;
|
||||
char *start;
|
||||
DWORD len, ofs = 0;
|
||||
UINT bb_end;
|
||||
len = GetGlyphOutlineW(dc, string[i], GGO_BEZIER, &gm, 0, NULL, &identity);
|
||||
if (len == GDI_ERROR)
|
||||
{
|
||||
|
@ -881,9 +885,6 @@ static GpStatus format_string_callback(HDC dc,
|
|||
break;
|
||||
}
|
||||
GetGlyphOutlineW(dc, string[i], GGO_BEZIER, &gm, len, start, &identity);
|
||||
bb_end = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
|
||||
if (bb_end + y > args->maxY)
|
||||
args->maxY = bb_end + y;
|
||||
|
||||
ofs = 0;
|
||||
while (ofs < len)
|
||||
|
@ -891,8 +892,8 @@ static GpStatus format_string_callback(HDC dc,
|
|||
DWORD ofs_start = ofs;
|
||||
ph = (TTPOLYGONHEADER*)&start[ofs];
|
||||
path->pathdata.Types[path->pathdata.Count] = PathPointTypeStart;
|
||||
path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(ph->pfxStart.x);
|
||||
path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(ph->pfxStart.y);
|
||||
path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(ph->pfxStart.x) * args->scale;
|
||||
path->pathdata.Points[path->pathdata.Count++].Y = y + args->ascent - fromfixedpoint(ph->pfxStart.y) * args->scale;
|
||||
TRACE("Starting at count %i with pos %f, %f)\n", path->pathdata.Count, x, y);
|
||||
ofs += sizeof(*ph);
|
||||
while (ofs - ofs_start < ph->cb)
|
||||
|
@ -907,16 +908,16 @@ static GpStatus format_string_callback(HDC dc,
|
|||
for (j = 0; j < curve->cpfx; ++j)
|
||||
{
|
||||
path->pathdata.Types[path->pathdata.Count] = PathPointTypeLine;
|
||||
path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(curve->apfx[j].x);
|
||||
path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(curve->apfx[j].y);
|
||||
path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(curve->apfx[j].x) * args->scale;
|
||||
path->pathdata.Points[path->pathdata.Count++].Y = y + args->ascent - fromfixedpoint(curve->apfx[j].y) * args->scale;
|
||||
}
|
||||
break;
|
||||
case TT_PRIM_CSPLINE:
|
||||
for (j = 0; j < curve->cpfx; ++j)
|
||||
{
|
||||
path->pathdata.Types[path->pathdata.Count] = PathPointTypeBezier;
|
||||
path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(curve->apfx[j].x);
|
||||
path->pathdata.Points[path->pathdata.Count++].Y = y + bb_end - fromfixedpoint(curve->apfx[j].y);
|
||||
path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(curve->apfx[j].x) * args->scale;
|
||||
path->pathdata.Points[path->pathdata.Count++].Y = y + args->ascent - fromfixedpoint(curve->apfx[j].y) * args->scale;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -927,8 +928,8 @@ static GpStatus format_string_callback(HDC dc,
|
|||
path->pathdata.Types[path->pathdata.Count - 1] |= PathPointTypeCloseSubpath;
|
||||
}
|
||||
path->newfigure = TRUE;
|
||||
x += gm.gmCellIncX;
|
||||
y += gm.gmCellIncY;
|
||||
x += gm.gmCellIncX * args->scale;
|
||||
y += gm.gmCellIncY * args->scale;
|
||||
|
||||
GdipFree(ph);
|
||||
if (status != Ok)
|
||||
|
@ -945,39 +946,70 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
|
|||
LOGFONTW lfw;
|
||||
HANDLE hfont;
|
||||
HDC dc;
|
||||
GpGraphics *graphics;
|
||||
GpPath *backup;
|
||||
struct format_string_args args;
|
||||
int i;
|
||||
UINT16 native_height;
|
||||
RectF scaled_layout_rect;
|
||||
TEXTMETRICW textmetric;
|
||||
|
||||
FIXME("(%p, %s, %d, %p, %d, %f, %p, %p): stub\n", path, debugstr_w(string), length, family, style, emSize, layoutRect, format);
|
||||
TRACE("(%p, %s, %d, %p, %d, %f, %p, %p)\n", path, debugstr_w(string), length, family, style, emSize, layoutRect, format);
|
||||
if (!path || !string || !family || !emSize || !layoutRect || !format)
|
||||
return InvalidParameter;
|
||||
|
||||
status = GdipCreateFont(family, emSize, style, UnitPixel, &font);
|
||||
status = GdipGetEmHeight(family, style, &native_height);
|
||||
if (status != Ok)
|
||||
return status;
|
||||
|
||||
status = GdipGetLogFontW((GpFont *)font, NULL, &lfw);
|
||||
if (status != Ok) return status;
|
||||
scaled_layout_rect.X = layoutRect->X;
|
||||
scaled_layout_rect.Y = layoutRect->Y;
|
||||
scaled_layout_rect.Width = layoutRect->Width * native_height / emSize;
|
||||
scaled_layout_rect.Height = layoutRect->Height * native_height / emSize;
|
||||
|
||||
if ((status = GdipClonePath(path, &backup)) != Ok)
|
||||
return status;
|
||||
|
||||
dc = CreateCompatibleDC(0);
|
||||
status = GdipCreateFromHDC(dc, &graphics);
|
||||
if (status != Ok)
|
||||
{
|
||||
DeleteDC(dc);
|
||||
GdipDeletePath(backup);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = GdipCreateFont(family, native_height, style, UnitPixel, &font);
|
||||
if (status != Ok)
|
||||
{
|
||||
GdipDeleteGraphics(graphics);
|
||||
DeleteDC(dc);
|
||||
GdipDeletePath(backup);
|
||||
return status;
|
||||
}
|
||||
|
||||
get_log_fontW(font, graphics, &lfw);
|
||||
GdipDeleteFont(font);
|
||||
GdipDeleteGraphics(graphics);
|
||||
|
||||
hfont = CreateFontIndirectW(&lfw);
|
||||
if (!hfont)
|
||||
{
|
||||
WARN("Failed to create font\n");
|
||||
DeleteDC(dc);
|
||||
GdipDeletePath(backup);
|
||||
return GenericError;
|
||||
}
|
||||
|
||||
if ((status = GdipClonePath(path, &backup)) != Ok)
|
||||
{
|
||||
DeleteObject(hfont);
|
||||
return status;
|
||||
}
|
||||
|
||||
dc = CreateCompatibleDC(0);
|
||||
SelectObject(dc, hfont);
|
||||
|
||||
GetTextMetricsW(dc, &textmetric);
|
||||
|
||||
args.path = path;
|
||||
args.maxY = 0;
|
||||
status = gdip_format_string(dc, string, length, NULL, layoutRect, format, format_string_callback, &args);
|
||||
args.scale = emSize / native_height;
|
||||
args.ascent = textmetric.tmAscent * args.scale;
|
||||
status = gdip_format_string(dc, string, length, NULL, &scaled_layout_rect, format, format_string_callback, &args);
|
||||
|
||||
DeleteDC(dc);
|
||||
DeleteObject(hfont);
|
||||
|
@ -992,12 +1024,12 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
|
|||
}
|
||||
if (format && format->vertalign == StringAlignmentCenter && layoutRect->Y + args.maxY < layoutRect->Height)
|
||||
{
|
||||
float inc = layoutRect->Height - args.maxY - layoutRect->Y;
|
||||
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->vertalign == StringAlignmentFar) {
|
||||
float inc = layoutRect->Height - args.maxY - layoutRect->Y;
|
||||
float inc = layoutRect->Height + layoutRect->Y - args.maxY;
|
||||
for (i = backup->pathdata.Count; i < path->pathdata.Count; ++i)
|
||||
path->pathdata.Points[i].Y += inc;
|
||||
}
|
||||
|
@ -1035,9 +1067,9 @@ GpStatus WINGDIPAPI GdipClonePath(GpPath* path, GpPath **clone)
|
|||
(*clone)->pathdata.Points = GdipAlloc(path->datalen * sizeof(PointF));
|
||||
(*clone)->pathdata.Types = GdipAlloc(path->datalen);
|
||||
if(!(*clone)->pathdata.Points || !(*clone)->pathdata.Types){
|
||||
GdipFree(*clone);
|
||||
GdipFree((*clone)->pathdata.Points);
|
||||
GdipFree((*clone)->pathdata.Types);
|
||||
GdipFree(*clone);
|
||||
return OutOfMemory;
|
||||
}
|
||||
|
||||
|
@ -1173,20 +1205,22 @@ GpStatus WINGDIPAPI GdipFlattenPath(GpPath *path, GpMatrix* matrix, REAL flatnes
|
|||
GpPointF pt;
|
||||
INT i = 1;
|
||||
INT startidx = 0;
|
||||
GpStatus stat;
|
||||
|
||||
TRACE("(%p, %p, %.2f)\n", path, matrix, flatness);
|
||||
|
||||
if(!path)
|
||||
return InvalidParameter;
|
||||
|
||||
if(matrix){
|
||||
WARN("transformation not supported yet!\n");
|
||||
return NotImplemented;
|
||||
}
|
||||
|
||||
if(path->pathdata.Count == 0)
|
||||
return Ok;
|
||||
|
||||
if(matrix){
|
||||
stat = GdipTransformPath(path, matrix);
|
||||
if (stat != Ok)
|
||||
return stat;
|
||||
}
|
||||
|
||||
pt = path->pathdata.Points[0];
|
||||
if(!init_path_list(&list, pt.X, pt.Y))
|
||||
return OutOfMemory;
|
||||
|
@ -1339,8 +1373,8 @@ GpStatus WINGDIPAPI GdipGetPathPointsI(GpPath *path, GpPoint* points, INT count)
|
|||
ret = GdipGetPathPoints(path,ptf,count);
|
||||
if(ret == Ok)
|
||||
for(i = 0;i < count;i++){
|
||||
points[i].X = roundr(ptf[i].X);
|
||||
points[i].Y = roundr(ptf[i].Y);
|
||||
points[i].X = gdip_round(ptf[i].X);
|
||||
points[i].Y = gdip_round(ptf[i].Y);
|
||||
};
|
||||
GdipFree(ptf);
|
||||
|
||||
|
@ -1460,10 +1494,10 @@ GpStatus WINGDIPAPI GdipGetPathWorldBoundsI(GpPath* path, GpRect* bounds,
|
|||
ret = GdipGetPathWorldBounds(path,&boundsF,matrix,pen);
|
||||
|
||||
if(ret == Ok){
|
||||
bounds->X = roundr(boundsF.X);
|
||||
bounds->Y = roundr(boundsF.Y);
|
||||
bounds->Width = roundr(boundsF.Width);
|
||||
bounds->Height = roundr(boundsF.Height);
|
||||
bounds->X = gdip_round(boundsF.X);
|
||||
bounds->Y = gdip_round(boundsF.Y);
|
||||
bounds->Width = gdip_round(boundsF.Width);
|
||||
bounds->Height = gdip_round(boundsF.Height);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -1589,7 +1623,7 @@ GpStatus WINGDIPAPI GdipIsVisiblePathPoint(GpPath* path, REAL x, REAL y, GpGraph
|
|||
return status;
|
||||
}
|
||||
|
||||
*result = PtInRegion(hrgn, roundr(x), roundr(y));
|
||||
*result = PtInRegion(hrgn, gdip_round(x), gdip_round(y));
|
||||
|
||||
DeleteObject(hrgn);
|
||||
GdipDeleteRegion(region);
|
||||
|
@ -1688,6 +1722,35 @@ static void widen_joint(const GpPointF *p1, const GpPointF *p2, const GpPointF *
|
|||
{
|
||||
switch (pen->join)
|
||||
{
|
||||
case LineJoinMiter:
|
||||
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 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;
|
||||
float dy0 = distance * (p2->Y - p1->Y) / length_0;
|
||||
float dx1 = distance * (p3->X - p2->X) / length_1;
|
||||
float dy1 = distance * (p3->Y - p2->Y) / length_1;
|
||||
float det = (dy0*dx1 - dx0*dy1);
|
||||
float dx = (dx0*dx1*(dx0-dx1) + dy0*dy0*dx1 - dy1*dy1*dx0)/det;
|
||||
float dy = (dy0*dy1*(dy0-dy1) + dx0*dx0*dy1 - dx1*dx1*dy0)/det;
|
||||
if (dx*dx + dy*dy < pen->miterlimit*pen->miterlimit * distance*distance)
|
||||
{
|
||||
*last_point = add_path_list_node(*last_point, p2->X + dx,
|
||||
p2->Y + dy, PathPointTypeLine);
|
||||
break;
|
||||
}
|
||||
else if (pen->join == LineJoinMiter)
|
||||
{
|
||||
static int once;
|
||||
if (!once++)
|
||||
FIXME("should add a clipped corner\n");
|
||||
}
|
||||
/* else fall-through */
|
||||
}
|
||||
/* else fall-through */
|
||||
default:
|
||||
case LineJoinBevel:
|
||||
add_bevel_point(p2, p1, pen, 1, last_point);
|
||||
|
@ -1709,6 +1772,74 @@ static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint,
|
|||
if (add_last_point)
|
||||
add_bevel_point(endpoint, nextpoint, pen, 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 bevel_dx, bevel_dy;
|
||||
REAL extend_dx, extend_dy;
|
||||
|
||||
extend_dx = -distance * segment_dx / segment_length;
|
||||
extend_dy = -distance * segment_dy / segment_length;
|
||||
|
||||
bevel_dx = -distance * segment_dy / segment_length;
|
||||
bevel_dy = distance * segment_dx / segment_length;
|
||||
|
||||
if (add_first_points)
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + extend_dx + bevel_dx,
|
||||
endpoint->Y + extend_dy + bevel_dy, PathPointTypeLine);
|
||||
|
||||
if (add_last_point)
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + extend_dx - bevel_dx,
|
||||
endpoint->Y + extend_dy - bevel_dy, PathPointTypeLine);
|
||||
|
||||
break;
|
||||
}
|
||||
case LineCapRound:
|
||||
{
|
||||
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 dx, dy, dx2, dy2;
|
||||
const REAL control_point_distance = 0.5522847498307935; /* 4/3 * (sqrt(2) - 1) */
|
||||
|
||||
if (add_first_points)
|
||||
{
|
||||
dx = -distance * segment_dx / segment_length;
|
||||
dy = -distance * segment_dy / segment_length;
|
||||
|
||||
dx2 = dx * control_point_distance;
|
||||
dy2 = dy * control_point_distance;
|
||||
|
||||
/* first 90-degree arc */
|
||||
*last_point = add_path_list_node(*last_point, endpoint->X + dy,
|
||||
endpoint->Y - dx, PathPointTypeLine);
|
||||
|
||||
*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);
|
||||
|
||||
/* midpoint */
|
||||
*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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1716,15 +1847,16 @@ static void widen_open_figure(GpPath *path, GpPen *pen, int start, int end,
|
|||
path_list_node_t **last_point)
|
||||
{
|
||||
int i;
|
||||
path_list_node_t *prev_point;
|
||||
|
||||
if (end <= start)
|
||||
return;
|
||||
|
||||
prev_point = *last_point;
|
||||
|
||||
widen_cap(&path->pathdata.Points[start], &path->pathdata.Points[start+1],
|
||||
pen, pen->startcap, pen->customstart, FALSE, TRUE, last_point);
|
||||
|
||||
(*last_point)->type = PathPointTypeStart;
|
||||
|
||||
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);
|
||||
|
@ -1739,6 +1871,7 @@ static void widen_open_figure(GpPath *path, GpPen *pen, int start, int end,
|
|||
widen_cap(&path->pathdata.Points[start], &path->pathdata.Points[start+1],
|
||||
pen, pen->startcap, pen->customstart, TRUE, FALSE, last_point);
|
||||
|
||||
prev_point->next->type = PathPointTypeStart;
|
||||
(*last_point)->type |= PathPointTypeCloseSubpath;
|
||||
}
|
||||
|
||||
|
@ -1813,16 +1946,16 @@ GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix,
|
|||
{
|
||||
last_point = points;
|
||||
|
||||
if (pen->endcap != LineCapFlat)
|
||||
if (pen->endcap > LineCapRound)
|
||||
FIXME("unimplemented end cap %x\n", pen->endcap);
|
||||
|
||||
if (pen->startcap != LineCapFlat)
|
||||
if (pen->startcap > LineCapRound)
|
||||
FIXME("unimplemented start cap %x\n", pen->startcap);
|
||||
|
||||
if (pen->dashcap != DashCapFlat)
|
||||
FIXME("unimplemented dash cap %d\n", pen->dashcap);
|
||||
|
||||
if (pen->join != LineJoinBevel)
|
||||
if (pen->join == LineJoinRound)
|
||||
FIXME("unimplemented line join %d\n", pen->join);
|
||||
|
||||
if (pen->dash != DashStyleSolid)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -393,8 +393,8 @@ GpStatus WINGDIPAPI GdipTransformMatrixPointsI(GpMatrix *matrix, GpPoint *pts, I
|
|||
|
||||
if(ret == Ok)
|
||||
for(i = 0; i < count; i++){
|
||||
pts[i].X = roundr(ptsF[i].X);
|
||||
pts[i].Y = roundr(ptsF[i].Y);
|
||||
pts[i].X = gdip_round(ptsF[i].X);
|
||||
pts[i].Y = gdip_round(ptsF[i].Y);
|
||||
}
|
||||
GdipFree(ptsF);
|
||||
|
||||
|
@ -474,8 +474,8 @@ GpStatus WINGDIPAPI GdipVectorTransformMatrixPointsI(GpMatrix *matrix, GpPoint *
|
|||
/* store back */
|
||||
if(ret == Ok)
|
||||
for(i = 0; i < count; i++){
|
||||
pts[i].X = roundr(ptsF[i].X);
|
||||
pts[i].Y = roundr(ptsF[i].Y);
|
||||
pts[i].X = gdip_round(ptsF[i].X);
|
||||
pts[i].Y = gdip_round(ptsF[i].Y);
|
||||
}
|
||||
GdipFree(ptsF);
|
||||
|
||||
|
|
|
@ -232,10 +232,7 @@ GpStatus WINGDIPAPI GdipRecordMetafile(HDC hdc, EmfType type, GDIPCONST GpRectF
|
|||
(*metafile)->image.type = ImageTypeMetafile;
|
||||
(*metafile)->image.picture = NULL;
|
||||
(*metafile)->image.flags = ImageFlagsNone;
|
||||
(*metafile)->image.palette_flags = 0;
|
||||
(*metafile)->image.palette_count = 0;
|
||||
(*metafile)->image.palette_size = 0;
|
||||
(*metafile)->image.palette_entries = NULL;
|
||||
(*metafile)->image.palette = NULL;
|
||||
(*metafile)->bounds = *frameRect;
|
||||
(*metafile)->unit = frameUnit;
|
||||
(*metafile)->metafile_type = type;
|
||||
|
@ -551,3 +548,41 @@ GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics,
|
|||
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int CALLBACK get_metafile_type_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR,
|
||||
int nObj, LPARAM lpData)
|
||||
{
|
||||
MetafileType *result = (MetafileType*)lpData;
|
||||
|
||||
if (lpEMFR->iType == EMR_GDICOMMENT)
|
||||
{
|
||||
const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR;
|
||||
|
||||
if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0)
|
||||
{
|
||||
const EmfPlusRecordHeader *header = (const EmfPlusRecordHeader*)&comment->Data[4];
|
||||
|
||||
if (4 + sizeof(EmfPlusRecordHeader) <= comment->cbData &&
|
||||
header->Type == EmfPlusRecordTypeHeader)
|
||||
{
|
||||
if ((header->Flags & 1) == 1)
|
||||
*result = MetafileTypeEmfPlusDual;
|
||||
else
|
||||
*result = MetafileTypeEmfPlusOnly;
|
||||
}
|
||||
}
|
||||
else
|
||||
*result = MetafileTypeEmf;
|
||||
}
|
||||
else
|
||||
*result = MetafileTypeEmf;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MetafileType METAFILE_GetEmfType(HENHMETAFILE hemf)
|
||||
{
|
||||
MetafileType result = MetafileTypeInvalid;
|
||||
EnumEnhMetaFile(NULL, hemf, get_metafile_type_proc, &result, NULL);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -151,15 +151,15 @@ static inline GpStatus clone_element(const region_element* element,
|
|||
{
|
||||
case RegionDataRect:
|
||||
(*element2)->elementdata.rect = element->elementdata.rect;
|
||||
break;
|
||||
return Ok;
|
||||
case RegionDataEmptyRect:
|
||||
case RegionDataInfiniteRect:
|
||||
break;
|
||||
return Ok;
|
||||
case RegionDataPath:
|
||||
(*element2)->elementdata.pathdata.pathheader = element->elementdata.pathdata.pathheader;
|
||||
stat = GdipClonePath(element->elementdata.pathdata.path,
|
||||
&(*element2)->elementdata.pathdata.path);
|
||||
if (stat != Ok) goto clone_out;
|
||||
if (stat == Ok) return Ok;
|
||||
break;
|
||||
default:
|
||||
(*element2)->elementdata.combine.left = NULL;
|
||||
|
@ -167,16 +167,15 @@ static inline GpStatus clone_element(const region_element* element,
|
|||
|
||||
stat = clone_element(element->elementdata.combine.left,
|
||||
&(*element2)->elementdata.combine.left);
|
||||
if (stat != Ok) goto clone_out;
|
||||
stat = clone_element(element->elementdata.combine.right,
|
||||
&(*element2)->elementdata.combine.right);
|
||||
if (stat != Ok) goto clone_out;
|
||||
if (stat == Ok)
|
||||
{
|
||||
stat = clone_element(element->elementdata.combine.right,
|
||||
&(*element2)->elementdata.combine.right);
|
||||
if (stat == Ok) return Ok;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return Ok;
|
||||
|
||||
clone_out:
|
||||
delete_element(*element2);
|
||||
*element2 = NULL;
|
||||
return stat;
|
||||
|
@ -254,20 +253,20 @@ GpStatus WINGDIPAPI GdipCombineRegionPath(GpRegion *region, GpPath *path, Combin
|
|||
}
|
||||
|
||||
left = GdipAlloc(sizeof(region_element));
|
||||
if (!left)
|
||||
goto out;
|
||||
*left = region->node;
|
||||
if (left)
|
||||
{
|
||||
*left = region->node;
|
||||
stat = clone_element(&path_region->node, &right);
|
||||
if (stat == Ok)
|
||||
{
|
||||
fuse_region(region, left, right, mode);
|
||||
GdipDeleteRegion(path_region);
|
||||
return Ok;
|
||||
}
|
||||
}
|
||||
else
|
||||
stat = OutOfMemory;
|
||||
|
||||
stat = clone_element(&path_region->node, &right);
|
||||
if (stat != Ok)
|
||||
goto out;
|
||||
|
||||
fuse_region(region, left, right, mode);
|
||||
|
||||
GdipDeleteRegion(path_region);
|
||||
return Ok;
|
||||
|
||||
out:
|
||||
GdipFree(left);
|
||||
GdipDeleteRegion(path_region);
|
||||
return stat;
|
||||
|
@ -301,20 +300,20 @@ GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region,
|
|||
}
|
||||
|
||||
left = GdipAlloc(sizeof(region_element));
|
||||
if (!left)
|
||||
goto out;
|
||||
memcpy(left, ®ion->node, sizeof(region_element));
|
||||
if (left)
|
||||
{
|
||||
memcpy(left, ®ion->node, sizeof(region_element));
|
||||
stat = clone_element(&rect_region->node, &right);
|
||||
if (stat == Ok)
|
||||
{
|
||||
fuse_region(region, left, right, mode);
|
||||
GdipDeleteRegion(rect_region);
|
||||
return Ok;
|
||||
}
|
||||
}
|
||||
else
|
||||
stat = OutOfMemory;
|
||||
|
||||
stat = clone_element(&rect_region->node, &right);
|
||||
if (stat != Ok)
|
||||
goto out;
|
||||
|
||||
fuse_region(region, left, right, mode);
|
||||
|
||||
GdipDeleteRegion(rect_region);
|
||||
return Ok;
|
||||
|
||||
out:
|
||||
GdipFree(left);
|
||||
GdipDeleteRegion(rect_region);
|
||||
return stat;
|
||||
|
@ -399,6 +398,8 @@ GpStatus WINGDIPAPI GdipCreateRegion(GpRegion **region)
|
|||
if(!*region)
|
||||
return OutOfMemory;
|
||||
|
||||
TRACE("=> %p\n", *region);
|
||||
|
||||
return init_region(*region, RegionDataInfiniteRect);
|
||||
}
|
||||
|
||||
|
@ -680,6 +681,7 @@ GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics,
|
|||
if(!hrgn){
|
||||
rect->X = rect->Y = -(REAL)(1 << 22);
|
||||
rect->Width = rect->Height = (REAL)(1 << 23);
|
||||
TRACE("%p => infinite\n", region);
|
||||
return Ok;
|
||||
}
|
||||
|
||||
|
@ -688,6 +690,7 @@ GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics,
|
|||
rect->Y = r.top;
|
||||
rect->Width = r.right - r.left;
|
||||
rect->Height = r.bottom - r.top;
|
||||
TRACE("%p => %s\n", region, debugstr_rectf(rect));
|
||||
}
|
||||
else
|
||||
status = GenericError;
|
||||
|
@ -712,10 +715,10 @@ GpStatus WINGDIPAPI GdipGetRegionBoundsI(GpRegion *region, GpGraphics *graphics,
|
|||
|
||||
status = GdipGetRegionBounds(region, graphics, &rectf);
|
||||
if(status == Ok){
|
||||
rect->X = roundr(rectf.X);
|
||||
rect->Y = roundr(rectf.X);
|
||||
rect->Width = roundr(rectf.Width);
|
||||
rect->Height = roundr(rectf.Height);
|
||||
rect->X = gdip_round(rectf.X);
|
||||
rect->Y = gdip_round(rectf.X);
|
||||
rect->Width = gdip_round(rectf.Width);
|
||||
rect->Height = gdip_round(rectf.Height);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@ -1080,12 +1083,19 @@ GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *region, GpGraphics *graphics, HR
|
|||
|
||||
GpStatus WINGDIPAPI GdipIsEmptyRegion(GpRegion *region, GpGraphics *graphics, BOOL *res)
|
||||
{
|
||||
GpStatus status;
|
||||
GpRectF rect;
|
||||
|
||||
TRACE("(%p, %p, %p)\n", region, graphics, res);
|
||||
|
||||
if(!region || !graphics || !res)
|
||||
return InvalidParameter;
|
||||
|
||||
*res = (region->node.type == RegionDataEmptyRect);
|
||||
status = GdipGetRegionBounds(region, graphics, &rect);
|
||||
if (status != Ok) return status;
|
||||
|
||||
*res = rect.Width == 0.0 && rect.Height == 0.0;
|
||||
TRACE("=> %d\n", *res);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
@ -1210,7 +1220,7 @@ GpStatus WINGDIPAPI GdipIsVisibleRegionPoint(GpRegion* region, REAL x, REAL y, G
|
|||
return Ok;
|
||||
}
|
||||
|
||||
*res = PtInRegion(hrgn, roundr(x), roundr(y));
|
||||
*res = PtInRegion(hrgn, gdip_round(x), gdip_round(y));
|
||||
|
||||
DeleteObject(hrgn);
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ GpStatus WINGDIPAPI GdipCreateStringFormat(INT attr, LANGID lang,
|
|||
(*format)->digitsub = StringDigitSubstituteUser;
|
||||
(*format)->character_ranges = NULL;
|
||||
(*format)->range_count = 0;
|
||||
(*format)->generic_typographic = FALSE;
|
||||
/* tabstops */
|
||||
(*format)->tabcount = 0;
|
||||
(*format)->firsttab = 0.0;
|
||||
|
@ -386,6 +387,9 @@ GpStatus WINGDIPAPI GdipStringFormatGetGenericTypographic(GpStringFormat **forma
|
|||
(*format)->hkprefix = HotkeyPrefixNone;
|
||||
(*format)->align = StringAlignmentNear;
|
||||
(*format)->vertalign = StringAlignmentNear;
|
||||
(*format)->generic_typographic = TRUE;
|
||||
|
||||
TRACE("%p => %p\n", format, *format);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
|
|
@ -299,13 +299,6 @@ enum HotkeyPrefix
|
|||
HotkeyPrefixHide = 2
|
||||
};
|
||||
|
||||
enum PaletteFlags
|
||||
{
|
||||
PaletteFlagsHasAlpha = 1,
|
||||
PaletteFlagsGrayScale = 2,
|
||||
PaletteFlagsHalftone = 4
|
||||
};
|
||||
|
||||
enum ImageCodecFlags
|
||||
{
|
||||
ImageCodecFlagsEncoder = 1,
|
||||
|
|
|
@ -364,6 +364,9 @@ typedef struct PropertyItem
|
|||
|
||||
#define PropertyTagFrameDelay 0x5100
|
||||
#define PropertyTagLoopCount 0x5101
|
||||
#define PropertyTagGlobalPalette 0x5102
|
||||
#define PropertyTagIndexBackground 0x5103
|
||||
#define PropertyTagIndexTransparent 0x5104
|
||||
|
||||
#define PropertyTagPixelUnit 0x5110
|
||||
#define PropertyTagPixelPerUnitX 0x5111
|
||||
|
|
|
@ -46,7 +46,40 @@ typedef INT PixelFormat;
|
|||
#define PixelFormat48bppRGB (12 | (48 << 8) | PixelFormatExtended)
|
||||
#define PixelFormat64bppARGB (13 | (64 << 8) | PixelFormatAlpha | PixelFormatCanonical | PixelFormatExtended)
|
||||
#define PixelFormat64bppPARGB (14 | (64 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatExtended)
|
||||
#define PixelFormatMax 15
|
||||
#define PixelFormat32bppCMYK (15 | (32 << 8))
|
||||
#define PixelFormatMax 16
|
||||
|
||||
static inline BOOL IsIndexedPixelFormat(PixelFormat format)
|
||||
{
|
||||
return (format & PixelFormatIndexed) != 0;
|
||||
}
|
||||
|
||||
static inline BOOL IsAlphaPixelFormat(PixelFormat format)
|
||||
{
|
||||
return (format & PixelFormatAlpha) != 0;
|
||||
}
|
||||
|
||||
static inline BOOL IsCanonicalPixelFormat(PixelFormat format)
|
||||
{
|
||||
return (format & PixelFormatCanonical) != 0;
|
||||
}
|
||||
|
||||
static inline BOOL IsExtendedPixelFormat(PixelFormat format)
|
||||
{
|
||||
return (format & PixelFormatExtended) != 0;
|
||||
}
|
||||
|
||||
static inline UINT GetPixelFormatSize(PixelFormat format)
|
||||
{
|
||||
return (format >> 8) & 0xff;
|
||||
}
|
||||
|
||||
enum PaletteFlags
|
||||
{
|
||||
PaletteFlagsHasAlpha = 1,
|
||||
PaletteFlagsGrayScale = 2,
|
||||
PaletteFlagsHalftone = 4
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
|
|
Loading…
Reference in a new issue