[1/10] gdiplus: added GdipMeasureString

Evan Stade estade at gmail.com
Wed Aug 15 18:21:52 CDT 2007


Hi,

 dlls/gdiplus/gdiplus.spec |    2 -
 dlls/gdiplus/graphics.c   |   93 +++++++++++++++++++++++++++++++++++++++++++++
 include/gdiplusflat.h     |    2 +
 3 files changed, 96 insertions(+), 1 deletions(-)

-- 
Evan Stade
-------------- next part --------------
diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec
index b31c6ed..615bb90 100644
--- a/dlls/gdiplus/gdiplus.spec
+++ b/dlls/gdiplus/gdiplus.spec
@@ -441,7 +441,7 @@
 @ stdcall GdipLoadImageFromStreamICM(ptr ptr)
 @ stub GdipMeasureCharacterRanges
 @ stub GdipMeasureDriverString
-@ stub GdipMeasureString
+@ stdcall GdipMeasureString(ptr ptr long ptr ptr ptr ptr ptr ptr)
 @ stub GdipMultiplyLineTransform
 @ stdcall GdipMultiplyMatrix(ptr ptr long)
 @ stub GdipMultiplyPathGradientTransform
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index f63e073..c8a732d 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -1709,6 +1709,99 @@ GpStatus WINGDIPAPI GdipGetWorldTransfor
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
+    GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font,
+    GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format, RectF *bounds,
+    INT *codepointsfitted, INT *linesfilled)
+{
+    HFONT oldfont;
+    WCHAR* stringdup;
+    INT sum = 0, height = 0, fit, fitcpy, max_width = 0, i, j, lret, nwidth;
+    SIZE size;
+
+    if(!graphics || !string || !font || !rect)
+        return InvalidParameter;
+
+    if(format || codepointsfitted || linesfilled){
+        FIXME("not implemented for given parameters\n");
+        if(format)
+            TRACE("format attr is %d\n", format->attr);
+        return NotImplemented;
+    }
+
+    if(length == -1) length = lstrlenW(string);
+
+    stringdup = GdipAlloc(length * sizeof(WCHAR));
+    if(!stringdup) return OutOfMemory;
+
+    oldfont = SelectObject(graphics->hdc, CreateFontIndirectW(&font->lfw));
+    nwidth = roundr(rect->Width);
+
+    for(i = 0, j = 0; i < length; i++){
+        if(!isprintW(string[i]) && (string[i] != '\n'))
+            continue;
+
+        stringdup[j] = string[i];
+        j++;
+    }
+
+    stringdup[j] = 0;
+    length = j;
+
+    while(sum < length){
+        GetTextExtentExPointW(graphics->hdc, stringdup + sum, length - sum,
+                              nwidth, &fit, NULL, &size);
+        fitcpy = fit;
+
+        if(fit == 0)
+            break;
+
+        for(lret = 0; lret < fit; lret++)
+            if(*(stringdup + sum + lret) == '\n')
+                break;
+
+        /* Line break code (may look strange, but it imitates windows). */
+        if(lret < fit)
+            fit = lret;    /* this is not an off-by-one error */
+        else if(fit < (length - sum)){
+            if(*(stringdup + sum + fit) == ' ')
+                while(*(stringdup + sum + fit) == ' ')
+                    fit++;
+            else
+                while(*(stringdup + sum + fit - 1) != ' '){
+                    fit--;
+
+                    if(*(stringdup + sum + fit) == '\t')
+                        break;
+
+                    if(fit == 0){
+                        fit = fitcpy;
+                        break;
+                    }
+                }
+        }
+
+        GetTextExtentExPointW(graphics->hdc, stringdup + sum, fit,
+                              nwidth, &j, NULL, &size);
+
+        sum += fit + (lret < fitcpy ? 1 : 0);
+        height += size.cy;
+        max_width = max(max_width, size.cx);
+
+        if(height > roundr(rect->Height))
+            break;
+    }
+
+    bounds->X = rect->X;
+    bounds->Y = rect->Y;
+    bounds->Width = (REAL)max_width;
+    bounds->Height = min((REAL)height, rect->Height);
+
+    DeleteObject(SelectObject(graphics->hdc, oldfont));
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipRestoreGraphics(GpGraphics *graphics, GraphicsState state)
 {
     static int calls;
diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h
index f63d895..872ac9b 100644
--- a/include/gdiplusflat.h
+++ b/include/gdiplusflat.h
@@ -94,6 +94,8 @@ GpStatus WINGDIPAPI GdipGetPixelOffsetMo
 GpStatus WINGDIPAPI GdipGetSmoothingMode(GpGraphics*,SmoothingMode*);
 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 GdipRestoreGraphics(GpGraphics*,GraphicsState);
 GpStatus WINGDIPAPI GdipRotateWorldTransform(GpGraphics*,REAL,GpMatrixOrder);
 GpStatus WINGDIPAPI GdipSaveGraphics(GpGraphics*,GraphicsState*);
-- 
1.4.1


More information about the wine-patches mailing list