[GPOS] Only mark unsafe-to-break if kerning happened
Fixes https://github.com/harfbuzz/harfbuzz/issues/1365
This commit is contained in:
parent
501a364d9b
commit
6ee6cd93d8
|
@ -103,56 +103,58 @@ struct ValueFormat : HBUINT16
|
||||||
inline unsigned int get_size (void) const
|
inline unsigned int get_size (void) const
|
||||||
{ return get_len () * Value::static_size; }
|
{ return get_len () * Value::static_size; }
|
||||||
|
|
||||||
void apply_value (hb_ot_apply_context_t *c,
|
bool apply_value (hb_ot_apply_context_t *c,
|
||||||
const void *base,
|
const void *base,
|
||||||
const Value *values,
|
const Value *values,
|
||||||
hb_glyph_position_t &glyph_pos) const
|
hb_glyph_position_t &glyph_pos) const
|
||||||
{
|
{
|
||||||
|
bool ret = false;
|
||||||
unsigned int format = *this;
|
unsigned int format = *this;
|
||||||
if (!format) return;
|
if (!format) return ret;
|
||||||
|
|
||||||
hb_font_t *font = c->font;
|
hb_font_t *font = c->font;
|
||||||
hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction);
|
hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction);
|
||||||
|
|
||||||
if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++));
|
if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++, &ret));
|
||||||
if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++));
|
if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++, &ret));
|
||||||
if (format & xAdvance) {
|
if (format & xAdvance) {
|
||||||
if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values));
|
if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values, &ret));
|
||||||
values++;
|
values++;
|
||||||
}
|
}
|
||||||
/* y_advance values grow downward but font-space grows upward, hence negation */
|
/* y_advance values grow downward but font-space grows upward, hence negation */
|
||||||
if (format & yAdvance) {
|
if (format & yAdvance) {
|
||||||
if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values));
|
if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values, &ret));
|
||||||
values++;
|
values++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_device ()) return;
|
if (!has_device ()) return ret;
|
||||||
|
|
||||||
bool use_x_device = font->x_ppem || font->num_coords;
|
bool use_x_device = font->x_ppem || font->num_coords;
|
||||||
bool use_y_device = font->y_ppem || font->num_coords;
|
bool use_y_device = font->y_ppem || font->num_coords;
|
||||||
|
|
||||||
if (!use_x_device && !use_y_device) return;
|
if (!use_x_device && !use_y_device) return ret;
|
||||||
|
|
||||||
const VariationStore &store = c->var_store;
|
const VariationStore &store = c->var_store;
|
||||||
|
|
||||||
/* pixel -> fractional pixel */
|
/* pixel -> fractional pixel */
|
||||||
if (format & xPlaDevice) {
|
if (format & xPlaDevice) {
|
||||||
if (use_x_device) glyph_pos.x_offset += (base + get_device (values)).get_x_delta (font, store);
|
if (use_x_device) glyph_pos.x_offset += (base + get_device (values, &ret)).get_x_delta (font, store);
|
||||||
values++;
|
values++;
|
||||||
}
|
}
|
||||||
if (format & yPlaDevice) {
|
if (format & yPlaDevice) {
|
||||||
if (use_y_device) glyph_pos.y_offset += (base + get_device (values)).get_y_delta (font, store);
|
if (use_y_device) glyph_pos.y_offset += (base + get_device (values, &ret)).get_y_delta (font, store);
|
||||||
values++;
|
values++;
|
||||||
}
|
}
|
||||||
if (format & xAdvDevice) {
|
if (format & xAdvDevice) {
|
||||||
if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font, store);
|
if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values, &ret)).get_x_delta (font, store);
|
||||||
values++;
|
values++;
|
||||||
}
|
}
|
||||||
if (format & yAdvDevice) {
|
if (format & yAdvDevice) {
|
||||||
/* y_advance values grow downward but font-space grows upward, hence negation */
|
/* y_advance values grow downward but font-space grows upward, hence negation */
|
||||||
if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font, store);
|
if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values, &ret)).get_y_delta (font, store);
|
||||||
values++;
|
values++;
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -175,11 +177,17 @@ struct ValueFormat : HBUINT16
|
||||||
|
|
||||||
static inline OffsetTo<Device>& get_device (Value* value)
|
static inline OffsetTo<Device>& get_device (Value* value)
|
||||||
{ return *CastP<OffsetTo<Device> > (value); }
|
{ return *CastP<OffsetTo<Device> > (value); }
|
||||||
static inline const OffsetTo<Device>& get_device (const Value* value)
|
static inline const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr)
|
||||||
{ return *CastP<OffsetTo<Device> > (value); }
|
{
|
||||||
|
if (worked) *worked |= *value;
|
||||||
|
return *CastP<OffsetTo<Device> > (value);
|
||||||
|
}
|
||||||
|
|
||||||
static inline const HBINT16& get_short (const Value* value)
|
static inline const HBINT16& get_short (const Value* value, bool *worked=nullptr)
|
||||||
{ return *CastP<HBINT16> (value); }
|
{
|
||||||
|
if (worked) *worked |= *value;
|
||||||
|
return *CastP<HBINT16> (value);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -672,9 +680,10 @@ struct PairSet
|
||||||
min = mid + 1;
|
min = mid + 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Note the intentional use of "|" instead of short-circuit "||". */
|
||||||
|
if (valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()) |
|
||||||
|
valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]))
|
||||||
buffer->unsafe_to_break (buffer->idx, pos + 1);
|
buffer->unsafe_to_break (buffer->idx, pos + 1);
|
||||||
valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
|
|
||||||
valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
|
|
||||||
if (len2)
|
if (len2)
|
||||||
pos++;
|
pos++;
|
||||||
buffer->idx = pos;
|
buffer->idx = pos;
|
||||||
|
@ -837,12 +846,11 @@ struct PairPosFormat2
|
||||||
unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
|
unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
|
||||||
if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
|
if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
|
||||||
|
|
||||||
/* TODO Only unsafe_to_break if kerning values not zero...
|
|
||||||
* https://github.com/harfbuzz/harfbuzz/issues/1365 */
|
|
||||||
buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
|
|
||||||
const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
|
const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
|
||||||
valueFormat1.apply_value (c, this, v, buffer->cur_pos());
|
/* Note the intentional use of "|" instead of short-circuit "||". */
|
||||||
valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
|
if (valueFormat1.apply_value (c, this, v, buffer->cur_pos()) |
|
||||||
|
valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]))
|
||||||
|
buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
|
||||||
|
|
||||||
buffer->idx = skippy_iter.idx;
|
buffer->idx = skippy_iter.idx;
|
||||||
if (len2)
|
if (len2)
|
||||||
|
|
Loading…
Reference in New Issue