From 520906b62d02cb9c886404caa03d1fcb634f574b Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 27 Jun 2011 13:24:39 -0500 Subject: [PATCH 2/3] gdiplus: Implement GdipMeasureDriverString. --- dlls/gdiplus/graphics.c | 143 ++++++++++++++++++++++++++++++++++++++++- dlls/gdiplus/tests/graphics.c | 28 ++++---- 2 files changed, 155 insertions(+), 16 deletions(-) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 8c6a042..656fb35 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -5624,8 +5624,147 @@ 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); + GpStatus stat; + PointF *real_positions, real_position; + POINT *pti; + HFONT hfont; + HDC hdc; + REAL min_x, min_y, max_x, max_y; + int i, j; + GLYPHMETRICS glyphmetrics; + static const MAT2 identity = {{0,1}, {0,0}, {0,0}, {0,1}}; + UINT ggo_flags = GGO_GRAY8_BITMAP; + GpMatrix *device_to_world; + + 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 & DriverStringOptionsCmapLookup)) + ggo_flags |= GGO_GLYPH_INDEX; + + if (flags & unsupported_flags) + FIXME("Ignoring flags %x\n", flags & unsupported_flags); + + if (matrix) + FIXME("Ignoring matrix\n"); + + pti = GdipAlloc(sizeof(POINT) * length); + if (!pti) + return OutOfMemory; + + if (flags & DriverStringOptionsRealizedAdvance) + { + real_position = positions[0]; + + transform_and_round_points(graphics, pti, &real_position, 1); + } + else + { + real_positions = GdipAlloc(sizeof(PointF) * length); + if (!real_positions) + { + GdipFree(pti); + return OutOfMemory; + } + + memcpy(real_positions, positions, sizeof(PointF) * length); + + transform_and_round_points(graphics, pti, real_positions, length); + + GdipFree(real_positions); + } + + get_font_hfont(graphics, font, &hfont); + + hdc = CreateCompatibleDC(0); + SelectObject(hdc, hfont); + + stat = get_graphics_transform(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, &device_to_world); + if (stat != Ok) + { + GdipFree(pti); + DeleteDC(hdc); + DeleteObject(hfont); + return stat; + } + + min_x = max_x = positions[0].X; + min_y = max_y = positions[0].Y; + + for (i=0; i max_x) max_x = corners[j].X; + if (corners[j].Y > max_y) max_y = corners[j].Y; + } + + if (i+1 < length && (flags & DriverStringOptionsRealizedAdvance) == DriverStringOptionsRealizedAdvance) + { + pti[i+1].x = pti[i].x + glyphmetrics.gmCellIncX; + pti[i+1].y = pti[i].y + glyphmetrics.gmCellIncY; + } + } + + GdipFree(pti); + DeleteDC(hdc); + DeleteObject(hfont); + GdipDeleteMatrix(device_to_world); + + boundingBox->X = min_x; + boundingBox->Y = min_y; + boundingBox->Width = max_x - min_x; + boundingBox->Height = max_y - min_y; + + return stat; } 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 49f6815..b4dd2bd 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -3047,36 +3047,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; @@ -3085,12 +3085,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(rc.X, 0.0); - 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; @@ -3102,11 +3102,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(rc.X, 0.0); - 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(rc.Height, char_height); GdipDeleteMatrix(identity); -- 1.7.1