From 95e7af029ff070046c60616d0a418eb035276c09 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 27 Jun 2011 13:24:39 -0500 Subject: [PATCH 3/4] gdiplus: Implement GdipMeasureDriverString. --- dlls/gdiplus/graphics.c | 108 ++++++++++++++++++++++++++++++++++++++++- dlls/gdiplus/tests/graphics.c | 34 ++++++------ 2 files changed, 123 insertions(+), 19 deletions(-) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 8c6a042..d756c0b 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -5624,8 +5624,112 @@ GpStatus WINGDIPAPI GdipMeasureDriverString(GpGraphics *graphics, GDIPCONST UINT GDIPCONST GpFont *font, GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix, RectF *boundingBox) { - FIXME("(%p %p %d %p %p %d %p %p): stub\n", graphics, text, length, font, positions, flags, matrix, boundingBox); - return NotImplemented; + static const INT unsupported_flags = ~(DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance); + HFONT hfont; + HDC hdc; + REAL min_x, min_y, max_x, max_y, x, y; + int i; + TEXTMETRICW textmetric; + const WORD *glyph_indices; + WORD *dynamic_glyph_indices=NULL; + REAL rel_width, rel_height, ascent, descent; + GpPointF pt[3]; + + TRACE("(%p %p %d %p %p %d %p %p)\n", graphics, text, length, font, positions, flags, matrix, boundingBox); + + if (!graphics || !text || !font || !positions || !boundingBox) + return InvalidParameter; + + if (length == -1) + length = strlenW(text); + + if (length == 0) + { + boundingBox->X = 0.0; + boundingBox->Y = 0.0; + boundingBox->Width = 0.0; + boundingBox->Height = 0.0; + } + + if (flags & unsupported_flags) + FIXME("Ignoring flags %x\n", flags & unsupported_flags); + + if (matrix) + FIXME("Ignoring matrix\n"); + + get_font_hfont(graphics, font, &hfont); + + hdc = CreateCompatibleDC(0); + SelectObject(hdc, hfont); + + GetTextMetricsW(hdc, &textmetric); + + pt[0].X = 0.0; + pt[0].Y = 0.0; + pt[1].X = 1.0; + pt[1].Y = 0.0; + pt[2].X = 0.0; + pt[2].Y = 1.0; + GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3); + rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+ + (pt[1].X-pt[0].X)*(pt[1].X-pt[0].X)); + rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+ + (pt[2].X-pt[0].X)*(pt[2].X-pt[0].X)); + + if (flags & DriverStringOptionsCmapLookup) + { + glyph_indices = dynamic_glyph_indices = GdipAlloc(sizeof(WORD) * length); + if (!glyph_indices) + { + DeleteDC(hdc); + DeleteObject(hfont); + return OutOfMemory; + } + + GetGlyphIndicesW(hdc, text, length, dynamic_glyph_indices, 0); + } + else + glyph_indices = text; + + min_x = max_x = x = positions[0].X; + min_y = max_y = y = positions[0].Y; + + ascent = textmetric.tmAscent / rel_height; + descent = textmetric.tmDescent / rel_height; + + for (i=0; i y - ascent) min_y = y - ascent; + if (max_y < y + descent) max_y = y + descent; + if (min_x > x) min_x = x; + + x += char_width / rel_width; + + if (max_x < x) max_x = x; + } + + GdipFree(dynamic_glyph_indices); + DeleteDC(hdc); + DeleteObject(hfont); + + boundingBox->X = min_x; + boundingBox->Y = min_y; + boundingBox->Width = max_x - min_x; + boundingBox->Height = max_y - min_y; + + return Ok; } static GpStatus GDI32_GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index 0ab570d..bbca69f 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -3048,36 +3048,36 @@ static void test_string_functions(void) status = GdipMeasureDriverString(NULL, teststring, 6, font, &position, DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, identity, &rc); - todo_wine expect(InvalidParameter, status); + expect(InvalidParameter, status); status = GdipMeasureDriverString(graphics, NULL, 6, font, &position, DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, identity, &rc); - todo_wine expect(InvalidParameter, status); + expect(InvalidParameter, status); status = GdipMeasureDriverString(graphics, teststring, 6, NULL, &position, DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, identity, &rc); - todo_wine expect(InvalidParameter, status); + expect(InvalidParameter, status); status = GdipMeasureDriverString(graphics, teststring, 6, font, NULL, DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, identity, &rc); - todo_wine expect(InvalidParameter, status); + expect(InvalidParameter, status); status = GdipMeasureDriverString(graphics, teststring, 6, font, &position, 0x100, identity, &rc); - todo_wine expect(Ok, status); + expect(Ok, status); status = GdipMeasureDriverString(graphics, teststring, 6, font, &position, DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, NULL, &rc); - todo_wine expect(Ok, status); + expect(Ok, status); status = GdipMeasureDriverString(graphics, teststring, 6, font, &position, DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, identity, NULL); - todo_wine expect(InvalidParameter, status); + expect(InvalidParameter, status); rc.X = 0; rc.Y = 0; @@ -3086,12 +3086,12 @@ static void test_string_functions(void) status = GdipMeasureDriverString(graphics, teststring, 6, font, &position, DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, identity, &rc); - todo_wine expect(Ok, status); + expect(Ok, status); expectf(0.0, rc.X); - todo_wine ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y); - todo_wine ok(rc.Width > 0.0, "unexpected Width %0.2f\n", rc.Width); - todo_wine ok(rc.Height > 0.0, "unexpected Y %0.2f\n", rc.Y); + ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y); + ok(rc.Width > 0.0, "unexpected Width %0.2f\n", rc.Width); + ok(rc.Height > 0.0, "unexpected Y %0.2f\n", rc.Y); char_width = rc.Width; char_height = rc.Height; @@ -3103,11 +3103,11 @@ static void test_string_functions(void) status = GdipMeasureDriverString(graphics, teststring, 4, font, &position, DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, identity, &rc); - todo_wine expect(Ok, status); + expect(Ok, status); expectf(0.0, rc.X); - todo_wine ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y); - todo_wine ok(rc.Width < char_width, "got Width %0.2f, expecting less than %0.2f\n", rc.Width, char_width); + ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y); + ok(rc.Width < char_width, "got Width %0.2f, expecting less than %0.2f\n", rc.Width, char_width); expectf(char_height, rc.Height); rc.X = 0; @@ -3117,11 +3117,11 @@ static void test_string_functions(void) status = GdipMeasureDriverString(graphics, teststring2, 1, font, &position, DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance, identity, &rc); - todo_wine expect(Ok, status); + expect(Ok, status); expectf(rc.X, 0.0); - todo_wine ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y); - todo_wine ok(rc.Width > 0, "unexpected Width %0.2f\n", rc.Width); + ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y); + ok(rc.Width > 0, "unexpected Width %0.2f\n", rc.Width); expectf(rc.Height, char_height); GdipDeleteMatrix(identity); -- 1.7.1