From 69720151910bf4497cf0008e5c9579f7a2c0501e Mon Sep 17 00:00:00 2001 From: Dmitry Chapyshev Date: Wed, 2 Jul 2008 08:19:00 +0000 Subject: [PATCH] - Sync with Wine HEAD svn path=/trunk/; revision=34251 --- reactos/dll/win32/gdiplus/brush.c | 14 + reactos/dll/win32/gdiplus/font.c | 385 ++++++++++++++++++++ reactos/dll/win32/gdiplus/gdiplus.spec | 76 ++-- reactos/dll/win32/gdiplus/gdiplus_private.h | 11 + reactos/dll/win32/gdiplus/graphics.c | 47 +++ reactos/dll/win32/gdiplus/graphicspath.c | 171 +++++++++ reactos/dll/win32/gdiplus/image.c | 41 ++- reactos/dll/win32/gdiplus/imageattributes.c | 11 + reactos/dll/win32/gdiplus/pathiterator.c | 10 + reactos/dll/win32/gdiplus/pen.c | 81 +++- reactos/dll/win32/gdiplus/region.c | 51 +++ 11 files changed, 849 insertions(+), 49 deletions(-) diff --git a/reactos/dll/win32/gdiplus/brush.c b/reactos/dll/win32/gdiplus/brush.c index aa740fc4860..328f02c6626 100644 --- a/reactos/dll/win32/gdiplus/brush.c +++ b/reactos/dll/win32/gdiplus/brush.c @@ -555,6 +555,17 @@ GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient return NotImplemented; } +GpStatus WINGDIPAPI GdipGetPathGradientWrapMode(GpPathGradient *brush, + GpWrapMode *wrapmode) +{ + if(!brush || !wrapmode) + return InvalidParameter; + + *wrapmode = brush->wrap; + + return Ok; +} + GpStatus WINGDIPAPI GdipGetSolidFillColor(GpSolidFill *sf, ARGB *argb) { if(!sf || !argb) @@ -822,6 +833,9 @@ GpStatus WINGDIPAPI GdipGetLineRectI(GpLineGradient *brush, GpRect *rect) GpRectF rectF; GpStatus ret; + if(!rect) + return InvalidParameter; + ret = GdipGetLineRect(brush, &rectF); if(ret == Ok){ diff --git a/reactos/dll/win32/gdiplus/font.c b/reactos/dll/win32/gdiplus/font.c index 82523cea4c6..98a4c43dc80 100644 --- a/reactos/dll/win32/gdiplus/font.c +++ b/reactos/dll/win32/gdiplus/font.c @@ -22,12 +22,141 @@ #include "winbase.h" #include "wingdi.h" #include "winnls.h" +#include "winreg.h" +#include "wine/debug.h" +#include "wine/unicode.h" + +WINE_DEFAULT_DEBUG_CHANNEL (gdiplus); #include "objbase.h" #include "gdiplus.h" #include "gdiplus_private.h" +static const REAL mm_per_inch = 25.4; +static const REAL inch_per_point = 1.0/72.0; + +static inline REAL get_dpi (void) +{ + REAL dpi; + GpGraphics *graphics; + HDC hdc = GetDC(0); + GdipCreateFromHDC (hdc, &graphics); + GdipGetDpiX(graphics, &dpi); + GdipDeleteGraphics(graphics); + ReleaseDC (0, hdc); + + return dpi; +} + +static inline REAL point_to_pixel (REAL point) +{ + return point * get_dpi() * inch_per_point; +} + +static inline REAL inch_to_pixel (REAL inch) +{ + return inch * get_dpi(); +} + +static inline REAL document_to_pixel (REAL doc) +{ + return doc * (get_dpi() / 300.0); /* Per MSDN */ +} + +static inline REAL mm_to_pixel (REAL mm) +{ + return mm * (get_dpi() / mm_per_inch); +} + +/******************************************************************************* + * GdipCreateFont [GDIPLUS.@] + * + * Create a new font based off of a FontFamily + * + * PARAMS + * *fontFamily [I] Family to base the font off of + * emSize [I] Size of the font + * style [I] Bitwise OR of FontStyle enumeration + * unit [I] Unit emSize is measured in + * **font [I] the resulting Font object + * + * RETURNS + * SUCCESS: Ok + * FAILURE: InvalidParameter if fontfamily or font is NULL. + * FAILURE: FontFamilyNotFound if an invalid FontFamily is given + * + * NOTES + * UnitDisplay is unsupported. + * emSize is stored separately from lfHeight, to hold the fraction. + */ +GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily, + REAL emSize, INT style, Unit unit, GpFont **font) +{ + WCHAR facename[LF_FACESIZE]; + LOGFONTW* lfw; + const TEXTMETRICW* tmw; + GpStatus stat; + + if (!fontFamily || !fontFamily->FamilyName || !font) + return InvalidParameter; + + TRACE("%p (%s), %f, %d, %d, %p\n", fontFamily, + debugstr_w(fontFamily->FamilyName), emSize, style, unit, font); + + stat = GdipGetFamilyName (fontFamily, facename, 0); + if (stat != Ok) return stat; + *font = GdipAlloc(sizeof(GpFont)); + + tmw = &fontFamily->tmw; + lfw = &((*font)->lfw); + ZeroMemory(&(*lfw), sizeof(*lfw)); + + lfw->lfWeight = tmw->tmWeight; + lfw->lfItalic = tmw->tmItalic; + lfw->lfUnderline = tmw->tmUnderlined; + lfw->lfStrikeOut = tmw->tmStruckOut; + lfw->lfCharSet = tmw->tmCharSet; + lfw->lfPitchAndFamily = tmw->tmPitchAndFamily; + lstrcpynW((lfw->lfFaceName), facename, sizeof(WCHAR) * LF_FACESIZE); + + switch (unit) + { + case UnitWorld: + /* FIXME: Figure out when World != Pixel */ + lfw->lfHeight = emSize; break; + 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 */ + lfw->lfHeight = 0; break; + case UnitPixel: + lfw->lfHeight = emSize; break; + case UnitPoint: + lfw->lfHeight = point_to_pixel(emSize); break; + case UnitInch: + lfw->lfHeight = inch_to_pixel(emSize); break; + case UnitDocument: + lfw->lfHeight = document_to_pixel(emSize); break; + case UnitMillimeter: + lfw->lfHeight = mm_to_pixel(emSize); break; + } + + lfw->lfHeight *= -1; + + lfw->lfWeight = style & FontStyleBold ? 700 : 400; + lfw->lfItalic = style & FontStyleItalic; + lfw->lfUnderline = style & FontStyleUnderline; + lfw->lfStrikeOut = style & FontStyleStrikeout; + + (*font)->unit = unit; + (*font)->emSize = emSize; + + return Ok; +} + GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc, GDIPCONST LOGFONTW *logfont, GpFont **font) { @@ -47,6 +176,9 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc, (*font)->lfw.lfUnderline = logfont->lfUnderline; (*font)->lfw.lfStrikeOut = logfont->lfStrikeOut; + (*font)->emSize = logfont->lfHeight; + (*font)->unit = UnitPixel; + hfont = CreateFontIndirectW(&(*font)->lfw); oldfont = SelectObject(hdc, hfont); GetTextMetricsW(hdc, &textmet); @@ -106,6 +238,51 @@ GpStatus WINGDIPAPI GdipCreateFontFromDC(HDC hdc, GpFont **font) return GdipCreateFontFromLogfontW(hdc, &lfw, font); } +/****************************************************************************** + * GdipGetFontSize [GDIPLUS.@] + * + * Returns the size of the font in Units + * + * PARAMS + * *font [I] The font to retrieve size from + * *size [O] Pointer to hold retrieved value + * + * RETURNS + * SUCCESS: Ok + * FAILURE: InvalidParamter (font or size was NULL) + * + * NOTES + * Size returned is actually emSize -- not internal size used for drawing. + */ +GpStatus WINGDIPAPI GdipGetFontSize(GpFont *font, REAL *size) +{ + if (!(font && size)) return InvalidParameter; + + *size = font->emSize; + + return Ok; +} + +/******************************************************************************* + * GdipGetFontUnit [GDIPLUS.@] + * + * PARAMS + * font [I] Font to retrieve from + * unit [O] Return value + * + * RETURNS + * FAILURE: font or unit was NULL + * OK: otherwise + */ +GpStatus WINGDIPAPI GdipGetFontUnit(GpFont *font, Unit *unit) +{ + if (!(font && unit)) return InvalidParameter; + + *unit = font->unit; + + return Ok; +} + /* FIXME: use graphics */ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics, LOGFONTW *lfw) @@ -130,3 +307,211 @@ GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont) return Ok; } + +/* Borrowed from GDI32 */ +static INT CALLBACK is_font_installed_proc(const LOGFONTW *elf, + const TEXTMETRICW *ntm, DWORD type, LPARAM lParam) +{ + return 0; +} + +static BOOL is_font_installed(const WCHAR *name) +{ + HDC hdc = GetDC(0); + BOOL ret = FALSE; + + if(!EnumFontFamiliesW(hdc, name, is_font_installed_proc, 0)) + ret = TRUE; + + ReleaseDC(0, hdc); + return ret; +} + +/******************************************************************************* + * GdipCreateFontFamilyFromName [GDIPLUS.@] + * + * Creates a font family object based on a supplied name + * + * PARAMS + * name [I] Name of the font + * fontCollection [I] What font collection (if any) the font belongs to (may be NULL) + * FontFamily [O] Pointer to the resulting FontFamily object + * + * RETURNS + * SUCCESS: Ok + * FAILURE: FamilyNotFound if the requested FontFamily does not exist on the system + * FAILURE: Invalid parameter if FontFamily or name is NULL + * + * NOTES + * If fontCollection is NULL then the object is not part of any collection + * + */ + +GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name, + GpFontCollection *fontCollection, + GpFontFamily **FontFamily) +{ + GpFontFamily* ffamily; + HDC hdc; + HFONT hFont, hfont_old; + LOGFONTW lfw; + + TRACE("%s, %p %p\n", debugstr_w(name), fontCollection, FontFamily); + + if (!(name && FontFamily)) + return InvalidParameter; + if (fontCollection) + FIXME("No support for FontCollections yet!\n"); + if (!is_font_installed(name)) + return FontFamilyNotFound; + + ffamily = GdipAlloc(sizeof (GpFontFamily)); + if (!ffamily) return OutOfMemory; + + hdc = GetDC(0); + lstrcpynW(lfw.lfFaceName, name, sizeof(WCHAR) * LF_FACESIZE); + hFont = CreateFontIndirectW (&lfw); + hfont_old = SelectObject(hdc, hFont); + + GetTextMetricsW(hdc, &ffamily->tmw); + DeleteObject(SelectObject(hdc, hfont_old)); + + ffamily->FamilyName = GdipAlloc(LF_FACESIZE * sizeof (WCHAR)); + if (!ffamily->FamilyName) + { + GdipFree(ffamily); + ReleaseDC(0, hdc); + return OutOfMemory; + } + + lstrcpynW(ffamily->FamilyName, name, sizeof(WCHAR) * LF_FACESIZE); + + *FontFamily = ffamily; + ReleaseDC(0, hdc); + + return Ok; +} + +/******************************************************************************* + * GdipGetFamilyName [GDIPLUS.@] + * + * Returns the family name into name + * + * PARAMS + * *family [I] Family to retrieve from + * *name [O] WCHARS of the family name + * LANGID [I] charset + * + * RETURNS + * SUCCESS: Ok + * 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) + */ +GpStatus WINGDIPAPI GdipGetFamilyName (GDIPCONST GpFontFamily *family, + WCHAR *name, LANGID language) +{ + if (family == NULL) + return InvalidParameter; + + TRACE("%p, %p, %d\n", family, name, language); + + if (language != LANG_NEUTRAL) + FIXME("No support for handling of multiple languages!\n"); + + lstrcpynW (name, family->FamilyName, LF_FACESIZE); + + return Ok; +} + + +/***************************************************************************** + * GdipDeleteFontFamily [GDIPLUS.@] + * + * Removes the specified FontFamily + * + * PARAMS + * *FontFamily [I] The family to delete + * + * RETURNS + * SUCCESS: Ok + * FAILURE: InvalidParameter if FontFamily is NULL. + * + */ +GpStatus WINGDIPAPI GdipDeleteFontFamily(GpFontFamily *FontFamily) +{ + if (!FontFamily) + return InvalidParameter; + TRACE("Deleting %p (%s)\n", FontFamily, debugstr_w(FontFamily->FamilyName)); + + if (FontFamily->FamilyName) GdipFree (FontFamily->FamilyName); + GdipFree (FontFamily); + + return Ok; +} + +/***************************************************************************** + * GdipGetGenericFontFamilyMonospace [GDIPLUS.@] + * + * Obtains a serif family (Courier New on Windows) + * + * PARAMS + * **nativeFamily [I] Where the font will be stored + * + * RETURNS + * InvalidParameter if nativeFamily is NULL. + * Ok otherwise. + */ +GpStatus WINGDIPAPI GdipGetGenericFontFamilyMonospace(GpFontFamily **nativeFamily) +{ + static const WCHAR CourierNew[] = {'C','o','u','r','i','e','r',' ','N','e','w','\0'}; + + if (nativeFamily == NULL) return InvalidParameter; + + return GdipCreateFontFamilyFromName(CourierNew, NULL, nativeFamily); +} + +/***************************************************************************** + * GdipGetGenericFontFamilySerif [GDIPLUS.@] + * + * Obtains a serif family (Times New Roman on Windows) + * + * PARAMS + * **nativeFamily [I] Where the font will be stored + * + * RETURNS + * InvalidParameter if nativeFamily is NULL. + * Ok otherwise. + */ +GpStatus WINGDIPAPI GdipGetGenericFontFamilySerif(GpFontFamily **nativeFamily) +{ + static const WCHAR TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'}; + + if (nativeFamily == NULL) return InvalidParameter; + + return GdipCreateFontFamilyFromName(TimesNewRoman, NULL, nativeFamily); +} + +/***************************************************************************** + * GdipGetGenericFontFamilySansSerif [GDIPLUS.@] + * + * Obtains a serif family (Microsoft Sans Serif on Windows) + * + * PARAMS + * **nativeFamily [I] Where the font will be stored + * + * RETURNS + * InvalidParameter if nativeFamily is NULL. + * Ok otherwise. + */ +GpStatus WINGDIPAPI GdipGetGenericFontFamilySansSerif(GpFontFamily **nativeFamily) +{ + /* FIXME: On Windows this is called Microsoft Sans Serif, this shouldn't + * affect anything */ + static const WCHAR MSSansSerif[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'}; + + if (nativeFamily == NULL) return InvalidParameter; + + return GdipCreateFontFamilyFromName(MSSansSerif, NULL, nativeFamily); +} diff --git a/reactos/dll/win32/gdiplus/gdiplus.spec b/reactos/dll/win32/gdiplus/gdiplus.spec index f2eb2b3a451..587f2ab1cd3 100644 --- a/reactos/dll/win32/gdiplus/gdiplus.spec +++ b/reactos/dll/win32/gdiplus/gdiplus.spec @@ -23,12 +23,12 @@ @ stdcall GdipAddPathPath(ptr ptr long) @ stub GdipAddPathPie @ stub GdipAddPathPieI -@ stub GdipAddPathPolygon -@ stub GdipAddPathPolygonI +@ stdcall GdipAddPathPolygon(ptr ptr long) +@ stdcall GdipAddPathPolygonI(ptr ptr long) @ stdcall GdipAddPathRectangle(ptr long long long long) @ stdcall GdipAddPathRectangleI(ptr long long long long) -@ stub GdipAddPathRectangles -@ stub GdipAddPathRectanglesI +@ stdcall GdipAddPathRectangles(ptr ptr long) +@ stdcall GdipAddPathRectanglesI(ptr ptr long) @ stub GdipAddPathString @ stub GdipAddPathStringI @ stdcall GdipAlloc(long) @@ -45,7 +45,7 @@ @ stub GdipBitmapSetPixel @ stub GdipBitmapSetResolution @ stdcall GdipBitmapUnlockBits(ptr ptr) -@ stub GdipClearPathMarkers +@ stdcall GdipClearPathMarkers(ptr) @ stub GdipCloneBitmapArea @ stub GdipCloneBitmapAreaI @ stdcall GdipCloneBrush(ptr ptr) @@ -53,7 +53,7 @@ @ stdcall GdipCloneFont(ptr ptr) @ stub GdipCloneFontFamily @ stub GdipCloneImage -@ stub GdipCloneImageAttributes +@ stdcall GdipCloneImageAttributes(ptr ptr) @ stdcall GdipCloneMatrix(ptr ptr) @ stdcall GdipClonePath(ptr ptr) @ stdcall GdipClonePen(ptr ptr) @@ -62,9 +62,9 @@ @ stdcall GdipClosePathFigure(ptr) @ stdcall GdipClosePathFigures(ptr) @ stub GdipCombineRegionPath -@ stub GdipCombineRegionRect -@ stub GdipCombineRegionRectI -@ stub GdipCombineRegionRegion +@ stdcall GdipCombineRegionRect(ptr ptr long) +@ stdcall GdipCombineRegionRectI(ptr ptr long) +@ stdcall GdipCombineRegionRegion(ptr ptr long) @ stub GdipComment @ stdcall GdipConvertToEmfPlus(ptr ptr ptr long ptr ptr) @ stub GdipConvertToEmfPlusToFile @@ -84,8 +84,8 @@ @ stub GdipCreateCachedBitmap @ stdcall GdipCreateCustomLineCap(ptr ptr long long ptr) @ stub GdipCreateEffect -@ stub GdipCreateFont -@ stub GdipCreateFontFamilyFromName +@ stdcall GdipCreateFont(ptr long long long ptr) +@ stdcall GdipCreateFontFamilyFromName(wstr ptr ptr) @ stdcall GdipCreateFontFromDC(long ptr) @ stdcall GdipCreateFontFromLogfontA(long ptr ptr) @ stdcall GdipCreateFontFromLogfontW(long ptr ptr) @@ -125,8 +125,8 @@ @ stdcall GdipCreateRegion(ptr) @ stub GdipCreateRegionHrgn @ stdcall GdipCreateRegionPath(ptr ptr) -@ stub GdipCreateRegionRect -@ stub GdipCreateRegionRectI +@ stdcall GdipCreateRegionRect(ptr ptr) +@ stdcall GdipCreateRegionRectI(ptr ptr) @ stub GdipCreateRegionRgnData @ stdcall GdipCreateSolidFill(long ptr) @ stdcall GdipCreateStreamOnFile(ptr long ptr) @@ -141,7 +141,7 @@ @ stdcall GdipDeleteCustomLineCap(ptr) @ stub GdipDeleteEffect @ stdcall GdipDeleteFont(ptr) -@ stub GdipDeleteFontFamily +@ stdcall GdipDeleteFontFamily(ptr) @ stdcall GdipDeleteGraphics(ptr) @ stdcall GdipDeleteMatrix(ptr) @ stdcall GdipDeletePath(ptr) @@ -170,8 +170,8 @@ @ stdcall GdipDrawCurve(ptr ptr ptr long) @ stdcall GdipDrawCurveI(ptr ptr ptr long) @ stub GdipDrawDriverString -@ stub GdipDrawEllipse -@ stub GdipDrawEllipseI +@ stdcall GdipDrawEllipse(ptr ptr long long long long) +@ stdcall GdipDrawEllipseI(ptr ptr long long long long) @ stdcall GdipDrawImage(ptr ptr long long) @ stub GdipDrawImageFX @ stdcall GdipDrawImageI(ptr ptr long long) @@ -234,7 +234,7 @@ @ stdcall GdipFindFirstImageItem(ptr ptr) @ stub GdipFindNextImageItem @ stub GdipFlattenPath -@ stub GdipFlush +@ stdcall GdipFlush(ptr long) @ stdcall GdipFree(ptr) @ stub GdipGetAdjustableArrowCapFillState @ stub GdipGetAdjustableArrowCapHeight @@ -264,17 +264,17 @@ @ stub GdipGetEncoderParameterList @ stub GdipGetEncoderParameterListSize @ stub GdipGetFamily -@ stub GdipGetFamilyName +@ stdcall GdipGetFamilyName(ptr ptr long) @ stub GdipGetFontCollectionFamilyCount @ stub GdipGetFontCollectionFamilyList @ stub GdipGetFontHeight @ stub GdipGetFontHeightGivenDPI -@ stub GdipGetFontSize +@ stdcall GdipGetFontSize(ptr ptr) @ stub GdipGetFontStyle -@ stub GdipGetFontUnit -@ stub GdipGetGenericFontFamilyMonospace -@ stub GdipGetGenericFontFamilySansSerif -@ stub GdipGetGenericFontFamilySerif +@ stdcall GdipGetFontUnit(ptr ptr) +@ stdcall GdipGetGenericFontFamilyMonospace(ptr) +@ stdcall GdipGetGenericFontFamilySansSerif(ptr) +@ stdcall GdipGetGenericFontFamilySerif(ptr) @ stub GdipGetHatchBackgroundColor @ stub GdipGetHatchForegroundColor @ stub GdipGetHatchStyle @@ -323,7 +323,7 @@ @ stub GdipGetNearestColor @ stdcall GdipGetPageScale(ptr ptr) @ stdcall GdipGetPageUnit(ptr ptr) -@ stub GdipGetPathData +@ stdcall GdipGetPathData(ptr ptr) @ stdcall GdipGetPathFillMode(ptr ptr) @ stub GdipGetPathGradientBlend @ stub GdipGetPathGradientBlendCount @@ -341,8 +341,8 @@ @ stub GdipGetPathGradientSurroundColorCount @ stdcall GdipGetPathGradientSurroundColorsWithCount(ptr ptr ptr) @ stub GdipGetPathGradientTransform -@ stub GdipGetPathGradientWrapMode -@ stub GdipGetPathLastPoint +@ stdcall GdipGetPathGradientWrapMode(ptr ptr) +@ stdcall GdipGetPathLastPoint(ptr ptr) @ stdcall GdipGetPathPoints(ptr ptr long) @ stdcall GdipGetPathPointsI(ptr ptr long) @ stdcall GdipGetPathTypes(ptr ptr long) @@ -355,19 +355,19 @@ @ stub GdipGetPenCustomEndCap @ stub GdipGetPenCustomStartCap @ stdcall GdipGetPenDashArray(ptr ptr long) -@ stub GdipGetPenDashCap197819 +@ stdcall GdipGetPenDashCap197819(ptr ptr) @ stub GdipGetPenDashCount @ stdcall GdipGetPenDashOffset(ptr ptr) @ stdcall GdipGetPenDashStyle(ptr ptr) -@ stub GdipGetPenEndCap +@ stdcall GdipGetPenEndCap(ptr ptr) @ stub GdipGetPenFillType -@ stub GdipGetPenLineJoin -@ stub GdipGetPenMiterLimit +@ stdcall GdipGetPenLineJoin(ptr ptr) +@ stdcall GdipGetPenMiterLimit(ptr ptr) @ stub GdipGetPenMode -@ stub GdipGetPenStartCap +@ stdcall GdipGetPenStartCap(ptr ptr) @ stub GdipGetPenTransform -@ stub GdipGetPenUnit -@ stub GdipGetPenWidth +@ stdcall GdipGetPenUnit(ptr ptr) +@ stdcall GdipGetPenWidth(ptr ptr) @ stdcall GdipGetPixelOffsetMode(ptr ptr) @ stdcall GdipGetPointCount(ptr ptr) @ stub GdipGetPropertyCount @@ -377,8 +377,8 @@ @ stub GdipGetPropertySize @ stub GdipGetRegionBounds @ stub GdipGetRegionBoundsI -@ stub GdipGetRegionData -@ stub GdipGetRegionDataSize +@ stdcall GdipGetRegionData(ptr ptr long ptr) +@ stdcall GdipGetRegionDataSize(ptr ptr) @ stdcall GdipGetRegionHRgn(ptr ptr ptr) @ stub GdipGetRegionScans @ stub GdipGetRegionScansCount @@ -407,7 +407,7 @@ @ stub GdipGraphicsSetAbort @ stub GdipImageForceValidation @ stdcall GdipImageGetFrameCount(ptr ptr ptr) -@ stub GdipImageGetFrameDimensionsCount +@ stdcall GdipImageGetFrameDimensionsCount(ptr ptr) @ stdcall GdipImageGetFrameDimensionsList(ptr ptr long) @ stub GdipImageRotateFlip @ stdcall GdipImageSelectActiveFrame(ptr ptr long) @@ -452,7 +452,7 @@ @ stub GdipNewPrivateFontCollection @ stdcall GdipPathIterCopyData(ptr ptr ptr ptr long long) @ stub GdipPathIterEnumerate -@ stub GdipPathIterGetCount +@ stdcall GdipPathIterGetCount(ptr ptr) @ stub GdipPathIterGetSubpathCount @ stub GdipPathIterHasCurve @ stub GdipPathIterIsValid @@ -561,7 +561,7 @@ @ stdcall GdipSetPathGradientSurroundColorsWithCount(ptr ptr ptr) @ stub GdipSetPathGradientTransform @ stdcall GdipSetPathGradientWrapMode(ptr long) -@ stub GdipSetPathMarker +@ stdcall GdipSetPathMarker(ptr) @ stdcall GdipSetPenBrushFill(ptr ptr) @ stdcall GdipSetPenColor(ptr long) @ stub GdipSetPenCompoundArray diff --git a/reactos/dll/win32/gdiplus/gdiplus_private.h b/reactos/dll/win32/gdiplus/gdiplus_private.h index d2d0373656b..ed763752575 100644 --- a/reactos/dll/win32/gdiplus/gdiplus_private.h +++ b/reactos/dll/win32/gdiplus/gdiplus_private.h @@ -174,6 +174,8 @@ struct GpImageAttributes{ struct GpFont{ LOGFONTW lfw; + REAL emSize; + Unit unit; }; struct GpStringFormat{ @@ -185,4 +187,13 @@ struct GpStringFormat{ StringAlignment vertalign; }; +struct GpFontCollection{ + GpFontFamily* FontFamilies; +}; + +struct GpFontFamily{ + TEXTMETRICW tmw; + WCHAR* FamilyName; +}; + #endif diff --git a/reactos/dll/win32/gdiplus/graphics.c b/reactos/dll/win32/gdiplus/graphics.c index 347543f5e8e..7103f2e70d5 100644 --- a/reactos/dll/win32/gdiplus/graphics.c +++ b/reactos/dll/win32/gdiplus/graphics.c @@ -1106,6 +1106,40 @@ GpStatus WINGDIPAPI GdipDrawCurve2I(GpGraphics *graphics, GpPen *pen, return ret; } +GpStatus WINGDIPAPI GdipDrawEllipse(GpGraphics *graphics, GpPen *pen, REAL x, + REAL y, REAL width, REAL height) +{ + INT save_state; + GpPointF ptf[2]; + POINT pti[2]; + + if(!graphics || !pen) + return InvalidParameter; + + ptf[0].X = x; + ptf[0].Y = y; + ptf[1].X = x + width; + ptf[1].Y = y + height; + + save_state = prepare_dc(graphics, pen); + SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH)); + + transform_and_round_points(graphics, pti, ptf, 2); + + Ellipse(graphics->hdc, pti[0].x, pti[0].y, pti[1].x, pti[1].y); + + restore_dc(graphics, save_state); + + return Ok; +} + +GpStatus WINGDIPAPI GdipDrawEllipseI(GpGraphics *graphics, GpPen *pen, INT x, + INT y, INT width, INT height) +{ + return GdipDrawEllipse(graphics,pen,(REAL)x,(REAL)y,(REAL)width,(REAL)height); +} + + GpStatus WINGDIPAPI GdipDrawImage(GpGraphics *graphics, GpImage *image, REAL x, REAL y) { /* IPicture::Render uses LONG coords */ @@ -1957,6 +1991,19 @@ GpStatus WINGDIPAPI GdipFillRectanglesI(GpGraphics *graphics, GpBrush *brush, GD return ret; } +GpStatus WINGDIPAPI GdipFlush(GpGraphics *graphics, GpFlushIntention intention) +{ + static int calls; + + if(!graphics) + return InvalidParameter; + + if(!(calls++)) + FIXME("not implemented\n"); + + return NotImplemented; +} + /* FIXME: Compositing mode is not used anywhere except the getter/setter. */ GpStatus WINGDIPAPI GdipGetCompositingMode(GpGraphics *graphics, CompositingMode *mode) diff --git a/reactos/dll/win32/gdiplus/graphicspath.c b/reactos/dll/win32/gdiplus/graphicspath.c index 3b09e04f37e..6e5747ff049 100644 --- a/reactos/dll/win32/gdiplus/graphicspath.c +++ b/reactos/dll/win32/gdiplus/graphicspath.c @@ -346,6 +346,55 @@ GpStatus WINGDIPAPI GdipAddPathPath(GpPath *path, GDIPCONST GpPath* addingPath, return Ok; } +GpStatus WINGDIPAPI GdipAddPathPolygon(GpPath *path, GDIPCONST GpPointF *points, INT count) +{ + INT old_count; + + if(!path || !points || count < 3) + return InvalidParameter; + + if(!lengthen_path(path, count)) + return OutOfMemory; + + old_count = path->pathdata.Count; + + memcpy(&path->pathdata.Points[old_count], points, count*sizeof(GpPointF)); + memset(&path->pathdata.Types[old_count + 1], PathPointTypeLine, count - 1); + + /* A polygon is an intrinsic figure */ + path->pathdata.Types[old_count] = PathPointTypeStart; + path->pathdata.Types[old_count + count - 1] |= PathPointTypeCloseSubpath; + path->newfigure = TRUE; + path->pathdata.Count += count; + + return Ok; +} + +GpStatus WINGDIPAPI GdipAddPathPolygonI(GpPath *path, GDIPCONST GpPoint *points, INT count) +{ + GpPointF *ptf; + GpStatus status; + INT i; + + if(!points || count < 3) + return InvalidParameter; + + ptf = GdipAlloc(sizeof(GpPointF) * count); + if(!ptf) + return OutOfMemory; + + for(i = 0; i < count; i++){ + ptf[i].X = (REAL)points[i].X; + ptf[i].Y = (REAL)points[i].Y; + } + + status = GdipAddPathPolygon(path, ptf, count); + + GdipFree(ptf); + + return status; +} + GpStatus WINGDIPAPI GdipClonePath(GpPath* path, GpPath **clone) { if(!path || !clone) @@ -479,6 +528,19 @@ GpStatus WINGDIPAPI GdipDeletePath(GpPath *path) return Ok; } +GpStatus WINGDIPAPI GdipGetPathData(GpPath *path, GpPathData* pathData) +{ + if(!path || !pathData) + return InvalidParameter; + + /* Only copy data. pathData allocation/freeing controlled by wrapper class. + Assumed that pathData is enough wide to get all data - controlled by wrapper too. */ + memcpy(pathData->Points, path->pathdata.Points, sizeof(PointF) * pathData->Count); + memcpy(pathData->Types , path->pathdata.Types , pathData->Count); + + return Ok; +} + GpStatus WINGDIPAPI GdipGetPathFillMode(GpPath *path, GpFillMode *fillmode) { if(!path || !fillmode) @@ -489,6 +551,20 @@ GpStatus WINGDIPAPI GdipGetPathFillMode(GpPath *path, GpFillMode *fillmode) return Ok; } +GpStatus WINGDIPAPI GdipGetPathLastPoint(GpPath* path, GpPointF* lastPoint) +{ + INT count; + + if(!path || !lastPoint) + return InvalidParameter; + + count = path->pathdata.Count; + if(count > 0) + *lastPoint = path->pathdata.Points[count-1]; + + return Ok; +} + GpStatus WINGDIPAPI GdipGetPathPoints(GpPath *path, GpPointF* points, INT count) { if(!path) @@ -758,3 +834,98 @@ GpStatus WINGDIPAPI GdipAddPathRectangleI(GpPath *path, INT x, INT y, { return GdipAddPathRectangle(path,(REAL)x,(REAL)y,(REAL)width,(REAL)height); } + +GpStatus WINGDIPAPI GdipAddPathRectangles(GpPath *path, GDIPCONST GpRectF *rects, INT count) +{ + GpPath *backup; + GpStatus retstat; + INT i; + + /* count == 0 - verified condition */ + if(!path || !rects || count == 0) + return InvalidParameter; + + if(count < 0) + return OutOfMemory; + + /* make a backup copy */ + if((retstat = GdipClonePath(path, &backup)) != Ok) + return retstat; + + for(i = 0; i < count; i++){ + if((retstat = GdipAddPathRectangle(path,rects[i].X,rects[i].Y,rects[i].Width,rects[i].Height)) != Ok) + goto fail; + } + + /* free backup */ + GdipDeletePath(backup); + return Ok; + +fail: + /* reverting */ + GdipDeletePath(path); + GdipClonePath(backup, &path); + GdipDeletePath(backup); + + return retstat; +} + +GpStatus WINGDIPAPI GdipAddPathRectanglesI(GpPath *path, GDIPCONST GpRect *rects, INT count) +{ + GpRectF *rectsF; + GpStatus retstat; + INT i; + + if(!rects || count == 0) + return InvalidParameter; + + if(count < 0) + return OutOfMemory; + + rectsF = GdipAlloc(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; + } + + retstat = GdipAddPathRectangles(path, rectsF, count); + GdipFree(rectsF); + + return retstat; +} + +GpStatus WINGDIPAPI GdipSetPathMarker(GpPath* path) +{ + INT count; + + if(!path) + return InvalidParameter; + + count = path->pathdata.Count; + + /* set marker flag */ + if(count > 0) + path->pathdata.Types[count-1] |= PathPointTypePathMarker; + + return Ok; +} + +GpStatus WINGDIPAPI GdipClearPathMarkers(GpPath* path) +{ + INT count; + INT i; + + if(!path) + return InvalidParameter; + + count = path->pathdata.Count; + + for(i = 0; i < count - 1; i++){ + path->pathdata.Types[i] &= ~PathPointTypePathMarker; + } + + return Ok; +} diff --git a/reactos/dll/win32/gdiplus/image.c b/reactos/dll/win32/gdiplus/image.c index 72bf7f509bf..330e54bfb03 100644 --- a/reactos/dll/win32/gdiplus/image.c +++ b/reactos/dll/win32/gdiplus/image.c @@ -101,15 +101,25 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect, BITMAPINFO bmi; BYTE *buff = NULL; UINT abs_height; + GpRect act_rect; /* actual rect to be used */ TRACE("%p %p %d %d %p\n", bitmap, rect, flags, format, lockeddata); - if(!lockeddata || !bitmap || !rect) + if(!lockeddata || !bitmap) return InvalidParameter; - if(rect->X < 0 || rect->Y < 0 || (rect->X + rect->Width > bitmap->width) || - (rect->Y + rect->Height > bitmap->height) || !flags) - return InvalidParameter; + if(rect){ + if(rect->X < 0 || rect->Y < 0 || (rect->X + rect->Width > bitmap->width) || + (rect->Y + rect->Height > bitmap->height) || !flags) + return InvalidParameter; + + act_rect = *rect; + } + else{ + act_rect.X = act_rect.Y = 0; + act_rect.Width = bitmap->width; + act_rect.Height = bitmap->height; + } if(flags & ImageLockModeUserInputBuf) return NotImplemented; @@ -151,19 +161,19 @@ GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap* bitmap, GDIPCONST GpRect* rect, if(!buff) return OutOfMemory; - lockeddata->Width = rect->Width; - lockeddata->Height = rect->Height; + lockeddata->Width = act_rect.Width; + lockeddata->Height = act_rect.Height; lockeddata->PixelFormat = format; lockeddata->Reserved = flags; if(bmi.bmiHeader.biHeight > 0){ lockeddata->Stride = -stride; - lockeddata->Scan0 = buff + (bitspp / 8) * rect->X + - stride * (abs_height - 1 - rect->Y); + lockeddata->Scan0 = buff + (bitspp / 8) * act_rect.X + + stride * (abs_height - 1 - act_rect.Y); } else{ lockeddata->Stride = stride; - lockeddata->Scan0 = buff + (bitspp / 8) * rect->X + stride * rect->Y; + lockeddata->Scan0 = buff + (bitspp / 8) * act_rect.X + stride * act_rect.Y; } bitmap->lockmode = flags; @@ -678,6 +688,19 @@ GpStatus WINGDIPAPI GdipImageGetFrameCount(GpImage *image, return NotImplemented; } +GpStatus WINGDIPAPI GdipImageGetFrameDimensionsCount(GpImage *image, + UINT* count) +{ + if(!image || !count) + return InvalidParameter; + + *count = 1; + + FIXME("stub\n"); + + return Ok; +} + GpStatus WINGDIPAPI GdipImageGetFrameDimensionsList(GpImage* image, GUID* dimensionIDs, UINT count) { diff --git a/reactos/dll/win32/gdiplus/imageattributes.c b/reactos/dll/win32/gdiplus/imageattributes.c index 858ea15e8cd..dcee68b0cd2 100644 --- a/reactos/dll/win32/gdiplus/imageattributes.c +++ b/reactos/dll/win32/gdiplus/imageattributes.c @@ -27,6 +27,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus); +GpStatus WINGDIPAPI GdipCloneImageAttributes(GDIPCONST GpImageAttributes *imageattr, + GpImageAttributes **cloneImageattr) +{ + if(!imageattr || !cloneImageattr) + return InvalidParameter; + + **cloneImageattr = *imageattr; + + return Ok; +} + GpStatus WINGDIPAPI GdipCreateImageAttributes(GpImageAttributes **imageattr) { if(!imageattr) diff --git a/reactos/dll/win32/gdiplus/pathiterator.c b/reactos/dll/win32/gdiplus/pathiterator.c index d1e4e88bf97..67d83a434bb 100644 --- a/reactos/dll/win32/gdiplus/pathiterator.c +++ b/reactos/dll/win32/gdiplus/pathiterator.c @@ -131,3 +131,13 @@ GpStatus WINGDIPAPI GdipPathIterRewind(GpPathIterator *iterator) return Ok; } + +GpStatus WINGDIPAPI GdipPathIterGetCount(GpPathIterator* iterator, INT* count) +{ + if(!iterator || !count) + return InvalidParameter; + + *count = iterator->pathdata.Count; + + return Ok; +} diff --git a/reactos/dll/win32/gdiplus/pen.c b/reactos/dll/win32/gdiplus/pen.c index 9ef14827cbf..852494f2ac2 100644 --- a/reactos/dll/win32/gdiplus/pen.c +++ b/reactos/dll/win32/gdiplus/pen.c @@ -88,14 +88,19 @@ GpStatus WINGDIPAPI GdipCreatePen1(ARGB color, REAL width, GpUnit unit, GpPen **pen) { GpBrush *brush; + GpStatus status; + GdipCreateSolidFill(color, (GpSolidFill **)(&brush)); - return GdipCreatePen2(brush, width, unit, pen); + status = GdipCreatePen2(brush, width, unit, pen); + GdipDeleteBrush(brush); + return status; } GpStatus WINGDIPAPI GdipCreatePen2(GpBrush *brush, REAL width, GpUnit unit, GpPen **pen) { GpPen *gp_pen; + GpBrush *clone_brush; if(!pen || !brush) return InvalidParameter; @@ -111,7 +116,6 @@ GpStatus WINGDIPAPI GdipCreatePen2(GpBrush *brush, REAL width, GpUnit unit, gp_pen->miterlimit = 10.0; gp_pen->dash = DashStyleSolid; gp_pen->offset = 0.0; - gp_pen->brush = brush; if(!((gp_pen->unit == UnitWorld) || (gp_pen->unit == UnitPixel))) { FIXME("UnitWorld, UnitPixel only supported units\n"); @@ -119,6 +123,9 @@ GpStatus WINGDIPAPI GdipCreatePen2(GpBrush *brush, REAL width, GpUnit unit, return NotImplemented; } + GdipCloneBrush(brush, &clone_brush); + gp_pen->brush = clone_brush; + *pen = gp_pen; return Ok; @@ -170,6 +177,16 @@ GpStatus WINGDIPAPI GdipGetPenDashArray(GpPen *pen, REAL *dash, INT count) return Ok; } +GpStatus WINGDIPAPI GdipGetPenDashCap197819(GpPen *pen, GpDashCap *dashCap) +{ + if(!pen || !dashCap) + return InvalidParameter; + + *dashCap = pen->dashcap; + + return Ok; +} + GpStatus WINGDIPAPI GdipGetPenDashOffset(GpPen *pen, REAL *offset) { if(!pen || !offset) @@ -190,6 +207,66 @@ GpStatus WINGDIPAPI GdipGetPenDashStyle(GpPen *pen, GpDashStyle *dash) return Ok; } +GpStatus WINGDIPAPI GdipGetPenEndCap(GpPen *pen, GpLineCap *endCap) +{ + if(!pen || !endCap) + return InvalidParameter; + + *endCap = pen->endcap; + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetPenLineJoin(GpPen *pen, GpLineJoin *lineJoin) +{ + if(!pen || !lineJoin) + return InvalidParameter; + + *lineJoin = pen->join; + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetPenMiterLimit(GpPen *pen, REAL *miterLimit) +{ + if(!pen || !miterLimit) + return InvalidParameter; + + *miterLimit = pen->miterlimit; + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetPenStartCap(GpPen *pen, GpLineCap *startCap) +{ + if(!pen || !startCap) + return InvalidParameter; + + *startCap = pen->startcap; + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetPenUnit(GpPen *pen, GpUnit *unit) +{ + if(!pen || !unit) + return InvalidParameter; + + *unit = pen->unit; + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetPenWidth(GpPen *pen, REAL *width) +{ + if(!pen || !width) + return InvalidParameter; + + *width = pen->width; + + return Ok; +} + GpStatus WINGDIPAPI GdipSetPenBrushFill(GpPen *pen, GpBrush *brush) { if(!pen || !brush) diff --git a/reactos/dll/win32/gdiplus/region.c b/reactos/dll/win32/gdiplus/region.c index 46e99194a5f..92239ff10fe 100644 --- a/reactos/dll/win32/gdiplus/region.c +++ b/reactos/dll/win32/gdiplus/region.c @@ -67,6 +67,27 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus); * */ +GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region, GDIPCONST GpRectF *rect, + CombineMode mode) +{ + FIXME("(%p %p %d): stub\n", region, rect, mode); + return NotImplemented; +} + +GpStatus WINGDIPAPI GdipCombineRegionRectI(GpRegion *region, GDIPCONST GpRect *rect, + CombineMode mode) +{ + FIXME("(%p %p %d): stub\n", region, rect, mode); + return NotImplemented; +} + +GpStatus WINGDIPAPI GdipCombineRegionRegion(GpRegion *region1, GpRegion *region2, + CombineMode mode) +{ + FIXME("(%p %p %d): stub\n", region1, region2, mode); + return NotImplemented; +} + GpStatus WINGDIPAPI GdipCreateRegion(GpRegion **region) { FIXME("(%p): stub\n", region); @@ -83,12 +104,42 @@ GpStatus WINGDIPAPI GdipCreateRegionPath(GpPath *path, GpRegion **region) return NotImplemented; } +GpStatus WINGDIPAPI GdipCreateRegionRect(GDIPCONST GpRectF *rect, GpRegion **region) +{ + FIXME("(%p, %p): stub\n", rect, region); + + *region = NULL; + return NotImplemented; +} + +GpStatus WINGDIPAPI GdipCreateRegionRectI(GDIPCONST GpRect *rect, GpRegion **region) +{ + FIXME("(%p, %p): stub\n", rect, region); + + *region = NULL; + return NotImplemented; +} + GpStatus WINGDIPAPI GdipDeleteRegion(GpRegion *region) { FIXME("(%p): stub\n", region); return NotImplemented; } +GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size, UINT *needed) +{ + FIXME("(%p, %p, %d, %p): stub\n", region, buffer, size, needed); + + return NotImplemented; +} + +GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed) +{ + FIXME("(%p, %p): stub\n", region, needed); + + return NotImplemented; +} + GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *region, GpGraphics *graphics, HRGN *hrgn) { FIXME("(%p, %p, %p): stub\n", region, graphics, hrgn); -- 2.17.1