|
|
|
@ -80,13 +80,20 @@ struct Glyph |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void update_mtx (const hb_subset_plan_t *plan, |
|
|
|
|
int xMin, int yMax, |
|
|
|
|
int xMin, int xMax, |
|
|
|
|
int yMin, int yMax, |
|
|
|
|
const contour_point_vector_t &all_points) const |
|
|
|
|
{ |
|
|
|
|
hb_codepoint_t new_gid = 0; |
|
|
|
|
if (!plan->new_gid_for_old_gid (gid, &new_gid)) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (type != EMPTY) |
|
|
|
|
{ |
|
|
|
|
plan->bounds_width_map.set (new_gid, xMax - xMin); |
|
|
|
|
plan->bounds_height_map.set (new_gid, yMax - yMin); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unsigned len = all_points.length; |
|
|
|
|
float leftSideX = all_points[len - 4].x; |
|
|
|
|
float rightSideX = all_points[len - 3].x; |
|
|
|
@ -109,7 +116,7 @@ struct Glyph |
|
|
|
|
hb_bytes_t &dest_bytes /* OUT */) const |
|
|
|
|
{ |
|
|
|
|
GlyphHeader *glyph_header = nullptr; |
|
|
|
|
if (type != EMPTY && all_points.length > 4) |
|
|
|
|
if (!plan->pinned_at_default && type != EMPTY && all_points.length > 4) |
|
|
|
|
{ |
|
|
|
|
glyph_header = (GlyphHeader *) hb_calloc (1, GlyphHeader::static_size); |
|
|
|
|
if (unlikely (!glyph_header)) return false; |
|
|
|
@ -133,18 +140,33 @@ struct Glyph |
|
|
|
|
yMax = hb_max (yMax, y); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
update_mtx (plan, roundf (xMin), roundf (yMax), all_points); |
|
|
|
|
update_mtx (plan, roundf (xMin), roundf (xMax), roundf (yMin), roundf (yMax), all_points); |
|
|
|
|
|
|
|
|
|
int rounded_xMin = roundf (xMin); |
|
|
|
|
int rounded_xMax = roundf (xMax); |
|
|
|
|
int rounded_yMin = roundf (yMin); |
|
|
|
|
int rounded_yMax = roundf (yMax); |
|
|
|
|
|
|
|
|
|
if (type != EMPTY) |
|
|
|
|
{ |
|
|
|
|
plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, rounded_xMin); |
|
|
|
|
plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, rounded_yMin); |
|
|
|
|
plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, rounded_xMax); |
|
|
|
|
plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, rounded_yMax); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*for empty glyphs: all_points only include phantom points.
|
|
|
|
|
*just update metrics and then return */ |
|
|
|
|
/* when pinned at default, no need to compile glyph header
|
|
|
|
|
* and for empty glyphs: all_points only include phantom points. |
|
|
|
|
* just update metrics and then return */ |
|
|
|
|
if (!glyph_header) |
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
glyph_header->numberOfContours = header->numberOfContours; |
|
|
|
|
glyph_header->xMin = roundf (xMin); |
|
|
|
|
glyph_header->yMin = roundf (yMin); |
|
|
|
|
glyph_header->xMax = roundf (xMax); |
|
|
|
|
glyph_header->yMax = roundf (yMax); |
|
|
|
|
|
|
|
|
|
glyph_header->xMin = rounded_xMin; |
|
|
|
|
glyph_header->yMin = rounded_yMin; |
|
|
|
|
glyph_header->xMax = rounded_xMax; |
|
|
|
|
glyph_header->yMax = rounded_yMax; |
|
|
|
|
|
|
|
|
|
dest_bytes = hb_bytes_t ((const char *)glyph_header, GlyphHeader::static_size); |
|
|
|
|
return true; |
|
|
|
@ -157,34 +179,42 @@ struct Glyph |
|
|
|
|
hb_bytes_t &dest_end /* OUT */) |
|
|
|
|
{ |
|
|
|
|
contour_point_vector_t all_points, deltas; |
|
|
|
|
if (!get_points (font, glyf, all_points, &deltas, false, false)) |
|
|
|
|
unsigned composite_contours = 0; |
|
|
|
|
if (!get_points (font, glyf, all_points, &deltas, &plan->head_maxp_info, &composite_contours, false, false)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
// .notdef, set type to empty so we only update metrics and don't compile bytes for
|
|
|
|
|
// it
|
|
|
|
|
if (gid == 0 && |
|
|
|
|
!(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) |
|
|
|
|
{ |
|
|
|
|
type = EMPTY; |
|
|
|
|
|
|
|
|
|
switch (type) { |
|
|
|
|
case COMPOSITE: |
|
|
|
|
if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start, |
|
|
|
|
deltas, |
|
|
|
|
dest_end)) |
|
|
|
|
return false; |
|
|
|
|
break; |
|
|
|
|
case SIMPLE: |
|
|
|
|
if (!SimpleGlyph (*header, bytes).compile_bytes_with_deltas (all_points, |
|
|
|
|
plan->flags & HB_SUBSET_FLAGS_NO_HINTING, |
|
|
|
|
dest_end)) |
|
|
|
|
return false; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
/* set empty bytes for empty glyph
|
|
|
|
|
* do not use source glyph's pointers */ |
|
|
|
|
dest_start = hb_bytes_t (); |
|
|
|
|
dest_end = hb_bytes_t (); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//dont compile bytes when pinned at default, just recalculate bounds
|
|
|
|
|
if (!plan->pinned_at_default) { |
|
|
|
|
switch (type) { |
|
|
|
|
case COMPOSITE: |
|
|
|
|
if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start, |
|
|
|
|
deltas, |
|
|
|
|
dest_end)) |
|
|
|
|
return false; |
|
|
|
|
break; |
|
|
|
|
case SIMPLE: |
|
|
|
|
if (!SimpleGlyph (*header, bytes).compile_bytes_with_deltas (all_points, |
|
|
|
|
plan->flags & HB_SUBSET_FLAGS_NO_HINTING, |
|
|
|
|
dest_end)) |
|
|
|
|
return false; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
/* set empty bytes for empty glyph
|
|
|
|
|
* do not use source glyph's pointers */ |
|
|
|
|
dest_start = hb_bytes_t (); |
|
|
|
|
dest_end = hb_bytes_t (); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!compile_header_bytes (plan, all_points, dest_start)) |
|
|
|
@ -203,6 +233,8 @@ struct Glyph |
|
|
|
|
bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator, |
|
|
|
|
contour_point_vector_t &all_points /* OUT */, |
|
|
|
|
contour_point_vector_t *deltas = nullptr, /* OUT */ |
|
|
|
|
head_maxp_info_t * head_maxp_info = nullptr, /* OUT */ |
|
|
|
|
unsigned *composite_contours = nullptr, /* OUT */ |
|
|
|
|
bool shift_points_hori = true, |
|
|
|
|
bool use_my_metrics = true, |
|
|
|
|
bool phantom_only = false, |
|
|
|
@ -215,6 +247,11 @@ struct Glyph |
|
|
|
|
if (!edge_count) edge_count = &stack_edge_count; |
|
|
|
|
if (unlikely (*edge_count > HB_GLYF_MAX_EDGE_COUNT)) return false; |
|
|
|
|
(*edge_count)++; |
|
|
|
|
|
|
|
|
|
if (head_maxp_info) |
|
|
|
|
{ |
|
|
|
|
head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!coords) |
|
|
|
|
coords = hb_array (font->coords, font->num_coords); |
|
|
|
@ -226,6 +263,10 @@ struct Glyph |
|
|
|
|
|
|
|
|
|
switch (type) { |
|
|
|
|
case SIMPLE: |
|
|
|
|
if (depth == 0 && head_maxp_info) |
|
|
|
|
head_maxp_info->maxContours = hb_max (head_maxp_info->maxContours, (unsigned) header->numberOfContours); |
|
|
|
|
if (depth > 0 && composite_contours) |
|
|
|
|
*composite_contours += (unsigned) header->numberOfContours; |
|
|
|
|
if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only))) |
|
|
|
|
return false; |
|
|
|
|
break; |
|
|
|
@ -301,6 +342,8 @@ struct Glyph |
|
|
|
|
|
|
|
|
|
switch (type) { |
|
|
|
|
case SIMPLE: |
|
|
|
|
if (depth == 0 && head_maxp_info) |
|
|
|
|
head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, points.length - 4); |
|
|
|
|
if (!inplace) |
|
|
|
|
all_points.extend (points.as_array ()); |
|
|
|
|
break; |
|
|
|
@ -311,12 +354,13 @@ struct Glyph |
|
|
|
|
for (auto &item : get_composite_iterator ()) |
|
|
|
|
{ |
|
|
|
|
comp_points.reset (); |
|
|
|
|
|
|
|
|
|
if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ()) |
|
|
|
|
.get_points (font, |
|
|
|
|
glyf_accelerator, |
|
|
|
|
comp_points, |
|
|
|
|
deltas, |
|
|
|
|
head_maxp_info, |
|
|
|
|
composite_contours, |
|
|
|
|
shift_points_hori, |
|
|
|
|
use_my_metrics, |
|
|
|
|
phantom_only, |
|
|
|
@ -358,6 +402,13 @@ struct Glyph |
|
|
|
|
comp_index++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (head_maxp_info && depth == 0) |
|
|
|
|
{ |
|
|
|
|
if (composite_contours) |
|
|
|
|
head_maxp_info->maxCompositeContours = hb_max (head_maxp_info->maxCompositeContours, *composite_contours); |
|
|
|
|
head_maxp_info->maxCompositePoints = hb_max (head_maxp_info->maxCompositePoints, all_points.length); |
|
|
|
|
head_maxp_info->maxComponentElements = hb_max (head_maxp_info->maxComponentElements, comp_index); |
|
|
|
|
} |
|
|
|
|
all_points.extend (phantoms); |
|
|
|
|
} break; |
|
|
|
|
#ifndef HB_NO_VAR_COMPOSITES |
|
|
|
@ -383,6 +434,8 @@ struct Glyph |
|
|
|
|
glyf_accelerator, |
|
|
|
|
comp_points, |
|
|
|
|
deltas, |
|
|
|
|
head_maxp_info, |
|
|
|
|
nullptr, |
|
|
|
|
shift_points_hori, |
|
|
|
|
use_my_metrics, |
|
|
|
|
phantom_only, |
|
|
|
|