[trak] Streamline a bit

Also use float math.
This commit is contained in:
Behdad Esfahbod 2025-02-09 02:43:09 +00:00
parent b1677e76aa
commit 1bf0a5bc17
2 changed files with 65 additions and 49 deletions

View file

@ -48,17 +48,69 @@ struct TrackTableEntry
float get_track_value () const { return track.to_float (); }
int get_value (const void *base, unsigned int index,
unsigned int table_size) const
{ return (base+valuesZ).as_array (table_size)[index]; }
float interpolate_at (unsigned int idx,
float ptem,
const void *base,
hb_array_t<const F16DOT16> size_table) const
{
const FWORD *values = (base+valuesZ).arrayZ;
float s0 = size_table[idx].to_float ();
float s1 = size_table[idx + 1].to_float ();
int v0 = values[idx];
int v1 = values[idx + 1];
// Deal with font bugs.
if (unlikely (s1 < s0))
{ hb_swap (s0, s1); hb_swap (v0, v1); }
if (unlikely (ptem < s0)) return v0;
if (unlikely (ptem > s1)) return v1;
if (unlikely (s0 == s1)) return (v0 + v1) * 0.5f;
float t = (ptem - s0) / (s1 - s0);
return v0 + t * (v1 - v0);
}
float get_value (float ptem,
const void *base,
hb_array_t<const F16DOT16> size_table) const
{
const FWORD *values = (base+valuesZ).arrayZ;
unsigned int n_sizes = size_table.length;
/*
* Choose size.
*/
if (!n_sizes) return 0.f;
if (n_sizes == 1) return values[0];
// At least two entries.
unsigned i;
for (i = 0; i < n_sizes; i++)
if (size_table[i].to_float () >= ptem)
break;
// Boundary conditions.
if (i == 0) return values[0];
if (i == n_sizes) return values[n_sizes - 1];
// Exact match.
if (size_table[i].to_float () == ptem) return values[i];
// Interpolate.
return interpolate_at (i - 1, ptem, base, size_table);
}
public:
bool sanitize (hb_sanitize_context_t *c, const void *base,
unsigned int table_size) const
bool sanitize (hb_sanitize_context_t *c,
const void *base,
unsigned int n_sizes) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) &&
(valuesZ.sanitize (c, base, table_size))));
(valuesZ.sanitize (c, base, n_sizes))));
}
protected:
@ -76,22 +128,7 @@ struct TrackTableEntry
struct TrackData
{
float interpolate_at (unsigned int idx,
float target_size,
const TrackTableEntry &trackTableEntry,
const void *base) const
{
unsigned int sizes = nSizes;
hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes);
float s0 = size_table[idx].to_float ();
float s1 = size_table[idx + 1].to_float ();
float t = unlikely (s0 == s1) ? 0.f : (target_size - s0) / (s1 - s0);
return t * trackTableEntry.get_value (base, idx + 1, sizes) +
(1.f - t) * trackTableEntry.get_value (base, idx, sizes);
}
int get_tracking (const void *base, float ptem) const
float get_tracking (const void *base, float ptem) const
{
/*
* Choose track.
@ -116,30 +153,9 @@ struct TrackData
}
if (!trackTableEntry) return 0;
/*
* Choose size.
*/
count = nSizes;
if (!count) return 0;
if (count == 1) return trackTableEntry->get_value (base, 0, count);
// At least two entries.
hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, count);
unsigned int size_index;
for (size_index = 0; size_index < count; size_index++)
if (size_table[size_index].to_float () >= ptem)
break;
if (size_index == 0)
return trackTableEntry->get_value (base, 0, count);
if (size_index == count)
return trackTableEntry->get_value (base, count - 1, count);
// Interpolate.
return roundf (interpolate_at (size_index - 1, ptem,
*trackTableEntry, base));
return trackTableEntry->get_value (ptem,
base,
(base+sizeTable).as_array (nSizes));
}
bool sanitize (hb_sanitize_context_t *c, const void *base) const
@ -187,7 +203,7 @@ struct trak
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
{
const TrackData &trackData = this+horizData;
int tracking = trackData.get_tracking (this, ptem);
float tracking = trackData.get_tracking (this, ptem);
hb_position_t offset_to_add = c->font->em_scalef_x (tracking / 2);
hb_position_t advance_to_add = c->font->em_scalef_x (tracking);
foreach_grapheme (buffer, start, end)
@ -200,7 +216,7 @@ struct trak
else
{
const TrackData &trackData = this+vertData;
int tracking = trackData.get_tracking (this, ptem);
float tracking = trackData.get_tracking (this, ptem);
hb_position_t offset_to_add = c->font->em_scalef_y (tracking / 2);
hb_position_t advance_to_add = c->font->em_scalef_y (tracking);
foreach_grapheme (buffer, start, end)

View file

@ -4,7 +4,7 @@
../fonts/TRAK.ttf;--font-ptem=2;U+0041,U+0042,U+0043;[A.alt=0@100,0+1200|B=1@100,0+1200|C.alt=2@100,0+1200]
../fonts/TRAK.ttf;--font-ptem=9;U+0041,U+0042,U+0043;[A.alt=0@30,0+1060|B=1@30,0+1060|C.alt=2@30,0+1060]
../fonts/TRAK.ttf;--font-ptem=24;U+0041,U+0042,U+0043;[A.alt=0@-7,0+986|B=1@-7,0+986|C.alt=2@-7,0+986]
../fonts/TRAK.ttf;--font-ptem=72;U+0041,U+0042,U+0043;[A.alt=0@-35,0+929|B=1@-35,0+929|C.alt=2@-35,0+929]
../fonts/TRAK.ttf;--font-ptem=72;U+0041,U+0042,U+0043;[A.alt=0@-36,0+929|B=1@-36,0+929|C.alt=2@-36,0+929]
../fonts/TRAK.ttf;--font-ptem=144;U+0041,U+0042,U+0043;[A.alt=0@-50,0+900|B=1@-50,0+900|C.alt=2@-50,0+900]
../fonts/TRAK.ttf;--font-ptem=144 --features=-trak;U+0041,U+0042,U+0043;[A.alt=0+1000|B=1+1000|C.alt=2+1000]
../fonts/TRAK.ttf;--font-ptem=144 --features=-trak[1:3];U+0041,U+0042,U+0043,U+0041,U+0042,U+0043;[A.alt=0@-50,0+900|B=1+1000|C.alt=2+1000|A.alt=3@-50,0+900|B=4@-50,0+900|C.alt=5@-50,0+900]