dwrite: Implement GetGlyphOrientationTransform().

This commit is contained in:
Nikolay Sivov 2015-05-28 19:12:03 +03:00 committed by Alexandre Julliard
parent 22983f2b65
commit a921941a17
2 changed files with 206 additions and 5 deletions

View File

@ -1320,8 +1320,8 @@ static HRESULT WINAPI dwritetextanalyzer1_AnalyzeVerticalGlyphOrientation(IDWrit
static HRESULT WINAPI dwritetextanalyzer1_GetGlyphOrientationTransform(IDWriteTextAnalyzer2 *iface,
DWRITE_GLYPH_ORIENTATION_ANGLE angle, BOOL is_sideways, DWRITE_MATRIX *transform)
{
FIXME("(%d %d %p): stub\n", angle, is_sideways, transform);
return E_NOTIMPL;
TRACE("(%d %d %p)\n", angle, is_sideways, transform);
return IDWriteTextAnalyzer2_GetGlyphOrientationTransform(iface, angle, is_sideways, 0.0, 0.0, transform);
}
static HRESULT WINAPI dwritetextanalyzer1_GetScriptProperties(IDWriteTextAnalyzer2 *iface, DWRITE_SCRIPT_ANALYSIS sa,
@ -1425,10 +1425,66 @@ static HRESULT WINAPI dwritetextanalyzer1_GetJustifiedGlyphs(IDWriteTextAnalyzer
}
static HRESULT WINAPI dwritetextanalyzer2_GetGlyphOrientationTransform(IDWriteTextAnalyzer2 *iface,
DWRITE_GLYPH_ORIENTATION_ANGLE angle, BOOL is_sideways, FLOAT originX, FLOAT originY, DWRITE_MATRIX *transform)
DWRITE_GLYPH_ORIENTATION_ANGLE angle, BOOL is_sideways, FLOAT originX, FLOAT originY, DWRITE_MATRIX *m)
{
FIXME("(%d %d %.2f %.2f %p): stub\n", angle, is_sideways, originX, originY, transform);
return E_NOTIMPL;
static const DWRITE_MATRIX transforms[] = {
{ 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 },
{ 0.0, 1.0, -1.0, 0.0, 0.0, 0.0 },
{ -1.0, 0.0, 0.0, -1.0, 0.0, 0.0 },
{ 0.0, -1.0, 1.0, 0.0, 0.0, 0.0 }
};
TRACE("(%d %d %.2f %.2f %p)\n", angle, is_sideways, originX, originY, m);
if ((UINT32)angle > DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES) {
memset(m, 0, sizeof(*m));
return E_INVALIDARG;
}
/* for sideways case simply rotate 90 degrees more */
if (is_sideways) {
switch (angle) {
case DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES:
angle = DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES;
break;
case DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES:
angle = DWRITE_GLYPH_ORIENTATION_ANGLE_180_DEGREES;
break;
case DWRITE_GLYPH_ORIENTATION_ANGLE_180_DEGREES:
angle = DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES;
break;
case DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES:
angle = DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES;
break;
default:
;
}
}
*m = transforms[angle];
/* shift components represent transform necessary to get from original point to
rotated one in new coordinate system */
if ((originX != 0.0 || originY != 0.0) && angle != DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES) {
const DWRITE_MATRIX *p;
switch (angle) {
case DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES:
angle = DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES;
break;
case DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES:
angle = DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES;
break;
default:
;
}
p = &transforms[angle];
m->dx = originX - (p->m11 * originX + p->m12 * originY);
m->dy = originY - (p->m21 * originX + p->m22 * originY);
}
return S_OK;
}
static HRESULT WINAPI dwritetextanalyzer2_GetTypographicFeatures(IDWriteTextAnalyzer2 *iface,

View File

@ -21,6 +21,7 @@
#define COBJMACROS
#include <assert.h>
#include <stdio.h>
#include "initguid.h"
#include "windows.h"
@ -1669,6 +1670,149 @@ static void test_ApplyCharacterSpacing(void)
IDWriteTextAnalyzer1_Release(analyzer1);
}
struct orientation_transf_test {
DWRITE_GLYPH_ORIENTATION_ANGLE angle;
BOOL is_sideways;
DWRITE_MATRIX m;
};
static const struct orientation_transf_test ot_tests[] = {
{ DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES, FALSE, { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES, FALSE, { 0.0, 1.0, -1.0, 0.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_180_DEGREES, FALSE, { -1.0, 0.0, 0.0, -1.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES, FALSE, { 0.0, -1.0, 1.0, 0.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES, TRUE, { 0.0, 1.0, -1.0, 0.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES, TRUE, { -1.0, 0.0, 0.0, -1.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_180_DEGREES, TRUE, { 0.0, -1.0, 1.0, 0.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES, TRUE, { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 } }
};
static inline const char *dbgstr_matrix(const DWRITE_MATRIX *m)
{
static char buff[64];
sprintf(buff, "{%.2f, %.2f, %.2f, %.2f, %.2f, %.2f}", m->m11, m->m12,
m->m21, m->m22, m->dx, m->dy);
return buff;
}
static void test_GetGlyphOrientationTransform(void)
{
IDWriteTextAnalyzer2 *analyzer2;
IDWriteTextAnalyzer1 *analyzer1;
IDWriteTextAnalyzer *analyzer;
FLOAT originx, originy;
DWRITE_MATRIX m;
HRESULT hr;
int i;
hr = IDWriteFactory_CreateTextAnalyzer(factory, &analyzer);
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IDWriteTextAnalyzer_QueryInterface(analyzer, &IID_IDWriteTextAnalyzer1, (void**)&analyzer1);
IDWriteTextAnalyzer_Release(analyzer);
if (hr != S_OK) {
win_skip("GetGlyphOrientationTransform() is not supported.\n");
return;
}
/* invalid angle value */
memset(&m, 0xcc, sizeof(m));
hr = IDWriteTextAnalyzer1_GetGlyphOrientationTransform(analyzer1,
DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES + 1, FALSE, &m);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
ok(m.m11 == 0.0, "got %.2f\n", m.m11);
for (i = 0; i < sizeof(ot_tests)/sizeof(ot_tests[0]); i++) {
memset(&m, 0, sizeof(m));
hr = IDWriteTextAnalyzer1_GetGlyphOrientationTransform(analyzer1, ot_tests[i].angle,
ot_tests[i].is_sideways, &m);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(!memcmp(&ot_tests[i].m, &m, sizeof(m)), "%d: wrong matrix %s\n", i, dbgstr_matrix(&m));
}
hr = IDWriteTextAnalyzer1_QueryInterface(analyzer1, &IID_IDWriteTextAnalyzer2, (void**)&analyzer2);
IDWriteTextAnalyzer1_Release(analyzer1);
if (hr != S_OK) {
win_skip("IDWriteTextAnalyzer2::GetGlyphOrientationTransform() is not supported.\n");
return;
}
/* invalid angle value */
memset(&m, 0xcc, sizeof(m));
hr = IDWriteTextAnalyzer2_GetGlyphOrientationTransform(analyzer2,
DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES + 1, FALSE, 0.0, 0.0, &m);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
ok(m.m11 == 0.0, "got %.2f\n", m.m11);
originx = 50.0;
originy = 60.0;
for (i = 0; i < sizeof(ot_tests)/sizeof(ot_tests[0]); i++) {
DWRITE_GLYPH_ORIENTATION_ANGLE angle = DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES;
DWRITE_MATRIX m_exp;
memset(&m, 0, sizeof(m));
/* zero offset gives same result as a call from IDWriteTextAnalyzer1 */
hr = IDWriteTextAnalyzer2_GetGlyphOrientationTransform(analyzer2, ot_tests[i].angle,
ot_tests[i].is_sideways, 0.0, 0.0, &m);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(!memcmp(&ot_tests[i].m, &m, sizeof(m)), "%d: wrong matrix %s\n", i, dbgstr_matrix(&m));
m_exp = ot_tests[i].m;
hr = IDWriteTextAnalyzer2_GetGlyphOrientationTransform(analyzer2, ot_tests[i].angle,
ot_tests[i].is_sideways, originx, originy, &m);
ok(hr == S_OK, "got 0x%08x\n", hr);
/* 90 degrees more for sideways */
if (ot_tests[i].is_sideways) {
switch (ot_tests[i].angle)
{
case DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES:
angle = DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES;
break;
case DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES:
angle = DWRITE_GLYPH_ORIENTATION_ANGLE_180_DEGREES;
break;
case DWRITE_GLYPH_ORIENTATION_ANGLE_180_DEGREES:
angle = DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES;
break;
case DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES:
angle = DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES;
break;
default:
;
}
}
else
angle = ot_tests[i].angle;
/* set expected offsets */
switch (angle)
{
case DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES:
break;
case DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES:
m_exp.dx = originx + originy;
m_exp.dy = originy - originx;
break;
case DWRITE_GLYPH_ORIENTATION_ANGLE_180_DEGREES:
m_exp.dx = originx + originx;
m_exp.dy = originy + originy;
break;
case DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES:
m_exp.dx = originx - originy;
m_exp.dy = originy + originx;
break;
default:
;
}
ok(!memcmp(&m_exp, &m, sizeof(m)), "%d: wrong matrix %s\n", i, dbgstr_matrix(&m));
}
IDWriteTextAnalyzer2_Release(analyzer2);
}
START_TEST(analyzer)
{
HRESULT hr;
@ -1693,6 +1837,7 @@ START_TEST(analyzer)
test_GetTypographicFeatures();
test_GetGlyphPlacements();
test_ApplyCharacterSpacing();
test_GetGlyphOrientationTransform();
IDWriteFactory_Release(factory);
}