From 250b1190c37fc1cd6886c95f1a259f5f937fd4bf Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Tue, 30 Mar 2010 15:51:44 -0500 Subject: [PATCH 8/8] gdiplus: Implement GdipMeasureCharacterRanges. --- dlls/gdiplus/graphics.c | 75 +++++++++++++++++++++++++++++++++++++++-- dlls/gdiplus/tests/graphics.c | 8 ++-- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index f6f5812..3d5a961 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -3479,18 +3479,87 @@ static GpStatus gdip_format_string(GpGraphics *graphics, return stat; } +struct measure_ranges_args { + GpRegion **regions; +}; + +GpStatus measure_ranges_callback(GpGraphics *graphics, + GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font, + GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format, + INT lineno, const RectF *bounds, void *user_data) +{ + int i; + GpStatus stat = Ok; + struct measure_ranges_args *args = user_data; + + for (i=0; irange_count; i++) + { + INT range_start = max(index, format->character_ranges[i].First); + INT range_end = min(index+length, format->character_ranges[i].First+format->character_ranges[i].Length); + if (range_start < range_end) + { + GpRectF range_rect; + SIZE range_size; + + range_rect.Y = bounds->Y; + range_rect.Height = bounds->Height; + + GetTextExtentExPointW(graphics->hdc, string + index, range_start - index, + INT_MAX, NULL, NULL, &range_size); + range_rect.X = bounds->X + range_size.cx; + + GetTextExtentExPointW(graphics->hdc, string + index, range_end - index, + INT_MAX, NULL, NULL, &range_size); + range_rect.Width = (bounds->X + range_size.cx) - range_rect.X; + + stat = GdipCombineRegionRect(args->regions[i], &range_rect, CombineModeUnion); + if (stat != Ok) + break; + } + } + + return stat; +} + GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics, GDIPCONST WCHAR* string, INT length, GDIPCONST GpFont* font, GDIPCONST RectF* layoutRect, GDIPCONST GpStringFormat *stringFormat, INT regionCount, GpRegion** regions) { - FIXME("stub: %p %s %d %p %p %p %d %p\n", graphics, debugstr_w(string), - length, font, layoutRect, stringFormat, regionCount, regions); + GpStatus stat; + int i; + HFONT oldfont; + struct measure_ranges_args args; + + TRACE("(%p %s %d %p %s %p %d %p)\n", graphics, debugstr_w(string), + length, font, debugstr_rectf(layoutRect), stringFormat, regionCount, regions); if (!(graphics && string && font && layoutRect && stringFormat && regions)) return InvalidParameter; - return NotImplemented; + if (regionCount < stringFormat->range_count) + return InvalidParameter; + + if (stringFormat->attr) + TRACE("may be ignoring some format flags: attr %x\n", stringFormat->attr); + + oldfont = SelectObject(graphics->hdc, CreateFontIndirectW(&font->lfw)); + + for (i=0; irange_count; i++) + { + stat = GdipSetEmpty(regions[i]); + if (stat != Ok) + return stat; + } + + args.regions = regions; + + stat = gdip_format_string(graphics, string, length, font, layoutRect, stringFormat, + measure_ranges_callback, &args); + + DeleteObject(SelectObject(graphics->hdc, oldfont)); + + return stat; } struct measure_string_args { diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index 17caf90..57ce638 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -2590,10 +2590,10 @@ static void test_string_functions(void) expect(InvalidParameter, status); status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 2, regions); - todo_wine expect(InvalidParameter, status); + expect(InvalidParameter, status); status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 4, regions); - todo_wine expect(Ok, status); + expect(Ok, status); for (i=0; i<4; i++) { @@ -2611,7 +2611,7 @@ static void test_string_functions(void) rc.Height = char_bounds.Height + char_height * 0.5; status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, regions); - todo_wine expect(Ok, status); + expect(Ok, status); for (i=0; i<4; i++) { @@ -2621,7 +2621,7 @@ static void test_string_functions(void) ok(!region_isempty[0], "region shouldn't be empty\n"); ok(!region_isempty[1], "region shouldn't be empty\n"); - todo_wine ok(region_isempty[2], "region should be empty\n"); + ok(region_isempty[2], "region should be empty\n"); ok(!region_isempty[3], "region shouldn't be empty\n"); for (i=0; i<4; i++) -- 1.6.3.3