Fix Cursive positioning
Test case: "مرا" rendered using IranNastaliq.
This commit is contained in:
parent
aefdb64689
commit
ea22c749c7
|
@ -826,123 +826,6 @@ struct CursivePosFormat1
|
||||||
inline bool apply (hb_apply_context_t *c) const
|
inline bool apply (hb_apply_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_APPLY ();
|
TRACE_APPLY ();
|
||||||
/* Now comes the messiest part of the whole OpenType
|
|
||||||
specification. At first glance, cursive connections seem easy
|
|
||||||
to understand, but there are pitfalls! The reason is that
|
|
||||||
the specs don't mention how to compute the advance values
|
|
||||||
resp. glyph offsets. I was told it would be an omission, to
|
|
||||||
be fixed in the next OpenType version... Again many thanks to
|
|
||||||
Andrei Burago <andreib@microsoft.com> for clarifications.
|
|
||||||
|
|
||||||
Consider the following example:
|
|
||||||
|
|
||||||
| xadv1 |
|
|
||||||
+---------+
|
|
||||||
| |
|
|
||||||
+-----+--+ 1 |
|
|
||||||
| | .| |
|
|
||||||
| 0+--+------+
|
|
||||||
| 2 |
|
|
||||||
| |
|
|
||||||
0+--------+
|
|
||||||
| xadv2 |
|
|
||||||
|
|
||||||
glyph1: advance width = 12
|
|
||||||
anchor point = (3,1)
|
|
||||||
|
|
||||||
glyph2: advance width = 11
|
|
||||||
anchor point = (9,4)
|
|
||||||
|
|
||||||
LSB is 1 for both glyphs (so the boxes drawn above are glyph
|
|
||||||
bboxes). Writing direction is R2L; `0' denotes the glyph's
|
|
||||||
coordinate origin.
|
|
||||||
|
|
||||||
Now the surprising part: The advance width of the *left* glyph
|
|
||||||
(resp. of the *bottom* glyph) will be modified, no matter
|
|
||||||
whether the writing direction is L2R or R2L (resp. T2B or
|
|
||||||
B2T)! This assymetry is caused by the fact that the glyph's
|
|
||||||
coordinate origin is always the lower left corner for all
|
|
||||||
writing directions.
|
|
||||||
|
|
||||||
Continuing the above example, we can compute the new
|
|
||||||
(horizontal) advance width of glyph2 as
|
|
||||||
|
|
||||||
9 - 3 = 6 ,
|
|
||||||
|
|
||||||
and the new vertical offset of glyph2 as
|
|
||||||
|
|
||||||
1 - 4 = -3 .
|
|
||||||
|
|
||||||
|
|
||||||
Vertical writing direction is far more complicated:
|
|
||||||
|
|
||||||
a) Assuming that we recompute the advance height of the lower glyph:
|
|
||||||
|
|
||||||
--
|
|
||||||
+---------+
|
|
||||||
-- | |
|
|
||||||
+-----+--+ 1 | yadv1
|
|
||||||
| | .| |
|
|
||||||
yadv2 | 0+--+------+ -- BSB1 --
|
|
||||||
| 2 | -- -- y_offset
|
|
||||||
| |
|
|
||||||
BSB2 -- 0+--------+ --
|
|
||||||
-- --
|
|
||||||
|
|
||||||
glyph1: advance height = 6
|
|
||||||
anchor point = (3,1)
|
|
||||||
|
|
||||||
glyph2: advance height = 7
|
|
||||||
anchor point = (9,4)
|
|
||||||
|
|
||||||
TSB is 1 for both glyphs; writing direction is T2B.
|
|
||||||
|
|
||||||
|
|
||||||
BSB1 = yadv1 - (TSB1 + ymax1)
|
|
||||||
BSB2 = yadv2 - (TSB2 + ymax2)
|
|
||||||
y_offset = y2 - y1
|
|
||||||
|
|
||||||
vertical advance width of glyph2
|
|
||||||
= y_offset + BSB2 - BSB1
|
|
||||||
= (y2 - y1) + (yadv2 - (TSB2 + ymax2)) - (yadv1 - (TSB1 + ymax1))
|
|
||||||
= y2 - y1 + yadv2 - TSB2 - ymax2 - (yadv1 - TSB1 - ymax1)
|
|
||||||
= y2 - y1 + yadv2 - TSB2 - ymax2 - yadv1 + TSB1 + ymax1
|
|
||||||
|
|
||||||
|
|
||||||
b) Assuming that we recompute the advance height of the upper glyph:
|
|
||||||
|
|
||||||
-- --
|
|
||||||
+---------+ -- TSB1
|
|
||||||
-- -- | |
|
|
||||||
TSB2 -- +-----+--+ 1 | yadv1 ymax1
|
|
||||||
| | .| |
|
|
||||||
yadv2 | 0+--+------+ -- --
|
|
||||||
ymax2 | 2 | -- y_offset
|
|
||||||
| |
|
|
||||||
-- 0+--------+ --
|
|
||||||
--
|
|
||||||
|
|
||||||
glyph1: advance height = 6
|
|
||||||
anchor point = (3,1)
|
|
||||||
|
|
||||||
glyph2: advance height = 7
|
|
||||||
anchor point = (9,4)
|
|
||||||
|
|
||||||
TSB is 1 for both glyphs; writing direction is T2B.
|
|
||||||
|
|
||||||
y_offset = y2 - y1
|
|
||||||
|
|
||||||
vertical advance width of glyph2
|
|
||||||
= TSB1 + ymax1 + y_offset - (TSB2 + ymax2)
|
|
||||||
= TSB1 + ymax1 + y2 - y1 - TSB2 - ymax2
|
|
||||||
|
|
||||||
|
|
||||||
Comparing a) with b) shows that b) is easier to compute. I'll wait
|
|
||||||
for a reply from Andrei to see what should really be implemented...
|
|
||||||
|
|
||||||
Since horizontal advance widths or vertical advance heights
|
|
||||||
can be used alone but not together, no ambiguity occurs. */
|
|
||||||
|
|
||||||
struct hb_ot_layout_context_t::info_t::gpos_t *gpi = &c->layout->info.gpos;
|
struct hb_ot_layout_context_t::info_t::gpos_t *gpi = &c->layout->info.gpos;
|
||||||
hb_codepoint_t last_pos = gpi->last;
|
hb_codepoint_t last_pos = gpi->last;
|
||||||
gpi->last = HB_OT_LAYOUT_GPOS_NO_LAST;
|
gpi->last = HB_OT_LAYOUT_GPOS_NO_LAST;
|
||||||
|
@ -965,15 +848,14 @@ struct CursivePosFormat1
|
||||||
|
|
||||||
/* TODO vertical */
|
/* TODO vertical */
|
||||||
|
|
||||||
|
/* Align the exit anchor of the left glyph with the entry anchor of the right glyph. */
|
||||||
if (c->buffer->props.direction == HB_DIRECTION_RTL)
|
if (c->buffer->props.direction == HB_DIRECTION_RTL)
|
||||||
{
|
{
|
||||||
/* advance is absolute, not relative */
|
c->buffer->pos[c->buffer->i].x_advance = c->buffer->pos[c->buffer->i].x_offset + entry_x - gpi->anchor_x;
|
||||||
c->buffer->pos[c->buffer->i].x_advance = entry_x - gpi->anchor_x;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* advance is absolute, not relative */
|
c->buffer->pos[last_pos].x_advance = c->buffer->pos[last_pos].x_advance + gpi->anchor_x - entry_x;
|
||||||
c->buffer->pos[last_pos].x_advance = gpi->anchor_x - entry_x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->lookup_flag & LookupFlag::RightToLeft)
|
if (c->lookup_flag & LookupFlag::RightToLeft)
|
||||||
|
|
Loading…
Reference in New Issue