diff options
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh')
-rw-r--r-- | Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh new file mode 100644 index 00000000000..d60f7b0c28b --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Var/VARC/VARC.hh @@ -0,0 +1,193 @@ +#ifndef OT_VAR_VARC_VARC_HH +#define OT_VAR_VARC_VARC_HH + +#include "../../../hb-ot-layout-common.hh" +#include "../../../hb-ot-glyf-table.hh" +#include "../../../hb-ot-cff2-table.hh" +#include "../../../hb-ot-cff1-table.hh" + +#include "coord-setter.hh" + +namespace OT { + +//namespace Var { + +/* + * VARC -- Variable Composites + * https://github.com/harfbuzz/boring-expansion-spec/blob/main/VARC.md + */ + +#ifndef HB_NO_VAR_COMPOSITES + +struct VarComponent +{ + enum class flags_t : uint32_t + { + RESET_UNSPECIFIED_AXES = 1u << 0, + HAVE_AXES = 1u << 1, + AXIS_VALUES_HAVE_VARIATION = 1u << 2, + TRANSFORM_HAS_VARIATION = 1u << 3, + HAVE_TRANSLATE_X = 1u << 4, + HAVE_TRANSLATE_Y = 1u << 5, + HAVE_ROTATION = 1u << 6, + HAVE_CONDITION = 1u << 7, + HAVE_SCALE_X = 1u << 8, + HAVE_SCALE_Y = 1u << 9, + HAVE_TCENTER_X = 1u << 10, + HAVE_TCENTER_Y = 1u << 11, + GID_IS_24BIT = 1u << 12, + HAVE_SKEW_X = 1u << 13, + HAVE_SKEW_Y = 1u << 14, + RESERVED_MASK = ~((1u << 15) - 1), + }; + + HB_INTERNAL hb_ubytes_t + get_path_at (hb_font_t *font, + hb_codepoint_t parent_gid, + hb_draw_session_t &draw_session, + hb_array_t<const int> coords, + hb_ubytes_t record, + hb_set_t *visited, + signed *edges_left, + signed depth_left, + VarRegionList::cache_t *cache = nullptr) const; +}; + +struct VarCompositeGlyph +{ + static void + get_path_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_session_t &draw_session, + hb_array_t<const int> coords, + hb_ubytes_t record, + hb_set_t *visited, + signed *edges_left, + signed depth_left, + VarRegionList::cache_t *cache = nullptr) + { + while (record) + { + const VarComponent &comp = * (const VarComponent *) (record.arrayZ); + record = comp.get_path_at (font, glyph, + draw_session, coords, + record, + visited, edges_left, depth_left, cache); + } + } +}; + +HB_MARK_AS_FLAG_T (VarComponent::flags_t); + +struct VARC +{ + friend struct VarComponent; + + static constexpr hb_tag_t tableTag = HB_TAG ('V', 'A', 'R', 'C'); + + bool + get_path_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_session_t &draw_session, + hb_array_t<const int> coords, + hb_codepoint_t parent_glyph = HB_CODEPOINT_INVALID, + hb_set_t *visited = nullptr, + signed *edges_left = nullptr, + signed depth_left = HB_MAX_NESTING_LEVEL) const + { + hb_set_t stack_set; + if (visited == nullptr) + visited = &stack_set; + signed stack_edges = HB_MAX_GRAPH_EDGE_COUNT; + if (edges_left == nullptr) + edges_left = &stack_edges; + + // Don't recurse on the same glyph. + unsigned idx = glyph == parent_glyph ? + NOT_COVERED : + (this+coverage).get_coverage (glyph); + if (idx == NOT_COVERED) + { + if (!font->face->table.glyf->get_path_at (font, glyph, draw_session, coords)) +#ifndef HB_NO_CFF + if (!font->face->table.cff2->get_path_at (font, glyph, draw_session, coords)) + if (!font->face->table.cff1->get_path (font, glyph, draw_session)) // Doesn't have variations +#endif + return false; + return true; + } + + if (depth_left <= 0) + return true; + + if (*edges_left <= 0) + return true; + (*edges_left)--; + + if (visited->has (glyph) || visited->in_error ()) + return true; + visited->add (glyph); + + hb_ubytes_t record = (this+glyphRecords)[idx]; + + VarRegionList::cache_t *cache = record.length >= 64 ? // Heuristic + (this+varStore).create_cache () + : nullptr; + + VarCompositeGlyph::get_path_at (font, glyph, + draw_session, coords, + record, + visited, edges_left, depth_left, + cache); + + (this+varStore).destroy_cache (cache); + + visited->del (glyph); + + return true; + } + + bool + get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const + { return get_path_at (font, gid, draw_session, hb_array (font->coords, font->num_coords)); } + + bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const + { + funcs->push_clip_glyph (data, gid, font); + funcs->color (data, true, foreground); + funcs->pop_clip (data); + + return true; + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (version.sanitize (c) && + hb_barrier () && + version.major == 1 && + coverage.sanitize (c, this) && + varStore.sanitize (c, this) && + conditionList.sanitize (c, this) && + axisIndicesList.sanitize (c, this) && + glyphRecords.sanitize (c, this)); + } + + protected: + FixedVersion<> version; /* Version identifier */ + Offset32To<Coverage> coverage; + Offset32To<MultiItemVariationStore> varStore; + Offset32To<ConditionList> conditionList; + Offset32To<TupleList> axisIndicesList; + Offset32To<CFF2Index/*Of<VarCompositeGlyph>*/> glyphRecords; + public: + DEFINE_SIZE_STATIC (24); +}; + +#endif + +//} + +} + +#endif /* OT_VAR_VARC_VARC_HH */ |