зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1757738 - Update HarfBuzz to 4.1.0. r=jfkthame
Differential Revision: https://phabricator.services.mozilla.com/D140064
This commit is contained in:
Родитель
cb0a86aae4
Коммит
d18a71361f
|
@ -1,3 +1,127 @@
|
|||
Overview of changes leading to 4.1.0
|
||||
Wednesday, March 23, 2022
|
||||
====================================
|
||||
- Various OSS-Fuzz fixes. (Behdad Esfahbod)
|
||||
- Make fallback vertical-origin match FreeType’s. (Behdad Esfahbod)
|
||||
- Treat visible viramas like dependent vowels in USE shaper. (David Corbett)
|
||||
- Apply presentation forms features and discretionary features in one go in
|
||||
Indic shaper, which seems to match Uniscribe and CoreText behaviour.
|
||||
(Behdad Esfahbod, David Corbett)
|
||||
- Various bug fixes.
|
||||
|
||||
- New API
|
||||
+hb_set_add_sorted_array()
|
||||
|
||||
Overview of changes leading to 4.0.1
|
||||
Friday, March 11, 2022
|
||||
====================================
|
||||
- Update OpenType to AAT mappings for “hist” and “vrtr” features.
|
||||
(Florian Pircher)
|
||||
- Update IANA Language Subtag Registry to 2022-03-02. (David Corbett)
|
||||
- Update USE shaper to allow any non-numeric tail in a symbol cluster, and
|
||||
remove obsolete data overrides. (David Corbett)
|
||||
- Fix handling of baseline variations to return correctly scaled values.
|
||||
(Matthias Clasen)
|
||||
- A new experimental hb_subset_repack_or_fail() to repack an array of objects,
|
||||
eliminating offset overflows. The API is not available unless HarfBuzz is
|
||||
built with experimental APIs enabled. (Qunxin Liu)
|
||||
|
||||
- New experimental API
|
||||
+hb_link_t
|
||||
+hb_object_t
|
||||
+hb_subset_repack_or_fail()
|
||||
|
||||
|
||||
Overview of changes leading to 4.0.0
|
||||
Tuesday, March 1, 2022
|
||||
====================================
|
||||
- New public API to create subset plan and gather information on things like
|
||||
glyph mappings in the final subset. The plan can then be passed on to perform
|
||||
the subsetting operation. (Garret Rieger)
|
||||
- Draw API for extracting glyph shapes have been extended and finalized and is
|
||||
no longer an experimental API. The draw API supports glyf, CFF and CFF2
|
||||
glyph outlines tables, and applies variation settings set on the font as well
|
||||
as synthetic slant. The new public API is not backward compatible with the
|
||||
previous, non-public, experimental API. (Behdad Esfahbod)
|
||||
- The hb-view tool will use HarfBuzz draw API to render the glyphs instead of
|
||||
cairo-ft when compiled with Cairo 1.17.5 or newer, setting HB_DRAW
|
||||
environment variable to 1 or 0 will force using or not use the draw API,
|
||||
respectively. (Behdad Esfahbod)
|
||||
- The hb-shape and hb-view tools now default to using HarfBuzz’s own font
|
||||
loading functions (ot) instead of FreeType ones (ft). They also have a new
|
||||
option, --font-slant, to apply synthetic slant to the font. (Behdad Esfahbod)
|
||||
- HarfBuzz now supports more than 65535 (the OpenType limit) glyph shapes and
|
||||
metrics. See https://github.com/be-fonts/boring-expansion-spec/issues/6 and
|
||||
https://github.com/be-fonts/boring-expansion-spec/issues/7 for details.
|
||||
(Behdad Esfahbod)
|
||||
- New API to get the dominant horizontal baseline tag for a given script.
|
||||
(Behdad Esfahbod)
|
||||
- New API to get the baseline positions from the font, and synthesize missing
|
||||
ones. As well as new API to get font metrics and synthesize missing ones.
|
||||
(Matthias Clasen)
|
||||
- Improvements to finding dependencies on Windows when building with Visual
|
||||
Studio. (Chun-wei Fan)
|
||||
- New buffer flag, HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT, that must be set
|
||||
during shaping for HB_GLYPH_FLAG_UNSAFE_TO_CONCAT flag to be reliably
|
||||
produced. This is to limit the performance hit of producing this flag to when
|
||||
it is actually needed. (Behdad Esfahbod)
|
||||
- Documentation improvements. (Matthias Clasen)
|
||||
|
||||
- New API
|
||||
- General:
|
||||
+HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT
|
||||
+hb_var_num_t
|
||||
|
||||
- Draw:
|
||||
+hb_draw_funcs_t
|
||||
+hb_draw_funcs_create()
|
||||
+hb_draw_funcs_reference()
|
||||
+hb_draw_funcs_destroy()
|
||||
+hb_draw_funcs_is_immutable()
|
||||
+hb_draw_funcs_make_immutable()
|
||||
+hb_draw_move_to_func_t
|
||||
+hb_draw_funcs_set_move_to_func()
|
||||
+hb_draw_line_to_func_t
|
||||
+hb_draw_funcs_set_line_to_func()
|
||||
+hb_draw_quadratic_to_func_t
|
||||
+hb_draw_funcs_set_quadratic_to_func()
|
||||
+hb_draw_cubic_to_func_t
|
||||
+hb_draw_funcs_set_cubic_to_func()
|
||||
+hb_draw_close_path_func_t
|
||||
+hb_draw_funcs_set_close_path_func()
|
||||
+hb_draw_state_t
|
||||
+HB_DRAW_STATE_DEFAULT
|
||||
+hb_draw_move_to()
|
||||
+hb_draw_line_to()
|
||||
+hb_draw_quadratic_to()
|
||||
+hb_draw_cubic_to()
|
||||
+hb_draw_close_path()
|
||||
+hb_font_get_glyph_shape_func_t
|
||||
+hb_font_funcs_set_glyph_shape_func()
|
||||
+hb_font_get_glyph_shape()
|
||||
|
||||
- OpenType layout
|
||||
+HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL
|
||||
+HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL
|
||||
+hb_ot_layout_get_horizontal_baseline_tag_for_script()
|
||||
+hb_ot_layout_get_baseline_with_fallback()
|
||||
|
||||
- Metrics:
|
||||
+hb_ot_metrics_get_position_with_fallback()
|
||||
|
||||
- Subset:
|
||||
+hb_subset_plan_t
|
||||
+hb_subset_plan_create_or_fail()
|
||||
+hb_subset_plan_reference()
|
||||
+hb_subset_plan_destroy()
|
||||
+hb_subset_plan_set_user_data()
|
||||
+hb_subset_plan_get_user_data()
|
||||
+hb_subset_plan_execute_or_fail()
|
||||
+hb_subset_plan_unicode_to_old_glyph_mapping()
|
||||
+hb_subset_plan_new_to_old_glyph_mapping()
|
||||
+hb_subset_plan_old_to_new_glyph_mapping()
|
||||
|
||||
|
||||
Overview of changes leading to 3.4.0
|
||||
Sunday, February 13, 2022
|
||||
====================================
|
||||
|
@ -10,15 +134,15 @@ Sunday, February 13, 2022
|
|||
‘math’ tag. (Alexis King)
|
||||
- It is now possible to get at once all math kerning values for a given glyph
|
||||
at a given corner. (Alexis King)
|
||||
- Fix locale_t portability issues on systems the typdef’s it to a void pointer.
|
||||
(Behdad Esfahbod)
|
||||
- Fix locale_t portability issues on systems the typedef’s it to a void
|
||||
pointer. (Behdad Esfahbod)
|
||||
|
||||
- New API:
|
||||
+HB_BUFFER_FLAG_VERIFY
|
||||
+HB_OT_TAG_MATH_SCRIPT
|
||||
+HB_SCRIPT_MATH
|
||||
+hb_ot_math_kern_entry_t
|
||||
+hb_ot_math_get_glyph_kernings
|
||||
+hb_ot_math_get_glyph_kernings()
|
||||
|
||||
- Deprecated API
|
||||
+HB_OT_MATH_SCRIPT
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
This directory contains the HarfBuzz source from the upstream repo:
|
||||
https://github.com/harfbuzz/harfbuzz
|
||||
|
||||
Current version: 3.4.0 [commit 0a129961341da370ec82bfccdd11ec9b1094b5a2]
|
||||
Current version: 4.1.0 [commit c36844d6d923bfc765f841fde10d6f505ff297fd]
|
||||
|
||||
!!!Please Note!!!
|
||||
Because LLVM added in D100581 support for -Wunused-but-set-parameter and -Wunused-but-set-variable
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
API issues:
|
||||
===========
|
||||
|
||||
- API to accept a list of languages?
|
||||
|
||||
- Remove hb_ot_shape_glyphs_closure()?
|
||||
|
||||
|
||||
API additions
|
||||
=============
|
||||
|
||||
- Language to/from script.
|
||||
|
||||
- Add hb-cairo glue
|
||||
|
||||
- Add sanitize API.
|
||||
|
||||
- Add query / enumeration API for aalt-like features?
|
||||
|
||||
- Add segmentation API
|
||||
|
||||
- Add hb-fribidi glue?
|
||||
|
||||
|
||||
hb-view / hb-shape enhancements:
|
||||
===============================
|
||||
|
||||
- Add --width, --height, --auto-size, --ink-box, --align, etc?
|
|
@ -1,6 +1,6 @@
|
|||
AC_PREREQ([2.64])
|
||||
AC_INIT([HarfBuzz],
|
||||
[3.4.0],
|
||||
[4.1.0],
|
||||
[https://github.com/harfbuzz/harfbuzz/issues/new],
|
||||
[harfbuzz],
|
||||
[http://harfbuzz.org/])
|
||||
|
@ -194,6 +194,10 @@ AC_ARG_WITH(cairo,
|
|||
have_cairo=false
|
||||
if test "x$with_cairo" = "xyes" -o "x$with_cairo" = "xauto"; then
|
||||
PKG_CHECK_MODULES(CAIRO, cairo >= 1.8.0, have_cairo=true, :)
|
||||
save_libs=$LIBS
|
||||
LIBS="$LIBS $CAIRO_LIBS"
|
||||
AC_CHECK_FUNCS(cairo_user_font_face_set_render_color_glyph_func)
|
||||
LIBS=$save_libs
|
||||
fi
|
||||
if test "x$with_cairo" = "xyes" -a "x$have_cairo" != "xtrue"; then
|
||||
AC_MSG_ERROR([cairo support requested but not found])
|
||||
|
|
|
@ -275,6 +275,7 @@ HB_SUBSET_sources = \
|
|||
hb-subset-input.hh \
|
||||
hb-subset-plan.cc \
|
||||
hb-subset-plan.hh \
|
||||
hb-subset-repacker.cc \
|
||||
hb-subset.cc \
|
||||
hb-subset.hh \
|
||||
hb-repacker.hh \
|
||||
|
@ -282,6 +283,7 @@ HB_SUBSET_sources = \
|
|||
|
||||
HB_SUBSET_headers = \
|
||||
hb-subset.h \
|
||||
hb-subset-repacker.h \
|
||||
$(NULL)
|
||||
|
||||
HB_GOBJECT_DIST_sources = hb-gobject-structs.cc
|
||||
|
|
|
@ -19,23 +19,7 @@ symbols = sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re
|
|||
if '--experimental-api' not in sys.argv:
|
||||
# Move these to harfbuzz-sections.txt when got stable
|
||||
experimental_symbols = \
|
||||
"""hb_font_draw_glyph
|
||||
hb_draw_funcs_t
|
||||
hb_draw_close_path_func_t
|
||||
hb_draw_cubic_to_func_t
|
||||
hb_draw_line_to_func_t
|
||||
hb_draw_move_to_func_t
|
||||
hb_draw_quadratic_to_func_t
|
||||
hb_draw_funcs_create
|
||||
hb_draw_funcs_destroy
|
||||
hb_draw_funcs_is_immutable
|
||||
hb_draw_funcs_make_immutable
|
||||
hb_draw_funcs_reference
|
||||
hb_draw_funcs_set_close_path_func
|
||||
hb_draw_funcs_set_cubic_to_func
|
||||
hb_draw_funcs_set_line_to_func
|
||||
hb_draw_funcs_set_move_to_func
|
||||
hb_draw_funcs_set_quadratic_to_func""".splitlines ()
|
||||
"""hb_subset_repack_or_fail""".splitlines ()
|
||||
symbols = [x for x in symbols if x not in experimental_symbols]
|
||||
symbols = "\n".join (symbols)
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ for j in range(7, 9):
|
|||
headers[j - 1].append(line)
|
||||
headers.append (["UnicodeData.txt does not have a header."])
|
||||
|
||||
data = [{} for _ in files]
|
||||
unicode_data = [{} for _ in files]
|
||||
values = [{} for _ in files]
|
||||
for i, f in enumerate (files):
|
||||
for line in f:
|
||||
|
@ -73,38 +73,16 @@ for i, f in enumerate (files):
|
|||
|
||||
i0 = i if i < 7 else i - 7
|
||||
for u in range (start, end + 1):
|
||||
data[i0][u] = t
|
||||
unicode_data[i0][u] = t
|
||||
values[i0][t] = values[i0].get (t, 0) + end - start + 1
|
||||
|
||||
defaults = ('Other', 'Not_Applicable', 'jt_X', '', 'Cn', 'No_Block', 'Unknown')
|
||||
|
||||
# TODO Characters that are not in Unicode Indic files, but used in USE
|
||||
data[0][0x1B61] = defaults[0]
|
||||
data[0][0x1B63] = defaults[0]
|
||||
data[0][0x1B64] = defaults[0]
|
||||
data[0][0x1B65] = defaults[0]
|
||||
data[0][0x1B66] = defaults[0]
|
||||
data[0][0x1B67] = defaults[0]
|
||||
data[0][0x1B69] = defaults[0]
|
||||
data[0][0x1B6A] = defaults[0]
|
||||
data[0][0x2060] = defaults[0]
|
||||
# TODO https://github.com/harfbuzz/harfbuzz/pull/1685
|
||||
data[0][0x1B5B] = 'Consonant_Placeholder'
|
||||
data[0][0x1B5C] = 'Consonant_Placeholder'
|
||||
data[0][0x1B5F] = 'Consonant_Placeholder'
|
||||
data[0][0x1B62] = 'Consonant_Placeholder'
|
||||
data[0][0x1B68] = 'Consonant_Placeholder'
|
||||
# TODO https://github.com/harfbuzz/harfbuzz/issues/1035
|
||||
data[0][0x11C44] = 'Consonant_Placeholder'
|
||||
data[0][0x11C45] = 'Consonant_Placeholder'
|
||||
# TODO https://github.com/harfbuzz/harfbuzz/pull/1399
|
||||
data[0][0x111C8] = 'Consonant_Placeholder'
|
||||
|
||||
# Merge data into one dict:
|
||||
for i,v in enumerate (defaults):
|
||||
values[i][v] = values[i].get (v, 0) + 1
|
||||
combined = {}
|
||||
for i,d in enumerate (data):
|
||||
for i,d in enumerate (unicode_data):
|
||||
for u,v in d.items ():
|
||||
if not u in combined:
|
||||
if i >= 4:
|
||||
|
@ -112,8 +90,6 @@ for i,d in enumerate (data):
|
|||
combined[u] = list (defaults)
|
||||
combined[u][i] = v
|
||||
combined = {k: v for k, v in combined.items() if v[6] not in DISABLED_SCRIPTS}
|
||||
data = combined
|
||||
del combined
|
||||
|
||||
|
||||
property_names = [
|
||||
|
@ -226,8 +202,8 @@ def is_BASE_OTHER(U, UISC, UDI, UGC, AJT):
|
|||
if UISC == Consonant_Placeholder: return True
|
||||
return U in [0x2015, 0x2022, 0x25FB, 0x25FC, 0x25FD, 0x25FE]
|
||||
def is_CGJ(U, UISC, UDI, UGC, AJT):
|
||||
# Also includes VARIATION_SELECTOR, WJ, and ZWJ
|
||||
return U == 0x200D or UDI and UGC in [Mc, Me, Mn]
|
||||
# Also includes VARIATION_SELECTOR and ZWJ
|
||||
return UISC == Joiner or UDI and UGC in [Mc, Me, Mn]
|
||||
def is_CONS_FINAL(U, UISC, UDI, UGC, AJT):
|
||||
return ((UISC == Consonant_Final and UGC != Lo) or
|
||||
UISC == Consonant_Succeeding_Repha)
|
||||
|
@ -245,13 +221,7 @@ def is_CONS_SUB(U, UISC, UDI, UGC, AJT):
|
|||
def is_CONS_WITH_STACKER(U, UISC, UDI, UGC, AJT):
|
||||
return UISC == Consonant_With_Stacker
|
||||
def is_HALANT(U, UISC, UDI, UGC, AJT):
|
||||
return (UISC in [Virama, Invisible_Stacker]
|
||||
and not is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UDI, UGC, AJT)
|
||||
and not is_SAKOT(U, UISC, UDI, UGC, AJT))
|
||||
def is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UDI, UGC, AJT):
|
||||
# Split off of HALANT
|
||||
# https://github.com/harfbuzz/harfbuzz/issues/1379
|
||||
return U == 0x1134D
|
||||
return UISC == Virama
|
||||
def is_HALANT_NUM(U, UISC, UDI, UGC, AJT):
|
||||
return UISC == Number_Joiner
|
||||
def is_HIEROGLYPH(U, UISC, UDI, UGC, AJT):
|
||||
|
@ -262,15 +232,21 @@ def is_HIEROGLYPH_SEGMENT_BEGIN(U, UISC, UDI, UGC, AJT):
|
|||
return UISC == Hieroglyph_Segment_Begin
|
||||
def is_HIEROGLYPH_SEGMENT_END(U, UISC, UDI, UGC, AJT):
|
||||
return UISC == Hieroglyph_Segment_End
|
||||
def is_INVISIBLE_STACKER(U, UISC, UDI, UGC, AJT):
|
||||
# Split off of HALANT
|
||||
return (UISC == Invisible_Stacker
|
||||
and not is_SAKOT(U, UISC, UDI, UGC, AJT)
|
||||
)
|
||||
def is_ZWNJ(U, UISC, UDI, UGC, AJT):
|
||||
return UISC == Non_Joiner
|
||||
def is_OTHER(U, UISC, UDI, UGC, AJT):
|
||||
# Also includes BASE_IND, Rsv, and SYM
|
||||
return ((UGC in [Cn, Po] or UISC in [Consonant_Dead, Joiner, Modifying_Letter, Other])
|
||||
# Also includes BASE_IND and SYM
|
||||
return ((UGC == Po or UISC in [Consonant_Dead, Joiner, Modifying_Letter, Other])
|
||||
and not is_BASE(U, UISC, UDI, UGC, AJT)
|
||||
and not is_BASE_OTHER(U, UISC, UDI, UGC, AJT)
|
||||
and not is_CGJ(U, UISC, UDI, UGC, AJT)
|
||||
and not is_SYM_MOD(U, UISC, UDI, UGC, AJT)
|
||||
and not is_Word_Joiner(U, UISC, UDI, UGC, AJT)
|
||||
)
|
||||
def is_REPHA(U, UISC, UDI, UGC, AJT):
|
||||
return UISC in [Consonant_Preceding_Repha, Consonant_Prefixed]
|
||||
|
@ -280,13 +256,17 @@ def is_SAKOT(U, UISC, UDI, UGC, AJT):
|
|||
def is_SYM_MOD(U, UISC, UDI, UGC, AJT):
|
||||
return U in [0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E, 0x1B6F, 0x1B70, 0x1B71, 0x1B72, 0x1B73]
|
||||
def is_VOWEL(U, UISC, UDI, UGC, AJT):
|
||||
# https://github.com/harfbuzz/harfbuzz/issues/376
|
||||
return (UISC == Pure_Killer or
|
||||
(UGC != Lo and UISC in [Vowel, Vowel_Dependent] and U not in [0xAA29]))
|
||||
UGC != Lo and UISC in [Vowel, Vowel_Dependent])
|
||||
def is_VOWEL_MOD(U, UISC, UDI, UGC, AJT):
|
||||
# https://github.com/harfbuzz/harfbuzz/issues/376
|
||||
return (UISC in [Tone_Mark, Cantillation_Mark, Register_Shifter, Visarga] or
|
||||
(UGC != Lo and (UISC == Bindu or U in [0xAA29])))
|
||||
UGC != Lo and UISC == Bindu)
|
||||
def is_Word_Joiner(U, UISC, UDI, UGC, AJT):
|
||||
# Also includes Rsv
|
||||
return (UDI and U not in [0x115F, 0x1160, 0x3164, 0xFFA0, 0x1BCA0, 0x1BCA1, 0x1BCA2, 0x1BCA3]
|
||||
and UISC == Other
|
||||
and not is_CGJ(U, UISC, UDI, UGC, AJT)
|
||||
) or UGC == Cn
|
||||
|
||||
use_mapping = {
|
||||
'B': is_BASE,
|
||||
|
@ -300,8 +280,8 @@ use_mapping = {
|
|||
'SUB': is_CONS_SUB,
|
||||
'CS': is_CONS_WITH_STACKER,
|
||||
'H': is_HALANT,
|
||||
'HVM': is_HALANT_OR_VOWEL_MODIFIER,
|
||||
'HN': is_HALANT_NUM,
|
||||
'IS': is_INVISIBLE_STACKER,
|
||||
'G': is_HIEROGLYPH,
|
||||
'J': is_HIEROGLYPH_JOINER,
|
||||
'SB': is_HIEROGLYPH_SEGMENT_BEGIN,
|
||||
|
@ -313,6 +293,7 @@ use_mapping = {
|
|||
'SM': is_SYM_MOD,
|
||||
'V': is_VOWEL,
|
||||
'VM': is_VOWEL_MOD,
|
||||
'WJ': is_Word_Joiner,
|
||||
}
|
||||
|
||||
use_positions = {
|
||||
|
@ -348,7 +329,7 @@ use_positions = {
|
|||
'Blw': [Bottom],
|
||||
},
|
||||
'H': None,
|
||||
'HVM': None,
|
||||
'IS': None,
|
||||
'B': None,
|
||||
'FM': {
|
||||
'Abv': [Top],
|
||||
|
@ -380,9 +361,6 @@ def map_to_use(data):
|
|||
# the nasalization marks, maybe only for U+1CE9..U+1CF1.
|
||||
if U == 0x1CED: UISC = Tone_Mark
|
||||
|
||||
# TODO: https://github.com/microsoft/font-tools/issues/1
|
||||
if U == 0xA982: UISC = Consonant_Succeeding_Repha
|
||||
|
||||
values = [k for k,v in items if v(U, UISC, UDI, UGC, AJT)]
|
||||
assert len(values) == 1, "%s %s %s %s %s %s" % (hex(U), UISC, UDI, UGC, AJT, values)
|
||||
USE = values[0]
|
||||
|
@ -416,8 +394,7 @@ def map_to_use(data):
|
|||
out[U] = (USE, UBlock)
|
||||
return out
|
||||
|
||||
defaults = ('O', 'No_Block')
|
||||
data = map_to_use(data)
|
||||
use_data = map_to_use(combined)
|
||||
|
||||
print ("/* == Start of generated table == */")
|
||||
print ("/*")
|
||||
|
@ -443,7 +420,7 @@ print ()
|
|||
total = 0
|
||||
used = 0
|
||||
last_block = None
|
||||
def print_block (block, start, end, data):
|
||||
def print_block (block, start, end, use_data):
|
||||
global total, used, last_block
|
||||
if block and block != last_block:
|
||||
print ()
|
||||
|
@ -458,17 +435,23 @@ def print_block (block, start, end, data):
|
|||
if u % 16 == 0:
|
||||
print ()
|
||||
print (" /* %04X */" % u, end='')
|
||||
if u in data:
|
||||
if u in use_data:
|
||||
num += 1
|
||||
d = data.get (u, defaults)
|
||||
print ("%6s," % d[0], end='')
|
||||
d = use_data.get (u)
|
||||
if d is not None:
|
||||
d = d[0]
|
||||
elif u in unicode_data[4]:
|
||||
d = 'O'
|
||||
else:
|
||||
d = 'WJ'
|
||||
print ("%6s," % d, end='')
|
||||
|
||||
total += end - start + 1
|
||||
used += num
|
||||
if block:
|
||||
last_block = block
|
||||
|
||||
uu = sorted (data.keys ())
|
||||
uu = sorted (use_data.keys ())
|
||||
|
||||
last = -100000
|
||||
num = 0
|
||||
|
@ -491,19 +474,19 @@ print ("static const uint8_t use_table[] = {")
|
|||
for u in uu:
|
||||
if u <= last:
|
||||
continue
|
||||
if data[u][0] == 'O':
|
||||
if use_data[u][0] == 'O':
|
||||
continue
|
||||
block = data[u][1]
|
||||
block = use_data[u][1]
|
||||
|
||||
start = u//8*8
|
||||
end = start+1
|
||||
while end in uu and block == data[end][1]:
|
||||
while end in uu and block == use_data[end][1]:
|
||||
end += 1
|
||||
end = (end-1)//8*8 + 7
|
||||
|
||||
if start != last + 1:
|
||||
if start - last <= 1+16*3:
|
||||
print_block (None, last+1, start-1, data)
|
||||
print_block (None, last+1, start-1, use_data)
|
||||
else:
|
||||
if last >= 0:
|
||||
ends.append (last + 1)
|
||||
|
@ -513,7 +496,7 @@ for u in uu:
|
|||
print ("#define use_offset_0x%04xu %d" % (start, offset))
|
||||
starts.append (start)
|
||||
|
||||
print_block (block, start, end, data)
|
||||
print_block (block, start, end, use_data)
|
||||
last = end
|
||||
ends.append (last + 1)
|
||||
offset += ends[-1] - starts[-1]
|
||||
|
@ -524,8 +507,9 @@ page_bits = 12
|
|||
print ("}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy))
|
||||
print ()
|
||||
print ("static inline uint8_t")
|
||||
print ("hb_use_get_category (hb_codepoint_t u)")
|
||||
print ("hb_use_get_category (hb_glyph_info_t info)")
|
||||
print ("{")
|
||||
print (" hb_codepoint_t u = info.codepoint;")
|
||||
print (" switch (u >> %d)" % page_bits)
|
||||
print (" {")
|
||||
pages = set([u>>page_bits for u in starts+ends])
|
||||
|
@ -540,7 +524,9 @@ for p in sorted(pages):
|
|||
print (" default:")
|
||||
print (" break;")
|
||||
print (" }")
|
||||
print (" return USE(O);")
|
||||
print (" if (_hb_glyph_info_get_general_category (&info) == HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED)")
|
||||
print (" return WJ;")
|
||||
print (" return O;")
|
||||
print ("}")
|
||||
print ()
|
||||
for k in sorted(use_mapping.keys()):
|
||||
|
|
|
@ -108,7 +108,7 @@ static const hb_aat_feature_mapping_t feature_mappings[] =
|
|||
{HB_TAG ('f','r','a','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS},
|
||||
{HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT, (hb_aat_layout_feature_selector_t) 7},
|
||||
{HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7},
|
||||
{HB_TAG ('h','i','s','t'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF},
|
||||
{HB_TAG ('h','i','s','t'), (hb_aat_layout_feature_type_t) 40, (hb_aat_layout_feature_selector_t) 0, (hb_aat_layout_feature_selector_t) 1},
|
||||
{HB_TAG ('h','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF},
|
||||
{HB_TAG ('h','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF},
|
||||
{HB_TAG ('h','n','g','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION, HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION},
|
||||
|
@ -170,6 +170,7 @@ static const hb_aat_feature_mapping_t feature_mappings[] =
|
|||
{HB_TAG ('v','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF},
|
||||
{HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7},
|
||||
{HB_TAG ('v','r','t','2'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF},
|
||||
{HB_TAG ('v','r','t','r'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, (hb_aat_layout_feature_selector_t) 2, (hb_aat_layout_feature_selector_t) 3},
|
||||
{HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF},
|
||||
};
|
||||
|
||||
|
|
|
@ -226,14 +226,8 @@ struct
|
|||
template <typename T> constexpr auto
|
||||
impl (const T& v, hb_priority<2>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
|
||||
|
||||
/* Sadly, we must give further hints to VS2015 to build the following template item */
|
||||
#if !defined (_MSC_VER) || defined (__clang__) || (_MSC_VER >= 1910)
|
||||
template <typename T> constexpr auto
|
||||
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v)))
|
||||
#else
|
||||
template <typename T> constexpr auto
|
||||
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v).hash ())>>{} (hb_deref (v)))
|
||||
#endif
|
||||
|
||||
template <typename T,
|
||||
hb_enable_if (std::is_integral<T>::value)> constexpr auto
|
||||
|
@ -504,7 +498,7 @@ struct hb_pair_t
|
|||
|
||||
template <typename Q1, typename Q2,
|
||||
hb_enable_if (hb_is_convertible (T1, Q1) &&
|
||||
hb_is_convertible (T2, T2))>
|
||||
hb_is_convertible (T2, Q2))>
|
||||
operator hb_pair_t<Q1, Q2> () { return hb_pair_t<Q1, Q2> (first, second); }
|
||||
|
||||
hb_pair_t<T1, T2> reverse () const
|
||||
|
|
|
@ -179,6 +179,8 @@ struct hb_bit_page_t
|
|||
typedef unsigned long long elt_t;
|
||||
static constexpr unsigned PAGE_BITS = 512;
|
||||
static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, "");
|
||||
static constexpr unsigned PAGE_BITS_LOG_2 = 9;
|
||||
static_assert (1 << PAGE_BITS_LOG_2 == PAGE_BITS, "");
|
||||
|
||||
static unsigned int elt_get_min (const elt_t &elt) { return hb_ctz (elt); }
|
||||
static unsigned int elt_get_max (const elt_t &elt) { return hb_bit_storage (elt) - 1; }
|
||||
|
@ -186,6 +188,9 @@ struct hb_bit_page_t
|
|||
typedef hb_vector_size_t<elt_t, PAGE_BITS / 8> vector_t;
|
||||
|
||||
static constexpr unsigned ELT_BITS = sizeof (elt_t) * 8;
|
||||
static constexpr unsigned ELT_BITS_LOG_2 = 6;
|
||||
static_assert (1 << ELT_BITS_LOG_2 == ELT_BITS, "");
|
||||
|
||||
static constexpr unsigned ELT_MASK = ELT_BITS - 1;
|
||||
static constexpr unsigned BITS = sizeof (vector_t) * 8;
|
||||
static constexpr unsigned MASK = BITS - 1;
|
||||
|
|
|
@ -203,7 +203,7 @@ struct hb_bit_set_t
|
|||
bool set_sorted_array (bool v, const T *array, unsigned int count, unsigned int stride=sizeof(T))
|
||||
{
|
||||
if (unlikely (!successful)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */
|
||||
if (!count) return true;
|
||||
if (unlikely (!count)) return true;
|
||||
dirty ();
|
||||
hb_codepoint_t g = *array;
|
||||
hb_codepoint_t last_g = g;
|
||||
|
@ -222,7 +222,7 @@ struct hb_bit_set_t
|
|||
if (v || page) /* The v check is to optimize out the page check if v is true. */
|
||||
page->add (g);
|
||||
|
||||
array = (const T *) ((const char *) array + stride);
|
||||
array = &StructAtOffsetUnaligned<T> (array, stride);
|
||||
count--;
|
||||
}
|
||||
while (count && (g = *array, g < end));
|
||||
|
@ -809,8 +809,8 @@ struct hb_bit_set_t
|
|||
}
|
||||
page_t &page_at (unsigned int i) { return pages[page_map[i].index]; }
|
||||
const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; }
|
||||
unsigned int get_major (hb_codepoint_t g) const { return g / page_t::PAGE_BITS; }
|
||||
hb_codepoint_t major_start (unsigned int major) const { return major * page_t::PAGE_BITS; }
|
||||
unsigned int get_major (hb_codepoint_t g) const { return g >> page_t::PAGE_BITS_LOG_2; }
|
||||
hb_codepoint_t major_start (unsigned int major) const { return major << page_t::PAGE_BITS_LOG_2; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -478,7 +478,7 @@ _resume:
|
|||
case 18:
|
||||
#line 58 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
/* TODO Unescape delimeters. */
|
||||
/* TODO Unescape delimiters. */
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
|
@ -535,7 +535,7 @@ _resume:
|
|||
case 16:
|
||||
#line 58 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
/* TODO Unescape delimeters. */
|
||||
/* TODO Unescape delimiters. */
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
|
@ -635,7 +635,7 @@ _resume:
|
|||
}
|
||||
#line 58 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
/* TODO Unescape delimeters. */
|
||||
/* TODO Unescape delimiters. */
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
|
@ -645,7 +645,7 @@ _resume:
|
|||
case 17:
|
||||
#line 58 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
/* TODO Unescape delimeters. */
|
||||
/* TODO Unescape delimiters. */
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
|
@ -674,7 +674,7 @@ _resume:
|
|||
}
|
||||
#line 58 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
/* TODO Unescape delimeters. */
|
||||
/* TODO Unescape delimiters. */
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
|
@ -701,7 +701,7 @@ _resume:
|
|||
}
|
||||
#line 58 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
/* TODO Unescape delimeters. */
|
||||
/* TODO Unescape delimiters. */
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
|
@ -733,7 +733,7 @@ _again:
|
|||
case 16:
|
||||
#line 58 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
/* TODO Unescape delimeters. */
|
||||
/* TODO Unescape delimiters. */
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
|
@ -820,7 +820,7 @@ _again:
|
|||
}
|
||||
#line 58 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
/* TODO Unescape delimeters. */
|
||||
/* TODO Unescape delimiters. */
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
|
|
|
@ -56,7 +56,7 @@ action ensure_glyphs { if (unlikely (!buffer->ensure_glyphs ())) return false; }
|
|||
action ensure_unicode { if (unlikely (!buffer->ensure_unicode ())) return false; }
|
||||
|
||||
action parse_glyph {
|
||||
/* TODO Unescape delimeters. */
|
||||
/* TODO Unescape delimiters. */
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
|
|
|
@ -397,7 +397,8 @@ hb_buffer_t::verify (hb_buffer_t *text_buffer,
|
|||
ret = false;
|
||||
if (!buffer_verify_unsafe_to_break (this, text_buffer, font, features, num_features, shapers))
|
||||
ret = false;
|
||||
if (!buffer_verify_unsafe_to_concat (this, text_buffer, font, features, num_features, shapers))
|
||||
if ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) != 0 &&
|
||||
!buffer_verify_unsafe_to_concat (this, text_buffer, font, features, num_features, shapers))
|
||||
ret = false;
|
||||
if (!ret)
|
||||
{
|
||||
|
|
|
@ -295,7 +295,6 @@ hb_buffer_t::clear ()
|
|||
idx = 0;
|
||||
len = 0;
|
||||
out_len = 0;
|
||||
|
||||
out_info = info;
|
||||
|
||||
memset (context, 0, sizeof context);
|
||||
|
@ -405,6 +404,7 @@ hb_buffer_t::sync ()
|
|||
reset:
|
||||
have_output = false;
|
||||
out_len = 0;
|
||||
out_info = info;
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ typedef struct hb_glyph_info_t {
|
|||
* from there, and repeat.
|
||||
* At the start of next line a similar algorithm can
|
||||
* be implemented. That is: 1. Iterate forward from
|
||||
* the line-break position untill the first cluster
|
||||
* the line-break position until the first cluster
|
||||
* start position that is NOT unsafe-to-concat, 2.
|
||||
* shape the segment from beginning of the line to
|
||||
* that position, 3. check whether the resulting
|
||||
|
@ -137,7 +137,11 @@ typedef struct hb_glyph_info_t {
|
|||
* clusters.
|
||||
* The #HB_GLYPH_FLAG_UNSAFE_TO_BREAK flag will
|
||||
* always imply this flag.
|
||||
* Since: 3.3.0
|
||||
* To use this flag, you must enable the buffer flag
|
||||
* @HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT during
|
||||
* shaping, otherwise the buffer flag will not be
|
||||
* reliably produced.
|
||||
* Since: 4.0.0
|
||||
* @HB_GLYPH_FLAG_DEFINED: All the currently defined flags.
|
||||
*
|
||||
* Flags for #hb_glyph_info_t.
|
||||
|
@ -365,6 +369,10 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
|
|||
* handler is installed on the buffer, or a message is written
|
||||
* to standard error. In either case, the shaping result might
|
||||
* be modified to show the failed output. Since: 3.4.0
|
||||
* @HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT:
|
||||
* flag indicating that the @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT
|
||||
* glyph-flag should be produced by the shaper. By default
|
||||
* it will not be produced since it incurs a cost. Since: 4.0.0
|
||||
*
|
||||
* Flags for #hb_buffer_t.
|
||||
*
|
||||
|
@ -377,7 +385,8 @@ typedef enum { /*< flags >*/
|
|||
HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u,
|
||||
HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES = 0x00000008u,
|
||||
HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u,
|
||||
HB_BUFFER_FLAG_VERIFY = 0x00000020u
|
||||
HB_BUFFER_FLAG_VERIFY = 0x00000020u,
|
||||
HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x00000040u
|
||||
} hb_buffer_flags_t;
|
||||
|
||||
HB_EXTERN void
|
||||
|
|
|
@ -460,6 +460,8 @@ struct hb_buffer_t
|
|||
}
|
||||
void unsafe_to_concat (unsigned int start = 0, unsigned int end = -1)
|
||||
{
|
||||
if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0))
|
||||
return;
|
||||
_set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
|
||||
start, end,
|
||||
true);
|
||||
|
@ -472,6 +474,8 @@ struct hb_buffer_t
|
|||
}
|
||||
void unsafe_to_concat_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
|
||||
{
|
||||
if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0))
|
||||
return;
|
||||
_set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
|
||||
start, end,
|
||||
false, true);
|
||||
|
|
|
@ -130,6 +130,16 @@ typedef union _hb_var_int_t {
|
|||
int8_t i8[4];
|
||||
} hb_var_int_t;
|
||||
|
||||
typedef union _hb_var_num_t {
|
||||
float f;
|
||||
uint32_t u32;
|
||||
int32_t i32;
|
||||
uint16_t u16[2];
|
||||
int16_t i16[2];
|
||||
uint8_t u8[4];
|
||||
int8_t i8[4];
|
||||
} hb_var_num_t;
|
||||
|
||||
|
||||
/* hb_tag_t */
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
#ifdef HB_MINI
|
||||
#define HB_NO_AAT
|
||||
#define HB_NO_LEGACY
|
||||
#define HB_NO_BORING_EXPANSION
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_CONFIG_OVERRIDE_H) || defined(HB_CONFIG_OVERRIDE_H)
|
||||
|
|
|
@ -897,7 +897,7 @@ resize_and_retry:
|
|||
DEBUG_MSG (CORETEXT, nullptr, "Num runs: %d", num_runs);
|
||||
|
||||
buffer->len = 0;
|
||||
uint32_t status_and = ~0, status_or = 0;
|
||||
uint32_t status_or = 0;
|
||||
CGFloat advances_so_far = 0;
|
||||
/* For right-to-left runs, CoreText returns the glyphs positioned such that
|
||||
* any trailing whitespace is to the left of (0,0). Adjust coordinate system
|
||||
|
@ -918,7 +918,6 @@ resize_and_retry:
|
|||
CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex (glyph_runs, i));
|
||||
CTRunStatus run_status = CTRunGetStatus (run);
|
||||
status_or |= run_status;
|
||||
status_and &= run_status;
|
||||
DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status);
|
||||
CGFloat run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr);
|
||||
if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
|
||||
|
@ -1140,21 +1139,6 @@ resize_and_retry:
|
|||
buffer->len += num_glyphs;
|
||||
}
|
||||
|
||||
/* Mac OS 10.6 doesn't have kCTTypesetterOptionForcedEmbeddingLevel,
|
||||
* or if it does, it doesn't respect it. So we get runs with wrong
|
||||
* directions. As such, disable the assert... It wouldn't crash, but
|
||||
* cursoring will be off...
|
||||
*
|
||||
* https://crbug.com/419769
|
||||
*/
|
||||
if (false)
|
||||
{
|
||||
/* Make sure all runs had the expected direction. */
|
||||
HB_UNUSED bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
|
||||
assert (bool (status_and & kCTRunStatusRightToLeft) == backward);
|
||||
assert (bool (status_or & kCTRunStatusRightToLeft) == backward);
|
||||
}
|
||||
|
||||
buffer->clear_positions ();
|
||||
|
||||
unsigned int count = buffer->len;
|
||||
|
|
|
@ -25,237 +25,313 @@
|
|||
#include "hb.hh"
|
||||
|
||||
#ifndef HB_NO_DRAW
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
|
||||
#include "hb-draw.hh"
|
||||
#include "hb-ot.h"
|
||||
#include "hb-ot-glyf-table.hh"
|
||||
#include "hb-ot-cff1-table.hh"
|
||||
#include "hb-ot-cff2-table.hh"
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_set_move_to_func:
|
||||
* @funcs: draw functions object
|
||||
* @move_to: move-to callback
|
||||
* SECTION:hb-draw
|
||||
* @title: hb-draw
|
||||
* @short_description: Glyph drawing
|
||||
* @include: hb.h
|
||||
*
|
||||
* Sets move-to callback to the draw functions object.
|
||||
*
|
||||
* Since: EXPERIMENTAL
|
||||
* Functions for drawing (extracting) glyph shapes.
|
||||
**/
|
||||
void
|
||||
hb_draw_funcs_set_move_to_func (hb_draw_funcs_t *funcs,
|
||||
hb_draw_move_to_func_t move_to)
|
||||
{
|
||||
if (unlikely (hb_object_is_immutable (funcs))) return;
|
||||
funcs->move_to = move_to;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_set_line_to_func:
|
||||
* @funcs: draw functions object
|
||||
* @line_to: line-to callback
|
||||
*
|
||||
* Sets line-to callback to the draw functions object.
|
||||
*
|
||||
* Since: EXPERIMENTAL
|
||||
**/
|
||||
void
|
||||
hb_draw_funcs_set_line_to_func (hb_draw_funcs_t *funcs,
|
||||
hb_draw_line_to_func_t line_to)
|
||||
{
|
||||
if (unlikely (hb_object_is_immutable (funcs))) return;
|
||||
funcs->line_to = line_to;
|
||||
}
|
||||
static void
|
||||
hb_draw_move_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
|
||||
hb_draw_state_t *st HB_UNUSED,
|
||||
float to_x HB_UNUSED, float to_y HB_UNUSED,
|
||||
void *user_data HB_UNUSED) {}
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_set_quadratic_to_func:
|
||||
* @funcs: draw functions object
|
||||
* @move_to: quadratic-to callback
|
||||
*
|
||||
* Sets quadratic-to callback to the draw functions object.
|
||||
*
|
||||
* Since: EXPERIMENTAL
|
||||
**/
|
||||
void
|
||||
hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t *funcs,
|
||||
hb_draw_quadratic_to_func_t quadratic_to)
|
||||
{
|
||||
if (unlikely (hb_object_is_immutable (funcs))) return;
|
||||
funcs->quadratic_to = quadratic_to;
|
||||
funcs->is_quadratic_to_set = true;
|
||||
}
|
||||
static void
|
||||
hb_draw_line_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
|
||||
hb_draw_state_t *st HB_UNUSED,
|
||||
float to_x HB_UNUSED, float to_y HB_UNUSED,
|
||||
void *user_data HB_UNUSED) {}
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_set_cubic_to_func:
|
||||
* @funcs: draw functions
|
||||
* @cubic_to: cubic-to callback
|
||||
*
|
||||
* Sets cubic-to callback to the draw functions object.
|
||||
*
|
||||
* Since: EXPERIMENTAL
|
||||
**/
|
||||
void
|
||||
hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t *funcs,
|
||||
hb_draw_cubic_to_func_t cubic_to)
|
||||
static void
|
||||
hb_draw_quadratic_to_nil (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float control_x, float control_y,
|
||||
float to_x, float to_y,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
if (unlikely (hb_object_is_immutable (funcs))) return;
|
||||
funcs->cubic_to = cubic_to;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_set_close_path_func:
|
||||
* @funcs: draw functions object
|
||||
* @close_path: close-path callback
|
||||
*
|
||||
* Sets close-path callback to the draw functions object.
|
||||
*
|
||||
* Since: EXPERIMENTAL
|
||||
**/
|
||||
void
|
||||
hb_draw_funcs_set_close_path_func (hb_draw_funcs_t *funcs,
|
||||
hb_draw_close_path_func_t close_path)
|
||||
{
|
||||
if (unlikely (hb_object_is_immutable (funcs))) return;
|
||||
funcs->close_path = close_path;
|
||||
dfuncs->emit_cubic_to (draw_data, *st,
|
||||
(st->current_x + 2.f * control_x) / 3.f,
|
||||
(st->current_y + 2.f * control_y) / 3.f,
|
||||
(to_x + 2.f * control_x) / 3.f,
|
||||
(to_y + 2.f * control_y) / 3.f,
|
||||
to_x, to_y);
|
||||
}
|
||||
|
||||
static void
|
||||
_move_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
|
||||
hb_draw_cubic_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
|
||||
hb_draw_state_t *st HB_UNUSED,
|
||||
float control1_x HB_UNUSED, float control1_y HB_UNUSED,
|
||||
float control2_x HB_UNUSED, float control2_y HB_UNUSED,
|
||||
float to_x HB_UNUSED, float to_y HB_UNUSED,
|
||||
void *user_data HB_UNUSED) {}
|
||||
|
||||
static void
|
||||
_line_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
|
||||
hb_draw_close_path_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
|
||||
hb_draw_state_t *st HB_UNUSED,
|
||||
void *user_data HB_UNUSED) {}
|
||||
|
||||
static void
|
||||
_quadratic_to_nil (hb_position_t control_x HB_UNUSED, hb_position_t control_y HB_UNUSED,
|
||||
hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED,
|
||||
void *user_data HB_UNUSED) {}
|
||||
|
||||
static void
|
||||
_cubic_to_nil (hb_position_t control1_x HB_UNUSED, hb_position_t control1_y HB_UNUSED,
|
||||
hb_position_t control2_x HB_UNUSED, hb_position_t control2_y HB_UNUSED,
|
||||
hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED,
|
||||
void *user_data HB_UNUSED) {}
|
||||
#define HB_DRAW_FUNC_IMPLEMENT(name) \
|
||||
\
|
||||
void \
|
||||
hb_draw_funcs_set_##name##_func (hb_draw_funcs_t *dfuncs, \
|
||||
hb_draw_##name##_func_t func, \
|
||||
void *user_data, \
|
||||
hb_destroy_func_t destroy) \
|
||||
{ \
|
||||
if (hb_object_is_immutable (dfuncs)) \
|
||||
return; \
|
||||
\
|
||||
if (dfuncs->destroy.name) \
|
||||
dfuncs->destroy.name (dfuncs->user_data.name); \
|
||||
\
|
||||
if (func) { \
|
||||
dfuncs->func.name = func; \
|
||||
dfuncs->user_data.name = user_data; \
|
||||
dfuncs->destroy.name = destroy; \
|
||||
} else { \
|
||||
dfuncs->func.name = hb_draw_##name##_nil; \
|
||||
dfuncs->user_data.name = nullptr; \
|
||||
dfuncs->destroy.name = nullptr; \
|
||||
} \
|
||||
}
|
||||
|
||||
static void
|
||||
_close_path_nil (void *user_data HB_UNUSED) {}
|
||||
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_DRAW_FUNC_IMPLEMENT
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_create:
|
||||
* hb_draw_funcs_create: (Xconstructor)
|
||||
*
|
||||
* Creates a new draw callbacks object.
|
||||
*
|
||||
* Since: EXPERIMENTAL
|
||||
* Return value: (transfer full):
|
||||
* A newly allocated #hb_draw_funcs_t with a reference count of 1. The initial
|
||||
* reference count should be released with hb_draw_funcs_destroy when you are
|
||||
* done using the #hb_draw_funcs_t. This function never returns %NULL. If
|
||||
* memory cannot be allocated, a special singleton #hb_draw_funcs_t object will
|
||||
* be returned.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
hb_draw_funcs_t *
|
||||
hb_draw_funcs_create ()
|
||||
{
|
||||
hb_draw_funcs_t *funcs;
|
||||
if (unlikely (!(funcs = hb_object_create<hb_draw_funcs_t> ())))
|
||||
hb_draw_funcs_t *dfuncs;
|
||||
if (unlikely (!(dfuncs = hb_object_create<hb_draw_funcs_t> ())))
|
||||
return const_cast<hb_draw_funcs_t *> (&Null (hb_draw_funcs_t));
|
||||
|
||||
funcs->move_to = (hb_draw_move_to_func_t) _move_to_nil;
|
||||
funcs->line_to = (hb_draw_line_to_func_t) _line_to_nil;
|
||||
funcs->quadratic_to = (hb_draw_quadratic_to_func_t) _quadratic_to_nil;
|
||||
funcs->is_quadratic_to_set = false;
|
||||
funcs->cubic_to = (hb_draw_cubic_to_func_t) _cubic_to_nil;
|
||||
funcs->close_path = (hb_draw_close_path_func_t) _close_path_nil;
|
||||
return funcs;
|
||||
dfuncs->func = Null (hb_draw_funcs_t).func;
|
||||
|
||||
return dfuncs;
|
||||
}
|
||||
|
||||
DEFINE_NULL_INSTANCE (hb_draw_funcs_t) =
|
||||
{
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
|
||||
{
|
||||
#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_nil,
|
||||
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_DRAW_FUNC_IMPLEMENT
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_reference:
|
||||
* @funcs: draw functions
|
||||
* hb_draw_funcs_reference: (skip)
|
||||
* @dfuncs: draw functions
|
||||
*
|
||||
* Add to callbacks object refcount.
|
||||
* Increases the reference count on @dfuncs by one. This prevents @buffer from
|
||||
* being destroyed until a matching call to hb_draw_funcs_destroy() is made.
|
||||
*
|
||||
* Returns: The same object.
|
||||
* Since: EXPERIMENTAL
|
||||
* Return value: (transfer full):
|
||||
* The referenced #hb_draw_funcs_t.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
hb_draw_funcs_t *
|
||||
hb_draw_funcs_reference (hb_draw_funcs_t *funcs)
|
||||
hb_draw_funcs_reference (hb_draw_funcs_t *dfuncs)
|
||||
{
|
||||
return hb_object_reference (funcs);
|
||||
return hb_object_reference (dfuncs);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_destroy:
|
||||
* @funcs: draw functions
|
||||
* hb_draw_funcs_destroy: (skip)
|
||||
* @dfuncs: draw functions
|
||||
*
|
||||
* Decreases refcount of callbacks object and deletes the object if it reaches
|
||||
* to zero.
|
||||
* Deallocate the @dfuncs.
|
||||
* Decreases the reference count on @dfuncs by one. If the result is zero, then
|
||||
* @dfuncs and all associated resources are freed. See hb_draw_funcs_reference().
|
||||
*
|
||||
* Since: EXPERIMENTAL
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
void
|
||||
hb_draw_funcs_destroy (hb_draw_funcs_t *funcs)
|
||||
hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs)
|
||||
{
|
||||
if (!hb_object_destroy (funcs)) return;
|
||||
if (!hb_object_destroy (dfuncs)) return;
|
||||
|
||||
hb_free (funcs);
|
||||
#define HB_DRAW_FUNC_IMPLEMENT(name) \
|
||||
if (dfuncs->destroy.name) dfuncs->destroy.name (dfuncs->user_data.name);
|
||||
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_DRAW_FUNC_IMPLEMENT
|
||||
|
||||
|
||||
hb_free (dfuncs);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_make_immutable:
|
||||
* @funcs: draw functions
|
||||
* @dfuncs: draw functions
|
||||
*
|
||||
* Makes funcs object immutable.
|
||||
* Makes @dfuncs object immutable.
|
||||
*
|
||||
* Since: EXPERIMENTAL
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
void
|
||||
hb_draw_funcs_make_immutable (hb_draw_funcs_t *funcs)
|
||||
hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs)
|
||||
{
|
||||
if (hb_object_is_immutable (funcs))
|
||||
if (hb_object_is_immutable (dfuncs))
|
||||
return;
|
||||
|
||||
hb_object_make_immutable (funcs);
|
||||
hb_object_make_immutable (dfuncs);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_is_immutable:
|
||||
* @funcs: draw functions
|
||||
* @dfuncs: draw functions
|
||||
*
|
||||
* Checks whether funcs is immutable.
|
||||
* Checks whether @dfuncs is immutable.
|
||||
*
|
||||
* Returns: If is immutable.
|
||||
* Since: EXPERIMENTAL
|
||||
* Return value: %true if @dfuncs is immutable, %false otherwise
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_draw_funcs_is_immutable (hb_draw_funcs_t *funcs)
|
||||
hb_draw_funcs_is_immutable (hb_draw_funcs_t *dfuncs)
|
||||
{
|
||||
return hb_object_is_immutable (funcs);
|
||||
return hb_object_is_immutable (dfuncs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_draw_move_to:
|
||||
* @dfuncs: draw functions
|
||||
* @draw_data: associated draw data passed by the caller
|
||||
* @st: current draw state
|
||||
* @to_x: X component of target point
|
||||
* @to_y: Y component of target point
|
||||
*
|
||||
* Perform a "move-to" draw operation.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
void
|
||||
hb_draw_move_to (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float to_x, float to_y)
|
||||
{
|
||||
dfuncs->move_to (draw_data, *st,
|
||||
to_x, to_y);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_font_draw_glyph:
|
||||
* @font: a font object
|
||||
* @glyph: a glyph id
|
||||
* @funcs: draw callbacks object
|
||||
* @user_data: parameter you like be passed to the callbacks when are called
|
||||
* hb_draw_line_to:
|
||||
* @dfuncs: draw functions
|
||||
* @draw_data: associated draw data passed by the caller
|
||||
* @st: current draw state
|
||||
* @to_x: X component of target point
|
||||
* @to_y: Y component of target point
|
||||
*
|
||||
* Draw a glyph.
|
||||
* Perform a "line-to" draw operation.
|
||||
*
|
||||
* Returns: Whether the font had the glyph and the operation completed successfully.
|
||||
* Since: EXPERIMENTAL
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph,
|
||||
const hb_draw_funcs_t *funcs,
|
||||
void *user_data)
|
||||
void
|
||||
hb_draw_line_to (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float to_x, float to_y)
|
||||
{
|
||||
if (unlikely (funcs == &Null (hb_draw_funcs_t) ||
|
||||
glyph >= font->face->get_num_glyphs ()))
|
||||
return false;
|
||||
|
||||
draw_helper_t draw_helper (funcs, user_data);
|
||||
if (font->face->table.glyf->get_path (font, glyph, draw_helper)) return true;
|
||||
#ifndef HB_NO_CFF
|
||||
if (font->face->table.cff1->get_path (font, glyph, draw_helper)) return true;
|
||||
if (font->face->table.cff2->get_path (font, glyph, draw_helper)) return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
dfuncs->line_to (draw_data, *st,
|
||||
to_x, to_y);
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* hb_draw_quadratic_to:
|
||||
* @dfuncs: draw functions
|
||||
* @draw_data: associated draw data passed by the caller
|
||||
* @st: current draw state
|
||||
* @control_x: X component of control point
|
||||
* @control_y: Y component of control point
|
||||
* @to_x: X component of target point
|
||||
* @to_y: Y component of target point
|
||||
*
|
||||
* Perform a "quadratic-to" draw operation.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
void
|
||||
hb_draw_quadratic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float control_x, float control_y,
|
||||
float to_x, float to_y)
|
||||
{
|
||||
dfuncs->quadratic_to (draw_data, *st,
|
||||
control_x, control_y,
|
||||
to_x, to_y);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_draw_cubic_to:
|
||||
* @dfuncs: draw functions
|
||||
* @draw_data: associated draw data passed by the caller
|
||||
* @st: current draw state
|
||||
* @control1_x: X component of first control point
|
||||
* @control1_y: Y component of first control point
|
||||
* @control2_x: X component of second control point
|
||||
* @control2_y: Y component of second control point
|
||||
* @to_x: X component of target point
|
||||
* @to_y: Y component of target point
|
||||
*
|
||||
* Perform a "cubic-to" draw operation.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
void
|
||||
hb_draw_cubic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float control1_x, float control1_y,
|
||||
float control2_x, float control2_y,
|
||||
float to_x, float to_y)
|
||||
{
|
||||
dfuncs->cubic_to (draw_data, *st,
|
||||
control1_x, control1_y,
|
||||
control2_x, control2_y,
|
||||
to_x, to_y);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_draw_close_path:
|
||||
* @dfuncs: draw functions
|
||||
* @draw_data: associated draw data passed by the caller
|
||||
* @st: current draw state
|
||||
*
|
||||
* Perform a "close-path" draw operation.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
void
|
||||
hb_draw_close_path (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st)
|
||||
{
|
||||
dfuncs->close_path (draw_data, *st);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,65 +33,292 @@
|
|||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
typedef void (*hb_draw_move_to_func_t) (hb_position_t to_x, hb_position_t to_y, void *user_data);
|
||||
typedef void (*hb_draw_line_to_func_t) (hb_position_t to_x, hb_position_t to_y, void *user_data);
|
||||
typedef void (*hb_draw_quadratic_to_func_t) (hb_position_t control_x, hb_position_t control_y,
|
||||
hb_position_t to_x, hb_position_t to_y,
|
||||
void *user_data);
|
||||
typedef void (*hb_draw_cubic_to_func_t) (hb_position_t control1_x, hb_position_t control1_y,
|
||||
hb_position_t control2_x, hb_position_t control2_y,
|
||||
hb_position_t to_x, hb_position_t to_y,
|
||||
void *user_data);
|
||||
typedef void (*hb_draw_close_path_func_t) (void *user_data);
|
||||
|
||||
/**
|
||||
* hb_draw_state_t
|
||||
* @path_open: Whether there is an open path
|
||||
* @path_start_x: X component of the start of current path
|
||||
* @path_start_y: Y component of the start of current path
|
||||
* @current_x: X component of current point
|
||||
* @current_y: Y component of current point
|
||||
*
|
||||
* Current drawing state.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
typedef struct hb_draw_state_t {
|
||||
hb_bool_t path_open;
|
||||
|
||||
float path_start_x;
|
||||
float path_start_y;
|
||||
|
||||
float current_x;
|
||||
float current_y;
|
||||
|
||||
/*< private >*/
|
||||
hb_var_num_t reserved1;
|
||||
hb_var_num_t reserved2;
|
||||
hb_var_num_t reserved3;
|
||||
hb_var_num_t reserved4;
|
||||
hb_var_num_t reserved5;
|
||||
hb_var_num_t reserved6;
|
||||
hb_var_num_t reserved7;
|
||||
} hb_draw_state_t;
|
||||
|
||||
/**
|
||||
* HB_DRAW_STATE_DEFAULT:
|
||||
*
|
||||
* The default #hb_draw_state_t at the start of glyph drawing.
|
||||
*/
|
||||
#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}}
|
||||
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_t:
|
||||
*
|
||||
* Glyph draw callbacks.
|
||||
*
|
||||
* _move_to, _line_to and _cubic_to calls are necessary to be defined but we
|
||||
* translate _quadratic_to calls to _cubic_to if the callback isn't defined.
|
||||
* #hb_draw_move_to_func_t, #hb_draw_line_to_func_t and
|
||||
* #hb_draw_cubic_to_func_t calls are necessary to be defined but we translate
|
||||
* #hb_draw_quadratic_to_func_t calls to #hb_draw_cubic_to_func_t if the
|
||||
* callback isn't defined.
|
||||
*
|
||||
* Since: EXPERIMENTAL
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
|
||||
typedef struct hb_draw_funcs_t hb_draw_funcs_t;
|
||||
|
||||
HB_EXTERN void
|
||||
hb_draw_funcs_set_move_to_func (hb_draw_funcs_t *funcs,
|
||||
hb_draw_move_to_func_t move_to);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_draw_funcs_set_line_to_func (hb_draw_funcs_t *funcs,
|
||||
hb_draw_line_to_func_t line_to);
|
||||
/**
|
||||
* hb_draw_move_to_func_t:
|
||||
* @dfuncs: draw functions object
|
||||
* @draw_data: The data accompanying the draw functions
|
||||
* @st: current draw state
|
||||
* @to_x: X component of target point
|
||||
* @to_y: Y component of target point
|
||||
* @user_data: User data pointer passed by the caller
|
||||
*
|
||||
* A virtual method for the #hb_draw_funcs_t to perform a "move-to" draw
|
||||
* operation.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
*
|
||||
**/
|
||||
typedef void (*hb_draw_move_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float to_x, float to_y,
|
||||
void *user_data);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t *funcs,
|
||||
hb_draw_quadratic_to_func_t quadratic_to);
|
||||
/**
|
||||
* hb_draw_line_to_func_t:
|
||||
* @dfuncs: draw functions object
|
||||
* @draw_data: The data accompanying the draw functions
|
||||
* @st: current draw state
|
||||
* @to_x: X component of target point
|
||||
* @to_y: Y component of target point
|
||||
* @user_data: User data pointer passed by the caller
|
||||
*
|
||||
* A virtual method for the #hb_draw_funcs_t to perform a "line-to" draw
|
||||
* operation.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
*
|
||||
**/
|
||||
typedef void (*hb_draw_line_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float to_x, float to_y,
|
||||
void *user_data);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t *funcs,
|
||||
hb_draw_cubic_to_func_t cubic_to);
|
||||
/**
|
||||
* hb_draw_quadratic_to_func_t:
|
||||
* @dfuncs: draw functions object
|
||||
* @draw_data: The data accompanying the draw functions
|
||||
* @st: current draw state
|
||||
* @control_x: X component of control point
|
||||
* @control_y: Y component of control point
|
||||
* @to_x: X component of target point
|
||||
* @to_y: Y component of target point
|
||||
* @user_data: User data pointer passed by the caller
|
||||
*
|
||||
* A virtual method for the #hb_draw_funcs_t to perform a "quadratic-to" draw
|
||||
* operation.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
*
|
||||
**/
|
||||
typedef void (*hb_draw_quadratic_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float control_x, float control_y,
|
||||
float to_x, float to_y,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* hb_draw_cubic_to_func_t:
|
||||
* @dfuncs: draw functions object
|
||||
* @draw_data: The data accompanying the draw functions
|
||||
* @st: current draw state
|
||||
* @control1_x: X component of first control point
|
||||
* @control1_y: Y component of first control point
|
||||
* @control2_x: X component of second control point
|
||||
* @control2_y: Y component of second control point
|
||||
* @to_x: X component of target point
|
||||
* @to_y: Y component of target point
|
||||
* @user_data: User data pointer passed by the caller
|
||||
*
|
||||
* A virtual method for the #hb_draw_funcs_t to perform a "cubic-to" draw
|
||||
* operation.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
*
|
||||
**/
|
||||
typedef void (*hb_draw_cubic_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float control1_x, float control1_y,
|
||||
float control2_x, float control2_y,
|
||||
float to_x, float to_y,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* hb_draw_close_path_func_t:
|
||||
* @dfuncs: draw functions object
|
||||
* @draw_data: The data accompanying the draw functions
|
||||
* @st: current draw state
|
||||
* @user_data: User data pointer passed by the caller
|
||||
*
|
||||
* A virtual method for the #hb_draw_funcs_t to perform a "close-path" draw
|
||||
* operation.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
*
|
||||
**/
|
||||
typedef void (*hb_draw_close_path_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_set_move_to_func:
|
||||
* @dfuncs: draw functions object
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified): move-to callback
|
||||
* @user_data: Data to pass to @func
|
||||
* @destroy: (nullable): The function to call when @user_data is not needed anymore
|
||||
*
|
||||
* Sets move-to callback to the draw functions object.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_draw_funcs_set_close_path_func (hb_draw_funcs_t *funcs,
|
||||
hb_draw_close_path_func_t close_path);
|
||||
hb_draw_funcs_set_move_to_func (hb_draw_funcs_t *dfuncs,
|
||||
hb_draw_move_to_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_set_line_to_func:
|
||||
* @dfuncs: draw functions object
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified): line-to callback
|
||||
* @user_data: Data to pass to @func
|
||||
* @destroy: (nullable): The function to call when @user_data is not needed anymore
|
||||
*
|
||||
* Sets line-to callback to the draw functions object.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_draw_funcs_set_line_to_func (hb_draw_funcs_t *dfuncs,
|
||||
hb_draw_line_to_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_set_quadratic_to_func:
|
||||
* @dfuncs: draw functions object
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified): quadratic-to callback
|
||||
* @user_data: Data to pass to @func
|
||||
* @destroy: (nullable): The function to call when @user_data is not needed anymore
|
||||
*
|
||||
* Sets quadratic-to callback to the draw functions object.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t *dfuncs,
|
||||
hb_draw_quadratic_to_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_set_cubic_to_func:
|
||||
* @dfuncs: draw functions
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified): cubic-to callback
|
||||
* @user_data: Data to pass to @func
|
||||
* @destroy: (nullable): The function to call when @user_data is not needed anymore
|
||||
*
|
||||
* Sets cubic-to callback to the draw functions object.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t *dfuncs,
|
||||
hb_draw_cubic_to_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_draw_funcs_set_close_path_func:
|
||||
* @dfuncs: draw functions object
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified): close-path callback
|
||||
* @user_data: Data to pass to @func
|
||||
* @destroy: (nullable): The function to call when @user_data is not needed anymore
|
||||
*
|
||||
* Sets close-path callback to the draw functions object.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_draw_funcs_set_close_path_func (hb_draw_funcs_t *dfuncs,
|
||||
hb_draw_close_path_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
|
||||
HB_EXTERN hb_draw_funcs_t *
|
||||
hb_draw_funcs_create (void);
|
||||
|
||||
HB_EXTERN hb_draw_funcs_t *
|
||||
hb_draw_funcs_reference (hb_draw_funcs_t *funcs);
|
||||
hb_draw_funcs_reference (hb_draw_funcs_t *dfuncs);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_draw_funcs_destroy (hb_draw_funcs_t *funcs);
|
||||
hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_draw_funcs_make_immutable (hb_draw_funcs_t *funcs);
|
||||
hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_draw_funcs_is_immutable (hb_draw_funcs_t *funcs);
|
||||
#endif
|
||||
hb_draw_funcs_is_immutable (hb_draw_funcs_t *dfuncs);
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_draw_move_to (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float to_x, float to_y);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_draw_line_to (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float to_x, float to_y);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_draw_quadratic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float control_x, float control_y,
|
||||
float to_x, float to_y);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_draw_cubic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float control1_x, float control1_y,
|
||||
float control2_x, float control2_y,
|
||||
float to_x, float to_y);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_draw_close_path (hb_draw_funcs_t *dfuncs, void *draw_data,
|
||||
hb_draw_state_t *st);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
|
|
|
@ -27,113 +27,205 @@
|
|||
|
||||
#include "hb.hh"
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
|
||||
/*
|
||||
* hb_draw_funcs_t
|
||||
*/
|
||||
|
||||
#define HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS \
|
||||
HB_DRAW_FUNC_IMPLEMENT (move_to) \
|
||||
HB_DRAW_FUNC_IMPLEMENT (line_to) \
|
||||
HB_DRAW_FUNC_IMPLEMENT (quadratic_to) \
|
||||
HB_DRAW_FUNC_IMPLEMENT (cubic_to) \
|
||||
HB_DRAW_FUNC_IMPLEMENT (close_path) \
|
||||
/* ^--- Add new callbacks here */
|
||||
|
||||
struct hb_draw_funcs_t
|
||||
{
|
||||
hb_object_header_t header;
|
||||
|
||||
hb_draw_move_to_func_t move_to;
|
||||
hb_draw_line_to_func_t line_to;
|
||||
hb_draw_quadratic_to_func_t quadratic_to;
|
||||
bool is_quadratic_to_set;
|
||||
hb_draw_cubic_to_func_t cubic_to;
|
||||
hb_draw_close_path_func_t close_path;
|
||||
};
|
||||
struct {
|
||||
#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_func_t name;
|
||||
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_DRAW_FUNC_IMPLEMENT
|
||||
} func;
|
||||
|
||||
struct draw_helper_t
|
||||
{
|
||||
draw_helper_t (const hb_draw_funcs_t *funcs_, void *user_data_)
|
||||
{
|
||||
funcs = funcs_;
|
||||
user_data = user_data_;
|
||||
path_open = false;
|
||||
path_start_x = current_x = path_start_y = current_y = 0;
|
||||
}
|
||||
~draw_helper_t () { end_path (); }
|
||||
struct {
|
||||
#define HB_DRAW_FUNC_IMPLEMENT(name) void *name;
|
||||
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_DRAW_FUNC_IMPLEMENT
|
||||
} user_data;
|
||||
|
||||
void move_to (hb_position_t x, hb_position_t y)
|
||||
struct {
|
||||
#define HB_DRAW_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
|
||||
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_DRAW_FUNC_IMPLEMENT
|
||||
} destroy;
|
||||
|
||||
void emit_move_to (void *draw_data, hb_draw_state_t &st,
|
||||
float to_x, float to_y)
|
||||
{ func.move_to (this, draw_data, &st,
|
||||
to_x, to_y,
|
||||
user_data.move_to); }
|
||||
void emit_line_to (void *draw_data, hb_draw_state_t &st,
|
||||
float to_x, float to_y)
|
||||
{ func.line_to (this, draw_data, &st,
|
||||
to_x, to_y,
|
||||
user_data.line_to); }
|
||||
void emit_quadratic_to (void *draw_data, hb_draw_state_t &st,
|
||||
float control_x, float control_y,
|
||||
float to_x, float to_y)
|
||||
{ func.quadratic_to (this, draw_data, &st,
|
||||
control_x, control_y,
|
||||
to_x, to_y,
|
||||
user_data.quadratic_to); }
|
||||
void emit_cubic_to (void *draw_data, hb_draw_state_t &st,
|
||||
float control1_x, float control1_y,
|
||||
float control2_x, float control2_y,
|
||||
float to_x, float to_y)
|
||||
{ func.cubic_to (this, draw_data, &st,
|
||||
control1_x, control1_y,
|
||||
control2_x, control2_y,
|
||||
to_x, to_y,
|
||||
user_data.cubic_to); }
|
||||
void emit_close_path (void *draw_data, hb_draw_state_t &st)
|
||||
{ func.close_path (this, draw_data, &st,
|
||||
user_data.close_path); }
|
||||
|
||||
|
||||
void move_to (void *draw_data, hb_draw_state_t &st,
|
||||
float to_x, float to_y)
|
||||
{
|
||||
if (path_open) end_path ();
|
||||
current_x = path_start_x = x;
|
||||
current_y = path_start_y = y;
|
||||
if (st.path_open) close_path (draw_data, st);
|
||||
st.current_x = to_x;
|
||||
st.current_y = to_y;
|
||||
}
|
||||
|
||||
void line_to (hb_position_t x, hb_position_t y)
|
||||
void line_to (void *draw_data, hb_draw_state_t &st,
|
||||
float to_x, float to_y)
|
||||
{
|
||||
if (equal_to_current (x, y)) return;
|
||||
if (!path_open) start_path ();
|
||||
funcs->line_to (x, y, user_data);
|
||||
current_x = x;
|
||||
current_y = y;
|
||||
if (!st.path_open) start_path (draw_data, st);
|
||||
emit_line_to (draw_data, st, to_x, to_y);
|
||||
st.current_x = to_x;
|
||||
st.current_y = to_y;
|
||||
}
|
||||
|
||||
void
|
||||
quadratic_to (hb_position_t control_x, hb_position_t control_y,
|
||||
hb_position_t to_x, hb_position_t to_y)
|
||||
quadratic_to (void *draw_data, hb_draw_state_t &st,
|
||||
float control_x, float control_y,
|
||||
float to_x, float to_y)
|
||||
{
|
||||
if (equal_to_current (control_x, control_y) && equal_to_current (to_x, to_y))
|
||||
return;
|
||||
if (!path_open) start_path ();
|
||||
if (funcs->is_quadratic_to_set)
|
||||
funcs->quadratic_to (control_x, control_y, to_x, to_y, user_data);
|
||||
else
|
||||
funcs->cubic_to (roundf ((current_x + 2.f * control_x) / 3.f),
|
||||
roundf ((current_y + 2.f * control_y) / 3.f),
|
||||
roundf ((to_x + 2.f * control_x) / 3.f),
|
||||
roundf ((to_y + 2.f * control_y) / 3.f),
|
||||
to_x, to_y, user_data);
|
||||
current_x = to_x;
|
||||
current_y = to_y;
|
||||
if (!st.path_open) start_path (draw_data, st);
|
||||
emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y);
|
||||
st.current_x = to_x;
|
||||
st.current_y = to_y;
|
||||
}
|
||||
|
||||
void
|
||||
cubic_to (hb_position_t control1_x, hb_position_t control1_y,
|
||||
hb_position_t control2_x, hb_position_t control2_y,
|
||||
hb_position_t to_x, hb_position_t to_y)
|
||||
cubic_to (void *draw_data, hb_draw_state_t &st,
|
||||
float control1_x, float control1_y,
|
||||
float control2_x, float control2_y,
|
||||
float to_x, float to_y)
|
||||
{
|
||||
if (equal_to_current (control1_x, control1_y) &&
|
||||
equal_to_current (control2_x, control2_y) &&
|
||||
equal_to_current (to_x, to_y))
|
||||
return;
|
||||
if (!path_open) start_path ();
|
||||
funcs->cubic_to (control1_x, control1_y, control2_x, control2_y, to_x, to_y, user_data);
|
||||
current_x = to_x;
|
||||
current_y = to_y;
|
||||
if (!st.path_open) start_path (draw_data, st);
|
||||
emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y);
|
||||
st.current_x = to_x;
|
||||
st.current_y = to_y;
|
||||
}
|
||||
|
||||
void end_path ()
|
||||
void
|
||||
close_path (void *draw_data, hb_draw_state_t &st)
|
||||
{
|
||||
if (path_open)
|
||||
if (st.path_open)
|
||||
{
|
||||
if ((path_start_x != current_x) || (path_start_y != current_y))
|
||||
funcs->line_to (path_start_x, path_start_y, user_data);
|
||||
funcs->close_path (user_data);
|
||||
if ((st.path_start_x != st.current_x) || (st.path_start_y != st.current_y))
|
||||
emit_line_to (draw_data, st, st.path_start_x, st.path_start_y);
|
||||
emit_close_path (draw_data, st);
|
||||
}
|
||||
path_open = false;
|
||||
path_start_x = current_x = path_start_y = current_y = 0;
|
||||
st.path_open = false;
|
||||
st.path_start_x = st.current_x = st.path_start_y = st.current_y = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool equal_to_current (hb_position_t x, hb_position_t y)
|
||||
{ return current_x == x && current_y == y; }
|
||||
|
||||
void start_path ()
|
||||
void start_path (void *draw_data, hb_draw_state_t &st)
|
||||
{
|
||||
if (path_open) end_path ();
|
||||
path_open = true;
|
||||
funcs->move_to (path_start_x, path_start_y, user_data);
|
||||
assert (!st.path_open);
|
||||
emit_move_to (draw_data, st, st.current_x, st.current_y);
|
||||
st.path_open = true;
|
||||
st.path_start_x = st.current_x;
|
||||
st.path_start_y = st.current_y;
|
||||
}
|
||||
};
|
||||
DECLARE_NULL_INSTANCE (hb_draw_funcs_t);
|
||||
|
||||
struct hb_draw_session_t
|
||||
{
|
||||
hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_, float slant_ = 0.f)
|
||||
: slant {slant_}, not_slanted {slant == 0.f},
|
||||
funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT
|
||||
{}
|
||||
|
||||
~hb_draw_session_t () { close_path (); }
|
||||
|
||||
void move_to (float to_x, float to_y)
|
||||
{
|
||||
if (likely (not_slanted))
|
||||
funcs->move_to (draw_data, st,
|
||||
to_x, to_y);
|
||||
else
|
||||
funcs->move_to (draw_data, st,
|
||||
to_x + to_y * slant, to_y);
|
||||
}
|
||||
void line_to (float to_x, float to_y)
|
||||
{
|
||||
if (likely (not_slanted))
|
||||
funcs->line_to (draw_data, st,
|
||||
to_x, to_y);
|
||||
else
|
||||
funcs->line_to (draw_data, st,
|
||||
to_x + to_y * slant, to_y);
|
||||
}
|
||||
void
|
||||
quadratic_to (float control_x, float control_y,
|
||||
float to_x, float to_y)
|
||||
{
|
||||
if (likely (not_slanted))
|
||||
funcs->quadratic_to (draw_data, st,
|
||||
control_x, control_y,
|
||||
to_x, to_y);
|
||||
else
|
||||
funcs->quadratic_to (draw_data, st,
|
||||
control_x + control_y * slant, control_y,
|
||||
to_x + to_y * slant, to_y);
|
||||
}
|
||||
void
|
||||
cubic_to (float control1_x, float control1_y,
|
||||
float control2_x, float control2_y,
|
||||
float to_x, float to_y)
|
||||
{
|
||||
if (likely (not_slanted))
|
||||
funcs->cubic_to (draw_data, st,
|
||||
control1_x, control1_y,
|
||||
control2_x, control2_y,
|
||||
to_x, to_y);
|
||||
else
|
||||
funcs->cubic_to (draw_data, st,
|
||||
control1_x + control1_y * slant, control1_y,
|
||||
control2_x + control2_y * slant, control2_y,
|
||||
to_x + to_y * slant, to_y);
|
||||
}
|
||||
void close_path ()
|
||||
{
|
||||
funcs->close_path (draw_data, st);
|
||||
}
|
||||
|
||||
hb_position_t path_start_x;
|
||||
hb_position_t path_start_y;
|
||||
|
||||
hb_position_t current_x;
|
||||
hb_position_t current_y;
|
||||
|
||||
bool path_open;
|
||||
const hb_draw_funcs_t *funcs;
|
||||
void *user_data;
|
||||
protected:
|
||||
float slant;
|
||||
bool not_slanted;
|
||||
hb_draw_funcs_t *funcs;
|
||||
void *draw_data;
|
||||
hb_draw_state_t st;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* HB_DRAW_HH */
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "hb.hh"
|
||||
|
||||
#include "hb-font.hh"
|
||||
#include "hb-draw.hh"
|
||||
#include "hb-machinery.hh"
|
||||
|
||||
#include "hb-ot.h"
|
||||
|
@ -501,6 +502,136 @@ hb_font_get_glyph_from_name_default (hb_font_t *font,
|
|||
return font->parent->get_glyph_from_name (name, len, glyph);
|
||||
}
|
||||
|
||||
static void
|
||||
hb_font_get_glyph_shape_nil (hb_font_t *font HB_UNUSED,
|
||||
void *font_data HB_UNUSED,
|
||||
hb_codepoint_t glyph,
|
||||
hb_draw_funcs_t *draw_funcs,
|
||||
void *draw_data,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
typedef struct hb_font_get_glyph_shape_default_adaptor_t {
|
||||
hb_draw_funcs_t *draw_funcs;
|
||||
void *draw_data;
|
||||
float x_scale;
|
||||
float y_scale;
|
||||
} hb_font_get_glyph_shape_default_adaptor_t;
|
||||
|
||||
static void
|
||||
hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED,
|
||||
void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float to_x, float to_y,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
|
||||
float x_scale = adaptor->x_scale;
|
||||
float y_scale = adaptor->y_scale;
|
||||
|
||||
adaptor->draw_funcs->emit_move_to (adaptor->draw_data, *st,
|
||||
x_scale * to_x, y_scale * to_y);
|
||||
}
|
||||
|
||||
static void
|
||||
hb_draw_line_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float to_x, float to_y,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
|
||||
float x_scale = adaptor->x_scale;
|
||||
float y_scale = adaptor->y_scale;
|
||||
|
||||
st->current_x *= x_scale;
|
||||
st->current_y *= y_scale;
|
||||
|
||||
adaptor->draw_funcs->emit_line_to (adaptor->draw_data, *st,
|
||||
x_scale * to_x, y_scale * to_y);
|
||||
}
|
||||
|
||||
static void
|
||||
hb_draw_quadratic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float control_x, float control_y,
|
||||
float to_x, float to_y,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
|
||||
float x_scale = adaptor->x_scale;
|
||||
float y_scale = adaptor->y_scale;
|
||||
|
||||
st->current_x *= x_scale;
|
||||
st->current_y *= y_scale;
|
||||
|
||||
adaptor->draw_funcs->emit_quadratic_to (adaptor->draw_data, *st,
|
||||
x_scale * control_x, y_scale * control_y,
|
||||
x_scale * to_x, y_scale * to_y);
|
||||
}
|
||||
|
||||
static void
|
||||
hb_draw_cubic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float control1_x, float control1_y,
|
||||
float control2_x, float control2_y,
|
||||
float to_x, float to_y,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
|
||||
float x_scale = adaptor->x_scale;
|
||||
float y_scale = adaptor->y_scale;
|
||||
|
||||
st->current_x *= x_scale;
|
||||
st->current_y *= y_scale;
|
||||
|
||||
adaptor->draw_funcs->emit_cubic_to (adaptor->draw_data, *st,
|
||||
x_scale * control1_x, y_scale * control1_y,
|
||||
x_scale * control2_x, y_scale * control2_y,
|
||||
x_scale * to_x, y_scale * to_y);
|
||||
}
|
||||
|
||||
static void
|
||||
hb_draw_close_path_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
|
||||
|
||||
adaptor->draw_funcs->emit_close_path (adaptor->draw_data, *st);
|
||||
}
|
||||
|
||||
static const hb_draw_funcs_t _hb_draw_funcs_default = {
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
|
||||
{
|
||||
#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_default,
|
||||
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_DRAW_FUNC_IMPLEMENT
|
||||
}
|
||||
};
|
||||
|
||||
static void
|
||||
hb_font_get_glyph_shape_default (hb_font_t *font,
|
||||
void *font_data HB_UNUSED,
|
||||
hb_codepoint_t glyph,
|
||||
hb_draw_funcs_t *draw_funcs,
|
||||
void *draw_data,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
hb_font_get_glyph_shape_default_adaptor_t adaptor = {
|
||||
draw_funcs,
|
||||
draw_data,
|
||||
(float) font->x_scale / (float) font->parent->x_scale,
|
||||
(float) font->y_scale / (float) font->parent->y_scale
|
||||
};
|
||||
|
||||
font->parent->get_glyph_shape (glyph,
|
||||
const_cast<hb_draw_funcs_t *> (&_hb_draw_funcs_default),
|
||||
&adaptor);
|
||||
}
|
||||
|
||||
DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
|
||||
{
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
|
@ -1168,6 +1299,26 @@ hb_font_get_glyph_from_name (hb_font_t *font,
|
|||
return font->get_glyph_from_name (name, len, glyph);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_font_get_glyph_shape:
|
||||
* @font: #hb_font_t to work upon
|
||||
* @glyph: : The glyph ID
|
||||
* @dfuncs: #hb_draw_funcs_t to draw to
|
||||
* @draw_data: User data to pass to draw callbacks
|
||||
*
|
||||
* Fetches the glyph shape that corresponds to a glyph in the specified @font.
|
||||
* The shape is returned by way of calls to the callsbacks of the @dfuncs
|
||||
* objects, with @draw_data passed to them.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
void
|
||||
hb_font_get_glyph_shape (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_draw_funcs_t *dfuncs, void *draw_data)
|
||||
{
|
||||
font->get_glyph_shape (glyph, dfuncs, draw_data);
|
||||
}
|
||||
|
||||
/* A bit higher-level, and with fallback */
|
||||
|
||||
|
@ -1190,7 +1341,7 @@ hb_font_get_extents_for_direction (hb_font_t *font,
|
|||
hb_direction_t direction,
|
||||
hb_font_extents_t *extents)
|
||||
{
|
||||
return font->get_extents_for_direction (direction, extents);
|
||||
font->get_extents_for_direction (direction, extents);
|
||||
}
|
||||
/**
|
||||
* hb_font_get_glyph_advance_for_direction:
|
||||
|
@ -1215,7 +1366,7 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
|
|||
hb_position_t *x,
|
||||
hb_position_t *y)
|
||||
{
|
||||
return font->get_glyph_advance_for_direction (glyph, direction, x, y);
|
||||
font->get_glyph_advance_for_direction (glyph, direction, x, y);
|
||||
}
|
||||
/**
|
||||
* hb_font_get_glyph_advances_for_direction:
|
||||
|
@ -2044,12 +2195,16 @@ hb_font_get_ptem (hb_font_t *font)
|
|||
* @slant: synthetic slant value.
|
||||
*
|
||||
* Sets the "synthetic slant" of a font. By default is zero.
|
||||
* Synthetic slant is the graphical skew that the renderer
|
||||
* applies to the font at rendering time.
|
||||
* Synthetic slant is the graphical skew applied to the font
|
||||
* at rendering time.
|
||||
*
|
||||
* HarfBuzz needs to know this value to adjust shaping results,
|
||||
* metrics, and style values to match the slanted rendering.
|
||||
*
|
||||
* <note>Note: The glyph shape fetched via the
|
||||
* hb_font_get_glyph_shape() is slanted to reflect this value
|
||||
* as well.</note>
|
||||
*
|
||||
* <note>Note: The slant value is a ratio. For example, a
|
||||
* 20% slant would be represented as a 0.2 value.</note>
|
||||
*
|
||||
|
|
|
@ -511,6 +511,25 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *
|
|||
hb_codepoint_t *glyph,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* hb_font_get_glyph_shape_func_t:
|
||||
* @font: #hb_font_t to work upon
|
||||
* @font_data: @font user data pointer
|
||||
* @glyph: The glyph ID to query
|
||||
* @draw_funcs: The draw functions to send the shape data to
|
||||
* @draw_data: The data accompanying the draw functions
|
||||
* @user_data: User data pointer passed by the caller
|
||||
*
|
||||
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
*
|
||||
**/
|
||||
typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
hb_draw_funcs_t *draw_funcs, void *draw_data,
|
||||
void *user_data);
|
||||
|
||||
|
||||
/* func setters */
|
||||
|
||||
|
@ -770,6 +789,22 @@ hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs,
|
|||
hb_font_get_glyph_from_name_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_glyph_shape_func:
|
||||
* @ffuncs: A font-function structure
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
|
||||
* @user_data: Data to pass to @func
|
||||
* @destroy: (nullable): The function to call when @user_data is not needed anymore
|
||||
*
|
||||
* Sets the implementation function for #hb_font_get_glyph_shape_func_t.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_shape_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/* func dispatch */
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
|
@ -850,6 +885,11 @@ hb_font_get_glyph_from_name (hb_font_t *font,
|
|||
const char *name, int len, /* -1 means nul-terminated */
|
||||
hb_codepoint_t *glyph);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_get_glyph_shape (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_draw_funcs_t *dfuncs, void *draw_data);
|
||||
|
||||
|
||||
/* high-level funcs, with fallback */
|
||||
|
||||
|
@ -1056,11 +1096,6 @@ HB_EXTERN void
|
|||
hb_font_set_var_named_instance (hb_font_t *font,
|
||||
unsigned instance_index);
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph,
|
||||
const hb_draw_funcs_t *funcs, void *user_data);
|
||||
#endif
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_name) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_shape) \
|
||||
/* ^--- Add new callbacks here */
|
||||
|
||||
struct hb_font_funcs_t
|
||||
|
@ -140,6 +141,8 @@ struct hb_font_t
|
|||
hb_position_t em_scalef_y (float v) { return em_scalef (v, y_scale); }
|
||||
float em_fscale_x (int16_t v) { return em_fscale (v, x_scale); }
|
||||
float em_fscale_y (int16_t v) { return em_fscale (v, y_scale); }
|
||||
float em_fscalef_x (float v) { return em_fscalef (v, x_scale); }
|
||||
float em_fscalef_y (float v) { return em_fscalef (v, y_scale); }
|
||||
hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
|
||||
{ return em_mult (v, dir_mult (direction)); }
|
||||
|
||||
|
@ -373,6 +376,15 @@ struct hb_font_t
|
|||
klass->user_data.glyph_from_name);
|
||||
}
|
||||
|
||||
void get_glyph_shape (hb_codepoint_t glyph,
|
||||
hb_draw_funcs_t *draw_funcs, void *draw_data)
|
||||
{
|
||||
klass->get.f.glyph_shape (this, user_data,
|
||||
glyph,
|
||||
draw_funcs, draw_data,
|
||||
klass->user_data.glyph_shape);
|
||||
}
|
||||
|
||||
|
||||
/* A bit higher-level, and with fallback */
|
||||
|
||||
|
@ -625,7 +637,9 @@ struct hb_font_t
|
|||
hb_position_t em_mult (int16_t v, int64_t mult)
|
||||
{ return (hb_position_t) ((v * mult + 32768) >> 16); }
|
||||
hb_position_t em_scalef (float v, int scale)
|
||||
{ return (hb_position_t) roundf (v * scale / face->get_upem ()); }
|
||||
{ return (hb_position_t) roundf (em_fscalef (v, scale)); }
|
||||
float em_fscalef (float v, int scale)
|
||||
{ return v * scale / face->get_upem (); }
|
||||
float em_fscale (int16_t v, int scale)
|
||||
{ return (float) v * scale / face->get_upem (); }
|
||||
};
|
||||
|
|
|
@ -33,12 +33,14 @@
|
|||
|
||||
#include "hb-ft.h"
|
||||
|
||||
#include "hb-draw.hh"
|
||||
#include "hb-font.hh"
|
||||
#include "hb-machinery.hh"
|
||||
#include "hb-cache.hh"
|
||||
|
||||
#include FT_ADVANCES_H
|
||||
#include FT_MULTIPLE_MASTERS_H
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_TRUETYPE_TABLES_H
|
||||
|
||||
|
||||
|
@ -380,6 +382,7 @@ hb_ft_get_glyph_v_advance (hb_font_t *font,
|
|||
|
||||
/* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
|
||||
* have a Y growing upward. Hence the extra negation. */
|
||||
|
||||
return (-v + (1<<9)) >> 10;
|
||||
}
|
||||
#endif
|
||||
|
@ -565,6 +568,82 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED,
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifndef HB_NO_DRAW
|
||||
|
||||
static int
|
||||
_hb_ft_move_to (const FT_Vector *to,
|
||||
hb_draw_session_t *drawing)
|
||||
{
|
||||
drawing->move_to (to->x, to->y);
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
static int
|
||||
_hb_ft_line_to (const FT_Vector *to,
|
||||
hb_draw_session_t *drawing)
|
||||
{
|
||||
drawing->line_to (to->x, to->y);
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
static int
|
||||
_hb_ft_conic_to (const FT_Vector *control,
|
||||
const FT_Vector *to,
|
||||
hb_draw_session_t *drawing)
|
||||
{
|
||||
drawing->quadratic_to (control->x, control->y,
|
||||
to->x, to->y);
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
static int
|
||||
_hb_ft_cubic_to (const FT_Vector *control1,
|
||||
const FT_Vector *control2,
|
||||
const FT_Vector *to,
|
||||
hb_draw_session_t *drawing)
|
||||
{
|
||||
drawing->cubic_to (control1->x, control1->y,
|
||||
control2->x, control2->y,
|
||||
to->x, to->y);
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
static void
|
||||
hb_ft_get_glyph_shape (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
hb_draw_funcs_t *draw_funcs, void *draw_data,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
hb_lock_t lock (ft_font->lock);
|
||||
FT_Face ft_face = ft_font->ft_face;
|
||||
|
||||
if (unlikely (FT_Load_Glyph (ft_face, glyph,
|
||||
FT_LOAD_NO_BITMAP | ft_font->load_flags)))
|
||||
return;
|
||||
|
||||
if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||
return;
|
||||
|
||||
const FT_Outline_Funcs outline_funcs = {
|
||||
(FT_Outline_MoveToFunc) _hb_ft_move_to,
|
||||
(FT_Outline_LineToFunc) _hb_ft_line_to,
|
||||
(FT_Outline_ConicToFunc) _hb_ft_conic_to,
|
||||
(FT_Outline_CubicToFunc) _hb_ft_cubic_to,
|
||||
0, /* shift */
|
||||
0, /* delta */
|
||||
};
|
||||
|
||||
hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy);
|
||||
|
||||
FT_Outline_Decompose (&ft_face->glyph->outline,
|
||||
&outline_funcs,
|
||||
&draw_session);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static inline void free_static_ft_funcs ();
|
||||
|
||||
static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft_font_funcs_lazy_loader_t>
|
||||
|
@ -596,6 +675,10 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft
|
|||
hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_from_name_func (funcs, hb_ft_get_glyph_from_name, nullptr, nullptr);
|
||||
|
||||
#ifndef HB_NO_DRAW
|
||||
hb_font_funcs_set_glyph_shape_func (funcs, hb_ft_get_glyph_shape, nullptr, nullptr);
|
||||
#endif
|
||||
|
||||
hb_font_funcs_make_immutable (funcs);
|
||||
|
||||
hb_atexit (free_static_ft_funcs);
|
||||
|
|
|
@ -90,6 +90,7 @@ hb_gobject_##name##_get_type () \
|
|||
|
||||
HB_DEFINE_OBJECT_TYPE (buffer)
|
||||
HB_DEFINE_OBJECT_TYPE (blob)
|
||||
HB_DEFINE_OBJECT_TYPE (draw_funcs)
|
||||
HB_DEFINE_OBJECT_TYPE (face)
|
||||
HB_DEFINE_OBJECT_TYPE (font)
|
||||
HB_DEFINE_OBJECT_TYPE (font_funcs)
|
||||
|
|
|
@ -48,6 +48,10 @@ HB_EXTERN GType
|
|||
hb_gobject_buffer_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ())
|
||||
|
||||
HB_EXTERN GType
|
||||
hb_gobject_draw_funcs_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_DRAW_FUNCS (hb_gobject_draw_funcs_get_type ())
|
||||
|
||||
HB_EXTERN GType
|
||||
hb_gobject_face_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ())
|
||||
|
|
|
@ -273,14 +273,19 @@ struct hb_face_lazy_loader_t : hb_lazy_loader_t<T,
|
|||
hb_face_lazy_loader_t<T, WheresFace>,
|
||||
hb_face_t, WheresFace> {};
|
||||
|
||||
template <typename T, unsigned int WheresFace>
|
||||
template <typename T, unsigned int WheresFace, bool core=false>
|
||||
struct hb_table_lazy_loader_t : hb_lazy_loader_t<T,
|
||||
hb_table_lazy_loader_t<T, WheresFace>,
|
||||
hb_table_lazy_loader_t<T, WheresFace, core>,
|
||||
hb_face_t, WheresFace,
|
||||
hb_blob_t>
|
||||
{
|
||||
static hb_blob_t *create (hb_face_t *face)
|
||||
{ return hb_sanitize_context_t ().reference_table<T> (face); }
|
||||
{
|
||||
auto c = hb_sanitize_context_t ();
|
||||
if (core)
|
||||
c.set_num_glyphs (0); // So we don't recurse ad infinitum...
|
||||
return c.reference_table<T> (face);
|
||||
}
|
||||
static void destroy (hb_blob_t *p) { hb_blob_destroy (p); }
|
||||
|
||||
static const hb_blob_t *get_null ()
|
||||
|
|
|
@ -442,13 +442,12 @@ bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
struct cff1_path_param_t
|
||||
{
|
||||
cff1_path_param_t (const OT::cff1::accelerator_t *cff_, hb_font_t *font_,
|
||||
draw_helper_t &draw_helper_, point_t *delta_)
|
||||
hb_draw_session_t &draw_session_, point_t *delta_)
|
||||
{
|
||||
draw_helper = &draw_helper_;
|
||||
draw_session = &draw_session_;
|
||||
cff = cff_;
|
||||
font = font_;
|
||||
delta = delta_;
|
||||
|
@ -458,14 +457,14 @@ struct cff1_path_param_t
|
|||
{
|
||||
point_t point = p;
|
||||
if (delta) point.move (*delta);
|
||||
draw_helper->move_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ()));
|
||||
draw_session->move_to (font->em_fscalef_x (point.x.to_real ()), font->em_fscalef_y (point.y.to_real ()));
|
||||
}
|
||||
|
||||
void line_to (const point_t &p)
|
||||
{
|
||||
point_t point = p;
|
||||
if (delta) point.move (*delta);
|
||||
draw_helper->line_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ()));
|
||||
draw_session->line_to (font->em_fscalef_x (point.x.to_real ()), font->em_fscalef_y (point.y.to_real ()));
|
||||
}
|
||||
|
||||
void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3)
|
||||
|
@ -477,15 +476,15 @@ struct cff1_path_param_t
|
|||
point2.move (*delta);
|
||||
point3.move (*delta);
|
||||
}
|
||||
draw_helper->cubic_to (font->em_scalef_x (point1.x.to_real ()), font->em_scalef_y (point1.y.to_real ()),
|
||||
font->em_scalef_x (point2.x.to_real ()), font->em_scalef_y (point2.y.to_real ()),
|
||||
font->em_scalef_x (point3.x.to_real ()), font->em_scalef_y (point3.y.to_real ()));
|
||||
draw_session->cubic_to (font->em_fscalef_x (point1.x.to_real ()), font->em_fscalef_y (point1.y.to_real ()),
|
||||
font->em_fscalef_x (point2.x.to_real ()), font->em_fscalef_y (point2.y.to_real ()),
|
||||
font->em_fscalef_x (point3.x.to_real ()), font->em_fscalef_y (point3.y.to_real ()));
|
||||
}
|
||||
|
||||
void end_path () { draw_helper->end_path (); }
|
||||
void end_path () { draw_session->close_path (); }
|
||||
|
||||
hb_font_t *font;
|
||||
draw_helper_t *draw_helper;
|
||||
hb_draw_session_t *draw_session;
|
||||
point_t *delta;
|
||||
|
||||
const OT::cff1::accelerator_t *cff;
|
||||
|
@ -513,7 +512,7 @@ struct cff1_path_procs_path_t : path_procs_t<cff1_path_procs_path_t, cff1_cs_int
|
|||
};
|
||||
|
||||
static bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph,
|
||||
draw_helper_t &draw_helper, bool in_seac = false, point_t *delta = nullptr);
|
||||
hb_draw_session_t &draw_session, bool in_seac = false, point_t *delta = nullptr);
|
||||
|
||||
struct cff1_cs_opset_path_t : cff1_cs_opset_t<cff1_cs_opset_path_t, cff1_path_param_t, cff1_path_procs_path_t>
|
||||
{
|
||||
|
@ -530,14 +529,14 @@ struct cff1_cs_opset_path_t : cff1_cs_opset_t<cff1_cs_opset_path_t, cff1_path_pa
|
|||
hb_codepoint_t accent = param.cff->std_code_to_glyph (env.argStack[n-1].to_int ());
|
||||
|
||||
if (unlikely (!(!env.in_seac && base && accent
|
||||
&& _get_path (param.cff, param.font, base, *param.draw_helper, true)
|
||||
&& _get_path (param.cff, param.font, accent, *param.draw_helper, true, &delta))))
|
||||
&& _get_path (param.cff, param.font, base, *param.draw_session, true)
|
||||
&& _get_path (param.cff, param.font, accent, *param.draw_session, true, &delta))))
|
||||
env.set_error ();
|
||||
}
|
||||
};
|
||||
|
||||
bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph,
|
||||
draw_helper_t &draw_helper, bool in_seac, point_t *delta)
|
||||
hb_draw_session_t &draw_session, bool in_seac, point_t *delta)
|
||||
{
|
||||
if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
|
||||
|
||||
|
@ -546,7 +545,7 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin
|
|||
const byte_str_t str = (*cff->charStrings)[glyph];
|
||||
interp.env.init (str, *cff, fd);
|
||||
interp.env.set_in_seac (in_seac);
|
||||
cff1_path_param_t param (cff, font, draw_helper, delta);
|
||||
cff1_path_param_t param (cff, font, draw_session, delta);
|
||||
if (unlikely (!interp.interpret (param))) return false;
|
||||
|
||||
/* Let's end the path specially since it is called inside seac also */
|
||||
|
@ -555,16 +554,15 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin
|
|||
return true;
|
||||
}
|
||||
|
||||
bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const
|
||||
bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const
|
||||
{
|
||||
#ifdef HB_NO_OT_FONT_CFF
|
||||
/* XXX Remove check when this code moves to .hh file. */
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return _get_path (this, font, glyph, draw_helper);
|
||||
return _get_path (this, font, glyph, draw_session);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct get_seac_param_t
|
||||
{
|
||||
|
|
|
@ -1347,9 +1347,7 @@ struct cff1
|
|||
|
||||
HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
|
||||
HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const;
|
||||
#endif
|
||||
HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const;
|
||||
|
||||
private:
|
||||
struct gname_t
|
||||
|
|
|
@ -143,30 +143,29 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
struct cff2_path_param_t
|
||||
{
|
||||
cff2_path_param_t (hb_font_t *font_, draw_helper_t &draw_helper_)
|
||||
cff2_path_param_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
|
||||
{
|
||||
draw_helper = &draw_helper_;
|
||||
draw_session = &draw_session_;
|
||||
font = font_;
|
||||
}
|
||||
|
||||
void move_to (const point_t &p)
|
||||
{ draw_helper->move_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); }
|
||||
{ draw_session->move_to (font->em_fscalef_x (p.x.to_real ()), font->em_fscalef_y (p.y.to_real ())); }
|
||||
|
||||
void line_to (const point_t &p)
|
||||
{ draw_helper->line_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); }
|
||||
{ draw_session->line_to (font->em_fscalef_x (p.x.to_real ()), font->em_fscalef_y (p.y.to_real ())); }
|
||||
|
||||
void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3)
|
||||
{
|
||||
draw_helper->cubic_to (font->em_scalef_x (p1.x.to_real ()), font->em_scalef_y (p1.y.to_real ()),
|
||||
font->em_scalef_x (p2.x.to_real ()), font->em_scalef_y (p2.y.to_real ()),
|
||||
font->em_scalef_x (p3.x.to_real ()), font->em_scalef_y (p3.y.to_real ()));
|
||||
draw_session->cubic_to (font->em_fscalef_x (p1.x.to_real ()), font->em_fscalef_y (p1.y.to_real ()),
|
||||
font->em_fscalef_x (p2.x.to_real ()), font->em_fscalef_y (p2.y.to_real ()),
|
||||
font->em_fscalef_x (p3.x.to_real ()), font->em_fscalef_y (p3.y.to_real ()));
|
||||
}
|
||||
|
||||
protected:
|
||||
draw_helper_t *draw_helper;
|
||||
hb_draw_session_t *draw_session;
|
||||
hb_font_t *font;
|
||||
};
|
||||
|
||||
|
@ -193,7 +192,7 @@ struct cff2_path_procs_path_t : path_procs_t<cff2_path_procs_path_t, cff2_cs_int
|
|||
|
||||
struct cff2_cs_opset_path_t : cff2_cs_opset_t<cff2_cs_opset_path_t, cff2_path_param_t, cff2_path_procs_path_t> {};
|
||||
|
||||
bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const
|
||||
bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const
|
||||
{
|
||||
#ifdef HB_NO_OT_FONT_CFF
|
||||
/* XXX Remove check when this code moves to .hh file. */
|
||||
|
@ -206,10 +205,9 @@ bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, d
|
|||
cff2_cs_interpreter_t<cff2_cs_opset_path_t, cff2_path_param_t> interp;
|
||||
const byte_str_t str = (*charStrings)[glyph];
|
||||
interp.env.init (str, *this, fd, font->coords, font->num_coords);
|
||||
cff2_path_param_t param (font, draw_helper);
|
||||
cff2_path_param_t param (font, draw_session);
|
||||
if (unlikely (!interp.interpret (param))) return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -515,9 +515,7 @@ struct cff2
|
|||
HB_INTERNAL bool get_extents (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents) const;
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const;
|
||||
#endif
|
||||
HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const;
|
||||
};
|
||||
|
||||
typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> accelerator_subset_t;
|
||||
|
|
|
@ -714,7 +714,7 @@ struct CmapSubtableLongSegmented
|
|||
if (unlikely ((unsigned int) (gid + end - start) >= num_glyphs))
|
||||
end = start + (hb_codepoint_t) num_glyphs - gid;
|
||||
|
||||
out->add_range (start, end);
|
||||
out->add_range (start, hb_min (end, 0x10FFFFu));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -883,7 +883,7 @@ struct DefaultUVS : SortedArray32Of<UnicodeValueRange>
|
|||
hb_codepoint_t first = arrayZ[i].startUnicodeValue;
|
||||
hb_codepoint_t last = hb_min ((hb_codepoint_t) (first + arrayZ[i].additionalCount),
|
||||
(hb_codepoint_t) HB_UNICODE_MAX);
|
||||
out->add_range (first, last);
|
||||
out->add_range (first, hb_min (last, 0x10FFFFu));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,11 @@
|
|||
#define HB_OT_FACE_TABLE_LIST_HH
|
||||
#endif /* HB_OT_FACE_TABLE_LIST_HH */ /* Dummy header guards */
|
||||
|
||||
#ifndef HB_OT_CORE_TABLE
|
||||
#define HB_OT_CORE_TABLE(Namespace, Type) HB_OT_TABLE (Namespace, Type)
|
||||
#define _HB_OT_CORE_TABLE_UNDEF
|
||||
#endif
|
||||
|
||||
#ifndef HB_OT_ACCELERATOR
|
||||
#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
|
||||
#define _HB_OT_ACCELERATOR_UNDEF
|
||||
|
@ -46,7 +51,8 @@
|
|||
|
||||
|
||||
/* OpenType fundamentals. */
|
||||
HB_OT_TABLE (OT, head)
|
||||
HB_OT_CORE_TABLE (OT, head)
|
||||
HB_OT_CORE_TABLE (OT, maxp)
|
||||
#if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT)
|
||||
HB_OT_ACCELERATOR (OT, cmap)
|
||||
#endif
|
||||
|
@ -74,6 +80,7 @@ HB_OT_TABLE (OT, VORG)
|
|||
#endif
|
||||
|
||||
/* TrueType outlines. */
|
||||
HB_OT_CORE_TABLE (OT, loca) // Also used to determine number of glyphs
|
||||
HB_OT_ACCELERATOR (OT, glyf)
|
||||
|
||||
/* CFF outlines. */
|
||||
|
@ -138,3 +145,7 @@ HB_OT_TABLE (OT, MATH)
|
|||
#ifdef _HB_OT_ACCELERATOR_UNDEF
|
||||
#undef HB_OT_ACCELERATOR
|
||||
#endif
|
||||
|
||||
#ifdef _HB_OT_CORE_TABLE_UNDEF
|
||||
#undef HB_OT_CORE_TABLE
|
||||
#endif
|
||||
|
|
|
@ -63,10 +63,13 @@ struct hb_ot_face_t
|
|||
hb_face_t *face; /* MUST be JUST before the lazy loaders. */
|
||||
#define HB_OT_TABLE(Namespace, Type) \
|
||||
hb_table_lazy_loader_t<Namespace::Type, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
|
||||
#define HB_OT_CORE_TABLE(Namespace, Type) \
|
||||
hb_table_lazy_loader_t<Namespace::Type, HB_OT_TABLE_ORDER (Namespace, Type), true> Type;
|
||||
#define HB_OT_ACCELERATOR(Namespace, Type) \
|
||||
hb_face_lazy_loader_t<Namespace::Type##_accelerator_t, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
|
||||
#include "hb-ot-face-table-list.hh"
|
||||
#undef HB_OT_ACCELERATOR
|
||||
#undef HB_OT_CORE_TABLE
|
||||
#undef HB_OT_TABLE
|
||||
};
|
||||
|
||||
|
|
|
@ -131,11 +131,25 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
|
|||
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
|
||||
const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (vmtx.has_data ())
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
*first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font));
|
||||
first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
|
||||
first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
*first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font));
|
||||
first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
|
||||
first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
|
||||
hb_font_extents_t font_extents;
|
||||
font->get_h_extents_with_fallback (&font_extents);
|
||||
hb_position_t advance = -(font_extents.ascender - font_extents.descender);
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
*first_advance = advance;
|
||||
first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
|
||||
first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -163,9 +177,19 @@ hb_ot_get_glyph_v_origin (hb_font_t *font,
|
|||
hb_glyph_extents_t extents = {0};
|
||||
if (ot_face->glyf->get_extents (font, glyph, &extents))
|
||||
{
|
||||
const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
|
||||
hb_position_t tsb = vmtx.get_side_bearing (font, glyph);
|
||||
*y = extents.y_bearing + font->em_scale_y (tsb);
|
||||
if (ot_face->vmtx->has_data ())
|
||||
{
|
||||
const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
|
||||
hb_position_t tsb = vmtx.get_side_bearing (font, glyph);
|
||||
*y = extents.y_bearing + font->em_scale_y (tsb);
|
||||
return true;
|
||||
}
|
||||
|
||||
hb_font_extents_t font_extents;
|
||||
font->get_h_extents_with_fallback (&font_extents);
|
||||
hb_position_t advance = font_extents.ascender - font_extents.descender;
|
||||
int diff = advance - -extents.height;
|
||||
*y = extents.y_bearing + (diff >> 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -257,6 +281,23 @@ hb_ot_get_font_v_extents (hb_font_t *font,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef HB_NO_DRAW
|
||||
static void
|
||||
hb_ot_get_glyph_shape (hb_font_t *font,
|
||||
void *font_data HB_UNUSED,
|
||||
hb_codepoint_t glyph,
|
||||
hb_draw_funcs_t *draw_funcs, void *draw_data,
|
||||
void *user_data)
|
||||
{
|
||||
hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy);
|
||||
if (font->face->table.glyf->get_path (font, glyph, draw_session)) return;
|
||||
#ifndef HB_NO_CFF
|
||||
if (font->face->table.cff1->get_path (font, glyph, draw_session)) return;
|
||||
if (font->face->table.cff2->get_path (font, glyph, draw_session)) return;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void free_static_ot_funcs ();
|
||||
|
||||
static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t>
|
||||
|
@ -279,6 +320,10 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot
|
|||
hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
|
||||
#endif
|
||||
|
||||
#ifndef HB_NO_DRAW
|
||||
hb_font_funcs_set_glyph_shape_func (funcs, hb_ot_get_glyph_shape, nullptr, nullptr);
|
||||
#endif
|
||||
|
||||
hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
|
||||
//hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
|
||||
|
||||
|
|
|
@ -936,7 +936,7 @@ struct glyf
|
|||
return;
|
||||
short_offset = 0 == head.indexToLocFormat;
|
||||
|
||||
loca_table = hb_sanitize_context_t ().reference_table<loca> (face);
|
||||
loca_table = face->table.loca.get_blob (); // Needs no destruct!
|
||||
glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
|
||||
#ifndef HB_NO_VAR
|
||||
gvar = face->table.gvar;
|
||||
|
@ -951,7 +951,6 @@ struct glyf
|
|||
}
|
||||
~accelerator_t ()
|
||||
{
|
||||
loca_table.destroy ();
|
||||
glyf_table.destroy ();
|
||||
}
|
||||
|
||||
|
@ -1152,11 +1151,10 @@ struct glyf
|
|||
return operation_count;
|
||||
}
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
struct path_builder_t
|
||||
{
|
||||
hb_font_t *font;
|
||||
draw_helper_t *draw_helper;
|
||||
hb_draw_session_t *draw_session;
|
||||
|
||||
struct optional_point_t
|
||||
{
|
||||
|
@ -1171,10 +1169,10 @@ struct glyf
|
|||
{ return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
|
||||
} first_oncurve, first_offcurve, last_offcurve;
|
||||
|
||||
path_builder_t (hb_font_t *font_, draw_helper_t &draw_helper_)
|
||||
path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
|
||||
{
|
||||
font = font_;
|
||||
draw_helper = &draw_helper_;
|
||||
draw_session = &draw_session_;
|
||||
first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
|
||||
}
|
||||
|
||||
|
@ -1184,10 +1182,6 @@ struct glyf
|
|||
* https://stackoverflow.com/a/20772557 */
|
||||
void consume_point (const contour_point_t &point)
|
||||
{
|
||||
/* Skip empty contours */
|
||||
if (unlikely (point.is_end_point && !first_oncurve.has_data && !first_offcurve.has_data))
|
||||
return;
|
||||
|
||||
bool is_on_curve = point.flag & Glyph::FLAG_ON_CURVE;
|
||||
optional_point_t p (point.x, point.y);
|
||||
if (!first_oncurve.has_data)
|
||||
|
@ -1195,7 +1189,7 @@ struct glyf
|
|||
if (is_on_curve)
|
||||
{
|
||||
first_oncurve = p;
|
||||
draw_helper->move_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y));
|
||||
draw_session->move_to (font->em_fscalef_x (p.x), font->em_fscalef_y (p.y));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1204,7 +1198,7 @@ struct glyf
|
|||
optional_point_t mid = first_offcurve.lerp (p, .5f);
|
||||
first_oncurve = mid;
|
||||
last_offcurve = p;
|
||||
draw_helper->move_to (font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
|
||||
draw_session->move_to (font->em_fscalef_x (mid.x), font->em_fscalef_y (mid.y));
|
||||
}
|
||||
else
|
||||
first_offcurve = p;
|
||||
|
@ -1216,22 +1210,22 @@ struct glyf
|
|||
{
|
||||
if (is_on_curve)
|
||||
{
|
||||
draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
|
||||
font->em_scalef_x (p.x), font->em_scalef_y (p.y));
|
||||
draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y),
|
||||
font->em_fscalef_x (p.x), font->em_fscalef_y (p.y));
|
||||
last_offcurve = optional_point_t ();
|
||||
}
|
||||
else
|
||||
{
|
||||
optional_point_t mid = last_offcurve.lerp (p, .5f);
|
||||
draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
|
||||
font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
|
||||
draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y),
|
||||
font->em_fscalef_x (mid.x), font->em_fscalef_y (mid.y));
|
||||
last_offcurve = p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_on_curve)
|
||||
draw_helper->line_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y));
|
||||
draw_session->line_to (font->em_fscalef_x (p.x), font->em_fscalef_y (p.y));
|
||||
else
|
||||
last_offcurve = p;
|
||||
}
|
||||
|
@ -1242,24 +1236,30 @@ struct glyf
|
|||
if (first_offcurve.has_data && last_offcurve.has_data)
|
||||
{
|
||||
optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f);
|
||||
draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
|
||||
font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
|
||||
draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y),
|
||||
font->em_fscalef_x (mid.x), font->em_fscalef_y (mid.y));
|
||||
last_offcurve = optional_point_t ();
|
||||
/* now check the rest */
|
||||
}
|
||||
|
||||
if (first_offcurve.has_data && first_oncurve.has_data)
|
||||
draw_helper->quadratic_to (font->em_scalef_x (first_offcurve.x), font->em_scalef_y (first_offcurve.y),
|
||||
font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
|
||||
draw_session->quadratic_to (font->em_fscalef_x (first_offcurve.x), font->em_fscalef_y (first_offcurve.y),
|
||||
font->em_fscalef_x (first_oncurve.x), font->em_fscalef_y (first_oncurve.y));
|
||||
else if (last_offcurve.has_data && first_oncurve.has_data)
|
||||
draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
|
||||
font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
|
||||
draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y),
|
||||
font->em_fscalef_x (first_oncurve.x), font->em_fscalef_y (first_oncurve.y));
|
||||
else if (first_oncurve.has_data)
|
||||
draw_helper->line_to (font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
|
||||
draw_session->line_to (font->em_fscalef_x (first_oncurve.x), font->em_fscalef_y (first_oncurve.y));
|
||||
else if (first_offcurve.has_data)
|
||||
{
|
||||
float x = font->em_fscalef_x (first_offcurve.x), y = font->em_fscalef_x (first_offcurve.y);
|
||||
draw_session->move_to (x, y);
|
||||
draw_session->quadratic_to (x, y, x, y);
|
||||
}
|
||||
|
||||
/* Getting ready for the next contour */
|
||||
first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
|
||||
draw_helper->end_path ();
|
||||
draw_session->close_path ();
|
||||
}
|
||||
}
|
||||
void points_end () {}
|
||||
|
@ -1269,9 +1269,8 @@ struct glyf
|
|||
};
|
||||
|
||||
bool
|
||||
get_path (hb_font_t *font, hb_codepoint_t gid, draw_helper_t &draw_helper) const
|
||||
{ return get_points (font, gid, path_builder_t (font, draw_helper)); }
|
||||
#endif
|
||||
get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const
|
||||
{ return get_points (font, gid, path_builder_t (font, draw_session)); }
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
const gvar_accelerator_t *gvar;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#define HB_OT_HMTX_TABLE_HH
|
||||
|
||||
#include "hb-open-type.hh"
|
||||
#include "hb-ot-maxp-table.hh"
|
||||
#include "hb-ot-hhea-table.hh"
|
||||
#include "hb-ot-var-hvar-table.hh"
|
||||
#include "hb-ot-metrics.hh"
|
||||
|
@ -98,12 +99,12 @@ struct hmtxvmtx
|
|||
hb_requires (hb_is_iterator (Iterator))>
|
||||
void serialize (hb_serialize_context_t *c,
|
||||
Iterator it,
|
||||
unsigned num_advances)
|
||||
unsigned num_long_metrics)
|
||||
{
|
||||
unsigned idx = 0;
|
||||
for (auto _ : it)
|
||||
{
|
||||
if (idx < num_advances)
|
||||
if (idx < num_long_metrics)
|
||||
{
|
||||
LongMetric lm;
|
||||
lm.advance = _.first;
|
||||
|
@ -128,17 +129,17 @@ struct hmtxvmtx
|
|||
if (unlikely (!table_prime)) return_trace (false);
|
||||
|
||||
accelerator_t _mtx (c->plan->source);
|
||||
unsigned num_advances;
|
||||
unsigned num_long_metrics;
|
||||
{
|
||||
/* Determine num_advances to encode. */
|
||||
/* Determine num_long_metrics to encode. */
|
||||
auto& plan = c->plan;
|
||||
num_advances = plan->num_output_glyphs ();
|
||||
num_long_metrics = plan->num_output_glyphs ();
|
||||
hb_codepoint_t old_gid = 0;
|
||||
unsigned int last_advance = plan->old_gid_for_new_gid (num_advances - 1, &old_gid) ? _mtx.get_advance (old_gid) : 0;
|
||||
while (num_advances > 1 &&
|
||||
last_advance == (plan->old_gid_for_new_gid (num_advances - 2, &old_gid) ? _mtx.get_advance (old_gid) : 0))
|
||||
unsigned int last_advance = plan->old_gid_for_new_gid (num_long_metrics - 1, &old_gid) ? _mtx.get_advance (old_gid) : 0;
|
||||
while (num_long_metrics > 1 &&
|
||||
last_advance == (plan->old_gid_for_new_gid (num_long_metrics - 2, &old_gid) ? _mtx.get_advance (old_gid) : 0))
|
||||
{
|
||||
num_advances--;
|
||||
num_long_metrics--;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,13 +154,13 @@ struct hmtxvmtx
|
|||
})
|
||||
;
|
||||
|
||||
table_prime->serialize (c->serializer, it, num_advances);
|
||||
table_prime->serialize (c->serializer, it, num_long_metrics);
|
||||
|
||||
if (unlikely (c->serializer->in_error ()))
|
||||
return_trace (false);
|
||||
|
||||
// Amend header num hmetrics
|
||||
if (unlikely (!subset_update_header (c->plan, num_advances)))
|
||||
if (unlikely (!subset_update_header (c->plan, num_long_metrics)))
|
||||
return_trace (false);
|
||||
|
||||
return_trace (true);
|
||||
|
@ -169,38 +170,48 @@ struct hmtxvmtx
|
|||
{
|
||||
friend struct hmtxvmtx;
|
||||
|
||||
accelerator_t (hb_face_t *face,
|
||||
unsigned int default_advance_ = 0)
|
||||
accelerator_t (hb_face_t *face)
|
||||
{
|
||||
default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
|
||||
|
||||
num_advances = T::is_horizontal ?
|
||||
face->table.hhea->numberOfLongMetrics :
|
||||
#ifndef HB_NO_VERTICAL
|
||||
face->table.vhea->numberOfLongMetrics
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
;
|
||||
|
||||
table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag);
|
||||
|
||||
/* Cap num_metrics() and num_advances() based on table length. */
|
||||
unsigned int len = table.get_length ();
|
||||
if (unlikely (num_advances * 4 > len))
|
||||
num_advances = len / 4;
|
||||
num_metrics = num_advances + (len - 4 * num_advances) / 2;
|
||||
|
||||
/* We MUST set num_metrics to zero if num_advances is zero.
|
||||
* Our get_advance() depends on that. */
|
||||
if (unlikely (!num_advances))
|
||||
{
|
||||
num_metrics = num_advances = 0;
|
||||
table.destroy ();
|
||||
table = hb_blob_get_empty ();
|
||||
}
|
||||
|
||||
var_table = hb_sanitize_context_t ().reference_table<HVARVVAR> (face, T::variationsTag);
|
||||
|
||||
default_advance = T::is_horizontal ? hb_face_get_upem (face) / 2 : hb_face_get_upem (face);
|
||||
|
||||
/* Populate count variables and sort them out as we go */
|
||||
|
||||
unsigned int len = table.get_length ();
|
||||
if (len & 1)
|
||||
len--;
|
||||
|
||||
num_long_metrics = T::is_horizontal ?
|
||||
face->table.hhea->numberOfLongMetrics :
|
||||
#ifndef HB_NO_VERTICAL
|
||||
face->table.vhea->numberOfLongMetrics
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
;
|
||||
if (unlikely (num_long_metrics * 4 > len))
|
||||
num_long_metrics = len / 4;
|
||||
len -= num_long_metrics * 4;
|
||||
|
||||
num_bearings = face->table.maxp->get_num_glyphs ();
|
||||
|
||||
if (unlikely (num_bearings < num_long_metrics))
|
||||
num_bearings = num_long_metrics;
|
||||
if (unlikely ((num_bearings - num_long_metrics) * 2 > len))
|
||||
num_bearings = num_long_metrics + len / 2;
|
||||
len -= (num_bearings - num_long_metrics) * 2;
|
||||
|
||||
/* We MUST set num_bearings to zero if num_long_metrics is zero.
|
||||
* Our get_advance() depends on that. */
|
||||
if (unlikely (!num_long_metrics))
|
||||
num_bearings = num_long_metrics = 0;
|
||||
|
||||
num_advances = num_bearings + len / 2;
|
||||
num_glyphs = face->get_num_glyphs ();
|
||||
if (num_glyphs < num_advances)
|
||||
num_glyphs = num_advances;
|
||||
}
|
||||
~accelerator_t ()
|
||||
{
|
||||
|
@ -208,16 +219,18 @@ struct hmtxvmtx
|
|||
var_table.destroy ();
|
||||
}
|
||||
|
||||
bool has_data () const { return (bool) num_bearings; }
|
||||
|
||||
int get_side_bearing (hb_codepoint_t glyph) const
|
||||
{
|
||||
if (glyph < num_advances)
|
||||
if (glyph < num_long_metrics)
|
||||
return table->longMetricZ[glyph].sb;
|
||||
|
||||
if (unlikely (glyph >= num_metrics))
|
||||
if (unlikely (glyph >= num_bearings))
|
||||
return 0;
|
||||
|
||||
const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_advances];
|
||||
return bearings[glyph - num_advances];
|
||||
const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics];
|
||||
return bearings[glyph - num_long_metrics];
|
||||
}
|
||||
|
||||
int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const
|
||||
|
@ -225,7 +238,7 @@ struct hmtxvmtx
|
|||
int side_bearing = get_side_bearing (glyph);
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
if (unlikely (glyph >= num_metrics) || !font->num_coords)
|
||||
if (unlikely (glyph >= num_bearings) || !font->num_coords)
|
||||
return side_bearing;
|
||||
|
||||
if (var_table.get_length ())
|
||||
|
@ -239,18 +252,35 @@ struct hmtxvmtx
|
|||
|
||||
unsigned int get_advance (hb_codepoint_t glyph) const
|
||||
{
|
||||
if (unlikely (glyph >= num_metrics))
|
||||
{
|
||||
/* If num_metrics is zero, it means we don't have the metrics table
|
||||
* for this direction: return default advance. Otherwise, it means that the
|
||||
* glyph index is out of bound: return zero. */
|
||||
if (num_metrics)
|
||||
return 0;
|
||||
else
|
||||
return default_advance;
|
||||
}
|
||||
/* OpenType case. */
|
||||
if (glyph < num_bearings)
|
||||
return table->longMetricZ[hb_min (glyph, (uint32_t) num_long_metrics - 1)].advance;
|
||||
|
||||
return table->longMetricZ[hb_min (glyph, (uint32_t) num_advances - 1)].advance;
|
||||
/* If num_advances is zero, it means we don't have the metrics table
|
||||
* for this direction: return default advance. Otherwise, there's a
|
||||
* well-defined answer. */
|
||||
if (unlikely (!num_advances))
|
||||
return default_advance;
|
||||
|
||||
#ifdef HB_NO_BORING_EXPANSION
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (unlikely (glyph >= num_glyphs))
|
||||
return 0;
|
||||
|
||||
/* num_bearings <= glyph < num_glyphs;
|
||||
* num_bearings <= num_advances */
|
||||
|
||||
/* TODO Optimize */
|
||||
|
||||
if (num_bearings == num_advances)
|
||||
return get_advance (num_bearings - 1);
|
||||
|
||||
const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics];
|
||||
const UFWORD *advances = (const UFWORD *) &bearings[num_bearings - num_long_metrics];
|
||||
|
||||
return advances[hb_min (glyph - num_bearings, num_advances - num_bearings - 1)];
|
||||
}
|
||||
|
||||
unsigned int get_advance (hb_codepoint_t glyph,
|
||||
|
@ -259,7 +289,7 @@ struct hmtxvmtx
|
|||
unsigned int advance = get_advance (glyph);
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
if (unlikely (glyph >= num_metrics) || !font->num_coords)
|
||||
if (unlikely (glyph >= num_bearings) || !font->num_coords)
|
||||
return advance;
|
||||
|
||||
if (var_table.get_length ())
|
||||
|
@ -272,8 +302,12 @@ struct hmtxvmtx
|
|||
}
|
||||
|
||||
protected:
|
||||
unsigned int num_metrics;
|
||||
unsigned int num_advances;
|
||||
// 0 <= num_long_metrics <= num_bearings <= num_advances <= num_glyphs
|
||||
unsigned num_long_metrics;
|
||||
unsigned num_bearings;
|
||||
unsigned num_advances;
|
||||
unsigned num_glyphs;
|
||||
|
||||
unsigned int default_advance;
|
||||
|
||||
private:
|
||||
|
@ -305,6 +339,8 @@ struct hmtxvmtx
|
|||
* the end. This allows a monospaced
|
||||
* font to vary the side bearing
|
||||
* values for each glyph. */
|
||||
/*UnsizedArrayOf<UFWORD>advancesX;*/
|
||||
/* TODO Document. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (0, longMetricZ);
|
||||
};
|
||||
|
|
|
@ -41,7 +41,10 @@ namespace OT {
|
|||
|
||||
struct BaseCoordFormat1
|
||||
{
|
||||
hb_position_t get_coord () const { return coordinate; }
|
||||
hb_position_t get_coord (hb_font_t *font, hb_direction_t direction) const
|
||||
{
|
||||
return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
|
@ -58,10 +61,10 @@ struct BaseCoordFormat1
|
|||
|
||||
struct BaseCoordFormat2
|
||||
{
|
||||
hb_position_t get_coord () const
|
||||
hb_position_t get_coord (hb_font_t *font, hb_direction_t direction) const
|
||||
{
|
||||
/* TODO */
|
||||
return coordinate;
|
||||
return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
|
@ -87,9 +90,10 @@ struct BaseCoordFormat3
|
|||
hb_direction_t direction) const
|
||||
{
|
||||
const Device &device = this+deviceTable;
|
||||
return coordinate + (HB_DIRECTION_IS_VERTICAL (direction) ?
|
||||
device.get_y_delta (font, var_store) :
|
||||
device.get_x_delta (font, var_store));
|
||||
|
||||
return HB_DIRECTION_IS_HORIZONTAL (direction)
|
||||
? font->em_scale_y (coordinate) + device.get_y_delta (font, var_store)
|
||||
: font->em_scale_x (coordinate) + device.get_x_delta (font, var_store);
|
||||
}
|
||||
|
||||
|
||||
|
@ -120,8 +124,8 @@ struct BaseCoord
|
|||
hb_direction_t direction) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1: return u.format1.get_coord ();
|
||||
case 2: return u.format2.get_coord ();
|
||||
case 1: return u.format1.get_coord (font, direction);
|
||||
case 2: return u.format2.get_coord (font, direction);
|
||||
case 3: return u.format3.get_coord (font, var_store, direction);
|
||||
default:return 0;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,10 @@
|
|||
#define HB_MAX_LANGSYS 2000
|
||||
#endif
|
||||
|
||||
#ifndef HB_MAX_LANGSYS_FEATURE_COUNT
|
||||
#define HB_MAX_LANGSYS_FEATURE_COUNT 50000
|
||||
#endif
|
||||
|
||||
#ifndef HB_MAX_FEATURES
|
||||
#define HB_MAX_FEATURES 750
|
||||
#endif
|
||||
|
@ -105,34 +109,15 @@ struct hb_prune_langsys_context_t
|
|||
script_langsys_map (script_langsys_map_),
|
||||
duplicate_feature_map (duplicate_feature_map_),
|
||||
new_feature_indexes (new_collected_feature_indexes_),
|
||||
script_count (0),langsys_count (0) {}
|
||||
script_count (0),langsys_feature_count (0) {}
|
||||
|
||||
bool visitedScript (const void *s)
|
||||
bool visitScript ()
|
||||
{ return script_count++ < HB_MAX_SCRIPTS; }
|
||||
|
||||
bool visitLangsys (unsigned feature_count)
|
||||
{
|
||||
if (script_count++ > HB_MAX_SCRIPTS)
|
||||
return true;
|
||||
|
||||
return visited (s, visited_script);
|
||||
}
|
||||
|
||||
bool visitedLangsys (const void *l)
|
||||
{
|
||||
if (langsys_count++ > HB_MAX_LANGSYS)
|
||||
return true;
|
||||
|
||||
return visited (l, visited_langsys);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
bool visited (const T *p, hb_set_t &visited_set)
|
||||
{
|
||||
hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) p - (uintptr_t) table);
|
||||
if (visited_set.in_error () || visited_set.has (delta))
|
||||
return true;
|
||||
|
||||
visited_set.add (delta);
|
||||
return false;
|
||||
langsys_feature_count += feature_count;
|
||||
return langsys_feature_count < HB_MAX_LANGSYS_FEATURE_COUNT;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -142,10 +127,8 @@ struct hb_prune_langsys_context_t
|
|||
hb_set_t *new_feature_indexes;
|
||||
|
||||
private:
|
||||
hb_set_t visited_script;
|
||||
hb_set_t visited_langsys;
|
||||
unsigned script_count;
|
||||
unsigned langsys_count;
|
||||
unsigned langsys_feature_count;
|
||||
};
|
||||
|
||||
struct hb_subset_layout_context_t :
|
||||
|
@ -643,11 +626,14 @@ struct LangSys
|
|||
| hb_map (feature_index_map)
|
||||
;
|
||||
|
||||
if (iter.len () != o_iter.len ())
|
||||
return false;
|
||||
for (; iter && o_iter; iter++, o_iter++)
|
||||
{
|
||||
unsigned a = *iter;
|
||||
unsigned b = *o_iter;
|
||||
if (a != b) return false;
|
||||
}
|
||||
|
||||
for (const auto _ : + hb_zip (iter, o_iter))
|
||||
if (_.first != _.second) return false;
|
||||
if (iter || o_iter) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -732,7 +718,7 @@ struct Script
|
|||
unsigned script_index) const
|
||||
{
|
||||
if (!has_default_lang_sys () && !get_lang_sys_count ()) return;
|
||||
if (c->visitedScript (this)) return;
|
||||
if (!c->visitScript ()) return;
|
||||
|
||||
if (!c->script_langsys_map->has (script_index))
|
||||
{
|
||||
|
@ -749,15 +735,14 @@ struct Script
|
|||
{
|
||||
//only collect features from non-redundant langsys
|
||||
const LangSys& d = get_default_lang_sys ();
|
||||
if (!c->visitedLangsys (&d)) {
|
||||
if (c->visitLangsys (d.get_feature_count ())) {
|
||||
d.collect_features (c);
|
||||
}
|
||||
|
||||
for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
|
||||
{
|
||||
|
||||
const LangSys& l = this+_.first.offset;
|
||||
if (c->visitedLangsys (&l)) continue;
|
||||
if (!c->visitLangsys (l.get_feature_count ())) continue;
|
||||
if (l.compare (d, c->duplicate_feature_map)) continue;
|
||||
|
||||
l.collect_features (c);
|
||||
|
@ -769,7 +754,7 @@ struct Script
|
|||
for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
|
||||
{
|
||||
const LangSys& l = this+_.first.offset;
|
||||
if (c->visitedLangsys (&l)) continue;
|
||||
if (!c->visitLangsys (l.get_feature_count ())) continue;
|
||||
l.collect_features (c);
|
||||
c->script_langsys_map->get (script_index)->add (_.second);
|
||||
}
|
||||
|
|
|
@ -361,6 +361,13 @@ hb_ot_layout_get_attach_points (hb_face_t *face,
|
|||
* Fetches a list of the caret positions defined for a ligature glyph in the GDEF
|
||||
* table of the font. The list returned will begin at the offset provided.
|
||||
*
|
||||
* Note that a ligature that is formed from n characters will have n-1
|
||||
* caret positions. The first character is not represented in the array,
|
||||
* since its caret position is the glyph position.
|
||||
*
|
||||
* The positions returned by this function are 'unshaped', and will have to
|
||||
* be fixed up for kerning that may be applied to the ligature glyph.
|
||||
*
|
||||
* Return value: Total number of ligature caret positions for @glyph.
|
||||
*
|
||||
**/
|
||||
|
@ -999,7 +1006,7 @@ struct hb_collect_features_context_t
|
|||
hb_collect_features_context_t (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
hb_set_t *feature_indices_,
|
||||
const hb_tag_t *features)
|
||||
const hb_tag_t *features)
|
||||
|
||||
: g (get_gsubgpos_table (face, table_tag)),
|
||||
feature_indices (feature_indices_),
|
||||
|
@ -1026,7 +1033,7 @@ struct hb_collect_features_context_t
|
|||
{
|
||||
hb_tag_t tag = g.get_feature_tag (i);
|
||||
if (features_set.has (tag))
|
||||
feature_indices_filter.add(i);
|
||||
feature_indices_filter.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1959,6 +1966,77 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
|
|||
}
|
||||
|
||||
#ifndef HB_NO_BASE
|
||||
/**
|
||||
* hb_ot_layout_get_horizontal_baseline_tag_for_script:
|
||||
* @script: a script tag.
|
||||
*
|
||||
* Fetches the dominant horizontal baseline tag used by @script.
|
||||
*
|
||||
* Return value: dominant baseline tag for the @script.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
hb_ot_layout_baseline_tag_t
|
||||
hb_ot_layout_get_horizontal_baseline_tag_for_script (hb_script_t script)
|
||||
{
|
||||
/* Keep in sync with hb_ot_layout_get_baseline_with_fallback */
|
||||
switch ((int) script)
|
||||
{
|
||||
/* Unicode-1.1 additions */
|
||||
case HB_SCRIPT_BENGALI:
|
||||
case HB_SCRIPT_DEVANAGARI:
|
||||
case HB_SCRIPT_GUJARATI:
|
||||
case HB_SCRIPT_GURMUKHI:
|
||||
/* Unicode-2.0 additions */
|
||||
case HB_SCRIPT_TIBETAN:
|
||||
/* Unicode-4.0 additions */
|
||||
case HB_SCRIPT_LIMBU:
|
||||
/* Unicode-4.1 additions */
|
||||
case HB_SCRIPT_SYLOTI_NAGRI:
|
||||
/* Unicode-5.0 additions */
|
||||
case HB_SCRIPT_PHAGS_PA:
|
||||
/* Unicode-5.2 additions */
|
||||
case HB_SCRIPT_MEETEI_MAYEK:
|
||||
/* Unicode-6.1 additions */
|
||||
case HB_SCRIPT_SHARADA:
|
||||
case HB_SCRIPT_TAKRI:
|
||||
/* Unicode-7.0 additions */
|
||||
case HB_SCRIPT_MODI:
|
||||
case HB_SCRIPT_SIDDHAM:
|
||||
case HB_SCRIPT_TIRHUTA:
|
||||
/* Unicode-9.0 additions */
|
||||
case HB_SCRIPT_MARCHEN:
|
||||
case HB_SCRIPT_NEWA:
|
||||
/* Unicode-10.0 additions */
|
||||
case HB_SCRIPT_SOYOMBO:
|
||||
case HB_SCRIPT_ZANABAZAR_SQUARE:
|
||||
/* Unicode-11.0 additions */
|
||||
case HB_SCRIPT_DOGRA:
|
||||
case HB_SCRIPT_GUNJALA_GONDI:
|
||||
/* Unicode-12.0 additions */
|
||||
case HB_SCRIPT_NANDINAGARI:
|
||||
return HB_OT_LAYOUT_BASELINE_TAG_HANGING;
|
||||
|
||||
/* Unicode-1.1 additions */
|
||||
case HB_SCRIPT_HANGUL:
|
||||
case HB_SCRIPT_HAN:
|
||||
case HB_SCRIPT_HIRAGANA:
|
||||
case HB_SCRIPT_KATAKANA:
|
||||
/* Unicode-3.0 additions */
|
||||
case HB_SCRIPT_BOPOMOFO:
|
||||
/* Unicode-9.0 additions */
|
||||
case HB_SCRIPT_TANGUT:
|
||||
/* Unicode-10.0 additions */
|
||||
case HB_SCRIPT_NUSHU:
|
||||
/* Unicode-13.0 additions */
|
||||
case HB_SCRIPT_KHITAN_SMALL_SCRIPT:
|
||||
return HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT;
|
||||
|
||||
default:
|
||||
return HB_OT_LAYOUT_BASELINE_TAG_ROMAN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_layout_get_baseline:
|
||||
* @font: a font
|
||||
|
@ -1966,7 +2044,7 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
|
|||
* @direction: text direction.
|
||||
* @script_tag: script tag.
|
||||
* @language_tag: language tag, currently unused.
|
||||
* @coord: (out): baseline value if found.
|
||||
* @coord: (out) (nullable): baseline value if found.
|
||||
*
|
||||
* Fetches a baseline value from the face.
|
||||
*
|
||||
|
@ -1982,13 +2060,231 @@ hb_ot_layout_get_baseline (hb_font_t *font,
|
|||
hb_tag_t language_tag,
|
||||
hb_position_t *coord /* OUT. May be NULL. */)
|
||||
{
|
||||
bool result = font->face->table.BASE->get_baseline (font, baseline_tag, direction, script_tag, language_tag, coord);
|
||||
|
||||
if (result && coord)
|
||||
*coord = HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (*coord) : font->em_scale_x (*coord);
|
||||
|
||||
return result;
|
||||
return font->face->table.BASE->get_baseline (font, baseline_tag, direction, script_tag, language_tag, coord);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_layout_get_baseline_with_fallback:
|
||||
* @font: a font
|
||||
* @baseline_tag: a baseline tag
|
||||
* @direction: text direction.
|
||||
* @script_tag: script tag.
|
||||
* @language_tag: language tag, currently unused.
|
||||
* @coord: (out): baseline value if found.
|
||||
*
|
||||
* Fetches a baseline value from the face, and synthesizes
|
||||
* it if the font does not have it.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
void
|
||||
hb_ot_layout_get_baseline_with_fallback (hb_font_t *font,
|
||||
hb_ot_layout_baseline_tag_t baseline_tag,
|
||||
hb_direction_t direction,
|
||||
hb_tag_t script_tag,
|
||||
hb_tag_t language_tag,
|
||||
hb_position_t *coord /* OUT */)
|
||||
{
|
||||
if (hb_ot_layout_get_baseline (font,
|
||||
baseline_tag,
|
||||
direction,
|
||||
script_tag,
|
||||
language_tag,
|
||||
coord))
|
||||
return;
|
||||
|
||||
/* Synthesize missing baselines.
|
||||
* See https://www.w3.org/TR/css-inline-3/#baseline-synthesis-fonts
|
||||
*/
|
||||
switch (baseline_tag)
|
||||
{
|
||||
case HB_OT_LAYOUT_BASELINE_TAG_ROMAN:
|
||||
*coord = 0; // FIXME origin ?
|
||||
break;
|
||||
|
||||
case HB_OT_LAYOUT_BASELINE_TAG_MATH:
|
||||
{
|
||||
hb_codepoint_t glyph;
|
||||
hb_glyph_extents_t extents;
|
||||
if (HB_DIRECTION_IS_HORIZONTAL (direction) &&
|
||||
(hb_font_get_nominal_glyph (font, 0x2212u, &glyph) ||
|
||||
hb_font_get_nominal_glyph (font, '-', &glyph)) &&
|
||||
hb_font_get_glyph_extents (font, glyph, &extents))
|
||||
{
|
||||
*coord = extents.y_bearing + extents.height / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_position_t x_height = font->y_scale / 2;
|
||||
#ifndef HB_NO_METRICS
|
||||
hb_ot_metrics_get_position_with_fallback (font, HB_OT_METRICS_TAG_X_HEIGHT, &x_height);
|
||||
#endif
|
||||
*coord = x_height / 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT:
|
||||
case HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT:
|
||||
{
|
||||
hb_position_t embox_top, embox_bottom;
|
||||
|
||||
hb_ot_layout_get_baseline_with_fallback (font,
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT,
|
||||
direction,
|
||||
script_tag,
|
||||
language_tag,
|
||||
&embox_top);
|
||||
hb_ot_layout_get_baseline_with_fallback (font,
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT,
|
||||
direction,
|
||||
script_tag,
|
||||
language_tag,
|
||||
&embox_bottom);
|
||||
|
||||
if (baseline_tag == HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT)
|
||||
*coord = embox_top + (embox_bottom - embox_top) / 10;
|
||||
else
|
||||
*coord = embox_bottom + (embox_top - embox_bottom) / 10;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT:
|
||||
if (hb_ot_layout_get_baseline (font,
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT,
|
||||
direction,
|
||||
script_tag,
|
||||
language_tag,
|
||||
coord))
|
||||
*coord += HB_DIRECTION_IS_HORIZONTAL (direction) ? font->y_scale : font->x_scale;
|
||||
else
|
||||
{
|
||||
hb_font_extents_t font_extents;
|
||||
hb_font_get_extents_for_direction (font, direction, &font_extents);
|
||||
*coord = font_extents.ascender;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT:
|
||||
if (hb_ot_layout_get_baseline (font,
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT,
|
||||
direction,
|
||||
script_tag,
|
||||
language_tag,
|
||||
coord))
|
||||
*coord -= HB_DIRECTION_IS_HORIZONTAL (direction) ? font->y_scale : font->x_scale;
|
||||
else
|
||||
{
|
||||
hb_font_extents_t font_extents;
|
||||
hb_font_get_extents_for_direction (font, direction, &font_extents);
|
||||
*coord = font_extents.descender;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_OT_LAYOUT_BASELINE_TAG_HANGING:
|
||||
if (HB_DIRECTION_IS_HORIZONTAL (direction))
|
||||
{
|
||||
hb_codepoint_t ch;
|
||||
hb_codepoint_t glyph;
|
||||
hb_glyph_extents_t extents;
|
||||
|
||||
/* Keep in sync with hb_ot_layout_get_horizontal_baseline_for_script */
|
||||
switch ((int) script_tag)
|
||||
{
|
||||
/* Unicode-1.1 additions */
|
||||
case HB_SCRIPT_BENGALI: ch = 0x0995u; break;
|
||||
case HB_SCRIPT_DEVANAGARI: ch = 0x0915u; break;
|
||||
case HB_SCRIPT_GUJARATI: ch = 0x0a95u; break;
|
||||
case HB_SCRIPT_GURMUKHI: ch = 0x0a15u; break;
|
||||
/* Unicode-2.0 additions */
|
||||
case HB_SCRIPT_TIBETAN: ch = 0x0f40u; break;
|
||||
/* Unicode-4.0 additions */
|
||||
case HB_SCRIPT_LIMBU: ch = 0x1901u; break;
|
||||
/* Unicode-4.1 additions */
|
||||
case HB_SCRIPT_SYLOTI_NAGRI: ch = 0xa807u; break;
|
||||
/* Unicode-5.0 additions */
|
||||
case HB_SCRIPT_PHAGS_PA: ch = 0xa840u; break;
|
||||
/* Unicode-5.2 additions */
|
||||
case HB_SCRIPT_MEETEI_MAYEK: ch = 0xabc0u; break;
|
||||
/* Unicode-6.1 additions */
|
||||
case HB_SCRIPT_SHARADA: ch = 0x11191u; break;
|
||||
case HB_SCRIPT_TAKRI: ch = 0x1168cu; break;
|
||||
/* Unicode-7.0 additions */
|
||||
case HB_SCRIPT_MODI: ch = 0x1160eu;break;
|
||||
case HB_SCRIPT_SIDDHAM: ch = 0x11590u; break;
|
||||
case HB_SCRIPT_TIRHUTA: ch = 0x1148fu; break;
|
||||
/* Unicode-9.0 additions */
|
||||
case HB_SCRIPT_MARCHEN: ch = 0x11c72u; break;
|
||||
case HB_SCRIPT_NEWA: ch = 0x1140eu; break;
|
||||
/* Unicode-10.0 additions */
|
||||
case HB_SCRIPT_SOYOMBO: ch = 0x11a5cu; break;
|
||||
case HB_SCRIPT_ZANABAZAR_SQUARE: ch = 0x11a0bu; break;
|
||||
/* Unicode-11.0 additions */
|
||||
case HB_SCRIPT_DOGRA: ch = 0x1180au; break;
|
||||
case HB_SCRIPT_GUNJALA_GONDI: ch = 0x11d6cu; break;
|
||||
/* Unicode-12.0 additions */
|
||||
case HB_SCRIPT_NANDINAGARI: ch = 0x119b0u; break;
|
||||
default: ch = 0; break;
|
||||
}
|
||||
|
||||
if (ch &&
|
||||
hb_font_get_nominal_glyph (font, ch, &glyph) &&
|
||||
hb_font_get_glyph_extents (font, glyph, &extents))
|
||||
*coord = extents.y_bearing;
|
||||
else
|
||||
*coord = font->y_scale * 6 / 10; // FIXME makes assumptions about origin
|
||||
}
|
||||
else
|
||||
*coord = font->x_scale * 6 / 10; // FIXME makes assumptions about origin
|
||||
break;
|
||||
|
||||
case HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL:
|
||||
{
|
||||
hb_position_t top, bottom;
|
||||
hb_ot_layout_get_baseline_with_fallback (font,
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT,
|
||||
direction,
|
||||
script_tag,
|
||||
language_tag,
|
||||
&top);
|
||||
hb_ot_layout_get_baseline_with_fallback (font,
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT,
|
||||
direction,
|
||||
script_tag,
|
||||
language_tag,
|
||||
&bottom);
|
||||
*coord = (top + bottom) / 2;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL:
|
||||
{
|
||||
hb_position_t top, bottom;
|
||||
hb_ot_layout_get_baseline_with_fallback (font,
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT,
|
||||
direction,
|
||||
script_tag,
|
||||
language_tag,
|
||||
&top);
|
||||
hb_ot_layout_get_baseline_with_fallback (font,
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT,
|
||||
direction,
|
||||
script_tag,
|
||||
language_tag,
|
||||
&bottom);
|
||||
*coord = (top + bottom) / 2;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case _HB_OT_LAYOUT_BASELINE_TAG_MAX_VALUE:
|
||||
default:
|
||||
*coord = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -332,31 +332,6 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
|
|||
hb_set_t *glyphs_after, /* OUT. May be NULL */
|
||||
hb_set_t *glyphs_output /* OUT. May be NULL */);
|
||||
|
||||
#ifdef HB_NOT_IMPLEMENTED
|
||||
typedef struct
|
||||
{
|
||||
const hb_codepoint_t *before,
|
||||
unsigned int before_length,
|
||||
const hb_codepoint_t *input,
|
||||
unsigned int input_length,
|
||||
const hb_codepoint_t *after,
|
||||
unsigned int after_length,
|
||||
} hb_ot_layout_glyph_sequence_t;
|
||||
|
||||
typedef hb_bool_t
|
||||
(*hb_ot_layout_glyph_sequence_func_t) (hb_font_t *font,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int lookup_index,
|
||||
const hb_ot_layout_glyph_sequence_t *sequence,
|
||||
void *user_data);
|
||||
|
||||
HB_EXTERN void
|
||||
Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int lookup_index,
|
||||
hb_ot_layout_glyph_sequence_func_t callback,
|
||||
void *user_data);
|
||||
#endif
|
||||
|
||||
/* Variations support */
|
||||
|
||||
|
@ -411,19 +386,6 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
|
|||
hb_set_t *glyphs);
|
||||
|
||||
|
||||
#ifdef HB_NOT_IMPLEMENTED
|
||||
/* Note: You better have GDEF when using this API, or marks won't do much. */
|
||||
HB_EXTERN hb_bool_t
|
||||
Xhb_ot_layout_lookup_substitute (hb_font_t *font,
|
||||
unsigned int lookup_index,
|
||||
const hb_ot_layout_glyph_sequence_t *sequence,
|
||||
unsigned int out_size,
|
||||
hb_codepoint_t *glyphs_out, /* OUT */
|
||||
unsigned int *clusters_out, /* OUT */
|
||||
unsigned int *out_length /* OUT */);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* GPOS
|
||||
*/
|
||||
|
@ -431,15 +393,6 @@ Xhb_ot_layout_lookup_substitute (hb_font_t *font,
|
|||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_has_positioning (hb_face_t *face);
|
||||
|
||||
#ifdef HB_NOT_IMPLEMENTED
|
||||
/* Note: You better have GDEF when using this API, or marks won't do much. */
|
||||
HB_EXTERN hb_bool_t
|
||||
Xhb_ot_layout_lookup_position (hb_font_t *font,
|
||||
unsigned int lookup_index,
|
||||
const hb_ot_layout_glyph_sequence_t *sequence,
|
||||
hb_glyph_position_t *positions /* IN / OUT */);
|
||||
#endif
|
||||
|
||||
/* Optical 'size' feature info. Returns true if found.
|
||||
* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */
|
||||
HB_EXTERN hb_bool_t
|
||||
|
@ -487,9 +440,11 @@ hb_ot_layout_feature_get_characters (hb_face_t *face,
|
|||
* if the direction is horizontal or vertical, respectively.
|
||||
* @HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT: Ideographic character face top or right edge,
|
||||
* if the direction is horizontal or vertical, respectively.
|
||||
* @HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL: The center of the ideographic character face. Since: 4.0.0
|
||||
* @HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT: Ideographic em-box bottom or left edge,
|
||||
* if the direction is horizontal or vertical, respectively.
|
||||
* @HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT: Ideographic em-box top or right edge baseline,
|
||||
* @HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL: The center of the ideographic em-box. Since: 4.0.0
|
||||
* if the direction is horizontal or vertical, respectively.
|
||||
* @HB_OT_LAYOUT_BASELINE_TAG_MATH: The baseline about which mathematical characters are centered.
|
||||
* In vertical writing mode when mathematical characters rotated 90 degrees clockwise, are centered.
|
||||
|
@ -503,14 +458,19 @@ typedef enum {
|
|||
HB_OT_LAYOUT_BASELINE_TAG_HANGING = HB_TAG ('h','a','n','g'),
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT = HB_TAG ('i','c','f','b'),
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT = HB_TAG ('i','c','f','t'),
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL = HB_TAG ('I','c','f','c'),
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT = HB_TAG ('i','d','e','o'),
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT = HB_TAG ('i','d','t','p'),
|
||||
HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL = HB_TAG ('I','d','c','e'),
|
||||
HB_OT_LAYOUT_BASELINE_TAG_MATH = HB_TAG ('m','a','t','h'),
|
||||
|
||||
/*< private >*/
|
||||
_HB_OT_LAYOUT_BASELINE_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
|
||||
} hb_ot_layout_baseline_tag_t;
|
||||
|
||||
HB_EXTERN hb_ot_layout_baseline_tag_t
|
||||
hb_ot_layout_get_horizontal_baseline_tag_for_script (hb_script_t script);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_get_baseline (hb_font_t *font,
|
||||
hb_ot_layout_baseline_tag_t baseline_tag,
|
||||
|
@ -519,6 +479,14 @@ hb_ot_layout_get_baseline (hb_font_t *font,
|
|||
hb_tag_t language_tag,
|
||||
hb_position_t *coord /* OUT. May be NULL. */);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_layout_get_baseline_with_fallback (hb_font_t *font,
|
||||
hb_ot_layout_baseline_tag_t baseline_tag,
|
||||
hb_direction_t direction,
|
||||
hb_tag_t script_tag,
|
||||
hb_tag_t language_tag,
|
||||
hb_position_t *coord /* OUT */);
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_OT_LAYOUT_H */
|
||||
|
|
|
@ -485,6 +485,8 @@ static inline uint8_t
|
|||
_hb_allocate_lig_id (hb_buffer_t *buffer)
|
||||
{
|
||||
uint8_t lig_id = buffer->next_serial () & 0x07;
|
||||
if (unlikely (!lig_id))
|
||||
lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
|
||||
return lig_id;
|
||||
}
|
||||
|
||||
|
|
|
@ -238,6 +238,145 @@ hb_ot_metrics_get_position (hb_font_t *font,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_metrics_get_position_with_fallback:
|
||||
* @font: an #hb_font_t object.
|
||||
* @metrics_tag: tag of metrics value you like to fetch.
|
||||
* @position: (out) (optional): result of metrics value from the font.
|
||||
*
|
||||
* Fetches metrics value corresponding to @metrics_tag from @font,
|
||||
* and synthesizes a value if it the value is missing in the font.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
void
|
||||
hb_ot_metrics_get_position_with_fallback (hb_font_t *font,
|
||||
hb_ot_metrics_tag_t metrics_tag,
|
||||
hb_position_t *position /* OUT */)
|
||||
{
|
||||
hb_font_extents_t font_extents;
|
||||
hb_codepoint_t glyph;
|
||||
hb_glyph_extents_t extents;
|
||||
|
||||
if (hb_ot_metrics_get_position (font, metrics_tag, position))
|
||||
{
|
||||
if ((metrics_tag != HB_OT_METRICS_TAG_STRIKEOUT_SIZE &&
|
||||
metrics_tag != HB_OT_METRICS_TAG_UNDERLINE_SIZE) ||
|
||||
*position != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
switch (metrics_tag)
|
||||
{
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER:
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT:
|
||||
hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
|
||||
*position = font_extents.ascender;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_VERTICAL_ASCENDER:
|
||||
hb_font_get_extents_for_direction (font, HB_DIRECTION_TTB, &font_extents);
|
||||
*position = font_extents.ascender;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER:
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT:
|
||||
hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
|
||||
*position = font_extents.descender;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_VERTICAL_DESCENDER:
|
||||
hb_font_get_extents_for_direction (font, HB_DIRECTION_TTB, &font_extents);
|
||||
*position = font_extents.ascender;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP:
|
||||
hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
|
||||
*position = font_extents.line_gap;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_VERTICAL_LINE_GAP:
|
||||
hb_font_get_extents_for_direction (font, HB_DIRECTION_TTB, &font_extents);
|
||||
*position = font_extents.line_gap;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE:
|
||||
case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE:
|
||||
*position = 1;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN:
|
||||
case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN:
|
||||
*position = 0;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET:
|
||||
case HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET:
|
||||
*position = 0;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_X_HEIGHT:
|
||||
if (hb_font_get_nominal_glyph (font, 'x', &glyph) &&
|
||||
hb_font_get_glyph_extents (font, glyph, &extents))
|
||||
*position = extents.y_bearing;
|
||||
else
|
||||
*position = font->y_scale / 2;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_CAP_HEIGHT:
|
||||
if (hb_font_get_nominal_glyph (font, 'O', &glyph) &&
|
||||
hb_font_get_glyph_extents (font, glyph, &extents))
|
||||
*position = extents.height + 2 * extents.y_bearing;
|
||||
else
|
||||
*position = font->y_scale * 2 / 3;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_STRIKEOUT_SIZE:
|
||||
case HB_OT_METRICS_TAG_UNDERLINE_SIZE:
|
||||
*position = font->y_scale / 18;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_STRIKEOUT_OFFSET:
|
||||
{
|
||||
hb_position_t ascender;
|
||||
hb_ot_metrics_get_position_with_fallback (font,
|
||||
HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER,
|
||||
&ascender);
|
||||
*position = ascender / 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_UNDERLINE_OFFSET:
|
||||
*position = - font->y_scale / 18;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE:
|
||||
case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_SIZE:
|
||||
*position = font->x_scale * 10 / 12;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_SIZE:
|
||||
case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_SIZE:
|
||||
*position = font->y_scale * 10 / 12;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_OFFSET:
|
||||
case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET:
|
||||
*position = 0;
|
||||
break;
|
||||
|
||||
case HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET:
|
||||
case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET:
|
||||
*position = font->y_scale / 5;
|
||||
break;
|
||||
|
||||
case _HB_OT_METRICS_TAG_MAX_VALUE:
|
||||
default:
|
||||
*position = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
/**
|
||||
* hb_ot_metrics_get_variation:
|
||||
|
|
|
@ -110,6 +110,11 @@ hb_ot_metrics_get_position (hb_font_t *font,
|
|||
hb_ot_metrics_tag_t metrics_tag,
|
||||
hb_position_t *position /* OUT. May be NULL. */);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_metrics_get_position_with_fallback (hb_font_t *font,
|
||||
hb_ot_metrics_tag_t metrics_tag,
|
||||
hb_position_t *position /* OUT */);
|
||||
|
||||
HB_EXTERN float
|
||||
hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
|
||||
|
||||
|
|
|
@ -198,11 +198,10 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
|
|||
}
|
||||
|
||||
map->add_gsub_pause (final_reordering_indic);
|
||||
map->add_gsub_pause (_hb_clear_syllables);
|
||||
|
||||
for (; i < INDIC_NUM_FEATURES; i++)
|
||||
map->add_feature (indic_features[i]);
|
||||
|
||||
map->add_gsub_pause (_hb_clear_syllables);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -69,7 +69,7 @@ enum use_syllable_type_t {
|
|||
#define use_syllable_machine_ex_GB 5u
|
||||
#define use_syllable_machine_ex_H 12u
|
||||
#define use_syllable_machine_ex_HN 13u
|
||||
#define use_syllable_machine_ex_HVM 44u
|
||||
#define use_syllable_machine_ex_IS 44u
|
||||
#define use_syllable_machine_ex_J 50u
|
||||
#define use_syllable_machine_ex_MAbv 27u
|
||||
#define use_syllable_machine_ex_MBlw 28u
|
||||
|
@ -92,234 +92,449 @@ enum use_syllable_type_t {
|
|||
#define use_syllable_machine_ex_VMPst 39u
|
||||
#define use_syllable_machine_ex_VPre 22u
|
||||
#define use_syllable_machine_ex_VPst 35u
|
||||
#define use_syllable_machine_ex_WJ 16u
|
||||
#define use_syllable_machine_ex_ZWNJ 14u
|
||||
|
||||
|
||||
#line 99 "hb-ot-shape-complex-use-machine.hh"
|
||||
#line 100 "hb-ot-shape-complex-use-machine.hh"
|
||||
static const unsigned char _use_syllable_machine_trans_keys[] = {
|
||||
0u, 51u, 41u, 42u, 42u, 42u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, 23u, 48u,
|
||||
0u, 51u, 11u, 48u, 11u, 48u, 1u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u,
|
||||
45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 48u,
|
||||
23u, 48u, 23u, 48u, 23u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 11u, 48u,
|
||||
1u, 1u, 11u, 48u, 41u, 42u, 42u, 42u, 11u, 48u, 11u, 48u, 1u, 48u, 23u, 48u,
|
||||
24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u,
|
||||
1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u,
|
||||
11u, 48u, 1u, 48u, 13u, 13u, 4u, 4u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u,
|
||||
23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u,
|
||||
24u, 48u, 1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u,
|
||||
22u, 48u, 11u, 48u, 1u, 48u, 4u, 4u, 13u, 13u, 1u, 48u, 11u, 48u, 41u, 42u,
|
||||
42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, 0
|
||||
1u, 1u, 24u, 48u, 22u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 12u, 48u, 12u, 48u,
|
||||
12u, 48u, 12u, 48u, 11u, 48u, 1u, 1u, 13u, 13u, 4u, 4u, 11u, 48u, 11u, 48u,
|
||||
1u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u,
|
||||
24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 48u, 23u, 48u, 23u, 48u, 23u, 48u,
|
||||
12u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 11u, 48u, 1u, 1u, 11u, 48u, 11u, 48u,
|
||||
1u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u,
|
||||
24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 48u, 23u, 48u, 23u, 48u, 23u, 48u,
|
||||
12u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 11u, 48u, 1u, 1u, 4u, 4u, 13u, 13u,
|
||||
1u, 48u, 11u, 48u, 41u, 42u, 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u,
|
||||
0
|
||||
};
|
||||
|
||||
static const char _use_syllable_machine_key_spans[] = {
|
||||
52, 2, 1, 38, 38, 1, 27, 26,
|
||||
52, 38, 38, 48, 26, 24, 23, 22,
|
||||
2, 1, 25, 25, 25, 1, 25, 27,
|
||||
26, 26, 26, 37, 37, 37, 37, 38,
|
||||
1, 38, 2, 1, 38, 38, 48, 26,
|
||||
24, 23, 22, 2, 1, 25, 25, 25,
|
||||
1, 25, 26, 26, 26, 27, 27, 27,
|
||||
38, 48, 1, 1, 38, 38, 1, 27,
|
||||
26, 24, 23, 22, 2, 1, 25, 25,
|
||||
25, 1, 25, 26, 26, 26, 27, 27,
|
||||
27, 38, 48, 1, 1, 48, 38, 2,
|
||||
1, 5, 3, 4, 3
|
||||
1, 25, 27, 26, 26, 26, 37, 37,
|
||||
37, 37, 38, 1, 1, 1, 38, 38,
|
||||
48, 26, 24, 23, 22, 2, 1, 25,
|
||||
25, 25, 1, 25, 27, 26, 26, 26,
|
||||
37, 37, 37, 37, 38, 1, 38, 38,
|
||||
48, 26, 24, 23, 22, 2, 1, 25,
|
||||
25, 25, 1, 25, 27, 26, 26, 26,
|
||||
37, 37, 37, 37, 38, 1, 1, 1,
|
||||
48, 38, 2, 1, 5, 3, 4, 3
|
||||
};
|
||||
|
||||
static const short _use_syllable_machine_index_offsets[] = {
|
||||
0, 53, 56, 58, 97, 136, 138, 166,
|
||||
193, 218, 242, 265, 268, 270, 296, 322,
|
||||
348, 350, 376, 403, 430, 457, 485, 513,
|
||||
541, 580, 629, 631, 633, 672, 711, 713,
|
||||
741, 768, 793, 817, 840, 843, 845, 871,
|
||||
897, 923, 925, 951, 978, 1005, 1032, 1060,
|
||||
1088, 1116, 1155, 1204, 1206, 1208, 1257, 1296,
|
||||
1299, 1301, 1307, 1311, 1316
|
||||
0, 53, 92, 131, 180, 207, 232, 256,
|
||||
279, 282, 284, 310, 336, 362, 364, 390,
|
||||
418, 445, 472, 499, 537, 575, 613, 651,
|
||||
690, 692, 731, 734, 736, 775, 814, 863,
|
||||
890, 915, 939, 962, 965, 967, 993, 1019,
|
||||
1045, 1047, 1073, 1101, 1128, 1155, 1182, 1220,
|
||||
1258, 1296, 1334, 1373, 1375, 1377, 1379, 1418,
|
||||
1457, 1506, 1533, 1558, 1582, 1605, 1608, 1610,
|
||||
1636, 1662, 1688, 1690, 1716, 1744, 1771, 1798,
|
||||
1825, 1863, 1901, 1939, 1977, 2016, 2018, 2057,
|
||||
2096, 2145, 2172, 2197, 2221, 2244, 2247, 2249,
|
||||
2275, 2301, 2327, 2329, 2355, 2383, 2410, 2437,
|
||||
2464, 2502, 2540, 2578, 2616, 2655, 2657, 2659,
|
||||
2661, 2710, 2749, 2752, 2754, 2760, 2764, 2769
|
||||
};
|
||||
|
||||
static const char _use_syllable_machine_indicies[] = {
|
||||
0, 1, 2, 2, 3, 4, 2, 2,
|
||||
2, 2, 2, 5, 6, 7, 2, 2,
|
||||
2, 2, 8, 2, 2, 2, 9, 10,
|
||||
11, 12, 13, 14, 15, 9, 16, 17,
|
||||
18, 19, 20, 21, 2, 22, 23, 24,
|
||||
2, 25, 26, 27, 28, 29, 30, 31,
|
||||
6, 32, 2, 33, 2, 0, 35, 34,
|
||||
35, 34, 37, 38, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 36, 39, 40, 41,
|
||||
42, 43, 44, 45, 39, 46, 1, 47,
|
||||
48, 49, 50, 36, 51, 52, 53, 36,
|
||||
36, 36, 36, 54, 55, 56, 57, 38,
|
||||
36, 37, 38, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 39, 40, 41, 42,
|
||||
43, 44, 45, 39, 46, 47, 47, 48,
|
||||
49, 50, 36, 51, 52, 53, 36, 36,
|
||||
36, 36, 54, 55, 56, 57, 38, 36,
|
||||
37, 58, 39, 40, 41, 42, 43, 36,
|
||||
36, 36, 36, 36, 36, 48, 49, 50,
|
||||
36, 51, 52, 53, 36, 36, 36, 36,
|
||||
40, 55, 56, 57, 59, 36, 40, 41,
|
||||
42, 43, 36, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 51, 52, 53, 36,
|
||||
36, 36, 36, 36, 55, 56, 57, 59,
|
||||
36, 41, 42, 43, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 36, 36, 55, 56,
|
||||
57, 36, 42, 43, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 36, 36, 55, 56,
|
||||
57, 36, 43, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 36, 55, 56, 57,
|
||||
36, 55, 56, 36, 56, 36, 41, 42,
|
||||
43, 36, 36, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 51, 52, 53, 36, 36,
|
||||
36, 36, 36, 55, 56, 57, 59, 36,
|
||||
41, 42, 43, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 36, 36, 52, 53,
|
||||
36, 36, 36, 36, 36, 55, 56, 57,
|
||||
59, 36, 41, 42, 43, 36, 36, 36,
|
||||
36, 36, 36, 36, 36, 36, 36, 36,
|
||||
36, 53, 36, 36, 36, 36, 36, 55,
|
||||
56, 57, 59, 36, 61, 60, 41, 42,
|
||||
43, 36, 36, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 55, 56, 57, 59, 36,
|
||||
40, 41, 42, 43, 36, 36, 36, 36,
|
||||
36, 36, 48, 49, 50, 36, 51, 52,
|
||||
53, 36, 36, 36, 36, 40, 55, 56,
|
||||
57, 59, 36, 40, 41, 42, 43, 36,
|
||||
36, 36, 36, 36, 36, 36, 49, 50,
|
||||
36, 51, 52, 53, 36, 36, 36, 36,
|
||||
40, 55, 56, 57, 59, 36, 40, 41,
|
||||
42, 43, 36, 36, 36, 36, 36, 36,
|
||||
36, 36, 50, 36, 51, 52, 53, 36,
|
||||
36, 36, 36, 40, 55, 56, 57, 59,
|
||||
36, 39, 40, 41, 42, 43, 36, 45,
|
||||
39, 36, 36, 36, 48, 49, 50, 36,
|
||||
51, 52, 53, 36, 36, 36, 36, 40,
|
||||
55, 56, 57, 59, 36, 39, 40, 41,
|
||||
42, 43, 36, 36, 39, 36, 36, 36,
|
||||
48, 49, 50, 36, 51, 52, 53, 36,
|
||||
36, 36, 36, 40, 55, 56, 57, 59,
|
||||
36, 39, 40, 41, 42, 43, 44, 45,
|
||||
39, 36, 36, 36, 48, 49, 50, 36,
|
||||
51, 52, 53, 36, 36, 36, 36, 40,
|
||||
55, 56, 57, 59, 36, 37, 38, 36,
|
||||
36, 36, 36, 36, 36, 36, 36, 36,
|
||||
39, 40, 41, 42, 43, 44, 45, 39,
|
||||
46, 36, 47, 48, 49, 50, 36, 51,
|
||||
52, 53, 36, 36, 36, 36, 54, 55,
|
||||
56, 57, 38, 36, 37, 58, 58, 58,
|
||||
58, 58, 58, 58, 58, 58, 58, 58,
|
||||
58, 58, 58, 58, 58, 58, 58, 58,
|
||||
58, 58, 40, 41, 42, 43, 58, 58,
|
||||
58, 58, 58, 58, 58, 58, 58, 58,
|
||||
51, 52, 53, 58, 58, 58, 58, 58,
|
||||
55, 56, 57, 59, 58, 63, 62, 3,
|
||||
64, 37, 38, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 39, 40, 41, 42,
|
||||
43, 44, 45, 39, 46, 1, 47, 48,
|
||||
49, 50, 36, 51, 52, 53, 36, 0,
|
||||
35, 36, 54, 55, 56, 57, 38, 36,
|
||||
5, 6, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 9, 10, 11, 12, 13,
|
||||
14, 15, 9, 16, 18, 18, 19, 20,
|
||||
21, 65, 22, 23, 24, 65, 65, 65,
|
||||
65, 28, 29, 30, 31, 6, 65, 5,
|
||||
65, 9, 10, 11, 12, 13, 65, 65,
|
||||
65, 65, 65, 65, 19, 20, 21, 65,
|
||||
22, 23, 24, 65, 65, 65, 65, 10,
|
||||
29, 30, 31, 66, 65, 10, 11, 12,
|
||||
13, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 22, 23, 24, 65, 65,
|
||||
65, 65, 65, 29, 30, 31, 66, 65,
|
||||
11, 12, 13, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 29, 30, 31,
|
||||
65, 12, 13, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 29, 30, 31,
|
||||
65, 13, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 29, 30, 31, 65,
|
||||
29, 30, 65, 30, 65, 11, 12, 13,
|
||||
65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 22, 23, 24, 65, 65, 65,
|
||||
65, 65, 29, 30, 31, 66, 65, 11,
|
||||
12, 13, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 23, 24, 65,
|
||||
65, 65, 65, 65, 29, 30, 31, 66,
|
||||
65, 11, 12, 13, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65,
|
||||
24, 65, 65, 65, 65, 65, 29, 30,
|
||||
31, 66, 65, 67, 65, 11, 12, 13,
|
||||
65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 29, 30, 31, 66, 65, 10,
|
||||
11, 12, 13, 65, 65, 65, 65, 65,
|
||||
65, 19, 20, 21, 65, 22, 23, 24,
|
||||
65, 65, 65, 65, 10, 29, 30, 31,
|
||||
66, 65, 10, 11, 12, 13, 65, 65,
|
||||
65, 65, 65, 65, 65, 20, 21, 65,
|
||||
22, 23, 24, 65, 65, 65, 65, 10,
|
||||
29, 30, 31, 66, 65, 10, 11, 12,
|
||||
13, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 21, 65, 22, 23, 24, 65, 65,
|
||||
65, 65, 10, 29, 30, 31, 66, 65,
|
||||
9, 10, 11, 12, 13, 65, 15, 9,
|
||||
65, 65, 65, 19, 20, 21, 65, 22,
|
||||
23, 24, 65, 65, 65, 65, 10, 29,
|
||||
30, 31, 66, 65, 9, 10, 11, 12,
|
||||
13, 65, 65, 9, 65, 65, 65, 19,
|
||||
20, 21, 65, 22, 23, 24, 65, 65,
|
||||
65, 65, 10, 29, 30, 31, 66, 65,
|
||||
9, 10, 11, 12, 13, 14, 15, 9,
|
||||
65, 65, 65, 19, 20, 21, 65, 22,
|
||||
23, 24, 65, 65, 65, 65, 10, 29,
|
||||
30, 31, 66, 65, 5, 6, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 9,
|
||||
10, 11, 12, 13, 14, 15, 9, 16,
|
||||
65, 18, 19, 20, 21, 65, 22, 23,
|
||||
24, 65, 65, 65, 65, 28, 29, 30,
|
||||
31, 6, 65, 5, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 10, 11, 12, 13, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 22,
|
||||
23, 24, 65, 65, 65, 65, 65, 29,
|
||||
30, 31, 66, 65, 68, 65, 7, 65,
|
||||
1, 65, 65, 65, 1, 65, 65, 65,
|
||||
65, 65, 5, 6, 7, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 9, 10, 11,
|
||||
12, 13, 14, 15, 9, 16, 17, 18,
|
||||
19, 20, 21, 65, 22, 23, 24, 65,
|
||||
25, 26, 65, 28, 29, 30, 31, 6,
|
||||
65, 5, 6, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 9, 10, 11, 12,
|
||||
13, 14, 15, 9, 16, 17, 18, 19,
|
||||
20, 21, 65, 22, 23, 24, 65, 65,
|
||||
65, 65, 28, 29, 30, 31, 6, 65,
|
||||
25, 26, 65, 26, 65, 1, 69, 69,
|
||||
69, 1, 69, 71, 70, 32, 70, 32,
|
||||
71, 70, 71, 70, 32, 70, 33, 70,
|
||||
0
|
||||
11, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 20, 21, 22, 2, 23, 24, 25,
|
||||
2, 26, 27, 28, 29, 30, 31, 32,
|
||||
29, 33, 2, 34, 2, 36, 37, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 35,
|
||||
38, 39, 40, 41, 42, 43, 44, 45,
|
||||
46, 47, 48, 49, 50, 51, 35, 52,
|
||||
53, 54, 35, 55, 56, 35, 57, 58,
|
||||
59, 60, 57, 35, 36, 37, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 46,
|
||||
48, 48, 49, 50, 51, 35, 52, 53,
|
||||
54, 35, 35, 35, 35, 57, 58, 59,
|
||||
60, 57, 35, 36, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 39, 40, 41, 42, 35, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 52,
|
||||
53, 54, 35, 35, 35, 35, 35, 58,
|
||||
59, 60, 61, 35, 39, 40, 41, 42,
|
||||
35, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 35, 52, 53, 54, 35, 35, 35,
|
||||
35, 35, 58, 59, 60, 61, 35, 40,
|
||||
41, 42, 35, 35, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 58, 59, 60, 35,
|
||||
41, 42, 35, 35, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 58, 59, 60, 35,
|
||||
42, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 35, 35, 58, 59, 60, 35, 58,
|
||||
59, 35, 59, 35, 40, 41, 42, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 52, 53, 54, 35, 35, 35, 35,
|
||||
35, 58, 59, 60, 61, 35, 40, 41,
|
||||
42, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 53, 54, 35, 35,
|
||||
35, 35, 35, 58, 59, 60, 61, 35,
|
||||
40, 41, 42, 35, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 54,
|
||||
35, 35, 35, 35, 35, 58, 59, 60,
|
||||
61, 35, 62, 35, 40, 41, 42, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 58, 59, 60, 61, 35, 38, 39,
|
||||
40, 41, 42, 35, 35, 35, 35, 35,
|
||||
35, 49, 50, 51, 35, 52, 53, 54,
|
||||
35, 35, 35, 35, 35, 58, 59, 60,
|
||||
61, 35, 39, 40, 41, 42, 35, 35,
|
||||
35, 35, 35, 35, 49, 50, 51, 35,
|
||||
52, 53, 54, 35, 35, 35, 35, 35,
|
||||
58, 59, 60, 61, 35, 39, 40, 41,
|
||||
42, 35, 35, 35, 35, 35, 35, 35,
|
||||
50, 51, 35, 52, 53, 54, 35, 35,
|
||||
35, 35, 35, 58, 59, 60, 61, 35,
|
||||
39, 40, 41, 42, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 51, 35, 52, 53,
|
||||
54, 35, 35, 35, 35, 35, 58, 59,
|
||||
60, 61, 35, 39, 35, 35, 35, 35,
|
||||
35, 35, 35, 35, 35, 38, 39, 40,
|
||||
41, 42, 35, 44, 45, 35, 35, 35,
|
||||
49, 50, 51, 35, 52, 53, 54, 35,
|
||||
35, 35, 35, 35, 58, 59, 60, 61,
|
||||
35, 39, 35, 35, 35, 35, 35, 35,
|
||||
35, 35, 35, 38, 39, 40, 41, 42,
|
||||
35, 35, 45, 35, 35, 35, 49, 50,
|
||||
51, 35, 52, 53, 54, 35, 35, 35,
|
||||
35, 35, 58, 59, 60, 61, 35, 39,
|
||||
35, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 38, 39, 40, 41, 42, 35, 35,
|
||||
35, 35, 35, 35, 49, 50, 51, 35,
|
||||
52, 53, 54, 35, 35, 35, 35, 35,
|
||||
58, 59, 60, 61, 35, 39, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 35,
|
||||
35, 35, 49, 50, 51, 35, 52, 53,
|
||||
54, 35, 35, 35, 35, 35, 58, 59,
|
||||
60, 61, 35, 36, 37, 35, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 35,
|
||||
48, 49, 50, 51, 35, 52, 53, 54,
|
||||
35, 35, 35, 35, 57, 58, 59, 60,
|
||||
57, 35, 36, 35, 36, 37, 35, 35,
|
||||
35, 35, 35, 35, 35, 35, 35, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 46,
|
||||
47, 48, 49, 50, 51, 35, 52, 53,
|
||||
54, 35, 35, 35, 35, 57, 58, 59,
|
||||
60, 57, 35, 55, 56, 35, 56, 35,
|
||||
64, 65, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 66, 67, 68, 69, 70,
|
||||
71, 72, 73, 74, 1, 75, 76, 77,
|
||||
78, 63, 79, 80, 81, 63, 63, 63,
|
||||
63, 82, 83, 84, 85, 86, 63, 64,
|
||||
65, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 66, 67, 68, 69, 70, 71,
|
||||
72, 73, 74, 75, 75, 76, 77, 78,
|
||||
63, 79, 80, 81, 63, 63, 63, 63,
|
||||
82, 83, 84, 85, 86, 63, 64, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 67, 68, 69, 70,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 79, 80, 81, 63, 63, 63,
|
||||
63, 63, 83, 84, 85, 87, 63, 67,
|
||||
68, 69, 70, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 79, 80, 81,
|
||||
63, 63, 63, 63, 63, 83, 84, 85,
|
||||
87, 63, 68, 69, 70, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 83,
|
||||
84, 85, 63, 69, 70, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 83,
|
||||
84, 85, 63, 70, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 83, 84,
|
||||
85, 63, 83, 84, 63, 84, 63, 68,
|
||||
69, 70, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 79, 80, 81, 63,
|
||||
63, 63, 63, 63, 83, 84, 85, 87,
|
||||
63, 68, 69, 70, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 80,
|
||||
81, 63, 63, 63, 63, 63, 83, 84,
|
||||
85, 87, 63, 68, 69, 70, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 81, 63, 63, 63, 63, 63,
|
||||
83, 84, 85, 87, 63, 89, 88, 68,
|
||||
69, 70, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 83, 84, 85, 87,
|
||||
63, 66, 67, 68, 69, 70, 63, 63,
|
||||
63, 63, 63, 63, 76, 77, 78, 63,
|
||||
79, 80, 81, 63, 63, 63, 63, 63,
|
||||
83, 84, 85, 87, 63, 67, 68, 69,
|
||||
70, 63, 63, 63, 63, 63, 63, 76,
|
||||
77, 78, 63, 79, 80, 81, 63, 63,
|
||||
63, 63, 63, 83, 84, 85, 87, 63,
|
||||
67, 68, 69, 70, 63, 63, 63, 63,
|
||||
63, 63, 63, 77, 78, 63, 79, 80,
|
||||
81, 63, 63, 63, 63, 63, 83, 84,
|
||||
85, 87, 63, 67, 68, 69, 70, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 78,
|
||||
63, 79, 80, 81, 63, 63, 63, 63,
|
||||
63, 83, 84, 85, 87, 63, 67, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
66, 67, 68, 69, 70, 63, 72, 73,
|
||||
63, 63, 63, 76, 77, 78, 63, 79,
|
||||
80, 81, 63, 63, 63, 63, 63, 83,
|
||||
84, 85, 87, 63, 67, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 66, 67,
|
||||
68, 69, 70, 63, 63, 73, 63, 63,
|
||||
63, 76, 77, 78, 63, 79, 80, 81,
|
||||
63, 63, 63, 63, 63, 83, 84, 85,
|
||||
87, 63, 67, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 66, 67, 68, 69,
|
||||
70, 63, 63, 63, 63, 63, 63, 76,
|
||||
77, 78, 63, 79, 80, 81, 63, 63,
|
||||
63, 63, 63, 83, 84, 85, 87, 63,
|
||||
67, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 66, 67, 68, 69, 70, 71,
|
||||
72, 73, 63, 63, 63, 76, 77, 78,
|
||||
63, 79, 80, 81, 63, 63, 63, 63,
|
||||
63, 83, 84, 85, 87, 63, 64, 65,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 66, 67, 68, 69, 70, 71, 72,
|
||||
73, 74, 63, 75, 76, 77, 78, 63,
|
||||
79, 80, 81, 63, 63, 63, 63, 82,
|
||||
83, 84, 85, 86, 63, 64, 90, 92,
|
||||
91, 3, 93, 94, 95, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 96, 97,
|
||||
98, 99, 100, 101, 102, 103, 104, 105,
|
||||
106, 107, 108, 109, 63, 110, 111, 112,
|
||||
63, 55, 56, 63, 113, 114, 115, 85,
|
||||
116, 63, 94, 95, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 96, 97, 98,
|
||||
99, 100, 101, 102, 103, 104, 106, 106,
|
||||
107, 108, 109, 63, 110, 111, 112, 63,
|
||||
63, 63, 63, 113, 114, 115, 85, 116,
|
||||
63, 94, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 97,
|
||||
98, 99, 100, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 110, 111, 112,
|
||||
63, 63, 63, 63, 63, 114, 115, 85,
|
||||
117, 63, 97, 98, 99, 100, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
110, 111, 112, 63, 63, 63, 63, 63,
|
||||
114, 115, 85, 117, 63, 98, 99, 100,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 114, 115, 85, 63, 99, 100,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 114, 115, 85, 63, 100, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 114, 115, 85, 63, 114, 115, 63,
|
||||
115, 63, 98, 99, 100, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 110,
|
||||
111, 112, 63, 63, 63, 63, 63, 114,
|
||||
115, 85, 117, 63, 98, 99, 100, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 111, 112, 63, 63, 63, 63,
|
||||
63, 114, 115, 85, 117, 63, 98, 99,
|
||||
100, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 112, 63, 63,
|
||||
63, 63, 63, 114, 115, 85, 117, 63,
|
||||
118, 88, 98, 99, 100, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 114,
|
||||
115, 85, 117, 63, 96, 97, 98, 99,
|
||||
100, 63, 63, 63, 63, 63, 63, 107,
|
||||
108, 109, 63, 110, 111, 112, 63, 63,
|
||||
63, 63, 63, 114, 115, 85, 117, 63,
|
||||
97, 98, 99, 100, 63, 63, 63, 63,
|
||||
63, 63, 107, 108, 109, 63, 110, 111,
|
||||
112, 63, 63, 63, 63, 63, 114, 115,
|
||||
85, 117, 63, 97, 98, 99, 100, 63,
|
||||
63, 63, 63, 63, 63, 63, 108, 109,
|
||||
63, 110, 111, 112, 63, 63, 63, 63,
|
||||
63, 114, 115, 85, 117, 63, 97, 98,
|
||||
99, 100, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 109, 63, 110, 111, 112, 63,
|
||||
63, 63, 63, 63, 114, 115, 85, 117,
|
||||
63, 97, 63, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 96, 97, 98, 99, 100,
|
||||
63, 102, 103, 63, 63, 63, 107, 108,
|
||||
109, 63, 110, 111, 112, 63, 63, 63,
|
||||
63, 63, 114, 115, 85, 117, 63, 97,
|
||||
63, 63, 63, 63, 63, 63, 63, 63,
|
||||
63, 96, 97, 98, 99, 100, 63, 63,
|
||||
103, 63, 63, 63, 107, 108, 109, 63,
|
||||
110, 111, 112, 63, 63, 63, 63, 63,
|
||||
114, 115, 85, 117, 63, 97, 63, 63,
|
||||
63, 63, 63, 63, 63, 63, 63, 96,
|
||||
97, 98, 99, 100, 63, 63, 63, 63,
|
||||
63, 63, 107, 108, 109, 63, 110, 111,
|
||||
112, 63, 63, 63, 63, 63, 114, 115,
|
||||
85, 117, 63, 97, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 96, 97, 98,
|
||||
99, 100, 101, 102, 103, 63, 63, 63,
|
||||
107, 108, 109, 63, 110, 111, 112, 63,
|
||||
63, 63, 63, 63, 114, 115, 85, 117,
|
||||
63, 94, 95, 63, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 96, 97, 98, 99,
|
||||
100, 101, 102, 103, 104, 63, 106, 107,
|
||||
108, 109, 63, 110, 111, 112, 63, 63,
|
||||
63, 63, 113, 114, 115, 85, 116, 63,
|
||||
94, 90, 94, 95, 63, 63, 63, 63,
|
||||
63, 63, 63, 63, 63, 96, 97, 98,
|
||||
99, 100, 101, 102, 103, 104, 105, 106,
|
||||
107, 108, 109, 63, 110, 111, 112, 63,
|
||||
63, 63, 63, 113, 114, 115, 85, 116,
|
||||
63, 5, 6, 119, 119, 119, 119, 119,
|
||||
119, 119, 119, 119, 9, 10, 11, 12,
|
||||
13, 14, 15, 16, 17, 19, 19, 20,
|
||||
21, 22, 119, 23, 24, 25, 119, 119,
|
||||
119, 119, 29, 30, 31, 32, 29, 119,
|
||||
5, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 119, 119, 119, 119, 119, 10, 11,
|
||||
12, 13, 119, 119, 119, 119, 119, 119,
|
||||
119, 119, 119, 119, 23, 24, 25, 119,
|
||||
119, 119, 119, 119, 30, 31, 32, 120,
|
||||
119, 10, 11, 12, 13, 119, 119, 119,
|
||||
119, 119, 119, 119, 119, 119, 119, 23,
|
||||
24, 25, 119, 119, 119, 119, 119, 30,
|
||||
31, 32, 120, 119, 11, 12, 13, 119,
|
||||
119, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 30, 31, 32, 119, 12, 13, 119,
|
||||
119, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 30, 31, 32, 119, 13, 119, 119,
|
||||
119, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 119, 119, 119, 119, 119, 119, 119,
|
||||
30, 31, 32, 119, 30, 31, 119, 31,
|
||||
119, 11, 12, 13, 119, 119, 119, 119,
|
||||
119, 119, 119, 119, 119, 119, 23, 24,
|
||||
25, 119, 119, 119, 119, 119, 30, 31,
|
||||
32, 120, 119, 11, 12, 13, 119, 119,
|
||||
119, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 24, 25, 119, 119, 119, 119, 119,
|
||||
30, 31, 32, 120, 119, 11, 12, 13,
|
||||
119, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 119, 119, 119, 25, 119, 119, 119,
|
||||
119, 119, 30, 31, 32, 120, 119, 121,
|
||||
119, 11, 12, 13, 119, 119, 119, 119,
|
||||
119, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 119, 119, 119, 119, 119, 30, 31,
|
||||
32, 120, 119, 9, 10, 11, 12, 13,
|
||||
119, 119, 119, 119, 119, 119, 20, 21,
|
||||
22, 119, 23, 24, 25, 119, 119, 119,
|
||||
119, 119, 30, 31, 32, 120, 119, 10,
|
||||
11, 12, 13, 119, 119, 119, 119, 119,
|
||||
119, 20, 21, 22, 119, 23, 24, 25,
|
||||
119, 119, 119, 119, 119, 30, 31, 32,
|
||||
120, 119, 10, 11, 12, 13, 119, 119,
|
||||
119, 119, 119, 119, 119, 21, 22, 119,
|
||||
23, 24, 25, 119, 119, 119, 119, 119,
|
||||
30, 31, 32, 120, 119, 10, 11, 12,
|
||||
13, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 22, 119, 23, 24, 25, 119, 119,
|
||||
119, 119, 119, 30, 31, 32, 120, 119,
|
||||
10, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 119, 9, 10, 11, 12, 13, 119,
|
||||
15, 16, 119, 119, 119, 20, 21, 22,
|
||||
119, 23, 24, 25, 119, 119, 119, 119,
|
||||
119, 30, 31, 32, 120, 119, 10, 119,
|
||||
119, 119, 119, 119, 119, 119, 119, 119,
|
||||
9, 10, 11, 12, 13, 119, 119, 16,
|
||||
119, 119, 119, 20, 21, 22, 119, 23,
|
||||
24, 25, 119, 119, 119, 119, 119, 30,
|
||||
31, 32, 120, 119, 10, 119, 119, 119,
|
||||
119, 119, 119, 119, 119, 119, 9, 10,
|
||||
11, 12, 13, 119, 119, 119, 119, 119,
|
||||
119, 20, 21, 22, 119, 23, 24, 25,
|
||||
119, 119, 119, 119, 119, 30, 31, 32,
|
||||
120, 119, 10, 119, 119, 119, 119, 119,
|
||||
119, 119, 119, 119, 9, 10, 11, 12,
|
||||
13, 14, 15, 16, 119, 119, 119, 20,
|
||||
21, 22, 119, 23, 24, 25, 119, 119,
|
||||
119, 119, 119, 30, 31, 32, 120, 119,
|
||||
5, 6, 119, 119, 119, 119, 119, 119,
|
||||
119, 119, 119, 9, 10, 11, 12, 13,
|
||||
14, 15, 16, 17, 119, 19, 20, 21,
|
||||
22, 119, 23, 24, 25, 119, 119, 119,
|
||||
119, 29, 30, 31, 32, 29, 119, 5,
|
||||
119, 122, 119, 7, 119, 1, 119, 119,
|
||||
119, 1, 119, 119, 119, 119, 119, 5,
|
||||
6, 7, 119, 119, 119, 119, 119, 119,
|
||||
119, 119, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22,
|
||||
119, 23, 24, 25, 119, 26, 27, 119,
|
||||
29, 30, 31, 32, 29, 119, 5, 6,
|
||||
119, 119, 119, 119, 119, 119, 119, 119,
|
||||
119, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 119,
|
||||
23, 24, 25, 119, 119, 119, 119, 29,
|
||||
30, 31, 32, 29, 119, 26, 27, 119,
|
||||
27, 119, 1, 123, 123, 123, 1, 123,
|
||||
125, 124, 33, 124, 33, 125, 124, 125,
|
||||
124, 33, 124, 34, 124, 0
|
||||
};
|
||||
|
||||
static const char _use_syllable_machine_trans_targs[] = {
|
||||
1, 3, 0, 26, 28, 29, 30, 51,
|
||||
53, 31, 32, 33, 34, 35, 46, 47,
|
||||
48, 54, 49, 43, 44, 45, 38, 39,
|
||||
40, 55, 56, 57, 50, 36, 37, 0,
|
||||
58, 60, 0, 2, 0, 4, 5, 6,
|
||||
7, 8, 9, 10, 21, 22, 23, 24,
|
||||
18, 19, 20, 13, 14, 15, 25, 11,
|
||||
12, 0, 0, 16, 0, 17, 0, 27,
|
||||
0, 0, 41, 42, 52, 0, 0, 59
|
||||
1, 28, 0, 52, 54, 79, 80, 102,
|
||||
104, 92, 81, 82, 83, 84, 96, 97,
|
||||
98, 99, 105, 100, 93, 94, 95, 87,
|
||||
88, 89, 106, 107, 108, 101, 85, 86,
|
||||
0, 109, 111, 0, 2, 3, 15, 4,
|
||||
5, 6, 7, 19, 20, 21, 22, 25,
|
||||
23, 16, 17, 18, 10, 11, 12, 26,
|
||||
27, 24, 8, 9, 0, 13, 14, 0,
|
||||
29, 30, 42, 31, 32, 33, 34, 46,
|
||||
47, 48, 49, 50, 43, 44, 45, 37,
|
||||
38, 39, 51, 35, 36, 0, 51, 40,
|
||||
0, 41, 0, 0, 53, 0, 55, 56,
|
||||
68, 57, 58, 59, 60, 72, 73, 74,
|
||||
75, 78, 76, 69, 70, 71, 63, 64,
|
||||
65, 77, 61, 62, 77, 66, 67, 0,
|
||||
90, 91, 103, 0, 0, 110
|
||||
};
|
||||
|
||||
static const char _use_syllable_machine_trans_actions[] = {
|
||||
0, 0, 3, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 4,
|
||||
0, 0, 5, 0, 6, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, 0, 0, 5, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 7, 8, 0, 9, 0, 10, 0,
|
||||
11, 12, 0, 0, 0, 13, 14, 0
|
||||
0, 0, 0, 0, 6, 0, 0, 7,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 8, 0, 0, 9, 10, 0,
|
||||
11, 0, 12, 13, 0, 14, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 8, 0, 0, 10, 0, 0, 15,
|
||||
0, 0, 0, 16, 17, 0
|
||||
};
|
||||
|
||||
static const char _use_syllable_machine_to_state_actions[] = {
|
||||
|
@ -330,7 +545,13 @@ static const char _use_syllable_machine_to_state_actions[] = {
|
|||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const char _use_syllable_machine_from_state_actions[] = {
|
||||
|
@ -341,18 +562,30 @@ static const char _use_syllable_machine_from_state_actions[] = {
|
|||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const short _use_syllable_machine_eof_trans[] = {
|
||||
0, 35, 35, 37, 37, 59, 37, 37,
|
||||
37, 37, 37, 37, 37, 37, 37, 37,
|
||||
61, 37, 37, 37, 37, 37, 37, 37,
|
||||
37, 59, 63, 65, 37, 66, 66, 66,
|
||||
66, 66, 66, 66, 66, 66, 66, 66,
|
||||
66, 66, 66, 66, 66, 66, 66, 66,
|
||||
66, 66, 66, 66, 66, 66, 66, 66,
|
||||
66, 70, 71, 71, 71
|
||||
0, 36, 36, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 36, 36, 36, 36,
|
||||
36, 36, 36, 36, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
89, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 91, 92, 94, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 89, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 91, 64, 120,
|
||||
120, 120, 120, 120, 120, 120, 120, 120,
|
||||
120, 120, 120, 120, 120, 120, 120, 120,
|
||||
120, 120, 120, 120, 120, 120, 120, 120,
|
||||
120, 120, 120, 120, 124, 125, 125, 125
|
||||
};
|
||||
|
||||
static const int use_syllable_machine_start = 0;
|
||||
|
@ -366,7 +599,7 @@ static const int use_syllable_machine_en_main = 0;
|
|||
|
||||
|
||||
|
||||
#line 179 "hb-ot-shape-complex-use-machine.rl"
|
||||
#line 181 "hb-ot-shape-complex-use-machine.rl"
|
||||
|
||||
|
||||
#define found_syllable(syllable_type) \
|
||||
|
@ -385,7 +618,9 @@ struct machine_index_t :
|
|||
typename Iter::item_t>
|
||||
{
|
||||
machine_index_t (const Iter& it) : it (it) {}
|
||||
machine_index_t (const machine_index_t& o) : it (o.it) {}
|
||||
machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>,
|
||||
typename Iter::item_t> (),
|
||||
it (o.it) {}
|
||||
|
||||
static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
|
||||
static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
|
||||
|
@ -420,7 +655,7 @@ HB_FUNCOBJ (machine_index);
|
|||
|
||||
static bool
|
||||
not_ccs_default_ignorable (const hb_glyph_info_t &i)
|
||||
{ return !(i.use_category() == USE(CGJ) && _hb_glyph_info_is_default_ignorable (&i)); }
|
||||
{ return i.use_category() != USE(CGJ); }
|
||||
|
||||
static inline void
|
||||
find_syllables_use (hb_buffer_t *buffer)
|
||||
|
@ -449,7 +684,7 @@ find_syllables_use (hb_buffer_t *buffer)
|
|||
unsigned int act HB_UNUSED;
|
||||
int cs;
|
||||
|
||||
#line 453 "hb-ot-shape-complex-use-machine.hh"
|
||||
#line 688 "hb-ot-shape-complex-use-machine.hh"
|
||||
{
|
||||
cs = use_syllable_machine_start;
|
||||
ts = 0;
|
||||
|
@ -457,12 +692,12 @@ find_syllables_use (hb_buffer_t *buffer)
|
|||
act = 0;
|
||||
}
|
||||
|
||||
#line 263 "hb-ot-shape-complex-use-machine.rl"
|
||||
#line 267 "hb-ot-shape-complex-use-machine.rl"
|
||||
|
||||
|
||||
unsigned int syllable_serial = 1;
|
||||
|
||||
#line 466 "hb-ot-shape-complex-use-machine.hh"
|
||||
#line 701 "hb-ot-shape-complex-use-machine.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
|
@ -476,7 +711,7 @@ _resume:
|
|||
#line 1 "NONE"
|
||||
{ts = p;}
|
||||
break;
|
||||
#line 480 "hb-ot-shape-complex-use-machine.hh"
|
||||
#line 715 "hb-ot-shape-complex-use-machine.hh"
|
||||
}
|
||||
|
||||
_keys = _use_syllable_machine_trans_keys + (cs<<1);
|
||||
|
@ -494,55 +729,79 @@ _eof_trans:
|
|||
goto _again;
|
||||
|
||||
switch ( _use_syllable_machine_trans_actions[_trans] ) {
|
||||
case 7:
|
||||
#line 169 "hb-ot-shape-complex-use-machine.rl"
|
||||
case 9:
|
||||
#line 171 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p+1;{ found_syllable (use_standard_cluster); }}
|
||||
break;
|
||||
case 4:
|
||||
case 6:
|
||||
#line 174 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p+1;{ found_syllable (use_symbol_cluster); }}
|
||||
break;
|
||||
case 4:
|
||||
#line 176 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p+1;{ found_syllable (use_broken_cluster); }}
|
||||
break;
|
||||
case 3:
|
||||
#line 175 "hb-ot-shape-complex-use-machine.rl"
|
||||
#line 177 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p+1;{ found_syllable (use_non_cluster); }}
|
||||
break;
|
||||
case 8:
|
||||
#line 167 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p;p--;{ found_syllable (use_virama_terminated_cluster); }}
|
||||
break;
|
||||
case 9:
|
||||
#line 168 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
|
||||
break;
|
||||
case 6:
|
||||
#line 169 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p;p--;{ found_syllable (use_standard_cluster); }}
|
||||
break;
|
||||
case 11:
|
||||
#line 170 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
|
||||
break;
|
||||
case 7:
|
||||
#line 171 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p;p--;{ found_syllable (use_standard_cluster); }}
|
||||
break;
|
||||
case 14:
|
||||
#line 172 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }}
|
||||
break;
|
||||
case 10:
|
||||
#line 171 "hb-ot-shape-complex-use-machine.rl"
|
||||
case 13:
|
||||
#line 173 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p;p--;{ found_syllable (use_numeral_cluster); }}
|
||||
break;
|
||||
case 5:
|
||||
#line 172 "hb-ot-shape-complex-use-machine.rl"
|
||||
#line 174 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p;p--;{ found_syllable (use_symbol_cluster); }}
|
||||
break;
|
||||
case 14:
|
||||
#line 173 "hb-ot-shape-complex-use-machine.rl"
|
||||
case 17:
|
||||
#line 175 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p;p--;{ found_syllable (use_hieroglyph_cluster); }}
|
||||
break;
|
||||
case 12:
|
||||
#line 174 "hb-ot-shape-complex-use-machine.rl"
|
||||
case 15:
|
||||
#line 176 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p;p--;{ found_syllable (use_broken_cluster); }}
|
||||
break;
|
||||
case 13:
|
||||
#line 175 "hb-ot-shape-complex-use-machine.rl"
|
||||
case 16:
|
||||
#line 177 "hb-ot-shape-complex-use-machine.rl"
|
||||
{te = p;p--;{ found_syllable (use_non_cluster); }}
|
||||
break;
|
||||
#line 546 "hb-ot-shape-complex-use-machine.hh"
|
||||
case 12:
|
||||
#line 1 "NONE"
|
||||
{ switch( act ) {
|
||||
case 1:
|
||||
{{p = ((te))-1;} found_syllable (use_virama_terminated_cluster); }
|
||||
break;
|
||||
case 2:
|
||||
{{p = ((te))-1;} found_syllable (use_sakot_terminated_cluster); }
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
#line 1 "NONE"
|
||||
{te = p+1;}
|
||||
#line 169 "hb-ot-shape-complex-use-machine.rl"
|
||||
{act = 1;}
|
||||
break;
|
||||
case 10:
|
||||
#line 1 "NONE"
|
||||
{te = p+1;}
|
||||
#line 170 "hb-ot-shape-complex-use-machine.rl"
|
||||
{act = 2;}
|
||||
break;
|
||||
#line 805 "hb-ot-shape-complex-use-machine.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
|
@ -551,7 +810,7 @@ _again:
|
|||
#line 1 "NONE"
|
||||
{ts = 0;}
|
||||
break;
|
||||
#line 555 "hb-ot-shape-complex-use-machine.hh"
|
||||
#line 814 "hb-ot-shape-complex-use-machine.hh"
|
||||
}
|
||||
|
||||
if ( ++p != pe )
|
||||
|
@ -567,7 +826,7 @@ _again:
|
|||
|
||||
}
|
||||
|
||||
#line 268 "hb-ot-shape-complex-use-machine.rl"
|
||||
#line 272 "hb-ot-shape-complex-use-machine.rl"
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -73,9 +73,10 @@ export H = 12; # HALANT
|
|||
|
||||
export HN = 13; # HALANT_NUM
|
||||
export ZWNJ = 14; # Zero width non-joiner
|
||||
export WJ = 16; # Word joiner
|
||||
export R = 18; # REPHA
|
||||
export CS = 43; # CONS_WITH_STACKER
|
||||
export HVM = 44; # HALANT_OR_VOWEL_MODIFIER
|
||||
export IS = 44; # INVISIBLE_STACKER
|
||||
export Sk = 48; # SAKOT
|
||||
export G = 49; # HIEROGLYPH
|
||||
export J = 50; # HIEROGLYPH_JOINER
|
||||
|
@ -106,12 +107,12 @@ export FMBlw = 46; # CONS_FINAL_MOD UIPC = Bottom
|
|||
export FMPst = 47; # CONS_FINAL_MOD UIPC = Not_Applicable
|
||||
|
||||
|
||||
h = H | HVM | Sk;
|
||||
h = H | IS | Sk;
|
||||
|
||||
consonant_modifiers = CMAbv* CMBlw* ((h B | SUB) CMAbv? CMBlw*)*;
|
||||
medial_consonants = MPre? MAbv? MBlw? MPst?;
|
||||
dependent_vowels = VPre* VAbv* VBlw* VPst*;
|
||||
vowel_modifiers = HVM? VMPre* VMAbv* VMBlw* VMPst*;
|
||||
dependent_vowels = VPre* VAbv* VBlw* VPst* | H;
|
||||
vowel_modifiers = VMPre* VMAbv* VMBlw* VMPst*;
|
||||
final_consonants = FAbv* FBlw* FPst*;
|
||||
final_modifiers = FMAbv* FMBlw* | FMPst?;
|
||||
|
||||
|
@ -134,7 +135,7 @@ symbol_cluster_tail = SMAbv+ SMBlw* | SMBlw+;
|
|||
|
||||
virama_terminated_cluster_tail =
|
||||
consonant_modifiers
|
||||
h
|
||||
IS
|
||||
;
|
||||
virama_terminated_cluster =
|
||||
complex_syllable_start
|
||||
|
@ -152,14 +153,15 @@ standard_cluster =
|
|||
complex_syllable_start
|
||||
complex_syllable_tail
|
||||
;
|
||||
tail = complex_syllable_tail | sakot_terminated_cluster_tail | symbol_cluster_tail | virama_terminated_cluster_tail;
|
||||
broken_cluster =
|
||||
R?
|
||||
(complex_syllable_tail | number_joiner_terminated_cluster_tail | numeral_cluster_tail | symbol_cluster_tail | virama_terminated_cluster_tail | sakot_terminated_cluster_tail)
|
||||
(tail | number_joiner_terminated_cluster_tail | numeral_cluster_tail)
|
||||
;
|
||||
|
||||
number_joiner_terminated_cluster = N number_joiner_terminated_cluster_tail;
|
||||
numeral_cluster = N numeral_cluster_tail?;
|
||||
symbol_cluster = (O | GB) symbol_cluster_tail?;
|
||||
symbol_cluster = (O | GB) tail?;
|
||||
hieroglyph_cluster = SB+ | SB* G SE* (J SE* (G SE*)?)*;
|
||||
other = any;
|
||||
|
||||
|
@ -194,7 +196,9 @@ struct machine_index_t :
|
|||
typename Iter::item_t>
|
||||
{
|
||||
machine_index_t (const Iter& it) : it (it) {}
|
||||
machine_index_t (const machine_index_t& o) : it (o.it) {}
|
||||
machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>,
|
||||
typename Iter::item_t> (),
|
||||
it (o.it) {}
|
||||
|
||||
static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
|
||||
static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
|
||||
|
@ -229,7 +233,7 @@ HB_FUNCOBJ (machine_index);
|
|||
|
||||
static bool
|
||||
not_ccs_default_ignorable (const hb_glyph_info_t &i)
|
||||
{ return !(i.use_category() == USE(CGJ) && _hb_glyph_info_is_default_ignorable (&i)); }
|
||||
{ return i.use_category() != USE(CGJ); }
|
||||
|
||||
static inline void
|
||||
find_syllables_use (hb_buffer_t *buffer)
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -206,7 +206,7 @@ setup_masks_use (const hb_ot_shape_plan_t *plan,
|
|||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
info[i].use_category() = hb_use_get_category (info[i].codepoint);
|
||||
info[i].use_category() = hb_use_get_category (info[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -257,7 +257,6 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
|
|||
use_syllable_type_t syllable_type = (use_syllable_type_t) (info[start].syllable() & 0x0F);
|
||||
switch (syllable_type)
|
||||
{
|
||||
case use_symbol_cluster:
|
||||
case use_hieroglyph_cluster:
|
||||
case use_non_cluster:
|
||||
/* These don't join. Nothing to do. */
|
||||
|
@ -269,6 +268,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
|
|||
case use_standard_cluster:
|
||||
case use_number_joiner_terminated_cluster:
|
||||
case use_numeral_cluster:
|
||||
case use_symbol_cluster:
|
||||
case use_broken_cluster:
|
||||
|
||||
bool join = last_form == JOINING_FORM_FINA || last_form == JOINING_FORM_ISOL;
|
||||
|
@ -350,7 +350,7 @@ record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
static inline bool
|
||||
is_halant_use (const hb_glyph_info_t &info)
|
||||
{
|
||||
return (info.use_category() == USE(H) || info.use_category() == USE(HVM)) &&
|
||||
return (info.use_category() == USE(H) || info.use_category() == USE(IS)) &&
|
||||
!_hb_glyph_info_ligated (&info);
|
||||
}
|
||||
|
||||
|
@ -363,6 +363,7 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end)
|
|||
(FLAG (use_virama_terminated_cluster) |
|
||||
FLAG (use_sakot_terminated_cluster) |
|
||||
FLAG (use_standard_cluster) |
|
||||
FLAG (use_symbol_cluster) |
|
||||
FLAG (use_broken_cluster) |
|
||||
0))))
|
||||
return;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* on files with these headers:
|
||||
*
|
||||
* <meta name="updated_at" content="2022-01-28 10:00 PM" />
|
||||
* File-Date: 2021-12-29
|
||||
* File-Date: 2022-03-02
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_TAG_TABLE_HH
|
||||
|
@ -54,6 +54,7 @@ static const LangTag ot_languages[] = {
|
|||
/*{"aio", HB_TAG('A','I','O',' ')},*/ /* Aiton */
|
||||
{"aiw", HB_TAG('A','R','I',' ')}, /* Aari */
|
||||
{"ajp", HB_TAG('A','R','A',' ')}, /* South Levantine Arabic -> Arabic */
|
||||
{"ajt", HB_TAG('A','R','A',' ')}, /* Judeo-Tunisian Arabic (retired code) -> Arabic */
|
||||
{"ak", HB_TAG('A','K','A',' ')}, /* Akan [macrolanguage] */
|
||||
{"akb", HB_TAG('A','K','B',' ')}, /* Batak Angkola */
|
||||
{"akb", HB_TAG('B','T','K',' ')}, /* Batak Angkola -> Batak */
|
||||
|
@ -809,7 +810,7 @@ static const LangTag ot_languages[] = {
|
|||
{"lac", HB_TAG('M','Y','N',' ')}, /* Lacandon -> Mayan */
|
||||
{"lad", HB_TAG('J','U','D',' ')}, /* Ladino */
|
||||
{"lah", HB_TAG_NONE }, /* Lahnda [macrolanguage] != Lahuli */
|
||||
{"lak", HB_TAG_NONE }, /* Laka (Nigeria) != Lak */
|
||||
{"lak", HB_TAG_NONE }, /* Laka (Nigeria) (retired code) != Lak */
|
||||
{"lam", HB_TAG_NONE }, /* Lamba != Lambani */
|
||||
{"laz", HB_TAG_NONE }, /* Aribwatsa != Laz */
|
||||
{"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */
|
||||
|
@ -1339,12 +1340,14 @@ static const LangTag ot_languages[] = {
|
|||
{"sla", HB_TAG_NONE }, /* Slavic [collection] != Slavey */
|
||||
{"sm", HB_TAG('S','M','O',' ')}, /* Samoan */
|
||||
{"sma", HB_TAG('S','S','M',' ')}, /* Southern Sami */
|
||||
{"smd", HB_TAG('M','B','N',' ')}, /* Sama (retired code) -> Mbundu */
|
||||
{"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */
|
||||
{"sml", HB_TAG_NONE }, /* Central Sama != Somali */
|
||||
{"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */
|
||||
{"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */
|
||||
{"smt", HB_TAG('Q','I','N',' ')}, /* Simte -> Chin */
|
||||
{"sn", HB_TAG('S','N','A','0')}, /* Shona */
|
||||
{"snb", HB_TAG('I','B','A',' ')}, /* Sebuyau (retired code) -> Iban */
|
||||
{"snh", HB_TAG_NONE }, /* Shinabo (retired code) != Sinhala (Sinhalese) */
|
||||
/*{"snk", HB_TAG('S','N','K',' ')},*/ /* Soninke */
|
||||
{"so", HB_TAG('S','M','L',' ')}, /* Somali */
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
* For a detailed writeup on the overflow resolution algorithm see:
|
||||
* docs/repacker.md
|
||||
*/
|
||||
|
||||
struct graph_t
|
||||
{
|
||||
struct vertex_t
|
||||
|
@ -140,7 +139,8 @@ struct graph_t
|
|||
* the 'packed' object stack used internally in the
|
||||
* serializer
|
||||
*/
|
||||
graph_t (const hb_vector_t<hb_serialize_context_t::object_t *>& objects)
|
||||
template<typename T>
|
||||
graph_t (const T& objects)
|
||||
: parents_invalid (true),
|
||||
distance_invalid (true),
|
||||
positions_invalid (true),
|
||||
|
@ -1098,8 +1098,9 @@ struct graph_t
|
|||
hb_vector_t<unsigned> num_roots_for_space_;
|
||||
};
|
||||
|
||||
static bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& overflows,
|
||||
graph_t& sorted_graph)
|
||||
static inline
|
||||
bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& overflows,
|
||||
graph_t& sorted_graph)
|
||||
{
|
||||
unsigned space = 0;
|
||||
hb_set_t roots_to_isolate;
|
||||
|
@ -1147,9 +1148,10 @@ static bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& overflows,
|
||||
hb_set_t& priority_bumped_parents,
|
||||
graph_t& sorted_graph)
|
||||
static inline
|
||||
bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& overflows,
|
||||
hb_set_t& priority_bumped_parents,
|
||||
graph_t& sorted_graph)
|
||||
{
|
||||
bool resolution_attempted = false;
|
||||
|
||||
|
@ -1207,8 +1209,9 @@ static bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& o
|
|||
* For a detailed writeup describing how the algorithm operates see:
|
||||
* docs/repacker.md
|
||||
*/
|
||||
template<typename T>
|
||||
inline hb_blob_t*
|
||||
hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& packed,
|
||||
hb_resolve_overflows (const T& packed,
|
||||
hb_tag_t table_tag,
|
||||
unsigned max_rounds = 20) {
|
||||
// Kahn sort is ~twice as fast as shortest distance sort and works for many fonts
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
#include "hb-map.hh"
|
||||
#include "hb-pool.hh"
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
#include "hb-subset-repacker.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Serialize
|
||||
|
@ -70,6 +73,24 @@ struct hb_serialize_context_t
|
|||
virtual_links.fini ();
|
||||
}
|
||||
|
||||
object_t () = default;
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
object_t (const hb_object_t &o)
|
||||
{
|
||||
head = o.head;
|
||||
tail = o.tail;
|
||||
next = nullptr;
|
||||
real_links.alloc (o.num_real_links);
|
||||
for (unsigned i = 0 ; i < o.num_real_links; i++)
|
||||
real_links.push (o.real_links[i]);
|
||||
|
||||
virtual_links.alloc (o.num_virtual_links);
|
||||
for (unsigned i = 0; i < o.num_virtual_links; i++)
|
||||
virtual_links.push (o.virtual_links[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool operator == (const object_t &o) const
|
||||
{
|
||||
// Virtual links aren't considered for equality since they don't affect the functionality
|
||||
|
@ -95,6 +116,20 @@ struct hb_serialize_context_t
|
|||
unsigned position: 28;
|
||||
unsigned bias;
|
||||
objidx_t objidx;
|
||||
|
||||
link_t () = default;
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
link_t (const hb_link_t &o)
|
||||
{
|
||||
width = o.width;
|
||||
is_signed = 0;
|
||||
whence = 0;
|
||||
position = o.position;
|
||||
bias = 0;
|
||||
objidx = o.objidx;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
char *head;
|
||||
|
|
|
@ -256,6 +256,29 @@ hb_set_add (hb_set_t *set,
|
|||
set->add (codepoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_set_add_sorted_array:
|
||||
* @set: A set
|
||||
* @sorted_codepoints: (array length=num_codepoints): Array of codepoints to add
|
||||
* @num_codepoints: Length of @sorted_codepoints
|
||||
*
|
||||
* Adds @num_codepoints codepoints to a set at once.
|
||||
* The codepoints array must be in increasing order,
|
||||
* with size at least @num_codepoints.
|
||||
*
|
||||
* Since: 4.1.0
|
||||
*/
|
||||
HB_EXTERN void
|
||||
hb_set_add_sorted_array (hb_set_t *set,
|
||||
const hb_codepoint_t *sorted_codepoints,
|
||||
unsigned int num_codepoints)
|
||||
{
|
||||
/* Immutible-safe. */
|
||||
set->add_sorted_array (sorted_codepoints,
|
||||
num_codepoints,
|
||||
sizeof(hb_codepoint_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_set_add_range:
|
||||
* @set: A set
|
||||
|
|
|
@ -110,6 +110,11 @@ hb_set_add_range (hb_set_t *set,
|
|||
hb_codepoint_t first,
|
||||
hb_codepoint_t last);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_set_add_sorted_array (hb_set_t *set,
|
||||
const hb_codepoint_t *sorted_codepoints,
|
||||
unsigned int num_codepoints);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_set_del (hb_set_t *set,
|
||||
hb_codepoint_t codepoint);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "hb-aat-layout-feat-table.hh"
|
||||
#include "hb-ot-layout-common.hh"
|
||||
#include "hb-ot-cmap-table.hh"
|
||||
#include "hb-ot-glyf-table.hh"
|
||||
#include "hb-ot-head-table.hh"
|
||||
#include "hb-ot-maxp-table.hh"
|
||||
|
||||
|
@ -55,17 +56,43 @@ const unsigned char _hb_Null_AAT_Lookup[2] = {0xFF, 0xFF};
|
|||
|
||||
/* hb_face_t */
|
||||
|
||||
#ifndef HB_NO_BORING_EXPANSION
|
||||
static inline unsigned
|
||||
load_num_glyphs_from_loca (const hb_face_t *face)
|
||||
{
|
||||
unsigned ret = 0;
|
||||
|
||||
unsigned indexToLocFormat = face->table.head->indexToLocFormat;
|
||||
|
||||
if (indexToLocFormat <= 1)
|
||||
{
|
||||
bool short_offset = 0 == indexToLocFormat;
|
||||
hb_blob_t *loca_blob = face->table.loca.get_blob ();
|
||||
ret = hb_max (1u, loca_blob->length / (short_offset ? 2 : 4)) - 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline unsigned
|
||||
load_num_glyphs_from_maxp (const hb_face_t *face)
|
||||
{
|
||||
return face->table.maxp->get_num_glyphs ();
|
||||
}
|
||||
|
||||
unsigned int
|
||||
hb_face_t::load_num_glyphs () const
|
||||
{
|
||||
hb_sanitize_context_t c = hb_sanitize_context_t ();
|
||||
c.set_num_glyphs (0); /* So we don't recurse ad infinitum. */
|
||||
hb_blob_t *maxp_blob = c.reference_table<OT::maxp> (this);
|
||||
const OT::maxp *maxp_table = maxp_blob->as<OT::maxp> ();
|
||||
unsigned ret = 0;
|
||||
|
||||
#ifndef HB_NO_BORING_EXPANSION
|
||||
ret = hb_max (ret, load_num_glyphs_from_loca (this));
|
||||
#endif
|
||||
|
||||
ret = hb_max (ret, load_num_glyphs_from_maxp (this));
|
||||
|
||||
unsigned int ret = maxp_table->get_num_glyphs ();
|
||||
num_glyphs.set_relaxed (ret);
|
||||
hb_blob_destroy (maxp_blob);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,13 +46,13 @@
|
|||
static inline float
|
||||
_hb_angle_to_ratio (float a)
|
||||
{
|
||||
return tanf (a * float (M_PI / 180.));
|
||||
return tanf (a * float (-M_PI / 180.));
|
||||
}
|
||||
|
||||
static inline float
|
||||
_hb_ratio_to_angle (float r)
|
||||
{
|
||||
return atanf (r) * float (180. / M_PI);
|
||||
return atanf (r) * float (-180. / M_PI);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,8 +72,7 @@ float
|
|||
hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
|
||||
{
|
||||
if (unlikely (style_tag == HB_STYLE_TAG_SLANT_RATIO))
|
||||
return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE))
|
||||
+ font->slant;
|
||||
return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE));
|
||||
|
||||
hb_face_t *face = font->face;
|
||||
|
||||
|
|
|
@ -43,8 +43,10 @@ HB_BEGIN_DECLS
|
|||
* @HB_STYLE_TAG_SLANT_ANGLE: Used to vary between upright and slanted text. Values
|
||||
* must be greater than -90 and less than +90. Values can be interpreted as
|
||||
* the angle, in counter-clockwise degrees, of oblique slant from whatever the
|
||||
* designer considers to be upright for that font design.
|
||||
* designer considers to be upright for that font design. Typical right-leaning
|
||||
* Italic fonts have a negative slant angle (typically around -12)
|
||||
* @HB_STYLE_TAG_SLANT_RATIO: same as @HB_STYLE_TAG_SLANT_ANGLE expression as ratio.
|
||||
* Typical right-leaning Italic fonts have a positive slant ratio (typically around 0.2)
|
||||
* @HB_STYLE_TAG_WIDTH: Used to vary width of text from narrower to wider.
|
||||
* Non-zero. Values can be interpreted as a percentage of whatever the font
|
||||
* designer considers “normal width” for that font design.
|
||||
|
|
|
@ -111,7 +111,7 @@ static void _collect_layout_indices (hb_face_t *face,
|
|||
retain_all_features = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (visited_features.has (tag))
|
||||
continue;
|
||||
|
||||
|
@ -249,9 +249,9 @@ static void _colr_closure (hb_face_t *face,
|
|||
hb_set_t glyphset_colrv0;
|
||||
for (hb_codepoint_t gid : glyphs_colred->iter ())
|
||||
colr.closure_glyphs (gid, &glyphset_colrv0);
|
||||
|
||||
|
||||
glyphs_colred->union_ (glyphset_colrv0);
|
||||
|
||||
|
||||
//closure for COLRv1
|
||||
colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices);
|
||||
} while (iteration_count++ <= HB_CLOSURE_MAX_STAGES &&
|
||||
|
@ -458,7 +458,7 @@ _nameid_closure (hb_face_t *face,
|
|||
}
|
||||
|
||||
/**
|
||||
* hb_subset_plan_create:
|
||||
* hb_subset_plan_create_or_fail:
|
||||
* @face: font face to create the plan for.
|
||||
* @input: a #hb_subset_input_t input.
|
||||
*
|
||||
|
@ -467,17 +467,18 @@ _nameid_closure (hb_face_t *face,
|
|||
* which tables and glyphs should be retained.
|
||||
*
|
||||
* Return value: (transfer full): New subset plan. Destroy with
|
||||
* hb_subset_plan_destroy().
|
||||
* hb_subset_plan_destroy(). If there is a failure creating the plan
|
||||
* nullptr will be returned.
|
||||
*
|
||||
* Since: 1.7.5
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
hb_subset_plan_t *
|
||||
hb_subset_plan_create (hb_face_t *face,
|
||||
const hb_subset_input_t *input)
|
||||
hb_subset_plan_create_or_fail (hb_face_t *face,
|
||||
const hb_subset_input_t *input)
|
||||
{
|
||||
hb_subset_plan_t *plan;
|
||||
if (unlikely (!(plan = hb_object_create<hb_subset_plan_t> ())))
|
||||
return const_cast<hb_subset_plan_t *> (&Null (hb_subset_plan_t));
|
||||
return nullptr;
|
||||
|
||||
plan->successful = true;
|
||||
plan->flags = input->flags;
|
||||
|
@ -514,8 +515,9 @@ hb_subset_plan_create (hb_face_t *face,
|
|||
plan->layout_variation_indices = hb_set_create ();
|
||||
plan->layout_variation_idx_map = hb_map_create ();
|
||||
|
||||
if (plan->in_error ()) {
|
||||
return plan;
|
||||
if (unlikely (plan->in_error ())) {
|
||||
hb_subset_plan_destroy (plan);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
_populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, plan);
|
||||
|
@ -532,6 +534,10 @@ hb_subset_plan_create (hb_face_t *face,
|
|||
plan->reverse_glyph_map,
|
||||
&plan->_num_output_glyphs);
|
||||
|
||||
if (unlikely (plan->in_error ())) {
|
||||
hb_subset_plan_destroy (plan);
|
||||
return nullptr;
|
||||
}
|
||||
return plan;
|
||||
}
|
||||
|
||||
|
@ -542,7 +548,7 @@ hb_subset_plan_create (hb_face_t *face,
|
|||
* Decreases the reference count on @plan, and if it reaches zero, destroys
|
||||
* @plan, freeing all memory.
|
||||
*
|
||||
* Since: 1.7.5
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
void
|
||||
hb_subset_plan_destroy (hb_subset_plan_t *plan)
|
||||
|
@ -596,3 +602,116 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
|
|||
|
||||
hb_free (plan);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset_plan_old_to_new_glyph_mapping:
|
||||
* @plan: a subsetting plan.
|
||||
*
|
||||
* Returns the mapping between glyphs in the original font to glyphs in the
|
||||
* subset that will be produced by @plan
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
* A pointer to the #hb_map_t of the mapping.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
const hb_map_t*
|
||||
hb_subset_plan_old_to_new_glyph_mapping (const hb_subset_plan_t *plan)
|
||||
{
|
||||
return plan->glyph_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset_plan_new_to_old_glyph_mapping:
|
||||
* @plan: a subsetting plan.
|
||||
*
|
||||
* Returns the mapping between glyphs in the subset that will be produced by
|
||||
* @plan and the glyph in the original font.
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
* A pointer to the #hb_map_t of the mapping.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
const hb_map_t*
|
||||
hb_subset_plan_new_to_old_glyph_mapping (const hb_subset_plan_t *plan)
|
||||
{
|
||||
return plan->reverse_glyph_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset_plan_unicode_to_old_glyph_mapping:
|
||||
* @plan: a subsetting plan.
|
||||
*
|
||||
* Returns the mapping between codepoints in the original font and the
|
||||
* associated glyph id in the original font.
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
* A pointer to the #hb_map_t of the mapping.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
const hb_map_t*
|
||||
hb_subset_plan_unicode_to_old_glyph_mapping (const hb_subset_plan_t *plan)
|
||||
{
|
||||
return plan->codepoint_to_glyph;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset_plan_reference: (skip)
|
||||
* @plan: a #hb_subset_plan_t object.
|
||||
*
|
||||
* Increases the reference count on @plan.
|
||||
*
|
||||
* Return value: @plan.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
hb_subset_plan_t *
|
||||
hb_subset_plan_reference (hb_subset_plan_t *plan)
|
||||
{
|
||||
return hb_object_reference (plan);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset_plan_set_user_data: (skip)
|
||||
* @plan: a #hb_subset_plan_t object.
|
||||
* @key: The user-data key to set
|
||||
* @data: A pointer to the user data
|
||||
* @destroy: (nullable): A callback to call when @data is not needed anymore
|
||||
* @replace: Whether to replace an existing data with the same key
|
||||
*
|
||||
* Attaches a user-data key/data pair to the given subset plan object.
|
||||
*
|
||||
* Return value: %true if success, %false otherwise
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_subset_plan_set_user_data (hb_subset_plan_t *plan,
|
||||
hb_user_data_key_t *key,
|
||||
void *data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
return hb_object_set_user_data (plan, key, data, destroy, replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset_plan_get_user_data: (skip)
|
||||
* @plan: a #hb_subset_plan_t object.
|
||||
* @key: The user-data key to query
|
||||
*
|
||||
* Fetches the user data associated with the specified key,
|
||||
* attached to the specified subset plan object.
|
||||
*
|
||||
* Return value: (transfer none): A pointer to the user data
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
void *
|
||||
hb_subset_plan_get_user_data (const hb_subset_plan_t *plan,
|
||||
hb_user_data_key_t *key)
|
||||
{
|
||||
return hb_object_get_user_data (plan, key);
|
||||
}
|
||||
|
|
|
@ -198,13 +198,4 @@ struct hb_subset_plan_t
|
|||
}
|
||||
};
|
||||
|
||||
typedef struct hb_subset_plan_t hb_subset_plan_t;
|
||||
|
||||
HB_INTERNAL hb_subset_plan_t *
|
||||
hb_subset_plan_create (hb_face_t *face,
|
||||
const hb_subset_input_t *input);
|
||||
|
||||
HB_INTERNAL void
|
||||
hb_subset_plan_destroy (hb_subset_plan_t *plan);
|
||||
|
||||
#endif /* HB_SUBSET_PLAN_HH */
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright © 2022 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
#include "hb-repacker.hh"
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
/**
|
||||
* hb_subset_repack_or_fail:
|
||||
* @hb_objects: raw array of struct hb_object_t, which provides
|
||||
* object graph info
|
||||
* @num_hb_objs: number of hb_object_t in the hb_objects array.
|
||||
*
|
||||
* Given the input object graph info, repack a table to eliminate
|
||||
* offset overflows. A nullptr is returned if the repacking attempt fails.
|
||||
*
|
||||
* Since: EXPERIMENTAL
|
||||
**/
|
||||
hb_blob_t* hb_subset_repack_or_fail (hb_object_t* hb_objects, unsigned num_hb_objs)
|
||||
{
|
||||
hb_vector_t<const hb_object_t *> packed;
|
||||
packed.alloc (num_hb_objs + 1);
|
||||
packed.push (nullptr);
|
||||
for (unsigned i = 0 ; i < num_hb_objs ; i++)
|
||||
packed.push (&(hb_objects[i]));
|
||||
return hb_resolve_overflows (packed, HB_OT_TAG_GSUB);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright © 2022 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HB_SUBSET_REPACKER_H
|
||||
#define HB_SUBSET_REPACKER_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
/**
|
||||
* struct hb_link_t
|
||||
* width: offsetSize in bytes
|
||||
* position: position of the offset field in bytes
|
||||
* from beginning of subtable
|
||||
* objidx: index of subtable
|
||||
**/
|
||||
struct hb_link_t
|
||||
{
|
||||
unsigned width;
|
||||
unsigned position;
|
||||
unsigned objidx;
|
||||
};
|
||||
|
||||
typedef struct hb_link_t hb_link_t;
|
||||
|
||||
/**
|
||||
* struct hb_object_t
|
||||
* head: start of object data
|
||||
* tail: end of object data
|
||||
* num_real_links: num of offset field in the object
|
||||
* real_links: pointer to array of offset info
|
||||
* num_virtual_links: num of objects that must be packed
|
||||
* after current object in the final serialized order
|
||||
* virtual_links: array of virtual link info
|
||||
**/
|
||||
struct hb_object_t
|
||||
{
|
||||
char *head;
|
||||
char *tail;
|
||||
unsigned num_real_links;
|
||||
hb_link_t *real_links;
|
||||
unsigned num_virtual_links;
|
||||
hb_link_t *virtual_links;
|
||||
};
|
||||
|
||||
typedef struct hb_object_t hb_object_t;
|
||||
|
||||
HB_EXTERN hb_blob_t*
|
||||
hb_subset_repack_or_fail (hb_object_t* hb_objects,
|
||||
unsigned num_hb_objs);
|
||||
|
||||
#endif
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_SUBSET_REPACKER_H */
|
|
@ -343,9 +343,33 @@ hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input)
|
|||
{
|
||||
if (unlikely (!input || !source)) return hb_face_get_empty ();
|
||||
|
||||
hb_subset_plan_t *plan = hb_subset_plan_create (source, input);
|
||||
if (unlikely (plan->in_error ())) {
|
||||
hb_subset_plan_destroy (plan);
|
||||
hb_subset_plan_t *plan = hb_subset_plan_create_or_fail (source, input);
|
||||
if (unlikely (!plan)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hb_face_t * result = hb_subset_plan_execute_or_fail (plan);
|
||||
hb_subset_plan_destroy (plan);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_subset_plan_execute_or_fail:
|
||||
* @plan: a subsetting plan.
|
||||
*
|
||||
* Executes the provided subsetting @plan.
|
||||
*
|
||||
* Return value:
|
||||
* on success returns a reference to generated font subset. If the subsetting operation fails
|
||||
* returns nullptr.
|
||||
*
|
||||
* Since: 4.0.0
|
||||
**/
|
||||
hb_face_t *
|
||||
hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan)
|
||||
{
|
||||
if (unlikely (!plan || plan->in_error ())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -353,7 +377,7 @@ hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input)
|
|||
bool success = true;
|
||||
hb_tag_t table_tags[32];
|
||||
unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags);
|
||||
while ((hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables))
|
||||
while ((hb_face_get_table_tags (plan->source, offset, &num_tables, table_tags), num_tables))
|
||||
{
|
||||
for (unsigned i = 0; i < num_tables; ++i)
|
||||
{
|
||||
|
@ -367,8 +391,5 @@ hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input)
|
|||
}
|
||||
end:
|
||||
|
||||
hb_face_t *result = success ? hb_face_reference (plan->dest) : nullptr;
|
||||
|
||||
hb_subset_plan_destroy (plan);
|
||||
return result;
|
||||
return success ? hb_face_reference (plan->dest) : nullptr;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,15 @@ HB_BEGIN_DECLS
|
|||
|
||||
typedef struct hb_subset_input_t hb_subset_input_t;
|
||||
|
||||
/**
|
||||
* hb_subset_plan_t:
|
||||
*
|
||||
* Contains information about how the subset operation will be executed.
|
||||
* Such as mappings from the old glyph ids to the new ones in the subset.
|
||||
*/
|
||||
|
||||
typedef struct hb_subset_plan_t hb_subset_plan_t;
|
||||
|
||||
/**
|
||||
* hb_subset_flags_t:
|
||||
* @HB_SUBSET_FLAGS_DEFAULT: all flags at their default value of false.
|
||||
|
@ -124,7 +133,7 @@ hb_subset_input_set_user_data (hb_subset_input_t *input,
|
|||
|
||||
HB_EXTERN void *
|
||||
hb_subset_input_get_user_data (const hb_subset_input_t *input,
|
||||
hb_user_data_key_t *key);
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
HB_EXTERN hb_set_t *
|
||||
hb_subset_input_unicode_set (hb_subset_input_t *input);
|
||||
|
@ -145,6 +154,41 @@ hb_subset_input_set_flags (hb_subset_input_t *input,
|
|||
HB_EXTERN hb_face_t *
|
||||
hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input);
|
||||
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan);
|
||||
|
||||
HB_EXTERN hb_subset_plan_t *
|
||||
hb_subset_plan_create_or_fail (hb_face_t *face,
|
||||
const hb_subset_input_t *input);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_subset_plan_destroy (hb_subset_plan_t *plan);
|
||||
|
||||
HB_EXTERN const hb_map_t*
|
||||
hb_subset_plan_old_to_new_glyph_mapping (const hb_subset_plan_t *plan);
|
||||
|
||||
HB_EXTERN const hb_map_t*
|
||||
hb_subset_plan_new_to_old_glyph_mapping (const hb_subset_plan_t *plan);
|
||||
|
||||
HB_EXTERN const hb_map_t*
|
||||
hb_subset_plan_unicode_to_old_glyph_mapping (const hb_subset_plan_t *plan);
|
||||
|
||||
|
||||
HB_EXTERN hb_subset_plan_t *
|
||||
hb_subset_plan_reference (hb_subset_plan_t *plan);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_subset_plan_set_user_data (hb_subset_plan_t *plan,
|
||||
hb_user_data_key_t *key,
|
||||
void *data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
HB_EXTERN void *
|
||||
hb_subset_plan_get_user_data (const hb_subset_plan_t *plan,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_SUBSET_H */
|
||||
|
|
|
@ -41,13 +41,13 @@ HB_BEGIN_DECLS
|
|||
*
|
||||
* The major component of the library version available at compile-time.
|
||||
*/
|
||||
#define HB_VERSION_MAJOR 3
|
||||
#define HB_VERSION_MAJOR 4
|
||||
/**
|
||||
* HB_VERSION_MINOR:
|
||||
*
|
||||
* The minor component of the library version available at compile-time.
|
||||
*/
|
||||
#define HB_VERSION_MINOR 4
|
||||
#define HB_VERSION_MINOR 1
|
||||
/**
|
||||
* HB_VERSION_MICRO:
|
||||
*
|
||||
|
@ -60,7 +60,7 @@ HB_BEGIN_DECLS
|
|||
*
|
||||
* A string literal containing the library version available at compile-time.
|
||||
*/
|
||||
#define HB_VERSION_STRING "3.4.0"
|
||||
#define HB_VERSION_STRING "4.1.0"
|
||||
|
||||
/**
|
||||
* HB_VERSION_ATLEAST:
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#define hb_blob_create_from_file_or_fail(x) hb_blob_get_empty ()
|
||||
#endif
|
||||
|
||||
#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW) && defined(HB_EXPERIMENTAL_API)
|
||||
#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW)
|
||||
static void
|
||||
svg_dump (hb_face_t *face, unsigned face_index)
|
||||
{
|
||||
|
@ -129,48 +129,60 @@ png_dump (hb_face_t *face, unsigned face_index)
|
|||
hb_font_destroy (font);
|
||||
}
|
||||
|
||||
struct user_data_t
|
||||
struct draw_data_t
|
||||
{
|
||||
FILE *f;
|
||||
hb_position_t ascender;
|
||||
};
|
||||
|
||||
static void
|
||||
move_to (hb_position_t to_x, hb_position_t to_y, user_data_t &user_data)
|
||||
move_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float to_x, float to_y,
|
||||
void *)
|
||||
{
|
||||
fprintf (user_data.f, "M%d,%d", to_x, user_data.ascender - to_y);
|
||||
fprintf (draw_data->f, "M%g,%g", to_x, draw_data->ascender - to_y);
|
||||
}
|
||||
|
||||
static void
|
||||
line_to (hb_position_t to_x, hb_position_t to_y, user_data_t &user_data)
|
||||
line_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float to_x, float to_y,
|
||||
void *)
|
||||
{
|
||||
fprintf (user_data.f, "L%d,%d", to_x, user_data.ascender - to_y);
|
||||
fprintf (draw_data->f, "L%g,%g", to_x, draw_data->ascender - to_y);
|
||||
}
|
||||
|
||||
static void
|
||||
quadratic_to (hb_position_t control_x, hb_position_t control_y,
|
||||
hb_position_t to_x, hb_position_t to_y,
|
||||
user_data_t &user_data)
|
||||
quadratic_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float control_x, float control_y,
|
||||
float to_x, float to_y,
|
||||
void *)
|
||||
{
|
||||
fprintf (user_data.f, "Q%d,%d %d,%d", control_x, user_data.ascender - control_y,
|
||||
to_x, user_data.ascender - to_y);
|
||||
fprintf (draw_data->f, "Q%g,%g %g,%g", control_x, draw_data->ascender - control_y,
|
||||
to_x, draw_data->ascender - to_y);
|
||||
}
|
||||
|
||||
static void
|
||||
cubic_to (hb_position_t control1_x, hb_position_t control1_y,
|
||||
hb_position_t control2_x, hb_position_t control2_y,
|
||||
hb_position_t to_x, hb_position_t to_y,
|
||||
user_data_t &user_data)
|
||||
cubic_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
float control1_x, float control1_y,
|
||||
float control2_x, float control2_y,
|
||||
float to_x, float to_y,
|
||||
void *)
|
||||
{
|
||||
fprintf (user_data.f, "C%d,%d %d,%d %d,%d", control1_x, user_data.ascender - control1_y,
|
||||
control2_x, user_data.ascender - control2_y,
|
||||
to_x, user_data.ascender - to_y);
|
||||
fprintf (draw_data->f, "C%g,%g %g,%g %g,%g", control1_x, draw_data->ascender - control1_y,
|
||||
control2_x, draw_data->ascender - control2_y,
|
||||
to_x, draw_data->ascender - to_y);
|
||||
}
|
||||
|
||||
static void
|
||||
close_path (user_data_t &user_data)
|
||||
close_path (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
hb_draw_state_t *st,
|
||||
void *)
|
||||
{
|
||||
fprintf (user_data.f, "Z");
|
||||
fprintf (draw_data->f, "Z");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -218,9 +230,9 @@ layered_glyph_dump (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index
|
|||
" viewBox=\"%d %d %d %d\">\n",
|
||||
extents.x_bearing, 0,
|
||||
extents.x_bearing + extents.width, -extents.height);
|
||||
user_data_t user_data;
|
||||
user_data.ascender = extents.y_bearing;
|
||||
user_data.f = f;
|
||||
draw_data_t draw_data;
|
||||
draw_data.ascender = extents.y_bearing;
|
||||
draw_data.f = f;
|
||||
|
||||
for (unsigned layer = 0; layer < num_layers; ++layer)
|
||||
{
|
||||
|
@ -232,8 +244,7 @@ layered_glyph_dump (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index
|
|||
if (hb_color_get_alpha (color) != 255)
|
||||
fprintf (f, "fill-opacity=\"%.3f\"", (double) hb_color_get_alpha (color) / 255.);
|
||||
fprintf (f, "d=\"");
|
||||
if (!hb_font_draw_glyph (font, layers[layer].glyph, funcs, &user_data))
|
||||
printf ("Failed to decompose layer %d while %d\n", layers[layer].glyph, gid);
|
||||
hb_font_get_glyph_shape (font, layers[layer].glyph, funcs, &draw_data);
|
||||
fprintf (f, "\"/>\n");
|
||||
}
|
||||
|
||||
|
@ -269,11 +280,10 @@ dump_glyphs (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index)
|
|||
" viewBox=\"%d %d %d %d\"><path d=\"",
|
||||
extents.x_bearing, 0,
|
||||
extents.x_bearing + extents.width, font_extents.ascender - font_extents.descender);
|
||||
user_data_t user_data;
|
||||
user_data.ascender = font_extents.ascender;
|
||||
user_data.f = f;
|
||||
if (!hb_font_draw_glyph (font, gid, funcs, &user_data))
|
||||
printf ("Failed to decompose gid: %d\n", gid);
|
||||
draw_data_t draw_data;
|
||||
draw_data.ascender = font_extents.ascender;
|
||||
draw_data.f = f;
|
||||
hb_font_get_glyph_shape (font, gid, funcs, &draw_data);
|
||||
fprintf (f, "\"/></svg>");
|
||||
fclose (f);
|
||||
}
|
||||
|
@ -300,11 +310,11 @@ dump_glyphs (hb_blob_t *blob, const char *font_name)
|
|||
fclose (font_name_file);
|
||||
|
||||
hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
|
||||
hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to);
|
||||
hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to);
|
||||
hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to);
|
||||
hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to);
|
||||
hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path);
|
||||
hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, nullptr, nullptr);
|
||||
hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, nullptr, nullptr);
|
||||
hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to, nullptr, nullptr);
|
||||
hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, nullptr, nullptr);
|
||||
hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, nullptr, nullptr);
|
||||
|
||||
unsigned num_faces = hb_face_count (blob);
|
||||
for (unsigned face_index = 0; face_index < num_faces; ++face_index)
|
||||
|
@ -512,7 +522,7 @@ main (int argc, char **argv)
|
|||
#ifndef MAIN_CC_NO_PRIVATE_API
|
||||
print_layout_info_using_private_api (blob);
|
||||
#endif
|
||||
#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW) && defined(HB_EXPERIMENTAL_API)
|
||||
#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW)
|
||||
dump_glyphs (blob, argv[1]);
|
||||
#endif
|
||||
hb_blob_destroy (blob);
|
||||
|
|
|
@ -276,11 +276,15 @@ hb_subset_sources = files(
|
|||
'hb-subset-input.hh',
|
||||
'hb-subset-plan.cc',
|
||||
'hb-subset-plan.hh',
|
||||
'hb-subset-repacker.cc',
|
||||
'hb-subset.cc',
|
||||
'hb-subset.hh',
|
||||
)
|
||||
|
||||
hb_subset_headers = files('hb-subset.h')
|
||||
hb_subset_headers = files(
|
||||
'hb-subset.h',
|
||||
'hb-subset-repacker.h'
|
||||
)
|
||||
|
||||
hb_gobject_sources = files(
|
||||
'hb-gobject-structs.cc'
|
||||
|
|
|
@ -86,6 +86,7 @@ UNIFIED_SOURCES += [
|
|||
'hb-subset-cff-common.cc',
|
||||
'hb-subset-cff1.cc',
|
||||
'hb-subset-cff2.cc',
|
||||
'hb-subset-repacker.cc',
|
||||
'hb-unicode.cc',
|
||||
]
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Not derivable
|
||||
# Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
|
||||
# Updated for Unicode 10.0 by Andrew Glass 2017-07-25
|
||||
# Amended for Unicode 10.0 by Andrew Glass 2018-09-21
|
||||
# Ammended for Unicode 10.0 by Andrew Glass 2018-09-21
|
||||
# Updated for L2/19-083 by Andrew Glass 2019-05-06
|
||||
# Updated for Unicode 12.1 by Andrew Glass 2019-05-30
|
||||
# Updated for Unicode 13.0 by Andrew Glass 2020-07-28
|
||||
|
@ -58,16 +58,16 @@ AA35 ; Top # Mn CHAM CONSONANT SIGN
|
|||
# Indic_Positional_Category=Bottom
|
||||
0859..085B ; Bottom # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK
|
||||
18A9 ; Bottom # Mn MONGOLIAN LETTER ALI GALI DAGALGA
|
||||
10AE5 ; Bottom # Mn MANICHAEAN ABBREVIATION MARK ABOVE # Overridden, ccc controls order
|
||||
10AE5 ; Bottom # Mn MANICHAEAN ABBREVIATION MARK ABOVE # Overriden, ccc controls order
|
||||
10AE6 ; Bottom # Mn MANICHAEAN ABBREVIATION MARK BELOW
|
||||
10F46..10F47 ; Bottom # Mn [2] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING TWO DOTS BELOW
|
||||
10F48..10F4A ; Bottom # Mn [3] SOGDIAN COMBINING DOT ABOVE..SOGDIAN COMBINING CURVE ABOVE # Overridden, ccc controls order
|
||||
10F48..10F4A ; Bottom # Mn [3] SOGDIAN COMBINING DOT ABOVE..SOGDIAN COMBINING CURVE ABOVE # Overriden, ccc controls order
|
||||
10F4B ; Bottom # Mn SOGDIAN COMBINING CURVE BELOW
|
||||
10F4C ; Bottom # Mn SOGDIAN COMBINING HOOK ABOVE # Overridden, ccc controls order
|
||||
10F4C ; Bottom # Mn SOGDIAN COMBINING HOOK ABOVE # Overriden, ccc controls order
|
||||
10F4D..10F50 ; Bottom # Mn [4] SOGDIAN COMBINING HOOK BELOW..SOGDIAN COMBINING STROKE BELOW
|
||||
10F82 ; Bottom # Mn OLD UYGHUR COMBINING DOT ABOVE # Overridden, ccc controls order
|
||||
10F82 ; Bottom # Mn OLD UYGHUR COMBINING DOT ABOVE # Overriden, ccc controls order
|
||||
10F83 ; Bottom # Mn OLD UYGHUR COMBINING DOT BELOW
|
||||
10F84 ; Bottom # Mn OLD UYGHUR COMBINING TWO DOTS ABOVE # Overridden, ccc controls order
|
||||
10F84 ; Bottom # Mn OLD UYGHUR COMBINING TWO DOTS ABOVE # Overriden, ccc controls order
|
||||
10F85 ; Bottom # Mn OLD UYGHUR COMBINING TWO DOTS BELOW
|
||||
16F4F ; Bottom # Mn MIAO SIGN CONSONANT MODIFIER BAR
|
||||
16F51..16F87 ; Bottom # Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
MY_TEMP_DIR=`mktemp -d -t harfbuzz_update.XXXXXX` || exit 1
|
||||
|
||||
VERSION=3.4.0
|
||||
VERSION=4.1.0
|
||||
|
||||
git clone https://github.com/harfbuzz/harfbuzz ${MY_TEMP_DIR}/harfbuzz
|
||||
git -C ${MY_TEMP_DIR}/harfbuzz checkout ${VERSION}
|
||||
|
|
Загрузка…
Ссылка в новой задаче