- Sync gdiplus with Wine head
authorDmitry Chapyshev <dmitry@reactos.org>
Tue, 5 Aug 2008 12:23:58 +0000 (12:23 +0000)
committerDmitry Chapyshev <dmitry@reactos.org>
Tue, 5 Aug 2008 12:23:58 +0000 (12:23 +0000)
svn path=/trunk/; revision=35124

18 files changed:
reactos/dll/win32/gdiplus/brush.c
reactos/dll/win32/gdiplus/customlinecap.c
reactos/dll/win32/gdiplus/font.c
reactos/dll/win32/gdiplus/gdiplus.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/matrix.c
reactos/dll/win32/gdiplus/pathiterator.c
reactos/dll/win32/gdiplus/pen.c
reactos/dll/win32/gdiplus/region.c
reactos/dll/win32/gdiplus/stringformat.c
reactos/include/psdk/gdiplusenums.h
reactos/include/psdk/gdiplusflat.h
reactos/include/psdk/gdiplusgpstubs.h
reactos/include/psdk/gdiplustypes.h

index 2d15e01..13cd3ab 100644 (file)
@@ -75,6 +75,24 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
             memcpy(dest->pathdata.Points, src->pathdata.Points, count * sizeof(PointF));
             memcpy(dest->pathdata.Types, src->pathdata.Types, count);
 
+            /* blending */
+            count = src->blendcount;
+            dest->blendcount = count;
+            dest->blendfac = GdipAlloc(count * sizeof(REAL));
+            dest->blendpos = GdipAlloc(count * sizeof(REAL));
+
+            if(!dest->blendfac || !dest->blendpos){
+                GdipFree(dest->pathdata.Points);
+                GdipFree(dest->pathdata.Types);
+                GdipFree(dest->blendfac);
+                GdipFree(dest->blendpos);
+                GdipFree(dest);
+                return OutOfMemory;
+            }
+
+            memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL));
+            memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));
+
             break;
         }
         case BrushTypeLinearGradient:
@@ -180,6 +198,25 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectI(GDIPCONST GpRect* rect,
     return GdipCreateLineBrushFromRect(&rectF, startcolor, endcolor, mode, wrap, line);
 }
 
