30 #ifndef HB_OT_GLYF_TABLE_HH
31 #define HB_OT_GLYF_TABLE_HH
46 #define HB_OT_TAG_loca HB_TAG('l','o','c','a')
48 #ifndef HB_MAX_COMPOSITE_OPERATIONS
49 #define HB_MAX_COMPOSITE_OPERATIONS 100000
79 #define HB_OT_TAG_glyf HB_TAG('g','l','y','f')
93 template<
typename Iterator,
98 unsigned num_offsets = padded_offsets.len () + 1;
102 if (
unlikely (!loca_prime_data))
return false;
104 DEBUG_MSG (SUBSET,
nullptr,
"loca entry_size %d num_offsets %d size %d",
125 template<
typename IteratorIn,
typename IteratorOut,
138 return offset >> right_shift;
145 template <
typename Iterator>
152 unsigned init_len =
c->length ();
153 for (
const auto &
_ :
it)
_.serialize (
c, use_short_loca, plan);
159 if (init_len ==
c->length ())
163 c->copy (empty_byte);
175 glyf *glyf_prime =
c->serializer->start_embed <
glyf> ();
181 auto padded_offsets =
186 unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0);
187 bool use_short_loca = max_offset < 0x1FFFF;
190 glyf_prime->
serialize (
c->serializer, hb_iter (glyphs), use_short_loca,
c->plan);
191 if (!use_short_loca) {
205 template <
typename SubsetGlyph>
216 subset_glyph.
new_gid = new_gid;
277 unsigned int size = min_size;
355 p += HBINT16::static_size;
357 p += HBINT16::static_size;
366 trans.
init ((
float) tx, (float)
ty);
404 glyph (glyph_), current (
nullptr), current_size (0)
415 if (!current->
has_more ()) { current =
nullptr;
return; }
417 set_next (&StructAtOffset<CompositeGlyphChain> (current, current_size));
420 {
return glyph !=
o.glyph || current !=
o.current; }
425 if (!glyph.
check_range (composite, CompositeGlyphChain::min_size))
446 unsigned current_size;
458 struct accelerator_t;
477 bool has_data ()
const {
return numberOfContours; }
484 extents->
x_bearing =
font->em_scale_x (glyf_accelerator.hmtx->get_side_bearing (
gid));
486 extents->
width =
font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax));
487 extents->
height =
font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax));
507 const GlyphHeader &
header;
509 SimpleGlyph (
const GlyphHeader &header_,
hb_bytes_t bytes_) :
512 unsigned int instruction_len_offset ()
const
513 {
return GlyphHeader::static_size + 2 *
header.numberOfContours; }
515 unsigned int length (
unsigned int instruction_len)
const
516 {
return instruction_len_offset () + 2 + instruction_len; }
518 unsigned int instructions_length ()
const
520 unsigned int instruction_length_offset = instruction_len_offset ();
523 const HBUINT16 &instructionLength = StructAtOffset<HBUINT16> (&
bytes, instruction_length_offset);
526 return instructionLength;
535 glyph += instruction_len_offset ();
538 unsigned int num_coordinates = StructAtOffset<HBUINT16> (glyph - 2, 0) + 1;
539 unsigned int num_instructions = StructAtOffset<HBUINT16> (glyph, 0);
541 glyph += 2 + num_instructions;
543 unsigned int coord_bytes = 0;
544 unsigned int coords_with_flags = 0;
545 while (glyph < glyph_end)
547 uint8_t flag = *glyph;
558 unsigned int xBytes, yBytes;
566 coord_bytes += (xBytes + yBytes) *
repeat;
567 coords_with_flags +=
repeat;
568 if (coords_with_flags >= num_coordinates)
break;
571 if (
unlikely (coords_with_flags != num_coordinates))
return Glyph ();
578 GlyphHeader &glyph_header =
const_cast<GlyphHeader &
> (
header);
579 (
HBUINT16 &) StructAtOffset<HBUINT16> (&glyph_header, instruction_len_offset ()) = 0;
584 unsigned int instructions_len = instructions_length ();
585 unsigned int glyph_length =
length (instructions_len);
586 dest_start =
bytes.
sub_array (0, glyph_length - instructions_len);
594 unsigned flags_offset =
length (instructions_length ());
601 static bool read_points (
const HBUINT8 *&
p ,
602 contour_point_vector_t &points_ ,
604 void (* setter) (contour_point_t &
_,
float v),
609 for (
unsigned i = 0;
i < points_.length;
i++)
611 uint8_t flag = points_[
i].flag;
612 if (flag & short_flag)
615 if (flag & same_flag)
622 if (!(flag & same_flag))
626 p += HBINT16::static_size;
629 setter (points_[
i],
v);
634 bool get_contour_points (contour_point_vector_t &points_ ,
635 bool phantom_only =
false)
const
637 const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (
header);
638 int num_contours =
header.numberOfContours;
640 unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
642 points_.resize (num_points);
643 for (
unsigned int i = 0;
i < points_.length;
i++) points_[
i].
init ();
644 if (phantom_only)
return true;
646 for (
int i = 0;
i < num_contours;
i++)
647 points_[endPtsOfContours[
i]].is_end_point =
true;
650 const HBUINT8 *
p = &StructAtOffset<HBUINT8> (&endPtsOfContours[num_contours + 1],
651 endPtsOfContours[num_contours]);
654 for (
unsigned int i = 0;
i < num_points;
i++)
658 points_[
i].flag = flag;
662 unsigned int repeat_count = *
p++;
663 while ((repeat_count-- > 0) && (++
i < num_points))
664 points_[
i].flag = flag;
669 return read_points (
p, points_,
bytes, [] (contour_point_t &
p,
float v) {
p.x =
v; },
671 && read_points (
p, points_,
bytes, [] (contour_point_t &
p,
float v) {
p.y =
v; },
676 struct CompositeGlyph
678 const GlyphHeader &
header;
680 CompositeGlyph (
const GlyphHeader &header_,
hb_bytes_t bytes_) :
683 composite_iter_t get_iterator ()
const
684 {
return composite_iter_t (
bytes, &StructAfter<CompositeGlyphChain, GlyphHeader> (
header)); }
690 const CompositeGlyphChain *last =
nullptr;
691 for (
auto &
item : get_iterator ())
695 if (last->has_instructions ())
707 for (
const auto &
_ : get_iterator ())
708 const_cast<CompositeGlyphChain &
> (
_).drop_instructions_flag ();
717 const_cast<CompositeGlyphChain &
> (StructAfter<CompositeGlyphChain, GlyphHeader> (
header))
722 enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE };
728 return CompositeGlyph (*
header,
bytes).get_iterator ();
734 case COMPOSITE:
return CompositeGlyph (*
header,
bytes).trim_padding ();
735 case SIMPLE:
return SimpleGlyph (*
header,
bytes).trim_padding ();
736 default:
return bytes;
743 case COMPOSITE: CompositeGlyph (*
header,
bytes).drop_hints ();
return;
744 case SIMPLE: SimpleGlyph (*
header,
bytes).drop_hints ();
return;
752 case COMPOSITE: CompositeGlyph (*
header,
bytes).set_overlaps_flag ();
return;
753 case SIMPLE: SimpleGlyph (*
header,
bytes).set_overlaps_flag ();
return;
761 case COMPOSITE: CompositeGlyph (*
header,
bytes).drop_hints_bytes (dest_start);
return;
762 case SIMPLE: SimpleGlyph (*
header,
bytes).drop_hints_bytes (dest_start, dest_end);
return;
772 bool phantom_only =
false,
773 unsigned int depth = 0)
const
782 unsigned num_points = hb_len (CompositeGlyph (*
header,
bytes).get_iterator ());
784 for (
unsigned i = 0;
i <
points.length;
i++)
799 int h_delta = (int)
header->xMin -
800 glyf_accelerator.
hmtx->get_side_bearing (
gid);
801 int v_orig = (int)
header->yMax +
802 #ifndef HB_NO_VERTICAL
803 glyf_accelerator.
vmtx->get_side_bearing (
gid)
808 unsigned h_adv = glyf_accelerator.
hmtx->get_advance (
gid);
810 #ifndef HB_NO_VERTICAL
811 glyf_accelerator.
vmtx->get_advance (
gid)
813 -
font->face->get_upem ()
832 unsigned int comp_index = 0;
838 phantom_only,
depth + 1)
843 if (
item.is_use_my_metrics ())
848 item.transform_points (comp_points);
853 if (
item.is_anchored ())
860 delta.
init (all_points[
p1].
x - comp_points[
p2].
x,
861 all_points[
p1].
y - comp_points[
p2].
y);
872 all_points.
extend (phantoms);
875 all_points.
extend (phantoms);
894 if (
type == EMPTY)
return true;
895 return header->get_extents (
font, glyf_accelerator,
gid, extents);
904 int num_contours =
header->numberOfContours;
906 else if (num_contours > 0)
type = SIMPLE;
907 else type = COMPOSITE;
921 short_offset =
false;
923 loca_table =
nullptr;
924 glyf_table =
nullptr;
929 #ifndef HB_NO_VERTICAL
938 loca_table =
face->table.loca.get_blob ();
944 #ifndef HB_NO_VERTICAL
948 num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
949 num_glyphs = hb_min (num_glyphs,
face->get_num_glyphs ());
953 glyf_table.destroy ();
960 if (gid >= num_glyphs)
return false;
968 bool phantom_only = !
consumer.is_consuming_contour_points ();
972 if (
consumer.is_consuming_contour_points ())
974 for (
unsigned point_index = 0; point_index + 4 < all_points.
length; ++point_index)
975 consumer.consume_point (all_points[point_index]);
1048 if (
unlikely (gid >= num_glyphs))
return 0;
1050 bool success =
false;
1058 #ifndef HB_NO_VERTICAL
1059 is_vertical ?
vmtx->get_advance (gid) :
1061 hmtx->get_advance (gid);
1063 float result = is_vertical
1066 return hb_clamp (
roundf (
result), 0.f, (
float) UINT_MAX / 2);
1071 if (
unlikely (gid >= num_glyphs))
return 0;
1078 #ifndef HB_NO_VERTICAL
1079 is_vertical ?
vmtx->get_side_bearing (gid) :
1081 hmtx->get_side_bearing (gid);
1092 if (
unlikely (gid >= num_glyphs))
return false;
1095 if (
font->num_coords &&
font->num_coords ==
gvar->get_axis_count ())
1112 end_offset = 2 *
offsets[gid + 1];
1118 end_offset =
offsets[gid + 1];
1126 return needs_padding_removal ? glyph.
trim_padding () : glyph;
1133 unsigned operation_count = 0)
const
1138 if (gids_to_retain->
has (gid))
return operation_count;
1140 gids_to_retain->
add (gid);
1150 return operation_count;
1278 #ifndef HB_NO_VERTICAL
1284 unsigned int num_glyphs;
1298 bool use_short_loca,
1305 unsigned int pad_length = use_short_loca ?
padding () : 0;
1306 DEBUG_MSG (SUBSET,
nullptr,
"serialize %d byte glyph, width %d pad %d", dest_glyph.
length, dest_glyph.
length + pad_length, pad_length);
1310 while (pad_length > 0)
1319 for (
auto &
_ :
Glyph (dest_glyph).get_composite_iterator ())
small capitals from c petite p scientific i
[1]
hb_array_t< T > hb_array(T *array, unsigned int length)
hb_array_t< const char > hb_bytes_t
hb_blob_t * hb_blob_copy_writable_or_fail(hb_blob_t *blob)
hb_blob_t * hb_blob_create(const char *data, unsigned int length, hb_memory_mode_t mode, void *user_data, hb_destroy_func_t destroy)
void hb_blob_destroy(hb_blob_t *blob)
char * hb_blob_get_data_writable(hb_blob_t *blob, unsigned int *length)
#define TRACE_SERIALIZE(this)
#define TRACE_SANITIZE(this)
#define DEBUG_MSG(WHAT, OBJ,...)
#define return_trace(RET)
#define TRACE_SUBSET(this)
void const void *obj HB_UNUSED
auto it hb_map(hb_second)) template< typename Type > inline hb_array_t< Type > operator()(hb_array_t< Type > array
static auto hb_requires(hb_is_iterable(Iterable))> static inline auto end(Iterable &&iterable) HB_AUTO_RETURN(hb_iter(iterable).end()) namespace OT
#define DEFINE_SIZE_STATIC(size)
HB_EXTERN unsigned int start_offset
#define HB_MAX_COMPOSITE_OPERATIONS
#define HB_MAX_NESTING_LEVEL
@ HB_SUBSET_FLAGS_NO_HINTING
@ HB_SUBSET_FLAGS_NOTDEF_OUTLINE
@ HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG
GeneratorWrapper< T > repeat(size_t repeats, GeneratorWrapper< T > &&generator)
HeaderSize entry_size(const QByteArray &name, const QByteArray &value)
IntType< uint8_t > HBUINT8
IntType< uint16_t > HBUINT16
IntType< int16_t > HBINT16
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
[3]
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld init[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld SRC pixld MASK if DST_R else pixld DST_R endif if src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head if pixblock_size cache_preload_simple endif process_pixblock_tail pixinterleave dst_w_basereg irp if pixblock_size chunk_size tst beq if DST_W else pixst DST_W else mov ORIG_W endif add lsl if lsl endif if lsl endif lsl endif lsl endif lsl endif subs mov DST_W if regs_shortage str endif bge start_of_loop_label endm macro generate_composite_function
GLenum GLuint GLenum GLsizei length
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLintptr offset
GLfixed GLfixed GLint GLint GLfixed points
GLuint GLsizei const GLuint const GLintptr * offsets
@ HB_MEMORY_MODE_WRITABLE
void translate(const contour_point_t &p)
void init(float x_=0.f, float y_=0.f, bool is_end_point_=false)
void extend(const hb_array_t< contour_point_t > &a)
void translate(const contour_point_t &delta)
void get_anchor_points(unsigned int &point1, unsigned int &point2) const
void transform_points(contour_point_vector_t &points) const
void set_glyph_index(hb_codepoint_t new_gid)
bool scaled_offsets() const
void drop_instructions_flag()
hb_codepoint_t get_glyph_index() const
unsigned int get_size() const
bool has_instructions() const
bool is_use_my_metrics() const
bool get_transformation(float(&matrix)[4], contour_point_t &trans) const
@ SCALED_COMPONENT_OFFSET
@ UNSCALED_COMPONENT_OFFSET
@ WE_HAVE_AN_X_AND_Y_SCALE
bool get_points(hb_font_t *font, const accelerator_t &glyf_accelerator, contour_point_vector_t &all_points, bool phantom_only=false, unsigned int depth=0) const
hb_bytes_t get_bytes() const
bool get_extents(hb_font_t *font, const accelerator_t &glyf_accelerator, hb_glyph_extents_t *extents) const
Glyph(hb_bytes_t bytes_=hb_bytes_t(), hb_codepoint_t gid_=(hb_codepoint_t) -1)
composite_iter_t get_composite_iterator() const
const GlyphHeader * header
const Glyph trim_padding() const
void drop_hints_bytes(hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
unsigned int padding() const
unsigned int length() const
unsigned int padded_size() const
bool serialize(hb_serialize_context_t *c, bool use_short_loca, const hb_subset_plan_t *plan) const
optional_point_t(float x_, float y_)
optional_point_t lerp(optional_point_t p, float t)
bool is_consuming_contour_points()
void consume_point(const contour_point_t &point)
struct OT::glyf::accelerator_t::path_builder_t::optional_point_t first_offcurve
struct OT::glyf::accelerator_t::path_builder_t::optional_point_t last_offcurve
contour_point_t * get_phantoms_sink()
struct OT::glyf::accelerator_t::path_builder_t::optional_point_t first_oncurve
path_builder_t(hb_font_t *font_, hb_draw_session_t &draw_session_)
hb_draw_session_t * draw_session
void get_extents(hb_font_t *font, hb_glyph_extents_t *extents)
void add(const contour_point_t &p)
contour_point_t * get_phantoms_sink()
void consume_point(const contour_point_t &point)
struct OT::glyf::accelerator_t::points_aggregator_t::contour_bounds_t bounds
points_aggregator_t(hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_)
contour_point_t * phantoms
bool is_consuming_contour_points()
hb_glyph_extents_t * extents
const hmtx_accelerator_t * hmtx
unsigned add_gid_and_children(hb_codepoint_t gid, hb_set_t *gids_to_retain, unsigned depth=0, unsigned operation_count=0) const
bool get_points(hb_font_t *font, hb_codepoint_t gid, T consumer) const
const gvar_accelerator_t * gvar
accelerator_t(hb_face_t *face)
const Glyph glyph_for_gid(hb_codepoint_t gid, bool needs_padding_removal=false) const
bool get_path(hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const
bool get_extents(hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
int get_side_bearing_var(hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
const vmtx_accelerator_t * vmtx
unsigned get_advance_var(hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
const CompositeGlyphChain * __item_t__
composite_iter_t(hb_bytes_t glyph_, __item_t__ current_)
const CompositeGlyphChain & __item__() const
void set_next(const CompositeGlyphChain *composite)
bool operator!=(const composite_iter_t &o) const
glyf_accelerator_t(hb_face_t *face)
bool subset(hb_subset_context_t *c) const
static bool _add_loca_and_head(hb_subset_plan_t *plan, Iterator padded_offsets, bool use_short_loca)
static void _write_loca(IteratorIn it, unsigned right_shift, IteratorOut dest)
UnsizedArrayOf< HBUINT8 > dataZ
static constexpr hb_tag_t tableTag
bool serialize(hb_serialize_context_t *c, Iterator it, bool use_short_loca, const hb_subset_plan_t *plan)
bool sanitize(hb_sanitize_context_t *c HB_UNUSED) const
static bool _add_head_and_set_loca_version(hb_subset_plan_t *plan, bool use_short_loca)
void _populate_subset_glyphs(const hb_subset_plan_t *plan, hb_vector_t< SubsetGlyph > *glyphs) const
bool apply_deltas_to_points(hb_codepoint_t glyph, hb_font_t *font, const hb_array_t< contour_point_t > points) const
HBUINT16 indexToLocFormat
UnsizedArrayOf< HBUINT8 > dataZ
bool sanitize(hb_sanitize_context_t *c HB_UNUSED) const
static constexpr hb_tag_t tableTag
bool check_range(const T *p, unsigned int size=T::static_size) const
hb_array_t copy(hb_serialize_context_t *c) const
hb_array_t sub_array(unsigned int start_offset=0, unsigned int *seg_count=nullptr) const
unsigned int get_size() const
void line_to(float to_x, float to_y)
void move_to(float to_x, float to_y)
void quadratic_to(float control_x, float control_y, float to_x, float to_y)
hb_position_t em_scalef_y(float v)
hb_position_t em_scalef_x(float v)
float em_fscalef_y(float v)
float em_fscalef_x(float v)
bool has(hb_codepoint_t k) const
void add(hb_codepoint_t g)
bool old_gid_for_new_gid(hb_codepoint_t new_gid, hb_codepoint_t *old_gid) const
bool new_gid_for_old_gid(hb_codepoint_t old_gid, hb_codepoint_t *new_gid) const
unsigned int num_output_glyphs() const
bool add_table(hb_tag_t tag, hb_blob_t *contents)
c_array_t sub_array(unsigned int start_offset, unsigned int count) const