gdiplus: Implement GdipMeasureDriverString.
This commit is contained in:
parent
640c7b5e4f
commit
6cc7e7f7c4
|
@ -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<length; i++)
|
||||
{
|
||||
int char_width;
|
||||
ABC abc;
|
||||
|
||||
if (!(flags & DriverStringOptionsRealizedAdvance))
|
||||
{
|
||||
x = positions[i].X;
|
||||
y = positions[i].Y;
|
||||
}
|
||||
|
||||
GetCharABCWidthsW(hdc, glyph_indices[i], glyph_indices[i], &abc);
|
||||
char_width = abc.abcA + abc.abcB + abc.abcB;
|
||||
|
||||
if (min_y > 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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue