[aat] Implement trak logic (#816)
This commit is contained in:
parent
b91e8da36e
commit
1ab16f4556
@ -263,6 +263,13 @@ struct kerx
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_AAT_TAG_kerx;
|
||||
|
||||
inline bool apply (hb_aat_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
/* TODO */
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
struct SubTableWrapper
|
||||
{
|
||||
enum coverage_flags_t {
|
||||
|
@ -37,4 +37,7 @@
|
||||
HB_INTERNAL void
|
||||
hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer);
|
||||
|
||||
HB_INTERNAL void
|
||||
hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer);
|
||||
|
||||
#endif /* HB_AAT_LAYOUT_PRIVATE_HH */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright © 2018 Google, Inc.
|
||||
* Copyright © 2018 Ebrahim Byagowi
|
||||
* Copyright © 2018 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
@ -45,10 +45,15 @@ struct TrackTableEntry
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
inline float get_value (const void *base, unsigned int index) const
|
||||
{
|
||||
return (base+values)[index];
|
||||
}
|
||||
|
||||
protected:
|
||||
Fixed track; /* Track value for this record. */
|
||||
HBUINT16 trackNameID; /* The 'name' table index for this track */
|
||||
OffsetTo<UnsizedArrayOf<Fixed> >
|
||||
OffsetTo<UnsizedArrayOf<HBINT16> >
|
||||
values; /* Offset from start of tracking table to
|
||||
* per-size tracking values for this track. */
|
||||
|
||||
@ -61,15 +66,48 @@ struct TrackData
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
/* TODO */
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
inline float get_tracking (const void *base, float ptem) const
|
||||
{
|
||||
/* CoreText points are CSS pixels (96 per inch),
|
||||
* NOT typographic points (72 per inch).
|
||||
*
|
||||
* https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
|
||||
*/
|
||||
float csspx = ptem * 96.f / 72.f;
|
||||
Fixed fixed_size;
|
||||
fixed_size.set_float (csspx);
|
||||
|
||||
// TODO: Make indexing work and use only an entry with zero track
|
||||
const TrackTableEntry trackTableEntry = trackTable[0];
|
||||
|
||||
unsigned int size_index;
|
||||
for (size_index = 0; size_index < nSizes; ++size_index)
|
||||
if ((base+sizeTable)[size_index] >= fixed_size)
|
||||
break;
|
||||
|
||||
// We don't attempt to extrapolate to larger or smaller values
|
||||
if (size_index == nSizes)
|
||||
return trackTableEntry.get_value (base, nSizes - 1);
|
||||
if (size_index == 0 || (base+sizeTable)[size_index] == fixed_size)
|
||||
return trackTableEntry.get_value (base, size_index);
|
||||
|
||||
float s0 = (base+sizeTable)[size_index - 1].to_float ();
|
||||
float s1 = (base+sizeTable)[size_index].to_float ();
|
||||
float t = (csspx - s0) / (s1 - s0);
|
||||
return t * trackTableEntry.get_value (base, size_index) +
|
||||
(1.0 - t) * trackTableEntry.get_value (base, size_index - 1);
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 nTracks; /* Number of separate tracks included in this table. */
|
||||
HBUINT16 nSizes; /* Number of point sizes included in this table. */
|
||||
LOffsetTo<UnsizedArrayOf<Fixed> >
|
||||
sizeTable;
|
||||
TrackTableEntry trackTable[VAR];/* Array[nSizes] of size values. */
|
||||
UnsizedArrayOf<TrackTableEntry> trackTable;/* Array[nSizes] of size values. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, trackTable);
|
||||
@ -82,9 +120,43 @@ struct trak
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
/* TODO */
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
inline bool apply (hb_aat_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
const float ptem = c->font->ptem;
|
||||
if (ptem > 0.f)
|
||||
{
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction))
|
||||
{
|
||||
const TrackData trackData = this+horizOffset;
|
||||
float tracking = trackData.get_tracking (this, ptem);
|
||||
hb_position_t advance_to_add = c->font->em_scalef_x (tracking / 2);
|
||||
foreach_grapheme (buffer, start, end)
|
||||
{
|
||||
buffer->pos[start].x_advance += advance_to_add;
|
||||
buffer->pos[end].x_advance += advance_to_add;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const TrackData trackData = this+vertOffset;
|
||||
float tracking = trackData.get_tracking (this, ptem);
|
||||
hb_position_t advance_to_add = c->font->em_scalef_y (tracking / 2);
|
||||
foreach_grapheme (buffer, start, end)
|
||||
{
|
||||
buffer->pos[start].y_advance += advance_to_add;
|
||||
buffer->pos[end].y_advance += advance_to_add;
|
||||
}
|
||||
}
|
||||
}
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion<> version; /* Version of the tracking table--currently
|
||||
* 0x00010000u for version 1.0. */
|
||||
|
@ -55,6 +55,40 @@ _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr)
|
||||
return morx;
|
||||
}
|
||||
|
||||
static inline const AAT::kerx&
|
||||
_get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr)
|
||||
{
|
||||
if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
|
||||
{
|
||||
if (blob)
|
||||
*blob = hb_blob_get_empty ();
|
||||
return OT::Null(AAT::kerx);
|
||||
}
|
||||
hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
|
||||
/* XXX this doesn't call set_num_glyphs on sanitizer. */
|
||||
const AAT::kerx& kerx = *(layout->kerx.get ());
|
||||
if (blob)
|
||||
*blob = layout->kerx.blob;
|
||||
return kerx;
|
||||
}
|
||||
|
||||
static inline const AAT::trak&
|
||||
_get_trak (hb_face_t *face, hb_blob_t **blob = nullptr)
|
||||
{
|
||||
if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
|
||||
{
|
||||
if (blob)
|
||||
*blob = hb_blob_get_empty ();
|
||||
return OT::Null(AAT::trak);
|
||||
}
|
||||
hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
|
||||
/* XXX this doesn't call set_num_glyphs on sanitizer. */
|
||||
const AAT::trak& trak = *(layout->trak.get ());
|
||||
if (blob)
|
||||
*blob = layout->trak.blob;
|
||||
return trak;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_aat_layout_create (hb_face_t *face)
|
||||
{
|
||||
@ -78,3 +112,15 @@ hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer)
|
||||
AAT::hb_aat_apply_context_t c (font, buffer, blob);
|
||||
morx.apply (&c);
|
||||
}
|
||||
|
||||
void
|
||||
hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer)
|
||||
{
|
||||
hb_blob_t *blob;
|
||||
const AAT::kerx& kerx = _get_kerx (font->face, &blob);
|
||||
const AAT::trak& trak = _get_trak (font->face, &blob);
|
||||
|
||||
AAT::hb_aat_apply_context_t c (font, buffer, blob);
|
||||
kerx.apply (&c);
|
||||
trak.apply (&c);
|
||||
}
|
||||
|
@ -692,8 +692,8 @@ struct F2DOT14 : HBINT16
|
||||
/* 32-bit signed fixed-point number (16.16). */
|
||||
struct Fixed: HBINT32
|
||||
{
|
||||
//inline float to_float (void) const { return ???; }
|
||||
//inline void set_float (float f) { v.set (f * ???); }
|
||||
inline float to_float (void) const { return ((int32_t) v) / 65536.0; }
|
||||
inline void set_float (float f) { v.set (round (f * 65536.0)); }
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
@ -363,6 +363,28 @@ _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
|
||||
return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0;
|
||||
}
|
||||
|
||||
|
||||
/* Loop over grapheme. Based on foreach_cluster(). */
|
||||
#define foreach_grapheme(buffer, start, end) \
|
||||
for (unsigned int \
|
||||
_count = buffer->len, \
|
||||
start = 0, end = _count ? _next_grapheme (buffer, 0) : 0; \
|
||||
start < _count; \
|
||||
start = end, end = _next_grapheme (buffer, start))
|
||||
|
||||
static inline unsigned int
|
||||
_next_grapheme (hb_buffer_t *buffer, unsigned int start)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
|
||||
while (++start < count && _hb_glyph_info_is_unicode_mark (&info[start]))
|
||||
;
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
#define info_cc(info) (_hb_glyph_info_get_modified_combining_class (&(info)))
|
||||
|
||||
static inline bool
|
||||
|
@ -65,6 +65,8 @@ _hb_ot_layout_create (hb_face_t *face)
|
||||
layout->fvar.init (face);
|
||||
layout->avar.init (face);
|
||||
layout->morx.init (face);
|
||||
layout->kerx.init (face);
|
||||
layout->trak.init (face);
|
||||
|
||||
{
|
||||
/*
|
||||
@ -215,6 +217,8 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
|
||||
layout->fvar.fini ();
|
||||
layout->avar.fini ();
|
||||
layout->morx.fini ();
|
||||
layout->kerx.fini ();
|
||||
layout->trak.fini ();
|
||||
|
||||
free (layout);
|
||||
}
|
||||
|
@ -787,6 +787,8 @@ hb_ot_position (hb_ot_shape_context_t *c)
|
||||
_hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
|
||||
|
||||
_hb_buffer_deallocate_gsubgpos_vars (c->buffer);
|
||||
|
||||
//hb_aat_layout_position (c->font, c->buffer);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
Loading…
Reference in New Issue
Block a user