- Sync with Wine HEAD
authorDmitry Chapyshev <dmitry@reactos.org>
Wed, 2 Jul 2008 08:19:00 +0000 (08:19 +0000)
committerDmitry Chapyshev <dmitry@reactos.org>
Wed, 2 Jul 2008 08:19:00 +0000 (08:19 +0000)
svn path=/trunk/; revision=34251

reactos/dll/win32/gdiplus/brush.c
reactos/dll/win32/gdiplus/font.c
reactos/dll/win32/gdiplus/gdiplus.spec
reactos/dll/win32/gdiplus/gdiplus_private.h
reactos/dll/win32/gdiplus/graphics.c
reactos/dll/win32/gdiplus/graphicspath.c
reactos/dll/win32/gdiplus/image.c
reactos/dll/win32/gdiplus/imageattributes.c
reactos/dll/win32/gdiplus/pathiterator.c
reactos/dll/win32/gdiplus/pen.c
reactos/dll/win32/gdiplus/region.c

index aa740fc..328f02c 100644 (file)
@@ -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){
index 82523ce..98a4c43 100644 (file)
 #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);
+}
index f2eb2b3..587f2ab 100644 (file)
 @ 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)
 @ 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)
 @ stdcall GdipDeleteCustomLineCap(ptr)
 @ stub GdipDeleteEffect
 @ stdcall GdipDeleteFont(ptr)
-@ stub GdipDeleteFontFamily
+@ stdcall GdipDeleteFontFamily(ptr)
 @ stdcall GdipDeleteGraphics(ptr)
 @ stdcall GdipDeleteMatrix(ptr)
 @ stdcall GdipDeletePath(ptr)
 @ 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)
 @ stdcall GdipFindFirstImageItem(ptr ptr)
 @ stub GdipFindNextImageItem
 @ stub GdipFlattenPath
-@ stub GdipFlush
+@ stdcall GdipFlush(ptr long)
 @ stdcall GdipFree(ptr)
 @ stub GdipGetAdjustableArrowCapFillState
 @ stub GdipGetAdjustableArrowCapHeight
 @ 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
 @ stub GdipGetNearestColor
 @ stdcall GdipGetPageScale(ptr ptr)
 @ stdcall GdipGetPageUnit(ptr ptr)
-@ stub GdipGetPathData
+@ stdcall GdipGetPathData(ptr ptr)
 @ stdcall GdipGetPathFillMode(ptr ptr)
 @ stub GdipGetPathGradientBlend
 @ stub GdipGetPathGradientBlendCount
 @ 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)
 @ 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
 @ 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
 @ 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)
 @ stub GdipNewPrivateFontCollection
 @ stdcall GdipPathIterCopyData(ptr ptr ptr ptr long long)
 @ stub GdipPathIterEnumerate
-@ stub GdipPathIterGetCount
+@ stdcall GdipPathIterGetCount(ptr ptr)
 @ stub GdipPathIterGetSubpathCount
 @ stub GdipPathIterHasCurve
 @ stub GdipPathIterIsValid
 @ 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
index d2d0373..ed76375 100644 (file)
@@ -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
index 347543f..7103f2e 100644 (file)
@@ -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)
index 3b09e04..6e5747f 100644 (file)
@@ -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;
+}
index 72bf7f5..330e54b 100644 (file)
@@ -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)
 {
index 858ea15..dcee68b 100644 (file)
 
 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)
index d1e4e88..67d83a4 100644 (file)
@@ -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;
+}
index 9ef1482..852494f 100644 (file)
@@ -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)
index 46e9919..92239ff 100644 (file)
@@ -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);