+/* FIXME: angle value completely ignored. Don't know how to use it since native
+          always set Brush rectangle to rect (independetly of this angle).
+          Maybe it's used only on drawing.  */
+GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect,
+    ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
+    GpLineGradient **line)
+{
+    return GdipCreateLineBrushFromRect(rect, startcolor, endcolor, LinearGradientModeForwardDiagonal,
+                                       wrap, line);
+}
+
+GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect,
+    ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap,
+    GpLineGradient **line)
+{
+    return GdipCreateLineBrushFromRectI(rect, startcolor, endcolor, LinearGradientModeForwardDiagonal,
+                                        wrap, line);
+}
+
 GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points,
     INT count, GpWrapMode wrap, GpPathGradient **grad)
 {
@@ -194,6 +231,15 @@ GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points,
     *grad = GdipAlloc(sizeof(GpPathGradient));
     if (!*grad) return OutOfMemory;
 
+    (*grad)->blendfac = GdipAlloc(sizeof(REAL));
+    if(!(*grad)->blendfac){
+        GdipFree(*grad);
+        return OutOfMemory;
+    }
+    (*grad)->blendfac[0] = 1.0;
+    (*grad)->blendpos    = NULL;
+    (*grad)->blendcount  = 1;
+
     (*grad)->pathdata.Count = count;
     (*grad)->pathdata.Points = GdipAlloc(count * sizeof(PointF));
     (*grad)->pathdata.Types = GdipAlloc(count);
@@ -265,6 +311,15 @@ GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
     *grad = GdipAlloc(sizeof(GpPathGradient));
     if (!*grad) return OutOfMemory;
 
+    (*grad)->blendfac = GdipAlloc(sizeof(REAL));
+    if(!(*grad)->blendfac){
+        GdipFree(*grad);
+        return OutOfMemory;
+    }
+    (*grad)->blendfac[0] = 1.0;
+    (*grad)->blendpos    = NULL;
+    (*grad)->blendcount  = 1;
+
     (*grad)->pathdata.Count = path->pathdata.Count;
     (*grad)->pathdata.Points = GdipAlloc(path->pathdata.Count * sizeof(PointF));
     (*grad)->pathdata.Types = GdipAlloc(path->pathdata.Count);
@@ -457,6 +512,8 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
         case BrushTypePathGradient:
             GdipFree(((GpPathGradient*) brush)->pathdata.Points);
             GdipFree(((GpPathGradient*) brush)->pathdata.Types);
+            GdipFree(((GpPathGradient*) brush)->blendfac);
+            GdipFree(((GpPathGradient*) brush)->blendpos);
             break;
         case BrushTypeSolidColor:
         case BrushTypeLinearGradient:
@@ -482,6 +539,43 @@ GpStatus WINGDIPAPI GdipGetLineGammaCorrection(GpLineGradient *line,
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient *brush, GpWrapMode *wrapmode)
+{
+    if(!brush || !wrapmode)
+        return InvalidParameter;
+
+    *wrapmode = brush->wrap;
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipGetPathGradientBlend(GpPathGradient *brush, REAL *blend,
+    REAL *positions, INT count)
+{
+    if(!brush || !blend || !positions || count <= 0)
+        return InvalidParameter;
+
+    if(count < brush->blendcount)
+        return InsufficientBuffer;
+
+    memcpy(blend, brush->blendfac, count*sizeof(REAL));
+    if(brush->blendcount > 1){
+        memcpy(positions, brush->blendpos, count*sizeof(REAL));
+    }
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipGetPathGradientBlendCount(GpPathGradient *brush, INT *count)
+{
+    if(!brush || !count)
+        return InvalidParameter;
+
+    *count = brush->blendcount;
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipGetPathGradientCenterPoint(GpPathGradient *grad,
     GpPointF *point)
 {
@@ -547,6 +641,51 @@ GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient *grad,
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect)
+{
+    GpRectF r;
+    GpPath* path;
+    GpStatus stat;
+
+    if(!brush || !rect)
+        return InvalidParameter;
+
+    stat = GdipCreatePath2(brush->pathdata.Points, brush->pathdata.Types,
+                           brush->pathdata.Count, FillModeAlternate, &path);
+    if(stat != Ok)  return stat;
+
+    stat = GdipGetPathWorldBounds(path, &r, NULL, NULL);
+    if(stat != Ok){
+        GdipDeletePath(path);
+        return stat;
+    }
+
+    memcpy(rect, &r, sizeof(GpRectF));
+
+    GdipDeletePath(path);
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect)
+{
+    GpRectF rectf;
+    GpStatus stat;
+
+    if(!brush || !rect)
+        return InvalidParameter;
+
+    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);
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient
     *grad, ARGB *argb, INT *count)
 {
index e8e18bc..48a20df 100644 (file)
@@ -100,6 +100,8 @@ GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath* fillPath, GpPath* strokePath
 
     (*customCap)->inset = baseInset;
     (*customCap)->cap = baseCap;
+    (*customCap)->join = LineJoinMiter;
+    (*customCap)->scale = 1.0;
 
     return Ok;
 }
@@ -116,6 +118,28 @@ GpStatus WINGDIPAPI GdipDeleteCustomLineCap(GpCustomLineCap *customCap)
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipGetCustomLineCapStrokeJoin(GpCustomLineCap* customCap,
+    GpLineJoin* lineJoin)
+{
+    if(!customCap || !lineJoin)
+        return InvalidParameter;
+
+    *lineJoin = customCap->join;
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipGetCustomLineCapWidthScale(GpCustomLineCap* custom,
+    REAL* widthScale)
+{
+    if(!custom || !widthScale)
+        return InvalidParameter;
+
+    *widthScale = custom->scale;
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeCaps(GpCustomLineCap* custom,
     GpLineCap start, GpLineCap end)
 {
@@ -144,12 +168,12 @@ GpStatus WINGDIPAPI GdipSetCustomLineCapBaseCap(GpCustomLineCap* custom,
 GpStatus WINGDIPAPI GdipGetCustomLineCapBaseInset(GpCustomLineCap* custom,
     REAL* inset)
 {
-    static int calls;
+    if(!custom || !inset)
+        return InvalidParameter;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
+    *inset = custom->inset;
 
-    return NotImplemented;
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipSetCustomLineCapBaseInset(GpCustomLineCap* custom,
@@ -163,15 +187,16 @@ GpStatus WINGDIPAPI GdipSetCustomLineCapBaseInset(GpCustomLineCap* custom,
     return NotImplemented;
 }
 
+/*FIXME: LineJoin completely ignored now */
 GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeJoin(GpCustomLineCap* custom,
     GpLineJoin join)
 {
-    static int calls;
+    if(!custom)
+        return InvalidParameter;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
+    custom->join = join;
 
-    return NotImplemented;
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipSetCustomLineCapWidthScale(GpCustomLineCap* custom,
index 78de0a6..70f7bb0 100644 (file)
@@ -95,10 +95,10 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
 {
     WCHAR facename[LF_FACESIZE];
     LOGFONTW* lfw;
-    const TEXTMETRICW* tmw;
+    const NEWTEXTMETRICW* tmw;
     GpStatus stat;
 
-    if (!fontFamily || !fontFamily->FamilyName || !font)
+    if (!fontFamily || !font)
         return InvalidParameter;
 
     TRACE("%p (%s), %f, %d, %d, %p\n", fontFamily,
@@ -118,7 +118,7 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
     lfw->lfStrikeOut = tmw->tmStruckOut;
     lfw->lfCharSet = tmw->tmCharSet;
     lfw->lfPitchAndFamily = tmw->tmPitchAndFamily;
-    lstrcpynW((lfw->lfFaceName), facename, sizeof(WCHAR) * LF_FACESIZE);
+    lstrcpynW(lfw->lfFaceName, facename, LF_FACESIZE);
 
     switch (unit)
     {
@@ -157,6 +157,9 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
     return Ok;
 }
 
+/*******************************************************************************
+ * GdipCreateFontFromLogfontW [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
     GDIPCONST LOGFONTW *logfont, GpFont **font)
 {
@@ -169,7 +172,7 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
     *font = GdipAlloc(sizeof(GpFont));
     if(!*font)  return OutOfMemory;
 
-    memcpy(&(*font)->lfw.lfFaceName, logfont->lfFaceName, LF_FACESIZE *
+    memcpy((*font)->lfw.lfFaceName, logfont->lfFaceName, LF_FACESIZE *
            sizeof(WCHAR));
     (*font)->lfw.lfHeight = logfont->lfHeight;
     (*font)->lfw.lfItalic = logfont->lfItalic;
@@ -192,6 +195,9 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
     return Ok;
 }
 
+/*******************************************************************************
+ * GdipCreateFontFromLogfontA [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipCreateFontFromLogfontA(HDC hdc,
     GDIPCONST LOGFONTA *lfa, GpFont **font)
 {
@@ -210,6 +216,9 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontA(HDC hdc,
     return Ok;
 }
 
+/*******************************************************************************
+ * GdipDeleteFont [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipDeleteFont(GpFont* font)
 {
     if(!font)
@@ -220,6 +229,9 @@ GpStatus WINGDIPAPI GdipDeleteFont(GpFont* font)
     return Ok;
 }
 
+/*******************************************************************************
+ * GdipCreateFontFromDC [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipCreateFontFromDC(HDC hdc, GpFont **font)
 {
     HFONT hfont;
@@ -283,10 +295,13 @@ GpStatus WINGDIPAPI GdipGetFontUnit(GpFont *font, Unit *unit)
     return Ok;
 }
 
-/* FIXME: use graphics */
+/*******************************************************************************
+ * GdipGetLogFontW [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics,
     LOGFONTW *lfw)
 {
+    /* FIXME: use graphics */
     if(!font || !graphics || !lfw)
         return InvalidParameter;
 
@@ -295,6 +310,9 @@ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics,
     return Ok;
 }
 
+/*******************************************************************************
+ * GdipCloneFont [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont)
 {
     if(!font || !cloneFont)
@@ -308,19 +326,56 @@ GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont)
     return Ok;
 }
 
-/* Borrowed from GDI32 */
+/*******************************************************************************
+ * GdipGetFontHeightGivenDPI [GDIPLUS.@]
+ * PARAMS
+ *  font        [I] Font to retrieve DPI from
+ *  dpi         [I] DPI to assume
+ *  height      [O] Return value
+ *
+ * RETURNS
+ *  SUCCESS: Ok
+ *  FAILURE: InvalidParameter if font or height is NULL
+ *
+ * NOTES
+ *  According to MSDN, the result is (lineSpacing)*(fontSize / emHeight)*dpi
+ *  (for anything other than unit Pixel)
+ */
+GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi, REAL *height)
+{
+    if (!(font && height)) return InvalidParameter;
+
+    FIXME("%p (%s), %f, %p\n", font,
+            debugstr_w(font->lfw.lfFaceName), dpi, height);
+
+    return NotImplemented;
+}
+
+/***********************************************************************
+ * Borrowed from GDI32:
+ *
+ * Elf is really an ENUMLOGFONTEXW, and ntm is a NEWTEXTMETRICEXW.
+ *     We have to use other types because of the FONTENUMPROCW definition.
+ */
 static INT CALLBACK is_font_installed_proc(const LOGFONTW *elf,
                             const TEXTMETRICW *ntm, DWORD type, LPARAM lParam)
 {
+    if (!ntm)
+    {
+        return 1;
+    }
+
+    *(NEWTEXTMETRICW*)lParam = *(const NEWTEXTMETRICW*)ntm;
+
     return 0;
 }
 
-static BOOL is_font_installed(const WCHAR *name)
+static BOOL find_installed_font(const WCHAR *name, NEWTEXTMETRICW *ntm)
 {
     HDC hdc = GetDC(0);
     BOOL ret = FALSE;
 
-    if(!EnumFontFamiliesW(hdc, name, is_font_installed_proc, 0))
+    if(!EnumFontFamiliesW(hdc, name, is_font_installed_proc, (LPARAM)ntm))
         ret = TRUE;
 
     ReleaseDC(0, hdc);
@@ -352,9 +407,7 @@ GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
                                         GpFontFamily **FontFamily)
 {
     GpFontFamily* ffamily;
-    HDC hdc;
-    HFONT hFont, hfont_old;
-    LOGFONTW lfw;
+    NEWTEXTMETRICW ntm;
 
     TRACE("%s, %p %p\n", debugstr_w(name), fontCollection, FontFamily);
 
@@ -362,32 +415,45 @@ GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
         return InvalidParameter;
     if (fontCollection)
         FIXME("No support for FontCollections yet!\n");
-    if (!is_font_installed(name))
+
+    if (!find_installed_font(name, &ntm))
         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);
+    ffamily->tmw = ntm;
+    lstrcpynW(ffamily->FamilyName, name, LF_FACESIZE);
 
-    GetTextMetricsW(hdc, &ffamily->tmw);
-    DeleteObject(SelectObject(hdc, hfont_old));
+    *FontFamily = ffamily;
 
-    ffamily->FamilyName = GdipAlloc(LF_FACESIZE * sizeof (WCHAR));
-    if (!ffamily->FamilyName)
-    {
-        GdipFree(ffamily);
-        ReleaseDC(0, hdc);
-        return OutOfMemory;
-    }
+    return Ok;
+}
+
+/*******************************************************************************
+ * GdipCloneFontFamily [GDIPLUS.@]
+ *
+ * Creates a deep copy of a Font Family object
+ *
+ * PARAMS
+ *  FontFamily          [I] Font to clone
+ *  clonedFontFamily    [O] The resulting cloned font
+ *
+ * RETURNS
+ *  SUCCESS: Ok
+ */
+GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily* FontFamily, GpFontFamily** clonedFontFamily)
+{
+    if (!(FontFamily && clonedFontFamily)) return InvalidParameter;
 
-    lstrcpynW(ffamily->FamilyName, name, sizeof(WCHAR) * LF_FACESIZE);
+    TRACE("stub: %p (%s), %p\n", FontFamily,
+            debugstr_w(FontFamily->FamilyName), clonedFontFamily);
 
-    *FontFamily = ffamily;
-    ReleaseDC(0, hdc);
+    *clonedFontFamily = GdipAlloc(sizeof(GpFontFamily));
+    if (!*clonedFontFamily) return OutOfMemory;
+
+    (*clonedFontFamily)->tmw = FontFamily->tmw;
+    lstrcpyW((*clonedFontFamily)->FamilyName, FontFamily->FamilyName);
 
     return Ok;
 }
@@ -445,12 +511,93 @@ GpStatus WINGDIPAPI GdipDeleteFontFamily(GpFontFamily *FontFamily)
         return InvalidParameter;
     TRACE("Deleting %p (%s)\n", FontFamily, debugstr_w(FontFamily->FamilyName));
 
-    GdipFree (FontFamily->FamilyName);
     GdipFree (FontFamily);
 
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipGetCellAscent(GDIPCONST GpFontFamily *family,
+        INT style, UINT16* CellAscent)
+{
+    if (!(family && CellAscent)) return InvalidParameter;
+
+    *CellAscent = family->tmw.tmAscent;
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipGetCellDescent(GDIPCONST GpFontFamily *family,
+        INT style, UINT16* CellDescent)
+{
+    if (!(family && CellDescent)) return InvalidParameter;
+
+    *CellDescent = family->tmw.tmDescent;
+
+    return Ok;
+}
+
+/*******************************************************************************
+ * GdipGetEmHeight [GDIPLUS.@]
+ *
+ * Gets the height of the specified family in EmHeights
+ *
+ * PARAMS
+ *  family      [I] Family to retrieve from
+ *  style       [I] (optional) style
+ *  EmHeight    [O] return value
+ *
+ * RETURNS
+ *  SUCCESS: Ok
+ *  FAILURE: InvalidParameter
+ */
+GpStatus WINGDIPAPI GdipGetEmHeight(GDIPCONST GpFontFamily *family, INT style, UINT16* EmHeight)
+{
+    if (!(family && EmHeight)) return InvalidParameter;
+
+    TRACE("%p (%s), %d, %p, stub!\n", family,
+            debugstr_w(family->FamilyName), style, EmHeight);
+
+    *EmHeight = family->tmw.ntmSizeEM;
+
+    return Ok;
+}
+
+
+/*******************************************************************************
+ * GdipGetLineSpacing [GDIPLUS.@]
+ *
+ * Returns the line spacing in design units
+ *
+ * PARAMS
+ *  family      [I] Family to retrieve from
+ *  style       [I] (Optional) font style
+ *  LineSpacing [O] Return value
+ *
+ * RETURNS
+ *  SUCCESS: Ok
+ *  FAILURE: InvalidParameter (family or LineSpacing was NULL)
+ */
+GpStatus WINGDIPAPI GdipGetLineSpacing(GDIPCONST GpFontFamily *family,
+        INT style, UINT16* LineSpacing)
+{
+    if (!(family && LineSpacing)) return InvalidParameter;
+
+    FIXME("stub!\n");
+
+    return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipIsStyleAvailable(GDIPCONST GpFontFamily* family,
+        INT style, BOOL* IsStyleAvailable)
+{
+    FIXME("%p %d %p stub!\n", family, style, IsStyleAvailable);
+
+    if (!(family && IsStyleAvailable))
+        return InvalidParameter;
+
+    return NotImplemented;
+}
+
 /*****************************************************************************
  * GdipGetGenericFontFamilyMonospace [GDIPLUS.@]
  *
@@ -515,3 +662,73 @@ GpStatus WINGDIPAPI GdipGetGenericFontFamilySansSerif(GpFontFamily **nativeFamil
 
     return GdipCreateFontFamilyFromName(MSSansSerif, NULL, nativeFamily);
 }
+
+/*****************************************************************************
+ * GdipGetGenericFontFamilySansSerif [GDIPLUS.@]
+ */
+GpStatus WINGDIPAPI GdipNewPrivateFontCollection(GpFontCollection** fontCollection)
+{
+    FIXME("stub %p\n", fontCollection);
+
+    if (!fontCollection)
+        return InvalidParameter;
+
+    return NotImplemented;
+}
+
+/*****************************************************************************
+ * GdipDeletePrivateFontCollection [GDIPLUS.@]
+ */
+GpStatus WINGDIPAPI GdipDeletePrivateFontCollection(GpFontCollection **fontCollection)
+{
+    FIXME("stub %p\n", fontCollection);
+
+    if (!fontCollection)
+        return InvalidParameter;
+
+    return NotImplemented;
+}
+
+/*****************************************************************************
+ * GdipPrivateAddFontFile [GDIPLUS.@]
+ */
+GpStatus WINGDIPAPI GdipPrivateAddFontFile(GpFontCollection* fontCollection,
+        GDIPCONST WCHAR* filename)
+{
+    FIXME("stub: %p, %s\n", fontCollection, debugstr_w(filename));
+
+    if (!(fontCollection && filename))
+        return InvalidParameter;
+
+    return NotImplemented;
+}
+
+/*****************************************************************************
+ * GdipGetFontCollectionFamilyCount [GDIPLUS.@]
+ */
+GpStatus WINGDIPAPI GdipGetFontCollectionFamilyCount(
+        GpFontCollection* fontCollection, INT* numFound)
+{
+    FIXME("stub: %p, %p\n", fontCollection, numFound);
+
+    if (!(fontCollection && numFound))
+        return InvalidParameter;
+
+    return NotImplemented;
+}
+
+/*****************************************************************************
+ * GdipGetFontCollectionFamilyList [GDIPLUS.@]
+ */
+GpStatus WINGDIPAPI GdipGetFontCollectionFamilyList(
+        GpFontCollection* fontCollection, INT numSought,
+        GpFontFamily* gpfamilies[], INT* numFound)
+{
+    FIXME("stub: %p, %d, %p, %p\n", fontCollection, numSought, gpfamilies,
+            numFound);
+
+    if (!(fontCollection && gpfamilies && numFound))
+        return InvalidParameter;
+
+    return NotImplemented;
+}
index f897eb5..2b50f2c 100644 (file)
@@ -285,3 +285,29 @@ REAL convert_unit(HDC hdc, GpUnit unit)
             return 1.0;
     }
 }
+
+/* Calculates Bezier points from cardinal spline points. */
+void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1,
+    REAL *y1, REAL *x2, REAL *y2)
+{
+    REAL xdiff, ydiff;
+
+    /* calculate tangent */
+    xdiff = pts[2].X - pts[0].X;
+    ydiff = pts[2].Y - pts[0].Y;
+
+    /* apply tangent to get control points */
+    *x1 = pts[1].X - tension * xdiff;
+    *y1 = pts[1].Y - tension * ydiff;
+    *x2 = pts[1].X + tension * xdiff;
+    *y2 = pts[1].Y + tension * ydiff;
+}
+
+/* Calculates Bezier points from cardinal spline endpoints. */
+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);
+}
index 9492065..18e7eeb 100644 (file)
@@ -4,16 +4,16 @@
 @ stdcall GdipAddPathBezierI(ptr long long long long long long long long)
 @ stdcall GdipAddPathBeziers(ptr ptr long)
 @ stdcall GdipAddPathBeziersI(ptr ptr long)
-@ stub GdipAddPathClosedCurve2
-@ stub GdipAddPathClosedCurve2I
-@ stub GdipAddPathClosedCurve
-@ stub GdipAddPathClosedCurveI
-@ stub GdipAddPathCurve2
-@ stub GdipAddPathCurve2I
+@ stdcall GdipAddPathClosedCurve2(ptr ptr long long)
+@ stdcall GdipAddPathClosedCurve2I(ptr ptr long long)
+@ stdcall GdipAddPathClosedCurve(ptr ptr long)
+@ stdcall GdipAddPathClosedCurveI(ptr ptr long)
+@ stdcall GdipAddPathCurve2(ptr ptr long long)
+@ stdcall GdipAddPathCurve2I(ptr ptr long long)
 @ stub GdipAddPathCurve3
 @ stub GdipAddPathCurve3I
-@ stub GdipAddPathCurve
-@ stub GdipAddPathCurveI
+@ stdcall GdipAddPathCurve(ptr ptr long)
+@ stdcall GdipAddPathCurveI(ptr ptr long)
 @ stdcall GdipAddPathEllipse(ptr long long long long)
 @ stdcall GdipAddPathEllipseI(ptr long long long long)
 @ stdcall GdipAddPathLine2(ptr ptr long)
@@ -51,7 +51,7 @@
 @ stdcall GdipCloneBrush(ptr ptr)
 @ stdcall GdipCloneCustomLineCap(ptr ptr)
 @ stdcall GdipCloneFont(ptr ptr)
-@ stub GdipCloneFontFamily
+@ stdcall GdipCloneFontFamily(ptr ptr)
 @ stdcall GdipCloneImage(ptr ptr)
 @ stdcall GdipCloneImageAttributes(ptr ptr)
 @ stdcall GdipCloneMatrix(ptr ptr)
 @ stub GdipCreateBitmapFromDirectDrawSurface
 @ stdcall GdipCreateBitmapFromFile(wstr ptr)
 @ stdcall GdipCreateBitmapFromFileICM(wstr ptr)
-@ stub GdipCreateBitmapFromGdiDib
+@ stdcall GdipCreateBitmapFromGdiDib(ptr ptr ptr)
 @ stdcall GdipCreateBitmapFromGraphics(long long ptr ptr)
-@ stdcall GdipCreateBitmapFromHBITMAP(ptr ptr ptr)
+@ stdcall GdipCreateBitmapFromHBITMAP(long long ptr)
 @ stub GdipCreateBitmapFromHICON
-@ stub GdipCreateBitmapFromResource
+@ stdcall GdipCreateBitmapFromResource(long wstr ptr)
 @ stdcall GdipCreateBitmapFromScan0(long long long long ptr ptr)
 @ stdcall GdipCreateBitmapFromStream(ptr ptr)
 @ stdcall GdipCreateBitmapFromStreamICM(ptr ptr)
 @ stdcall GdipCreateLineBrush(ptr ptr long long long ptr)
 @ stdcall GdipCreateLineBrushFromRect(ptr long long long long ptr)
 @ stdcall GdipCreateLineBrushFromRectI(ptr long long long long ptr)
-@ stub GdipCreateLineBrushFromRectWithAngle
-@ stub GdipCreateLineBrushFromRectWithAngleI
+@ stdcall GdipCreateLineBrushFromRectWithAngle(ptr long long long long long ptr)
+@ stdcall GdipCreateLineBrushFromRectWithAngleI(ptr long long long long long ptr)
 @ stdcall GdipCreateLineBrushI(ptr ptr long long long ptr)
 @ stdcall GdipCreateMatrix2(long long long long long long ptr)
 @ stdcall GdipCreateMatrix3(ptr ptr ptr)
 @ stub GdipCreateMetafileFromFile
 @ stub GdipCreateMetafileFromStream
 @ stdcall GdipCreateMetafileFromWmf(ptr long ptr ptr)
-@ stub GdipCreateMetafileFromWmfFile
+@ stdcall GdipCreateMetafileFromWmfFile(wstr ptr ptr)
 @ stdcall GdipCreatePath2(ptr ptr long long ptr)
 @ stdcall GdipCreatePath2I(ptr ptr long long ptr)
 @ stdcall GdipCreatePath(long ptr)
 @ stdcall GdipDeletePath(ptr)
 @ stdcall GdipDeletePathIter(ptr)
 @ stdcall GdipDeletePen(ptr)
-@ stub GdipDeletePrivateFontCollection
+@ stdcall GdipDeletePrivateFontCollection(ptr)
 @ stdcall GdipDeleteRegion(ptr)
 @ stdcall GdipDeleteStringFormat(ptr)
 @ stdcall GdipDisposeImage(ptr)
 @ stdcall GdipDrawBeziers(ptr ptr ptr long)
 @ stdcall GdipDrawBeziersI(ptr ptr ptr long)
 @ stub GdipDrawCachedBitmap
-@ stub GdipDrawClosedCurve2
-@ stub GdipDrawClosedCurve2I
-@ stub GdipDrawClosedCurve
-@ stub GdipDrawClosedCurveI
+@ stdcall GdipDrawClosedCurve2(ptr ptr ptr long long)
+@ stdcall GdipDrawClosedCurve2I(ptr ptr ptr long long)
+@ stdcall GdipDrawClosedCurve(ptr ptr ptr long)
+@ stdcall GdipDrawClosedCurveI(ptr ptr ptr long)
 @ stdcall GdipDrawCurve2(ptr ptr ptr long long)
 @ stdcall GdipDrawCurve2I(ptr ptr ptr long long)
 @ stub GdipDrawCurve3
 @ stdcall GdipFillPath(ptr ptr ptr)
 @ stdcall GdipFillPie(ptr ptr long long long long long long)
 @ stdcall GdipFillPieI(ptr ptr long long long long long long)
-@ stub GdipFillPolygon2
-@ stub GdipFillPolygon2I
+@ stdcall GdipFillPolygon2(ptr ptr ptr long)
+@ stdcall GdipFillPolygon2I(ptr ptr ptr long)
 @ stdcall GdipFillPolygon(ptr ptr ptr long long)
 @ stdcall GdipFillPolygonI(ptr ptr ptr long long)
 @ stdcall GdipFillRectangle(ptr ptr long long long long)
 @ stdcall GdipFillRectangleI(ptr ptr long long long long)
 @ stdcall GdipFillRectangles(ptr ptr ptr long)
 @ stdcall GdipFillRectanglesI(ptr ptr ptr long)
-@ stub GdipFillRegion
+@ stdcall GdipFillRegion(ptr ptr ptr)
 @ stdcall GdipFindFirstImageItem(ptr ptr)
 @ stub GdipFindNextImageItem
 @ stub GdipFlattenPath
 @ stub GdipGetAdjustableArrowCapWidth
 @ stub GdipGetAllPropertyItems
 @ stdcall GdipGetBrushType(ptr ptr)
-@ stub GdipGetCellAscent
-@ stub GdipGetCellDescent
+@ stdcall GdipGetCellAscent(ptr long ptr)
+@ stdcall GdipGetCellDescent(ptr long ptr)
 @ stdcall GdipGetClip(ptr ptr)
 @ stub GdipGetClipBounds
 @ stub GdipGetClipBoundsI
 @ stdcall GdipGetCustomLineCapBaseCap(ptr ptr)
 @ stdcall GdipGetCustomLineCapBaseInset(ptr ptr)
 @ stub GdipGetCustomLineCapStrokeCaps
-@ stub GdipGetCustomLineCapStrokeJoin
+@ stdcall GdipGetCustomLineCapStrokeJoin(ptr ptr)
 @ stub GdipGetCustomLineCapType
-@ stub GdipGetCustomLineCapWidthScale
+@ stdcall GdipGetCustomLineCapWidthScale(ptr ptr)
 @ stdcall GdipGetDC(ptr ptr)
 @ stdcall GdipGetDpiX(ptr ptr)
 @ stdcall GdipGetDpiY(ptr ptr)
 @ stub GdipGetEffectParameterSize
 @ stub GdipGetEffectParameters
-@ stub GdipGetEmHeight
+@ stdcall GdipGetEmHeight(ptr long ptr)
 @ stub GdipGetEncoderParameterList
 @ stub GdipGetEncoderParameterListSize
 @ stub GdipGetFamily
 @ stdcall GdipGetFamilyName(ptr ptr long)
-@ stub GdipGetFontCollectionFamilyCount
-@ stub GdipGetFontCollectionFamilyList
+@ stdcall GdipGetFontCollectionFamilyCount(ptr ptr)
+@ stdcall GdipGetFontCollectionFamilyList(ptr long ptr ptr)
 @ stub GdipGetFontHeight
-@ stub GdipGetFontHeightGivenDPI
+@ stdcall GdipGetFontHeightGivenDPI(ptr long ptr)
 @ stdcall GdipGetFontSize(ptr ptr)
 @ stub GdipGetFontStyle
 @ stdcall GdipGetFontUnit(ptr ptr)
 @ stub GdipGetLinePresetBlendCount
 @ stdcall GdipGetLineRect(ptr ptr)
 @ stdcall GdipGetLineRectI(ptr ptr)
-@ stub GdipGetLineSpacing
+@ stdcall GdipGetLineSpacing(ptr long ptr)
 @ stub GdipGetLineTransform
-@ stub GdipGetLineWrapMode
+@ stdcall GdipGetLineWrapMode(ptr ptr)
 @ stub GdipGetLogFontA
 @ stdcall GdipGetLogFontW(ptr ptr ptr)
 @ stdcall GdipGetMatrixElements(ptr ptr)
 @ stdcall GdipGetPageUnit(ptr ptr)
 @ stdcall GdipGetPathData(ptr ptr)
 @ stdcall GdipGetPathFillMode(ptr ptr)
-@ stub GdipGetPathGradientBlend
-@ stub GdipGetPathGradientBlendCount
+@ stdcall GdipGetPathGradientBlend(ptr ptr ptr long)
+@ stdcall GdipGetPathGradientBlendCount(ptr ptr)
 @ stub GdipGetPathGradientCenterColor
 @ stdcall GdipGetPathGradientCenterPoint(ptr ptr)
 @ stdcall GdipGetPathGradientCenterPointI(ptr ptr)
 @ stdcall GdipGetPathGradientPointCount(ptr ptr)
 @ stub GdipGetPathGradientPresetBlend
 @ stub GdipGetPathGradientPresetBlendCount
-@ stub GdipGetPathGradientRect
-@ stub GdipGetPathGradientRectI
+@ stdcall GdipGetPathGradientRect(ptr ptr)
+@ stdcall GdipGetPathGradientRectI(ptr ptr)
 @ stub GdipGetPathGradientSurroundColorCount
 @ stdcall GdipGetPathGradientSurroundColorsWithCount(ptr ptr ptr)
 @ stub GdipGetPathGradientTransform
 @ stdcall GdipGetPenColor(ptr ptr)
 @ stub GdipGetPenCompoundArray
 @ stub GdipGetPenCompoundCount
-@ stub GdipGetPenCustomEndCap
-@ stub GdipGetPenCustomStartCap
+@ stdcall GdipGetPenCustomEndCap(ptr ptr)
+@ stdcall GdipGetPenCustomStartCap(ptr ptr)
 @ stdcall GdipGetPenDashArray(ptr ptr long)
 @ stdcall GdipGetPenDashCap197819(ptr ptr)
-@ stub GdipGetPenDashCount
+@ stdcall GdipGetPenDashCount(ptr ptr)
 @ stdcall GdipGetPenDashOffset(ptr ptr)
 @ stdcall GdipGetPenDashStyle(ptr ptr)
 @ stdcall GdipGetPenEndCap(ptr ptr)
 @ stub GdipGetPenFillType
 @ stdcall GdipGetPenLineJoin(ptr ptr)
 @ stdcall GdipGetPenMiterLimit(ptr ptr)
-@ stub GdipGetPenMode
+@ stdcall GdipGetPenMode(ptr ptr)
 @ stdcall GdipGetPenStartCap(ptr ptr)
 @ stub GdipGetPenTransform
 @ stdcall GdipGetPenUnit(ptr ptr)
 @ stdcall GdipGetSmoothingMode(ptr ptr)
 @ stdcall GdipGetSolidFillColor(ptr ptr)
 @ stdcall GdipGetStringFormatAlign(ptr ptr)
-@ stub GdipGetStringFormatDigitSubstitution
-@ stub GdipGetStringFormatFlags
+@ stdcall GdipGetStringFormatDigitSubstitution(ptr ptr ptr)
+@ stdcall GdipGetStringFormatFlags(ptr ptr)
 @ stdcall GdipGetStringFormatHotkeyPrefix(ptr ptr)
 @ stdcall GdipGetStringFormatLineAlign(ptr ptr)
-@ stub GdipGetStringFormatMeasurableCharacterRangeCount
-@ stub GdipGetStringFormatTabStopCount
-@ stub GdipGetStringFormatTabStops
+@ stdcall GdipGetStringFormatMeasurableCharacterRangeCount(ptr ptr)
+@ stdcall GdipGetStringFormatTabStopCount(ptr ptr)
+@ stdcall GdipGetStringFormatTabStops(ptr long ptr ptr)
 @ stdcall GdipGetStringFormatTrimming(ptr ptr)
 @ stub GdipGetTextContrast
 @ stdcall GdipGetTextRenderingHint(ptr ptr)
 @ stdcall GdipImageSelectActiveFrame(ptr ptr long)
 @ stub GdipImageSetAbort
 @ stub GdipInitializePalette
-@ stub GdipInvertMatrix
+@ stdcall GdipInvertMatrix(ptr)
 @ stub GdipIsClipEmpty
 @ stdcall GdipIsEmptyRegion(ptr ptr ptr)
 @ stdcall GdipIsEqualRegion(ptr ptr ptr ptr)
 @ stdcall GdipIsInfiniteRegion(ptr ptr ptr)
 @ stdcall GdipIsMatrixEqual(ptr ptr ptr)
 @ stdcall GdipIsMatrixIdentity(ptr ptr)
-@ stub GdipIsMatrixInvertible
-@ stub GdipIsOutlineVisiblePathPoint
+@ stdcall GdipIsMatrixInvertible(ptr ptr)
+@ stdcall GdipIsOutlineVisiblePathPoint(ptr long long ptr ptr ptr)
 @ stdcall GdipIsOutlineVisiblePathPointI(ptr long long ptr ptr ptr)
-@ stub GdipIsStyleAvailable
+@ stdcall GdipIsStyleAvailable(ptr long ptr)
 @ stub GdipIsVisibleClipEmpty
-@ stub GdipIsVisiblePathPoint
-@ stub GdipIsVisiblePathPointI
+@ stdcall GdipIsVisiblePathPoint(ptr long long ptr ptr)
+@ stdcall GdipIsVisiblePathPointI(ptr long long ptr ptr)
 @ stub GdipIsVisiblePoint
 @ stub GdipIsVisiblePointI
 @ stub GdipIsVisibleRect
 @ stdcall GdipLoadImageFromFileICM(wstr ptr)
 @ stdcall GdipLoadImageFromStream(ptr ptr)
 @ stdcall GdipLoadImageFromStreamICM(ptr ptr)
-@ stub GdipMeasureCharacterRanges
+@ stdcall GdipMeasureCharacterRanges(ptr wstr long ptr ptr ptr long ptr)
 @ stub GdipMeasureDriverString
-@ stdcall GdipMeasureString(ptr ptr long ptr ptr ptr ptr ptr ptr)
+@ stdcall GdipMeasureString(ptr wstr long ptr ptr ptr ptr ptr ptr)
 @ stub GdipMultiplyLineTransform
 @ stdcall GdipMultiplyMatrix(ptr ptr long)
 @ stub GdipMultiplyPathGradientTransform
 @ stub GdipMultiplyTextureTransform
 @ stdcall GdipMultiplyWorldTransform(ptr ptr long)
 @ stub GdipNewInstalledFontCollection
-@ stub GdipNewPrivateFontCollection
+@ stdcall GdipNewPrivateFontCollection(ptr)
 @ stdcall GdipPathIterCopyData(ptr ptr ptr ptr long long)
 @ stdcall GdipPathIterEnumerate(ptr ptr ptr ptr long)
 @ stdcall GdipPathIterGetCount(ptr ptr)
-@ stub GdipPathIterGetSubpathCount
+@ stdcall GdipPathIterGetSubpathCount(ptr ptr)
 @ stdcall GdipPathIterHasCurve(ptr ptr)
 @ stub GdipPathIterIsValid
-@ stub GdipPathIterNextMarker
+@ stdcall GdipPathIterNextMarker(ptr ptr ptr ptr)
 @ stub GdipPathIterNextMarkerPath
 @ stub GdipPathIterNextPathType
 @ stdcall GdipPathIterNextSubpath(ptr ptr ptr ptr ptr)
 @ stdcall GdipPathIterRewind(ptr)
 @ stub GdipPlayMetafileRecord
 @ stub GdipPlayTSClientRecord
-@ stub GdipPrivateAddFontFile
+@ stdcall GdipPrivateAddFontFile(ptr wstr)
 @ stub GdipPrivateAddMemoryFont
 @ stub GdipRecordMetafile
 @ stub GdipRecordMetafileFileName
 @ stdcall GdipSetPenCustomEndCap(ptr ptr)
 @ stdcall GdipSetPenCustomStartCap(ptr ptr)
 @ stdcall GdipSetPenDashArray(ptr ptr long)
-@ stub GdipSetPenDashCap197819
+@ stdcall GdipSetPenDashCap197819(ptr long)
 @ stdcall GdipSetPenDashOffset(ptr long)
 @ stdcall GdipSetPenDashStyle(ptr long)
 @ stdcall GdipSetPenEndCap(ptr long)
 @ stdcall GdipSetSmoothingMode(ptr long)
 @ stdcall GdipSetSolidFillColor(ptr ptr)
 @ stdcall GdipSetStringFormatAlign(ptr long)
-@ stub GdipSetStringFormatDigitSubstitution
+@ stdcall GdipSetStringFormatDigitSubstitution(ptr long long)
 @ stdcall GdipSetStringFormatFlags(ptr long)
 @ stdcall GdipSetStringFormatHotkeyPrefix(ptr long)
 @ stdcall GdipSetStringFormatLineAlign(ptr long)
-@ stub GdipSetStringFormatMeasurableCharacterRanges
-@ stub GdipSetStringFormatTabStops
+@ stdcall GdipSetStringFormatMeasurableCharacterRanges(ptr long ptr)
+@ stdcall GdipSetStringFormatTabStops(ptr long long ptr)
 @ stdcall GdipSetStringFormatTrimming(ptr long)
 @ stub GdipSetTextContrast
 @ stdcall GdipSetTextRenderingHint(ptr long)
 @ stdcall GdipSetTextureTransform(ptr ptr)
 @ stub GdipSetTextureWrapMode
 @ stdcall GdipSetWorldTransform(ptr ptr)
-@ stub GdipShearMatrix
+@ stdcall GdipShearMatrix(ptr long long long)
 @ stdcall GdipStartPathFigure(ptr)
-@ stub GdipStringFormatGetGenericDefault
-@ stub GdipStringFormatGetGenericTypographic
+@ stdcall GdipStringFormatGetGenericDefault(ptr)
+@ stdcall GdipStringFormatGetGenericTypographic(ptr)
 @ stub GdipTestControl
 @ stdcall GdipTransformMatrixPoints(ptr ptr long)
 @ stdcall GdipTransformMatrixPointsI(ptr ptr long)
 @ stdcall GdipTransformPath(ptr ptr)
-@ stub GdipTransformPoints
-@ stub GdipTransformPointsI
+@ stdcall GdipTransformPoints(ptr long long ptr long)
+@ stdcall GdipTransformPointsI(ptr long long ptr long)
 @ stdcall GdipTransformRegion(ptr ptr)
 @ stub GdipTranslateClip
 @ stub GdipTranslateClipI
index ed76375..80fc5a6 100644 (file)
@@ -37,6 +37,9 @@
 #define MAX_DASHLEN (16) /* this is a limitation of gdi */
 #define INCH_HIMETRIC (2540)
 
+#define VERSION_MAGIC 0xdbc01001
+#define TENSION_CONST (0.3)
+
 COLORREF ARGB2COLORREF(ARGB color);
 extern INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2,
     REAL startAngle, REAL sweepAngle);
@@ -44,6 +47,11 @@ extern REAL gdiplus_atan2(REAL dy, REAL dx);
 extern GpStatus hresult_to_status(HRESULT res);
 extern REAL convert_unit(HDC hdc, GpUnit unit);
 
+extern void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1,
+    REAL *y1, REAL *x2, REAL *y2);
+extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj,
+    REAL tension, REAL *x, REAL *y);
+
 static inline INT roundr(REAL x)
 {
     return (INT) floor(x + 0.5);
@@ -70,6 +78,7 @@ struct GpPen{
     INT numdashes;
     REAL offset;    /* dash offset */
     GpBrush *brush;
+    GpPenAlignment align;
 };
 
 struct GpGraphics{
@@ -105,6 +114,9 @@ struct GpPathGradient{
     BOOL gamma;
     GpPointF center;
     GpPointF focus;
+    REAL* blendfac;  /* blend factors */
+    REAL* blendpos;  /* blend positions */
+    INT blendcount;
 };
 
 struct GpLineGradient{
@@ -144,6 +156,8 @@ struct GpCustomLineCap{
     BOOL fill;      /* TRUE for fill, FALSE for stroke */
     GpLineCap cap;  /* as far as I can tell, this value is ignored */
     REAL inset;     /* how much to adjust the end of the line */
+    GpLineJoin join;
+    REAL scale;
 };
 
 struct GpImage{
@@ -181,10 +195,15 @@ struct GpFont{
 struct GpStringFormat{
     INT attr;
     LANGID lang;
+    LANGID digitlang;
     StringAlignment align;
     StringTrimming trimming;
     HotkeyPrefix hkprefix;
     StringAlignment vertalign;
+    StringDigitSubstitute digitsub;
+    INT tabcount;
+    REAL firsttab;
+    REAL *tabs;
 };
 
 struct GpFontCollection{
@@ -192,8 +211,44 @@ struct GpFontCollection{
 };
 
 struct GpFontFamily{
-    TEXTMETRICW tmw;
-    WCHAR* FamilyName;
+    NEWTEXTMETRICW tmw;
+    WCHAR FamilyName[LF_FACESIZE];
+};
+
+typedef struct region_element
+{
+    DWORD type; /* Rectangle, Path, SpecialRectangle, or CombineMode */
+    union
+    {
+        GpRectF rect;
+        struct
+        {
+            GpPath* path;
+            struct
+            {
+                DWORD size;
+                DWORD magic;
+                DWORD count;
+                DWORD flags;
+            } pathheader;
+        } pathdata;
+        struct
+        {
+            struct region_element *left;  /* the original region */
+            struct region_element *right; /* what *left was combined with */
+        } combine;
+    } elementdata;
+} region_element;
+
+struct GpRegion{
+    struct
+    {
+        DWORD size;
+        DWORD checksum;
+        DWORD magic;
+        DWORD num_children;
+    } header;
+    region_element node;
 };
 
 #endif
index 81faee2..af8331c 100644 (file)
@@ -42,7 +42,6 @@
 WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
 
 /* looks-right constants */
-#define TENSION_CONST (0.3)
 #define ANCHOR_WIDTH (2.0)
 #define MAX_ITERS (50)
 
@@ -194,34 +193,6 @@ static void draw_pie(GpGraphics *graphics, REAL x, REAL y, REAL width,
         pti[2].y, pti[3].x, pti[3].y);
 }
 
-/* GdipDrawCurve helper function.
- * Calculates Bezier points from cardinal spline points. */
-static void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1,
-    REAL *y1, REAL *x2, REAL *y2)
-{
-    REAL xdiff, ydiff;
-
-    /* calculate tangent */
-    xdiff = pts[2].X - pts[0].X;
-    ydiff = pts[2].Y - pts[0].Y;
-
-    /* apply tangent to get control points */
-    *x1 = pts[1].X - tension * xdiff;
-    *y1 = pts[1].Y - tension * ydiff;
-    *x2 = pts[1].X + tension * xdiff;
-    *y2 = pts[1].Y + tension * ydiff;
-}
-
-/* GdipDrawCurve helper function.
- * Calculates Bezier points from cardinal spline endpoints. */
-static 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);
-}
-
 /* Draws the linecap the specified color and size on the hdc.  The linecap is in
  * direction of the line from x1, y1 to x2, y2 and is anchored on x2, y2. Probably
  * should not be called on an hdc that has a path you care about. */
@@ -881,6 +852,18 @@ err:
     return retval;
 }
 
+GpStatus WINGDIPAPI GdipCreateMetafileFromWmfFile(GDIPCONST WCHAR *file,
+    GDIPCONST WmfPlaceableFileHeader * placeable, GpMetafile **metafile)
+{
+    HMETAFILE hmf = GetMetaFileW(file);
+
+    TRACE("(%s, %p, %p)\n", debugstr_w(file), placeable, metafile);
+
+    if(!hmf) return InvalidParameter;
+
+    return GdipCreateMetafileFromWmf(hmf, TRUE, placeable, metafile);
+}
+
 GpStatus WINGDIPAPI GdipCreateStreamOnFile(GDIPCONST WCHAR * filename,
     UINT access, IStream **stream)
 {
@@ -1045,6 +1028,69 @@ GpStatus WINGDIPAPI GdipDrawBeziersI(GpGraphics *graphics, GpPen *pen,
     return ret;
 }
 
+GpStatus WINGDIPAPI GdipDrawClosedCurve(GpGraphics *graphics, GpPen *pen,
+    GDIPCONST GpPointF *points, INT count)
+{
+    return GdipDrawClosedCurve2(graphics, pen, points, count, 1.0);
+}
+
+GpStatus WINGDIPAPI GdipDrawClosedCurveI(GpGraphics *graphics, GpPen *pen,
+    GDIPCONST GpPoint *points, INT count)
+{
+    return GdipDrawClosedCurve2I(graphics, pen, points, count, 1.0);
+}
+
+GpStatus WINGDIPAPI GdipDrawClosedCurve2(GpGraphics *graphics, GpPen *pen,
+    GDIPCONST GpPointF *points, INT count, REAL tension)
+{
+    GpPointF *ptf;
+    GpStatus stat;
+
+    if(!graphics || !pen || !points || count <= 0)
+        return InvalidParameter;
+
+    /* make a full points copy.. */
+    ptf = GdipAlloc(sizeof(GpPointF)*(count+1));
+    if(!ptf)
+        return OutOfMemory;
+    memcpy(ptf, points, sizeof(GpPointF)*count);
+
+    /* ..and add a first point as a last one */
+    ptf[count] = ptf[0];
+
+    stat = GdipDrawCurve2(graphics, pen, ptf, count + 1, tension);
+
+    GdipFree(ptf);
+
+    return stat;
+}
+
+GpStatus WINGDIPAPI GdipDrawClosedCurve2I(GpGraphics *graphics, GpPen *pen,
+    GDIPCONST GpPoint *points, INT count, REAL tension)
+{
+    GpPointF *ptf;
+    GpStatus stat;
+    INT i;
+
+    if(!points || count <= 0)
+        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;
+    }
+
+    stat = GdipDrawClosedCurve2(graphics, pen, ptf, count, tension);
+
+    GdipFree(ptf);
+
+    return stat;
+}
+
 GpStatus WINGDIPAPI GdipDrawCurve(GpGraphics *graphics, GpPen *pen,
     GDIPCONST GpPointF *points, INT count)
 {
@@ -1929,6 +1975,18 @@ end:
     return retval;
 }
 
+GpStatus WINGDIPAPI GdipFillPolygon2(GpGraphics *graphics, GpBrush *brush,
+    GDIPCONST GpPointF *points, INT count)
+{
+    return GdipFillPolygon(graphics, brush, points, count, FillModeAlternate);
+}
+
+GpStatus WINGDIPAPI GdipFillPolygon2I(GpGraphics *graphics, GpBrush *brush,
+    GDIPCONST GpPoint *points, INT count)
+{
+    return GdipFillPolygonI(graphics, brush, points, count, FillModeAlternate);
+}
+
 GpStatus WINGDIPAPI GdipFillRectangle(GpGraphics *graphics, GpBrush *brush,
     REAL x, REAL y, REAL width, REAL height)
 {
@@ -2039,6 +2097,17 @@ GpStatus WINGDIPAPI GdipFillRectanglesI(GpGraphics *graphics, GpBrush *brush, GD
     return ret;
 }
 
+GpStatus WINGDIPAPI GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
+        GpRegion* region)
+{
+    if (!(graphics && brush && region))
+        return InvalidParameter;
+
+    FIXME("(%p, %p, %p): stub\n", graphics, brush, region);
+
+    return NotImplemented;
+}
+
 GpStatus WINGDIPAPI GdipFlush(GpGraphics *graphics, GpFlushIntention intention)
 {
     static int calls;
@@ -2152,6 +2221,20 @@ GpStatus WINGDIPAPI GdipGetWorldTransform(GpGraphics *graphics, GpMatrix *matrix
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
+        GDIPCONST WCHAR* string, INT length, GDIPCONST GpFont* font,
+        GDIPCONST RectF* layoutRect, GDIPCONST GpStringFormat *stringFormat,
+        INT regionCount, GpRegion** regions)
+{
+    if (!(graphics && string && font && layoutRect && stringFormat && regions))
+        return InvalidParameter;
+
+    FIXME("stub: %p %s %d %p %p %p %d %p\n", graphics, debugstr_w(string),
+            length, font, layoutRect, stringFormat, regionCount, regions);
+
+    return NotImplemented;
+}
+
 /* Find the smallest rectangle that bounds the text when it is printed in rect
  * according to the format options listed in format. If rect has 0 width and
  * height, then just find the smallest rectangle that bounds the text when it's
@@ -2544,3 +2627,19 @@ GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region)
 
    return NotImplemented;
 }
+
+GpStatus WINGDIPAPI GdipTransformPoints(GpGraphics *graphics, GpCoordinateSpace dst_space,
+                                        GpCoordinateSpace src_space, GpPointF *points, INT count)
+{
+    FIXME("(%p, %d, %d, %p, %d): stub\n", graphics, dst_space, src_space, points, count);
+
+    return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipTransformPointsI(GpGraphics *graphics, GpCoordinateSpace dst_space,
+                                         GpCoordinateSpace src_space, GpPoint *points, INT count)
+{
+    FIXME("(%p, %d, %d, %p, %d): stub\n", graphics, dst_space, src_space, points, count);
+
+    return NotImplemented;
+}
index 1022fb4..136afe7 100644 (file)
@@ -196,6 +196,206 @@ GpStatus WINGDIPAPI GdipAddPathBeziersI(GpPath *path, GDIPCONST GpPoint *points,
     return ret;
 }
 
+GpStatus WINGDIPAPI GdipAddPathClosedCurve(GpPath *path, GDIPCONST GpPointF *points,
+    INT count)
+{
+    return GdipAddPathClosedCurve2(path, points, count, 1.0);
+}
+
+GpStatus WINGDIPAPI GdipAddPathClosedCurveI(GpPath *path, GDIPCONST GpPoint *points,
+    INT count)
+{
+    return GdipAddPathClosedCurve2I(path, points, count, 1.0);
+}
+
+GpStatus WINGDIPAPI GdipAddPathClosedCurve2(GpPath *path, GDIPCONST GpPointF *points,
+    INT count, REAL tension)
+{
+    INT i, len_pt = (count + 1)*3-2;
+    GpPointF *pt;
+    GpPointF *pts;
+    REAL x1, x2, y1, y2;
+    GpStatus stat;
+
+    if(!path || !points || count <= 1)
+        return InvalidParameter;
+
+    pt = GdipAlloc(len_pt * sizeof(GpPointF));
+    pts = GdipAlloc((count + 1)*sizeof(GpPointF));
+    if(!pt || !pts){
+        GdipFree(pt);
+        GdipFree(pts);
+        return OutOfMemory;
+    }
+
+    /* copy source points to extend with the last one */
+    memcpy(pts, points, sizeof(GpPointF)*count);
+    pts[count] = pts[0];
+
+    tension = tension * TENSION_CONST;
+
+    for(i = 0; i < count-1; i++){
+        calc_curve_bezier(&(pts[i]), tension, &x1, &y1, &x2, &y2);
+
+        pt[3*i+2].X = x1;
+        pt[3*i+2].Y = y1;
+        pt[3*i+3].X = pts[i+1].X;
+        pt[3*i+3].Y = pts[i+1].Y;
+        pt[3*i+4].X = x2;
+        pt[3*i+4].Y = y2;
+    }
+
+    /* points [len_pt-2] and [0] are calculated
+       separetely to connect splines properly */
+    pts[0] = points[count-1];
+    pts[1] = points[0]; /* equals to start and end of a resulting path */
+    pts[2] = points[1];
+
+    calc_curve_bezier(pts, tension, &x1, &y1, &x2, &y2);
+    pt[len_pt-2].X = x1;
+    pt[len_pt-2].Y = y1;
+    pt[0].X = pts[1].X;
+    pt[0].Y = pts[1].Y;
+    pt[1].X = x2;
+    pt[1].Y = y2;
+    /* close path */
+    pt[len_pt-1].X = pt[0].X;
+    pt[len_pt-1].Y = pt[0].Y;
+
+    stat = GdipAddPathBeziers(path, pt, len_pt);
+
+    /* close figure */
+    if(stat == Ok){
+        INT count = path->pathdata.Count;
+        path->pathdata.Types[count - 1] |= PathPointTypeCloseSubpath;
+        path->newfigure = TRUE;
+    }
+
+    GdipFree(pts);
+    GdipFree(pt);
+
+    return stat;
+}
+
+GpStatus WINGDIPAPI GdipAddPathClosedCurve2I(GpPath *path, GDIPCONST GpPoint *points,
+    INT count, REAL tension)
+{
+    GpPointF *ptf;
+    INT i;
+    GpStatus stat;
+
+    if(!path || !points || count <= 1)
+        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;
+    }
+
+    stat = GdipAddPathClosedCurve2(path, ptf, count, tension);
+
+    GdipFree(ptf);
+
+    return stat;
+}
+
+GpStatus WINGDIPAPI GdipAddPathCurve(GpPath *path, GDIPCONST GpPointF *points, INT count)
+{
+    if(!path || !points || count <= 1)
+        return InvalidParameter;
+
+   return GdipAddPathCurve2(path, points, count, 1.0);
+}
+
+GpStatus WINGDIPAPI GdipAddPathCurveI(GpPath *path, GDIPCONST GpPoint *points, INT count)
+{
+    if(!path || !points || count <= 1)
+        return InvalidParameter;
+
+   return GdipAddPathCurve2I(path, points, count, 1.0);
+}
+
+GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points, INT count,
+    REAL tension)
+{
+    INT i, len_pt = count*3-2;
+    GpPointF *pt;
+    REAL x1, x2, y1, y2;
+    GpStatus stat;
+
+    if(!path || !points || count <= 1)
+        return InvalidParameter;
+
+    pt = GdipAlloc(len_pt * sizeof(GpPointF));
+    if(!pt)
+        return OutOfMemory;
+
+    tension = tension * TENSION_CONST;
+
+    calc_curve_bezier_endp(points[0].X, points[0].Y, points[1].X, points[1].Y,
+        tension, &x1, &y1);
+
+    pt[0].X = points[0].X;
+    pt[0].Y = points[0].Y;
+    pt[1].X = x1;
+    pt[1].Y = y1;
+
+    for(i = 0; i < count-2; i++){
+        calc_curve_bezier(&(points[i]), tension, &x1, &y1, &x2, &y2);
+
+        pt[3*i+2].X = x1;
+        pt[3*i+2].Y = y1;
+        pt[3*i+3].X = points[i+1].X;
+        pt[3*i+3].Y = points[i+1].Y;
+        pt[3*i+4].X = x2;
+        pt[3*i+4].Y = y2;
+    }
+
+    calc_curve_bezier_endp(points[count-1].X, points[count-1].Y,
+        points[count-2].X, points[count-2].Y, tension, &x1, &y1);
+
+    pt[len_pt-2].X = x1;
+    pt[len_pt-2].Y = y1;
+    pt[len_pt-1].X = points[count-1].X;
+    pt[len_pt-1].Y = points[count-1].Y;
+
+    stat = GdipAddPathBeziers(path, pt, len_pt);
+
+    GdipFree(pt);
+
+    return stat;
+}
+
+GpStatus WINGDIPAPI GdipAddPathCurve2I(GpPath *path, GDIPCONST GpPoint *points,
+    INT count, REAL tension)
+{
+    GpPointF *ptf;
+    INT i;
+    GpStatus stat;
+
+    if(!path || !points || count <= 1)
+        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;
+    }
+
+    stat = GdipAddPathCurve2(path, ptf, count, tension);
+
+    GdipFree(ptf);
+
+    return stat;
+}
+
 GpStatus WINGDIPAPI GdipAddPathEllipse(GpPath *path, REAL x, REAL y, REAL width,
     REAL height)
 {
@@ -729,6 +929,12 @@ GpStatus WINGDIPAPI GdipGetPointCount(GpPath *path, INT *count)
 
 GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPointI(GpPath* path, INT x, INT y,
     GpPen *pen, GpGraphics *graphics, BOOL *result)
+{
+    return GdipIsOutlineVisiblePathPoint(path, x, y, pen, graphics, result);
+}
+
+GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPoint(GpPath* path, REAL x, REAL y,
+    GpPen *pen, GpGraphics *graphics, BOOL *result)
 {
     static int calls;
 
@@ -741,6 +947,23 @@ GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPointI(GpPath* path, INT x, INT y,
     return NotImplemented;
 }
 
+GpStatus WINGDIPAPI GdipIsVisiblePathPointI(GpPath* path, INT x, INT y, GpGraphics *graphics, BOOL *result)
+{
+    return GdipIsVisiblePathPoint(path, x, y, graphics, result);
+}
+
+GpStatus WINGDIPAPI GdipIsVisiblePathPoint(GpPath* path, REAL x, REAL y, GpGraphics *graphics, BOOL *result)
+{
+    static int calls;
+
+    if(!path) return InvalidParameter;
+
+    if(!(calls++))
+        FIXME("not implemented\n");
+
+    return NotImplemented;
+}
+
 GpStatus WINGDIPAPI GdipStartPathFigure(GpPath *path)
 {
     if(!path)
index bf2ac35..197665d 100644 (file)
@@ -244,7 +244,7 @@ GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage)
 {
     if (!(image && cloneImage)) return InvalidParameter;
 
-    FIXME("stub: %p, %p", image, cloneImage);
+    FIXME("stub: %p, %p\n", image, cloneImage);
 
     return NotImplemented;
 }
@@ -270,6 +270,47 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromFile(GDIPCONST WCHAR* filename,
     return stat;
 }
 
+GpStatus WINGDIPAPI GdipCreateBitmapFromGdiDib(GDIPCONST BITMAPINFO* info,
+                                               VOID *bits, GpBitmap **bitmap)
+{
+    DWORD height, stride;
+    PixelFormat format;
+
+    FIXME("(%p, %p, %p) - partially implemented\n", info, bits, bitmap);
+
+    height = abs(info->bmiHeader.biHeight);
+    stride = ((info->bmiHeader.biWidth * info->bmiHeader.biBitCount + 31) >> 3) & ~3;
+
+    if(info->bmiHeader.biHeight > 0) /* bottom-up */
+    {
+        bits = (BYTE*)bits + (height - 1) * stride;
+        stride = -stride;
+    }
+
+    switch(info->bmiHeader.biBitCount) {
+    case 1:
+        format = PixelFormat1bppIndexed;
+        break;
+    case 4:
+        format = PixelFormat4bppIndexed;
+        break;
+    case 8:
+        format = PixelFormat8bppIndexed;
+        break;
+    case 24:
+        format = PixelFormat24bppRGB;
+        break;
+    default:
+        FIXME("don't know how to handle %d bpp\n", info->bmiHeader.biBitCount);
+        *bitmap = NULL;
+        return InvalidParameter;
+    }
+
+    return GdipCreateBitmapFromScan0(info->bmiHeader.biWidth, height, stride, format,
+                                     bits, bitmap);
+
+}
+
 /* FIXME: no icm */
 GpStatus WINGDIPAPI GdipCreateBitmapFromFileICM(GDIPCONST WCHAR* filename,
     GpBitmap **bitmap)
@@ -277,6 +318,26 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromFileICM(GDIPCONST WCHAR* filename,
     return GdipCreateBitmapFromFile(filename, bitmap);
 }
 
+GpStatus WINGDIPAPI GdipCreateBitmapFromResource(HINSTANCE hInstance,
+    GDIPCONST WCHAR* lpBitmapName, GpBitmap** bitmap)
+{
+    HBITMAP hbm;
+    GpStatus stat = InvalidParameter;
+
+    if(!lpBitmapName || !bitmap)
+        return InvalidParameter;
+
+    /* load DIB */
+    hbm = (HBITMAP)LoadImageW(hInstance,lpBitmapName,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
+
+    if(hbm){
+        stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, bitmap);
+        DeleteObject(hbm);
+    }
+
+    return stat;
+}
+
 GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
     HBITMAP* hbmReturn, ARGB background)
 {
@@ -942,6 +1003,9 @@ static encode_image_func *const encode_image_funcs[NUM_ENCODERS_SUPPORTED] = {
     encode_image_BMP,
 };
 
+/*****************************************************************************
+ * GdipSaveImageToStream [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream* stream,
     GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
 {
@@ -1024,6 +1088,9 @@ GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream* stream,
     return stat;
 }
 
+/*****************************************************************************
+ * GdipSetImagePalette [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipSetImagePalette(GpImage *image,
     GDIPCONST ColorPalette *palette)
 {
@@ -1070,6 +1137,9 @@ static const ImageCodecInfo codecs[NUM_ENCODERS_SUPPORTED] =
         },
     };
 
+/*****************************************************************************
+ * GdipGetImageEncodersSize [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipGetImageEncodersSize(UINT *numEncoders, UINT *size)
 {
     if (!numEncoders || !size)
@@ -1081,6 +1151,9 @@ GpStatus WINGDIPAPI GdipGetImageEncodersSize(UINT *numEncoders, UINT *size)
     return Ok;
 }
 
+/*****************************************************************************
+ * GdipGetImageEncoders [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipGetImageEncoders(UINT numEncoders, UINT size, ImageCodecInfo *encoders)
 {
     if (!encoders ||
@@ -1092,6 +1165,10 @@ GpStatus WINGDIPAPI GdipGetImageEncoders(UINT numEncoders, UINT size, ImageCodec
 
     return Ok;
 }
+
+/*****************************************************************************
+ * GdipCreateBitmapFromHBITMAP [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBitmap** bitmap)
 {
     BITMAP bm;
@@ -1138,6 +1215,9 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBi
     return retval;
 }
 
+/*****************************************************************************
+ * GdipSetEffectParameters [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipSetEffectParameters(CGpEffect *effect,
     const VOID *params, const UINT size)
 {
@@ -1149,6 +1229,9 @@ GpStatus WINGDIPAPI GdipSetEffectParameters(CGpEffect *effect,
     return NotImplemented;
 }
 
+/*****************************************************************************
+ * GdipGetImageFlags [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipGetImageFlags(GpImage *image, UINT *flags)
 {
     if(!image || !flags)
index eb83884..a29508d 100644 (file)
@@ -50,6 +50,11 @@ static void matrix_multiply(GDIPCONST REAL * left, GDIPCONST REAL * right, REAL
     memcpy(out, temp, 6 * sizeof(REAL));
 }
 
+static REAL matrix_det(GDIPCONST GpMatrix *matrix)
+{
+    return matrix->matrix[0]*matrix->matrix[3] - matrix->matrix[1]*matrix->matrix[2];
+}
+
 GpStatus WINGDIPAPI GdipCreateMatrix2(REAL m11, REAL m12, REAL m21, REAL m22,
     REAL dx, REAL dy, GpMatrix **matrix)
 {
@@ -158,6 +163,43 @@ GpStatus WINGDIPAPI GdipGetMatrixElements(GDIPCONST GpMatrix *matrix,
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipInvertMatrix(GpMatrix *matrix)
+{
+    GpMatrix copy;
+    REAL det;
+    BOOL invertible;
+
+    if(!matrix)
+        return InvalidParameter;
+
+    GdipIsMatrixInvertible(matrix, &invertible);
+    if(!invertible)
+        return InvalidParameter;
+
+    det = matrix_det(matrix);
+
+    copy = *matrix;
+    /* store result */
+    matrix->matrix[0] =   copy.matrix[3] / det;
+    matrix->matrix[1] =  -copy.matrix[1] / det;
+    matrix->matrix[2] =  -copy.matrix[2] / det;
+    matrix->matrix[3] =   copy.matrix[0] / det;
+    matrix->matrix[4] =  (copy.matrix[2]*copy.matrix[5]-copy.matrix[3]*copy.matrix[4]) / det;
+    matrix->matrix[5] = -(copy.matrix[0]*copy.matrix[5]-copy.matrix[1]*copy.matrix[4]) / det;
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *result)
+{
+    if(!matrix || !result)
+        return InvalidParameter;
+
+    *result = (fabs(matrix_det(matrix)) >= 1e-5);
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipMultiplyMatrix(GpMatrix *matrix, GpMatrix* matrix2,
     GpMatrixOrder order)
 {
@@ -238,6 +280,30 @@ GpStatus WINGDIPAPI GdipSetMatrixElements(GpMatrix *matrix, REAL m11, REAL m12,
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipShearMatrix(GpMatrix *matrix, REAL shearX, REAL shearY,
+    GpMatrixOrder order)
+{
+    REAL shear[6];
+
+    if(!matrix)
+        return InvalidParameter;
+
+    /* prepare transformation matrix */
+    shear[0] = 1.0;
+    shear[1] = shearY;
+    shear[2] = shearX;
+    shear[3] = 1.0;
+    shear[4] = 0.0;
+    shear[5] = 0.0;
+
+    if(order == MatrixOrderAppend)
+        matrix_multiply(matrix->matrix, shear, matrix->matrix);
+    else
+        matrix_multiply(shear, matrix->matrix, matrix->matrix);
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts,
                                               INT count)
 {
index abb5dbb..95f1774 100644 (file)
@@ -31,24 +31,30 @@ GpStatus WINGDIPAPI GdipCreatePathIter(GpPathIterator **iterator, GpPath* path)
 {
     INT size;
 
-    if(!iterator || !path)
+    if(!iterator)
         return InvalidParameter;
 
-    size = path->pathdata.Count;
-
     *iterator = GdipAlloc(sizeof(GpPathIterator));
     if(!*iterator)  return OutOfMemory;
 
-    (*iterator)->pathdata.Types = GdipAlloc(size);
-    (*iterator)->pathdata.Points = GdipAlloc(size * sizeof(PointF));
+    if(path){
+        size = path->pathdata.Count;
 
-    memcpy((*iterator)->pathdata.Types, path->pathdata.Types, size);
-    memcpy((*iterator)->pathdata.Points, path->pathdata.Points,
-           size * sizeof(PointF));
-    (*iterator)->pathdata.Count = size;
+        (*iterator)->pathdata.Types  = GdipAlloc(size);
+        (*iterator)->pathdata.Points = GdipAlloc(size * sizeof(PointF));
+
+        memcpy((*iterator)->pathdata.Types, path->pathdata.Types, size);
+        memcpy((*iterator)->pathdata.Points, path->pathdata.Points,size * sizeof(PointF));
+        (*iterator)->pathdata.Count = size;
+    }
+    else{
+        (*iterator)->pathdata.Types  = NULL;
+        (*iterator)->pathdata.Points = NULL;
+        (*iterator)->pathdata.Count  = 0;
+    }
 
-    (*iterator)->subpath_pos = 0;
-    (*iterator)->marker_pos = 0;
+    (*iterator)->subpath_pos  = 0;
+    (*iterator)->marker_pos   = 0;
     (*iterator)->pathtype_pos = 0;
 
     return Ok;
@@ -105,16 +111,62 @@ GpStatus WINGDIPAPI GdipPathIterHasCurve(GpPathIterator* iterator, BOOL* hasCurv
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipPathIterGetSubpathCount(GpPathIterator* iterator, INT* count)
+{
+    INT i;
+
+    if(!iterator || !count)
+        return InvalidParameter;
+
+    *count = 0;
+    for(i = 0; i < iterator->pathdata.Count; i++){
+        if(iterator->pathdata.Types[i] == PathPointTypeStart)
+            (*count)++;
+    }
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipPathIterNextMarker(GpPathIterator* iterator, INT *resultCount,
+    INT* startIndex, INT* endIndex)
+{
+    INT i;
+
+    if(!iterator || !startIndex || !endIndex)
+        return InvalidParameter;
+
+    *resultCount = 0;
+
+    /* first call could start with second point as all subsequent, cause
+       path couldn't contain only one */
+    for(i = iterator->marker_pos + 1; i < iterator->pathdata.Count; i++){
+        if((iterator->pathdata.Types[i] & PathPointTypePathMarker) ||
+           (i == iterator->pathdata.Count - 1)){
+            *startIndex = iterator->marker_pos;
+            if(iterator->marker_pos > 0) (*startIndex)++;
+            *endIndex   = iterator->marker_pos = i;
+            *resultCount= *endIndex - *startIndex + 1;
+            break;
+        }
+    }
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipPathIterNextSubpath(GpPathIterator* iterator,
     INT *resultCount, INT* startIndex, INT* endIndex, BOOL* isClosed)
 {
     INT i, count;
 
-    if(!iterator)
+    if(!iterator || !startIndex || !endIndex || !isClosed || !resultCount)
         return InvalidParameter;
 
     count = iterator->pathdata.Count;
 
+    /* iterator created with NULL path */
+    if(count == 0)
+        return Ok;
+
     if(iterator->subpath_pos == count){
         *startIndex = *endIndex = *resultCount = 0;
         *isClosed = 1;
index 852494f..104d9de 100644 (file)
@@ -116,6 +116,8 @@ 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->customstart = NULL;
+    gp_pen->customend = NULL;
 
     if(!((gp_pen->unit == UnitWorld) || (gp_pen->unit == UnitPixel))) {
         FIXME("UnitWorld, UnitPixel only supported units\n");
@@ -163,6 +165,32 @@ GpStatus WINGDIPAPI GdipGetPenColor(GpPen *pen, ARGB *argb)
     return GdipGetSolidFillColor(((GpSolidFill*)pen->brush), argb);
 }
 
+GpStatus WINGDIPAPI GdipGetPenCustomEndCap(GpPen *pen, GpCustomLineCap** customCap)
+{
+    if(!pen || !customCap)
+        return InvalidParameter;
+
+    if(!pen->customend){
+        *customCap = NULL;
+        return Ok;
+    }
+
+    return GdipCloneCustomLineCap(pen->customend, customCap);
+}
+
+GpStatus WINGDIPAPI GdipGetPenCustomStartCap(GpPen *pen, GpCustomLineCap** customCap)
+{
+    if(!pen || !customCap)
+        return InvalidParameter;
+
+    if(!pen->customstart){
+        *customCap = NULL;
+        return Ok;
+    }
+
+    return GdipCloneCustomLineCap(pen->customstart, customCap);
+}
+
 GpStatus WINGDIPAPI GdipGetPenDashArray(GpPen *pen, REAL *dash, INT count)
 {
     if(!pen || !dash || count > pen->numdashes)
@@ -187,6 +215,16 @@ GpStatus WINGDIPAPI GdipGetPenDashCap197819(GpPen *pen, GpDashCap *dashCap)
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipGetPenDashCount(GpPen *pen, INT *count)
+{
+    if(!pen || !count)
+        return InvalidParameter;
+
+    *count = pen->numdashes;
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipGetPenDashOffset(GpPen *pen, REAL *offset)
 {
     if(!pen || !offset)
@@ -227,6 +265,16 @@ GpStatus WINGDIPAPI GdipGetPenLineJoin(GpPen *pen, GpLineJoin *lineJoin)
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipGetPenMode(GpPen *pen, GpPenAlignment *mode)
+{
+    if(!pen || !mode)
+        return InvalidParameter;
+
+    *mode = pen->align;
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipGetPenMiterLimit(GpPen *pen, REAL *miterLimit)
 {
     if(!pen || !miterLimit)
@@ -292,7 +340,8 @@ GpStatus WINGDIPAPI GdipSetPenCustomEndCap(GpPen *pen, GpCustomLineCap* customCa
     GpCustomLineCap * cap;
     GpStatus ret;
 
-    if(!pen || !customCap) return InvalidParameter;
+    /* native crashes on pen == NULL, customCap != NULL */
+    if(!customCap) return InvalidParameter;
 
     if((ret = GdipCloneCustomLineCap(customCap, &cap)) == Ok){
         GdipDeleteCustomLineCap(pen->customend);
@@ -308,7 +357,8 @@ GpStatus WINGDIPAPI GdipSetPenCustomStartCap(GpPen *pen, GpCustomLineCap* custom
     GpCustomLineCap * cap;
     GpStatus ret;
 
-    if(!pen || !customCap) return InvalidParameter;
+    /* native crashes on pen == NULL, customCap != NULL */
+    if(!customCap) return InvalidParameter;
 
     if((ret = GdipCloneCustomLineCap(customCap, &cap)) == Ok){
         GdipDeleteCustomLineCap(pen->customstart);
@@ -357,6 +407,16 @@ GpStatus WINGDIPAPI GdipSetPenDashArray(GpPen *pen, GDIPCONST REAL *dash,
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipSetPenDashCap197819(GpPen *pen, GpDashCap dashCap)
+{
+    if(!pen)
+        return InvalidParameter;
+
+    pen->dashcap = dashCap;
+
+    return Ok;
+}
+
 /* FIXME: dash offset not used */
 GpStatus WINGDIPAPI GdipSetPenDashOffset(GpPen *pen, REAL offset)
 {
@@ -461,12 +521,11 @@ GpStatus WINGDIPAPI GdipSetPenWidth(GpPen *pen, REAL width)
     return Ok;
 }
 
-
-GpStatus WINGDIPAPI GdipSetPenMode(GpPen *pen, GpPenAlignment penAlignment)
+GpStatus WINGDIPAPI GdipSetPenMode(GpPen *pen, GpPenAlignment mode)
 {
     if(!pen)    return InvalidParameter;
 
-    FIXME("stub (%d)\n", penAlignment);
+    pen->align = mode;
 
     return Ok;
 }
index 3d95723..c4007b3 100644 (file)
@@ -32,8 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
 
 /**********************************************************
  *
- * Data returned by GdipGetRegionData (for rectangle based regions)
- * looks something like this:
+ * Data returned by GdipGetRegionData looks something like this:
  *
  * struct region_data_header
  * {
@@ -43,7 +42,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
  *   DWORD num_ops;  number of combining ops * 2
  * };
  *
- * Then follows a sequence of combining ops and RECTFs.
+ * Then follows a sequence of combining ops and region elements.
+ *
+ * A region element is either a RECTF or some path data.
  *
  * Combining ops are just stored as their CombineMode value.
  *
@@ -51,22 +52,99 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
  * stored as 0x10000002 (with no following RECTF) and an infinite rect
  * is stored as 0x10000003 (again with no following RECTF).
  *
- * The combining ops are stored in the reverse order to the RECTFs and in the
- * reverse order to which the region was constructed.
+ * Path data is preceded by the DWORD 0x10000001.  Then follows a
+ * DWORD size and then size bytes of data.
+ *
+ * The combining ops are stored in the reverse order to the region
+ * elements and in the reverse order to which the region was
+ * constructed.
  *
- * When two or more complex regions (ie those with more than one rect)
- * are combined, the combining op for the two regions comes first,
- * then the combining ops for the rects in region 1, followed by the
- * rects for region 1, then follows the combining ops for region 2 and
- * finally region 2's rects.  Presumably you're supposed to use the
- * 0x10000000 rect header to find the end of the op list (the count of
- * the rects in each region is not stored).
+ * When two or more complex regions (ie those with more than one
+ * element) are combined, the combining op for the two regions comes
+ * first, then the combining ops for the region elements in region 1,
+ * followed by the region elements for region 1, then follows the
+ * combining ops for region 2 and finally region 2's region elements.
+ * Presumably you're supposed to use the 0x1000000x header to find the
+ * end of the op list (the count of the elements in each region is not
+ * stored).
  *
- * When a simple region (1 rect) is combined, it's treated as if a single rect
- * is being combined.
+ * When a simple region (1 element) is combined, it's treated as if a
+ * single rect/path is being combined.
  *
  */
 
+typedef enum RegionType
+{
+    RegionDataRect          = 0x10000000,
+    RegionDataPath          = 0x10000001,
+    RegionDataEmptyRect     = 0x10000002,
+    RegionDataInfiniteRect  = 0x10000003,
+} RegionType;
+
+/* Header size as far as header->size is concerned. This doesn't include
+ * header->size or header->checksum
+ */
+static const INT sizeheader_size = sizeof(DWORD) * 2;
+
+static inline INT get_element_size(const region_element* element)
+{
+    INT needed = sizeof(DWORD); /* DWORD for the type */
+    switch(element->type)
+    {
+        case RegionDataRect:
+            return needed + sizeof(GpRect);
+        case RegionDataPath:
+             needed += element->elementdata.pathdata.pathheader.size;
+             needed += sizeof(DWORD); /* Extra DWORD for pathheader.size */
+             return needed;
+        case RegionDataEmptyRect:
+        case RegionDataInfiniteRect:
+            return needed;
+        default:
+            needed += get_element_size(element->elementdata.combine.left);
+            needed += get_element_size(element->elementdata.combine.right);
+            return needed;
+    }
+
+    return 0;
+}
+
+/* Does not check parameters, caller must do that */
+static inline GpStatus init_region(GpRegion* region, const RegionType type)
+{
+    region->node.type       = type;
+    region->header.checksum = 0xdeadbeef;
+    region->header.magic    = VERSION_MAGIC;
+    region->header.num_children  = 0;
+    region->header.size     = sizeheader_size + get_element_size(&region->node);
+
+    return Ok;
+}
+
+static inline void delete_element(region_element* element)
+{
+    switch(element->type)
+    {
+        case RegionDataRect:
+            break;
+        case RegionDataPath:
+            GdipDeletePath(element->elementdata.pathdata.path);
+            break;
+        case RegionDataEmptyRect:
+        case RegionDataInfiniteRect:
+            break;
+        default:
+            delete_element(element->elementdata.combine.left);
+            delete_element(element->elementdata.combine.right);
+            GdipFree(element->elementdata.combine.left);
+            GdipFree(element->elementdata.combine.right);
+            break;
+    }
+}
+
+/*****************************************************************************
+ * GdipCloneRegion [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipCloneRegion(GpRegion *region, GpRegion **clone)
 {
     FIXME("(%p %p): stub\n", region, clone);
@@ -104,10 +182,16 @@ GpStatus WINGDIPAPI GdipCombineRegionRegion(GpRegion *region1, GpRegion *region2
 
 GpStatus WINGDIPAPI GdipCreateRegion(GpRegion **region)
 {
-    FIXME("(%p): stub\n", region);
+    if(!region)
+        return InvalidParameter;
 
-    *region = NULL;
-    return NotImplemented;
+    TRACE("%p\n", region);
+
+    *region = GdipAlloc(sizeof(GpRegion));
+    if(!*region)
+        return OutOfMemory;
+
+    return init_region(*region, RegionDataInfiniteRect);
 }
 
 GpStatus WINGDIPAPI GdipCreateRegionPath(GpPath *path, GpRegion **region)
@@ -152,8 +236,15 @@ GpStatus WINGDIPAPI GdipCreateRegionHrgn(HRGN hrgn, GpRegion **region)
 
 GpStatus WINGDIPAPI GdipDeleteRegion(GpRegion *region)
 {
-    FIXME("(%p): stub\n", region);
-    return NotImplemented;
+    TRACE("%p\n", region);
+
+    if (!region)
+        return InvalidParameter;
+
+    delete_element(&region->node);
+    GdipFree(region);
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics, GpRectF *rect)
@@ -179,11 +270,20 @@ GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size,
 
 GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed)
 {
-    FIXME("(%p, %p): stub\n", region, needed);
+    if (!(region && needed))
+        return InvalidParameter;
 
-    return NotImplemented;
+    TRACE("%p, %p\n", region, needed);
+
+    /* header.size doesn't count header.size and header.checksum */
+    *needed = region->header.size + sizeof(DWORD) * 2;
+
+    return Ok;
 }
 
+/*****************************************************************************
+ * GdipGetRegionHRgn [GDIPLUS.@]
+ */
 GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *region, GpGraphics *graphics, HRGN *hrgn)
 {
     FIXME("(%p, %p, %p): stub\n", region, graphics, hrgn);
@@ -216,22 +316,32 @@ GpStatus WINGDIPAPI GdipIsInfiniteRegion(GpRegion *region, GpGraphics *graphics,
 
 GpStatus WINGDIPAPI GdipSetEmpty(GpRegion *region)
 {
-    static int calls;
+    GpStatus stat;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
+    TRACE("%p\n", region);
 
-    return NotImplemented;
+    if (!region)
+        return InvalidParameter;
+
+    delete_element(&region->node);
+    stat = init_region(region, RegionDataEmptyRect);
+
+    return stat;
 }
 
 GpStatus WINGDIPAPI GdipSetInfinite(GpRegion *region)
 {
-    static int calls;
+    GpStatus stat;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
+    if (!region)
+        return InvalidParameter;
 
-    return NotImplemented;
+    TRACE("%p\n", region);
+
+    delete_element(&region->node);
+    stat = init_region(region, RegionDataInfiniteRect);
+
+    return stat;
 }
 
 GpStatus WINGDIPAPI GdipTransformRegion(GpRegion *region, GpMatrix *matrix)
index bd5d6ad..201201a 100644 (file)
@@ -43,7 +43,13 @@ GpStatus WINGDIPAPI GdipCreateStringFormat(INT attr, LANGID lang,
 
     (*format)->attr = attr;
     (*format)->lang = lang;
+    (*format)->digitlang = LANG_NEUTRAL;
     (*format)->trimming = StringTrimmingCharacter;
+    (*format)->digitsub = StringDigitSubstituteUser;
+    /* tabstops */
+    (*format)->tabcount = 0;
+    (*format)->firsttab = 0.0;
+    (*format)->tabs = NULL;
 
     return Ok;
 }
@@ -53,11 +59,29 @@ GpStatus WINGDIPAPI GdipDeleteStringFormat(GpStringFormat *format)
     if(!format)
         return InvalidParameter;
 
+    GdipFree(format->tabs);
     GdipFree(format);
 
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipStringFormatGetGenericDefault(GpStringFormat **format)
+{
+    GpStatus stat;
+
+    if (!format)
+        return InvalidParameter;
+
+    stat = GdipCreateStringFormat(0, LANG_NEUTRAL, format);
+    if(stat != Ok)
+        return stat;
+
+    (*format)->align     = StringAlignmentNear;
+    (*format)->vertalign = StringAlignmentNear;
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipGetStringFormatAlign(GpStringFormat *format,
     StringAlignment *align)
 {
@@ -69,6 +93,29 @@ GpStatus WINGDIPAPI GdipGetStringFormatAlign(GpStringFormat *format,
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipGetStringFormatDigitSubstitution(GDIPCONST GpStringFormat *format,
+    LANGID *language, StringDigitSubstitute *substitute)
+{
+    if(!format)
+        return InvalidParameter;
+
+    if(language)    *language   = format->digitlang;
+    if(substitute)  *substitute = format->digitsub;
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipGetStringFormatFlags(GDIPCONST GpStringFormat* format,
+        INT* flags)
+{
+    if (!(format && flags))
+        return InvalidParameter;
+
+    *flags = format->attr;
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipGetStringFormatHotkeyPrefix(GDIPCONST GpStringFormat
     *format, INT *hkpx)
 {
@@ -91,6 +138,43 @@ GpStatus WINGDIPAPI GdipGetStringFormatLineAlign(GpStringFormat *format,
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipGetStringFormatMeasurableCharacterRangeCount(
+        GDIPCONST GpStringFormat* format, INT* count)
+{
+    if (!(format && count))
+        return InvalidParameter;
+
+    FIXME("stub: %p %p\n", format, count);
+
+    return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipGetStringFormatTabStopCount(GDIPCONST GpStringFormat *format,
+    INT *count)
+{
+    if(!format || !count)
+        return InvalidParameter;
+
+    *count = format->tabcount;
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipGetStringFormatTabStops(GDIPCONST GpStringFormat *format, INT count,
+    REAL *firsttab, REAL *tabs)
+{
+    if(!format || !firsttab || !tabs)
+        return InvalidParameter;
+
+    /* native simply crashes on count < 0 */
+    if(count != 0)
+        memcpy(tabs, format->tabs, sizeof(REAL)*count);
+
+    *firsttab = format->firsttab;
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipGetStringFormatTrimming(GpStringFormat *format,
     StringTrimming *trimming)
 {
@@ -113,6 +197,19 @@ GpStatus WINGDIPAPI GdipSetStringFormatAlign(GpStringFormat *format,
     return Ok;
 }
 
+/*FIXME: digit substitution actually not implemented, get/set only */
+GpStatus WINGDIPAPI GdipSetStringFormatDigitSubstitution(GpStringFormat *format,
+    LANGID language, StringDigitSubstitute substitute)
+{
+    if(!format)
+        return InvalidParameter;
+
+    format->digitlang = language;
+    format->digitsub  = substitute;
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipSetStringFormatHotkeyPrefix(GpStringFormat *format,
     INT hkpx)
 {
@@ -135,6 +232,47 @@ GpStatus WINGDIPAPI GdipSetStringFormatLineAlign(GpStringFormat *format,
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipSetStringFormatMeasurableCharacterRanges(GpStringFormat*
+        format, INT rangeCount, GDIPCONST CharacterRange* ranges)
+{
+    if (!(format && rangeCount && ranges))
+        return InvalidParameter;
+
+    FIXME("stub: %p, %d, %p\n", format, rangeCount, ranges);
+
+    return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipSetStringFormatTabStops(GpStringFormat *format, REAL firsttab,
+    INT count, GDIPCONST REAL *tabs)
+{
+    if(!format || !tabs)
+        return InvalidParameter;
+
+    if(count > 0){
+        if(firsttab < 0.0)  return NotImplemented;
+        /* first time allocation */
+        if(format->tabcount == 0){
+            format->tabs = GdipAlloc(sizeof(REAL)*count);
+            if(!format->tabs)
+                return OutOfMemory;
+        }
+        /* reallocation */
+        if((format->tabcount < count) && (format->tabcount > 0)){
+            REAL *ptr;
+            ptr = HeapReAlloc(GetProcessHeap(), 0, format->tabs, sizeof(REAL)*count);
+            if(!ptr)
+                return OutOfMemory;
+            format->tabs = ptr;
+        }
+        format->firsttab = firsttab;
+        format->tabcount = count;
+        memcpy(format->tabs, tabs, sizeof(REAL)*count);
+    }
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipSetStringFormatTrimming(GpStringFormat *format,
     StringTrimming trimming)
 {
@@ -163,7 +301,41 @@ GpStatus WINGDIPAPI GdipCloneStringFormat(GDIPCONST GpStringFormat *format, GpSt
 
     **newFormat = *format;
 
+    if(format->tabcount > 0){
+        (*newFormat)->tabs = GdipAlloc(sizeof(REAL) * format->tabcount);
+        if(!(*newFormat)->tabs){
+            GdipFree(*newFormat);
+            return OutOfMemory;
+        }
+        memcpy((*newFormat)->tabs, format->tabs, sizeof(REAL) * format->tabcount);
+    }
+    else
+        (*newFormat)->tabs = NULL;
+
     TRACE("%p %p\n",format,newFormat);
 
     return Ok;
 }
+
+GpStatus WINGDIPAPI GdipStringFormatGetGenericTypographic(GpStringFormat **format)
+{
+    GpStatus stat;
+
+    if(!format)
+        return InvalidParameter;
+
+    stat = GdipCreateStringFormat(StringFormatFlagsNoFitBlackBox |
+                                  StringFormatFlagsLineLimit |
+                                  StringFormatFlagsNoClip, LANG_NEUTRAL, format);
+    if(stat != Ok)
+        return stat;
+
+    (*format)->digitlang = LANG_NEUTRAL;
+    (*format)->digitsub  = StringDigitSubstituteUser;
+    (*format)->trimming  = StringTrimmingNone;
+    (*format)->hkprefix  = HotkeyPrefixNone;
+    (*format)->align     = StringAlignmentNear;
+    (*format)->vertalign = StringAlignmentNear;
+
+    return Ok;
+}
index 8e1148d..bc52bd5 100644 (file)
@@ -227,6 +227,14 @@ enum StringAlignment
     StringAlignmentFar     = 2
 };
 
+enum  StringDigitSubstitute
+{
+    StringDigitSubstituteUser        = 0,
+    StringDigitSubstituteNone        = 1,
+    StringDigitSubstituteNational    = 2,
+    StringDigitSubstituteTraditional = 3
+};
+
 enum StringFormatFlags
 {
     StringFormatFlagsDirectionRightToLeft  = 0x00000001,
@@ -314,6 +322,13 @@ enum FlushIntention
     FlushIntentionSync  = 1
 };
 
+enum CoordinateSpace
+{
+    CoordinateSpaceWorld,
+    CoordinateSpacePage,
+    CoordinateSpaceDevice
+};
+
 #ifndef __cplusplus
 
 typedef enum Unit Unit;
@@ -339,6 +354,7 @@ typedef enum EmfType EmfType;
 typedef enum CompositingMode CompositingMode;
 typedef enum TextRenderingHint TextRenderingHint;
 typedef enum StringAlignment StringAlignment;
+typedef enum StringDigitSubstitute StringDigitSubstitute;
 typedef enum StringTrimming StringTrimming;
 typedef enum FontStyle FontStyle;
 typedef enum StringFormatFlags StringFormatFlags;
@@ -347,6 +363,7 @@ typedef enum PenAlignment GpPenAlignment;
 typedef enum ImageCodecFlags ImageCodecFlags;
 typedef enum CombineMode CombineMode;
 typedef enum FlushIntention FlushIntention;
+typedef enum CoordinateSpace CoordinateSpace;
 
 #endif /* end of c typedefs */
 
index 9ef7ad7..dc938ac 100644 (file)
@@ -33,19 +33,25 @@ GpStatus WINGDIPAPI GdipCreatePen2(GpBrush*,REAL,GpUnit,GpPen**);
 GpStatus WINGDIPAPI GdipDeletePen(GpPen*);
 GpStatus WINGDIPAPI GdipGetPenBrushFill(GpPen*,GpBrush**);
 GpStatus WINGDIPAPI GdipGetPenColor(GpPen*,ARGB*);
+GpStatus WINGDIPAPI GdipGetPenCustomStartCap(GpPen*,GpCustomLineCap**);
+GpStatus WINGDIPAPI GdipGetPenCustomEndCap(GpPen*,GpCustomLineCap**);
 GpStatus WINGDIPAPI GdipGetPenDashArray(GpPen*,REAL*,INT);
+GpStatus WINGDIPAPI GdipGetPenDashCount(GpPen*,INT*);
 GpStatus WINGDIPAPI GdipGetPenDashOffset(GpPen*,REAL*);
 GpStatus WINGDIPAPI GdipGetPenDashStyle(GpPen*,GpDashStyle*);
+GpStatus WINGDIPAPI GdipGetPenMode(GpPen*,GpPenAlignment*);
 GpStatus WINGDIPAPI GdipSetPenBrushFill(GpPen*,GpBrush*);
 GpStatus WINGDIPAPI GdipSetPenColor(GpPen*,ARGB);
 GpStatus WINGDIPAPI GdipSetPenCustomEndCap(GpPen*,GpCustomLineCap*);
 GpStatus WINGDIPAPI GdipSetPenCustomStartCap(GpPen*,GpCustomLineCap*);
 GpStatus WINGDIPAPI GdipSetPenDashArray(GpPen*,GDIPCONST REAL*,INT);
+GpStatus WINGDIPAPI GdipSetPenDashCap197819(GpPen*,GpDashCap);
 GpStatus WINGDIPAPI GdipSetPenDashOffset(GpPen*,REAL);
 GpStatus WINGDIPAPI GdipSetPenDashStyle(GpPen*,GpDashStyle);
 GpStatus WINGDIPAPI GdipSetPenEndCap(GpPen*,GpLineCap);
 GpStatus WINGDIPAPI GdipSetPenLineCap197819(GpPen*,GpLineCap,GpLineCap,GpDashCap);
 GpStatus WINGDIPAPI GdipSetPenLineJoin(GpPen*,GpLineJoin);
+GpStatus WINGDIPAPI GdipSetPenMode(GpPen*,GpPenAlignment);
 GpStatus WINGDIPAPI GdipSetPenMiterLimit(GpPen*,REAL);
 GpStatus WINGDIPAPI GdipSetPenStartCap(GpPen*,GpLineCap);
 GpStatus WINGDIPAPI GdipSetPenWidth(GpPen*,REAL);
@@ -69,9 +75,15 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRect(GDIPCONST GpRectF*,ARGB,ARGB,
     LinearGradientMode,GpWrapMode,GpLineGradient**);
 GpStatus WINGDIPAPI GdipCreateLineBrushFromRectI(GDIPCONST GpRect*,ARGB,ARGB,
     LinearGradientMode,GpWrapMode,GpLineGradient**);
+GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF*,
+    ARGB,ARGB,REAL,BOOL,GpWrapMode,GpLineGradient**);
+GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect*,
+    ARGB,ARGB,REAL,BOOL,GpWrapMode,GpLineGradient**);
+
 GpStatus WINGDIPAPI GdipCreateMetafileFromEmf(HENHMETAFILE,BOOL,GpMetafile**);
 GpStatus WINGDIPAPI GdipCreateMetafileFromWmf(HMETAFILE,BOOL,
     GDIPCONST WmfPlaceableFileHeader*,GpMetafile**);
+GpStatus WINGDIPAPI GdipCreateMetafileFromWmfFile(GDIPCONST WCHAR*, GDIPCONST WmfPlaceableFileHeader*,GpMetafile**);
 GpStatus WINGDIPAPI GdipCreateStreamOnFile(GDIPCONST WCHAR*,UINT,IStream**);
 GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *);
 GpStatus WINGDIPAPI GdipDrawArc(GpGraphics*,GpPen*,REAL,REAL,REAL,REAL,REAL,REAL);
@@ -80,6 +92,10 @@ GpStatus WINGDIPAPI GdipDrawBezier(GpGraphics*,GpPen*,REAL,REAL,REAL,REAL,REAL,R
 GpStatus WINGDIPAPI GdipDrawBezierI(GpGraphics*,GpPen*,INT,INT,INT,INT,INT,INT,INT,INT);
 GpStatus WINGDIPAPI GdipDrawBeziers(GpGraphics*,GpPen*,GDIPCONST GpPointF*,INT);
 GpStatus WINGDIPAPI GdipDrawBeziersI(GpGraphics*,GpPen*,GDIPCONST GpPoint*,INT);
+GpStatus WINGDIPAPI GdipDrawClosedCurve(GpGraphics*,GpPen*,GDIPCONST GpPointF*,INT);
+GpStatus WINGDIPAPI GdipDrawClosedCurveI(GpGraphics*,GpPen*,GDIPCONST GpPoint*,INT);
+GpStatus WINGDIPAPI GdipDrawClosedCurve2(GpGraphics*,GpPen*,GDIPCONST GpPointF*,INT,REAL);
+GpStatus WINGDIPAPI GdipDrawClosedCurve2I(GpGraphics*,GpPen*,GDIPCONST GpPoint*,INT,REAL);
 GpStatus WINGDIPAPI GdipDrawCurve(GpGraphics*,GpPen*,GDIPCONST GpPointF*,INT);
 GpStatus WINGDIPAPI GdipDrawCurveI(GpGraphics*,GpPen*,GDIPCONST GpPoint*,INT);
 GpStatus WINGDIPAPI GdipDrawCurve2(GpGraphics*,GpPen*,GDIPCONST GpPointF*,INT,REAL);
@@ -145,6 +161,10 @@ GpStatus WINGDIPAPI GdipGetTextRenderingHint(GpGraphics*,TextRenderingHint*);
 GpStatus WINGDIPAPI GdipGetWorldTransform(GpGraphics*,GpMatrix*);
 GpStatus WINGDIPAPI GdipMeasureString(GpGraphics*,GDIPCONST WCHAR*,INT,
     GDIPCONST GpFont*,GDIPCONST RectF*,GDIPCONST GpStringFormat*,RectF*,INT*,INT*);
+GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics*, GDIPCONST WCHAR*,
+    INT, GDIPCONST GpFont*, GDIPCONST RectF*, GDIPCONST GpStringFormat*, INT,
+    GpRegion**);
+
 GpStatus WINGDIPAPI GdipReleaseDC(GpGraphics*,HDC);
 GpStatus WINGDIPAPI GdipRestoreGraphics(GpGraphics*,GraphicsState);
 GpStatus WINGDIPAPI GdipRotateWorldTransform(GpGraphics*,REAL,GpMatrixOrder);
@@ -179,15 +199,20 @@ GpStatus WINGDIPAPI GdipCreateTextureIAI(GpImage*,GDIPCONST GpImageAttributes*,
 GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush*);
 GpStatus WINGDIPAPI GdipGetBrushType(GpBrush*,GpBrushType*);
 GpStatus WINGDIPAPI GdipGetLineGammaCorrection(GpLineGradient*,BOOL*);
+GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient*,GpWrapMode*);
 GpStatus WINGDIPAPI GdipGetLineRect(GpLineGradient*,GpRectF*);
 GpStatus WINGDIPAPI GdipGetLineRectI(GpLineGradient*,GpRect*);
 GpStatus WINGDIPAPI GdipGetLineColors(GpLineGradient*,ARGB*);
+GpStatus WINGDIPAPI GdipGetPathGradientBlend(GpPathGradient*,REAL*,REAL*,INT);
+GpStatus WINGDIPAPI GdipGetPathGradientBlendCount(GpPathGradient*,INT*);
 GpStatus WINGDIPAPI GdipGetPathGradientCenterColor(GpPathGradient*,ARGB*);
 GpStatus WINGDIPAPI GdipGetPathGradientCenterPoint(GpPathGradient*,GpPointF*);
 GpStatus WINGDIPAPI GdipGetPathGradientCenterPointI(GpPathGradient*,GpPoint*);
 GpStatus WINGDIPAPI GdipGetPathGradientFocusScales(GpPathGradient*,REAL*,REAL*);
 GpStatus WINGDIPAPI GdipGetPathGradientGammaCorrection(GpPathGradient*,BOOL*);
 GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient*,INT*);
+GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient*,GpRectF*);
+GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient*,GpRect*);
 GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient*,
     ARGB*,INT*);
 GpStatus WINGDIPAPI GdipGetPathGradientWrapMode(GpPathGradient*,GpWrapMode*);
@@ -210,6 +235,10 @@ GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient*,
 GpStatus WINGDIPAPI GdipSetPathGradientWrapMode(GpPathGradient*,GpWrapMode);
 GpStatus WINGDIPAPI GdipSetSolidFillColor(GpSolidFill*,ARGB);
 GpStatus WINGDIPAPI GdipSetTextureTransform(GpTexture *,GDIPCONST GpMatrix*);
+GpStatus WINGDIPAPI GdipTransformPoints(GpGraphics*, GpCoordinateSpace, GpCoordinateSpace,
+                                        GpPointF *, INT);
+GpStatus WINGDIPAPI GdipTransformPointsI(GpGraphics*, GpCoordinateSpace, GpCoordinateSpace,
+                                         GpPoint *, INT);
 
 GpStatus WINGDIPAPI GdipAddPathArc(GpPath*,REAL,REAL,REAL,REAL,REAL,REAL);
 GpStatus WINGDIPAPI GdipAddPathArcI(GpPath*,INT,INT,INT,INT,REAL,REAL);
@@ -217,6 +246,14 @@ GpStatus WINGDIPAPI GdipAddPathBezier(GpPath*,REAL,REAL,REAL,REAL,REAL,REAL,REAL
 GpStatus WINGDIPAPI GdipAddPathBezierI(GpPath*,INT,INT,INT,INT,INT,INT,INT,INT);
 GpStatus WINGDIPAPI GdipAddPathBeziers(GpPath*,GDIPCONST GpPointF*,INT);
 GpStatus WINGDIPAPI GdipAddPathBeziersI(GpPath*,GDIPCONST GpPoint*,INT);
+GpStatus WINGDIPAPI GdipAddPathClosedCurve(GpPath*,GDIPCONST GpPointF*,INT);
+GpStatus WINGDIPAPI GdipAddPathClosedCurveI(GpPath*,GDIPCONST GpPoint*,INT);
+GpStatus WINGDIPAPI GdipAddPathClosedCurve2(GpPath*,GDIPCONST GpPointF*,INT,REAL);
+GpStatus WINGDIPAPI GdipAddPathClosedCurve2I(GpPath*,GDIPCONST GpPoint*,INT,REAL);
+GpStatus WINGDIPAPI GdipAddPathCurve(GpPath*,GDIPCONST GpPointF*,INT);
+GpStatus WINGDIPAPI GdipAddPathCurveI(GpPath*,GDIPCONST GpPoint*,INT);
+GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath*,GDIPCONST GpPointF*,INT,REAL);
+GpStatus WINGDIPAPI GdipAddPathCurve2I(GpPath*,GDIPCONST GpPoint*,INT,REAL);
 GpStatus WINGDIPAPI GdipAddPathEllipse(GpPath*,REAL,REAL,REAL,REAL);
 GpStatus WINGDIPAPI GdipAddPathEllipseI(GpPath*,INT,INT,INT,INT);
 GpStatus WINGDIPAPI GdipAddPathLine(GpPath*,REAL,REAL,REAL,REAL);
@@ -247,10 +284,12 @@ GpStatus WINGDIPAPI GdipGetPathTypes(GpPath*,BYTE*,INT);
 GpStatus WINGDIPAPI GdipGetPathWorldBounds(GpPath*,GpRectF*,GDIPCONST GpMatrix*,GDIPCONST GpPen*);
 GpStatus WINGDIPAPI GdipGetPathWorldBoundsI(GpPath*,GpRect*,GDIPCONST GpMatrix*,GDIPCONST GpPen*);
 GpStatus WINGDIPAPI GdipGetPointCount(GpPath*,INT*);
-    GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPoint(GpPath*,REAL,REAL,GpPen*,
+GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPoint(GpPath*,REAL,REAL,GpPen*,
     GpGraphics*,BOOL*);
 GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPointI(GpPath*,INT,INT,GpPen*,
     GpGraphics*,BOOL*);
+GpStatus WINGDIPAPI GdipIsVisiblePathPoint(GpPath*,REAL,REAL,GpGraphics*,BOOL*);
+GpStatus WINGDIPAPI GdipIsVisiblePathPointI(GpPath*,INT,INT,GpGraphics*,BOOL*);
 GpStatus WINGDIPAPI GdipResetPath(GpPath*);
 GpStatus WINGDIPAPI GdipSetPathFillMode(GpPath*,GpFillMode);
 GpStatus WINGDIPAPI GdipStartPathFigure(GpPath*);
@@ -261,8 +300,11 @@ GpStatus WINGDIPAPI GdipCreateMatrix(GpMatrix**);
 GpStatus WINGDIPAPI GdipCreateMatrix2(REAL,REAL,REAL,REAL,REAL,REAL,GpMatrix**);
 GpStatus WINGDIPAPI GdipCreateMatrix3(GDIPCONST GpRectF *,GDIPCONST GpPointF*,GpMatrix**);
 GpStatus WINGDIPAPI GdipCreateMatrix3I(GDIPCONST GpRect*,GDIPCONST GpPoint*,GpMatrix**);
+GpStatus WINGDIPAPI GdipInvertMatrix(GpMatrix*);
+GpStatus WINGDIPAPI GdipShearMatrix(GpMatrix*,REAL,REAL,GpMatrixOrder);
 GpStatus WINGDIPAPI GdipIsMatrixEqual(GDIPCONST GpMatrix*, GDIPCONST GpMatrix*, BOOL*);
 GpStatus WINGDIPAPI GdipIsMatrixIdentity(GDIPCONST GpMatrix*, BOOL*);
+GpStatus WINGDIPAPI GdipIsMatrixInvertible(GDIPCONST GpMatrix*, BOOL*);
 
 GpStatus WINGDIPAPI GdipDeleteMatrix(GpMatrix*);
 GpStatus WINGDIPAPI GdipGetMatrixElements(GDIPCONST GpMatrix*,REAL*);
@@ -281,9 +323,11 @@ GpStatus WINGDIPAPI GdipCreatePathIter(GpPathIterator**,GpPath*);
 GpStatus WINGDIPAPI GdipDeletePathIter(GpPathIterator*);
 GpStatus WINGDIPAPI GdipPathIterCopyData(GpPathIterator*,INT*,GpPointF*,BYTE*,
     INT,INT);
+GpStatus WINGDIPAPI GdipPathIterNextMarker(GpPathIterator*,INT*,INT*,INT*);
 GpStatus WINGDIPAPI GdipPathIterNextSubpath(GpPathIterator*,INT*,INT*,INT*,BOOL*);
 GpStatus WINGDIPAPI GdipPathIterRewind(GpPathIterator*);
 GpStatus WINGDIPAPI GdipPathIterGetCount(GpPathIterator*,INT*);
+GpStatus WINGDIPAPI GdipPathIterGetSubpathCount(GpPathIterator*,INT*);
 GpStatus WINGDIPAPI GdipPathIterEnumerate(GpPathIterator*,INT*,GpPointF*,BYTE*,INT);
 GpStatus WINGDIPAPI GdipPathIterHasCurve(GpPathIterator*,BOOL*);
 
@@ -294,6 +338,10 @@ GpStatus WINGDIPAPI GdipDeleteCustomLineCap(GpCustomLineCap*);
 GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeCaps(GpCustomLineCap*,GpLineCap,
     GpLineCap);
 GpStatus WINGDIPAPI GdipGetCustomLineCapBaseCap(GpCustomLineCap*,GpLineCap*);
+GpStatus WINGDIPAPI GdipGetCustomLineCapBaseInset(GpCustomLineCap*,REAL*);
+GpStatus WINGDIPAPI GdipGetCustomLineCapStrokeJoin(GpCustomLineCap*,GpLineJoin*);
+GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeJoin(GpCustomLineCap*,GpLineJoin);
+GpStatus WINGDIPAPI GdipGetCustomLineCapWidthScale(GpCustomLineCap*,REAL*);
 
 GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap*,INT,INT,ARGB*);
 GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap*,INT,INT,ARGB);
@@ -306,7 +354,9 @@ GpStatus WINGDIPAPI GdipConvertToEmfPlusToFile(const GpGraphics*,GpMetafile*,INT
 GpStatus WINGDIPAPI GdipConvertToEmfPlusToStream(const GpGraphics*,GpMetafile*,INT*,IStream*,EmfType,const WCHAR*,GpMetafile**);
 GpStatus WINGDIPAPI GdipCreateBitmapFromFile(GDIPCONST WCHAR*,GpBitmap**);
 GpStatus WINGDIPAPI GdipCreateBitmapFromFileICM(GDIPCONST WCHAR*,GpBitmap**);
+GpStatus WINGDIPAPI GdipCreateBitmapFromGdiDib(GDIPCONST BITMAPINFO*,VOID*,GpBitmap**);
 GpStatus WINGDIPAPI GdipCreateBitmapFromGraphics(INT,INT,GpGraphics*,GpBitmap**);
+GpStatus WINGDIPAPI GdipCreateBitmapFromResource(HINSTANCE,GDIPCONST WCHAR*,GpBitmap**);
 GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT,INT,INT,PixelFormat,BYTE*,
     GpBitmap**);
 GpStatus WINGDIPAPI GdipCreateBitmapFromStream(IStream*,GpBitmap**);
@@ -370,25 +420,52 @@ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont*,GpGraphics*,LOGFONTW*);
 GpStatus WINGDIPAPI GdipCloneFont(GpFont*,GpFont**);
 GpStatus WINGDIPAPI GdipGetFontUnit(GpFont*, Unit*);
 GpStatus WINGDIPAPI GdipGetFontSize(GpFont*, REAL*);
+GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont*, REAL, REAL*);
 
 GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR*,
     GpFontCollection*, GpFontFamily**);
+GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily*, GpFontFamily**);
 GpStatus WINGDIPAPI GdipDeleteFontFamily(GpFontFamily*);
 GpStatus WINGDIPAPI GdipGetFamilyName(GDIPCONST GpFontFamily*, WCHAR*, LANGID);
+GpStatus WINGDIPAPI GdipGetCellAscent(GDIPCONST GpFontFamily*, INT, UINT16*);
+GpStatus WINGDIPAPI GdipGetCellDescent(GDIPCONST GpFontFamily*, INT, UINT16*);
+GpStatus WINGDIPAPI GdipGetEmHeight(GDIPCONST GpFontFamily*, INT, UINT16*);
+GpStatus WINGDIPAPI GdipGetLineSpacing(GDIPCONST GpFontFamily*, INT, UINT16*);
+GpStatus WINGDIPAPI GdipIsStyleAvailable(GDIPCONST GpFontFamily *, INT, BOOL*);
 
 GpStatus WINGDIPAPI GdipGetGenericFontFamilySansSerif(GpFontFamily**);
 GpStatus WINGDIPAPI GdipGetGenericFontFamilySerif(GpFontFamily**);
 GpStatus WINGDIPAPI GdipGetGenericFontFamilyMonospace(GpFontFamily**);
 
+GpStatus WINGDIPAPI GdipNewPrivateFontCollection(GpFontCollection**);
+GpStatus WINGDIPAPI GdipDeletePrivateFontCollection(GpFontCollection**);
+GpStatus WINGDIPAPI GdipPrivateAddFontFile(GpFontCollection*, GDIPCONST WCHAR*);
+GpStatus WINGDIPAPI GdipGetFontCollectionFamilyCount(GpFontCollection*, INT*);
+GpStatus WINGDIPAPI GdipGetFontCollectionFamilyList(GpFontCollection*, INT,
+        GpFontFamily*[], INT*);
+
 GpStatus WINGDIPAPI GdipCreateStringFormat(INT,LANGID,GpStringFormat**);
 GpStatus WINGDIPAPI GdipDeleteStringFormat(GpStringFormat*);
+GpStatus WINGDIPAPI GdipStringFormatGetGenericDefault(GpStringFormat **);
+GpStatus WINGDIPAPI GdipStringFormatGetGenericTypographic(GpStringFormat **);
 GpStatus WINGDIPAPI GdipGetStringFormatAlign(GpStringFormat*,StringAlignment*);
+GpStatus WINGDIPAPI GdipGetStringFormatDigitSubstitution(GDIPCONST GpStringFormat*,LANGID*,
+        StringDigitSubstitute*);
+GpStatus WINGDIPAPI GdipGetStringFormatFlags(GDIPCONST GpStringFormat*, INT*);
 GpStatus WINGDIPAPI GdipGetStringFormatHotkeyPrefix(GDIPCONST GpStringFormat*,INT*);
 GpStatus WINGDIPAPI GdipGetStringFormatLineAlign(GpStringFormat*,StringAlignment*);
+GpStatus WINGDIPAPI GdipGetStringFormatMeasurableCharacterRangeCount(
+        GDIPCONST GpStringFormat*, INT*);
+GpStatus WINGDIPAPI GdipGetStringFormatTabStopCount(GDIPCONST GpStringFormat*,INT*);
+GpStatus WINGDIPAPI GdipGetStringFormatTabStops(GDIPCONST GpStringFormat*,INT,REAL*,REAL*);
 GpStatus WINGDIPAPI GdipGetStringFormatTrimming(GpStringFormat*,StringTrimming*);
 GpStatus WINGDIPAPI GdipSetStringFormatAlign(GpStringFormat*,StringAlignment);
+GpStatus WINGDIPAPI GdipSetStringFormatDigitSubstitution(GpStringFormat*,LANGID,StringDigitSubstitute);
 GpStatus WINGDIPAPI GdipSetStringFormatHotkeyPrefix(GpStringFormat*,INT);
 GpStatus WINGDIPAPI GdipSetStringFormatLineAlign(GpStringFormat*,StringAlignment);
+GpStatus WINGDIPAPI GdipSetStringFormatMeasurableCharacterRanges(
+        GpStringFormat*, INT, GDIPCONST CharacterRange*);
+GpStatus WINGDIPAPI GdipSetStringFormatTabStops(GpStringFormat*,REAL,INT,GDIPCONST REAL*);
 GpStatus WINGDIPAPI GdipSetStringFormatTrimming(GpStringFormat*,StringTrimming);
 GpStatus WINGDIPAPI GdipCloneStringFormat(GDIPCONST GpStringFormat*,GpStringFormat**);
 
index e2f8ab7..bb7c47f 100644 (file)
@@ -21,7 +21,6 @@
 
 #ifdef __cplusplus
 
-class GpGraphics {};
 class GpGraphics {};
 class GpBrush {};
 class GpSolidFill : public GpBrush {};
@@ -86,5 +85,6 @@ typedef Point GpPoint;
 typedef WrapMode GpWrapMode;
 typedef Color GpColor;
 typedef FlushIntention GpFlushIntention;
+typedef CoordinateSpace GpCoordinateSpace;
 
 #endif
index 29616e9..4f97432 100644 (file)
@@ -236,6 +236,12 @@ typedef struct Rect
     INT Height;
 } Rect;
 
+typedef struct CharacterRange
+{
+    INT First;
+    INT Length;
+} CharacterRange;
+
 typedef enum Status Status;
 
 #endif /* end of c typedefs */