[subset] Support sbix subsetting
This commit is contained in:
parent
8ffc9add22
commit
43b6c865ae
|
@ -26,6 +26,7 @@
|
||||||
#define HB_OT_COLOR_SBIX_TABLE_HH
|
#define HB_OT_COLOR_SBIX_TABLE_HH
|
||||||
|
|
||||||
#include "hb-open-type.hh"
|
#include "hb-open-type.hh"
|
||||||
|
#include "hb-ot-layout-common.hh"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sbix -- Standard Bitmap Graphics
|
* sbix -- Standard Bitmap Graphics
|
||||||
|
@ -40,6 +41,32 @@ namespace OT {
|
||||||
|
|
||||||
struct SBIXGlyph
|
struct SBIXGlyph
|
||||||
{
|
{
|
||||||
|
static unsigned int get_size (unsigned int data_length)
|
||||||
|
{ return min_size + data_length * HBUINT8::static_size; }
|
||||||
|
|
||||||
|
bool serialize (hb_serialize_context_t *c, unsigned x_offset, unsigned y_offset, Tag graphic_type, const UnsizedArrayOf<HBUINT8>* src_data, unsigned int data_length)
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
|
|
||||||
|
if (unlikely (!c->extend (*this, data_length))) return_trace (false);
|
||||||
|
|
||||||
|
xOffset = x_offset;
|
||||||
|
yOffset = y_offset;
|
||||||
|
graphicType = graphic_type;
|
||||||
|
memcpy(&data, src_data, data_length);
|
||||||
|
return_trace (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c, unsigned int data_length) const {
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
|
||||||
|
SBIXGlyph* new_glyph = c->serializer->start_embed<SBIXGlyph> ();
|
||||||
|
if (unlikely (!new_glyph)) return_trace (false);
|
||||||
|
|
||||||
|
new_glyph->serialize (c->serializer, xOffset, yOffset, graphicType, &data, data_length);
|
||||||
|
return_trace (true);
|
||||||
|
}
|
||||||
|
|
||||||
HBINT16 xOffset; /* The horizontal (x-axis) offset from the left
|
HBINT16 xOffset; /* The horizontal (x-axis) offset from the left
|
||||||
* edge of the graphic to the glyph’s origin.
|
* edge of the graphic to the glyph’s origin.
|
||||||
* That is, the x-coordinate of the point on the
|
* That is, the x-coordinate of the point on the
|
||||||
|
@ -62,6 +89,9 @@ struct SBIXGlyph
|
||||||
|
|
||||||
struct SBIXStrike
|
struct SBIXStrike
|
||||||
{
|
{
|
||||||
|
static unsigned int get_size (unsigned num_glyphs)
|
||||||
|
{ return min_size + num_glyphs * HBUINT32::static_size; }
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -116,6 +146,38 @@ struct SBIXStrike
|
||||||
return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length);
|
return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t* c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
unsigned int num_output_glyphs = c->plan->num_output_glyphs ();
|
||||||
|
|
||||||
|
auto* out = c->serializer->start_embed<SBIXStrike> ();
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
if (unlikely (!c->serializer->extend (*out, num_output_glyphs + 1))) return_trace (false);
|
||||||
|
out->ppem = ppem;
|
||||||
|
out->resolution = resolution;
|
||||||
|
HBUINT32 head;
|
||||||
|
head = get_size(num_output_glyphs + 1);
|
||||||
|
for (unsigned new_gid = 0; new_gid < num_output_glyphs; new_gid++)
|
||||||
|
{
|
||||||
|
hb_codepoint_t old_gid;
|
||||||
|
if (!c->plan->old_gid_for_new_gid (new_gid, &old_gid) ||
|
||||||
|
unlikely (imageOffsetsZ[old_gid + 1] <= imageOffsetsZ[old_gid] ||
|
||||||
|
imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid] <= SBIXGlyph::min_size)) {
|
||||||
|
out->imageOffsetsZ[new_gid] = head;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
unsigned int delta = imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid];
|
||||||
|
unsigned int glyph_data_length = delta - SBIXGlyph::min_size;
|
||||||
|
if (!(this + imageOffsetsZ[old_gid]).subset(c, glyph_data_length))
|
||||||
|
return_trace (false);
|
||||||
|
out->imageOffsetsZ[new_gid] = head;
|
||||||
|
head += delta;
|
||||||
|
}
|
||||||
|
out->imageOffsetsZ[num_output_glyphs] = head;
|
||||||
|
return_trace (true);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HBUINT16 ppem; /* The PPEM size for which this strike was designed. */
|
HBUINT16 ppem; /* The PPEM size for which this strike was designed. */
|
||||||
HBUINT16 resolution; /* The device pixel density (in PPI) for which this
|
HBUINT16 resolution; /* The device pixel density (in PPI) for which this
|
||||||
|
@ -275,6 +337,70 @@ struct sbix
|
||||||
strikes.sanitize (c, this)));
|
strikes.sanitize (c, this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool add_strike (hb_subset_context_t *c,
|
||||||
|
const void *dst_base,
|
||||||
|
LOffsetTo<SBIXStrike>* o,
|
||||||
|
unsigned int i) const {
|
||||||
|
*o = 0;
|
||||||
|
if (strikes[i].is_null ())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto *s = c->serializer;
|
||||||
|
|
||||||
|
s->push ();
|
||||||
|
|
||||||
|
return (this+strikes[i]).subset (c);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool serialize_strike_offsets (hb_subset_context_t *c,
|
||||||
|
const void *dst_base) const
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
|
|
||||||
|
auto *out = c->serializer->start_embed<LOffsetLArrayOf<SBIXStrike>> ();
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
if (unlikely (!c->serializer->allocate_size<HBUINT32> (HBUINT32::static_size))) return_trace (false);
|
||||||
|
|
||||||
|
hb_vector_t<LOffsetTo<SBIXStrike>*> new_strikes;
|
||||||
|
hb_vector_t<hb_serialize_context_t::objidx_t> objidxs;
|
||||||
|
for (int i = strikes.len - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
auto* o = out->serialize_append (c->serializer);
|
||||||
|
if (unlikely (!o)) return_trace (false);
|
||||||
|
auto snap = c->serializer->snapshot ();
|
||||||
|
bool ret = add_strike(c, dst_base, o, i);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
c->serializer->pop_discard ();
|
||||||
|
out->pop();
|
||||||
|
c->serializer->revert (snap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
objidxs.push (c->serializer->pop_pack ());
|
||||||
|
new_strikes.push (o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < new_strikes.length; ++i)
|
||||||
|
{
|
||||||
|
c->serializer->add_link (*new_strikes[i], objidxs[new_strikes.length - 1 - i], dst_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
return_trace (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t* c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
|
||||||
|
sbix *sbix_prime = c->serializer->start_embed<sbix> ();
|
||||||
|
if (unlikely (!sbix_prime)) return_trace (false);
|
||||||
|
if (unlikely (!c->serializer->embed (this->version))) return_trace (false);
|
||||||
|
if (unlikely (!c->serializer->embed (this->flags))) return_trace (false);
|
||||||
|
|
||||||
|
return_trace (serialize_strike_offsets (c, sbix_prime));
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 version; /* Table version number — set to 1 */
|
HBUINT16 version; /* Table version number — set to 1 */
|
||||||
HBUINT16 flags; /* Bit 0: Set to 1. Bit 1: Draw outlines.
|
HBUINT16 flags; /* Bit 0: Set to 1. Bit 1: Draw outlines.
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "hb-ot-hhea-table.hh"
|
#include "hb-ot-hhea-table.hh"
|
||||||
#include "hb-ot-hmtx-table.hh"
|
#include "hb-ot-hmtx-table.hh"
|
||||||
#include "hb-ot-maxp-table.hh"
|
#include "hb-ot-maxp-table.hh"
|
||||||
|
#include "hb-ot-color-sbix-table.hh"
|
||||||
#include "hb-ot-os2-table.hh"
|
#include "hb-ot-os2-table.hh"
|
||||||
#include "hb-ot-post-table.hh"
|
#include "hb-ot-post-table.hh"
|
||||||
#include "hb-ot-cff1-table.hh"
|
#include "hb-ot-cff1-table.hh"
|
||||||
|
@ -187,6 +188,9 @@ _subset_table (hb_subset_plan_t *plan,
|
||||||
case HB_OT_TAG_maxp:
|
case HB_OT_TAG_maxp:
|
||||||
result = _subset2<const OT::maxp> (plan);
|
result = _subset2<const OT::maxp> (plan);
|
||||||
break;
|
break;
|
||||||
|
case HB_OT_TAG_sbix:
|
||||||
|
result = _subset2<const OT::sbix> (plan);
|
||||||
|
break;
|
||||||
case HB_OT_TAG_loca:
|
case HB_OT_TAG_loca:
|
||||||
DEBUG_MSG(SUBSET, nullptr, "skip loca handled by glyf");
|
DEBUG_MSG(SUBSET, nullptr, "skip loca handled by glyf");
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -18,6 +18,7 @@ EXTRA_DIST += \
|
||||||
expected/layout.gpos3 \
|
expected/layout.gpos3 \
|
||||||
expected/layout.gsub6 \
|
expected/layout.gsub6 \
|
||||||
expected/cmap14 \
|
expected/cmap14 \
|
||||||
|
expected/sbix \
|
||||||
fonts \
|
fonts \
|
||||||
profiles \
|
profiles \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -10,6 +10,7 @@ TESTS = \
|
||||||
tests/layout.gpos3.tests \
|
tests/layout.gpos3.tests \
|
||||||
tests/layout.gsub6.tests \
|
tests/layout.gsub6.tests \
|
||||||
tests/cmap14.tests \
|
tests/cmap14.tests \
|
||||||
|
tests/sbix.tests \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
XFAIL_TESTS = \
|
XFAIL_TESTS = \
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,13 @@
|
||||||
|
FONTS:
|
||||||
|
sbix.ttf
|
||||||
|
|
||||||
|
PROFILES:
|
||||||
|
default.txt
|
||||||
|
drop-hints.txt
|
||||||
|
drop-hints-retain-gids.txt
|
||||||
|
retain-gids.txt
|
||||||
|
name-ids.txt
|
||||||
|
|
||||||
|
SUBSETS:
|
||||||
|
X
|
||||||
|
Y
|
|
@ -24,6 +24,7 @@ def generate_expected_output(input_file, unicodes, profile_flags, output_path):
|
||||||
"--name-legacy",
|
"--name-legacy",
|
||||||
"--layout-features=*",
|
"--layout-features=*",
|
||||||
"--drop-tables+=DSIG,GPOS,GSUB,GDEF",
|
"--drop-tables+=DSIG,GPOS,GSUB,GDEF",
|
||||||
|
"--drop-tables-=sbix",
|
||||||
"--unicodes=%s" % unicodes,
|
"--unicodes=%s" % unicodes,
|
||||||
"--output-file=%s" % output_path])
|
"--output-file=%s" % output_path])
|
||||||
args.extend(profile_flags)
|
args.extend(profile_flags)
|
||||||
|
|
|
@ -67,7 +67,8 @@ def run_test (test, should_check_ots):
|
||||||
"--font-file=" + test.font_path,
|
"--font-file=" + test.font_path,
|
||||||
"--output-file=" + out_file,
|
"--output-file=" + out_file,
|
||||||
"--unicodes=%s" % test.unicodes (),
|
"--unicodes=%s" % test.unicodes (),
|
||||||
"--drop-tables+=DSIG,GPOS,GSUB,GDEF"]
|
"--drop-tables+=DSIG,GPOS,GSUB,GDEF",
|
||||||
|
"--drop-tables-=sbix"]
|
||||||
cli_args.extend (test.get_profile_flags ())
|
cli_args.extend (test.get_profile_flags ())
|
||||||
print (' '.join (cli_args))
|
print (' '.join (cli_args))
|
||||||
_, return_code = cmd (cli_args)
|
_, return_code = cmd (cli_args)
|
||||||
|
|
Loading…
Reference in New Issue