dwrite: Implement ApplyCharacterSpacing().
This commit is contained in:
parent
4a1ebd7369
commit
14158a71db
|
@ -1076,14 +1076,229 @@ static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWrite
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static inline FLOAT get_cluster_advance(const FLOAT *advances, UINT32 start, UINT32 end)
|
||||
{
|
||||
FLOAT advance = 0.0;
|
||||
for (; start < end; start++)
|
||||
advance += advances[start];
|
||||
return advance;
|
||||
}
|
||||
|
||||
static void apply_single_glyph_spacing(FLOAT leading_spacing, FLOAT trailing_spacing,
|
||||
FLOAT min_advance_width, UINT32 g, FLOAT const *advances, DWRITE_GLYPH_OFFSET const *offsets,
|
||||
DWRITE_SHAPING_GLYPH_PROPERTIES const *props, FLOAT *modified_advances, DWRITE_GLYPH_OFFSET *modified_offsets)
|
||||
{
|
||||
BOOL reduced = leading_spacing < 0.0 || trailing_spacing < 0.0;
|
||||
FLOAT advance = advances[g];
|
||||
FLOAT origin = 0.0;
|
||||
|
||||
if (props[g].isZeroWidthSpace) {
|
||||
modified_advances[g] = advances[g];
|
||||
modified_offsets[g] = offsets[g];
|
||||
return;
|
||||
}
|
||||
|
||||
/* first apply negative spacing and check if we hit minimum width */
|
||||
if (leading_spacing < 0.0) {
|
||||
advance += leading_spacing;
|
||||
origin -= leading_spacing;
|
||||
}
|
||||
if (trailing_spacing < 0.0)
|
||||
advance += trailing_spacing;
|
||||
|
||||
if (advance < min_advance_width) {
|
||||
FLOAT half = (min_advance_width - advance) / 2.0;
|
||||
|
||||
if (!reduced)
|
||||
origin -= half;
|
||||
else if (leading_spacing < 0.0 && trailing_spacing < 0.0)
|
||||
origin -= half;
|
||||
else if (leading_spacing < 0.0)
|
||||
origin -= min_advance_width - advance;
|
||||
|
||||
advance = min_advance_width;
|
||||
}
|
||||
|
||||
/* now apply positive spacing adjustments */
|
||||
if (leading_spacing > 0.0) {
|
||||
advance += leading_spacing;
|
||||
origin -= leading_spacing;
|
||||
}
|
||||
if (trailing_spacing > 0.0)
|
||||
advance += trailing_spacing;
|
||||
|
||||
modified_advances[g] = advance;
|
||||
modified_offsets[g].advanceOffset = offsets[g].advanceOffset - origin;
|
||||
/* ascender is never touched, it's orthogonal to reading direction and is not
|
||||
affected by advance adjustments */
|
||||
modified_offsets[g].ascenderOffset = offsets[g].ascenderOffset;
|
||||
}
|
||||
|
||||
static void apply_cluster_spacing(FLOAT leading_spacing, FLOAT trailing_spacing, FLOAT min_advance_width,
|
||||
UINT32 start, UINT32 end, FLOAT const *advances, DWRITE_GLYPH_OFFSET const *offsets,
|
||||
FLOAT *modified_advances, DWRITE_GLYPH_OFFSET *modified_offsets)
|
||||
{
|
||||
BOOL reduced = leading_spacing < 0.0 || trailing_spacing < 0.0;
|
||||
FLOAT advance = get_cluster_advance(advances, start, end);
|
||||
FLOAT origin = 0.0;
|
||||
UINT16 g;
|
||||
|
||||
modified_advances[start] = advances[start];
|
||||
modified_advances[end-1] = advances[end-1];
|
||||
|
||||
/* first apply negative spacing and check if we hit minimum width */
|
||||
if (leading_spacing < 0.0) {
|
||||
advance += leading_spacing;
|
||||
modified_advances[start] += leading_spacing;
|
||||
origin -= leading_spacing;
|
||||
}
|
||||
if (trailing_spacing < 0.0) {
|
||||
advance += trailing_spacing;
|
||||
modified_advances[end-1] += trailing_spacing;
|
||||
}
|
||||
if (advance < min_advance_width) {
|
||||
/* additional spacing is only applied to leading and trailing glyph */
|
||||
FLOAT half = (min_advance_width - advance) / 2.0;
|
||||
|
||||
if (!reduced) {
|
||||
origin -= half;
|
||||
modified_advances[start] += half;
|
||||
modified_advances[end-1] += half;
|
||||
}
|
||||
else if (leading_spacing < 0.0 && trailing_spacing < 0.0) {
|
||||
origin -= half;
|
||||
modified_advances[start] += half;
|
||||
modified_advances[end-1] += half;
|
||||
}
|
||||
else if (leading_spacing < 0.0) {
|
||||
origin -= min_advance_width - advance;
|
||||
modified_advances[start] += min_advance_width - advance;
|
||||
}
|
||||
else
|
||||
modified_advances[end-1] += min_advance_width - advance;
|
||||
|
||||
advance = min_advance_width;
|
||||
}
|
||||
|
||||
/* now apply positive spacing adjustments */
|
||||
if (leading_spacing > 0.0) {
|
||||
modified_advances[start] += leading_spacing;
|
||||
origin -= leading_spacing;
|
||||
}
|
||||
if (trailing_spacing > 0.0)
|
||||
modified_advances[end-1] += trailing_spacing;
|
||||
|
||||
for (g = start; g < end; g++) {
|
||||
if (g == start) {
|
||||
modified_offsets[g].advanceOffset = offsets[g].advanceOffset - origin;
|
||||
modified_offsets[g].ascenderOffset = offsets[g].ascenderOffset;
|
||||
}
|
||||
else if (g == end - 1)
|
||||
/* trailing glyph offset is not adjusted */
|
||||
modified_offsets[g] = offsets[g];
|
||||
else {
|
||||
/* for all glyphs within a cluster use original advances and offsets */
|
||||
modified_advances[g] = advances[g];
|
||||
modified_offsets[g] = offsets[g];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline UINT32 get_cluster_length(UINT16 const *clustermap, UINT32 start, UINT32 text_len)
|
||||
{
|
||||
UINT16 g = clustermap[start];
|
||||
UINT32 length = 1;
|
||||
|
||||
while (start < text_len && clustermap[++start] == g)
|
||||
length++;
|
||||
return length;
|
||||
}
|
||||
|
||||
/* Applies spacing adjustments to clusters.
|
||||
|
||||
Adjustments are applied in the following order:
|
||||
|
||||
1. Negative adjustments
|
||||
|
||||
Leading and trailing spacing could be negative, at this step
|
||||
only negative ones are actually applied. Leading spacing is only
|
||||
applied to leading glyph, trailing - to trailing glyph.
|
||||
|
||||
2. Minimum advance width
|
||||
|
||||
Advances could only be reduced at this point or unchanged. In any
|
||||
case it's checked if cluster advance width is less than minimum width.
|
||||
If it's the case advance width is incremented up to minimum value.
|
||||
|
||||
Important part is the direction in which this increment is applied;
|
||||
it depends on from which directions total cluster advance was trimmed
|
||||
at step 1. So it could be incremented from leading, trailing, or both
|
||||
sides. When applied to both sides, each side gets half of difference
|
||||
that bring advance to minimum width.
|
||||
|
||||
3. Positive adjustments
|
||||
|
||||
After minimum width rule was applied, positive spacing is applied in same
|
||||
way as negative ones on step 1.
|
||||
|
||||
Glyph offset for leading glyph is adjusted too in a way that glyph origin
|
||||
keeps its position in coordinate system where initial advance width is counted
|
||||
from 0.
|
||||
|
||||
Glyph properties
|
||||
|
||||
It's known that isZeroWidthSpace property keeps initial advance from changing.
|
||||
|
||||
TODO: test other properties; make isZeroWidthSpace work properly for clusters
|
||||
with more than one glyph.
|
||||
|
||||
*/
|
||||
static HRESULT WINAPI dwritetextanalyzer1_ApplyCharacterSpacing(IDWriteTextAnalyzer2 *iface,
|
||||
FLOAT leading_spacing, FLOAT trailing_spacing, FLOAT min_advance_width, UINT32 len,
|
||||
UINT32 glyph_count, UINT16 const *clustermap, FLOAT const *advances, DWRITE_GLYPH_OFFSET const *offsets,
|
||||
DWRITE_SHAPING_GLYPH_PROPERTIES const *props, FLOAT *modified_advances, DWRITE_GLYPH_OFFSET *modified_offsets)
|
||||
{
|
||||
FIXME("(%.2f %.2f %.2f %u %u %p %p %p %p %p %p): stub\n", leading_spacing, trailing_spacing, min_advance_width,
|
||||
UINT16 start;
|
||||
|
||||
TRACE("(%.2f %.2f %.2f %u %u %p %p %p %p %p %p)\n", leading_spacing, trailing_spacing, min_advance_width,
|
||||
len, glyph_count, clustermap, advances, offsets, props, modified_advances, modified_offsets);
|
||||
return E_NOTIMPL;
|
||||
|
||||
if (min_advance_width < 0.0) {
|
||||
memset(modified_advances, 0, glyph_count*sizeof(*modified_advances));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
/* minimum advance is not applied if no adjustments were made */
|
||||
if (leading_spacing == 0.0 && trailing_spacing == 0.0) {
|
||||
memmove(modified_advances, advances, glyph_count*sizeof(*advances));
|
||||
memmove(modified_offsets, offsets, glyph_count*sizeof(*offsets));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
start = 0;
|
||||
for (start = 0; start < len;) {
|
||||
UINT32 length = get_cluster_length(clustermap, start, len);
|
||||
|
||||
if (length == 1) {
|
||||
UINT32 g = clustermap[start];
|
||||
|
||||
apply_single_glyph_spacing(leading_spacing, trailing_spacing, min_advance_width,
|
||||
g, advances, offsets, props, modified_advances, modified_offsets);
|
||||
}
|
||||
else {
|
||||
UINT32 g_start, g_end;
|
||||
|
||||
g_start = clustermap[start];
|
||||
g_end = (start + length < len) ? clustermap[start + length] : glyph_count;
|
||||
|
||||
apply_cluster_spacing(leading_spacing, trailing_spacing, min_advance_width,
|
||||
g_start, g_end, advances, offsets, modified_advances, modified_offsets);
|
||||
}
|
||||
|
||||
start += length;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritetextanalyzer1_GetBaseline(IDWriteTextAnalyzer2 *iface, IDWriteFontFace *face,
|
||||
|
|
|
@ -1449,6 +1449,167 @@ static void test_GetGlyphPlacements(void)
|
|||
DELETE_FONTFILE(path);
|
||||
}
|
||||
|
||||
struct spacing_test {
|
||||
FLOAT leading;
|
||||
FLOAT trailing;
|
||||
FLOAT min_advance;
|
||||
FLOAT advances[3];
|
||||
FLOAT offsets[3];
|
||||
FLOAT modified_advances[3];
|
||||
FLOAT modified_offsets[3];
|
||||
BOOL single_cluster;
|
||||
BOOL is_ZWS[3];
|
||||
};
|
||||
|
||||
static const struct spacing_test spacing_tests[] = {
|
||||
{ 0.0, 0.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 11.0 }, { 2.0, 3.0 } }, /* 0 */
|
||||
{ 0.0, 0.0, 2.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 11.0 }, { 2.0, 3.0 } },
|
||||
{ 1.0, 0.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 11.0, 12.0 }, { 3.0, 4.0 } },
|
||||
{ 1.0, 1.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 12.0, 13.0 }, { 3.0, 4.0 } },
|
||||
{ 1.0, -1.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 11.0 }, { 3.0, 4.0 } },
|
||||
{ 0.0, -10.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 0.0, 1.0 }, { 2.0, 3.0 } }, /* 5 */
|
||||
{ -5.0, -4.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 5.0, 5.0 }, { -1.0, -0.5 } },
|
||||
{ -5.0, -5.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 5.0, 5.0 }, { -0.5, 0.0 } },
|
||||
{ 2.0, 0.0, 5.0, { 1.0, 2.0 }, { 2.0, 3.0 }, { 7.0, 7.0 }, { 6.0, 6.5 } },
|
||||
{ 2.0, 1.0, 5.0, { 1.0, 2.0 }, { 2.0, 3.0 }, { 8.0, 8.0 }, { 6.0, 6.5 } },
|
||||
{ 2.0, -10.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 7.0, 7.0 }, { 4.0, 5.0 } }, /* 10 */
|
||||
{ 1.0, -10.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 6.0, 6.0 }, { 3.0, 4.0 } },
|
||||
{ -10.0, 1.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 6.0, 6.0 }, { -3.0, -3.0 } },
|
||||
{ 0.0, -10.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 5.0, 5.0 }, { 2.0, 3.0 } },
|
||||
{ 1.0, -10.0, -5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 0.0, 0.0 }, { 2.0, 3.0 } },
|
||||
{ -10.0, 1.0, 5.0, { 8.0, 11.0 }, { 2.0, 3.0 }, { 6.0, 6.0 }, { -1.0, -3.0 } }, /* 15 */
|
||||
/* cluster of more than 1 glyph */
|
||||
{ 0.0, 0.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 11.0 }, { 2.0, 3.0 }, TRUE },
|
||||
{ 1.0, 0.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.5 }, { 11.0, 11.0 }, { 3.0, 3.5 }, TRUE },
|
||||
{ 1.0, 1.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 11.0, 12.0 }, { 3.0, 3.0 }, TRUE },
|
||||
{ 1.0, -1.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 11.0, 10.0 }, { 3.0, 3.0 }, TRUE },
|
||||
{ 0.0, -10.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 1.0 }, { 2.0, 3.0 }, TRUE }, /* 20 */
|
||||
{ 0.0, -10.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 1.0 }, { 2.0, 3.0 }, TRUE },
|
||||
{ 1.0, -10.0, -5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 0.0, 0.0 }, { 2.0, 3.0 }, TRUE },
|
||||
{ -5.0, -10.0, 4.0, { 10.0, 11.0, 12.0 }, { 2.0, 3.0, 4.0 }, { 5.0, 11.0, 2.0 }, { -3.0, 3.0, 4.0 }, TRUE },
|
||||
{ -10.0, -10.0, 4.0, { 10.0, 11.0, 12.0 }, { 2.0, 3.0, 4.0 }, { 0.0, 11.0, 2.0 }, { -8.0, 3.0, 4.0 }, TRUE },
|
||||
{ -10.0, -10.0, 5.0, { 10.0, 1.0, 12.0 }, { 2.0, 3.0, 4.0 }, { 1.0, 1.0, 3.0 }, { -7.0, 3.0, 4.0 }, TRUE }, /* 25 */
|
||||
{ -10.0, 1.0, 5.0, { 10.0, 1.0, 2.0 }, { 2.0, 3.0, 4.0 }, { 2.0, 1.0, 3.0 }, { -6.0, 3.0, 4.0 }, TRUE },
|
||||
{ 1.0, -10.0, 5.0, { 2.0, 1.0, 10.0 }, { 2.0, 3.0, 4.0 }, { 3.0, 1.0, 2.0 }, { 3.0, 3.0, 4.0 }, TRUE },
|
||||
{ -10.0, -10.0, 5.0, { 11.0, 1.0, 11.0 }, { 2.0, 3.0, 4.0 }, { 2.0, 1.0, 2.0 }, { -7.0, 3.0, 4.0 }, TRUE },
|
||||
/* isZeroWidthSpace set */
|
||||
{ 1.0, 0.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 12.0 }, { 2.0, 4.0 }, FALSE, { TRUE, FALSE } },
|
||||
{ 1.0, 1.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 13.0 }, { 2.0, 4.0 }, FALSE, { TRUE, FALSE } }, /* 30 */
|
||||
{ 1.0, -1.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 11.0 }, { 3.0, 3.0 }, FALSE, { FALSE, TRUE } },
|
||||
{ 0.0, -10.0, 0.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 1.0 }, { 2.0, 3.0 }, FALSE, { TRUE, FALSE } },
|
||||
{ -5.0, -4.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 5.0, 11.0 }, { -1.0, 3.0 }, FALSE, { FALSE, TRUE } },
|
||||
{ -5.0, -5.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 11.0 }, { 2.0, 3.0 }, FALSE, { TRUE, TRUE } },
|
||||
{ 2.0, 0.0, 5.0, { 1.0, 2.0 }, { 2.0, 3.0 }, { 7.0, 2.0 }, { 6.0, 3.0 }, FALSE, { FALSE, TRUE } }, /* 35 */
|
||||
{ 2.0, 1.0, 5.0, { 1.0, 2.0 }, { 2.0, 3.0 }, { 8.0, 2.0 }, { 6.0, 3.0 }, FALSE, { FALSE, TRUE } },
|
||||
{ 2.0, -10.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 11.0 }, { 2.0, 3.0 }, FALSE, { TRUE, TRUE } },
|
||||
{ 1.0, -10.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 6.0, 11.0 }, { 3.0, 3.0 }, FALSE, { FALSE, TRUE } },
|
||||
{ -10.0, 1.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 10.0, 11.0 }, { 2.0, 3.0 }, FALSE, { TRUE, TRUE } },
|
||||
{ 0.0, -10.0, 5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 5.0, 11.0 }, { 2.0, 3.0 }, FALSE, { FALSE, TRUE } }, /* 40 */
|
||||
{ 1.0, -10.0, -5.0, { 10.0, 11.0 }, { 2.0, 3.0 }, { 0.0, 0.0 }, { 2.0, 3.0 }, FALSE, { TRUE, FALSE } },
|
||||
{ -10.0, 1.0, 5.0, { 8.0, 11.0 }, { 2.0, 3.0 }, { 6.0, 11.0 }, { -1.0, 3.0 }, FALSE, { FALSE, TRUE } },
|
||||
};
|
||||
|
||||
static void test_ApplyCharacterSpacing(void)
|
||||
{
|
||||
DWRITE_SHAPING_GLYPH_PROPERTIES props[3];
|
||||
IDWriteTextAnalyzer1 *analyzer1;
|
||||
IDWriteTextAnalyzer *analyzer;
|
||||
UINT16 clustermap[2];
|
||||
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("ApplyCharacterSpacing() is not supported.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(spacing_tests)/sizeof(spacing_tests[0]); i++) {
|
||||
const struct spacing_test *ptr = spacing_tests + i;
|
||||
DWRITE_GLYPH_OFFSET offsets[3];
|
||||
UINT32 glyph_count;
|
||||
FLOAT advances[3];
|
||||
|
||||
offsets[0].advanceOffset = ptr->offsets[0];
|
||||
offsets[1].advanceOffset = ptr->offsets[1];
|
||||
offsets[2].advanceOffset = ptr->offsets[2];
|
||||
/* Ascender offsets are never thouched as spacing applies in reading direction only,
|
||||
we'll only test them to see if they are not changed */
|
||||
offsets[0].ascenderOffset = 23.0;
|
||||
offsets[1].ascenderOffset = 32.0;
|
||||
offsets[2].ascenderOffset = 31.0;
|
||||
|
||||
glyph_count = ptr->advances[2] > 0.0 ? 3 : 2;
|
||||
if (ptr->single_cluster) {
|
||||
clustermap[0] = 0;
|
||||
clustermap[1] = 0;
|
||||
}
|
||||
else {
|
||||
/* trivial case with one glyph per cluster */
|
||||
clustermap[0] = 0;
|
||||
clustermap[1] = 1;
|
||||
}
|
||||
|
||||
advances[0] = advances[1] = 123.45;
|
||||
memset(props, 0, sizeof(props));
|
||||
props[0].isZeroWidthSpace = ptr->is_ZWS[0];
|
||||
props[1].isZeroWidthSpace = ptr->is_ZWS[1];
|
||||
props[2].isZeroWidthSpace = ptr->is_ZWS[2];
|
||||
|
||||
hr = IDWriteTextAnalyzer1_ApplyCharacterSpacing(analyzer1,
|
||||
ptr->leading,
|
||||
ptr->trailing,
|
||||
ptr->min_advance,
|
||||
sizeof(clustermap)/sizeof(clustermap[0]),
|
||||
glyph_count,
|
||||
clustermap,
|
||||
ptr->advances,
|
||||
offsets,
|
||||
props,
|
||||
advances,
|
||||
offsets);
|
||||
/* invalid argument cases */
|
||||
if (ptr->min_advance < 0.0)
|
||||
ok(hr == E_INVALIDARG, "%d: got 0x%08x\n", i, hr);
|
||||
else
|
||||
ok(hr == S_OK, "%d: got 0x%08x\n", i, hr);
|
||||
if (hr == S_OK) {
|
||||
ok(ptr->modified_advances[0] == advances[0], "%d: got advance[0] %.2f, expected %.2f\n", i, advances[0], ptr->modified_advances[0]);
|
||||
ok(ptr->modified_advances[1] == advances[1], "%d: got advance[1] %.2f, expected %.2f\n", i, advances[1], ptr->modified_advances[1]);
|
||||
if (glyph_count > 2)
|
||||
ok(ptr->modified_advances[2] == advances[2], "%d: got advance[2] %.2f, expected %.2f\n", i, advances[2], ptr->modified_advances[2]);
|
||||
|
||||
ok(ptr->modified_offsets[0] == offsets[0].advanceOffset, "%d: got offset[0] %.2f, expected %.2f\n", i,
|
||||
offsets[0].advanceOffset, ptr->modified_offsets[0]);
|
||||
ok(ptr->modified_offsets[1] == offsets[1].advanceOffset, "%d: got offset[1] %.2f, expected %.2f\n", i,
|
||||
offsets[1].advanceOffset, ptr->modified_offsets[1]);
|
||||
if (glyph_count > 2)
|
||||
ok(ptr->modified_offsets[2] == offsets[2].advanceOffset, "%d: got offset[2] %.2f, expected %.2f\n", i,
|
||||
offsets[2].advanceOffset, ptr->modified_offsets[2]);
|
||||
|
||||
ok(offsets[0].ascenderOffset == 23.0, "%d: unexpected ascenderOffset %.2f\n", i, offsets[0].ascenderOffset);
|
||||
ok(offsets[1].ascenderOffset == 32.0, "%d: unexpected ascenderOffset %.2f\n", i, offsets[1].ascenderOffset);
|
||||
ok(offsets[2].ascenderOffset == 31.0, "%d: unexpected ascenderOffset %.2f\n", i, offsets[2].ascenderOffset);
|
||||
}
|
||||
else {
|
||||
ok(ptr->modified_advances[0] == advances[0], "%d: got advance[0] %.2f, expected %.2f\n", i, advances[0], ptr->modified_advances[0]);
|
||||
ok(ptr->modified_advances[1] == advances[1], "%d: got advance[1] %.2f, expected %.2f\n", i, advances[1], ptr->modified_advances[1]);
|
||||
ok(ptr->offsets[0] == offsets[0].advanceOffset, "%d: got offset[0] %.2f, expected %.2f\n", i,
|
||||
offsets[0].advanceOffset, ptr->modified_offsets[0]);
|
||||
ok(ptr->offsets[1] == offsets[1].advanceOffset, "%d: got offset[1] %.2f, expected %.2f\n", i,
|
||||
offsets[1].advanceOffset, ptr->modified_offsets[1]);
|
||||
ok(offsets[0].ascenderOffset == 23.0, "%d: unexpected ascenderOffset %.2f\n", i, offsets[0].ascenderOffset);
|
||||
ok(offsets[1].ascenderOffset == 32.0, "%d: unexpected ascenderOffset %.2f\n", i, offsets[1].ascenderOffset);
|
||||
}
|
||||
}
|
||||
|
||||
IDWriteTextAnalyzer1_Release(analyzer1);
|
||||
}
|
||||
|
||||
START_TEST(analyzer)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
@ -1472,6 +1633,7 @@ START_TEST(analyzer)
|
|||
test_numbersubstitution();
|
||||
test_GetTypographicFeatures();
|
||||
test_GetGlyphPlacements();
|
||||
test_ApplyCharacterSpacing();
|
||||
|
||||
IDWriteFactory_Release(factory);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue