Add stripped version of HarfBuzz-NG 0.9.19 sources to 3rdparty
Change-Id: I06fbf58131ebce51ce95921d8dfd65dd3d3e236f Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
79e77a58a6
commit
9ece604d9b
8
src/3rdparty/harfbuzz-ng/AUTHORS
vendored
Normal file
8
src/3rdparty/harfbuzz-ng/AUTHORS
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
Behdad Esfahbod
|
||||
Simon Hausmann
|
||||
Martin Hosken
|
||||
Jonathan Kew
|
||||
Lars Knoll
|
||||
Werner Lemberg
|
||||
Owen Taylor
|
||||
David Turner
|
36
src/3rdparty/harfbuzz-ng/COPYING
vendored
Normal file
36
src/3rdparty/harfbuzz-ng/COPYING
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
HarfBuzz is licensed under the so-called "Old MIT" license. Details follow.
|
||||
For parts of HarfBuzz that are licensed under different licenses see individual
|
||||
files names COPYING in subdirectories where applicable.
|
||||
|
||||
Copyright © 2010,2011,2012 Google, Inc.
|
||||
Copyright © 2012 Mozilla Foundation
|
||||
Copyright © 2011 Codethink Limited
|
||||
Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
|
||||
Copyright © 2009 Keith Stribley
|
||||
Copyright © 2009 Martin Hosken and SIL International
|
||||
Copyright © 2007 Chris Wilson
|
||||
Copyright © 2006 Behdad Esfahbod
|
||||
Copyright © 2005 David Turner
|
||||
Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
|
||||
Copyright © 1998-2004 David Turner and Werner Lemberg
|
||||
|
||||
For full copyright notices consult the individual files in the package.
|
||||
|
||||
|
||||
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.
|
749
src/3rdparty/harfbuzz-ng/NEWS
vendored
Normal file
749
src/3rdparty/harfbuzz-ng/NEWS
vendored
Normal file
@ -0,0 +1,749 @@
|
||||
Overview of changes leading to 0.9.19
|
||||
Tuesday, July 16, 2013
|
||||
=====================================
|
||||
|
||||
- Build fixes.
|
||||
- Better handling of multiple variation selectors in a row.
|
||||
- Pass on variation selector to GSUB if not consumed by cmap.
|
||||
- Fix undefined memory access.
|
||||
- Add Javanese config to Indic shaper.
|
||||
- Misc bug fixes.
|
||||
|
||||
Overview of changes leading to 0.9.18
|
||||
Tuesday, May 28, 2013
|
||||
=====================================
|
||||
|
||||
New build system:
|
||||
|
||||
- All unneeded code is all disabled by default,
|
||||
|
||||
- Uniscribe and CoreText shapers can be enabled with their --with options,
|
||||
|
||||
- icu_le and old shapers cannot be enabled for now,
|
||||
|
||||
- glib, freetype, and cairo will be detected automatically.
|
||||
They can be force on/off'ed with their --with options,
|
||||
|
||||
- icu and graphite2 are default off, can be enabled with their --with
|
||||
options,
|
||||
|
||||
Moreover, ICU support is now build into a separate library:
|
||||
libharfbuzz-icu.so, and a new harfbuzz-icu.pc is shipped for it.
|
||||
Distros can enable ICU now without every application on earth
|
||||
getting linked to via libharfbuzz.so.
|
||||
|
||||
For distros I recommend that they make sure they are building --with-glib
|
||||
--with-freetype --with-cairo, --with-icu, and optionally --with-graphite2;
|
||||
And package harfbuzz and harfbuzz-icu separately.
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.17
|
||||
Monday, May 20, 2013
|
||||
=====================================
|
||||
|
||||
- Build fixes.
|
||||
- Fix bug in hb_set_get_min().
|
||||
- Fix regression with Arabic mark positioning / width-zeroing.
|
||||
|
||||
Overview of changes leading to 0.9.16
|
||||
Friday, April 19, 2013
|
||||
=====================================
|
||||
|
||||
- Major speedup in OpenType lookup processing. With the Amiri
|
||||
Arabic font, this release is over 3x faster than previous
|
||||
release. All scripts / languages should see this speedup.
|
||||
|
||||
- New --num-iterations option for hb-shape / hb-view; useful for
|
||||
profiling.
|
||||
|
||||
Overview of changes leading to 0.9.15
|
||||
Friday, April 05, 2013
|
||||
=====================================
|
||||
|
||||
- Build fixes.
|
||||
- Fix crasher in graphite2 shaper.
|
||||
- Fix Arabic mark width zeroing regression.
|
||||
- Don't compose Hangul jamo into Unicode syllables.
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.14
|
||||
Thursday, March 21, 2013
|
||||
=====================================
|
||||
|
||||
- Build fixes.
|
||||
- Fix time-consuming sanitize with malicious fonts.
|
||||
- Implement hb_buffer_deserialize_glyphs() for both json and text.
|
||||
- Do not ignore Hangul filler characters.
|
||||
- Indic fixes:
|
||||
* Fix Malayalam pre-base reordering interaction with post-forms.
|
||||
* Further adjust ZWJ handling. Should fix known regressions from
|
||||
0.9.13.
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.13
|
||||
Thursday, February 25, 2013
|
||||
=====================================
|
||||
|
||||
- Build fixes.
|
||||
- Ngapi HarfBuzz Hackfest in London (February 2013):
|
||||
* Fixed all known Indic bugs,
|
||||
* New Win8-style Myanmar shaper,
|
||||
* New South-East Asian shaper for Tai Tham, Cham, and New Tai Lue,
|
||||
* Smartly ignore Default_Ignorable characters (joiners, etc) wheb
|
||||
matching GSUB/GPOS lookups,
|
||||
* Fix 'Phags-Pa U+A872 shaping,
|
||||
* Fix partial disabling of default-on features,
|
||||
* Allow disabling of TrueType kerning.
|
||||
- Fix possible crasher with broken fonts with overlapping tables.
|
||||
- Removed generated files from git again. So, one needs ragel to
|
||||
bootstrap from the git tree.
|
||||
|
||||
API changes:
|
||||
- hb_shape() and related APIs now abort if buffer direction is
|
||||
HB_DIRECTION_INVALID. Previously, hb_shape() was calling
|
||||
hb_buffer_guess_segment_properties() on the buffer before
|
||||
shaping. The heuristics in that function are fragile. If the
|
||||
user really wants the old behvaior, they can call that function
|
||||
right before calling hb_shape() to get the old behavior.
|
||||
- hb_blob_create_sub_blob() always creates sub-blob with
|
||||
HB_MEMORY_MODE_READONLY. See comments for the reason.
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.12
|
||||
Thursday, January 18, 2013
|
||||
=====================================
|
||||
|
||||
- Build fixes for Sun compiler.
|
||||
- Minor bug fix.
|
||||
|
||||
Overview of changes leading to 0.9.11
|
||||
Thursday, January 10, 2013
|
||||
=====================================
|
||||
|
||||
- Build fixes.
|
||||
- Fix GPOS mark attachment with null Anchor offsets.
|
||||
- [Indic] Fix old-spec reordering of viramas if sequence ends in one.
|
||||
- Fix multi-threaded shaper data creation crash.
|
||||
- Add atomic ops for Solaris.
|
||||
|
||||
API changes:
|
||||
- Rename hb_buffer_clear() to hb_buffer_clear_contents().
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.10
|
||||
Thursday, January 3, 2013
|
||||
=====================================
|
||||
|
||||
- [Indic] Fixed rendering of Malayalam dot-reph
|
||||
- Updated OT language tags.
|
||||
- Updated graphite2 backend.
|
||||
- Improved hb_ot_layout_get_size_params() logic.
|
||||
- Improve hb-shape/hb-view help output.
|
||||
- Fixed hb-set.h implementation to not crash.
|
||||
- Fixed various issues with hb_ot_layout_collect_lookups().
|
||||
- Various build fixes.
|
||||
|
||||
New API:
|
||||
|
||||
hb_graphite2_face_get_gr_face()
|
||||
hb_graphite2_font_get_gr_font()
|
||||
hb_coretext_face_get_cg_font()
|
||||
|
||||
Modified API:
|
||||
|
||||
hb_ot_layout_get_size_params()
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.9
|
||||
Wednesday, December 5, 2012
|
||||
====================================
|
||||
|
||||
- Fix build on Windows.
|
||||
- Minor improvements.
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.8
|
||||
Tuesday, December 4, 2012
|
||||
====================================
|
||||
|
||||
|
||||
- Actually implement hb_shape_plan_get_shaper ().
|
||||
- Make UCDB data tables const.
|
||||
- Lots of internal refactoring in OTLayout tables.
|
||||
- Flesh out hb_ot_layout_lookup_collect_glyphs().
|
||||
|
||||
New API:
|
||||
|
||||
hb_ot_layout_collect_lookups()
|
||||
hb_ot_layout_get_size_params()
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.7
|
||||
Sunday, November 21, 2012
|
||||
====================================
|
||||
|
||||
|
||||
HarfBuzz "All-You-Can-Eat-Sushi" (aka Vancouver) Hackfest and follow-on fixes.
|
||||
|
||||
- Fix Arabic contextual joining using pre-context text.
|
||||
- Fix Sinhala "split matra" mess.
|
||||
- Fix Khmer shaping with broken fonts.
|
||||
- Implement Thai "PUA" shaping for old fonts.
|
||||
- Do NOT route Kharoshthi script through the Indic shaper.
|
||||
- Disable fallback positioning for Indic and Thai shapers.
|
||||
- Misc fixes.
|
||||
|
||||
|
||||
hb-shape / hb-view changes:
|
||||
|
||||
- Add --text-before and --text-after
|
||||
- Add --bot / --eot / --preserve-default-ignorables
|
||||
- hb-shape --output-format=json
|
||||
|
||||
|
||||
New API:
|
||||
|
||||
hb_buffer_clear()
|
||||
|
||||
hb_buffer_flags_t
|
||||
|
||||
HB_BUFFER_FLAGS_DEFAULT
|
||||
HB_BUFFER_FLAG_BOT
|
||||
HB_BUFFER_FLAG_EOT
|
||||
HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES
|
||||
|
||||
hb_buffer_set_flags()
|
||||
hb_buffer_get_flags()
|
||||
|
||||
HB_BUFFER_SERIALIZE_FLAGS
|
||||
hb_buffer_serialize_glyphs()
|
||||
hb_buffer_deserialize_glyphs()
|
||||
hb_buffer_serialize_list_formats()
|
||||
|
||||
hb_set_add_range()
|
||||
hb_set_del_range()
|
||||
hb_set_get_population()
|
||||
hb_set_next_range()
|
||||
|
||||
hb_face_[sg]et_glyph_count()
|
||||
|
||||
hb_segment_properties_t
|
||||
HB_SEGMENT_PROPERTIES_DEFAULT
|
||||
hb_segment_properties_equal()
|
||||
hb_segment_properties_hash()
|
||||
|
||||
hb_buffer_set_segment_properties()
|
||||
hb_buffer_get_segment_properties()
|
||||
|
||||
hb_ot_layout_glyph_class_t
|
||||
hb_ot_layout_get_glyph_class()
|
||||
hb_ot_layout_get_glyphs_in_class()
|
||||
|
||||
hb_shape_plan_t
|
||||
hb_shape_plan_create()
|
||||
hb_shape_plan_create_cached()
|
||||
hb_shape_plan_get_empty()
|
||||
hb_shape_plan_reference()
|
||||
hb_shape_plan_destroy()
|
||||
hb_shape_plan_set_user_data()
|
||||
hb_shape_plan_get_user_data()
|
||||
hb_shape_plan_execute()
|
||||
hb_shape_plan_get_shaper()
|
||||
|
||||
hb_ot_shape_plan_collect_lookups()
|
||||
|
||||
|
||||
API changes:
|
||||
|
||||
- Remove "mask" parameter from hb_buffer_add().
|
||||
- Rename hb_ot_layout_would_substitute_lookup() and hb_ot_layout_substitute_closure_lookup().
|
||||
- hb-set.h API const correction.
|
||||
- Renamed hb_set_min/max() to hb_set_get_min/max().
|
||||
- Rename hb_ot_layout_feature_get_lookup_indexes() to hb_ot_layout_feature_get_lookups().
|
||||
- Rename hb_buffer_guess_properties() to hb_buffer_guess_segment_properties().
|
||||
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.6
|
||||
Sunday, November 13, 2012
|
||||
====================================
|
||||
|
||||
- Don't clear pre-context text if no new context is provided.
|
||||
- Fix ReverseChainingSubstLookup, which was totally borked.
|
||||
- Adjust output format of hb-shape a bit.
|
||||
- Include config.h.in in-tree. Makes it easier for alternate build systems.
|
||||
- Fix hb_buffer_set_length(buffer, 0) invalid memory allocation.
|
||||
- Use ICU LayoutEngine's C API instead of C++. Avoids much headache.
|
||||
- Drop glyphs for all of Unicode Default_Ignorable characters.
|
||||
- Misc build fixes.
|
||||
|
||||
Arabic shaper:
|
||||
- Enable 'dlig' and 'mset' features in Arabic shaper.
|
||||
- Implement 'Phags-pa shaping, improve Mongolian.
|
||||
|
||||
Indic shaper:
|
||||
- Decompose Sinhala split matras the way old HarfBuzz / Pango did.
|
||||
- Initial support for Consonant Medials.
|
||||
- Start adding new-style Myanmar shaping.
|
||||
- Make reph and 'pref' logic introspect the font.
|
||||
- Route Meetei-Mayek through the Indic shaper.
|
||||
- Don't apply 'liga' in Indic shaper.
|
||||
- Improve Malayalam pre-base reordering Ra interaction with Chillus.
|
||||
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.5
|
||||
Sunday, October 14, 2012
|
||||
====================================
|
||||
|
||||
- Synthetic-GSUB Arabic fallback shaping.
|
||||
|
||||
- Misc Indic improvements.
|
||||
|
||||
- Add build system support for pthread.
|
||||
|
||||
- Imported UCDN for in-tree Unicode callbacks implementation.
|
||||
|
||||
- Context-aware Arabic joining.
|
||||
|
||||
- Misc other fixes.
|
||||
|
||||
- New API:
|
||||
|
||||
hb_feature_to/from-string()
|
||||
hb_buffer_[sg]et_content_type()
|
||||
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.4
|
||||
Tuesday, Sep 03, 2012
|
||||
====================================
|
||||
|
||||
- Indic improvements with old-spec Malayalam.
|
||||
|
||||
- Better fallback glyph positioning, specially with Thai / Lao marks.
|
||||
|
||||
- Implement dotted-circle insertion.
|
||||
|
||||
- Better Arabic fallback shaping / ligation.
|
||||
|
||||
- Added ICU LayoutEngine backend for testing. Call it by the 'icu_le' name.
|
||||
|
||||
- Misc fixes.
|
||||
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.3
|
||||
Friday, Aug 18, 2012
|
||||
====================================
|
||||
|
||||
- Fixed fallback mark positioning for left-to-right text.
|
||||
|
||||
- Improve mark positioning for the remaining combining classes.
|
||||
|
||||
- Unbreak Thai and fallback Arabic shaping.
|
||||
|
||||
- Port Arabic shaper to shape-plan caching.
|
||||
|
||||
- Use new ICU normalizer functions.
|
||||
|
||||
|
||||
|
||||
Overview of changes leading to 0.9.2
|
||||
Friday, Aug 10, 2012
|
||||
====================================
|
||||
|
||||
- Over a thousand commits! This is the first major release of HarfBuzz.
|
||||
|
||||
- HarfBuzz is feature-complete now! It should be in par, or better, than
|
||||
both Pango's shapers and old HarfBuzz / Qt shapers.
|
||||
|
||||
- New Indic shaper, supporting main Indic scripts, Sinhala, and Khmer.
|
||||
|
||||
- Improved Arabic shaper, with fallback Arabic shaping, supporting Arabic,
|
||||
Sinhala, N'ko, Mongolian, and Mandaic.
|
||||
|
||||
- New Thai / Lao shaper.
|
||||
|
||||
- Tibetan / Hangul support in the generic shaper.
|
||||
|
||||
- Synthetic GDEF support for fonts without a GDEF table.
|
||||
|
||||
- Fallback mark positioning for fonts without a GPOS table.
|
||||
|
||||
- Unicode normalization shaping heuristic during glyph mapping.
|
||||
|
||||
- New experimental Graphite2 backend.
|
||||
|
||||
- New Uniscribe backend (primarily for testing).
|
||||
|
||||
- New CoreText backend (primarily for testing).
|
||||
|
||||
- Major optimization and speedup.
|
||||
|
||||
- Test suites and testing infrastructure (work in progress).
|
||||
|
||||
- Greatly improved hb-view cmdline tool.
|
||||
|
||||
- hb-shape cmdline tool.
|
||||
|
||||
- Unicode 6.1 support.
|
||||
|
||||
Summary of API changes:
|
||||
|
||||
o Changed API:
|
||||
|
||||
- Users are expected to only include main header files now (ie. hb.h,
|
||||
hb-glib.h, hb-ft.h, ...)
|
||||
|
||||
- All struct tag names had their initial underscore removed.
|
||||
Ie. "struct _hb_buffer_t" is "struct hb_buffer_t" now.
|
||||
|
||||
- All set_user_data() functions now take a "replace" boolean parameter.
|
||||
|
||||
- hb_buffer_create() takes zero arguments now.
|
||||
Use hb_buffer_pre_allocate() to pre-allocate.
|
||||
|
||||
- hb_buffer_add_utf*() now accept -1 for length parameteres,
|
||||
meaning "nul-terminated".
|
||||
|
||||
- hb_direction_t enum values changed.
|
||||
|
||||
- All *_from_string() APIs now take a length parameter to allow for
|
||||
non-nul-terminated strings. A -1 length means "nul-terminated".
|
||||
|
||||
- Typedef for hb_language_t changed.
|
||||
|
||||
- hb_get_table_func_t renamed to hb_reference_table_func_t.
|
||||
|
||||
- hb_ot_layout_table_choose_script()
|
||||
|
||||
- Various renames in hb-unicode.h.
|
||||
|
||||
o New API:
|
||||
|
||||
- hb_buffer_guess_properties()
|
||||
Automatically called by hb_shape().
|
||||
|
||||
- hb_buffer_normalize_glyphs()
|
||||
|
||||
- hb_tag_from_string()
|
||||
|
||||
- hb-coretext.h
|
||||
|
||||
- hb-uniscribe.h
|
||||
|
||||
- hb_face_reference_blob()
|
||||
- hb_face_[sg]et_index()
|
||||
- hb_face_set_upem()
|
||||
|
||||
- hb_font_get_glyph_name_func_t
|
||||
hb_font_get_glyph_from_name_func_t
|
||||
hb_font_funcs_set_glyph_name_func()
|
||||
hb_font_funcs_set_glyph_from_name_func()
|
||||
hb_font_get_glyph_name()
|
||||
hb_font_get_glyph_from_name()
|
||||
hb_font_glyph_to_string()
|
||||
hb_font_glyph_from_string()
|
||||
|
||||
- hb_font_set_funcs_data()
|
||||
|
||||
- hb_ft_font_set_funcs()
|
||||
- hb_ft_font_get_face()
|
||||
|
||||
- hb-gobject.h (work in progress)
|
||||
|
||||
- hb_ot_shape_glyphs_closure()
|
||||
hb_ot_layout_substitute_closure_lookup()
|
||||
|
||||
- hb-set.h
|
||||
|
||||
- hb_shape_full()
|
||||
|
||||
- hb_unicode_combining_class_t
|
||||
|
||||
- hb_unicode_compose_func_t
|
||||
hb_unicode_decompose_func_t
|
||||
hb_unicode_decompose_compatibility_func_t
|
||||
hb_unicode_funcs_set_compose_func()
|
||||
hb_unicode_funcs_set_decompose_func()
|
||||
hb_unicode_funcs_set_decompose_compatibility_func()
|
||||
hb_unicode_compose()
|
||||
hb_unicode_decompose()
|
||||
hb_unicode_decompose_compatibility()
|
||||
|
||||
o Removed API:
|
||||
|
||||
- hb_ft_get_font_funcs()
|
||||
|
||||
- hb_ot_layout_substitute_start()
|
||||
hb_ot_layout_substitute_lookup()
|
||||
hb_ot_layout_substitute_finish()
|
||||
hb_ot_layout_position_start()
|
||||
hb_ot_layout_position_lookup()
|
||||
hb_ot_layout_position_finish()
|
||||
|
||||
|
||||
|
||||
Overview of changes leading to 0.6.0
|
||||
Friday, May 27, 2011
|
||||
====================================
|
||||
|
||||
- Vertical text support in GPOS
|
||||
- Almost all API entries have unit tests now, under test/
|
||||
- All thread-safety issues are fixed
|
||||
|
||||
Summary of API changes follows.
|
||||
|
||||
|
||||
* Simple Types API:
|
||||
|
||||
o New API:
|
||||
HB_LANGUAGE_INVALID
|
||||
hb_language_get_default()
|
||||
hb_direction_to_string()
|
||||
hb_direction_from_string()
|
||||
hb_script_get_horizontal_direction()
|
||||
HB_UNTAG()
|
||||
|
||||
o Renamed API:
|
||||
hb_category_t renamed to hb_unicode_general_category_t
|
||||
|
||||
o Changed API:
|
||||
hb_language_t is a typed pointers now
|
||||
|
||||
o Removed API:
|
||||
HB_TAG_STR()
|
||||
|
||||
|
||||
* Use ISO 15924 tags for hb_script_t:
|
||||
|
||||
o New API:
|
||||
hb_script_from_iso15924_tag()
|
||||
hb_script_to_iso15924_tag()
|
||||
hb_script_from_string()
|
||||
|
||||
o Changed API:
|
||||
HB_SCRIPT_* enum members changed value.
|
||||
|
||||
|
||||
* Buffer API streamlined:
|
||||
|
||||
o New API:
|
||||
hb_buffer_reset()
|
||||
hb_buffer_set_length()
|
||||
hb_buffer_allocation_successful()
|
||||
|
||||
o Renamed API:
|
||||
hb_buffer_ensure() renamed to hb_buffer_pre_allocate()
|
||||
hb_buffer_add_glyph() renamed to hb_buffer_add()
|
||||
|
||||
o Removed API:
|
||||
hb_buffer_clear()
|
||||
hb_buffer_clear_positions()
|
||||
|
||||
o Changed API:
|
||||
hb_buffer_get_glyph_infos() takes an out length parameter now
|
||||
hb_buffer_get_glyph_positions() takes an out length parameter now
|
||||
|
||||
|
||||
* Blob API streamlined:
|
||||
|
||||
o New API:
|
||||
hb_blob_get_data()
|
||||
hb_blob_get_data_writable()
|
||||
|
||||
o Renamed API:
|
||||
hb_blob_create_empty() renamed to hb_blob_get_empty()
|
||||
|
||||
o Removed API:
|
||||
hb_blob_lock()
|
||||
hb_blob_unlock()
|
||||
hb_blob_is_writable()
|
||||
hb_blob_try_writable()
|
||||
|
||||
o Changed API:
|
||||
hb_blob_create() takes user_data before destroy now
|
||||
|
||||
|
||||
* Unicode functions API:
|
||||
|
||||
o Unicode function vectors can subclass other unicode function vectors now.
|
||||
Unimplemented callbacks in the subclass automatically chainup to the parent.
|
||||
|
||||
o All hb_unicode_funcs_t callbacks take a user_data now. Their setters
|
||||
take a user_data and its respective destroy callback.
|
||||
|
||||
o New API:
|
||||
hb_unicode_funcs_get_empty()
|
||||
hb_unicode_funcs_get_default()
|
||||
hb_unicode_funcs_get_parent()
|
||||
|
||||
o Changed API:
|
||||
hb_unicode_funcs_create() now takes a parent_funcs.
|
||||
|
||||
o Removed func getter functions:
|
||||
hb_unicode_funcs_get_mirroring_func()
|
||||
hb_unicode_funcs_get_general_category_func()
|
||||
hb_unicode_funcs_get_script_func()
|
||||
hb_unicode_funcs_get_combining_class_func()
|
||||
hb_unicode_funcs_get_eastasian_width_func()
|
||||
|
||||
|
||||
* Face API:
|
||||
|
||||
o Renamed API:
|
||||
hb_face_get_table() renamed to hb_face_reference_table()
|
||||
hb_face_create_for_data() renamed to hb_face_create()
|
||||
|
||||
o Changed API:
|
||||
hb_face_create_for_tables() takes user_data before destroy now
|
||||
hb_face_reference_table() returns empty blob instead of NULL
|
||||
hb_get_table_func_t accepts the face as first parameter now
|
||||
|
||||
* Font API:
|
||||
|
||||
o Fonts can subclass other fonts now. Unimplemented callbacks in the
|
||||
subclass automatically chainup to the parent. When chaining up,
|
||||
scale is adjusted if the parent font has a different scale.
|
||||
|
||||
o All hb_font_funcs_t callbacks take a user_data now. Their setters
|
||||
take a user_data and its respective destroy callback.
|
||||
|
||||
o New API:
|
||||
hb_font_get_parent()
|
||||
hb_font_funcs_get_empty()
|
||||
hb_font_create_sub_font()
|
||||
|
||||
o Removed API:
|
||||
hb_font_funcs_copy()
|
||||
hb_font_unset_funcs()
|
||||
|
||||
o Removed func getter functions:
|
||||
hb_font_funcs_get_glyph_func()
|
||||
hb_font_funcs_get_glyph_advance_func()
|
||||
hb_font_funcs_get_glyph_extents_func()
|
||||
hb_font_funcs_get_contour_point_func()
|
||||
hb_font_funcs_get_kerning_func()
|
||||
|
||||
o Changed API:
|
||||
hb_font_create() takes a face and references it now
|
||||
hb_font_set_funcs() takes user_data before destroy now
|
||||
hb_font_set_scale() accepts signed integers now
|
||||
hb_font_get_contour_point_func_t now takes glyph first, then point_index
|
||||
hb_font_get_glyph_func_t returns a success boolean now
|
||||
|
||||
|
||||
* Changed object model:
|
||||
|
||||
o All object types have a _get_empty() now:
|
||||
hb_blob_get_empty()
|
||||
hb_buffer_get_empty()
|
||||
hb_face_get_empty()
|
||||
hb_font_get_empty()
|
||||
hb_font_funcs_get_empty()
|
||||
hb_unicode_funcs_get_empty()
|
||||
|
||||
o Added _set_user_data() and _get_user_data() for all object types:
|
||||
hb_blob_get_user_data()
|
||||
hb_blob_set_user_data()
|
||||
hb_buffer_get_user_data()
|
||||
hb_buffer_set_user_data()
|
||||
hb_face_get_user_data()
|
||||
hb_face_set_user_data()
|
||||
hb_font_funcs_get_user_data()
|
||||
hb_font_funcs_set_user_data()
|
||||
hb_font_get_user_data()
|
||||
hb_font_set_user_data()
|
||||
hb_unicode_funcs_get_user_data()
|
||||
hb_unicode_funcs_set_user_data()
|
||||
|
||||
o Removed the _get_reference_count() from all object types:
|
||||
hb_blob_get_reference_count()
|
||||
hb_buffer_get_reference_count()
|
||||
hb_face_get_reference_count()
|
||||
hb_font_funcs_get_reference_count()
|
||||
hb_font_get_reference_count()
|
||||
hb_unicode_funcs_get_reference_count()
|
||||
|
||||
o Added _make_immutable() and _is_immutable() for all object types except for buffer:
|
||||
hb_blob_make_immutable()
|
||||
hb_blob_is_immutable()
|
||||
hb_face_make_immutable()
|
||||
hb_face_is_immutable()
|
||||
|
||||
|
||||
* Changed API for vertical text support
|
||||
|
||||
o The following callbacks where removed:
|
||||
hb_font_get_glyph_advance_func_t
|
||||
hb_font_get_kerning_func_t
|
||||
|
||||
o The following new callbacks added instead:
|
||||
hb_font_get_glyph_h_advance_func_t
|
||||
hb_font_get_glyph_v_advance_func_t
|
||||
hb_font_get_glyph_h_origin_func_t
|
||||
hb_font_get_glyph_v_origin_func_t
|
||||
hb_font_get_glyph_h_kerning_func_t
|
||||
hb_font_get_glyph_v_kerning_func_t
|
||||
|
||||
o The following API removed as such:
|
||||
hb_font_funcs_set_glyph_advance_func()
|
||||
hb_font_funcs_set_kerning_func()
|
||||
hb_font_get_glyph_advance()
|
||||
hb_font_get_kerning()
|
||||
|
||||
o New API added instead:
|
||||
hb_font_funcs_set_glyph_h_advance_func()
|
||||
hb_font_funcs_set_glyph_v_advance_func()
|
||||
hb_font_funcs_set_glyph_h_origin_func()
|
||||
hb_font_funcs_set_glyph_v_origin_func()
|
||||
hb_font_funcs_set_glyph_h_kerning_func()
|
||||
hb_font_funcs_set_glyph_v_kerning_func()
|
||||
hb_font_get_glyph_h_advance()
|
||||
hb_font_get_glyph_v_advance()
|
||||
hb_font_get_glyph_h_origin()
|
||||
hb_font_get_glyph_v_origin()
|
||||
hb_font_get_glyph_h_kerning()
|
||||
hb_font_get_glyph_v_kerning()
|
||||
|
||||
o The following higher-leve API added for convenience:
|
||||
hb_font_get_glyph_advance_for_direction()
|
||||
hb_font_get_glyph_origin_for_direction()
|
||||
hb_font_add_glyph_origin_for_direction()
|
||||
hb_font_subtract_glyph_origin_for_direction()
|
||||
hb_font_get_glyph_kerning_for_direction()
|
||||
hb_font_get_glyph_extents_for_origin()
|
||||
hb_font_get_glyph_contour_point_for_origin()
|
||||
|
||||
|
||||
* OpenType Layout API:
|
||||
|
||||
o New API:
|
||||
hb_ot_layout_position_start()
|
||||
hb_ot_layout_substitute_start()
|
||||
hb_ot_layout_substitute_finish()
|
||||
|
||||
|
||||
* Glue code:
|
||||
|
||||
o New API:
|
||||
hb_glib_script_to_script()
|
||||
hb_glib_script_from_script()
|
||||
hb_icu_script_to_script()
|
||||
hb_icu_script_from_script()
|
||||
|
||||
|
||||
* Version API added:
|
||||
|
||||
o New API:
|
||||
HB_VERSION_MAJOR
|
||||
HB_VERSION_MINOR
|
||||
HB_VERSION_MICRO
|
||||
HB_VERSION_STRING
|
||||
HB_VERSION_CHECK()
|
||||
hb_version()
|
||||
hb_version_string()
|
||||
hb_version_check()
|
||||
|
||||
|
7
src/3rdparty/harfbuzz-ng/README
vendored
Normal file
7
src/3rdparty/harfbuzz-ng/README
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
This is HarfBuzz, a text shaping library.
|
||||
|
||||
For bug reports, mailing list, and other information please visit:
|
||||
|
||||
http://harfbuzz.org/
|
||||
|
||||
For license information, see the file COPYING.
|
7
src/3rdparty/harfbuzz-ng/THANKS
vendored
Normal file
7
src/3rdparty/harfbuzz-ng/THANKS
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
Bradley Grainger
|
||||
Khaled Hosny
|
||||
Kenichi Ishibashi
|
||||
Ryan Lortie
|
||||
Jeff Muizelaar
|
||||
suzuki toshiya
|
||||
Philip Withnall
|
81
src/3rdparty/harfbuzz-ng/TODO
vendored
Normal file
81
src/3rdparty/harfbuzz-ng/TODO
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
General fixes:
|
||||
=============
|
||||
|
||||
- AAT 'morx' implementation.
|
||||
|
||||
- Return "safe-to-break" bit from shaping.
|
||||
|
||||
- Implement 'rand' feature.
|
||||
|
||||
- mask propagation? (when ligation, "or" the masks).
|
||||
|
||||
- Warn at compile time (and runtime with HB_DEBUG?) if no Unicode / font
|
||||
funcs found / set.
|
||||
|
||||
- Misc features:
|
||||
* init/medi/fina/isol for non-cursive scripts
|
||||
|
||||
|
||||
API issues to fix before 1.0:
|
||||
============================
|
||||
|
||||
- API to accept a list of languages?
|
||||
|
||||
- Add init_func to font_funcs. Adjust ft.
|
||||
|
||||
- hb-ft load_flags issues.
|
||||
|
||||
- Add pkg-config files for glue codes (harfbuzz-glib, etc)
|
||||
|
||||
- 'const' for getter APIs? (use mutable internally)
|
||||
|
||||
- Remove hb_ot_shape_glyphs_closure()?
|
||||
|
||||
|
||||
API additions
|
||||
=============
|
||||
|
||||
- Language to/from script.
|
||||
|
||||
- blob_from_file?
|
||||
|
||||
- Add hb-cairo glue
|
||||
|
||||
- Add sanitize API (and a cached version, that saves result on blob user-data)
|
||||
|
||||
- Add glib GBoxedType stuff and introspection
|
||||
|
||||
- BCP 47 language handling / API (language_matches?)
|
||||
|
||||
- Add hb_font_create_linear()?
|
||||
|
||||
- Add query / enumeration API for aalt-like features?
|
||||
|
||||
- SFNT api? get_num_faces? get_table_tags? (there's something in stash)
|
||||
|
||||
- Add segmentation API
|
||||
|
||||
- Add hb-fribidi glue?
|
||||
|
||||
|
||||
hb-view / hb-shape enhancements:
|
||||
===============================
|
||||
|
||||
- Add --width, --height, --auto-size, --align, etc?
|
||||
|
||||
|
||||
Tests to write:
|
||||
==============
|
||||
|
||||
- ot-layout enumeration API (needs font)
|
||||
|
||||
- Finish test-shape.c, grep for TODO
|
||||
|
||||
- Finish test-unicode.c, grep for TODO
|
||||
|
||||
- GObject, FreeType, etc
|
||||
|
||||
- hb_cache_t and relatives
|
||||
|
||||
- hb_feature_to/from_string
|
||||
- hb_buffer_[sg]et_contents
|
132
src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
vendored
Normal file
132
src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright © 2007 Chris Wilson
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_ATOMIC_PRIVATE_HH
|
||||
#define HB_ATOMIC_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
/* atomic_int */
|
||||
|
||||
/* We need external help for these */
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(__MINGW32__) && !defined(MemoryBarrier)
|
||||
static inline void _HBMemoryBarrier (void) {
|
||||
long dummy = 0;
|
||||
InterlockedExchange (&dummy, 1);
|
||||
}
|
||||
# define MemoryBarrier _HBMemoryBarrier
|
||||
#endif
|
||||
|
||||
typedef LONG hb_atomic_int_t;
|
||||
#define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
|
||||
|
||||
#define hb_atomic_ptr_get(P) (MemoryBarrier (), (void *) *(P))
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(__APPLE__)
|
||||
|
||||
#include <libkern/OSAtomic.h>
|
||||
#ifdef __MAC_OS_X_MIN_REQUIRED
|
||||
#include <AvailabilityMacros.h>
|
||||
#elif defined(__IPHONE_OS_MIN_REQUIRED)
|
||||
#include <Availability.h>
|
||||
#endif
|
||||
|
||||
typedef int32_t hb_atomic_int_t;
|
||||
#define hb_atomic_int_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_get(P) (OSMemoryBarrier (), (void *) *(P))
|
||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
|
||||
#else
|
||||
#if __ppc64__ || __x86_64__
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
|
||||
#else
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
|
||||
|
||||
typedef int hb_atomic_int_t;
|
||||
#define hb_atomic_int_add(AI, V) __sync_fetch_and_add (&(AI), (V))
|
||||
|
||||
#define hb_atomic_ptr_get(P) (void *) (__sync_synchronize (), *(P))
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N))
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
|
||||
|
||||
#include <atomic.h>
|
||||
#include <mbarrier.h>
|
||||
|
||||
typedef unsigned int hb_atomic_int_t;
|
||||
#define hb_atomic_int_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P))
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT)
|
||||
|
||||
#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
|
||||
typedef volatile int hb_atomic_int_t;
|
||||
#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_get(P) ((void *) *(P))
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false)
|
||||
|
||||
|
||||
#else /* HB_NO_MT */
|
||||
|
||||
typedef int hb_atomic_int_t;
|
||||
#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_get(P) ((void *) *(P))
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
|
||||
|
||||
#endif
|
||||
|
||||
/* TODO Add tracing. */
|
||||
|
||||
#endif /* HB_ATOMIC_PRIVATE_HH */
|
328
src/3rdparty/harfbuzz-ng/src/hb-blob.cc
vendored
Normal file
328
src/3rdparty/harfbuzz-ng/src/hb-blob.cc
vendored
Normal file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
/* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-blob.h"
|
||||
#include "hb-object-private.hh"
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
#include <sys/mman.h>
|
||||
#endif /* HAVE_SYS_MMAN_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_BLOB
|
||||
#define HB_DEBUG_BLOB (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
struct hb_blob_t {
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
||||
bool immutable;
|
||||
|
||||
const char *data;
|
||||
unsigned int length;
|
||||
hb_memory_mode_t mode;
|
||||
|
||||
void *user_data;
|
||||
hb_destroy_func_t destroy;
|
||||
};
|
||||
|
||||
|
||||
static bool _try_writable (hb_blob_t *blob);
|
||||
|
||||
static void
|
||||
_hb_blob_destroy_user_data (hb_blob_t *blob)
|
||||
{
|
||||
if (blob->destroy) {
|
||||
blob->destroy (blob->user_data);
|
||||
blob->user_data = NULL;
|
||||
blob->destroy = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
hb_blob_t *
|
||||
hb_blob_create (const char *data,
|
||||
unsigned int length,
|
||||
hb_memory_mode_t mode,
|
||||
void *user_data,
|
||||
hb_destroy_func_t destroy)
|
||||
{
|
||||
hb_blob_t *blob;
|
||||
|
||||
if (!length || !(blob = hb_object_create<hb_blob_t> ())) {
|
||||
if (destroy)
|
||||
destroy (user_data);
|
||||
return hb_blob_get_empty ();
|
||||
}
|
||||
|
||||
blob->data = data;
|
||||
blob->length = length;
|
||||
blob->mode = mode;
|
||||
|
||||
blob->user_data = user_data;
|
||||
blob->destroy = destroy;
|
||||
|
||||
if (blob->mode == HB_MEMORY_MODE_DUPLICATE) {
|
||||
blob->mode = HB_MEMORY_MODE_READONLY;
|
||||
if (!_try_writable (blob)) {
|
||||
hb_blob_destroy (blob);
|
||||
return hb_blob_get_empty ();
|
||||
}
|
||||
}
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
hb_blob_t *
|
||||
hb_blob_create_sub_blob (hb_blob_t *parent,
|
||||
unsigned int offset,
|
||||
unsigned int length)
|
||||
{
|
||||
hb_blob_t *blob;
|
||||
|
||||
if (!length || offset >= parent->length)
|
||||
return hb_blob_get_empty ();
|
||||
|
||||
hb_blob_make_immutable (parent);
|
||||
|
||||
blob = hb_blob_create (parent->data + offset,
|
||||
MIN (length, parent->length - offset),
|
||||
HB_MEMORY_MODE_READONLY,
|
||||
hb_blob_reference (parent),
|
||||
(hb_destroy_func_t) hb_blob_destroy);
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
hb_blob_t *
|
||||
hb_blob_get_empty (void)
|
||||
{
|
||||
static const hb_blob_t _hb_blob_nil = {
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
|
||||
true, /* immutable */
|
||||
|
||||
NULL, /* data */
|
||||
0, /* length */
|
||||
HB_MEMORY_MODE_READONLY, /* mode */
|
||||
|
||||
NULL, /* user_data */
|
||||
NULL /* destroy */
|
||||
};
|
||||
|
||||
return const_cast<hb_blob_t *> (&_hb_blob_nil);
|
||||
}
|
||||
|
||||
hb_blob_t *
|
||||
hb_blob_reference (hb_blob_t *blob)
|
||||
{
|
||||
return hb_object_reference (blob);
|
||||
}
|
||||
|
||||
void
|
||||
hb_blob_destroy (hb_blob_t *blob)
|
||||
{
|
||||
if (!hb_object_destroy (blob)) return;
|
||||
|
||||
_hb_blob_destroy_user_data (blob);
|
||||
|
||||
free (blob);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_blob_set_user_data (hb_blob_t *blob,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
return hb_object_set_user_data (blob, key, data, destroy, replace);
|
||||
}
|
||||
|
||||
void *
|
||||
hb_blob_get_user_data (hb_blob_t *blob,
|
||||
hb_user_data_key_t *key)
|
||||
{
|
||||
return hb_object_get_user_data (blob, key);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hb_blob_make_immutable (hb_blob_t *blob)
|
||||
{
|
||||
if (hb_object_is_inert (blob))
|
||||
return;
|
||||
|
||||
blob->immutable = true;
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_blob_is_immutable (hb_blob_t *blob)
|
||||
{
|
||||
return blob->immutable;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
hb_blob_get_length (hb_blob_t *blob)
|
||||
{
|
||||
return blob->length;
|
||||
}
|
||||
|
||||
const char *
|
||||
hb_blob_get_data (hb_blob_t *blob, unsigned int *length)
|
||||
{
|
||||
if (length)
|
||||
*length = blob->length;
|
||||
|
||||
return blob->data;
|
||||
}
|
||||
|
||||
char *
|
||||
hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length)
|
||||
{
|
||||
if (!_try_writable (blob)) {
|
||||
if (length)
|
||||
*length = 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (length)
|
||||
*length = blob->length;
|
||||
|
||||
return const_cast<char *> (blob->data);
|
||||
}
|
||||
|
||||
|
||||
static hb_bool_t
|
||||
_try_make_writable_inplace_unix (hb_blob_t *blob)
|
||||
{
|
||||
#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT)
|
||||
uintptr_t pagesize = -1, mask, length;
|
||||
const char *addr;
|
||||
|
||||
#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
|
||||
pagesize = (uintptr_t) sysconf (_SC_PAGE_SIZE);
|
||||
#elif defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
|
||||
pagesize = (uintptr_t) sysconf (_SC_PAGESIZE);
|
||||
#elif defined(HAVE_GETPAGESIZE)
|
||||
pagesize = (uintptr_t) getpagesize ();
|
||||
#endif
|
||||
|
||||
if ((uintptr_t) -1L == pagesize) {
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "failed to get pagesize: %s", strerror (errno));
|
||||
return false;
|
||||
}
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "pagesize is %lu", (unsigned long) pagesize);
|
||||
|
||||
mask = ~(pagesize-1);
|
||||
addr = (const char *) (((uintptr_t) blob->data) & mask);
|
||||
length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask) - addr;
|
||||
DEBUG_MSG_FUNC (BLOB, blob,
|
||||
"calling mprotect on [%p..%p] (%lu bytes)",
|
||||
addr, addr+length, (unsigned long) length);
|
||||
if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "mprotect failed: %s", strerror (errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
blob->mode = HB_MEMORY_MODE_WRITABLE;
|
||||
|
||||
DEBUG_MSG_FUNC (BLOB, blob,
|
||||
"successfully made [%p..%p] (%lu bytes) writable\n",
|
||||
addr, addr+length, (unsigned long) length);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
_try_writable_inplace (hb_blob_t *blob)
|
||||
{
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "making writable inplace\n");
|
||||
|
||||
if (_try_make_writable_inplace_unix (blob))
|
||||
return true;
|
||||
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "making writable -> FAILED\n");
|
||||
|
||||
/* Failed to make writable inplace, mark that */
|
||||
blob->mode = HB_MEMORY_MODE_READONLY;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
_try_writable (hb_blob_t *blob)
|
||||
{
|
||||
if (blob->immutable)
|
||||
return false;
|
||||
|
||||
if (blob->mode == HB_MEMORY_MODE_WRITABLE)
|
||||
return true;
|
||||
|
||||
if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && _try_writable_inplace (blob))
|
||||
return true;
|
||||
|
||||
if (blob->mode == HB_MEMORY_MODE_WRITABLE)
|
||||
return true;
|
||||
|
||||
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "current data is -> %p\n", blob->data);
|
||||
|
||||
char *new_data;
|
||||
|
||||
new_data = (char *) malloc (blob->length);
|
||||
if (unlikely (!new_data))
|
||||
return false;
|
||||
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "dupped successfully -> %p\n", blob->data);
|
||||
|
||||
memcpy (new_data, blob->data, blob->length);
|
||||
_hb_blob_destroy_user_data (blob);
|
||||
blob->mode = HB_MEMORY_MODE_WRITABLE;
|
||||
blob->data = new_data;
|
||||
blob->user_data = new_data;
|
||||
blob->destroy = free;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
127
src/3rdparty/harfbuzz-ng/src/hb-blob.h
vendored
Normal file
127
src/3rdparty/harfbuzz-ng/src/hb-blob.h
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_BLOB_H
|
||||
#define HB_BLOB_H
|
||||
|
||||
#include "hb-common.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
/*
|
||||
* Note re various memory-modes:
|
||||
*
|
||||
* - In no case shall the HarfBuzz client modify memory
|
||||
* that is passed to HarfBuzz in a blob. If there is
|
||||
* any such possibility, MODE_DUPLICATE should be used
|
||||
* such that HarfBuzz makes a copy immediately,
|
||||
*
|
||||
* - Use MODE_READONLY otherse, unless you really really
|
||||
* really know what you are doing,
|
||||
*
|
||||
* - MODE_WRITABLE is appropriate if you relaly made a
|
||||
* copy of data solely for the purpose of passing to
|
||||
* HarfBuzz and doing that just once (no reuse!),
|
||||
*
|
||||
* - If the font is mmap()ed, it's ok to use
|
||||
* READONLY_MAY_MAKE_WRITABLE, however, there were
|
||||
* design problems with that mode, so HarfBuzz do not
|
||||
* really use it anymore. If not sure, use MODE_READONLY.
|
||||
*/
|
||||
typedef enum {
|
||||
HB_MEMORY_MODE_DUPLICATE,
|
||||
HB_MEMORY_MODE_READONLY,
|
||||
HB_MEMORY_MODE_WRITABLE,
|
||||
HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE
|
||||
} hb_memory_mode_t;
|
||||
|
||||
typedef struct hb_blob_t hb_blob_t;
|
||||
|
||||
hb_blob_t *
|
||||
hb_blob_create (const char *data,
|
||||
unsigned int length,
|
||||
hb_memory_mode_t mode,
|
||||
void *user_data,
|
||||
hb_destroy_func_t destroy);
|
||||
|
||||
/* Always creates with MEMORY_MODE_READONLY.
|
||||
* Even if the parent blob is writable, we don't
|
||||
* want the user of the sub-blob to be able to
|
||||
* modify the parent data as that data may be
|
||||
* shared among multiple sub-blobs.
|
||||
*/
|
||||
hb_blob_t *
|
||||
hb_blob_create_sub_blob (hb_blob_t *parent,
|
||||
unsigned int offset,
|
||||
unsigned int length);
|
||||
|
||||
hb_blob_t *
|
||||
hb_blob_get_empty (void);
|
||||
|
||||
hb_blob_t *
|
||||
hb_blob_reference (hb_blob_t *blob);
|
||||
|
||||
void
|
||||
hb_blob_destroy (hb_blob_t *blob);
|
||||
|
||||
hb_bool_t
|
||||
hb_blob_set_user_data (hb_blob_t *blob,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
|
||||
void *
|
||||
hb_blob_get_user_data (hb_blob_t *blob,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
|
||||
void
|
||||
hb_blob_make_immutable (hb_blob_t *blob);
|
||||
|
||||
hb_bool_t
|
||||
hb_blob_is_immutable (hb_blob_t *blob);
|
||||
|
||||
|
||||
unsigned int
|
||||
hb_blob_get_length (hb_blob_t *blob);
|
||||
|
||||
const char *
|
||||
hb_blob_get_data (hb_blob_t *blob, unsigned int *length);
|
||||
|
||||
char *
|
||||
hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_BLOB_H */
|
643
src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh
vendored
Normal file
643
src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh
vendored
Normal file
@ -0,0 +1,643 @@
|
||||
|
||||
#line 1 "hb-buffer-deserialize-json.rl"
|
||||
/*
|
||||
* Copyright © 2013 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_BUFFER_DESERIALIZE_JSON_HH
|
||||
#define HB_BUFFER_DESERIALIZE_JSON_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
#line 36 "hb-buffer-deserialize-json.hh"
|
||||
static const unsigned char _deserialize_json_trans_keys[] = {
|
||||
0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
|
||||
48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u,
|
||||
9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u,
|
||||
120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u,
|
||||
9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u,
|
||||
65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0
|
||||
};
|
||||
|
||||
static const char _deserialize_json_key_spans[] = {
|
||||
0, 115, 26, 7, 2, 1, 50, 49,
|
||||
10, 117, 117, 117, 1, 50, 49, 10,
|
||||
117, 117, 1, 1, 50, 49, 117, 117,
|
||||
2, 1, 50, 49, 10, 117, 117, 1,
|
||||
50, 49, 10, 117, 117, 1, 50, 49,
|
||||
58, 89, 117, 117, 85, 115, 0
|
||||
};
|
||||
|
||||
static const short _deserialize_json_index_offsets[] = {
|
||||
0, 0, 116, 143, 151, 154, 156, 207,
|
||||
257, 268, 386, 504, 622, 624, 675, 725,
|
||||
736, 854, 972, 974, 976, 1027, 1077, 1195,
|
||||
1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666,
|
||||
1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069,
|
||||
2119, 2178, 2268, 2386, 2504, 2590, 2706
|
||||
};
|
||||
|
||||
static const char _deserialize_json_indicies[] = {
|
||||
0, 0, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 2, 1, 3, 3, 3,
|
||||
3, 3, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 3, 1, 4, 1,
|
||||
5, 1, 6, 7, 1, 1, 8, 1,
|
||||
9, 10, 1, 11, 1, 11, 11, 11,
|
||||
11, 11, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 11, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 12, 1,
|
||||
12, 12, 12, 12, 12, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 12,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 13, 1, 1, 14,
|
||||
15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 1, 16, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 1, 18, 18, 18,
|
||||
18, 18, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 18, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
19, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 20, 1, 21, 21, 21, 21, 21,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 21, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 3, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 22,
|
||||
1, 18, 18, 18, 18, 18, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
18, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 19, 1, 1, 1,
|
||||
17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 20, 1, 23,
|
||||
1, 23, 23, 23, 23, 23, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
23, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 24, 1, 24, 24, 24, 24,
|
||||
24, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 24, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
25, 1, 1, 26, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 27, 1, 28, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29,
|
||||
1, 30, 30, 30, 30, 30, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
30, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 31, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 32, 1, 30,
|
||||
30, 30, 30, 30, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 30, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 31, 1, 1, 1, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 32, 1, 33, 1, 34,
|
||||
1, 34, 34, 34, 34, 34, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
34, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 35, 1, 35, 35, 35, 35,
|
||||
35, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 35, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 36, 37, 37, 37, 37,
|
||||
37, 37, 37, 37, 37, 1, 38, 38,
|
||||
38, 38, 38, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 38, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 39, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 40, 1, 38, 38, 38, 38,
|
||||
38, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 38, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 39,
|
||||
1, 1, 1, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
40, 1, 42, 43, 1, 44, 1, 44,
|
||||
44, 44, 44, 44, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 44, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
45, 1, 45, 45, 45, 45, 45, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 45, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 46, 1,
|
||||
1, 47, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 1, 49, 50, 50, 50,
|
||||
50, 50, 50, 50, 50, 50, 1, 51,
|
||||
51, 51, 51, 51, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 51, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 52, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 53, 1, 51, 51, 51,
|
||||
51, 51, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 51, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
52, 1, 1, 1, 50, 50, 50, 50,
|
||||
50, 50, 50, 50, 50, 50, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 53, 1, 54, 1, 54, 54, 54,
|
||||
54, 54, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 54, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 55, 1,
|
||||
55, 55, 55, 55, 55, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 55,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 56, 1, 1, 57,
|
||||
58, 58, 58, 58, 58, 58, 58, 58,
|
||||
58, 1, 59, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 1, 61, 61, 61,
|
||||
61, 61, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 61, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
62, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 63, 1, 61, 61, 61, 61, 61,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 61, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 62, 1,
|
||||
1, 1, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 63,
|
||||
1, 64, 1, 64, 64, 64, 64, 64,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 64, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 65, 1, 65, 65,
|
||||
65, 65, 65, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 65, 1, 66,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 67, 68, 68,
|
||||
68, 68, 68, 68, 68, 68, 68, 1,
|
||||
69, 69, 69, 69, 69, 69, 69, 69,
|
||||
69, 69, 69, 69, 69, 69, 69, 69,
|
||||
69, 69, 69, 69, 69, 69, 69, 69,
|
||||
69, 69, 1, 1, 1, 1, 1, 1,
|
||||
69, 69, 69, 69, 69, 69, 69, 69,
|
||||
69, 69, 69, 69, 69, 69, 69, 69,
|
||||
69, 69, 69, 69, 69, 69, 69, 69,
|
||||
69, 69, 1, 70, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 71, 71,
|
||||
1, 71, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 1, 1, 1, 1, 1,
|
||||
1, 1, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 71, 1, 1, 1, 1,
|
||||
71, 1, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 71, 1, 72, 72, 72,
|
||||
72, 72, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 72, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
73, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 74, 1, 72, 72, 72, 72, 72,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 72, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 73, 1,
|
||||
1, 1, 75, 75, 75, 75, 75, 75,
|
||||
75, 75, 75, 75, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 74,
|
||||
1, 76, 76, 76, 76, 76, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
76, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 77, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 78, 1, 0,
|
||||
0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 0, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 2, 1, 1, 0
|
||||
};
|
||||
|
||||
static const char _deserialize_json_trans_targs[] = {
|
||||
1, 0, 2, 2, 3, 4, 18, 24,
|
||||
37, 5, 12, 6, 7, 8, 9, 11,
|
||||
9, 11, 10, 2, 44, 10, 44, 13,
|
||||
14, 15, 16, 17, 16, 17, 10, 2,
|
||||
44, 19, 20, 21, 22, 23, 10, 2,
|
||||
44, 23, 25, 31, 26, 27, 28, 29,
|
||||
30, 29, 30, 10, 2, 44, 32, 33,
|
||||
34, 35, 36, 35, 36, 10, 2, 44,
|
||||
38, 39, 40, 42, 43, 41, 10, 41,
|
||||
10, 2, 44, 43, 44, 45, 46
|
||||
};
|
||||
|
||||
static const char _deserialize_json_trans_actions[] = {
|
||||
0, 0, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 2, 2, 2,
|
||||
0, 0, 3, 3, 4, 0, 5, 0,
|
||||
0, 2, 2, 2, 0, 0, 6, 6,
|
||||
7, 0, 0, 0, 2, 2, 8, 8,
|
||||
9, 0, 0, 0, 0, 0, 2, 2,
|
||||
2, 0, 0, 10, 10, 11, 0, 0,
|
||||
2, 2, 2, 0, 0, 12, 12, 13,
|
||||
0, 0, 0, 2, 2, 2, 14, 0,
|
||||
15, 15, 16, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const int deserialize_json_start = 1;
|
||||
static const int deserialize_json_first_final = 44;
|
||||
static const int deserialize_json_error = 0;
|
||||
|
||||
static const int deserialize_json_en_main = 1;
|
||||
|
||||
|
||||
#line 97 "hb-buffer-deserialize-json.rl"
|
||||
|
||||
|
||||
static hb_bool_t
|
||||
_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer,
|
||||
const char *buf,
|
||||
unsigned int buf_len,
|
||||
const char **end_ptr,
|
||||
hb_font_t *font)
|
||||
{
|
||||
const char *p = buf, *pe = buf + buf_len;
|
||||
|
||||
/* Ensure we have positions. */
|
||||
(void) hb_buffer_get_glyph_positions (buffer, NULL);
|
||||
|
||||
while (p < pe && ISSPACE (*p))
|
||||
p++;
|
||||
if (p < pe && *p == (buffer->len ? ',' : '['))
|
||||
{
|
||||
*end_ptr = ++p;
|
||||
}
|
||||
|
||||
const char *tok = NULL;
|
||||
int cs;
|
||||
hb_glyph_info_t info;
|
||||
hb_glyph_position_t pos;
|
||||
|
||||
#line 466 "hb-buffer-deserialize-json.hh"
|
||||
{
|
||||
cs = deserialize_json_start;
|
||||
}
|
||||
|
||||
#line 471 "hb-buffer-deserialize-json.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
const unsigned char *_keys;
|
||||
const char *_inds;
|
||||
if ( p == pe )
|
||||
goto _test_eof;
|
||||
if ( cs == 0 )
|
||||
goto _out;
|
||||
_resume:
|
||||
_keys = _deserialize_json_trans_keys + (cs<<1);
|
||||
_inds = _deserialize_json_indicies + _deserialize_json_index_offsets[cs];
|
||||
|
||||
_slen = _deserialize_json_key_spans[cs];
|
||||
_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
|
||||
(*p) <= _keys[1] ?
|
||||
(*p) - _keys[0] : _slen ];
|
||||
|
||||
cs = _deserialize_json_trans_targs[_trans];
|
||||
|
||||
if ( _deserialize_json_trans_actions[_trans] == 0 )
|
||||
goto _again;
|
||||
|
||||
switch ( _deserialize_json_trans_actions[_trans] ) {
|
||||
case 1:
|
||||
#line 38 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
memset (&info, 0, sizeof (info));
|
||||
memset (&pos , 0, sizeof (pos ));
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
#line 51 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
tok = p;
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
#line 55 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
#line 62 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
|
||||
break;
|
||||
case 8:
|
||||
#line 63 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||
break;
|
||||
case 10:
|
||||
#line 64 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
||||
break;
|
||||
case 12:
|
||||
#line 65 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||
break;
|
||||
case 3:
|
||||
#line 66 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||
break;
|
||||
case 6:
|
||||
#line 67 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||
break;
|
||||
case 16:
|
||||
#line 62 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
#line 63 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
#line 64 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
#line 65 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
#line 66 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
#line 67 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
#line 624 "hb-buffer-deserialize-json.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
if ( cs == 0 )
|
||||
goto _out;
|
||||
if ( ++p != pe )
|
||||
goto _resume;
|
||||
_test_eof: {}
|
||||
_out: {}
|
||||
}
|
||||
|
||||
#line 125 "hb-buffer-deserialize-json.rl"
|
||||
|
||||
|
||||
*end_ptr = p;
|
||||
|
||||
return p == pe && *(p-1) != ']';
|
||||
}
|
||||
|
||||
#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */
|
571
src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh
vendored
Normal file
571
src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh
vendored
Normal file
@ -0,0 +1,571 @@
|
||||
|
||||
#line 1 "hb-buffer-deserialize-text.rl"
|
||||
/*
|
||||
* Copyright © 2013 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_BUFFER_DESERIALIZE_TEXT_HH
|
||||
#define HB_BUFFER_DESERIALIZE_TEXT_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
#line 36 "hb-buffer-deserialize-text.hh"
|
||||
static const unsigned char _deserialize_text_trans_keys[] = {
|
||||
0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
|
||||
48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u,
|
||||
9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u,
|
||||
9u, 124u, 9u, 124u, 9u, 124u, 0
|
||||
};
|
||||
|
||||
static const char _deserialize_text_key_spans[] = {
|
||||
0, 114, 13, 10, 13, 10, 10, 13,
|
||||
10, 1, 13, 10, 14, 116, 116, 0,
|
||||
114, 116, 116, 116, 116, 116, 116, 116,
|
||||
116, 116, 116
|
||||
};
|
||||
|
||||
static const short _deserialize_text_index_offsets[] = {
|
||||
0, 0, 115, 129, 140, 154, 165, 176,
|
||||
190, 201, 203, 217, 228, 243, 360, 477,
|
||||
478, 593, 710, 827, 944, 1061, 1178, 1295,
|
||||
1412, 1529, 1646
|
||||
};
|
||||
|
||||
static const char _deserialize_text_indicies[] = {
|
||||
0, 0, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 1, 1, 1, 1, 1, 1,
|
||||
1, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 1, 1, 1, 1, 1,
|
||||
1, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 1, 5, 1, 1, 6,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 1, 8, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 1, 10, 1, 1,
|
||||
11, 12, 12, 12, 12, 12, 12, 12,
|
||||
12, 12, 1, 13, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 1, 15, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16,
|
||||
1, 17, 1, 1, 18, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 1, 20,
|
||||
21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 1, 22, 1, 23, 1, 1, 24,
|
||||
25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 1, 26, 27, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 1, 22, 1, 1,
|
||||
1, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 1, 28, 28, 28, 28,
|
||||
28, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 28, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 29, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
30, 1, 1, 31, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
32, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 33,
|
||||
1, 34, 34, 34, 34, 34, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
34, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 35, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 36, 1, 1, 0,
|
||||
0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 0, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3,
|
||||
1, 1, 1, 1, 1, 1, 1, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 1, 1, 1, 1, 1, 1, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 1, 28, 28, 28, 28, 28, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 28, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 29, 1, 1, 1,
|
||||
1, 37, 37, 37, 37, 37, 37, 37,
|
||||
37, 37, 37, 1, 1, 1, 30, 1,
|
||||
1, 31, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 32, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 33, 1, 38,
|
||||
38, 38, 38, 38, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 38, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 39, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 40, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 41, 1, 42, 42, 42, 42,
|
||||
42, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 42, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
43, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 44,
|
||||
1, 42, 42, 42, 42, 42, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
42, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 43, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 44, 1, 38, 38,
|
||||
38, 38, 38, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 38, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 39, 1, 1, 1, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 40, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 41, 1, 45, 45, 45, 45, 45,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 45, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 46, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 47, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 48,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 49, 1,
|
||||
50, 50, 50, 50, 50, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 50,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 51, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 52, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 53, 1, 50, 50, 50,
|
||||
50, 50, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 50, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 51,
|
||||
1, 1, 1, 1, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 27, 27, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 52, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
53, 1, 45, 45, 45, 45, 45, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 45, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 46, 1, 1, 1,
|
||||
1, 54, 54, 54, 54, 54, 54, 54,
|
||||
54, 54, 54, 1, 1, 1, 1, 1,
|
||||
1, 47, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 48, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 49, 1, 28,
|
||||
28, 28, 28, 28, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 28, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 29, 1, 55, 55, 1, 55, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
1, 1, 1, 30, 1, 1, 31, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
55, 1, 1, 32, 1, 55, 1, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
55, 1, 33, 1, 0
|
||||
};
|
||||
|
||||
static const char _deserialize_text_trans_targs[] = {
|
||||
1, 0, 13, 17, 26, 3, 18, 21,
|
||||
18, 21, 5, 19, 20, 19, 20, 22,
|
||||
25, 8, 9, 12, 9, 12, 10, 11,
|
||||
23, 24, 23, 24, 14, 2, 6, 7,
|
||||
15, 16, 14, 15, 16, 17, 14, 4,
|
||||
15, 16, 14, 15, 16, 14, 2, 7,
|
||||
15, 16, 14, 2, 15, 16, 25, 26
|
||||
};
|
||||
|
||||
static const char _deserialize_text_trans_actions[] = {
|
||||
0, 0, 1, 1, 1, 2, 2, 2,
|
||||
0, 0, 2, 2, 2, 0, 0, 2,
|
||||
2, 2, 2, 2, 0, 0, 3, 2,
|
||||
2, 2, 0, 0, 4, 5, 5, 5,
|
||||
4, 4, 0, 0, 0, 0, 6, 7,
|
||||
6, 6, 8, 8, 8, 9, 10, 10,
|
||||
9, 9, 11, 12, 11, 11, 0, 0
|
||||
};
|
||||
|
||||
static const char _deserialize_text_eof_actions[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 4, 0, 0,
|
||||
0, 4, 6, 8, 8, 6, 9, 11,
|
||||
11, 9, 4
|
||||
};
|
||||
|
||||
static const int deserialize_text_start = 1;
|
||||
static const int deserialize_text_first_final = 13;
|
||||
static const int deserialize_text_error = 0;
|
||||
|
||||
static const int deserialize_text_en_main = 1;
|
||||
|
||||
|
||||
#line 91 "hb-buffer-deserialize-text.rl"
|
||||
|
||||
|
||||
static hb_bool_t
|
||||
_hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
|
||||
const char *buf,
|
||||
unsigned int buf_len,
|
||||
const char **end_ptr,
|
||||
hb_font_t *font)
|
||||
{
|
||||
const char *p = buf, *pe = buf + buf_len;
|
||||
|
||||
/* Ensure we have positions. */
|
||||
(void) hb_buffer_get_glyph_positions (buffer, NULL);
|
||||
|
||||
while (p < pe && ISSPACE (*p))
|
||||
p++;
|
||||
if (p < pe && *p == (buffer->len ? '|' : '['))
|
||||
{
|
||||
*end_ptr = ++p;
|
||||
}
|
||||
|
||||
const char *eof = pe, *tok = NULL;
|
||||
int cs;
|
||||
hb_glyph_info_t info;
|
||||
hb_glyph_position_t pos;
|
||||
|
||||
#line 343 "hb-buffer-deserialize-text.hh"
|
||||
{
|
||||
cs = deserialize_text_start;
|
||||
}
|
||||
|
||||
#line 348 "hb-buffer-deserialize-text.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
const unsigned char *_keys;
|
||||
const char *_inds;
|
||||
if ( p == pe )
|
||||
goto _test_eof;
|
||||
if ( cs == 0 )
|
||||
goto _out;
|
||||
_resume:
|
||||
_keys = _deserialize_text_trans_keys + (cs<<1);
|
||||
_inds = _deserialize_text_indicies + _deserialize_text_index_offsets[cs];
|
||||
|
||||
_slen = _deserialize_text_key_spans[cs];
|
||||
_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
|
||||
(*p) <= _keys[1] ?
|
||||
(*p) - _keys[0] : _slen ];
|
||||
|
||||
cs = _deserialize_text_trans_targs[_trans];
|
||||
|
||||
if ( _deserialize_text_trans_actions[_trans] == 0 )
|
||||
goto _again;
|
||||
|
||||
switch ( _deserialize_text_trans_actions[_trans] ) {
|
||||
case 2:
|
||||
#line 51 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
tok = p;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
#line 55 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
#line 62 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||
break;
|
||||
case 3:
|
||||
#line 63 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
||||
break;
|
||||
case 12:
|
||||
#line 64 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||
break;
|
||||
case 7:
|
||||
#line 65 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||
break;
|
||||
case 1:
|
||||
#line 38 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
memset (&info, 0, sizeof (info));
|
||||
memset (&pos , 0, sizeof (pos ));
|
||||
}
|
||||
#line 51 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
tok = p;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
#line 55 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
return false;
|
||||
}
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
#line 62 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
#line 64 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
#line 65 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
#line 66 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
#line 480 "hb-buffer-deserialize-text.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
if ( cs == 0 )
|
||||
goto _out;
|
||||
if ( ++p != pe )
|
||||
goto _resume;
|
||||
_test_eof: {}
|
||||
if ( p == eof )
|
||||
{
|
||||
switch ( _deserialize_text_eof_actions[cs] ) {
|
||||
case 4:
|
||||
#line 55 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
return false;
|
||||
}
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
#line 62 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
#line 64 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
#line 65 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
#line 66 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
#line 557 "hb-buffer-deserialize-text.hh"
|
||||
}
|
||||
}
|
||||
|
||||
_out: {}
|
||||
}
|
||||
|
||||
#line 119 "hb-buffer-deserialize-text.rl"
|
||||
|
||||
|
||||
*end_ptr = p;
|
||||
|
||||
return p == pe && *(p-1) != ']';
|
||||
}
|
||||
|
||||
#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */
|
202
src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
vendored
Normal file
202
src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright © 1998-2004 David Turner and Werner Lemberg
|
||||
* Copyright © 2004,2007,2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Owen Taylor, Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_BUFFER_PRIVATE_HH
|
||||
#define HB_BUFFER_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-buffer.h"
|
||||
#include "hb-object-private.hh"
|
||||
#include "hb-unicode-private.hh"
|
||||
|
||||
|
||||
ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20);
|
||||
ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t));
|
||||
|
||||
|
||||
/*
|
||||
* hb_buffer_t
|
||||
*/
|
||||
|
||||
struct hb_buffer_t {
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
||||
/* Information about how the text in the buffer should be treated */
|
||||
|
||||
hb_unicode_funcs_t *unicode; /* Unicode functions */
|
||||
hb_segment_properties_t props; /* Script, language, direction */
|
||||
hb_buffer_flags_t flags; /* BOT / EOT / etc. */
|
||||
|
||||
/* Buffer contents */
|
||||
|
||||
hb_buffer_content_type_t content_type;
|
||||
|
||||
bool in_error; /* Allocation failed */
|
||||
bool have_output; /* Whether we have an output buffer going on */
|
||||
bool have_positions; /* Whether we have positions */
|
||||
|
||||
unsigned int idx; /* Cursor into ->info and ->pos arrays */
|
||||
unsigned int len; /* Length of ->info and ->pos arrays */
|
||||
unsigned int out_len; /* Length of ->out array if have_output */
|
||||
|
||||
unsigned int allocated; /* Length of allocated arrays */
|
||||
hb_glyph_info_t *info;
|
||||
hb_glyph_info_t *out_info;
|
||||
hb_glyph_position_t *pos;
|
||||
|
||||
inline hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; }
|
||||
inline hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; }
|
||||
|
||||
inline hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; }
|
||||
inline hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; }
|
||||
|
||||
inline hb_glyph_info_t &prev (void) { return out_info[out_len - 1]; }
|
||||
inline hb_glyph_info_t prev (void) const { return info[out_len - 1]; }
|
||||
|
||||
inline bool has_separate_output (void) const { return info != out_info; }
|
||||
|
||||
unsigned int serial;
|
||||
|
||||
/* These reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
|
||||
uint8_t allocated_var_bytes[8];
|
||||
const char *allocated_var_owner[8];
|
||||
|
||||
/* Text before / after the main buffer contents.
|
||||
* Always in Unicode, and ordered outward.
|
||||
* Index 0 is for "pre-context", 1 for "post-context". */
|
||||
static const unsigned int CONTEXT_LENGTH = 5;
|
||||
hb_codepoint_t context[2][CONTEXT_LENGTH];
|
||||
unsigned int context_len[2];
|
||||
|
||||
|
||||
/* Methods */
|
||||
|
||||
HB_INTERNAL void reset (void);
|
||||
HB_INTERNAL void clear (void);
|
||||
|
||||
inline unsigned int backtrack_len (void) const
|
||||
{ return have_output? out_len : idx; }
|
||||
inline unsigned int next_serial (void) { return serial++; }
|
||||
|
||||
HB_INTERNAL void allocate_var (unsigned int byte_i, unsigned int count, const char *owner);
|
||||
HB_INTERNAL void deallocate_var (unsigned int byte_i, unsigned int count, const char *owner);
|
||||
HB_INTERNAL void assert_var (unsigned int byte_i, unsigned int count, const char *owner);
|
||||
HB_INTERNAL void deallocate_var_all (void);
|
||||
|
||||
HB_INTERNAL void add (hb_codepoint_t codepoint,
|
||||
unsigned int cluster);
|
||||
HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info);
|
||||
|
||||
HB_INTERNAL void reverse_range (unsigned int start, unsigned int end);
|
||||
HB_INTERNAL void reverse (void);
|
||||
HB_INTERNAL void reverse_clusters (void);
|
||||
HB_INTERNAL void guess_segment_properties (void);
|
||||
|
||||
HB_INTERNAL void swap_buffers (void);
|
||||
HB_INTERNAL void remove_output (void);
|
||||
HB_INTERNAL void clear_output (void);
|
||||
HB_INTERNAL void clear_positions (void);
|
||||
|
||||
HB_INTERNAL void replace_glyphs (unsigned int num_in,
|
||||
unsigned int num_out,
|
||||
const hb_codepoint_t *glyph_data);
|
||||
|
||||
HB_INTERNAL void replace_glyph (hb_codepoint_t glyph_index);
|
||||
/* Makes a copy of the glyph at idx to output and replace glyph_index */
|
||||
HB_INTERNAL void output_glyph (hb_codepoint_t glyph_index);
|
||||
HB_INTERNAL void output_info (const hb_glyph_info_t &glyph_info);
|
||||
/* Copies glyph at idx to output but doesn't advance idx */
|
||||
HB_INTERNAL void copy_glyph (void);
|
||||
/* Copies glyph at idx to output and advance idx.
|
||||
* If there's no output, just advance idx. */
|
||||
inline void
|
||||
next_glyph (void)
|
||||
{
|
||||
if (have_output)
|
||||
{
|
||||
if (unlikely (out_info != info || out_len != idx)) {
|
||||
if (unlikely (!make_room_for (1, 1))) return;
|
||||
out_info[out_len] = info[idx];
|
||||
}
|
||||
out_len++;
|
||||
}
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
/* Advance idx without copying to output. */
|
||||
inline void skip_glyph (void) { idx++; }
|
||||
|
||||
inline void reset_masks (hb_mask_t mask)
|
||||
{
|
||||
for (unsigned int j = 0; j < len; j++)
|
||||
info[j].mask = mask;
|
||||
}
|
||||
inline void add_masks (hb_mask_t mask)
|
||||
{
|
||||
for (unsigned int j = 0; j < len; j++)
|
||||
info[j].mask |= mask;
|
||||
}
|
||||
HB_INTERNAL void set_masks (hb_mask_t value,
|
||||
hb_mask_t mask,
|
||||
unsigned int cluster_start,
|
||||
unsigned int cluster_end);
|
||||
|
||||
HB_INTERNAL void merge_clusters (unsigned int start,
|
||||
unsigned int end);
|
||||
HB_INTERNAL void merge_out_clusters (unsigned int start,
|
||||
unsigned int end);
|
||||
|
||||
/* Internal methods */
|
||||
HB_INTERNAL bool enlarge (unsigned int size);
|
||||
|
||||
inline bool ensure (unsigned int size)
|
||||
{ return likely (size < allocated) ? true : enlarge (size); }
|
||||
|
||||
HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
|
||||
|
||||
HB_INTERNAL void *get_scratch_buffer (unsigned int *size);
|
||||
|
||||
inline void clear_context (unsigned int side) { context_len[side] = 0; }
|
||||
};
|
||||
|
||||
|
||||
#define HB_BUFFER_XALLOCATE_VAR(b, func, var, owner) \
|
||||
b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \
|
||||
sizeof (b->info[0].var), owner)
|
||||
#define HB_BUFFER_ALLOCATE_VAR(b, var) \
|
||||
HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var (), #var)
|
||||
#define HB_BUFFER_DEALLOCATE_VAR(b, var) \
|
||||
HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var (), #var)
|
||||
#define HB_BUFFER_ASSERT_VAR(b, var) \
|
||||
HB_BUFFER_XALLOCATE_VAR (b, assert_var, var (), #var)
|
||||
|
||||
|
||||
#endif /* HB_BUFFER_PRIVATE_HH */
|
336
src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
vendored
Normal file
336
src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
vendored
Normal file
@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright © 2012,2013 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-buffer-private.hh"
|
||||
|
||||
|
||||
static const char *serialize_formats[] = {
|
||||
"text",
|
||||
"json",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char **
|
||||
hb_buffer_serialize_list_formats (void)
|
||||
{
|
||||
return serialize_formats;
|
||||
}
|
||||
|
||||
hb_buffer_serialize_format_t
|
||||
hb_buffer_serialize_format_from_string (const char *str, int len)
|
||||
{
|
||||
/* Upper-case it. */
|
||||
return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020);
|
||||
}
|
||||
|
||||
const char *
|
||||
hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
|
||||
default:
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
_hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
char *buf,
|
||||
unsigned int buf_size,
|
||||
unsigned int *buf_consumed,
|
||||
hb_font_t *font,
|
||||
hb_buffer_serialize_flags_t flags)
|
||||
{
|
||||
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
|
||||
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL);
|
||||
|
||||
*buf_consumed = 0;
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
{
|
||||
char b[1024];
|
||||
char *p = b;
|
||||
|
||||
/* In the following code, we know b is large enough that no overflow can happen. */
|
||||
|
||||
#define APPEND(s) HB_STMT_START { strcpy (p, s); p += strlen (s); } HB_STMT_END
|
||||
|
||||
if (i)
|
||||
*p++ = ',';
|
||||
|
||||
*p++ = '{';
|
||||
|
||||
APPEND ("\"g\":");
|
||||
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
|
||||
{
|
||||
char g[128];
|
||||
hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));
|
||||
*p++ = '"';
|
||||
for (char *q = g; *q; q++) {
|
||||
if (*q == '"')
|
||||
*p++ = '\\';
|
||||
*p++ = *q;
|
||||
}
|
||||
*p++ = '"';
|
||||
}
|
||||
else
|
||||
p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint);
|
||||
|
||||
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
|
||||
p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster);
|
||||
}
|
||||
|
||||
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
|
||||
{
|
||||
p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
|
||||
pos[i].x_offset, pos[i].y_offset);
|
||||
p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
|
||||
pos[i].x_advance, pos[i].y_advance);
|
||||
}
|
||||
|
||||
*p++ = '}';
|
||||
|
||||
if (buf_size > (p - b))
|
||||
{
|
||||
unsigned int l = p - b;
|
||||
memcpy (buf, b, l);
|
||||
buf += l;
|
||||
buf_size -= l;
|
||||
*buf_consumed += l;
|
||||
*buf = '\0';
|
||||
} else
|
||||
return i - start;
|
||||
}
|
||||
|
||||
return end - start;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
char *buf,
|
||||
unsigned int buf_size,
|
||||
unsigned int *buf_consumed,
|
||||
hb_font_t *font,
|
||||
hb_buffer_serialize_flags_t flags)
|
||||
{
|
||||
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
|
||||
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL);
|
||||
|
||||
*buf_consumed = 0;
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
{
|
||||
char b[1024];
|
||||
char *p = b;
|
||||
|
||||
/* In the following code, we know b is large enough that no overflow can happen. */
|
||||
|
||||
if (i)
|
||||
*p++ = '|';
|
||||
|
||||
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
|
||||
{
|
||||
hb_font_glyph_to_string (font, info[i].codepoint, p, 128);
|
||||
p += strlen (p);
|
||||
}
|
||||
else
|
||||
p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint);
|
||||
|
||||
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
|
||||
p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster);
|
||||
}
|
||||
|
||||
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
|
||||
{
|
||||
if (pos[i].x_offset || pos[i].y_offset)
|
||||
p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset);
|
||||
|
||||
*p++ = '+';
|
||||
p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance);
|
||||
if (pos->y_advance)
|
||||
p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance);
|
||||
}
|
||||
|
||||
if (buf_size > (p - b))
|
||||
{
|
||||
unsigned int l = p - b;
|
||||
memcpy (buf, b, l);
|
||||
buf += l;
|
||||
buf_size -= l;
|
||||
*buf_consumed += l;
|
||||
*buf = '\0';
|
||||
} else
|
||||
return i - start;
|
||||
}
|
||||
|
||||
return end - start;
|
||||
}
|
||||
|
||||
/* Returns number of items, starting at start, that were serialized. */
|
||||
unsigned int
|
||||
hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
char *buf,
|
||||
unsigned int buf_size,
|
||||
unsigned int *buf_consumed, /* May be NULL */
|
||||
hb_font_t *font, /* May be NULL */
|
||||
hb_buffer_serialize_format_t format,
|
||||
hb_buffer_serialize_flags_t flags)
|
||||
{
|
||||
assert (start <= end && end <= buffer->len);
|
||||
|
||||
unsigned int sconsumed;
|
||||
if (!buf_consumed)
|
||||
buf_consumed = &sconsumed;
|
||||
*buf_consumed = 0;
|
||||
|
||||
assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
|
||||
buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
|
||||
|
||||
if (unlikely (start == end))
|
||||
return 0;
|
||||
|
||||
if (!font)
|
||||
font = hb_font_get_empty ();
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
|
||||
return _hb_buffer_serialize_glyphs_text (buffer, start, end,
|
||||
buf, buf_size, buf_consumed,
|
||||
font, flags);
|
||||
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
|
||||
return _hb_buffer_serialize_glyphs_json (buffer, start, end,
|
||||
buf, buf_size, buf_consumed,
|
||||
font, flags);
|
||||
|
||||
default:
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static hb_bool_t
|
||||
parse_uint (const char *pp, const char *end, uint32_t *pv)
|
||||
{
|
||||
char buf[32];
|
||||
unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
|
||||
strncpy (buf, pp, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
char *p = buf;
|
||||
char *pend = p;
|
||||
uint32_t v;
|
||||
|
||||
errno = 0;
|
||||
v = strtol (p, &pend, 10);
|
||||
if (errno || p == pend || pend - p != end - pp)
|
||||
return false;
|
||||
|
||||
*pv = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
parse_int (const char *pp, const char *end, int32_t *pv)
|
||||
{
|
||||
char buf[32];
|
||||
unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
|
||||
strncpy (buf, pp, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
char *p = buf;
|
||||
char *pend = p;
|
||||
int32_t v;
|
||||
|
||||
errno = 0;
|
||||
v = strtol (p, &pend, 10);
|
||||
if (errno || p == pend || pend - p != end - pp)
|
||||
return false;
|
||||
|
||||
*pv = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "hb-buffer-deserialize-json.hh"
|
||||
#include "hb-buffer-deserialize-text.hh"
|
||||
|
||||
hb_bool_t
|
||||
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
|
||||
const char *buf,
|
||||
int buf_len, /* -1 means nul-terminated */
|
||||
const char **end_ptr, /* May be NULL */
|
||||
hb_font_t *font, /* May be NULL */
|
||||
hb_buffer_serialize_format_t format)
|
||||
{
|
||||
const char *end;
|
||||
if (!end_ptr)
|
||||
end_ptr = &end;
|
||||
*end_ptr = buf;
|
||||
|
||||
assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
|
||||
buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
|
||||
|
||||
if (buf_len == -1)
|
||||
buf_len = strlen (buf);
|
||||
|
||||
if (!buf_len)
|
||||
{
|
||||
*end_ptr = buf;
|
||||
return false;
|
||||
}
|
||||
|
||||
hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);
|
||||
|
||||
if (!font)
|
||||
font = hb_font_get_empty ();
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
|
||||
return _hb_buffer_deserialize_glyphs_text (buffer,
|
||||
buf, buf_len, end_ptr,
|
||||
font);
|
||||
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
|
||||
return _hb_buffer_deserialize_glyphs_json (buffer,
|
||||
buf, buf_len, end_ptr,
|
||||
font);
|
||||
|
||||
default:
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
1077
src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
vendored
Normal file
1077
src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
323
src/3rdparty/harfbuzz-ng/src/hb-buffer.h
vendored
Normal file
323
src/3rdparty/harfbuzz-ng/src/hb-buffer.h
vendored
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Copyright © 1998-2004 David Turner and Werner Lemberg
|
||||
* Copyright © 2004,2007,2009 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Owen Taylor, Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_BUFFER_H
|
||||
#define HB_BUFFER_H
|
||||
|
||||
#include "hb-common.h"
|
||||
#include "hb-unicode.h"
|
||||
#include "hb-font.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
typedef struct hb_glyph_info_t {
|
||||
hb_codepoint_t codepoint;
|
||||
hb_mask_t mask;
|
||||
uint32_t cluster;
|
||||
|
||||
/*< private >*/
|
||||
hb_var_int_t var1;
|
||||
hb_var_int_t var2;
|
||||
} hb_glyph_info_t;
|
||||
|
||||
typedef struct hb_glyph_position_t {
|
||||
hb_position_t x_advance;
|
||||
hb_position_t y_advance;
|
||||
hb_position_t x_offset;
|
||||
hb_position_t y_offset;
|
||||
|
||||
/*< private >*/
|
||||
hb_var_int_t var;
|
||||
} hb_glyph_position_t;
|
||||
|
||||
|
||||
typedef struct hb_segment_properties_t {
|
||||
hb_direction_t direction;
|
||||
hb_script_t script;
|
||||
hb_language_t language;
|
||||
/*< private >*/
|
||||
void *reserved1;
|
||||
void *reserved2;
|
||||
} hb_segment_properties_t;
|
||||
|
||||
#define HB_SEGMENT_PROPERTIES_DEFAULT {HB_DIRECTION_INVALID, \
|
||||
HB_SCRIPT_INVALID, \
|
||||
HB_LANGUAGE_INVALID, \
|
||||
NULL, \
|
||||
NULL}
|
||||
|
||||
hb_bool_t
|
||||
hb_segment_properties_equal (const hb_segment_properties_t *a,
|
||||
const hb_segment_properties_t *b);
|
||||
|
||||
unsigned int
|
||||
hb_segment_properties_hash (const hb_segment_properties_t *p);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* hb_buffer_t
|
||||
*/
|
||||
|
||||
typedef struct hb_buffer_t hb_buffer_t;
|
||||
|
||||
hb_buffer_t *
|
||||
hb_buffer_create (void);
|
||||
|
||||
hb_buffer_t *
|
||||
hb_buffer_get_empty (void);
|
||||
|
||||
hb_buffer_t *
|
||||
hb_buffer_reference (hb_buffer_t *buffer);
|
||||
|
||||
void
|
||||
hb_buffer_destroy (hb_buffer_t *buffer);
|
||||
|
||||
hb_bool_t
|
||||
hb_buffer_set_user_data (hb_buffer_t *buffer,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
void *
|
||||
hb_buffer_get_user_data (hb_buffer_t *buffer,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
|
||||
typedef enum {
|
||||
HB_BUFFER_CONTENT_TYPE_INVALID = 0,
|
||||
HB_BUFFER_CONTENT_TYPE_UNICODE,
|
||||
HB_BUFFER_CONTENT_TYPE_GLYPHS
|
||||
} hb_buffer_content_type_t;
|
||||
|
||||
void
|
||||
hb_buffer_set_content_type (hb_buffer_t *buffer,
|
||||
hb_buffer_content_type_t content_type);
|
||||
|
||||
hb_buffer_content_type_t
|
||||
hb_buffer_get_content_type (hb_buffer_t *buffer);
|
||||
|
||||
|
||||
void
|
||||
hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
|
||||
hb_unicode_funcs_t *unicode_funcs);
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_buffer_get_unicode_funcs (hb_buffer_t *buffer);
|
||||
|
||||
void
|
||||
hb_buffer_set_direction (hb_buffer_t *buffer,
|
||||
hb_direction_t direction);
|
||||
|
||||
hb_direction_t
|
||||
hb_buffer_get_direction (hb_buffer_t *buffer);
|
||||
|
||||
void
|
||||
hb_buffer_set_script (hb_buffer_t *buffer,
|
||||
hb_script_t script);
|
||||
|
||||
hb_script_t
|
||||
hb_buffer_get_script (hb_buffer_t *buffer);
|
||||
|
||||
void
|
||||
hb_buffer_set_language (hb_buffer_t *buffer,
|
||||
hb_language_t language);
|
||||
|
||||
|
||||
hb_language_t
|
||||
hb_buffer_get_language (hb_buffer_t *buffer);
|
||||
|
||||
void
|
||||
hb_buffer_set_segment_properties (hb_buffer_t *buffer,
|
||||
const hb_segment_properties_t *props);
|
||||
|
||||
void
|
||||
hb_buffer_get_segment_properties (hb_buffer_t *buffer,
|
||||
hb_segment_properties_t *props);
|
||||
|
||||
void
|
||||
hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
|
||||
|
||||
|
||||
typedef enum {
|
||||
HB_BUFFER_FLAGS_DEFAULT = 0x00000000,
|
||||
HB_BUFFER_FLAG_BOT = 0x00000001, /* Beginning-of-text */
|
||||
HB_BUFFER_FLAG_EOT = 0x00000002, /* End-of-text */
|
||||
HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004
|
||||
} hb_buffer_flags_t;
|
||||
|
||||
void
|
||||
hb_buffer_set_flags (hb_buffer_t *buffer,
|
||||
hb_buffer_flags_t flags);
|
||||
|
||||
hb_buffer_flags_t
|
||||
hb_buffer_get_flags (hb_buffer_t *buffer);
|
||||
|
||||
|
||||
/* Resets the buffer. Afterwards it's as if it was just created,
|
||||
* except that it has a larger buffer allocated perhaps... */
|
||||
void
|
||||
hb_buffer_reset (hb_buffer_t *buffer);
|
||||
|
||||
/* Like reset, but does NOT clear unicode_funcs. */
|
||||
void
|
||||
hb_buffer_clear_contents (hb_buffer_t *buffer);
|
||||
|
||||
/* Returns false if allocation failed */
|
||||
hb_bool_t
|
||||
hb_buffer_pre_allocate (hb_buffer_t *buffer,
|
||||
unsigned int size);
|
||||
|
||||
|
||||
/* Returns false if allocation has failed before */
|
||||
hb_bool_t
|
||||
hb_buffer_allocation_successful (hb_buffer_t *buffer);
|
||||
|
||||
void
|
||||
hb_buffer_reverse (hb_buffer_t *buffer);
|
||||
|
||||
void
|
||||
hb_buffer_reverse_clusters (hb_buffer_t *buffer);
|
||||
|
||||
|
||||
/* Filling the buffer in */
|
||||
|
||||
void
|
||||
hb_buffer_add (hb_buffer_t *buffer,
|
||||
hb_codepoint_t codepoint,
|
||||
unsigned int cluster);
|
||||
|
||||
void
|
||||
hb_buffer_add_utf8 (hb_buffer_t *buffer,
|
||||
const char *text,
|
||||
int text_length,
|
||||
unsigned int item_offset,
|
||||
int item_length);
|
||||
|
||||
void
|
||||
hb_buffer_add_utf16 (hb_buffer_t *buffer,
|
||||
const uint16_t *text,
|
||||
int text_length,
|
||||
unsigned int item_offset,
|
||||
int item_length);
|
||||
|
||||
void
|
||||
hb_buffer_add_utf32 (hb_buffer_t *buffer,
|
||||
const uint32_t *text,
|
||||
int text_length,
|
||||
unsigned int item_offset,
|
||||
int item_length);
|
||||
|
||||
|
||||
/* Clears any new items added at the end */
|
||||
hb_bool_t
|
||||
hb_buffer_set_length (hb_buffer_t *buffer,
|
||||
unsigned int length);
|
||||
|
||||
/* Return value valid as long as buffer not modified */
|
||||
unsigned int
|
||||
hb_buffer_get_length (hb_buffer_t *buffer);
|
||||
|
||||
/* Getting glyphs out of the buffer */
|
||||
|
||||
/* Return value valid as long as buffer not modified */
|
||||
hb_glyph_info_t *
|
||||
hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
|
||||
unsigned int *length);
|
||||
|
||||
/* Return value valid as long as buffer not modified */
|
||||
hb_glyph_position_t *
|
||||
hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
|
||||
unsigned int *length);
|
||||
|
||||
|
||||
/* Reorders a glyph buffer to have canonical in-cluster glyph order / position.
|
||||
* The resulting clusters should behave identical to pre-reordering clusters.
|
||||
* NOTE: This has nothing to do with Unicode normalization. */
|
||||
void
|
||||
hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
|
||||
|
||||
|
||||
/*
|
||||
* Serialize
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
HB_BUFFER_SERIALIZE_FLAGS_DEFAULT = 0x00000000,
|
||||
HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001,
|
||||
HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002,
|
||||
HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004
|
||||
} hb_buffer_serialize_flags_t;
|
||||
|
||||
typedef enum {
|
||||
HB_BUFFER_SERIALIZE_FORMAT_TEXT = HB_TAG('T','E','X','T'),
|
||||
HB_BUFFER_SERIALIZE_FORMAT_JSON = HB_TAG('J','S','O','N'),
|
||||
HB_BUFFER_SERIALIZE_FORMAT_INVALID = HB_TAG_NONE
|
||||
} hb_buffer_serialize_format_t;
|
||||
|
||||
/* len=-1 means str is NUL-terminated. */
|
||||
hb_buffer_serialize_format_t
|
||||
hb_buffer_serialize_format_from_string (const char *str, int len);
|
||||
|
||||
const char *
|
||||
hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format);
|
||||
|
||||
const char **
|
||||
hb_buffer_serialize_list_formats (void);
|
||||
|
||||
/* Returns number of items, starting at start, that were serialized. */
|
||||
unsigned int
|
||||
hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
char *buf,
|
||||
unsigned int buf_size,
|
||||
unsigned int *buf_consumed, /* May be NULL */
|
||||
hb_font_t *font, /* May be NULL */
|
||||
hb_buffer_serialize_format_t format,
|
||||
hb_buffer_serialize_flags_t flags);
|
||||
|
||||
hb_bool_t
|
||||
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
|
||||
const char *buf,
|
||||
int buf_len, /* -1 means nul-terminated */
|
||||
const char **end_ptr, /* May be NULL */
|
||||
hb_font_t *font, /* May be NULL */
|
||||
hb_buffer_serialize_format_t format);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_BUFFER_H */
|
74
src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh
vendored
Normal file
74
src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_CACHE_PRIVATE_HH
|
||||
#define HB_CACHE_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
/* Implements a lock-free cache for int->int functions. */
|
||||
|
||||
template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bits>
|
||||
struct hb_cache_t
|
||||
{
|
||||
ASSERT_STATIC (key_bits >= cache_bits);
|
||||
ASSERT_STATIC (key_bits + value_bits - cache_bits < 8 * sizeof (unsigned int));
|
||||
|
||||
inline void clear (void)
|
||||
{
|
||||
memset (values, 255, sizeof (values));
|
||||
}
|
||||
|
||||
inline bool get (unsigned int key, unsigned int *value)
|
||||
{
|
||||
unsigned int k = key & ((1<<cache_bits)-1);
|
||||
unsigned int v = values[k];
|
||||
if ((v >> value_bits) != (key >> cache_bits))
|
||||
return false;
|
||||
*value = v & ((1<<value_bits)-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool set (unsigned int key, unsigned int value)
|
||||
{
|
||||
if (unlikely ((key >> key_bits) || (value >> value_bits)))
|
||||
return false; /* Overflows */
|
||||
unsigned int k = key & ((1<<cache_bits)-1);
|
||||
unsigned int v = ((key>>cache_bits)<<value_bits) | value;
|
||||
values[k] = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int values[1<<cache_bits];
|
||||
};
|
||||
|
||||
typedef hb_cache_t<21, 16, 8> hb_cmap_cache_t;
|
||||
typedef hb_cache_t<16, 24, 8> hb_advance_cache_t;
|
||||
|
||||
|
||||
#endif /* HB_CACHE_PRIVATE_HH */
|
434
src/3rdparty/harfbuzz-ng/src/hb-common.cc
vendored
Normal file
434
src/3rdparty/harfbuzz-ng/src/hb-common.cc
vendored
Normal file
@ -0,0 +1,434 @@
|
||||
/*
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-version.h"
|
||||
|
||||
#include "hb-mutex-private.hh"
|
||||
#include "hb-object-private.hh"
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
|
||||
/* hb_options_t */
|
||||
|
||||
hb_options_union_t _hb_options;
|
||||
|
||||
void
|
||||
_hb_options_init (void)
|
||||
{
|
||||
hb_options_union_t u;
|
||||
u.i = 0;
|
||||
u.opts.initialized = 1;
|
||||
|
||||
char *c = getenv ("HB_OPTIONS");
|
||||
u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
|
||||
|
||||
/* This is idempotent and threadsafe. */
|
||||
_hb_options = u;
|
||||
}
|
||||
|
||||
|
||||
/* hb_tag_t */
|
||||
|
||||
hb_tag_t
|
||||
hb_tag_from_string (const char *s, int len)
|
||||
{
|
||||
char tag[4];
|
||||
unsigned int i;
|
||||
|
||||
if (!s || !len || !*s)
|
||||
return HB_TAG_NONE;
|
||||
|
||||
if (len < 0 || len > 4)
|
||||
len = 4;
|
||||
for (i = 0; i < (unsigned) len && s[i]; i++)
|
||||
tag[i] = s[i];
|
||||
for (; i < 4; i++)
|
||||
tag[i] = ' ';
|
||||
|
||||
return HB_TAG_CHAR4 (tag);
|
||||
}
|
||||
|
||||
void
|
||||
hb_tag_to_string (hb_tag_t tag, char *buf)
|
||||
{
|
||||
buf[0] = (char) (uint8_t) (tag >> 24);
|
||||
buf[1] = (char) (uint8_t) (tag >> 16);
|
||||
buf[2] = (char) (uint8_t) (tag >> 8);
|
||||
buf[3] = (char) (uint8_t) (tag >> 0);
|
||||
}
|
||||
|
||||
|
||||
/* hb_direction_t */
|
||||
|
||||
const char direction_strings[][4] = {
|
||||
"ltr",
|
||||
"rtl",
|
||||
"ttb",
|
||||
"btt"
|
||||
};
|
||||
|
||||
hb_direction_t
|
||||
hb_direction_from_string (const char *str, int len)
|
||||
{
|
||||
if (unlikely (!str || !len || !*str))
|
||||
return HB_DIRECTION_INVALID;
|
||||
|
||||
/* Lets match loosely: just match the first letter, such that
|
||||
* all of "ltr", "left-to-right", etc work!
|
||||
*/
|
||||
char c = TOLOWER (str[0]);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (direction_strings); i++)
|
||||
if (c == direction_strings[i][0])
|
||||
return (hb_direction_t) (HB_DIRECTION_LTR + i);
|
||||
|
||||
return HB_DIRECTION_INVALID;
|
||||
}
|
||||
|
||||
const char *
|
||||
hb_direction_to_string (hb_direction_t direction)
|
||||
{
|
||||
if (likely ((unsigned int) (direction - HB_DIRECTION_LTR)
|
||||
< ARRAY_LENGTH (direction_strings)))
|
||||
return direction_strings[direction - HB_DIRECTION_LTR];
|
||||
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
|
||||
/* hb_language_t */
|
||||
|
||||
struct hb_language_impl_t {
|
||||
const char s[1];
|
||||
};
|
||||
|
||||
static const char canon_map[256] = {
|
||||
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', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0,
|
||||
'-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-',
|
||||
0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static hb_bool_t
|
||||
lang_equal (hb_language_t v1,
|
||||
const void *v2)
|
||||
{
|
||||
const unsigned char *p1 = (const unsigned char *) v1;
|
||||
const unsigned char *p2 = (const unsigned char *) v2;
|
||||
|
||||
while (*p1 && *p1 == canon_map[*p2])
|
||||
p1++, p2++;
|
||||
|
||||
return *p1 == canon_map[*p2];
|
||||
}
|
||||
|
||||
#if 0
|
||||
static unsigned int
|
||||
lang_hash (const void *key)
|
||||
{
|
||||
const unsigned char *p = key;
|
||||
unsigned int h = 0;
|
||||
while (canon_map[*p])
|
||||
{
|
||||
h = (h << 5) - h + canon_map[*p];
|
||||
p++;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct hb_language_item_t {
|
||||
|
||||
struct hb_language_item_t *next;
|
||||
hb_language_t lang;
|
||||
|
||||
inline bool operator == (const char *s) const {
|
||||
return lang_equal (lang, s);
|
||||
}
|
||||
|
||||
inline hb_language_item_t & operator = (const char *s) {
|
||||
lang = (hb_language_t) strdup (s);
|
||||
for (unsigned char *p = (unsigned char *) lang; *p; p++)
|
||||
*p = canon_map[*p];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void finish (void) { free (lang); }
|
||||
};
|
||||
|
||||
|
||||
/* Thread-safe lock-free language list */
|
||||
|
||||
static hb_language_item_t *langs;
|
||||
|
||||
static inline
|
||||
void free_langs (void)
|
||||
{
|
||||
while (langs) {
|
||||
hb_language_item_t *next = langs->next;
|
||||
langs->finish ();
|
||||
free (langs);
|
||||
langs = next;
|
||||
}
|
||||
}
|
||||
|
||||
static hb_language_item_t *
|
||||
lang_find_or_insert (const char *key)
|
||||
{
|
||||
retry:
|
||||
hb_language_item_t *first_lang = (hb_language_item_t *) hb_atomic_ptr_get (&langs);
|
||||
|
||||
for (hb_language_item_t *lang = first_lang; lang; lang = lang->next)
|
||||
if (*lang == key)
|
||||
return lang;
|
||||
|
||||
/* Not found; allocate one. */
|
||||
hb_language_item_t *lang = (hb_language_item_t *) calloc (1, sizeof (hb_language_item_t));
|
||||
if (unlikely (!lang))
|
||||
return NULL;
|
||||
lang->next = first_lang;
|
||||
*lang = key;
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) {
|
||||
free (lang);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ATEXIT
|
||||
if (!first_lang)
|
||||
atexit (free_langs); /* First person registers atexit() callback. */
|
||||
#endif
|
||||
|
||||
return lang;
|
||||
}
|
||||
|
||||
|
||||
hb_language_t
|
||||
hb_language_from_string (const char *str, int len)
|
||||
{
|
||||
if (!str || !len || !*str)
|
||||
return HB_LANGUAGE_INVALID;
|
||||
|
||||
if (len >= 0) {
|
||||
char strbuf[64];
|
||||
len = MIN (len, (int) sizeof (strbuf) - 1);
|
||||
str = (char *) memcpy (strbuf, str, len);
|
||||
strbuf[len] = '\0';
|
||||
}
|
||||
|
||||
hb_language_item_t *item = lang_find_or_insert (str);
|
||||
|
||||
return likely (item) ? item->lang : HB_LANGUAGE_INVALID;
|
||||
}
|
||||
|
||||
const char *
|
||||
hb_language_to_string (hb_language_t language)
|
||||
{
|
||||
/* This is actually NULL-safe! */
|
||||
return language->s;
|
||||
}
|
||||
|
||||
hb_language_t
|
||||
hb_language_get_default (void)
|
||||
{
|
||||
static hb_language_t default_language = HB_LANGUAGE_INVALID;
|
||||
|
||||
hb_language_t language = (hb_language_t) hb_atomic_ptr_get (&default_language);
|
||||
if (unlikely (language == HB_LANGUAGE_INVALID)) {
|
||||
language = hb_language_from_string (setlocale (LC_CTYPE, NULL), -1);
|
||||
hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language);
|
||||
}
|
||||
|
||||
return default_language;
|
||||
}
|
||||
|
||||
|
||||
/* hb_script_t */
|
||||
|
||||
hb_script_t
|
||||
hb_script_from_iso15924_tag (hb_tag_t tag)
|
||||
{
|
||||
if (unlikely (tag == HB_TAG_NONE))
|
||||
return HB_SCRIPT_INVALID;
|
||||
|
||||
/* Be lenient, adjust case (one capital letter followed by three small letters) */
|
||||
tag = (tag & 0xDFDFDFDF) | 0x00202020;
|
||||
|
||||
switch (tag) {
|
||||
|
||||
/* These graduated from the 'Q' private-area codes, but
|
||||
* the old code is still aliased by Unicode, and the Qaai
|
||||
* one in use by ICU. */
|
||||
case HB_TAG('Q','a','a','i'): return HB_SCRIPT_INHERITED;
|
||||
case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC;
|
||||
|
||||
/* Script variants from http://unicode.org/iso15924/ */
|
||||
case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC;
|
||||
case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN;
|
||||
case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN;
|
||||
case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC;
|
||||
case HB_TAG('S','y','r','j'): return HB_SCRIPT_SYRIAC;
|
||||
case HB_TAG('S','y','r','n'): return HB_SCRIPT_SYRIAC;
|
||||
}
|
||||
|
||||
/* If it looks right, just use the tag as a script */
|
||||
if (((uint32_t) tag & 0xE0E0E0E0) == 0x40606060)
|
||||
return (hb_script_t) tag;
|
||||
|
||||
/* Otherwise, return unknown */
|
||||
return HB_SCRIPT_UNKNOWN;
|
||||
}
|
||||
|
||||
hb_script_t
|
||||
hb_script_from_string (const char *s, int len)
|
||||
{
|
||||
return hb_script_from_iso15924_tag (hb_tag_from_string (s, len));
|
||||
}
|
||||
|
||||
hb_tag_t
|
||||
hb_script_to_iso15924_tag (hb_script_t script)
|
||||
{
|
||||
return (hb_tag_t) script;
|
||||
}
|
||||
|
||||
hb_direction_t
|
||||
hb_script_get_horizontal_direction (hb_script_t script)
|
||||
{
|
||||
/* http://goo.gl/x9ilM */
|
||||
switch ((hb_tag_t) script)
|
||||
{
|
||||
/* Unicode-1.1 additions */
|
||||
case HB_SCRIPT_ARABIC:
|
||||
case HB_SCRIPT_HEBREW:
|
||||
|
||||
/* Unicode-3.0 additions */
|
||||
case HB_SCRIPT_SYRIAC:
|
||||
case HB_SCRIPT_THAANA:
|
||||
|
||||
/* Unicode-4.0 additions */
|
||||
case HB_SCRIPT_CYPRIOT:
|
||||
|
||||
/* Unicode-4.1 additions */
|
||||
case HB_SCRIPT_KHAROSHTHI:
|
||||
|
||||
/* Unicode-5.0 additions */
|
||||
case HB_SCRIPT_PHOENICIAN:
|
||||
case HB_SCRIPT_NKO:
|
||||
|
||||
/* Unicode-5.1 additions */
|
||||
case HB_SCRIPT_LYDIAN:
|
||||
|
||||
/* Unicode-5.2 additions */
|
||||
case HB_SCRIPT_AVESTAN:
|
||||
case HB_SCRIPT_IMPERIAL_ARAMAIC:
|
||||
case HB_SCRIPT_INSCRIPTIONAL_PAHLAVI:
|
||||
case HB_SCRIPT_INSCRIPTIONAL_PARTHIAN:
|
||||
case HB_SCRIPT_OLD_SOUTH_ARABIAN:
|
||||
case HB_SCRIPT_OLD_TURKIC:
|
||||
case HB_SCRIPT_SAMARITAN:
|
||||
|
||||
/* Unicode-6.0 additions */
|
||||
case HB_SCRIPT_MANDAIC:
|
||||
|
||||
/* Unicode-6.1 additions */
|
||||
case HB_SCRIPT_MEROITIC_CURSIVE:
|
||||
case HB_SCRIPT_MEROITIC_HIEROGLYPHS:
|
||||
|
||||
return HB_DIRECTION_RTL;
|
||||
}
|
||||
|
||||
return HB_DIRECTION_LTR;
|
||||
}
|
||||
|
||||
|
||||
/* hb_user_data_array_t */
|
||||
|
||||
bool
|
||||
hb_user_data_array_t::set (hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
if (!key)
|
||||
return false;
|
||||
|
||||
if (replace) {
|
||||
if (!data && !destroy) {
|
||||
items.remove (key, lock);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
hb_user_data_item_t item = {key, data, destroy};
|
||||
bool ret = !!items.replace_or_insert (item, lock, replace);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
hb_user_data_array_t::get (hb_user_data_key_t *key)
|
||||
{
|
||||
hb_user_data_item_t item = {NULL };
|
||||
|
||||
return items.find (key, &item, lock) ? item.data : NULL;
|
||||
}
|
||||
|
||||
|
||||
/* hb_version */
|
||||
|
||||
void
|
||||
hb_version (unsigned int *major,
|
||||
unsigned int *minor,
|
||||
unsigned int *micro)
|
||||
{
|
||||
*major = HB_VERSION_MAJOR;
|
||||
*minor = HB_VERSION_MINOR;
|
||||
*micro = HB_VERSION_MICRO;
|
||||
}
|
||||
|
||||
const char *
|
||||
hb_version_string (void)
|
||||
{
|
||||
return HB_VERSION_STRING;
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_version_check (unsigned int major,
|
||||
unsigned int minor,
|
||||
unsigned int micro)
|
||||
{
|
||||
return HB_VERSION_CHECK (major, minor, micro);
|
||||
}
|
336
src/3rdparty/harfbuzz-ng/src/hb-common.h
vendored
Normal file
336
src/3rdparty/harfbuzz-ng/src/hb-common.h
vendored
Normal file
@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_COMMON_H
|
||||
#define HB_COMMON_H
|
||||
|
||||
#ifndef HB_BEGIN_DECLS
|
||||
# ifdef __cplusplus
|
||||
# define HB_BEGIN_DECLS extern "C" {
|
||||
# define HB_END_DECLS }
|
||||
# else /* !__cplusplus */
|
||||
# define HB_BEGIN_DECLS
|
||||
# define HB_END_DECLS
|
||||
# endif /* !__cplusplus */
|
||||
#endif
|
||||
|
||||
#if !defined (HB_DONT_DEFINE_STDINT)
|
||||
|
||||
#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \
|
||||
defined (_sgi) || defined (__sun) || defined (sun) || \
|
||||
defined (__digital__) || defined (__HP_cc)
|
||||
# include <inttypes.h>
|
||||
#elif defined (_AIX)
|
||||
# include <sys/inttypes.h>
|
||||
/* VS 2010 (_MSC_VER 1600) has stdint.h */
|
||||
#elif defined (_MSC_VER) && _MSC_VER < 1600
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
typedef int hb_bool_t;
|
||||
|
||||
typedef uint32_t hb_codepoint_t;
|
||||
typedef int32_t hb_position_t;
|
||||
typedef uint32_t hb_mask_t;
|
||||
|
||||
typedef union _hb_var_int_t {
|
||||
uint32_t u32;
|
||||
int32_t i32;
|
||||
uint16_t u16[2];
|
||||
int16_t i16[2];
|
||||
uint8_t u8[4];
|
||||
int8_t i8[4];
|
||||
} hb_var_int_t;
|
||||
|
||||
|
||||
/* hb_tag_t */
|
||||
|
||||
typedef uint32_t hb_tag_t;
|
||||
|
||||
#define HB_TAG(a,b,c,d) ((hb_tag_t)((((uint8_t)(a))<<24)|(((uint8_t)(b))<<16)|(((uint8_t)(c))<<8)|((uint8_t)(d))))
|
||||
#define HB_UNTAG(tag) ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag))
|
||||
|
||||
#define HB_TAG_NONE HB_TAG(0,0,0,0)
|
||||
|
||||
/* len=-1 means str is NUL-terminated. */
|
||||
hb_tag_t
|
||||
hb_tag_from_string (const char *str, int len);
|
||||
|
||||
/* buf should have 4 bytes. */
|
||||
void
|
||||
hb_tag_to_string (hb_tag_t tag, char *buf);
|
||||
|
||||
|
||||
/* hb_direction_t */
|
||||
|
||||
typedef enum {
|
||||
HB_DIRECTION_INVALID = 0,
|
||||
HB_DIRECTION_LTR = 4,
|
||||
HB_DIRECTION_RTL,
|
||||
HB_DIRECTION_TTB,
|
||||
HB_DIRECTION_BTT
|
||||
} hb_direction_t;
|
||||
|
||||
/* len=-1 means str is NUL-terminated */
|
||||
hb_direction_t
|
||||
hb_direction_from_string (const char *str, int len);
|
||||
|
||||
const char *
|
||||
hb_direction_to_string (hb_direction_t direction);
|
||||
|
||||
#define HB_DIRECTION_IS_HORIZONTAL(dir) ((((unsigned int) (dir)) & ~1U) == 4)
|
||||
#define HB_DIRECTION_IS_VERTICAL(dir) ((((unsigned int) (dir)) & ~1U) == 6)
|
||||
#define HB_DIRECTION_IS_FORWARD(dir) ((((unsigned int) (dir)) & ~2U) == 4)
|
||||
#define HB_DIRECTION_IS_BACKWARD(dir) ((((unsigned int) (dir)) & ~2U) == 5)
|
||||
#define HB_DIRECTION_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4)
|
||||
#define HB_DIRECTION_REVERSE(dir) ((hb_direction_t) (((unsigned int) (dir)) ^ 1)) /* Direction must be valid */
|
||||
|
||||
|
||||
/* hb_language_t */
|
||||
|
||||
typedef struct hb_language_impl_t *hb_language_t;
|
||||
|
||||
/* len=-1 means str is NUL-terminated */
|
||||
hb_language_t
|
||||
hb_language_from_string (const char *str, int len);
|
||||
|
||||
const char *
|
||||
hb_language_to_string (hb_language_t language);
|
||||
|
||||
#define HB_LANGUAGE_INVALID ((hb_language_t) NULL)
|
||||
|
||||
hb_language_t
|
||||
hb_language_get_default (void);
|
||||
|
||||
|
||||
/* hb_script_t */
|
||||
|
||||
/* http://unicode.org/iso15924/ */
|
||||
/* http://goo.gl/x9ilM */
|
||||
/* Unicode Character Database property: Script (sc) */
|
||||
typedef enum
|
||||
{
|
||||
/*1.1*/ HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'),
|
||||
/*1.1*/ HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'),
|
||||
/*5.0*/ HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'),
|
||||
|
||||
/*1.1*/ HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'),
|
||||
/*1.1*/ HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'),
|
||||
/*1.1*/ HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'),
|
||||
/*1.1*/ HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'),
|
||||
/*1.1*/ HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'),
|
||||
/*1.1*/ HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'),
|
||||
/*1.1*/ HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'),
|
||||
/*1.1*/ HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'),
|
||||
/*1.1*/ HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'),
|
||||
/*1.1*/ HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'),
|
||||
/*1.1*/ HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'),
|
||||
/*1.1*/ HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'),
|
||||
/*1.1*/ HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'),
|
||||
/*1.1*/ HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'),
|
||||
/*1.1*/ HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'),
|
||||
/*1.1*/ HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'),
|
||||
/*1.1*/ HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'),
|
||||
/*1.1*/ HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'),
|
||||
/*1.1*/ HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'),
|
||||
/*1.1*/ HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'),
|
||||
/*1.1*/ HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'),
|
||||
/*1.1*/ HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'),
|
||||
|
||||
/*2.0*/ HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'),
|
||||
|
||||
/*3.0*/ HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'),
|
||||
/*3.0*/ HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'),
|
||||
/*3.0*/ HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'),
|
||||
/*3.0*/ HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'),
|
||||
/*3.0*/ HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'),
|
||||
/*3.0*/ HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'),
|
||||
/*3.0*/ HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'),
|
||||
/*3.0*/ HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'),
|
||||
/*3.0*/ HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'),
|
||||
/*3.0*/ HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'),
|
||||
/*3.0*/ HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'),
|
||||
/*3.0*/ HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'),
|
||||
/*3.0*/ HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'),
|
||||
/*3.0*/ HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'),
|
||||
|
||||
/*3.1*/ HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'),
|
||||
/*3.1*/ HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'),
|
||||
/*3.1*/ HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'),
|
||||
|
||||
/*3.2*/ HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'),
|
||||
/*3.2*/ HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'),
|
||||
/*3.2*/ HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'),
|
||||
/*3.2*/ HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'),
|
||||
|
||||
/*4.0*/ HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'),
|
||||
/*4.0*/ HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'),
|
||||
/*4.0*/ HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'),
|
||||
/*4.0*/ HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'),
|
||||
/*4.0*/ HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'),
|
||||
/*4.0*/ HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'),
|
||||
/*4.0*/ HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'),
|
||||
|
||||
/*4.1*/ HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'),
|
||||
/*4.1*/ HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'),
|
||||
/*4.1*/ HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'),
|
||||
/*4.1*/ HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'),
|
||||
/*4.1*/ HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'),
|
||||
/*4.1*/ HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'),
|
||||
/*4.1*/ HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'),
|
||||
/*4.1*/ HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'),
|
||||
|
||||
/*5.0*/ HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'),
|
||||
/*5.0*/ HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'),
|
||||
/*5.0*/ HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'),
|
||||
/*5.0*/ HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'),
|
||||
/*5.0*/ HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'),
|
||||
|
||||
/*5.1*/ HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'),
|
||||
/*5.1*/ HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'),
|
||||
/*5.1*/ HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'),
|
||||
/*5.1*/ HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'),
|
||||
/*5.1*/ HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'),
|
||||
/*5.1*/ HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'),
|
||||
/*5.1*/ HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'),
|
||||
/*5.1*/ HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'),
|
||||
/*5.1*/ HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'),
|
||||
/*5.1*/ HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'),
|
||||
/*5.1*/ HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'),
|
||||
|
||||
/*5.2*/ HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'),
|
||||
/*5.2*/ HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'),
|
||||
/*5.2*/ HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'),
|
||||
/*5.2*/ HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'),
|
||||
/*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'),
|
||||
/*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'),
|
||||
/*5.2*/ HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'),
|
||||
/*5.2*/ HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'),
|
||||
/*5.2*/ HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'),
|
||||
/*5.2*/ HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'),
|
||||
/*5.2*/ HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'),
|
||||
/*5.2*/ HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'),
|
||||
/*5.2*/ HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'),
|
||||
/*5.2*/ HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'),
|
||||
/*5.2*/ HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'),
|
||||
|
||||
/*6.0*/ HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'),
|
||||
/*6.0*/ HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'),
|
||||
/*6.0*/ HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'),
|
||||
|
||||
/*6.1*/ HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'),
|
||||
/*6.1*/ HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'),
|
||||
/*6.1*/ HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'),
|
||||
/*6.1*/ HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'),
|
||||
/*6.1*/ HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'),
|
||||
/*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'),
|
||||
/*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'),
|
||||
|
||||
/* No script set. */
|
||||
/*---*/ HB_SCRIPT_INVALID = HB_TAG_NONE
|
||||
} hb_script_t;
|
||||
|
||||
/* Deprecated misspellings. */
|
||||
#define HB_SCRIPT_CANADIAN_ABORIGINAL HB_SCRIPT_CANADIAN_SYLLABICS
|
||||
|
||||
/* These are moved out of hb_script_t because glib-mkenums chokes otherwise. */
|
||||
#if 0
|
||||
/*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'),
|
||||
/*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'),
|
||||
/*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'),
|
||||
/*7.0*/ HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'),
|
||||
/*7.0*/ HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'),
|
||||
/*7.0*/ HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'),
|
||||
/*7.0*/ HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'),
|
||||
/*7.0*/ HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'),
|
||||
/*7.0*/ HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'),
|
||||
/*7.0*/ HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'),
|
||||
/*7.0*/ HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'),
|
||||
/*7.0*/ HB_SCRIPT_MODI = ???
|
||||
/*7.0*/ HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'),
|
||||
/*7.0*/ HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'),
|
||||
/*7.0*/ HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'),
|
||||
/*7.0*/ HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'),
|
||||
/*7.0*/ HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'),
|
||||
/*7.0*/ HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'),
|
||||
/*7.0*/ HB_SCRIPT_PAU_CIN_HAU = ???
|
||||
/*7.0*/ HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'),
|
||||
/*7.0*/ HB_SCRIPT_SIDDHAM = ???
|
||||
/*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'),
|
||||
/*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'),
|
||||
#endif
|
||||
|
||||
|
||||
/* Script functions */
|
||||
|
||||
hb_script_t
|
||||
hb_script_from_iso15924_tag (hb_tag_t tag);
|
||||
|
||||
/* suger for tag_from_string() then script_from_iso15924_tag */
|
||||
/* len=-1 means s is NUL-terminated */
|
||||
hb_script_t
|
||||
hb_script_from_string (const char *s, int len);
|
||||
|
||||
hb_tag_t
|
||||
hb_script_to_iso15924_tag (hb_script_t script);
|
||||
|
||||
hb_direction_t
|
||||
hb_script_get_horizontal_direction (hb_script_t script);
|
||||
|
||||
|
||||
/* User data */
|
||||
|
||||
typedef struct hb_user_data_key_t {
|
||||
/*< private >*/
|
||||
char unused;
|
||||
} hb_user_data_key_t;
|
||||
|
||||
typedef void (*hb_destroy_func_t) (void *user_data);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_COMMON_H */
|
128
src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
vendored
Normal file
128
src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright © 2011 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#define HB_SHAPER fallback
|
||||
#include "hb-shaper-impl-private.hh"
|
||||
|
||||
|
||||
/*
|
||||
* shaper face data
|
||||
*/
|
||||
|
||||
struct hb_fallback_shaper_face_data_t {};
|
||||
|
||||
hb_fallback_shaper_face_data_t *
|
||||
_hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED)
|
||||
{
|
||||
return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper font data
|
||||
*/
|
||||
|
||||
struct hb_fallback_shaper_font_data_t {};
|
||||
|
||||
hb_fallback_shaper_font_data_t *
|
||||
_hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED)
|
||||
{
|
||||
return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper shape_plan data
|
||||
*/
|
||||
|
||||
struct hb_fallback_shaper_shape_plan_data_t {};
|
||||
|
||||
hb_fallback_shaper_shape_plan_data_t *
|
||||
_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED)
|
||||
{
|
||||
return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper
|
||||
*/
|
||||
|
||||
hb_bool_t
|
||||
_hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features HB_UNUSED,
|
||||
unsigned int num_features HB_UNUSED)
|
||||
{
|
||||
hb_codepoint_t space;
|
||||
font->get_glyph (' ', 0, &space);
|
||||
|
||||
buffer->clear_positions ();
|
||||
|
||||
unsigned int count = buffer->len;
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if (buffer->unicode->is_default_ignorable (buffer->info[i].codepoint)) {
|
||||
buffer->info[i].codepoint = space;
|
||||
buffer->pos[i].x_advance = 0;
|
||||
buffer->pos[i].y_advance = 0;
|
||||
continue;
|
||||
}
|
||||
font->get_glyph (buffer->info[i].codepoint, 0, &buffer->info[i].codepoint);
|
||||
font->get_glyph_advance_for_direction (buffer->info[i].codepoint,
|
||||
buffer->props.direction,
|
||||
&buffer->pos[i].x_advance,
|
||||
&buffer->pos[i].y_advance);
|
||||
font->subtract_glyph_origin_for_direction (buffer->info[i].codepoint,
|
||||
buffer->props.direction,
|
||||
&buffer->pos[i].x_offset,
|
||||
&buffer->pos[i].y_offset);
|
||||
}
|
||||
|
||||
if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
|
||||
hb_buffer_reverse (buffer);
|
||||
|
||||
return true;
|
||||
}
|
478
src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
vendored
Normal file
478
src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
vendored
Normal file
@ -0,0 +1,478 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2011 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_FONT_PRIVATE_HH
|
||||
#define HB_FONT_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-font.h"
|
||||
#include "hb-object-private.hh"
|
||||
#include "hb-shaper-private.hh"
|
||||
#include "hb-shape-plan-private.hh"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* hb_font_funcs_t
|
||||
*/
|
||||
|
||||
#define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_name) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
|
||||
/* ^--- Add new callbacks here */
|
||||
|
||||
struct hb_font_funcs_t {
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
||||
hb_bool_t immutable;
|
||||
|
||||
/* Don't access these directly. Call hb_font_get_*() instead. */
|
||||
|
||||
struct {
|
||||
#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
|
||||
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_FONT_FUNC_IMPLEMENT
|
||||
} get;
|
||||
|
||||
struct {
|
||||
#define HB_FONT_FUNC_IMPLEMENT(name) void *name;
|
||||
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_FONT_FUNC_IMPLEMENT
|
||||
} user_data;
|
||||
|
||||
struct {
|
||||
#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
|
||||
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_FONT_FUNC_IMPLEMENT
|
||||
} destroy;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* hb_face_t
|
||||
*/
|
||||
|
||||
struct hb_face_t {
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
||||
hb_bool_t immutable;
|
||||
|
||||
hb_reference_table_func_t reference_table_func;
|
||||
void *user_data;
|
||||
hb_destroy_func_t destroy;
|
||||
|
||||
unsigned int index;
|
||||
mutable unsigned int upem;
|
||||
mutable unsigned int num_glyphs;
|
||||
|
||||
struct hb_shaper_data_t shaper_data;
|
||||
|
||||
struct plan_node_t {
|
||||
hb_shape_plan_t *shape_plan;
|
||||
plan_node_t *next;
|
||||
} *shape_plans;
|
||||
|
||||
|
||||
inline hb_blob_t *reference_table (hb_tag_t tag) const
|
||||
{
|
||||
hb_blob_t *blob;
|
||||
|
||||
if (unlikely (!this || !reference_table_func))
|
||||
return hb_blob_get_empty ();
|
||||
|
||||
blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data);
|
||||
if (unlikely (!blob))
|
||||
return hb_blob_get_empty ();
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
inline HB_PURE_FUNC unsigned int get_upem (void) const
|
||||
{
|
||||
if (unlikely (!upem))
|
||||
load_upem ();
|
||||
return upem;
|
||||
}
|
||||
|
||||
inline unsigned int get_num_glyphs (void) const
|
||||
{
|
||||
if (unlikely (num_glyphs == (unsigned int) -1))
|
||||
load_num_glyphs ();
|
||||
return num_glyphs;
|
||||
}
|
||||
|
||||
private:
|
||||
HB_INTERNAL void load_upem (void) const;
|
||||
HB_INTERNAL void load_num_glyphs (void) const;
|
||||
};
|
||||
|
||||
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face);
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
||||
|
||||
|
||||
/*
|
||||
* hb_font_t
|
||||
*/
|
||||
|
||||
struct hb_font_t {
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
||||
hb_bool_t immutable;
|
||||
|
||||
hb_font_t *parent;
|
||||
hb_face_t *face;
|
||||
|
||||
int x_scale;
|
||||
int y_scale;
|
||||
|
||||
unsigned int x_ppem;
|
||||
unsigned int y_ppem;
|
||||
|
||||
hb_font_funcs_t *klass;
|
||||
void *user_data;
|
||||
hb_destroy_func_t destroy;
|
||||
|
||||
struct hb_shaper_data_t shaper_data;
|
||||
|
||||
|
||||
/* Convert from font-space to user-space */
|
||||
inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scale); }
|
||||
inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, this->y_scale); }
|
||||
|
||||
/* Convert from parent-font user-space to our user-space */
|
||||
inline hb_position_t parent_scale_x_distance (hb_position_t v) {
|
||||
if (unlikely (parent && parent->x_scale != x_scale))
|
||||
return v * (int64_t) this->x_scale / this->parent->x_scale;
|
||||
return v;
|
||||
}
|
||||
inline hb_position_t parent_scale_y_distance (hb_position_t v) {
|
||||
if (unlikely (parent && parent->y_scale != y_scale))
|
||||
return v * (int64_t) this->y_scale / this->parent->y_scale;
|
||||
return v;
|
||||
}
|
||||
inline hb_position_t parent_scale_x_position (hb_position_t v) {
|
||||
return parent_scale_x_distance (v);
|
||||
}
|
||||
inline hb_position_t parent_scale_y_position (hb_position_t v) {
|
||||
return parent_scale_y_distance (v);
|
||||
}
|
||||
|
||||
inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) {
|
||||
*x = parent_scale_x_distance (*x);
|
||||
*y = parent_scale_y_distance (*y);
|
||||
}
|
||||
inline void parent_scale_position (hb_position_t *x, hb_position_t *y) {
|
||||
*x = parent_scale_x_position (*x);
|
||||
*y = parent_scale_y_position (*y);
|
||||
}
|
||||
|
||||
|
||||
/* Public getters */
|
||||
|
||||
inline hb_bool_t get_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
|
||||
hb_codepoint_t *glyph)
|
||||
{
|
||||
*glyph = 0;
|
||||
return klass->get.glyph (this, user_data,
|
||||
unicode, variation_selector, glyph,
|
||||
klass->user_data.glyph);
|
||||
}
|
||||
|
||||
inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
|
||||
{
|
||||
return klass->get.glyph_h_advance (this, user_data,
|
||||
glyph,
|
||||
klass->user_data.glyph_h_advance);
|
||||
}
|
||||
|
||||
inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
|
||||
{
|
||||
return klass->get.glyph_v_advance (this, user_data,
|
||||
glyph,
|
||||
klass->user_data.glyph_v_advance);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
*x = *y = 0;
|
||||
return klass->get.glyph_h_origin (this, user_data,
|
||||
glyph, x, y,
|
||||
klass->user_data.glyph_h_origin);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
*x = *y = 0;
|
||||
return klass->get.glyph_v_origin (this, user_data,
|
||||
glyph, x, y,
|
||||
klass->user_data.glyph_v_origin);
|
||||
}
|
||||
|
||||
inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
|
||||
{
|
||||
return klass->get.glyph_h_kerning (this, user_data,
|
||||
left_glyph, right_glyph,
|
||||
klass->user_data.glyph_h_kerning);
|
||||
}
|
||||
|
||||
inline hb_position_t get_glyph_v_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
|
||||
{
|
||||
return klass->get.glyph_v_kerning (this, user_data,
|
||||
left_glyph, right_glyph,
|
||||
klass->user_data.glyph_v_kerning);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents)
|
||||
{
|
||||
memset (extents, 0, sizeof (*extents));
|
||||
return klass->get.glyph_extents (this, user_data,
|
||||
glyph,
|
||||
extents,
|
||||
klass->user_data.glyph_extents);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
*x = *y = 0;
|
||||
return klass->get.glyph_contour_point (this, user_data,
|
||||
glyph, point_index,
|
||||
x, y,
|
||||
klass->user_data.glyph_contour_point);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_name (hb_codepoint_t glyph,
|
||||
char *name, unsigned int size)
|
||||
{
|
||||
if (size) *name = '\0';
|
||||
return klass->get.glyph_name (this, user_data,
|
||||
glyph,
|
||||
name, size,
|
||||
klass->user_data.glyph_name);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
|
||||
hb_codepoint_t *glyph)
|
||||
{
|
||||
*glyph = 0;
|
||||
if (len == -1) len = strlen (name);
|
||||
return klass->get.glyph_from_name (this, user_data,
|
||||
name, len,
|
||||
glyph,
|
||||
klass->user_data.glyph_from_name);
|
||||
}
|
||||
|
||||
|
||||
/* A bit higher-level, and with fallback */
|
||||
|
||||
inline void get_glyph_advance_for_direction (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
|
||||
*x = get_glyph_h_advance (glyph);
|
||||
*y = 0;
|
||||
} else {
|
||||
*x = 0;
|
||||
*y = get_glyph_v_advance (glyph);
|
||||
}
|
||||
}
|
||||
|
||||
/* Internal only */
|
||||
inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
*x = get_glyph_h_advance (glyph) / 2;
|
||||
|
||||
/* TODO use font_metics.ascent */
|
||||
*y = y_scale;
|
||||
}
|
||||
|
||||
inline void get_glyph_origin_for_direction (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
|
||||
{
|
||||
if (!get_glyph_h_origin (glyph, x, y) &&
|
||||
get_glyph_v_origin (glyph, x, y))
|
||||
{
|
||||
hb_position_t dx, dy;
|
||||
guess_v_origin_minus_h_origin (glyph, &dx, &dy);
|
||||
*x -= dx; *y -= dy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!get_glyph_v_origin (glyph, x, y) &&
|
||||
get_glyph_h_origin (glyph, x, y))
|
||||
{
|
||||
hb_position_t dx, dy;
|
||||
guess_v_origin_minus_h_origin (glyph, &dx, &dy);
|
||||
*x += dx; *y += dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void add_glyph_origin_for_direction (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
hb_position_t origin_x, origin_y;
|
||||
|
||||
get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
|
||||
|
||||
*x += origin_x;
|
||||
*y += origin_y;
|
||||
}
|
||||
|
||||
inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
hb_position_t origin_x, origin_y;
|
||||
|
||||
get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
|
||||
|
||||
*x -= origin_x;
|
||||
*y -= origin_y;
|
||||
}
|
||||
|
||||
inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
|
||||
*x = get_glyph_h_kerning (first_glyph, second_glyph);
|
||||
*y = 0;
|
||||
} else {
|
||||
*x = 0;
|
||||
*y = get_glyph_v_kerning (first_glyph, second_glyph);
|
||||
}
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_glyph_extents_t *extents)
|
||||
{
|
||||
hb_bool_t ret = get_glyph_extents (glyph, extents);
|
||||
|
||||
if (ret)
|
||||
subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y);
|
||||
|
||||
if (ret)
|
||||
subtract_glyph_origin_for_direction (glyph, direction, x, y);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Generates gidDDD if glyph has no name. */
|
||||
inline void
|
||||
glyph_to_string (hb_codepoint_t glyph,
|
||||
char *s, unsigned int size)
|
||||
{
|
||||
if (get_glyph_name (glyph, s, size)) return;
|
||||
|
||||
snprintf (s, size, "gid%u", glyph);
|
||||
}
|
||||
|
||||
/* Parses gidDDD and uniUUUU strings automatically. */
|
||||
inline hb_bool_t
|
||||
glyph_from_string (const char *s, int len, /* -1 means nul-terminated */
|
||||
hb_codepoint_t *glyph)
|
||||
{
|
||||
if (get_glyph_from_name (s, len, glyph)) return true;
|
||||
|
||||
if (len == -1) len = strlen (s);
|
||||
|
||||
/* Straight glyph index. */
|
||||
if (hb_codepoint_parse (s, len, 10, glyph))
|
||||
return true;
|
||||
|
||||
if (len > 3)
|
||||
{
|
||||
/* gidDDD syntax for glyph indices. */
|
||||
if (0 == strncmp (s, "gid", 3) &&
|
||||
hb_codepoint_parse (s + 3, len - 3, 10, glyph))
|
||||
return true;
|
||||
|
||||
/* uniUUUU and other Unicode character indices. */
|
||||
hb_codepoint_t unichar;
|
||||
if (0 == strncmp (s, "uni", 3) &&
|
||||
hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
|
||||
get_glyph (unichar, 0, glyph))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
inline hb_position_t em_scale (int16_t v, int scale)
|
||||
{
|
||||
unsigned int upem = face->get_upem ();
|
||||
return (v * (int64_t) scale + upem / 2) / upem;
|
||||
}
|
||||
};
|
||||
|
||||
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
||||
|
||||
|
||||
#endif /* HB_FONT_PRIVATE_HH */
|
1008
src/3rdparty/harfbuzz-ng/src/hb-font.cc
vendored
Normal file
1008
src/3rdparty/harfbuzz-ng/src/hb-font.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
454
src/3rdparty/harfbuzz-ng/src/hb-font.h
vendored
Normal file
454
src/3rdparty/harfbuzz-ng/src/hb-font.h
vendored
Normal file
@ -0,0 +1,454 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_FONT_H
|
||||
#define HB_FONT_H
|
||||
|
||||
#include "hb-common.h"
|
||||
#include "hb-blob.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
typedef struct hb_face_t hb_face_t;
|
||||
typedef struct hb_font_t hb_font_t;
|
||||
|
||||
/*
|
||||
* hb_face_t
|
||||
*/
|
||||
|
||||
hb_face_t *
|
||||
hb_face_create (hb_blob_t *blob,
|
||||
unsigned int index);
|
||||
|
||||
typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data);
|
||||
|
||||
/* calls destroy() when not needing user_data anymore */
|
||||
hb_face_t *
|
||||
hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
|
||||
void *user_data,
|
||||
hb_destroy_func_t destroy);
|
||||
|
||||
hb_face_t *
|
||||
hb_face_get_empty (void);
|
||||
|
||||
hb_face_t *
|
||||
hb_face_reference (hb_face_t *face);
|
||||
|
||||
void
|
||||
hb_face_destroy (hb_face_t *face);
|
||||
|
||||
hb_bool_t
|
||||
hb_face_set_user_data (hb_face_t *face,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
|
||||
void *
|
||||
hb_face_get_user_data (hb_face_t *face,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
void
|
||||
hb_face_make_immutable (hb_face_t *face);
|
||||
|
||||
hb_bool_t
|
||||
hb_face_is_immutable (hb_face_t *face);
|
||||
|
||||
|
||||
hb_blob_t *
|
||||
hb_face_reference_table (hb_face_t *face,
|
||||
hb_tag_t tag);
|
||||
|
||||
hb_blob_t *
|
||||
hb_face_reference_blob (hb_face_t *face);
|
||||
|
||||
void
|
||||
hb_face_set_index (hb_face_t *face,
|
||||
unsigned int index);
|
||||
|
||||
unsigned int
|
||||
hb_face_get_index (hb_face_t *face);
|
||||
|
||||
void
|
||||
hb_face_set_upem (hb_face_t *face,
|
||||
unsigned int upem);
|
||||
|
||||
unsigned int
|
||||
hb_face_get_upem (hb_face_t *face);
|
||||
|
||||
void
|
||||
hb_face_set_glyph_count (hb_face_t *face,
|
||||
unsigned int glyph_count);
|
||||
|
||||
unsigned int
|
||||
hb_face_get_glyph_count (hb_face_t *face);
|
||||
|
||||
|
||||
/*
|
||||
* hb_font_funcs_t
|
||||
*/
|
||||
|
||||
typedef struct hb_font_funcs_t hb_font_funcs_t;
|
||||
|
||||
hb_font_funcs_t *
|
||||
hb_font_funcs_create (void);
|
||||
|
||||
hb_font_funcs_t *
|
||||
hb_font_funcs_get_empty (void);
|
||||
|
||||
hb_font_funcs_t *
|
||||
hb_font_funcs_reference (hb_font_funcs_t *ffuncs);
|
||||
|
||||
void
|
||||
hb_font_funcs_destroy (hb_font_funcs_t *ffuncs);
|
||||
|
||||
hb_bool_t
|
||||
hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
|
||||
void *
|
||||
hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
|
||||
void
|
||||
hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs);
|
||||
|
||||
hb_bool_t
|
||||
hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs);
|
||||
|
||||
|
||||
/* glyph extents */
|
||||
|
||||
typedef struct hb_glyph_extents_t
|
||||
{
|
||||
hb_position_t x_bearing;
|
||||
hb_position_t y_bearing;
|
||||
hb_position_t width;
|
||||
hb_position_t height;
|
||||
} hb_glyph_extents_t;
|
||||
|
||||
|
||||
/* func types */
|
||||
|
||||
typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data);
|
||||
|
||||
|
||||
typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data);
|
||||
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
|
||||
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
|
||||
|
||||
typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y,
|
||||
void *user_data);
|
||||
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
|
||||
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
|
||||
|
||||
typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
|
||||
void *user_data);
|
||||
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
|
||||
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
|
||||
|
||||
|
||||
typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents,
|
||||
void *user_data);
|
||||
typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t glyph, unsigned int point_index,
|
||||
hb_position_t *x, hb_position_t *y,
|
||||
void *user_data);
|
||||
|
||||
|
||||
typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
char *name, unsigned int size,
|
||||
void *user_data);
|
||||
typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *font_data,
|
||||
const char *name, int len, /* -1 means nul-terminated */
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data);
|
||||
|
||||
|
||||
/* func setters */
|
||||
|
||||
void
|
||||
hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_func_t glyph_func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_h_advance_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
void
|
||||
hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_v_advance_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_h_origin_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
void
|
||||
hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_v_origin_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_h_kerning_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
void
|
||||
hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_v_kerning_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_extents_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
void
|
||||
hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_contour_point_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_name_func_t glyph_func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
void
|
||||
hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_from_name_func_t glyph_func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
|
||||
/* func dispatch */
|
||||
|
||||
hb_bool_t
|
||||
hb_font_get_glyph (hb_font_t *font,
|
||||
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
|
||||
hb_codepoint_t *glyph);
|
||||
|
||||
hb_position_t
|
||||
hb_font_get_glyph_h_advance (hb_font_t *font,
|
||||
hb_codepoint_t glyph);
|
||||
hb_position_t
|
||||
hb_font_get_glyph_v_advance (hb_font_t *font,
|
||||
hb_codepoint_t glyph);
|
||||
|
||||
hb_bool_t
|
||||
hb_font_get_glyph_h_origin (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
hb_bool_t
|
||||
hb_font_get_glyph_v_origin (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
|
||||
hb_position_t
|
||||
hb_font_get_glyph_h_kerning (hb_font_t *font,
|
||||
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
|
||||
hb_position_t
|
||||
hb_font_get_glyph_v_kerning (hb_font_t *font,
|
||||
hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
|
||||
|
||||
hb_bool_t
|
||||
hb_font_get_glyph_extents (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents);
|
||||
|
||||
hb_bool_t
|
||||
hb_font_get_glyph_contour_point (hb_font_t *font,
|
||||
hb_codepoint_t glyph, unsigned int point_index,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
|
||||
hb_bool_t
|
||||
hb_font_get_glyph_name (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
char *name, unsigned int size);
|
||||
hb_bool_t
|
||||
hb_font_get_glyph_from_name (hb_font_t *font,
|
||||
const char *name, int len, /* -1 means nul-terminated */
|
||||
hb_codepoint_t *glyph);
|
||||
|
||||
|
||||
/* high-level funcs, with fallback */
|
||||
|
||||
void
|
||||
hb_font_get_glyph_advance_for_direction (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
void
|
||||
hb_font_get_glyph_origin_for_direction (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
void
|
||||
hb_font_add_glyph_origin_for_direction (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
void
|
||||
hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
|
||||
void
|
||||
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
|
||||
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
|
||||
hb_bool_t
|
||||
hb_font_get_glyph_extents_for_origin (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_glyph_extents_t *extents);
|
||||
|
||||
hb_bool_t
|
||||
hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
|
||||
hb_codepoint_t glyph, unsigned int point_index,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
|
||||
/* Generates gidDDD if glyph has no name. */
|
||||
void
|
||||
hb_font_glyph_to_string (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
char *s, unsigned int size);
|
||||
/* Parses gidDDD and uniUUUU strings automatically. */
|
||||
hb_bool_t
|
||||
hb_font_glyph_from_string (hb_font_t *font,
|
||||
const char *s, int len, /* -1 means nul-terminated */
|
||||
hb_codepoint_t *glyph);
|
||||
|
||||
|
||||
/*
|
||||
* hb_font_t
|
||||
*/
|
||||
|
||||
/* Fonts are very light-weight objects */
|
||||
|
||||
hb_font_t *
|
||||
hb_font_create (hb_face_t *face);
|
||||
|
||||
hb_font_t *
|
||||
hb_font_create_sub_font (hb_font_t *parent);
|
||||
|
||||
hb_font_t *
|
||||
hb_font_get_empty (void);
|
||||
|
||||
hb_font_t *
|
||||
hb_font_reference (hb_font_t *font);
|
||||
|
||||
void
|
||||
hb_font_destroy (hb_font_t *font);
|
||||
|
||||
hb_bool_t
|
||||
hb_font_set_user_data (hb_font_t *font,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
|
||||
void *
|
||||
hb_font_get_user_data (hb_font_t *font,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
void
|
||||
hb_font_make_immutable (hb_font_t *font);
|
||||
|
||||
hb_bool_t
|
||||
hb_font_is_immutable (hb_font_t *font);
|
||||
|
||||
hb_font_t *
|
||||
hb_font_get_parent (hb_font_t *font);
|
||||
|
||||
hb_face_t *
|
||||
hb_font_get_face (hb_font_t *font);
|
||||
|
||||
|
||||
void
|
||||
hb_font_set_funcs (hb_font_t *font,
|
||||
hb_font_funcs_t *klass,
|
||||
void *font_data,
|
||||
hb_destroy_func_t destroy);
|
||||
|
||||
/* Be *very* careful with this function! */
|
||||
void
|
||||
hb_font_set_funcs_data (hb_font_t *font,
|
||||
void *font_data,
|
||||
hb_destroy_func_t destroy);
|
||||
|
||||
|
||||
void
|
||||
hb_font_set_scale (hb_font_t *font,
|
||||
int x_scale,
|
||||
int y_scale);
|
||||
|
||||
void
|
||||
hb_font_get_scale (hb_font_t *font,
|
||||
int *x_scale,
|
||||
int *y_scale);
|
||||
|
||||
/*
|
||||
* A zero value means "no hinting in that direction"
|
||||
*/
|
||||
void
|
||||
hb_font_set_ppem (hb_font_t *font,
|
||||
unsigned int x_ppem,
|
||||
unsigned int y_ppem);
|
||||
|
||||
void
|
||||
hb_font_get_ppem (hb_font_t *font,
|
||||
unsigned int *x_ppem,
|
||||
unsigned int *y_ppem);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_FONT_H */
|
130
src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh
vendored
Normal file
130
src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright © 2007 Chris Wilson
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_MUTEX_PRIVATE_HH
|
||||
#define HB_MUTEX_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
/* mutex */
|
||||
|
||||
/* We need external help for these */
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
typedef CRITICAL_SECTION hb_mutex_impl_t;
|
||||
#define HB_MUTEX_IMPL_INIT { NULL, 0, 0, NULL, NULL, 0 }
|
||||
#define hb_mutex_impl_init(M) InitializeCriticalSection (M)
|
||||
#define hb_mutex_impl_lock(M) EnterCriticalSection (M)
|
||||
#define hb_mutex_impl_unlock(M) LeaveCriticalSection (M)
|
||||
#define hb_mutex_impl_finish(M) DeleteCriticalSection (M)
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
|
||||
|
||||
#include <pthread.h>
|
||||
typedef pthread_mutex_t hb_mutex_impl_t;
|
||||
#define HB_MUTEX_IMPL_INIT PTHREAD_MUTEX_INITIALIZER
|
||||
#define hb_mutex_impl_init(M) pthread_mutex_init (M, NULL)
|
||||
#define hb_mutex_impl_lock(M) pthread_mutex_lock (M)
|
||||
#define hb_mutex_impl_unlock(M) pthread_mutex_unlock (M)
|
||||
#define hb_mutex_impl_finish(M) pthread_mutex_destroy (M)
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
|
||||
|
||||
#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
|
||||
# include <sched.h>
|
||||
# define HB_SCHED_YIELD() sched_yield ()
|
||||
#else
|
||||
# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
|
||||
#endif
|
||||
|
||||
/* This actually is not a totally awful implementation. */
|
||||
typedef volatile int hb_mutex_impl_t;
|
||||
#define HB_MUTEX_IMPL_INIT 0
|
||||
#define hb_mutex_impl_init(M) *(M) = 0
|
||||
#define hb_mutex_impl_lock(M) HB_STMT_START { while (__sync_lock_test_and_set((M), 1)) HB_SCHED_YIELD (); } HB_STMT_END
|
||||
#define hb_mutex_impl_unlock(M) __sync_lock_release (M)
|
||||
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT)
|
||||
|
||||
#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
|
||||
# include <sched.h>
|
||||
# define HB_SCHED_YIELD() sched_yield ()
|
||||
#else
|
||||
# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
|
||||
#endif
|
||||
|
||||
#define HB_MUTEX_INT_NIL 1 /* Warn that fallback implementation is in use. */
|
||||
typedef volatile int hb_mutex_impl_t;
|
||||
#define HB_MUTEX_IMPL_INIT 0
|
||||
#define hb_mutex_impl_init(M) *(M) = 0
|
||||
#define hb_mutex_impl_lock(M) HB_STMT_START { while (*(M)) HB_SCHED_YIELD (); (*(M))++; } HB_STMT_END
|
||||
#define hb_mutex_impl_unlock(M) (*(M))--;
|
||||
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
|
||||
|
||||
|
||||
#else /* HB_NO_MT */
|
||||
|
||||
typedef int hb_mutex_impl_t;
|
||||
#define HB_MUTEX_IMPL_INIT 0
|
||||
#define hb_mutex_impl_init(M) HB_STMT_START {} HB_STMT_END
|
||||
#define hb_mutex_impl_lock(M) HB_STMT_START {} HB_STMT_END
|
||||
#define hb_mutex_impl_unlock(M) HB_STMT_START {} HB_STMT_END
|
||||
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT}
|
||||
struct hb_mutex_t
|
||||
{
|
||||
/* TODO Add tracing. */
|
||||
|
||||
hb_mutex_impl_t m;
|
||||
|
||||
inline void init (void) { hb_mutex_impl_init (&m); }
|
||||
inline void lock (void) { hb_mutex_impl_lock (&m); }
|
||||
inline void unlock (void) { hb_mutex_impl_unlock (&m); }
|
||||
inline void finish (void) { hb_mutex_impl_finish (&m); }
|
||||
};
|
||||
|
||||
|
||||
#endif /* HB_MUTEX_PRIVATE_HH */
|
227
src/3rdparty/harfbuzz-ng/src/hb-object-private.hh
vendored
Normal file
227
src/3rdparty/harfbuzz-ng/src/hb-object-private.hh
vendored
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright © 2007 Chris Wilson
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OBJECT_PRIVATE_HH
|
||||
#define HB_OBJECT_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-atomic-private.hh"
|
||||
#include "hb-mutex-private.hh"
|
||||
|
||||
|
||||
/* Debug */
|
||||
|
||||
#ifndef HB_DEBUG_OBJECT
|
||||
#define HB_DEBUG_OBJECT (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
/* reference_count */
|
||||
|
||||
#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
|
||||
#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
|
||||
struct hb_reference_count_t
|
||||
{
|
||||
hb_atomic_int_t ref_count;
|
||||
|
||||
inline void init (int v) { ref_count = v; }
|
||||
inline int inc (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), 1); }
|
||||
inline int dec (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), -1); }
|
||||
inline void finish (void) { ref_count = HB_REFERENCE_COUNT_INVALID_VALUE; }
|
||||
|
||||
inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_INVALID_VALUE; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* user_data */
|
||||
|
||||
#define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT}
|
||||
struct hb_user_data_array_t
|
||||
{
|
||||
/* TODO Add tracing. */
|
||||
|
||||
struct hb_user_data_item_t {
|
||||
hb_user_data_key_t *key;
|
||||
void *data;
|
||||
hb_destroy_func_t destroy;
|
||||
|
||||
inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
|
||||
inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; }
|
||||
|
||||
void finish (void) { if (destroy) destroy (data); }
|
||||
};
|
||||
|
||||
hb_mutex_t lock;
|
||||
hb_lockable_set_t<hb_user_data_item_t, hb_mutex_t> items;
|
||||
|
||||
inline void init (void) { lock.init (); items.init (); }
|
||||
|
||||
HB_INTERNAL bool set (hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
HB_INTERNAL void *get (hb_user_data_key_t *key);
|
||||
|
||||
inline void finish (void) { items.finish (lock); lock.finish (); }
|
||||
};
|
||||
|
||||
|
||||
/* object_header */
|
||||
|
||||
struct hb_object_header_t
|
||||
{
|
||||
hb_reference_count_t ref_count;
|
||||
hb_user_data_array_t user_data;
|
||||
|
||||
#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_INIT}
|
||||
|
||||
static inline void *create (unsigned int size) {
|
||||
hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size);
|
||||
|
||||
if (likely (obj))
|
||||
obj->init ();
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
inline void init (void) {
|
||||
ref_count.init (1);
|
||||
user_data.init ();
|
||||
}
|
||||
|
||||
inline bool is_inert (void) const {
|
||||
return unlikely (ref_count.is_invalid ());
|
||||
}
|
||||
|
||||
inline void reference (void) {
|
||||
if (unlikely (!this || this->is_inert ()))
|
||||
return;
|
||||
ref_count.inc ();
|
||||
}
|
||||
|
||||
inline bool destroy (void) {
|
||||
if (unlikely (!this || this->is_inert ()))
|
||||
return false;
|
||||
if (ref_count.dec () != 1)
|
||||
return false;
|
||||
|
||||
ref_count.finish (); /* Do this before user_data */
|
||||
user_data.finish ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool set_user_data (hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy_func,
|
||||
hb_bool_t replace) {
|
||||
if (unlikely (!this || this->is_inert ()))
|
||||
return false;
|
||||
|
||||
return user_data.set (key, data, destroy_func, replace);
|
||||
}
|
||||
|
||||
inline void *get_user_data (hb_user_data_key_t *key) {
|
||||
if (unlikely (!this || this->is_inert ()))
|
||||
return NULL;
|
||||
|
||||
return user_data.get (key);
|
||||
}
|
||||
|
||||
inline void trace (const char *function) const {
|
||||
if (unlikely (!this)) return;
|
||||
/* TODO We cannot use DEBUG_MSG_FUNC here since that one currently only
|
||||
* prints the class name and throws away the template info. */
|
||||
DEBUG_MSG (OBJECT, (void *) this,
|
||||
"%s refcount=%d",
|
||||
function,
|
||||
this ? ref_count.ref_count : 0);
|
||||
}
|
||||
|
||||
private:
|
||||
ASSERT_POD ();
|
||||
};
|
||||
|
||||
|
||||
/* object */
|
||||
|
||||
template <typename Type>
|
||||
static inline void hb_object_trace (const Type *obj, const char *function)
|
||||
{
|
||||
obj->header.trace (function);
|
||||
}
|
||||
template <typename Type>
|
||||
static inline Type *hb_object_create (void)
|
||||
{
|
||||
Type *obj = (Type *) hb_object_header_t::create (sizeof (Type));
|
||||
hb_object_trace (obj, HB_FUNC);
|
||||
return obj;
|
||||
}
|
||||
template <typename Type>
|
||||
static inline bool hb_object_is_inert (const Type *obj)
|
||||
{
|
||||
return unlikely (obj->header.is_inert ());
|
||||
}
|
||||
template <typename Type>
|
||||
static inline Type *hb_object_reference (Type *obj)
|
||||
{
|
||||
hb_object_trace (obj, HB_FUNC);
|
||||
obj->header.reference ();
|
||||
return obj;
|
||||
}
|
||||
template <typename Type>
|
||||
static inline bool hb_object_destroy (Type *obj)
|
||||
{
|
||||
hb_object_trace (obj, HB_FUNC);
|
||||
return obj->header.destroy ();
|
||||
}
|
||||
template <typename Type>
|
||||
static inline bool hb_object_set_user_data (Type *obj,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
return obj->header.set_user_data (key, data, destroy, replace);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
static inline void *hb_object_get_user_data (Type *obj,
|
||||
hb_user_data_key_t *key)
|
||||
{
|
||||
return obj->header.get_user_data (key);
|
||||
}
|
||||
|
||||
|
||||
#endif /* HB_OBJECT_PRIVATE_HH */
|
261
src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh
vendored
Normal file
261
src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh
vendored
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OPEN_FILE_PRIVATE_HH
|
||||
#define HB_OPEN_FILE_PRIVATE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* The OpenType Font File
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Organization of an OpenType Font
|
||||
*/
|
||||
|
||||
struct OpenTypeFontFile;
|
||||
struct OffsetTable;
|
||||
struct TTCHeader;
|
||||
|
||||
|
||||
typedef struct TableRecord
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
|
||||
Tag tag; /* 4-byte identifier. */
|
||||
CheckSum checkSum; /* CheckSum for this table. */
|
||||
ULONG offset; /* Offset from beginning of TrueType font
|
||||
* file. */
|
||||
ULONG length; /* Length of this table. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (16);
|
||||
} OpenTypeTable;
|
||||
|
||||
typedef struct OffsetTable
|
||||
{
|
||||
friend struct OpenTypeFontFile;
|
||||
|
||||
inline unsigned int get_table_count (void) const
|
||||
{ return numTables; }
|
||||
inline const TableRecord& get_table (unsigned int i) const
|
||||
{
|
||||
if (unlikely (i >= numTables)) return Null(TableRecord);
|
||||
return tables[i];
|
||||
}
|
||||
inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
|
||||
{
|
||||
Tag t;
|
||||
t.set (tag);
|
||||
unsigned int count = numTables;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if (t == tables[i].tag)
|
||||
{
|
||||
if (table_index) *table_index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (table_index) *table_index = Index::NOT_FOUND_INDEX;
|
||||
return false;
|
||||
}
|
||||
inline const TableRecord& get_table_by_tag (hb_tag_t tag) const
|
||||
{
|
||||
unsigned int table_index;
|
||||
find_table_index (tag, &table_index);
|
||||
return get_table (table_index);
|
||||
}
|
||||
|
||||
public:
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables));
|
||||
}
|
||||
|
||||
protected:
|
||||
Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
|
||||
USHORT numTables; /* Number of tables. */
|
||||
USHORT searchRange; /* (Maximum power of 2 <= numTables) x 16 */
|
||||
USHORT entrySelector; /* Log2(maximum power of 2 <= numTables). */
|
||||
USHORT rangeShift; /* NumTables x 16-searchRange. */
|
||||
TableRecord tables[VAR]; /* TableRecord entries. numTables items */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (12, tables);
|
||||
} OpenTypeFontFace;
|
||||
|
||||
|
||||
/*
|
||||
* TrueType Collections
|
||||
*/
|
||||
|
||||
struct TTCHeaderVersion1
|
||||
{
|
||||
friend struct TTCHeader;
|
||||
|
||||
inline unsigned int get_face_count (void) const { return table.len; }
|
||||
inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (table.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
|
||||
FixedVersion version; /* Version of the TTC Header (1.0),
|
||||
* 0x00010000 */
|
||||
LongOffsetLongArrayOf<OffsetTable>
|
||||
table; /* Array of offsets to the OffsetTable for each font
|
||||
* from the beginning of the file */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (12, table);
|
||||
};
|
||||
|
||||
struct TTCHeader
|
||||
{
|
||||
friend struct OpenTypeFontFile;
|
||||
|
||||
private:
|
||||
|
||||
inline unsigned int get_face_count (void) const
|
||||
{
|
||||
switch (u.header.version.major) {
|
||||
case 2: /* version 2 is compatible with version 1 */
|
||||
case 1: return u.version1.get_face_count ();
|
||||
default:return 0;
|
||||
}
|
||||
}
|
||||
inline const OpenTypeFontFace& get_face (unsigned int i) const
|
||||
{
|
||||
switch (u.header.version.major) {
|
||||
case 2: /* version 2 is compatible with version 1 */
|
||||
case 1: return u.version1.get_face (i);
|
||||
default:return Null(OpenTypeFontFace);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false);
|
||||
switch (u.header.version.major) {
|
||||
case 2: /* version 2 is compatible with version 1 */
|
||||
case 1: return TRACE_RETURN (u.version1.sanitize (c));
|
||||
default:return TRACE_RETURN (true);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
struct {
|
||||
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
|
||||
FixedVersion version; /* Version of the TTC Header (1.0 or 2.0),
|
||||
* 0x00010000 or 0x00020000 */
|
||||
} header;
|
||||
TTCHeaderVersion1 version1;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* OpenType Font File
|
||||
*/
|
||||
|
||||
struct OpenTypeFontFile
|
||||
{
|
||||
static const hb_tag_t CFFTag = HB_TAG ('O','T','T','O'); /* OpenType with Postscript outlines */
|
||||
static const hb_tag_t TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ); /* OpenType with TrueType outlines */
|
||||
static const hb_tag_t TTCTag = HB_TAG ('t','t','c','f'); /* TrueType Collection */
|
||||
static const hb_tag_t TrueTag = HB_TAG ('t','r','u','e'); /* Obsolete Apple TrueType */
|
||||
static const hb_tag_t Typ1Tag = HB_TAG ('t','y','p','1'); /* Obsolete Apple Type1 font in SFNT container */
|
||||
|
||||
inline hb_tag_t get_tag (void) const { return u.tag; }
|
||||
|
||||
inline unsigned int get_face_count (void) const
|
||||
{
|
||||
switch (u.tag) {
|
||||
case CFFTag: /* All the non-collection tags */
|
||||
case TrueTag:
|
||||
case Typ1Tag:
|
||||
case TrueTypeTag: return 1;
|
||||
case TTCTag: return u.ttcHeader.get_face_count ();
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
inline const OpenTypeFontFace& get_face (unsigned int i) const
|
||||
{
|
||||
switch (u.tag) {
|
||||
/* Note: for non-collection SFNT data we ignore index. This is because
|
||||
* Apple dfont container is a container of SFNT's. So each SFNT is a
|
||||
* non-TTC, but the index is more than zero. */
|
||||
case CFFTag: /* All the non-collection tags */
|
||||
case TrueTag:
|
||||
case Typ1Tag:
|
||||
case TrueTypeTag: return u.fontFace;
|
||||
case TTCTag: return u.ttcHeader.get_face (i);
|
||||
default: return Null(OpenTypeFontFace);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false);
|
||||
switch (u.tag) {
|
||||
case CFFTag: /* All the non-collection tags */
|
||||
case TrueTag:
|
||||
case Typ1Tag:
|
||||
case TrueTypeTag: return TRACE_RETURN (u.fontFace.sanitize (c));
|
||||
case TTCTag: return TRACE_RETURN (u.ttcHeader.sanitize (c));
|
||||
default: return TRACE_RETURN (true);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
Tag tag; /* 4-byte identifier. */
|
||||
OpenTypeFontFace fontFace;
|
||||
TTCHeader ttcHeader;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (4, tag);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OPEN_FILE_PRIVATE_HH */
|
981
src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
vendored
Normal file
981
src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
vendored
Normal file
@ -0,0 +1,981 @@
|
||||
/*
|
||||
* Copyright © 2007,2008,2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OPEN_TYPE_PRIVATE_HH
|
||||
#define HB_OPEN_TYPE_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-blob.h"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Casts
|
||||
*/
|
||||
|
||||
/* Cast to struct T, reference to reference */
|
||||
template<typename Type, typename TObject>
|
||||
inline const Type& CastR(const TObject &X)
|
||||
{ return reinterpret_cast<const Type&> (X); }
|
||||
template<typename Type, typename TObject>
|
||||
inline Type& CastR(TObject &X)
|
||||
{ return reinterpret_cast<Type&> (X); }
|
||||
|
||||
/* Cast to struct T, pointer to pointer */
|
||||
template<typename Type, typename TObject>
|
||||
inline const Type* CastP(const TObject *X)
|
||||
{ return reinterpret_cast<const Type*> (X); }
|
||||
template<typename Type, typename TObject>
|
||||
inline Type* CastP(TObject *X)
|
||||
{ return reinterpret_cast<Type*> (X); }
|
||||
|
||||
/* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory
|
||||
* location pointed to by P plus Ofs bytes. */
|
||||
template<typename Type>
|
||||
inline const Type& StructAtOffset(const void *P, unsigned int offset)
|
||||
{ return * reinterpret_cast<const Type*> ((const char *) P + offset); }
|
||||
template<typename Type>
|
||||
inline Type& StructAtOffset(void *P, unsigned int offset)
|
||||
{ return * reinterpret_cast<Type*> ((char *) P + offset); }
|
||||
|
||||
/* StructAfter<T>(X) returns the struct T& that is placed after X.
|
||||
* Works with X of variable size also. X must implement get_size() */
|
||||
template<typename Type, typename TObject>
|
||||
inline const Type& StructAfter(const TObject &X)
|
||||
{ return StructAtOffset<Type>(&X, X.get_size()); }
|
||||
template<typename Type, typename TObject>
|
||||
inline Type& StructAfter(TObject &X)
|
||||
{ return StructAtOffset<Type>(&X, X.get_size()); }
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Size checking
|
||||
*/
|
||||
|
||||
/* Check _assertion in a method environment */
|
||||
#define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
|
||||
inline void _instance_assertion_on_line_##_line (void) const \
|
||||
{ \
|
||||
ASSERT_STATIC (_assertion); \
|
||||
ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \
|
||||
}
|
||||
# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
|
||||
# define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
|
||||
|
||||
/* Check that _code compiles in a method environment */
|
||||
#define _DEFINE_COMPILES_ASSERTION1(_line, _code) \
|
||||
inline void _compiles_assertion_on_line_##_line (void) const \
|
||||
{ _code; }
|
||||
# define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code)
|
||||
# define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code)
|
||||
|
||||
|
||||
#define DEFINE_SIZE_STATIC(size) \
|
||||
DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \
|
||||
static const unsigned int static_size = (size); \
|
||||
static const unsigned int min_size = (size)
|
||||
|
||||
/* Size signifying variable-sized array */
|
||||
#define VAR 1
|
||||
|
||||
#define DEFINE_SIZE_UNION(size, _member) \
|
||||
DEFINE_INSTANCE_ASSERTION (this->u._member.static_size == (size)); \
|
||||
static const unsigned int min_size = (size)
|
||||
|
||||
#define DEFINE_SIZE_MIN(size) \
|
||||
DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \
|
||||
static const unsigned int min_size = (size)
|
||||
|
||||
#define DEFINE_SIZE_ARRAY(size, array) \
|
||||
DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \
|
||||
DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
|
||||
static const unsigned int min_size = (size)
|
||||
|
||||
#define DEFINE_SIZE_ARRAY2(size, array1, array2) \
|
||||
DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
|
||||
DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
|
||||
static const unsigned int min_size = (size)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Null objects
|
||||
*/
|
||||
|
||||
/* Global nul-content Null pool. Enlarge as necessary. */
|
||||
/* TODO This really should be a extern HB_INTERNAL and defined somewhere... */
|
||||
static const void *_NullPool[64 / sizeof (void *)];
|
||||
|
||||
/* Generic nul-content Null objects. */
|
||||
template <typename Type>
|
||||
static inline const Type& Null (void) {
|
||||
ASSERT_STATIC (sizeof (Type) <= sizeof (_NullPool));
|
||||
return *CastP<Type> (_NullPool);
|
||||
}
|
||||
|
||||
/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */
|
||||
#define DEFINE_NULL_DATA(Type, data) \
|
||||
static const char _Null##Type[sizeof (Type) + 1] = data; /* +1 is for nul-termination in data */ \
|
||||
template <> \
|
||||
inline const Type& Null<Type> (void) { \
|
||||
return *CastP<Type> (_Null##Type); \
|
||||
} /* The following line really exists such that we end in a place needing semicolon */ \
|
||||
ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type))
|
||||
|
||||
/* Accessor macro. */
|
||||
#define Null(Type) Null<Type>()
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Sanitize
|
||||
*/
|
||||
|
||||
#ifndef HB_DEBUG_SANITIZE
|
||||
#define HB_DEBUG_SANITIZE (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
#define TRACE_SANITIZE(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"");
|
||||
|
||||
/* This limits sanitizing time on really broken fonts. */
|
||||
#ifndef HB_SANITIZE_MAX_EDITS
|
||||
#define HB_SANITIZE_MAX_EDITS 100
|
||||
#endif
|
||||
|
||||
struct hb_sanitize_context_t
|
||||
{
|
||||
inline const char *get_name (void) { return "SANITIZE"; }
|
||||
static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE;
|
||||
typedef bool return_t;
|
||||
template <typename T>
|
||||
inline return_t dispatch (const T &obj) { return obj.sanitize (this); }
|
||||
static return_t default_return_value (void) { return true; }
|
||||
bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return false; }
|
||||
|
||||
inline void init (hb_blob_t *b)
|
||||
{
|
||||
this->blob = hb_blob_reference (b);
|
||||
this->writable = false;
|
||||
}
|
||||
|
||||
inline void start_processing (void)
|
||||
{
|
||||
this->start = hb_blob_get_data (this->blob, NULL);
|
||||
this->end = this->start + hb_blob_get_length (this->blob);
|
||||
this->edit_count = 0;
|
||||
this->debug_depth = 0;
|
||||
|
||||
DEBUG_MSG_LEVEL (SANITIZE, this->blob, 0, +1,
|
||||
"start [%p..%p] (%lu bytes)",
|
||||
this->start, this->end,
|
||||
(unsigned long) (this->end - this->start));
|
||||
}
|
||||
|
||||
inline void end_processing (void)
|
||||
{
|
||||
DEBUG_MSG_LEVEL (SANITIZE, this->blob, 0, -1,
|
||||
"end [%p..%p] %u edit requests",
|
||||
this->start, this->end, this->edit_count);
|
||||
|
||||
hb_blob_destroy (this->blob);
|
||||
this->blob = NULL;
|
||||
this->start = this->end = NULL;
|
||||
}
|
||||
|
||||
inline bool check_range (const void *base, unsigned int len) const
|
||||
{
|
||||
const char *p = (const char *) base;
|
||||
|
||||
hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace
|
||||
(&this->debug_depth, "SANITIZE", this->blob, NULL,
|
||||
"check_range [%p..%p] (%d bytes) in [%p..%p]",
|
||||
p, p + len, len,
|
||||
this->start, this->end);
|
||||
|
||||
return TRACE_RETURN (likely (this->start <= p && p <= this->end && (unsigned int) (this->end - p) >= len));
|
||||
}
|
||||
|
||||
inline bool check_array (const void *base, unsigned int record_size, unsigned int len) const
|
||||
{
|
||||
const char *p = (const char *) base;
|
||||
bool overflows = _hb_unsigned_int_mul_overflows (len, record_size);
|
||||
|
||||
hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace
|
||||
(&this->debug_depth, "SANITIZE", this->blob, NULL,
|
||||
"check_array [%p..%p] (%d*%d=%ld bytes) in [%p..%p]",
|
||||
p, p + (record_size * len), record_size, len, (unsigned long) record_size * len,
|
||||
this->start, this->end);
|
||||
|
||||
return TRACE_RETURN (likely (!overflows && this->check_range (base, record_size * len)));
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline bool check_struct (const Type *obj) const
|
||||
{
|
||||
return likely (this->check_range (obj, obj->min_size));
|
||||
}
|
||||
|
||||
inline bool may_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED)
|
||||
{
|
||||
if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
|
||||
return false;
|
||||
|
||||
const char *p = (const char *) base;
|
||||
this->edit_count++;
|
||||
|
||||
hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace
|
||||
(&this->debug_depth, "SANITIZE", this->blob, NULL,
|
||||
"may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
|
||||
this->edit_count,
|
||||
p, p + len, len,
|
||||
this->start, this->end,
|
||||
this->writable ? "GRANTED" : "DENIED");
|
||||
|
||||
return TRACE_RETURN (this->writable);
|
||||
}
|
||||
|
||||
mutable unsigned int debug_depth;
|
||||
const char *start, *end;
|
||||
bool writable;
|
||||
unsigned int edit_count;
|
||||
hb_blob_t *blob;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Template to sanitize an object. */
|
||||
template <typename Type>
|
||||
struct Sanitizer
|
||||
{
|
||||
static hb_blob_t *sanitize (hb_blob_t *blob) {
|
||||
hb_sanitize_context_t c[1] = {{0}};
|
||||
bool sane;
|
||||
|
||||
/* TODO is_sane() stuff */
|
||||
|
||||
c->init (blob);
|
||||
|
||||
retry:
|
||||
DEBUG_MSG_FUNC (SANITIZE, blob, "start");
|
||||
|
||||
c->start_processing ();
|
||||
|
||||
if (unlikely (!c->start)) {
|
||||
c->end_processing ();
|
||||
return blob;
|
||||
}
|
||||
|
||||
Type *t = CastP<Type> (const_cast<char *> (c->start));
|
||||
|
||||
sane = t->sanitize (c);
|
||||
if (sane) {
|
||||
if (c->edit_count) {
|
||||
DEBUG_MSG_FUNC (SANITIZE, blob, "passed first round with %d edits; going for second round", c->edit_count);
|
||||
|
||||
/* sanitize again to ensure no toe-stepping */
|
||||
c->edit_count = 0;
|
||||
sane = t->sanitize (c);
|
||||
if (c->edit_count) {
|
||||
DEBUG_MSG_FUNC (SANITIZE, blob, "requested %d edits in second round; FAILLING", c->edit_count);
|
||||
sane = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned int edit_count = c->edit_count;
|
||||
if (edit_count && !c->writable) {
|
||||
c->start = hb_blob_get_data_writable (blob, NULL);
|
||||
c->end = c->start + hb_blob_get_length (blob);
|
||||
|
||||
if (c->start) {
|
||||
c->writable = true;
|
||||
/* ok, we made it writable by relocating. try again */
|
||||
DEBUG_MSG_FUNC (SANITIZE, blob, "retry");
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c->end_processing ();
|
||||
|
||||
DEBUG_MSG_FUNC (SANITIZE, blob, sane ? "PASSED" : "FAILED");
|
||||
if (sane)
|
||||
return blob;
|
||||
else {
|
||||
hb_blob_destroy (blob);
|
||||
return hb_blob_get_empty ();
|
||||
}
|
||||
}
|
||||
|
||||
static const Type* lock_instance (hb_blob_t *blob) {
|
||||
hb_blob_make_immutable (blob);
|
||||
const char *base = hb_blob_get_data (blob, NULL);
|
||||
return unlikely (!base) ? &Null(Type) : CastP<Type> (base);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Serialize
|
||||
*/
|
||||
|
||||
#ifndef HB_DEBUG_SERIALIZE
|
||||
#define HB_DEBUG_SERIALIZE (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
#define TRACE_SERIALIZE(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \
|
||||
(&c->debug_depth, "SERIALIZE", c, HB_FUNC, \
|
||||
"");
|
||||
|
||||
|
||||
struct hb_serialize_context_t
|
||||
{
|
||||
inline hb_serialize_context_t (void *start, unsigned int size)
|
||||
{
|
||||
this->start = (char *) start;
|
||||
this->end = this->start + size;
|
||||
|
||||
this->ran_out_of_room = false;
|
||||
this->head = this->start;
|
||||
this->debug_depth = 0;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline Type *start_serialize (void)
|
||||
{
|
||||
DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
|
||||
"start [%p..%p] (%lu bytes)",
|
||||
this->start, this->end,
|
||||
(unsigned long) (this->end - this->start));
|
||||
|
||||
return start_embed<Type> ();
|
||||
}
|
||||
|
||||
inline void end_serialize (void)
|
||||
{
|
||||
DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
|
||||
"end [%p..%p] serialized %d bytes; %s",
|
||||
this->start, this->end,
|
||||
(int) (this->head - this->start),
|
||||
this->ran_out_of_room ? "RAN OUT OF ROOM" : "did not ran out of room");
|
||||
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline Type *copy (void)
|
||||
{
|
||||
assert (!this->ran_out_of_room);
|
||||
unsigned int len = this->head - this->start;
|
||||
void *p = malloc (len);
|
||||
if (p)
|
||||
memcpy (p, this->start, len);
|
||||
return reinterpret_cast<Type *> (p);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline Type *allocate_size (unsigned int size)
|
||||
{
|
||||
if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) {
|
||||
this->ran_out_of_room = true;
|
||||
return NULL;
|
||||
}
|
||||
memset (this->head, 0, size);
|
||||
char *ret = this->head;
|
||||
this->head += size;
|
||||
return reinterpret_cast<Type *> (ret);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline Type *allocate_min (void)
|
||||
{
|
||||
return this->allocate_size<Type> (Type::min_size);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline Type *start_embed (void)
|
||||
{
|
||||
Type *ret = reinterpret_cast<Type *> (this->head);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline Type *embed (const Type &obj)
|
||||
{
|
||||
unsigned int size = obj.get_size ();
|
||||
Type *ret = this->allocate_size<Type> (size);
|
||||
if (unlikely (!ret)) return NULL;
|
||||
memcpy (ret, obj, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline Type *extend_min (Type &obj)
|
||||
{
|
||||
unsigned int size = obj.min_size;
|
||||
assert (this->start <= (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
|
||||
if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return NULL;
|
||||
return reinterpret_cast<Type *> (&obj);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline Type *extend (Type &obj)
|
||||
{
|
||||
unsigned int size = obj.get_size ();
|
||||
assert (this->start < (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
|
||||
if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return NULL;
|
||||
return reinterpret_cast<Type *> (&obj);
|
||||
}
|
||||
|
||||
inline void truncate (void *head)
|
||||
{
|
||||
assert (this->start < head && head <= this->head);
|
||||
this->head = (char *) head;
|
||||
}
|
||||
|
||||
unsigned int debug_depth;
|
||||
char *start, *end, *head;
|
||||
bool ran_out_of_room;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct Supplier
|
||||
{
|
||||
inline Supplier (const Type *array, unsigned int len_)
|
||||
{
|
||||
head = array;
|
||||
len = len_;
|
||||
}
|
||||
inline const Type operator [] (unsigned int i) const
|
||||
{
|
||||
if (unlikely (i >= len)) return Type ();
|
||||
return head[i];
|
||||
}
|
||||
|
||||
inline void advance (unsigned int count)
|
||||
{
|
||||
if (unlikely (count > len))
|
||||
count = len;
|
||||
len -= count;
|
||||
head += count;
|
||||
}
|
||||
|
||||
private:
|
||||
inline Supplier (const Supplier<Type> &); /* Disallow copy */
|
||||
inline Supplier<Type>& operator= (const Supplier<Type> &); /* Disallow copy */
|
||||
|
||||
unsigned int len;
|
||||
const Type *head;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* The OpenType Font File: Data Types
|
||||
*/
|
||||
|
||||
|
||||
/* "The following data types are used in the OpenType font file.
|
||||
* All OpenType fonts use Motorola-style byte ordering (Big Endian):" */
|
||||
|
||||
/*
|
||||
* Int types
|
||||
*/
|
||||
|
||||
|
||||
template <typename Type, int Bytes> struct BEInt;
|
||||
|
||||
template <typename Type>
|
||||
struct BEInt<Type, 2>
|
||||
{
|
||||
public:
|
||||
inline void set (Type i) { hb_be_uint16_put (v,i); }
|
||||
inline operator Type (void) const { return hb_be_uint16_get (v); }
|
||||
inline bool operator == (const BEInt<Type, 2>& o) const { return hb_be_uint16_eq (v, o.v); }
|
||||
inline bool operator != (const BEInt<Type, 2>& o) const { return !(*this == o); }
|
||||
private: uint8_t v[2];
|
||||
};
|
||||
template <typename Type>
|
||||
struct BEInt<Type, 4>
|
||||
{
|
||||
public:
|
||||
inline void set (Type i) { hb_be_uint32_put (v,i); }
|
||||
inline operator Type (void) const { return hb_be_uint32_get (v); }
|
||||
inline bool operator == (const BEInt<Type, 4>& o) const { return hb_be_uint32_eq (v, o.v); }
|
||||
inline bool operator != (const BEInt<Type, 4>& o) const { return !(*this == o); }
|
||||
private: uint8_t v[4];
|
||||
};
|
||||
template <typename Type>
|
||||
struct BEInt<Type, 3>
|
||||
{
|
||||
public:
|
||||
inline void set (Type i) { hb_be_uint24_put (v,i); }
|
||||
inline operator Type (void) const { return hb_be_uint24_get (v); }
|
||||
inline bool operator == (const BEInt<Type, 3>& o) const { return hb_be_uint24_eq (v, o.v); }
|
||||
inline bool operator != (const BEInt<Type, 3>& o) const { return !(*this == o); }
|
||||
private: uint8_t v[3];
|
||||
};
|
||||
|
||||
/* Integer types in big-endian order and no alignment requirement */
|
||||
template <typename Type, unsigned int Size>
|
||||
struct IntType
|
||||
{
|
||||
inline void set (Type i) { v.set (i); }
|
||||
inline operator Type(void) const { return v; }
|
||||
inline bool operator == (const IntType<Type,Size> &o) const { return v == o.v; }
|
||||
inline bool operator != (const IntType<Type,Size> &o) const { return v != o.v; }
|
||||
static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
|
||||
inline int cmp (IntType<Type,Size> va) const { Type a = va; Type b = v; return a < b ? -1 : a == b ? 0 : +1; }
|
||||
inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : +1; }
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (likely (c->check_struct (this)));
|
||||
}
|
||||
protected:
|
||||
BEInt<Type, Size> v;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (Size);
|
||||
};
|
||||
|
||||
typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */
|
||||
typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */
|
||||
typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */
|
||||
typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */
|
||||
typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */
|
||||
|
||||
/* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */
|
||||
typedef SHORT FWORD;
|
||||
|
||||
/* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */
|
||||
typedef USHORT UFWORD;
|
||||
|
||||
/* Date represented in number of seconds since 12:00 midnight, January 1,
|
||||
* 1904. The value is represented as a signed 64-bit integer. */
|
||||
struct LONGDATETIME
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (likely (c->check_struct (this)));
|
||||
}
|
||||
private:
|
||||
LONG major;
|
||||
ULONG minor;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
};
|
||||
|
||||
/* Array of four uint8s (length = 32 bits) used to identify a script, language
|
||||
* system, feature, or baseline */
|
||||
struct Tag : ULONG
|
||||
{
|
||||
/* What the char* converters return is NOT nul-terminated. Print using "%.4s" */
|
||||
inline operator const char* (void) const { return reinterpret_cast<const char *> (&this->v); }
|
||||
inline operator char* (void) { return reinterpret_cast<char *> (&this->v); }
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
DEFINE_NULL_DATA (Tag, " ");
|
||||
|
||||
/* Glyph index number, same as uint16 (length = 16 bits) */
|
||||
typedef USHORT GlyphID;
|
||||
|
||||
/* Script/language-system/feature index */
|
||||
struct Index : USHORT {
|
||||
static const unsigned int NOT_FOUND_INDEX = 0xFFFF;
|
||||
};
|
||||
DEFINE_NULL_DATA (Index, "\xff\xff");
|
||||
|
||||
/* Offset to a table, same as uint16 (length = 16 bits), Null offset = 0x0000 */
|
||||
struct Offset : USHORT
|
||||
{
|
||||
inline bool is_null (void) const { return 0 == *this; }
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (2);
|
||||
};
|
||||
|
||||
/* LongOffset to a table, same as uint32 (length = 32 bits), Null offset = 0x00000000 */
|
||||
struct LongOffset : ULONG
|
||||
{
|
||||
inline bool is_null (void) const { return 0 == *this; }
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
|
||||
/* CheckSum */
|
||||
struct CheckSum : ULONG
|
||||
{
|
||||
/* This is reference implementation from the spec. */
|
||||
static inline uint32_t CalcTableChecksum (const ULONG *Table, uint32_t Length)
|
||||
{
|
||||
uint32_t Sum = 0L;
|
||||
const ULONG *EndPtr = Table+((Length+3) & ~3) / ULONG::static_size;
|
||||
|
||||
while (Table < EndPtr)
|
||||
Sum += *Table++;
|
||||
return Sum;
|
||||
}
|
||||
|
||||
/* Note: data should be 4byte aligned and have 4byte padding at the end. */
|
||||
inline void set_for_data (const void *data, unsigned int length)
|
||||
{ set (CalcTableChecksum ((const ULONG *) data, length)); }
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Version Numbers
|
||||
*/
|
||||
|
||||
struct FixedVersion
|
||||
{
|
||||
inline uint32_t to_int (void) const { return (major << 16) + minor; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
|
||||
USHORT major;
|
||||
USHORT minor;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Template subclasses of Offset and LongOffset that do the dereferencing.
|
||||
* Use: (base+offset)
|
||||
*/
|
||||
|
||||
template <typename OffsetType, typename Type>
|
||||
struct GenericOffsetTo : OffsetType
|
||||
{
|
||||
inline const Type& operator () (const void *base) const
|
||||
{
|
||||
unsigned int offset = *this;
|
||||
if (unlikely (!offset)) return Null(Type);
|
||||
return StructAtOffset<Type> (base, offset);
|
||||
}
|
||||
|
||||
inline Type& serialize (hb_serialize_context_t *c, void *base)
|
||||
{
|
||||
Type *t = c->start_embed<Type> ();
|
||||
this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
|
||||
return *t;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
|
||||
unsigned int offset = *this;
|
||||
if (unlikely (!offset)) return TRACE_RETURN (true);
|
||||
Type &obj = StructAtOffset<Type> (base, offset);
|
||||
return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c));
|
||||
}
|
||||
template <typename T>
|
||||
inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) {
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
|
||||
unsigned int offset = *this;
|
||||
if (unlikely (!offset)) return TRACE_RETURN (true);
|
||||
Type &obj = StructAtOffset<Type> (base, offset);
|
||||
return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c));
|
||||
}
|
||||
|
||||
inline bool try_set (hb_sanitize_context_t *c, const OffsetType &v) {
|
||||
if (c->may_edit (this, this->static_size)) {
|
||||
this->set (v);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/* Set the offset to Null */
|
||||
inline bool neuter (hb_sanitize_context_t *c) {
|
||||
if (c->may_edit (this, this->static_size)) {
|
||||
this->set (0); /* 0 is Null offset */
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
template <typename Base, typename OffsetType, typename Type>
|
||||
inline const Type& operator + (const Base &base, const GenericOffsetTo<OffsetType, Type> &offset) { return offset (base); }
|
||||
template <typename Base, typename OffsetType, typename Type>
|
||||
inline Type& operator + (Base &base, GenericOffsetTo<OffsetType, Type> &offset) { return offset (base); }
|
||||
|
||||
template <typename Type>
|
||||
struct OffsetTo : GenericOffsetTo<Offset, Type> {};
|
||||
|
||||
template <typename Type>
|
||||
struct LongOffsetTo : GenericOffsetTo<LongOffset, Type> {};
|
||||
|
||||
|
||||
/*
|
||||
* Array Types
|
||||
*/
|
||||
|
||||
template <typename LenType, typename Type>
|
||||
struct GenericArrayOf
|
||||
{
|
||||
const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
|
||||
{
|
||||
unsigned int count = len;
|
||||
if (unlikely (start_offset > count))
|
||||
count = 0;
|
||||
else
|
||||
count -= start_offset;
|
||||
count = MIN (count, *pcount);
|
||||
*pcount = count;
|
||||
return array + start_offset;
|
||||
}
|
||||
|
||||
inline const Type& operator [] (unsigned int i) const
|
||||
{
|
||||
if (unlikely (i >= len)) return Null(Type);
|
||||
return array[i];
|
||||
}
|
||||
inline Type& operator [] (unsigned int i)
|
||||
{
|
||||
return array[i];
|
||||
}
|
||||
inline unsigned int get_size (void) const
|
||||
{ return len.static_size + len * Type::static_size; }
|
||||
|
||||
inline bool serialize (hb_serialize_context_t *c,
|
||||
unsigned int items_len)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
|
||||
len.set (items_len); /* TODO(serialize) Overflow? */
|
||||
if (unlikely (!c->extend (*this))) return TRACE_RETURN (false);
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool serialize (hb_serialize_context_t *c,
|
||||
Supplier<Type> &items,
|
||||
unsigned int items_len)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
if (unlikely (!serialize (c, items_len))) return TRACE_RETURN (false);
|
||||
for (unsigned int i = 0; i < items_len; i++)
|
||||
array[i] = items[i];
|
||||
items.advance (items_len);
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
||||
|
||||
/* Note: for structs that do not reference other structs,
|
||||
* we do not need to call their sanitize() as we already did
|
||||
* a bound check on the aggregate array size. We just include
|
||||
* a small unreachable expression to make sure the structs
|
||||
* pointed to do have a simple sanitize(), ie. they do not
|
||||
* reference other structs via offsets.
|
||||
*/
|
||||
(void) (false && array[0].sanitize (c));
|
||||
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
||||
unsigned int count = len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (unlikely (!array[i].sanitize (c, base)))
|
||||
return TRACE_RETURN (false);
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
template <typename T>
|
||||
inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) {
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
||||
unsigned int count = len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (unlikely (!array[i].sanitize (c, base, user_data)))
|
||||
return TRACE_RETURN (false);
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
private:
|
||||
inline bool sanitize_shallow (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::static_size, len));
|
||||
}
|
||||
|
||||
public:
|
||||
LenType len;
|
||||
Type array[VAR];
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (sizeof (LenType), array);
|
||||
};
|
||||
|
||||
/* An array with a USHORT number of elements. */
|
||||
template <typename Type>
|
||||
struct ArrayOf : GenericArrayOf<USHORT, Type> {};
|
||||
|
||||
/* An array with a ULONG number of elements. */
|
||||
template <typename Type>
|
||||
struct LongArrayOf : GenericArrayOf<ULONG, Type> {};
|
||||
|
||||
/* Array of Offset's */
|
||||
template <typename Type>
|
||||
struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {};
|
||||
|
||||
/* Array of LongOffset's */
|
||||
template <typename Type>
|
||||
struct LongOffsetArrayOf : ArrayOf<LongOffsetTo<Type> > {};
|
||||
|
||||
/* LongArray of LongOffset's */
|
||||
template <typename Type>
|
||||
struct LongOffsetLongArrayOf : LongArrayOf<LongOffsetTo<Type> > {};
|
||||
|
||||
/* Array of offsets relative to the beginning of the array itself. */
|
||||
template <typename Type>
|
||||
struct OffsetListOf : OffsetArrayOf<Type>
|
||||
{
|
||||
inline const Type& operator [] (unsigned int i) const
|
||||
{
|
||||
if (unlikely (i >= this->len)) return Null(Type);
|
||||
return this+this->array[i];
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this));
|
||||
}
|
||||
template <typename T>
|
||||
inline bool sanitize (hb_sanitize_context_t *c, T user_data) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* An array with a USHORT number of elements,
|
||||
* starting at second element. */
|
||||
template <typename Type>
|
||||
struct HeadlessArrayOf
|
||||
{
|
||||
inline const Type& operator [] (unsigned int i) const
|
||||
{
|
||||
if (unlikely (i >= len || !i)) return Null(Type);
|
||||
return array[i-1];
|
||||
}
|
||||
inline unsigned int get_size (void) const
|
||||
{ return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
|
||||
|
||||
inline bool serialize (hb_serialize_context_t *c,
|
||||
Supplier<Type> &items,
|
||||
unsigned int items_len)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
|
||||
len.set (items_len); /* TODO(serialize) Overflow? */
|
||||
if (unlikely (!items_len)) return TRACE_RETURN (true);
|
||||
if (unlikely (!c->extend (*this))) return TRACE_RETURN (false);
|
||||
for (unsigned int i = 0; i < items_len - 1; i++)
|
||||
array[i] = items[i];
|
||||
items.advance (items_len - 1);
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize_shallow (hb_sanitize_context_t *c) {
|
||||
return c->check_struct (this)
|
||||
&& c->check_array (this, Type::static_size, len);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
||||
|
||||
/* Note: for structs that do not reference other structs,
|
||||
* we do not need to call their sanitize() as we already did
|
||||
* a bound check on the aggregate array size. We just include
|
||||
* a small unreachable expression to make sure the structs
|
||||
* pointed to do have a simple sanitize(), ie. they do not
|
||||
* reference other structs via offsets.
|
||||
*/
|
||||
(void) (false && array[0].sanitize (c));
|
||||
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
USHORT len;
|
||||
Type array[VAR];
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (sizeof (USHORT), array);
|
||||
};
|
||||
|
||||
|
||||
/* An array with sorted elements. Supports binary searching. */
|
||||
template <typename Type>
|
||||
struct SortedArrayOf : ArrayOf<Type> {
|
||||
|
||||
template <typename SearchType>
|
||||
inline int search (const SearchType &x) const
|
||||
{
|
||||
/* Hand-coded bsearch here since this is in the hot inner loop. */
|
||||
int min = 0, max = (int) this->len - 1;
|
||||
while (min <= max)
|
||||
{
|
||||
int mid = (min + max) / 2;
|
||||
int c = this->array[mid].cmp (x);
|
||||
if (c < 0)
|
||||
max = mid - 1;
|
||||
else if (c > 0)
|
||||
min = mid + 1;
|
||||
else
|
||||
return mid;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OPEN_TYPE_PRIVATE_HH */
|
149
src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
vendored
Normal file
149
src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright © 2010 Red Hat, Inc.
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_HEAD_TABLE_HH
|
||||
#define HB_OT_HEAD_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* head -- Font Header
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_head HB_TAG('h','e','a','d')
|
||||
|
||||
struct head
|
||||
{
|
||||
static const hb_tag_t Tag = HB_OT_TAG_head;
|
||||
|
||||
inline unsigned int get_upem (void) const {
|
||||
unsigned int upem = unitsPerEm;
|
||||
/* If no valid head table found, assume 1000, which matches typical Type1 usage. */
|
||||
return 16 <= upem && upem <= 16384 ? upem : 1000;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion version; /* Version of the head table--currently
|
||||
* 0x00010000 for version 1.0. */
|
||||
FixedVersion fontRevision; /* Set by font manufacturer. */
|
||||
ULONG checkSumAdjustment; /* To compute: set it to 0, sum the
|
||||
* entire font as ULONG, then store
|
||||
* 0xB1B0AFBA - sum. */
|
||||
ULONG magicNumber; /* Set to 0x5F0F3CF5. */
|
||||
USHORT flags; /* Bit 0: Baseline for font at y=0;
|
||||
* Bit 1: Left sidebearing point at x=0;
|
||||
* Bit 2: Instructions may depend on point size;
|
||||
* Bit 3: Force ppem to integer values for all
|
||||
* internal scaler math; may use fractional
|
||||
* ppem sizes if this bit is clear;
|
||||
* Bit 4: Instructions may alter advance width
|
||||
* (the advance widths might not scale linearly);
|
||||
|
||||
* Bits 5-10: These should be set according to
|
||||
* Apple's specification. However, they are not
|
||||
* implemented in OpenType.
|
||||
* Bit 5: This bit should be set in fonts that are
|
||||
* intended to e laid out vertically, and in
|
||||
* which the glyphs have been drawn such that an
|
||||
* x-coordinate of 0 corresponds to the desired
|
||||
* vertical baseline.
|
||||
* Bit 6: This bit must be set to zero.
|
||||
* Bit 7: This bit should be set if the font
|
||||
* requires layout for correct linguistic
|
||||
* rendering (e.g. Arabic fonts).
|
||||
* Bit 8: This bit should be set for a GX font
|
||||
* which has one or more metamorphosis effects
|
||||
* designated as happening by default.
|
||||
* Bit 9: This bit should be set if the font
|
||||
* contains any strong right-to-left glyphs.
|
||||
* Bit 10: This bit should be set if the font
|
||||
* contains Indic-style rearrangement effects.
|
||||
|
||||
* Bit 11: Font data is 'lossless,' as a result
|
||||
* of having been compressed and decompressed
|
||||
* with the Agfa MicroType Express engine.
|
||||
* Bit 12: Font converted (produce compatible metrics)
|
||||
* Bit 13: Font optimized for ClearType™.
|
||||
* Note, fonts that rely on embedded bitmaps (EBDT)
|
||||
* for rendering should not be considered optimized
|
||||
* for ClearType, and therefore should keep this bit
|
||||
* cleared.
|
||||
* Bit 14: Last Resort font. If set, indicates that
|
||||
* the glyphs encoded in the cmap subtables are simply
|
||||
* generic symbolic representations of code point
|
||||
* ranges and don’t truly represent support for those
|
||||
* code points. If unset, indicates that the glyphs
|
||||
* encoded in the cmap subtables represent proper
|
||||
* support for those code points.
|
||||
* Bit 15: Reserved, set to 0. */
|
||||
USHORT unitsPerEm; /* Valid range is from 16 to 16384. This value
|
||||
* should be a power of 2 for fonts that have
|
||||
* TrueType outlines. */
|
||||
LONGDATETIME created; /* Number of seconds since 12:00 midnight,
|
||||
January 1, 1904. 64-bit integer */
|
||||
LONGDATETIME modified; /* Number of seconds since 12:00 midnight,
|
||||
January 1, 1904. 64-bit integer */
|
||||
SHORT xMin; /* For all glyph bounding boxes. */
|
||||
SHORT yMin; /* For all glyph bounding boxes. */
|
||||
SHORT xMax; /* For all glyph bounding boxes. */
|
||||
SHORT yMax; /* For all glyph bounding boxes. */
|
||||
USHORT macStyle; /* Bit 0: Bold (if set to 1);
|
||||
* Bit 1: Italic (if set to 1)
|
||||
* Bit 2: Underline (if set to 1)
|
||||
* Bit 3: Outline (if set to 1)
|
||||
* Bit 4: Shadow (if set to 1)
|
||||
* Bit 5: Condensed (if set to 1)
|
||||
* Bit 6: Extended (if set to 1)
|
||||
* Bits 7-15: Reserved (set to 0). */
|
||||
USHORT lowestRecPPEM; /* Smallest readable size in pixels. */
|
||||
SHORT fontDirectionHint; /* Deprecated (Set to 2).
|
||||
* 0: Fully mixed directional glyphs;
|
||||
* 1: Only strongly left to right;
|
||||
* 2: Like 1 but also contains neutrals;
|
||||
* -1: Only strongly right to left;
|
||||
* -2: Like -1 but also contains neutrals. */
|
||||
SHORT indexToLocFormat; /* 0 for short offsets, 1 for long. */
|
||||
SHORT glyphDataFormat; /* 0 for current format. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (54);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_HEAD_TABLE_HH */
|
97
src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
vendored
Normal file
97
src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_HHEA_TABLE_HH
|
||||
#define HB_OT_HHEA_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* hhea -- The Horizontal Header Table
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_hhea HB_TAG('h','h','e','a')
|
||||
|
||||
|
||||
struct hhea
|
||||
{
|
||||
static const hb_tag_t Tag = HB_OT_TAG_hhea;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion version; /* 0x00010000 for version 1.0. */
|
||||
FWORD ascender; /* Typographic ascent. <a
|
||||
* href="http://developer.apple.com/fonts/TTRefMan/RM06/Chap6hhea.html">
|
||||
* (Distance from baseline of highest
|
||||
* ascender)</a> */
|
||||
FWORD descender; /* Typographic descent. <a
|
||||
* href="http://developer.apple.com/fonts/TTRefMan/RM06/Chap6hhea.html">
|
||||
* (Distance from baseline of lowest
|
||||
* descender)</a> */
|
||||
FWORD lineGap; /* Typographic line gap. Negative
|
||||
* LineGap values are treated as zero
|
||||
* in Windows 3.1, System 6, and
|
||||
* System 7. */
|
||||
UFWORD advanceWidthMax; /* Maximum advance width value in
|
||||
* 'hmtx' table. */
|
||||
FWORD minLeftSideBearing; /* Minimum left sidebearing value in
|
||||
* 'hmtx' table. */
|
||||
FWORD minRightSideBearing; /* Minimum right sidebearing value;
|
||||
* calculated as Min(aw - lsb -
|
||||
* (xMax - xMin)). */
|
||||
FWORD xMaxExtent; /* Max(lsb + (xMax - xMin)). */
|
||||
SHORT caretSlopeRise; /* Used to calculate the slope of the
|
||||
* cursor (rise/run); 1 for vertical. */
|
||||
SHORT caretSlopeRun; /* 0 for vertical. */
|
||||
SHORT caretOffset; /* The amount by which a slanted
|
||||
* highlight on a glyph needs
|
||||
* to be shifted to produce the
|
||||
* best appearance. Set to 0 for
|
||||
* non--slanted fonts */
|
||||
SHORT reserved1; /* set to 0 */
|
||||
SHORT reserved2; /* set to 0 */
|
||||
SHORT reserved3; /* set to 0 */
|
||||
SHORT reserved4; /* set to 0 */
|
||||
SHORT metricDataFormat; /* 0 for current format. */
|
||||
USHORT numberOfHMetrics; /* Number of hMetric entries in 'hmtx'
|
||||
* table */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (36);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_HHEA_TABLE_HH */
|
92
src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
vendored
Normal file
92
src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_HMTX_TABLE_HH
|
||||
#define HB_OT_HMTX_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* hmtx -- The Horizontal Metrics Table
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_hmtx HB_TAG('h','m','t','x')
|
||||
|
||||
|
||||
struct LongHorMetric
|
||||
{
|
||||
USHORT advanceWidth;
|
||||
SHORT lsb;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct hmtx
|
||||
{
|
||||
static const hb_tag_t Tag = HB_OT_TAG_hmtx;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
/* We don't check for anything specific here. The users of the
|
||||
* struct do all the hard work... */
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
protected:
|
||||
LongHorMetric longHorMetric[VAR]; /* Paired advance width and left side
|
||||
* bearing values for each glyph. The
|
||||
* value numOfHMetrics comes from
|
||||
* the 'hhea' table. If the font is
|
||||
* monospaced, only one entry need
|
||||
* be in the array, but that entry is
|
||||
* required. The last entry applies to
|
||||
* all subsequent glyphs. */
|
||||
SHORT leftSideBearingX[VAR]; /* Here the advanceWidth is assumed
|
||||
* to be the same as the advanceWidth
|
||||
* for the last entry above. The
|
||||
* number of entries in this array is
|
||||
* derived from numGlyphs (from 'maxp'
|
||||
* table) minus numberOfHMetrics. This
|
||||
* generally is used with a run of
|
||||
* monospaced glyphs (e.g., Kanji
|
||||
* fonts or Courier fonts). Only one
|
||||
* run is allowed and it must be at
|
||||
* the end. This allows a monospaced
|
||||
* font to vary the left side bearing
|
||||
* values for each glyph. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY2 (0, longHorMetric, leftSideBearingX);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_HMTX_TABLE_HH */
|
1170
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
vendored
Normal file
1170
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
vendored
Normal file
File diff suppressed because it is too large
Load Diff
431
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
vendored
Normal file
431
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
vendored
Normal file
@ -0,0 +1,431 @@
|
||||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2010,2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_LAYOUT_GDEF_TABLE_HH
|
||||
#define HB_OT_LAYOUT_GDEF_TABLE_HH
|
||||
|
||||
#include "hb-ot-layout-common-private.hh"
|
||||
|
||||
#include "hb-font-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* Attachment List Table
|
||||
*/
|
||||
|
||||
typedef ArrayOf<USHORT> AttachPoint; /* Array of contour point indices--in
|
||||
* increasing numerical order */
|
||||
|
||||
struct AttachList
|
||||
{
|
||||
inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
|
||||
unsigned int start_offset,
|
||||
unsigned int *point_count /* IN/OUT */,
|
||||
unsigned int *point_array /* OUT */) const
|
||||
{
|
||||
unsigned int index = (this+coverage).get_coverage (glyph_id);
|
||||
if (index == NOT_COVERED)
|
||||
{
|
||||
if (point_count)
|
||||
*point_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const AttachPoint &points = this+attachPoint[index];
|
||||
|
||||
if (point_count) {
|
||||
const USHORT *array = points.sub_array (start_offset, point_count);
|
||||
unsigned int count = *point_count;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
point_array[i] = array[i];
|
||||
}
|
||||
|
||||
return points.len;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<Coverage>
|
||||
coverage; /* Offset to Coverage table -- from
|
||||
* beginning of AttachList table */
|
||||
OffsetArrayOf<AttachPoint>
|
||||
attachPoint; /* Array of AttachPoint tables
|
||||
* in Coverage Index order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, attachPoint);
|
||||
};
|
||||
|
||||
/*
|
||||
* Ligature Caret Table
|
||||
*/
|
||||
|
||||
struct CaretValueFormat1
|
||||
{
|
||||
friend struct CaretValue;
|
||||
|
||||
private:
|
||||
inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const
|
||||
{
|
||||
return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT caretValueFormat; /* Format identifier--format = 1 */
|
||||
SHORT coordinate; /* X or Y value, in design units */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct CaretValueFormat2
|
||||
{
|
||||
friend struct CaretValue;
|
||||
|
||||
private:
|
||||
inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
|
||||
{
|
||||
hb_position_t x, y;
|
||||
if (font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y))
|
||||
return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT caretValueFormat; /* Format identifier--format = 2 */
|
||||
USHORT caretValuePoint; /* Contour point index on glyph */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct CaretValueFormat3
|
||||
{
|
||||
friend struct CaretValue;
|
||||
|
||||
inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const
|
||||
{
|
||||
return HB_DIRECTION_IS_HORIZONTAL (direction) ?
|
||||
font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font) :
|
||||
font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && deviceTable.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT caretValueFormat; /* Format identifier--format = 3 */
|
||||
SHORT coordinate; /* X or Y value, in design units */
|
||||
OffsetTo<Device>
|
||||
deviceTable; /* Offset to Device table for X or Y
|
||||
* value--from beginning of CaretValue
|
||||
* table */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
||||
struct CaretValue
|
||||
{
|
||||
inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1: return u.format1.get_caret_value (font, direction, glyph_id);
|
||||
case 2: return u.format2.get_caret_value (font, direction, glyph_id);
|
||||
case 3: return u.format3.get_caret_value (font, direction, glyph_id);
|
||||
default:return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
||||
case 2: return TRACE_RETURN (u.format2.sanitize (c));
|
||||
case 3: return TRACE_RETURN (u.format3.sanitize (c));
|
||||
default:return TRACE_RETURN (true);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
CaretValueFormat1 format1;
|
||||
CaretValueFormat2 format2;
|
||||
CaretValueFormat3 format3;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, format);
|
||||
};
|
||||
|
||||
struct LigGlyph
|
||||
{
|
||||
inline unsigned int get_lig_carets (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph_id,
|
||||
unsigned int start_offset,
|
||||
unsigned int *caret_count /* IN/OUT */,
|
||||
hb_position_t *caret_array /* OUT */) const
|
||||
{
|
||||
if (caret_count) {
|
||||
const OffsetTo<CaretValue> *array = carets.sub_array (start_offset, caret_count);
|
||||
unsigned int count = *caret_count;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id);
|
||||
}
|
||||
|
||||
return carets.len;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (carets.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetArrayOf<CaretValue>
|
||||
carets; /* Offset array of CaretValue tables
|
||||
* --from beginning of LigGlyph table
|
||||
* --in increasing coordinate order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2, carets);
|
||||
};
|
||||
|
||||
struct LigCaretList
|
||||
{
|
||||
inline unsigned int get_lig_carets (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph_id,
|
||||
unsigned int start_offset,
|
||||
unsigned int *caret_count /* IN/OUT */,
|
||||
hb_position_t *caret_array /* OUT */) const
|
||||
{
|
||||
unsigned int index = (this+coverage).get_coverage (glyph_id);
|
||||
if (index == NOT_COVERED)
|
||||
{
|
||||
if (caret_count)
|
||||
*caret_count = 0;
|
||||
return 0;
|
||||
}
|
||||
const LigGlyph &lig_glyph = this+ligGlyph[index];
|
||||
return lig_glyph.get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<Coverage>
|
||||
coverage; /* Offset to Coverage table--from
|
||||
* beginning of LigCaretList table */
|
||||
OffsetArrayOf<LigGlyph>
|
||||
ligGlyph; /* Array of LigGlyph tables
|
||||
* in Coverage Index order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, ligGlyph);
|
||||
};
|
||||
|
||||
|
||||
struct MarkGlyphSetsFormat1
|
||||
{
|
||||
inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
||||
{ return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (coverage.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT format; /* Format identifier--format = 1 */
|
||||
LongOffsetArrayOf<Coverage>
|
||||
coverage; /* Array of long offsets to mark set
|
||||
* coverage tables */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, coverage);
|
||||
};
|
||||
|
||||
struct MarkGlyphSets
|
||||
{
|
||||
inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1: return u.format1.covers (set_index, glyph_id);
|
||||
default:return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
||||
default:return TRACE_RETURN (true);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
MarkGlyphSetsFormat1 format1;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, format);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* GDEF -- The Glyph Definition Table
|
||||
*/
|
||||
|
||||
struct GDEF
|
||||
{
|
||||
static const hb_tag_t Tag = HB_OT_TAG_GDEF;
|
||||
|
||||
enum GlyphClasses {
|
||||
UnclassifiedGlyph = 0,
|
||||
BaseGlyph = 1,
|
||||
LigatureGlyph = 2,
|
||||
MarkGlyph = 3,
|
||||
ComponentGlyph = 4
|
||||
};
|
||||
|
||||
inline bool has_glyph_classes (void) const { return glyphClassDef != 0; }
|
||||
inline unsigned int get_glyph_class (hb_codepoint_t glyph) const
|
||||
{ return (this+glyphClassDef).get_class (glyph); }
|
||||
inline void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
|
||||
{ (this+glyphClassDef).add_class (glyphs, klass); }
|
||||
|
||||
inline bool has_mark_attachment_types (void) const { return markAttachClassDef != 0; }
|
||||
inline unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
|
||||
{ return (this+markAttachClassDef).get_class (glyph); }
|
||||
|
||||
inline bool has_attach_points (void) const { return attachList != 0; }
|
||||
inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
|
||||
unsigned int start_offset,
|
||||
unsigned int *point_count /* IN/OUT */,
|
||||
unsigned int *point_array /* OUT */) const
|
||||
{ return (this+attachList).get_attach_points (glyph_id, start_offset, point_count, point_array); }
|
||||
|
||||
inline bool has_lig_carets (void) const { return ligCaretList != 0; }
|
||||
inline unsigned int get_lig_carets (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph_id,
|
||||
unsigned int start_offset,
|
||||
unsigned int *caret_count /* IN/OUT */,
|
||||
hb_position_t *caret_array /* OUT */) const
|
||||
{ return (this+ligCaretList).get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); }
|
||||
|
||||
inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002 && markGlyphSetsDef[0] != 0; }
|
||||
inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
||||
{ return version.to_int () >= 0x00010002 && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (version.sanitize (c) &&
|
||||
likely (version.major == 1) &&
|
||||
glyphClassDef.sanitize (c, this) &&
|
||||
attachList.sanitize (c, this) &&
|
||||
ligCaretList.sanitize (c, this) &&
|
||||
markAttachClassDef.sanitize (c, this) &&
|
||||
(version.to_int () < 0x00010002 || markGlyphSetsDef[0].sanitize (c, this)));
|
||||
}
|
||||
|
||||
|
||||
/* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
|
||||
* glyph class and other bits, and high 8-bit gthe mark attachment type (if any).
|
||||
* Not to be confused with lookup_props which is very similar. */
|
||||
inline unsigned int get_glyph_props (hb_codepoint_t glyph) const
|
||||
{
|
||||
unsigned int klass = get_glyph_class (glyph);
|
||||
|
||||
switch (klass) {
|
||||
default:
|
||||
case UnclassifiedGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED;
|
||||
case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
|
||||
case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
|
||||
case ComponentGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT;
|
||||
case MarkGlyph:
|
||||
klass = get_mark_attachment_type (glyph);
|
||||
return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
FixedVersion version; /* Version of the GDEF table--currently
|
||||
* 0x00010002 */
|
||||
OffsetTo<ClassDef>
|
||||
glyphClassDef; /* Offset to class definition table
|
||||
* for glyph type--from beginning of
|
||||
* GDEF header (may be Null) */
|
||||
OffsetTo<AttachList>
|
||||
attachList; /* Offset to list of glyphs with
|
||||
* attachment points--from beginning
|
||||
* of GDEF header (may be Null) */
|
||||
OffsetTo<LigCaretList>
|
||||
ligCaretList; /* Offset to list of positioning points
|
||||
* for ligature carets--from beginning
|
||||
* of GDEF header (may be Null) */
|
||||
OffsetTo<ClassDef>
|
||||
markAttachClassDef; /* Offset to class definition table for
|
||||
* mark attachment type--from beginning
|
||||
* of GDEF header (may be Null) */
|
||||
OffsetTo<MarkGlyphSets>
|
||||
markGlyphSetsDef[VAR]; /* Offset to the table of mark set
|
||||
* definitions--from beginning of GDEF
|
||||
* header (may be NULL). Introduced
|
||||
* in version 00010002. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (12, markGlyphSetsDef);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_LAYOUT_GDEF_TABLE_HH */
|
1629
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
vendored
Normal file
1629
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1427
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
vendored
Normal file
1427
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2449
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
vendored
Normal file
2449
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
vendored
Normal file
File diff suppressed because it is too large
Load Diff
296
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
vendored
Normal file
296
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
vendored
Normal file
@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_LAYOUT_PRIVATE_HH
|
||||
#define HB_OT_LAYOUT_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-ot-layout.h"
|
||||
|
||||
#include "hb-font-private.hh"
|
||||
#include "hb-buffer-private.hh"
|
||||
#include "hb-set-private.hh"
|
||||
|
||||
|
||||
/* buffer var allocations, used during the GSUB/GPOS processing */
|
||||
#define glyph_props() var1.u16[0] /* GDEF glyph properties */
|
||||
#define syllable() var1.u8[2] /* GSUB/GPOS shaping boundaries */
|
||||
#define lig_props() var1.u8[3] /* GSUB/GPOS ligature tracking */
|
||||
|
||||
/* buffer var allocations, used during the entire shaping process */
|
||||
#define unicode_props0() var2.u8[0]
|
||||
#define unicode_props1() var2.u8[1]
|
||||
|
||||
|
||||
inline void
|
||||
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
|
||||
{
|
||||
info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
|
||||
(unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0) |
|
||||
(info->codepoint == 0x200C ? 0x40 : 0) |
|
||||
(info->codepoint == 0x200D ? 0x20 : 0);
|
||||
info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
|
||||
}
|
||||
|
||||
inline void
|
||||
_hb_glyph_info_set_general_category (hb_glyph_info_t *info, hb_unicode_general_category_t gen_cat)
|
||||
{
|
||||
info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~0x1F);
|
||||
}
|
||||
|
||||
inline hb_unicode_general_category_t
|
||||
_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
|
||||
{
|
||||
return (hb_unicode_general_category_t) (info->unicode_props0() & 0x1F);
|
||||
}
|
||||
|
||||
inline void
|
||||
_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class)
|
||||
{
|
||||
info->unicode_props1() = modified_class;
|
||||
}
|
||||
|
||||
inline unsigned int
|
||||
_hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
|
||||
{
|
||||
return info->unicode_props1();
|
||||
}
|
||||
|
||||
inline hb_bool_t
|
||||
_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->unicode_props0() & 0x80);
|
||||
}
|
||||
|
||||
inline hb_bool_t
|
||||
_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->unicode_props0() & 0x40);
|
||||
}
|
||||
|
||||
inline hb_bool_t
|
||||
_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->unicode_props0() & 0x20);
|
||||
}
|
||||
|
||||
|
||||
#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
|
||||
|
||||
/*
|
||||
* GDEF
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED = 1 << HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED,
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 1 << HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH,
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 1 << HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE,
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_MARK = 1 << HB_OT_LAYOUT_GLYPH_CLASS_MARK,
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT = 1 << HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT
|
||||
} hb_ot_layout_glyph_class_mask_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* GSUB/GPOS
|
||||
*/
|
||||
|
||||
/* lig_id / lig_comp
|
||||
*
|
||||
* When a ligature is formed:
|
||||
*
|
||||
* - The ligature glyph and any marks in between all the same newly allocated
|
||||
* lig_id,
|
||||
* - The ligature glyph will get lig_num_comps set to the number of components
|
||||
* - The marks get lig_comp > 0, reflecting which component of the ligature
|
||||
* they were applied to.
|
||||
* - This is used in GPOS to attach marks to the right component of a ligature
|
||||
* in MarkLigPos.
|
||||
*
|
||||
* When a multiple-substitution is done:
|
||||
*
|
||||
* - All resulting glyphs will have lig_id = 0,
|
||||
* - The resulting glyphs will have lig_comp = 0, 1, 2, ... respectively.
|
||||
* - This is used in GPOS to attach marks to the first component of a
|
||||
* multiple substitution in MarkBasePos.
|
||||
*
|
||||
* The numbers are also used in GPOS to do mark-to-mark positioning only
|
||||
* to marks that belong to the same component of a ligature in MarkMarPos.
|
||||
*/
|
||||
#define IS_LIG_BASE 0x10
|
||||
static inline void
|
||||
set_lig_props_for_ligature (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_num_comps)
|
||||
{
|
||||
info.lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F);
|
||||
}
|
||||
static inline void
|
||||
set_lig_props_for_mark (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_comp)
|
||||
{
|
||||
info.lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
|
||||
}
|
||||
static inline void
|
||||
set_lig_props_for_component (hb_glyph_info_t &info, unsigned int comp)
|
||||
{
|
||||
set_lig_props_for_mark (info, 0, comp);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
get_lig_id (const hb_glyph_info_t &info)
|
||||
{
|
||||
return info.lig_props() >> 5;
|
||||
}
|
||||
static inline bool
|
||||
is_a_ligature (const hb_glyph_info_t &info)
|
||||
{
|
||||
return !!(info.lig_props() & IS_LIG_BASE);
|
||||
}
|
||||
static inline unsigned int
|
||||
get_lig_comp (const hb_glyph_info_t &info)
|
||||
{
|
||||
if (is_a_ligature (info))
|
||||
return 0;
|
||||
else
|
||||
return info.lig_props() & 0x0F;
|
||||
}
|
||||
static inline unsigned int
|
||||
get_lig_num_comps (const hb_glyph_info_t &info)
|
||||
{
|
||||
if ((info.glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) && is_a_ligature (info))
|
||||
return info.lig_props() & 0x0F;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
|
||||
uint8_t lig_id = buffer->next_serial () & 0x07;
|
||||
if (unlikely (!lig_id))
|
||||
lig_id = allocate_lig_id (buffer); /* in case of overflow */
|
||||
return lig_id;
|
||||
}
|
||||
|
||||
|
||||
HB_INTERNAL hb_bool_t
|
||||
hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
|
||||
unsigned int lookup_index,
|
||||
const hb_codepoint_t *glyphs,
|
||||
unsigned int glyphs_length,
|
||||
hb_bool_t zero_context);
|
||||
|
||||
|
||||
/* Should be called before all the substitute_lookup's are done. */
|
||||
HB_INTERNAL void
|
||||
hb_ot_layout_substitute_start (hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
|
||||
struct hb_ot_layout_lookup_accelerator_t;
|
||||
|
||||
namespace OT {
|
||||
struct hb_apply_context_t;
|
||||
struct SubstLookup;
|
||||
}
|
||||
|
||||
HB_INTERNAL void
|
||||
hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
|
||||
const OT::SubstLookup &lookup,
|
||||
const hb_ot_layout_lookup_accelerator_t &accel);
|
||||
|
||||
|
||||
/* Should be called after all the substitute_lookup's are done */
|
||||
HB_INTERNAL void
|
||||
hb_ot_layout_substitute_finish (hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
|
||||
/* Should be called before all the position_lookup's are done. Resets positions to zero. */
|
||||
HB_INTERNAL void
|
||||
hb_ot_layout_position_start (hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
/* Should be called after all the position_lookup's are done */
|
||||
HB_INTERNAL void
|
||||
hb_ot_layout_position_finish (hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* hb_ot_layout_t
|
||||
*/
|
||||
|
||||
namespace OT {
|
||||
struct GDEF;
|
||||
struct GSUB;
|
||||
struct GPOS;
|
||||
}
|
||||
|
||||
struct hb_ot_layout_lookup_accelerator_t
|
||||
{
|
||||
template <typename TLookup>
|
||||
inline void init (const TLookup &lookup)
|
||||
{
|
||||
digest.init ();
|
||||
lookup.add_coverage (&digest);
|
||||
}
|
||||
|
||||
template <typename TLookup>
|
||||
inline void fini (const TLookup &lookup)
|
||||
{
|
||||
}
|
||||
|
||||
hb_set_digest_t digest;
|
||||
};
|
||||
|
||||
struct hb_ot_layout_t
|
||||
{
|
||||
hb_blob_t *gdef_blob;
|
||||
hb_blob_t *gsub_blob;
|
||||
hb_blob_t *gpos_blob;
|
||||
|
||||
const struct OT::GDEF *gdef;
|
||||
const struct OT::GSUB *gsub;
|
||||
const struct OT::GPOS *gpos;
|
||||
|
||||
unsigned int gsub_lookup_count;
|
||||
unsigned int gpos_lookup_count;
|
||||
|
||||
hb_ot_layout_lookup_accelerator_t *gsub_accels;
|
||||
hb_ot_layout_lookup_accelerator_t *gpos_accels;
|
||||
};
|
||||
|
||||
|
||||
HB_INTERNAL hb_ot_layout_t *
|
||||
_hb_ot_layout_create (hb_face_t *face);
|
||||
|
||||
HB_INTERNAL void
|
||||
_hb_ot_layout_destroy (hb_ot_layout_t *layout);
|
||||
|
||||
|
||||
|
||||
#endif /* HB_OT_LAYOUT_PRIVATE_HH */
|
910
src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
vendored
Normal file
910
src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
vendored
Normal file
@ -0,0 +1,910 @@
|
||||
/*
|
||||
* Copyright © 1998-2004 David Turner and Werner Lemberg
|
||||
* Copyright © 2006 Behdad Esfahbod
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2012,2013 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-ot-layout-private.hh"
|
||||
|
||||
#include "hb-ot-layout-gdef-table.hh"
|
||||
#include "hb-ot-layout-gsub-table.hh"
|
||||
#include "hb-ot-layout-gpos-table.hh"
|
||||
|
||||
#include "hb-ot-map-private.hh"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
|
||||
|
||||
hb_ot_layout_t *
|
||||
_hb_ot_layout_create (hb_face_t *face)
|
||||
{
|
||||
hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
|
||||
if (unlikely (!layout))
|
||||
return NULL;
|
||||
|
||||
layout->gdef_blob = OT::Sanitizer<OT::GDEF>::sanitize (face->reference_table (HB_OT_TAG_GDEF));
|
||||
layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob);
|
||||
|
||||
layout->gsub_blob = OT::Sanitizer<OT::GSUB>::sanitize (face->reference_table (HB_OT_TAG_GSUB));
|
||||
layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob);
|
||||
|
||||
layout->gpos_blob = OT::Sanitizer<OT::GPOS>::sanitize (face->reference_table (HB_OT_TAG_GPOS));
|
||||
layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
|
||||
|
||||
layout->gsub_lookup_count = layout->gsub->get_lookup_count ();
|
||||
layout->gpos_lookup_count = layout->gpos->get_lookup_count ();
|
||||
|
||||
layout->gsub_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t));
|
||||
layout->gpos_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t));
|
||||
|
||||
if (unlikely ((layout->gsub_lookup_count && !layout->gsub_accels) ||
|
||||
(layout->gpos_lookup_count && !layout->gpos_accels)))
|
||||
{
|
||||
_hb_ot_layout_destroy (layout);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
|
||||
layout->gsub_accels[i].init (layout->gsub->get_lookup (i));
|
||||
for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
|
||||
layout->gpos_accels[i].init (layout->gpos->get_lookup (i));
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_ot_layout_destroy (hb_ot_layout_t *layout)
|
||||
{
|
||||
for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
|
||||
layout->gsub_accels[i].fini (layout->gsub->get_lookup (i));
|
||||
for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
|
||||
layout->gpos_accels[i].fini (layout->gpos->get_lookup (i));
|
||||
|
||||
free (layout->gsub_accels);
|
||||
free (layout->gpos_accels);
|
||||
|
||||
hb_blob_destroy (layout->gdef_blob);
|
||||
hb_blob_destroy (layout->gsub_blob);
|
||||
hb_blob_destroy (layout->gpos_blob);
|
||||
|
||||
free (layout);
|
||||
}
|
||||
|
||||
static inline const OT::GDEF&
|
||||
_get_gdef (hb_face_t *face)
|
||||
{
|
||||
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GDEF);
|
||||
return *hb_ot_layout_from_face (face)->gdef;
|
||||
}
|
||||
static inline const OT::GSUB&
|
||||
_get_gsub (hb_face_t *face)
|
||||
{
|
||||
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB);
|
||||
return *hb_ot_layout_from_face (face)->gsub;
|
||||
}
|
||||
static inline const OT::GPOS&
|
||||
_get_gpos (hb_face_t *face)
|
||||
{
|
||||
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS);
|
||||
return *hb_ot_layout_from_face (face)->gpos;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GDEF
|
||||
*/
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_has_glyph_classes (hb_face_t *face)
|
||||
{
|
||||
return _get_gdef (face).has_glyph_classes ();
|
||||
}
|
||||
|
||||
hb_ot_layout_glyph_class_t
|
||||
hb_ot_layout_get_glyph_class (hb_face_t *face,
|
||||
hb_codepoint_t glyph)
|
||||
{
|
||||
return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph);
|
||||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
|
||||
hb_ot_layout_glyph_class_t klass,
|
||||
hb_set_t *glyphs /* OUT */)
|
||||
{
|
||||
return _get_gdef (face).get_glyphs_in_class (klass, glyphs);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_get_attach_points (hb_face_t *face,
|
||||
hb_codepoint_t glyph,
|
||||
unsigned int start_offset,
|
||||
unsigned int *point_count /* IN/OUT */,
|
||||
unsigned int *point_array /* OUT */)
|
||||
{
|
||||
return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_get_ligature_carets (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph,
|
||||
unsigned int start_offset,
|
||||
unsigned int *caret_count /* IN/OUT */,
|
||||
int *caret_array /* OUT */)
|
||||
{
|
||||
return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GSUB/GPOS
|
||||
*/
|
||||
|
||||
static const OT::GSUBGPOS&
|
||||
get_gsubgpos_table (hb_face_t *face,
|
||||
hb_tag_t table_tag)
|
||||
{
|
||||
switch (table_tag) {
|
||||
case HB_OT_TAG_GSUB: return _get_gsub (face);
|
||||
case HB_OT_TAG_GPOS: return _get_gpos (face);
|
||||
default: return OT::Null(OT::GSUBGPOS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_table_get_script_tags (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int start_offset,
|
||||
unsigned int *script_count /* IN/OUT */,
|
||||
hb_tag_t *script_tags /* OUT */)
|
||||
{
|
||||
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
|
||||
|
||||
return g.get_script_tags (start_offset, script_count, script_tags);
|
||||
}
|
||||
|
||||
#define HB_OT_TAG_LATIN_SCRIPT HB_TAG ('l', 'a', 't', 'n')
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_table_find_script (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
hb_tag_t script_tag,
|
||||
unsigned int *script_index)
|
||||
{
|
||||
ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
|
||||
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
|
||||
|
||||
if (g.find_script_index (script_tag, script_index))
|
||||
return true;
|
||||
|
||||
/* try finding 'DFLT' */
|
||||
if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index))
|
||||
return false;
|
||||
|
||||
/* try with 'dflt'; MS site has had typos and many fonts use it now :(.
|
||||
* including many versions of DejaVu Sans Mono! */
|
||||
if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index))
|
||||
return false;
|
||||
|
||||
/* try with 'latn'; some old fonts put their features there even though
|
||||
they're really trying to support Thai, for example :( */
|
||||
if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index))
|
||||
return false;
|
||||
|
||||
if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
|
||||
return false;
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_table_choose_script (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
const hb_tag_t *script_tags,
|
||||
unsigned int *script_index,
|
||||
hb_tag_t *chosen_script)
|
||||
{
|
||||
ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
|
||||
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
|
||||
|
||||
while (*script_tags)
|
||||
{
|
||||
if (g.find_script_index (*script_tags, script_index)) {
|
||||
if (chosen_script)
|
||||
*chosen_script = *script_tags;
|
||||
return true;
|
||||
}
|
||||
script_tags++;
|
||||
}
|
||||
|
||||
/* try finding 'DFLT' */
|
||||
if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) {
|
||||
if (chosen_script)
|
||||
*chosen_script = HB_OT_TAG_DEFAULT_SCRIPT;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* try with 'dflt'; MS site has had typos and many fonts use it now :( */
|
||||
if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) {
|
||||
if (chosen_script)
|
||||
*chosen_script = HB_OT_TAG_DEFAULT_LANGUAGE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* try with 'latn'; some old fonts put their features there even though
|
||||
they're really trying to support Thai, for example :( */
|
||||
if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index)) {
|
||||
if (chosen_script)
|
||||
*chosen_script = HB_OT_TAG_LATIN_SCRIPT;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
|
||||
if (chosen_script)
|
||||
*chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_table_get_feature_tags (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int start_offset,
|
||||
unsigned int *feature_count /* IN/OUT */,
|
||||
hb_tag_t *feature_tags /* OUT */)
|
||||
{
|
||||
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
|
||||
|
||||
return g.get_feature_tags (start_offset, feature_count, feature_tags);
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_script_get_language_tags (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *language_count /* IN/OUT */,
|
||||
hb_tag_t *language_tags /* OUT */)
|
||||
{
|
||||
const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
|
||||
|
||||
return s.get_lang_sys_tags (start_offset, language_count, language_tags);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_script_find_language (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
hb_tag_t language_tag,
|
||||
unsigned int *language_index)
|
||||
{
|
||||
ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
|
||||
const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
|
||||
|
||||
if (s.find_lang_sys_index (language_tag, language_index))
|
||||
return true;
|
||||
|
||||
/* try with 'dflt'; MS site has had typos and many fonts use it now :( */
|
||||
if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index))
|
||||
return false;
|
||||
|
||||
if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
|
||||
return false;
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
unsigned int *feature_index)
|
||||
{
|
||||
const OT::LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index);
|
||||
|
||||
if (feature_index) *feature_index = l.get_required_feature_index ();
|
||||
|
||||
return l.has_required_feature ();
|
||||
}
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *feature_count /* IN/OUT */,
|
||||
unsigned int *feature_indexes /* OUT */)
|
||||
{
|
||||
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
|
||||
const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
|
||||
|
||||
return l.get_feature_indexes (start_offset, feature_count, feature_indexes);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_language_get_feature_tags (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *feature_count /* IN/OUT */,
|
||||
hb_tag_t *feature_tags /* OUT */)
|
||||
{
|
||||
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
|
||||
const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
|
||||
|
||||
ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t));
|
||||
unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags);
|
||||
|
||||
if (feature_tags) {
|
||||
unsigned int count = *feature_count;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_language_find_feature (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
hb_tag_t feature_tag,
|
||||
unsigned int *feature_index)
|
||||
{
|
||||
ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
|
||||
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
|
||||
const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
|
||||
|
||||
unsigned int num_features = l.get_feature_count ();
|
||||
for (unsigned int i = 0; i < num_features; i++) {
|
||||
unsigned int f_index = l.get_feature_index (i);
|
||||
|
||||
if (feature_tag == g.get_feature_tag (f_index)) {
|
||||
if (feature_index) *feature_index = f_index;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_feature_get_lookups (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int feature_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *lookup_count /* IN/OUT */,
|
||||
unsigned int *lookup_indexes /* OUT */)
|
||||
{
|
||||
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
|
||||
const OT::Feature &f = g.get_feature (feature_index);
|
||||
|
||||
return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes);
|
||||
}
|
||||
|
||||
static void
|
||||
_hb_ot_layout_collect_lookups_lookups (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int feature_index,
|
||||
hb_set_t *lookup_indexes /* OUT */)
|
||||
{
|
||||
unsigned int lookup_indices[32];
|
||||
unsigned int offset, len;
|
||||
|
||||
offset = 0;
|
||||
do {
|
||||
len = ARRAY_LENGTH (lookup_indices);
|
||||
hb_ot_layout_feature_get_lookups (face,
|
||||
table_tag,
|
||||
feature_index,
|
||||
offset, &len,
|
||||
lookup_indices);
|
||||
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
lookup_indexes->add (lookup_indices[i]);
|
||||
|
||||
offset += len;
|
||||
} while (len == ARRAY_LENGTH (lookup_indices));
|
||||
}
|
||||
|
||||
static void
|
||||
_hb_ot_layout_collect_lookups_features (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
const hb_tag_t *features,
|
||||
hb_set_t *lookup_indexes /* OUT */)
|
||||
{
|
||||
if (!features)
|
||||
{
|
||||
unsigned int required_feature_index;
|
||||
if (hb_ot_layout_language_get_required_feature_index (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
language_index,
|
||||
&required_feature_index))
|
||||
_hb_ot_layout_collect_lookups_lookups (face,
|
||||
table_tag,
|
||||
required_feature_index,
|
||||
lookup_indexes);
|
||||
|
||||
/* All features */
|
||||
unsigned int feature_indices[32];
|
||||
unsigned int offset, len;
|
||||
|
||||
offset = 0;
|
||||
do {
|
||||
len = ARRAY_LENGTH (feature_indices);
|
||||
hb_ot_layout_language_get_feature_indexes (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
language_index,
|
||||
offset, &len,
|
||||
feature_indices);
|
||||
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
_hb_ot_layout_collect_lookups_lookups (face,
|
||||
table_tag,
|
||||
feature_indices[i],
|
||||
lookup_indexes);
|
||||
|
||||
offset += len;
|
||||
} while (len == ARRAY_LENGTH (feature_indices));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; *features; features++)
|
||||
{
|
||||
unsigned int feature_index;
|
||||
if (hb_ot_layout_language_find_feature (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
language_index,
|
||||
*features,
|
||||
&feature_index))
|
||||
_hb_ot_layout_collect_lookups_lookups (face,
|
||||
table_tag,
|
||||
feature_index,
|
||||
lookup_indexes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_hb_ot_layout_collect_lookups_languages (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
const hb_tag_t *languages,
|
||||
const hb_tag_t *features,
|
||||
hb_set_t *lookup_indexes /* OUT */)
|
||||
{
|
||||
_hb_ot_layout_collect_lookups_features (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
|
||||
features,
|
||||
lookup_indexes);
|
||||
|
||||
if (!languages)
|
||||
{
|
||||
/* All languages */
|
||||
unsigned int count = hb_ot_layout_script_get_language_tags (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
0, NULL, NULL);
|
||||
for (unsigned int language_index = 0; language_index < count; language_index++)
|
||||
_hb_ot_layout_collect_lookups_features (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
language_index,
|
||||
features,
|
||||
lookup_indexes);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; *languages; languages++)
|
||||
{
|
||||
unsigned int language_index;
|
||||
if (hb_ot_layout_script_find_language (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
*languages,
|
||||
&language_index))
|
||||
_hb_ot_layout_collect_lookups_features (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
language_index,
|
||||
features,
|
||||
lookup_indexes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_collect_lookups (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
const hb_tag_t *scripts,
|
||||
const hb_tag_t *languages,
|
||||
const hb_tag_t *features,
|
||||
hb_set_t *lookup_indexes /* OUT */)
|
||||
{
|
||||
if (!scripts)
|
||||
{
|
||||
/* All scripts */
|
||||
unsigned int count = hb_ot_layout_table_get_script_tags (face,
|
||||
table_tag,
|
||||
0, NULL, NULL);
|
||||
for (unsigned int script_index = 0; script_index < count; script_index++)
|
||||
_hb_ot_layout_collect_lookups_languages (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
languages,
|
||||
features,
|
||||
lookup_indexes);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; *scripts; scripts++)
|
||||
{
|
||||
unsigned int script_index;
|
||||
if (hb_ot_layout_table_find_script (face,
|
||||
table_tag,
|
||||
*scripts,
|
||||
&script_index))
|
||||
_hb_ot_layout_collect_lookups_languages (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
languages,
|
||||
features,
|
||||
lookup_indexes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int lookup_index,
|
||||
hb_set_t *glyphs_before, /* OUT. May be NULL */
|
||||
hb_set_t *glyphs_input, /* OUT. May be NULL */
|
||||
hb_set_t *glyphs_after, /* OUT. May be NULL */
|
||||
hb_set_t *glyphs_output /* OUT. May be NULL */)
|
||||
{
|
||||
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return;
|
||||
|
||||
OT::hb_collect_glyphs_context_t c (face,
|
||||
glyphs_before,
|
||||
glyphs_input,
|
||||
glyphs_after,
|
||||
glyphs_output);
|
||||
|
||||
switch (table_tag)
|
||||
{
|
||||
case HB_OT_TAG_GSUB:
|
||||
{
|
||||
const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
|
||||
l.collect_glyphs (&c);
|
||||
return;
|
||||
}
|
||||
case HB_OT_TAG_GPOS:
|
||||
{
|
||||
const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (lookup_index);
|
||||
l.collect_glyphs (&c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* OT::GSUB
|
||||
*/
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_has_substitution (hb_face_t *face)
|
||||
{
|
||||
return &_get_gsub (face) != &OT::Null(OT::GSUB);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_lookup_would_substitute (hb_face_t *face,
|
||||
unsigned int lookup_index,
|
||||
const hb_codepoint_t *glyphs,
|
||||
unsigned int glyphs_length,
|
||||
hb_bool_t zero_context)
|
||||
{
|
||||
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false;
|
||||
return hb_ot_layout_lookup_would_substitute_fast (face, lookup_index, glyphs, glyphs_length, zero_context);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
|
||||
unsigned int lookup_index,
|
||||
const hb_codepoint_t *glyphs,
|
||||
unsigned int glyphs_length,
|
||||
hb_bool_t zero_context)
|
||||
{
|
||||
if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false;
|
||||
OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, zero_context);
|
||||
|
||||
const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
|
||||
|
||||
return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index].digest);
|
||||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer)
|
||||
{
|
||||
OT::GSUB::substitute_start (font, buffer);
|
||||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer)
|
||||
{
|
||||
OT::GSUB::substitute_finish (font, buffer);
|
||||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
|
||||
unsigned int lookup_index,
|
||||
hb_set_t *glyphs)
|
||||
{
|
||||
OT::hb_closure_context_t c (face, glyphs);
|
||||
|
||||
const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index);
|
||||
|
||||
l.closure (&c);
|
||||
}
|
||||
|
||||
/*
|
||||
* OT::GPOS
|
||||
*/
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_has_positioning (hb_face_t *face)
|
||||
{
|
||||
return &_get_gpos (face) != &OT::Null(OT::GPOS);
|
||||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer)
|
||||
{
|
||||
OT::GPOS::position_start (font, buffer);
|
||||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer)
|
||||
{
|
||||
OT::GPOS::position_finish (font, buffer);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_get_size_params (hb_face_t *face,
|
||||
unsigned int *design_size, /* OUT. May be NULL */
|
||||
unsigned int *subfamily_id, /* OUT. May be NULL */
|
||||
unsigned int *subfamily_name_id, /* OUT. May be NULL */
|
||||
unsigned int *range_start, /* OUT. May be NULL */
|
||||
unsigned int *range_end /* OUT. May be NULL */)
|
||||
{
|
||||
const OT::GPOS &gpos = _get_gpos (face);
|
||||
const hb_tag_t tag = HB_TAG ('s','i','z','e');
|
||||
|
||||
unsigned int num_features = gpos.get_feature_count ();
|
||||
for (unsigned int i = 0; i < num_features; i++)
|
||||
{
|
||||
if (tag == gpos.get_feature_tag (i))
|
||||
{
|
||||
const OT::Feature &f = gpos.get_feature (i);
|
||||
const OT::FeatureParamsSize ¶ms = f.get_feature_params ().get_size_params (tag);
|
||||
|
||||
if (params.designSize)
|
||||
{
|
||||
#define PARAM(a, A) if (a) *a = params.A
|
||||
PARAM (design_size, designSize);
|
||||
PARAM (subfamily_id, subfamilyID);
|
||||
PARAM (subfamily_name_id, subfamilyNameID);
|
||||
PARAM (range_start, rangeStart);
|
||||
PARAM (range_end, rangeEnd);
|
||||
#undef PARAM
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define PARAM(a, A) if (a) *a = 0
|
||||
PARAM (design_size, designSize);
|
||||
PARAM (subfamily_id, subfamilyID);
|
||||
PARAM (subfamily_name_id, subfamilyNameID);
|
||||
PARAM (range_start, rangeStart);
|
||||
PARAM (range_end, rangeEnd);
|
||||
#undef PARAM
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parts of different types are implemented here such that they have direct
|
||||
* access to GSUB/GPOS lookups.
|
||||
*/
|
||||
|
||||
|
||||
struct GSUBProxy
|
||||
{
|
||||
static const unsigned int table_index = 0;
|
||||
typedef OT::SubstLookup Lookup;
|
||||
|
||||
GSUBProxy (hb_face_t *face) :
|
||||
table (*hb_ot_layout_from_face (face)->gsub),
|
||||
accels (hb_ot_layout_from_face (face)->gsub_accels) {}
|
||||
|
||||
const OT::GSUB &table;
|
||||
const hb_ot_layout_lookup_accelerator_t *accels;
|
||||
};
|
||||
|
||||
struct GPOSProxy
|
||||
{
|
||||
static const unsigned int table_index = 1;
|
||||
typedef OT::PosLookup Lookup;
|
||||
|
||||
GPOSProxy (hb_face_t *face) :
|
||||
table (*hb_ot_layout_from_face (face)->gpos),
|
||||
accels (hb_ot_layout_from_face (face)->gpos_accels) {}
|
||||
|
||||
const OT::GPOS &table;
|
||||
const hb_ot_layout_lookup_accelerator_t *accels;
|
||||
};
|
||||
|
||||
|
||||
template <typename Lookup>
|
||||
static inline bool apply_once (OT::hb_apply_context_t *c,
|
||||
const Lookup &lookup)
|
||||
{
|
||||
if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props))
|
||||
return false;
|
||||
return lookup.dispatch (c);
|
||||
}
|
||||
|
||||
template <typename Proxy>
|
||||
static inline bool
|
||||
apply_string (OT::hb_apply_context_t *c,
|
||||
const typename Proxy::Lookup &lookup,
|
||||
const hb_ot_layout_lookup_accelerator_t &accel)
|
||||
{
|
||||
bool ret = false;
|
||||
OT::hb_is_inplace_context_t inplace_c (c->face);
|
||||
bool inplace = lookup.is_inplace (&inplace_c);
|
||||
|
||||
if (unlikely (!c->buffer->len || !c->lookup_mask))
|
||||
return false;
|
||||
|
||||
c->set_lookup (lookup);
|
||||
|
||||
if (likely (!lookup.is_reverse ()))
|
||||
{
|
||||
/* in/out forward substitution/positioning */
|
||||
if (Proxy::table_index == 0)
|
||||
c->buffer->clear_output ();
|
||||
c->buffer->idx = 0;
|
||||
|
||||
while (c->buffer->idx < c->buffer->len)
|
||||
{
|
||||
if (accel.digest.may_have (c->buffer->cur().codepoint) &&
|
||||
(c->buffer->cur().mask & c->lookup_mask) &&
|
||||
apply_once (c, lookup))
|
||||
ret = true;
|
||||
else
|
||||
c->buffer->next_glyph ();
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
if (!inplace)
|
||||
c->buffer->swap_buffers ();
|
||||
else
|
||||
assert (!c->buffer->has_separate_output ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* in-place backward substitution/positioning */
|
||||
if (Proxy::table_index == 0)
|
||||
c->buffer->remove_output ();
|
||||
c->buffer->idx = c->buffer->len - 1;
|
||||
do
|
||||
{
|
||||
if (accel.digest.may_have (c->buffer->cur().codepoint) &&
|
||||
(c->buffer->cur().mask & c->lookup_mask) &&
|
||||
apply_once (c, lookup))
|
||||
ret = true;
|
||||
else
|
||||
c->buffer->idx--;
|
||||
|
||||
}
|
||||
while ((int) c->buffer->idx >= 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename Proxy>
|
||||
inline void hb_ot_map_t::apply (const Proxy &proxy,
|
||||
const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer) const
|
||||
{
|
||||
const unsigned int table_index = proxy.table_index;
|
||||
unsigned int i = 0;
|
||||
OT::hb_apply_context_t c (table_index, font, buffer);
|
||||
c.set_recurse_func (Proxy::Lookup::apply_recurse_func);
|
||||
|
||||
for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) {
|
||||
const stage_map_t *stage = &stages[table_index][stage_index];
|
||||
for (; i < stage->last_lookup; i++)
|
||||
{
|
||||
unsigned int lookup_index = lookups[table_index][i].index;
|
||||
c.set_lookup_mask (lookups[table_index][i].mask);
|
||||
c.set_auto_zwj (lookups[table_index][i].auto_zwj);
|
||||
apply_string<Proxy> (&c,
|
||||
proxy.table.get_lookup (lookup_index),
|
||||
proxy.accels[lookup_index]);
|
||||
}
|
||||
|
||||
if (stage->pause_func)
|
||||
{
|
||||
buffer->clear_output ();
|
||||
stage->pause_func (plan, font, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
|
||||
{
|
||||
GSUBProxy proxy (font->face);
|
||||
apply (proxy, plan, font, buffer);
|
||||
}
|
||||
|
||||
void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
|
||||
{
|
||||
GPOSProxy proxy (font->face);
|
||||
apply (proxy, plan, font, buffer);
|
||||
}
|
||||
|
||||
HB_INTERNAL void
|
||||
hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
|
||||
const OT::SubstLookup &lookup,
|
||||
const hb_ot_layout_lookup_accelerator_t &accel)
|
||||
{
|
||||
apply_string<GSUBProxy> (c, lookup, accel);
|
||||
}
|
293
src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
vendored
Normal file
293
src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
vendored
Normal file
@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_H_IN
|
||||
#error "Include <hb-ot.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_OT_LAYOUT_H
|
||||
#define HB_OT_LAYOUT_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
#include "hb-ot-tag.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
#define HB_OT_TAG_GDEF HB_TAG('G','D','E','F')
|
||||
#define HB_OT_TAG_GSUB HB_TAG('G','S','U','B')
|
||||
#define HB_OT_TAG_GPOS HB_TAG('G','P','O','S')
|
||||
|
||||
|
||||
/*
|
||||
* GDEF
|
||||
*/
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_has_glyph_classes (hb_face_t *face);
|
||||
|
||||
typedef enum {
|
||||
HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0,
|
||||
HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 1,
|
||||
HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE = 2,
|
||||
HB_OT_LAYOUT_GLYPH_CLASS_MARK = 3,
|
||||
HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 4
|
||||
} hb_ot_layout_glyph_class_t;
|
||||
|
||||
hb_ot_layout_glyph_class_t
|
||||
hb_ot_layout_get_glyph_class (hb_face_t *face,
|
||||
hb_codepoint_t glyph);
|
||||
|
||||
void
|
||||
hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
|
||||
hb_ot_layout_glyph_class_t klass,
|
||||
hb_set_t *glyphs /* OUT */);
|
||||
|
||||
|
||||
/* Not that useful. Provides list of attach points for a glyph that a
|
||||
* client may want to cache */
|
||||
unsigned int
|
||||
hb_ot_layout_get_attach_points (hb_face_t *face,
|
||||
hb_codepoint_t glyph,
|
||||
unsigned int start_offset,
|
||||
unsigned int *point_count /* IN/OUT */,
|
||||
unsigned int *point_array /* OUT */);
|
||||
|
||||
/* Ligature caret positions */
|
||||
unsigned int
|
||||
hb_ot_layout_get_ligature_carets (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph,
|
||||
unsigned int start_offset,
|
||||
unsigned int *caret_count /* IN/OUT */,
|
||||
hb_position_t *caret_array /* OUT */);
|
||||
|
||||
|
||||
/*
|
||||
* GSUB/GPOS feature query and enumeration interface
|
||||
*/
|
||||
|
||||
#define HB_OT_LAYOUT_NO_SCRIPT_INDEX ((unsigned int) 0xFFFF)
|
||||
#define HB_OT_LAYOUT_NO_FEATURE_INDEX ((unsigned int) 0xFFFF)
|
||||
#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX ((unsigned int) 0xFFFF)
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_table_get_script_tags (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int start_offset,
|
||||
unsigned int *script_count /* IN/OUT */,
|
||||
hb_tag_t *script_tags /* OUT */);
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_table_find_script (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
hb_tag_t script_tag,
|
||||
unsigned int *script_index);
|
||||
|
||||
/* Like find_script, but takes zero-terminated array of scripts to test */
|
||||
hb_bool_t
|
||||
hb_ot_layout_table_choose_script (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
const hb_tag_t *script_tags,
|
||||
unsigned int *script_index,
|
||||
hb_tag_t *chosen_script);
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_table_get_feature_tags (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int start_offset,
|
||||
unsigned int *feature_count /* IN/OUT */,
|
||||
hb_tag_t *feature_tags /* OUT */);
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_script_get_language_tags (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *language_count /* IN/OUT */,
|
||||
hb_tag_t *language_tags /* OUT */);
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_script_find_language (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
hb_tag_t language_tag,
|
||||
unsigned int *language_index);
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
unsigned int *feature_index);
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *feature_count /* IN/OUT */,
|
||||
unsigned int *feature_indexes /* OUT */);
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_language_get_feature_tags (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *feature_count /* IN/OUT */,
|
||||
hb_tag_t *feature_tags /* OUT */);
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_language_find_feature (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
hb_tag_t feature_tag,
|
||||
unsigned int *feature_index);
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_feature_get_lookups (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int feature_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *lookup_count /* IN/OUT */,
|
||||
unsigned int *lookup_indexes /* OUT */);
|
||||
|
||||
void
|
||||
hb_ot_layout_collect_lookups (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
const hb_tag_t *scripts,
|
||||
const hb_tag_t *languages,
|
||||
const hb_tag_t *features,
|
||||
hb_set_t *lookup_indexes /* OUT */);
|
||||
|
||||
void
|
||||
hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
|
||||
hb_tag_t table_tag,
|
||||
hb_set_t *lookup_indexes /* OUT */);
|
||||
|
||||
void
|
||||
hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int lookup_index,
|
||||
hb_set_t *glyphs_before, /* OUT. May be NULL */
|
||||
hb_set_t *glyphs_input, /* OUT. May be NULL */
|
||||
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);
|
||||
|
||||
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
|
||||
|
||||
|
||||
/*
|
||||
* GSUB
|
||||
*/
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_has_substitution (hb_face_t *face);
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_lookup_would_substitute (hb_face_t *face,
|
||||
unsigned int lookup_index,
|
||||
const hb_codepoint_t *glyphs,
|
||||
unsigned int glyphs_length,
|
||||
hb_bool_t zero_context);
|
||||
|
||||
void
|
||||
hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
|
||||
unsigned int lookup_index,
|
||||
hb_set_t *glyphs
|
||||
/*TODO , hb_bool_t inclusive */);
|
||||
|
||||
#ifdef HB_NOT_IMPLEMENTED
|
||||
/* Note: You better have GDEF when using this API, or marks won't do much. */
|
||||
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
|
||||
*/
|
||||
|
||||
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_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.
|
||||
* http://www.microsoft.com/typography/otspec/features_pt.htm#size */
|
||||
hb_bool_t
|
||||
hb_ot_layout_get_size_params (hb_face_t *face,
|
||||
unsigned int *design_size, /* OUT. May be NULL */
|
||||
unsigned int *subfamily_id, /* OUT. May be NULL */
|
||||
unsigned int *subfamily_name_id, /* OUT. May be NULL */
|
||||
unsigned int *range_start, /* OUT. May be NULL */
|
||||
unsigned int *range_end /* OUT. May be NULL */);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_OT_LAYOUT_H */
|
247
src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh
vendored
Normal file
247
src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2010,2011,2012,2013 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_MAP_PRIVATE_HH
|
||||
#define HB_OT_MAP_PRIVATE_HH
|
||||
|
||||
#include "hb-buffer-private.hh"
|
||||
|
||||
|
||||
struct hb_ot_shape_plan_t;
|
||||
|
||||
static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS};
|
||||
|
||||
struct hb_ot_map_t
|
||||
{
|
||||
friend struct hb_ot_map_builder_t;
|
||||
|
||||
public:
|
||||
|
||||
struct feature_map_t {
|
||||
hb_tag_t tag; /* should be first for our bsearch to work */
|
||||
unsigned int index[2]; /* GSUB/GPOS */
|
||||
unsigned int stage[2]; /* GSUB/GPOS */
|
||||
unsigned int shift;
|
||||
hb_mask_t mask;
|
||||
hb_mask_t _1_mask; /* mask for value=1, for quick access */
|
||||
unsigned int needs_fallback : 1;
|
||||
unsigned int auto_zwj : 1;
|
||||
|
||||
static int cmp (const feature_map_t *a, const feature_map_t *b)
|
||||
{ return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; }
|
||||
};
|
||||
|
||||
struct lookup_map_t {
|
||||
unsigned short index;
|
||||
unsigned short auto_zwj : 1;
|
||||
hb_mask_t mask;
|
||||
|
||||
static int cmp (const lookup_map_t *a, const lookup_map_t *b)
|
||||
{ return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
|
||||
};
|
||||
|
||||
typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
|
||||
|
||||
struct stage_map_t {
|
||||
unsigned int last_lookup; /* Cumulative */
|
||||
pause_func_t pause_func;
|
||||
};
|
||||
|
||||
|
||||
hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); }
|
||||
|
||||
inline hb_mask_t get_global_mask (void) const { return global_mask; }
|
||||
|
||||
inline hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = NULL) const {
|
||||
const feature_map_t *map = features.bsearch (&feature_tag);
|
||||
if (shift) *shift = map ? map->shift : 0;
|
||||
return map ? map->mask : 0;
|
||||
}
|
||||
|
||||
inline bool needs_fallback (hb_tag_t feature_tag) const {
|
||||
const feature_map_t *map = features.bsearch (&feature_tag);
|
||||
return map ? map->needs_fallback : false;
|
||||
}
|
||||
|
||||
inline hb_mask_t get_1_mask (hb_tag_t feature_tag) const {
|
||||
const feature_map_t *map = features.bsearch (&feature_tag);
|
||||
return map ? map->_1_mask : 0;
|
||||
}
|
||||
|
||||
inline unsigned int get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const {
|
||||
const feature_map_t *map = features.bsearch (&feature_tag);
|
||||
return map ? map->index[table_index] : HB_OT_LAYOUT_NO_FEATURE_INDEX;
|
||||
}
|
||||
|
||||
inline unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const {
|
||||
const feature_map_t *map = features.bsearch (&feature_tag);
|
||||
return map ? map->stage[table_index] : (unsigned int) -1;
|
||||
}
|
||||
|
||||
inline void get_stage_lookups (unsigned int table_index, unsigned int stage,
|
||||
const struct lookup_map_t **plookups, unsigned int *lookup_count) const {
|
||||
if (unlikely (stage == (unsigned int) -1)) {
|
||||
*plookups = NULL;
|
||||
*lookup_count = 0;
|
||||
return;
|
||||
}
|
||||
assert (stage <= stages[table_index].len);
|
||||
unsigned int start = stage ? stages[table_index][stage - 1].last_lookup : 0;
|
||||
unsigned int end = stage < stages[table_index].len ? stages[table_index][stage].last_lookup : lookups[table_index].len;
|
||||
*plookups = &lookups[table_index][start];
|
||||
*lookup_count = end - start;
|
||||
}
|
||||
|
||||
HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const;
|
||||
template <typename Proxy>
|
||||
HB_INTERNAL inline void apply (const Proxy &proxy,
|
||||
const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
|
||||
HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
|
||||
HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
|
||||
|
||||
inline void finish (void) {
|
||||
features.finish ();
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||
{
|
||||
lookups[table_index].finish ();
|
||||
stages[table_index].finish ();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
hb_tag_t chosen_script[2];
|
||||
bool found_script[2];
|
||||
|
||||
private:
|
||||
|
||||
HB_INTERNAL void add_lookups (hb_face_t *face,
|
||||
unsigned int table_index,
|
||||
unsigned int feature_index,
|
||||
hb_mask_t mask,
|
||||
bool auto_zwj);
|
||||
|
||||
hb_mask_t global_mask;
|
||||
|
||||
hb_prealloced_array_t<feature_map_t, 8> features;
|
||||
hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */
|
||||
hb_prealloced_array_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */
|
||||
};
|
||||
|
||||
enum hb_ot_map_feature_flags_t {
|
||||
F_NONE = 0x0000,
|
||||
F_GLOBAL = 0x0001,
|
||||
F_HAS_FALLBACK = 0x0002,
|
||||
F_MANUAL_ZWJ = 0x0004
|
||||
};
|
||||
/* Macro version for where const is desired. */
|
||||
#define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r)))
|
||||
inline hb_ot_map_feature_flags_t
|
||||
operator | (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
|
||||
{ return hb_ot_map_feature_flags_t ((unsigned int) l | (unsigned int) r); }
|
||||
inline hb_ot_map_feature_flags_t
|
||||
operator & (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
|
||||
{ return hb_ot_map_feature_flags_t ((unsigned int) l & (unsigned int) r); }
|
||||
inline hb_ot_map_feature_flags_t
|
||||
operator ~ (hb_ot_map_feature_flags_t r)
|
||||
{ return hb_ot_map_feature_flags_t (~(unsigned int) r); }
|
||||
inline hb_ot_map_feature_flags_t&
|
||||
operator |= (hb_ot_map_feature_flags_t &l, hb_ot_map_feature_flags_t r)
|
||||
{ l = l | r; return l; }
|
||||
inline hb_ot_map_feature_flags_t&
|
||||
operator &= (hb_ot_map_feature_flags_t& l, hb_ot_map_feature_flags_t r)
|
||||
{ l = l & r; return l; }
|
||||
|
||||
|
||||
struct hb_ot_map_builder_t
|
||||
{
|
||||
public:
|
||||
|
||||
HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_,
|
||||
const hb_segment_properties_t *props_);
|
||||
|
||||
HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value,
|
||||
hb_ot_map_feature_flags_t flags);
|
||||
|
||||
inline void add_global_bool_feature (hb_tag_t tag)
|
||||
{ add_feature (tag, 1, F_GLOBAL); }
|
||||
|
||||
inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
|
||||
{ add_pause (0, pause_func); }
|
||||
inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func)
|
||||
{ add_pause (1, pause_func); }
|
||||
|
||||
HB_INTERNAL void compile (struct hb_ot_map_t &m);
|
||||
|
||||
inline void finish (void) {
|
||||
feature_infos.finish ();
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||
{
|
||||
stages[table_index].finish ();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
struct feature_info_t {
|
||||
hb_tag_t tag;
|
||||
unsigned int seq; /* sequence#, used for stable sorting only */
|
||||
unsigned int max_value;
|
||||
hb_ot_map_feature_flags_t flags;
|
||||
unsigned int default_value; /* for non-global features, what should the unset glyphs take */
|
||||
unsigned int stage[2]; /* GSUB/GPOS */
|
||||
|
||||
static int cmp (const feature_info_t *a, const feature_info_t *b)
|
||||
{ return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) : (a->seq < b->seq ? -1 : 1); }
|
||||
};
|
||||
|
||||
struct stage_info_t {
|
||||
unsigned int index;
|
||||
hb_ot_map_t::pause_func_t pause_func;
|
||||
};
|
||||
|
||||
HB_INTERNAL void add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func);
|
||||
|
||||
public:
|
||||
|
||||
hb_face_t *face;
|
||||
hb_segment_properties_t props;
|
||||
|
||||
hb_tag_t chosen_script[2];
|
||||
bool found_script[2];
|
||||
unsigned int script_index[2], language_index[2];
|
||||
|
||||
private:
|
||||
|
||||
unsigned int current_stage[2]; /* GSUB/GPOS */
|
||||
hb_prealloced_array_t<feature_info_t, 32> feature_infos;
|
||||
hb_prealloced_array_t<stage_info_t, 8> stages[2]; /* GSUB/GPOS */
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* HB_OT_MAP_PRIVATE_HH */
|
275
src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
vendored
Normal file
275
src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2010,2011,2013 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-ot-map-private.hh"
|
||||
|
||||
#include "hb-ot-layout-private.hh"
|
||||
|
||||
|
||||
void
|
||||
hb_ot_map_t::add_lookups (hb_face_t *face,
|
||||
unsigned int table_index,
|
||||
unsigned int feature_index,
|
||||
hb_mask_t mask,
|
||||
bool auto_zwj)
|
||||
{
|
||||
unsigned int lookup_indices[32];
|
||||
unsigned int offset, len;
|
||||
|
||||
offset = 0;
|
||||
do {
|
||||
len = ARRAY_LENGTH (lookup_indices);
|
||||
hb_ot_layout_feature_get_lookups (face,
|
||||
table_tags[table_index],
|
||||
feature_index,
|
||||
offset, &len,
|
||||
lookup_indices);
|
||||
|
||||
for (unsigned int i = 0; i < len; i++) {
|
||||
hb_ot_map_t::lookup_map_t *lookup = lookups[table_index].push ();
|
||||
if (unlikely (!lookup))
|
||||
return;
|
||||
lookup->mask = mask;
|
||||
lookup->index = lookup_indices[i];
|
||||
lookup->auto_zwj = auto_zwj;
|
||||
}
|
||||
|
||||
offset += len;
|
||||
} while (len == ARRAY_LENGTH (lookup_indices));
|
||||
}
|
||||
|
||||
hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_,
|
||||
const hb_segment_properties_t *props_)
|
||||
{
|
||||
memset (this, 0, sizeof (*this));
|
||||
|
||||
face = face_;
|
||||
props = *props_;
|
||||
|
||||
|
||||
/* Fetch script/language indices for GSUB/GPOS. We need these later to skip
|
||||
* features not available in either table and not waste precious bits for them. */
|
||||
|
||||
hb_tag_t script_tags[3] = {HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE};
|
||||
hb_tag_t language_tag;
|
||||
|
||||
hb_ot_tags_from_script (props.script, &script_tags[0], &script_tags[1]);
|
||||
language_tag = hb_ot_tag_from_language (props.language);
|
||||
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++) {
|
||||
hb_tag_t table_tag = table_tags[table_index];
|
||||
found_script[table_index] = hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]);
|
||||
hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]);
|
||||
}
|
||||
}
|
||||
|
||||
void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
|
||||
hb_ot_map_feature_flags_t flags)
|
||||
{
|
||||
feature_info_t *info = feature_infos.push();
|
||||
if (unlikely (!info)) return;
|
||||
info->tag = tag;
|
||||
info->seq = feature_infos.len;
|
||||
info->max_value = value;
|
||||
info->flags = flags;
|
||||
info->default_value = (flags & F_GLOBAL) ? value : 0;
|
||||
info->stage[0] = current_stage[0];
|
||||
info->stage[1] = current_stage[1];
|
||||
}
|
||||
|
||||
|
||||
void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const
|
||||
{
|
||||
for (unsigned int i = 0; i < lookups[table_index].len; i++)
|
||||
hb_set_add (lookups_out, lookups[table_index][i].index);
|
||||
}
|
||||
|
||||
void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func)
|
||||
{
|
||||
stage_info_t *s = stages[table_index].push ();
|
||||
if (likely (s)) {
|
||||
s->index = current_stage[table_index];
|
||||
s->pause_func = pause_func;
|
||||
}
|
||||
|
||||
current_stage[table_index]++;
|
||||
}
|
||||
|
||||
void
|
||||
hb_ot_map_builder_t::compile (hb_ot_map_t &m)
|
||||
{
|
||||
m.global_mask = 1;
|
||||
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++) {
|
||||
m.chosen_script[table_index] = chosen_script[table_index];
|
||||
m.found_script[table_index] = found_script[table_index];
|
||||
}
|
||||
|
||||
if (!feature_infos.len)
|
||||
return;
|
||||
|
||||
/* Sort features and merge duplicates */
|
||||
{
|
||||
feature_infos.sort ();
|
||||
unsigned int j = 0;
|
||||
for (unsigned int i = 1; i < feature_infos.len; i++)
|
||||
if (feature_infos[i].tag != feature_infos[j].tag)
|
||||
feature_infos[++j] = feature_infos[i];
|
||||
else {
|
||||
if (feature_infos[i].flags & F_GLOBAL) {
|
||||
feature_infos[j].flags |= F_GLOBAL;
|
||||
feature_infos[j].max_value = feature_infos[i].max_value;
|
||||
feature_infos[j].default_value = feature_infos[i].default_value;
|
||||
} else {
|
||||
feature_infos[j].flags &= ~F_GLOBAL;
|
||||
feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value);
|
||||
/* Inherit default_value from j */
|
||||
}
|
||||
feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK);
|
||||
feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]);
|
||||
feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]);
|
||||
}
|
||||
feature_infos.shrink (j + 1);
|
||||
}
|
||||
|
||||
|
||||
/* Allocate bits now */
|
||||
unsigned int next_bit = 1;
|
||||
for (unsigned int i = 0; i < feature_infos.len; i++) {
|
||||
const feature_info_t *info = &feature_infos[i];
|
||||
|
||||
unsigned int bits_needed;
|
||||
|
||||
if ((info->flags & F_GLOBAL) && info->max_value == 1)
|
||||
/* Uses the global bit */
|
||||
bits_needed = 0;
|
||||
else
|
||||
bits_needed = _hb_bit_storage (info->max_value);
|
||||
|
||||
if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t))
|
||||
continue; /* Feature disabled, or not enough bits. */
|
||||
|
||||
|
||||
bool found = false;
|
||||
unsigned int feature_index[2];
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||
found |= hb_ot_layout_language_find_feature (face,
|
||||
table_tags[table_index],
|
||||
script_index[table_index],
|
||||
language_index[table_index],
|
||||
info->tag,
|
||||
&feature_index[table_index]);
|
||||
if (!found && !(info->flags & F_HAS_FALLBACK))
|
||||
continue;
|
||||
|
||||
|
||||
hb_ot_map_t::feature_map_t *map = m.features.push ();
|
||||
if (unlikely (!map))
|
||||
break;
|
||||
|
||||
map->tag = info->tag;
|
||||
map->index[0] = feature_index[0];
|
||||
map->index[1] = feature_index[1];
|
||||
map->stage[0] = info->stage[0];
|
||||
map->stage[1] = info->stage[1];
|
||||
map->auto_zwj = !(info->flags & F_MANUAL_ZWJ);
|
||||
if ((info->flags & F_GLOBAL) && info->max_value == 1) {
|
||||
/* Uses the global bit */
|
||||
map->shift = 0;
|
||||
map->mask = 1;
|
||||
} else {
|
||||
map->shift = next_bit;
|
||||
map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit);
|
||||
next_bit += bits_needed;
|
||||
m.global_mask |= (info->default_value << map->shift) & map->mask;
|
||||
}
|
||||
map->_1_mask = (1 << map->shift) & map->mask;
|
||||
map->needs_fallback = !found;
|
||||
|
||||
}
|
||||
feature_infos.shrink (0); /* Done with these */
|
||||
|
||||
|
||||
add_gsub_pause (NULL);
|
||||
add_gpos_pause (NULL);
|
||||
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++) {
|
||||
hb_tag_t table_tag = table_tags[table_index];
|
||||
|
||||
/* Collect lookup indices for features */
|
||||
|
||||
unsigned int required_feature_index;
|
||||
if (hb_ot_layout_language_get_required_feature_index (face,
|
||||
table_tag,
|
||||
script_index[table_index],
|
||||
language_index[table_index],
|
||||
&required_feature_index))
|
||||
m.add_lookups (face, table_index, required_feature_index, 1, true);
|
||||
|
||||
unsigned int stage_index = 0;
|
||||
unsigned int last_num_lookups = 0;
|
||||
for (unsigned stage = 0; stage < current_stage[table_index]; stage++)
|
||||
{
|
||||
for (unsigned i = 0; i < m.features.len; i++)
|
||||
if (m.features[i].stage[table_index] == stage)
|
||||
m.add_lookups (face, table_index,
|
||||
m.features[i].index[table_index],
|
||||
m.features[i].mask,
|
||||
m.features[i].auto_zwj);
|
||||
|
||||
/* Sort lookups and merge duplicates */
|
||||
if (last_num_lookups < m.lookups[table_index].len)
|
||||
{
|
||||
m.lookups[table_index].sort (last_num_lookups, m.lookups[table_index].len);
|
||||
|
||||
unsigned int j = last_num_lookups;
|
||||
for (unsigned int i = j + 1; i < m.lookups[table_index].len; i++)
|
||||
if (m.lookups[table_index][i].index != m.lookups[table_index][j].index)
|
||||
m.lookups[table_index][++j] = m.lookups[table_index][i];
|
||||
else
|
||||
{
|
||||
m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask;
|
||||
m.lookups[table_index][j].auto_zwj &= m.lookups[table_index][i].auto_zwj;
|
||||
}
|
||||
m.lookups[table_index].shrink (j + 1);
|
||||
}
|
||||
|
||||
last_num_lookups = m.lookups[table_index].len;
|
||||
|
||||
if (stage_index < stages[table_index].len && stages[table_index][stage_index].index == stage) {
|
||||
hb_ot_map_t::stage_map_t *stage_map = m.stages[table_index].push ();
|
||||
if (likely (stage_map)) {
|
||||
stage_map->last_lookup = last_num_lookups;
|
||||
stage_map->pause_func = stages[table_index][stage_index].pause_func;
|
||||
}
|
||||
|
||||
stage_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
69
src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
vendored
Normal file
69
src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_MAXP_TABLE_HH
|
||||
#define HB_OT_MAXP_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* maxp -- The Maximum Profile Table
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_maxp HB_TAG('m','a','x','p')
|
||||
|
||||
struct maxp
|
||||
{
|
||||
static const hb_tag_t Tag = HB_OT_TAG_maxp;
|
||||
|
||||
inline unsigned int get_num_glyphs (void) const {
|
||||
return numGlyphs;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) &&
|
||||
likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000)));
|
||||
}
|
||||
|
||||
/* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */
|
||||
protected:
|
||||
FixedVersion version; /* Version of the maxp table (0.5 or 1.0),
|
||||
* 0x00005000 or 0x00010000. */
|
||||
USHORT numGlyphs; /* The number of glyphs in the font. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_MAXP_TABLE_HH */
|
134
src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
vendored
Normal file
134
src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_NAME_TABLE_HH
|
||||
#define HB_OT_NAME_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* name -- The Naming Table
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_name HB_TAG('n','a','m','e')
|
||||
|
||||
|
||||
struct NameRecord
|
||||
{
|
||||
static int cmp (const NameRecord *a, const NameRecord *b)
|
||||
{
|
||||
int ret;
|
||||
ret = b->platformID.cmp (a->platformID);
|
||||
if (ret) return ret;
|
||||
ret = b->encodingID.cmp (a->encodingID);
|
||||
if (ret) return ret;
|
||||
ret = b->languageID.cmp (a->languageID);
|
||||
if (ret) return ret;
|
||||
ret = b->nameID.cmp (a->nameID);
|
||||
if (ret) return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
||||
TRACE_SANITIZE (this);
|
||||
/* We can check from base all the way up to the end of string... */
|
||||
return TRACE_RETURN (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
|
||||
}
|
||||
|
||||
USHORT platformID; /* Platform ID. */
|
||||
USHORT encodingID; /* Platform-specific encoding ID. */
|
||||
USHORT languageID; /* Language ID. */
|
||||
USHORT nameID; /* Name ID. */
|
||||
USHORT length; /* String length (in bytes). */
|
||||
USHORT offset; /* String offset from start of storage area (in bytes). */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (12);
|
||||
};
|
||||
|
||||
struct name
|
||||
{
|
||||
static const hb_tag_t Tag = HB_OT_TAG_name;
|
||||
|
||||
inline unsigned int get_name (unsigned int platform_id,
|
||||
unsigned int encoding_id,
|
||||
unsigned int language_id,
|
||||
unsigned int name_id,
|
||||
void *buffer,
|
||||
unsigned int buffer_length) const
|
||||
{
|
||||
NameRecord key;
|
||||
key.platformID.set (platform_id);
|
||||
key.encodingID.set (encoding_id);
|
||||
key.languageID.set (language_id);
|
||||
key.nameID.set (name_id);
|
||||
NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), (hb_compare_func_t) NameRecord::cmp);
|
||||
|
||||
if (!match)
|
||||
return 0;
|
||||
|
||||
unsigned int length = MIN (buffer_length, (unsigned int) match->length);
|
||||
memcpy (buffer, (char *) this + stringOffset + match->offset, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
inline unsigned int get_size (void) const
|
||||
{ return min_size + count * nameRecord[0].min_size; }
|
||||
|
||||
inline bool sanitize_records (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
char *string_pool = (char *) this + stringOffset;
|
||||
unsigned int _count = count;
|
||||
for (unsigned int i = 0; i < _count; i++)
|
||||
if (!nameRecord[i].sanitize (c, string_pool)) return TRACE_RETURN (false);
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) &&
|
||||
likely (format == 0 || format == 1) &&
|
||||
c->check_array (nameRecord, nameRecord[0].static_size, count) &&
|
||||
sanitize_records (c));
|
||||
}
|
||||
|
||||
/* We only implement format 0 for now. */
|
||||
USHORT format; /* Format selector (=0/1). */
|
||||
USHORT count; /* Number of name records. */
|
||||
Offset stringOffset; /* Offset to start of string storage (from start of table). */
|
||||
NameRecord nameRecord[VAR]; /* The name records where count is the number of records. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, nameRecord);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_NAME_TABLE_HH */
|
260
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh
vendored
Normal file
260
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh
vendored
Normal file
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-ot-shape-private.hh"
|
||||
#include "hb-ot-layout-gsub-table.hh"
|
||||
|
||||
|
||||
static const hb_tag_t arabic_fallback_features[] =
|
||||
{
|
||||
HB_TAG('i','n','i','t'),
|
||||
HB_TAG('m','e','d','i'),
|
||||
HB_TAG('f','i','n','a'),
|
||||
HB_TAG('i','s','o','l'),
|
||||
HB_TAG('r','l','i','g'),
|
||||
};
|
||||
|
||||
/* Same order as the fallback feature array */
|
||||
enum {
|
||||
FALLBACK_INIT,
|
||||
FALLBACK_MEDI,
|
||||
FALLBACK_FINA,
|
||||
FALLBACK_ISOL,
|
||||
FALLBACK_RLIG,
|
||||
ARABIC_NUM_FALLBACK_FEATURES
|
||||
};
|
||||
|
||||
static OT::SubstLookup *
|
||||
arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
unsigned int feature_index)
|
||||
{
|
||||
OT::GlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||
OT::GlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||
unsigned int num_glyphs = 0;
|
||||
|
||||
/* Populate arrays */
|
||||
for (hb_codepoint_t u = SHAPING_TABLE_FIRST; u < SHAPING_TABLE_LAST + 1; u++)
|
||||
{
|
||||
hb_codepoint_t s = shaping_table[u - SHAPING_TABLE_FIRST][feature_index];
|
||||
hb_codepoint_t u_glyph, s_glyph;
|
||||
|
||||
if (!s ||
|
||||
!hb_font_get_glyph (font, u, 0, &u_glyph) ||
|
||||
!hb_font_get_glyph (font, s, 0, &s_glyph) ||
|
||||
u_glyph == s_glyph ||
|
||||
u_glyph > 0xFFFF || s_glyph > 0xFFFF)
|
||||
continue;
|
||||
|
||||
glyphs[num_glyphs].set (u_glyph);
|
||||
substitutes[num_glyphs].set (s_glyph);
|
||||
|
||||
num_glyphs++;
|
||||
}
|
||||
|
||||
/* Bubble-sort!
|
||||
* May not be good-enough for presidential candidate interviews, but good-enough for us... */
|
||||
hb_bubble_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]);
|
||||
|
||||
OT::Supplier<OT::GlyphID> glyphs_supplier (glyphs, num_glyphs);
|
||||
OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
|
||||
|
||||
/* Each glyph takes four bytes max, and there's some overhead. */
|
||||
char buf[(SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1) * 4 + 128];
|
||||
OT::hb_serialize_context_t c (buf, sizeof (buf));
|
||||
OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
|
||||
bool ret = lookup->serialize_single (&c,
|
||||
OT::LookupFlag::IgnoreMarks,
|
||||
glyphs_supplier,
|
||||
substitutes_supplier,
|
||||
num_glyphs);
|
||||
c.end_serialize ();
|
||||
/* TODO sanitize the results? */
|
||||
|
||||
return ret ? c.copy<OT::SubstLookup> () : NULL;
|
||||
}
|
||||
|
||||
static OT::SubstLookup *
|
||||
arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font)
|
||||
{
|
||||
OT::GlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
|
||||
unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)];
|
||||
unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
|
||||
unsigned int num_first_glyphs = 0;
|
||||
|
||||
/* We know that all our ligatures are 2-component */
|
||||
OT::GlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
|
||||
unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)];
|
||||
OT::GlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
|
||||
unsigned int num_ligatures = 0;
|
||||
|
||||
/* Populate arrays */
|
||||
|
||||
/* Sort out the first-glyphs */
|
||||
for (unsigned int first_glyph_idx = 0; first_glyph_idx < ARRAY_LENGTH (first_glyphs); first_glyph_idx++)
|
||||
{
|
||||
hb_codepoint_t first_u = ligature_table[first_glyph_idx].first;
|
||||
hb_codepoint_t first_glyph;
|
||||
if (!hb_font_get_glyph (font, first_u, 0, &first_glyph))
|
||||
continue;
|
||||
first_glyphs[num_first_glyphs].set (first_glyph);
|
||||
ligature_per_first_glyph_count_list[num_first_glyphs] = 0;
|
||||
first_glyphs_indirection[num_first_glyphs] = first_glyph_idx;
|
||||
num_first_glyphs++;
|
||||
}
|
||||
hb_bubble_sort (&first_glyphs[0], num_first_glyphs, OT::GlyphID::cmp, &first_glyphs_indirection[0]);
|
||||
|
||||
/* Now that the first-glyphs are sorted, walk again, populate ligatures. */
|
||||
for (unsigned int i = 0; i < num_first_glyphs; i++)
|
||||
{
|
||||
unsigned int first_glyph_idx = first_glyphs_indirection[i];
|
||||
|
||||
for (unsigned int second_glyph_idx = 0; second_glyph_idx < ARRAY_LENGTH (ligature_table[0].ligatures); second_glyph_idx++)
|
||||
{
|
||||
hb_codepoint_t second_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].second;
|
||||
hb_codepoint_t ligature_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].ligature;
|
||||
hb_codepoint_t second_glyph, ligature_glyph;
|
||||
if (!second_u ||
|
||||
!hb_font_get_glyph (font, second_u, 0, &second_glyph) ||
|
||||
!hb_font_get_glyph (font, ligature_u, 0, &ligature_glyph))
|
||||
continue;
|
||||
|
||||
ligature_per_first_glyph_count_list[i]++;
|
||||
|
||||
ligature_list[num_ligatures].set (ligature_glyph);
|
||||
component_count_list[num_ligatures] = 2;
|
||||
component_list[num_ligatures].set (second_glyph);
|
||||
num_ligatures++;
|
||||
}
|
||||
}
|
||||
|
||||
OT::Supplier<OT::GlyphID> first_glyphs_supplier (first_glyphs, num_first_glyphs);
|
||||
OT::Supplier<unsigned int > ligature_per_first_glyph_count_supplier (ligature_per_first_glyph_count_list, num_first_glyphs);
|
||||
OT::Supplier<OT::GlyphID> ligatures_supplier (ligature_list, num_ligatures);
|
||||
OT::Supplier<unsigned int > component_count_supplier (component_count_list, num_ligatures);
|
||||
OT::Supplier<OT::GlyphID> component_supplier (component_list, num_ligatures);
|
||||
|
||||
/* 16 bytes per ligature ought to be enough... */
|
||||
char buf[ARRAY_LENGTH_CONST (ligature_list) * 16 + 128];
|
||||
OT::hb_serialize_context_t c (buf, sizeof (buf));
|
||||
OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
|
||||
bool ret = lookup->serialize_ligature (&c,
|
||||
OT::LookupFlag::IgnoreMarks,
|
||||
first_glyphs_supplier,
|
||||
ligature_per_first_glyph_count_supplier,
|
||||
num_first_glyphs,
|
||||
ligatures_supplier,
|
||||
component_count_supplier,
|
||||
component_supplier);
|
||||
|
||||
c.end_serialize ();
|
||||
/* TODO sanitize the results? */
|
||||
|
||||
return ret ? c.copy<OT::SubstLookup> () : NULL;
|
||||
}
|
||||
|
||||
static OT::SubstLookup *
|
||||
arabic_fallback_synthesize_lookup (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
unsigned int feature_index)
|
||||
{
|
||||
if (feature_index < 4)
|
||||
return arabic_fallback_synthesize_lookup_single (plan, font, feature_index);
|
||||
else
|
||||
return arabic_fallback_synthesize_lookup_ligature (plan, font);
|
||||
}
|
||||
|
||||
struct arabic_fallback_plan_t
|
||||
{
|
||||
ASSERT_POD ();
|
||||
|
||||
hb_mask_t mask_array[ARABIC_NUM_FALLBACK_FEATURES];
|
||||
OT::SubstLookup *lookup_array[ARABIC_NUM_FALLBACK_FEATURES];
|
||||
hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_NUM_FALLBACK_FEATURES];
|
||||
};
|
||||
|
||||
static const arabic_fallback_plan_t arabic_fallback_plan_nil = {};
|
||||
|
||||
static arabic_fallback_plan_t *
|
||||
arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font)
|
||||
{
|
||||
arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t));
|
||||
if (unlikely (!fallback_plan))
|
||||
return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
|
||||
|
||||
for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++)
|
||||
{
|
||||
fallback_plan->mask_array[i] = plan->map.get_1_mask (arabic_fallback_features[i]);
|
||||
if (fallback_plan->mask_array[i]) {
|
||||
fallback_plan->lookup_array[i] = arabic_fallback_synthesize_lookup (plan, font, i);
|
||||
if (fallback_plan->lookup_array[i])
|
||||
fallback_plan->accel_array[i].init (*fallback_plan->lookup_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return fallback_plan;
|
||||
}
|
||||
|
||||
static void
|
||||
arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan)
|
||||
{
|
||||
if (!fallback_plan || fallback_plan == &arabic_fallback_plan_nil)
|
||||
return;
|
||||
|
||||
for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++)
|
||||
if (fallback_plan->lookup_array[i])
|
||||
{
|
||||
fallback_plan->accel_array[i].fini (fallback_plan->lookup_array[i]);
|
||||
free (fallback_plan->lookup_array[i]);
|
||||
}
|
||||
|
||||
free (fallback_plan);
|
||||
}
|
||||
|
||||
static void
|
||||
arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
OT::hb_apply_context_t c (0, font, buffer);
|
||||
for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++)
|
||||
if (fallback_plan->lookup_array[i]) {
|
||||
c.set_lookup_mask (fallback_plan->mask_array[i]);
|
||||
hb_ot_layout_substitute_lookup (&c,
|
||||
*fallback_plan->lookup_array[i],
|
||||
fallback_plan->accel_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH */
|
942
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh
vendored
Normal file
942
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh
vendored
Normal file
@ -0,0 +1,942 @@
|
||||
/* == Start of generated table == */
|
||||
/*
|
||||
* The following table is generated by running:
|
||||
*
|
||||
* ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt
|
||||
*
|
||||
* on files with these headers:
|
||||
*
|
||||
* # ArabicShaping-6.2.0.txt
|
||||
* # Date: 2012-05-15, 21:05:00 GMT [KW]
|
||||
* UnicodeData.txt does not have a header.
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
|
||||
|
||||
|
||||
static const uint8_t joining_table[] =
|
||||
{
|
||||
|
||||
/* Arabic Characters */
|
||||
|
||||
JOINING_TYPE_U, /* 0600; ARABIC NUMBER SIGN; U; No_Joining_Group */
|
||||
JOINING_TYPE_U, /* 0601; ARABIC SIGN SANAH; U; No_Joining_Group */
|
||||
JOINING_TYPE_U, /* 0602; ARABIC FOOTNOTE MARKER; U; No_Joining_Group */
|
||||
JOINING_TYPE_U, /* 0603; ARABIC SIGN SAFHA; U; No_Joining_Group */
|
||||
JOINING_TYPE_U, /* 0604; ARABIC SIGN SAMVAT; U; No_Joining_Group */
|
||||
JOINING_TYPE_X, /* 0605 */
|
||||
JOINING_TYPE_X, /* 0606 */
|
||||
JOINING_TYPE_X, /* 0607 */
|
||||
JOINING_TYPE_U, /* 0608; ARABIC RAY; U; No_Joining_Group */
|
||||
JOINING_TYPE_X, /* 0609 */
|
||||
JOINING_TYPE_X, /* 060A */
|
||||
JOINING_TYPE_U, /* 060B; AFGHANI SIGN; U; No_Joining_Group */
|
||||
JOINING_TYPE_X, /* 060C */
|
||||
JOINING_TYPE_X, /* 060D */
|
||||
JOINING_TYPE_X, /* 060E */
|
||||
JOINING_TYPE_X, /* 060F */
|
||||
JOINING_TYPE_X, /* 0610 */
|
||||
JOINING_TYPE_X, /* 0611 */
|
||||
JOINING_TYPE_X, /* 0612 */
|
||||
JOINING_TYPE_X, /* 0613 */
|
||||
JOINING_TYPE_X, /* 0614 */
|
||||
JOINING_TYPE_X, /* 0615 */
|
||||
JOINING_TYPE_X, /* 0616 */
|
||||
JOINING_TYPE_X, /* 0617 */
|
||||
JOINING_TYPE_X, /* 0618 */
|
||||
JOINING_TYPE_X, /* 0619 */
|
||||
JOINING_TYPE_X, /* 061A */
|
||||
JOINING_TYPE_X, /* 061B */
|
||||
JOINING_TYPE_X, /* 061C */
|
||||
JOINING_TYPE_X, /* 061D */
|
||||
JOINING_TYPE_X, /* 061E */
|
||||
JOINING_TYPE_X, /* 061F */
|
||||
JOINING_TYPE_D, /* 0620; DOTLESS YEH WITH SEPARATE RING BELOW; D; YEH */
|
||||
JOINING_TYPE_U, /* 0621; HAMZA; U; No_Joining_Group */
|
||||
JOINING_TYPE_R, /* 0622; ALEF WITH MADDA ABOVE; R; ALEF */
|
||||
JOINING_TYPE_R, /* 0623; ALEF WITH HAMZA ABOVE; R; ALEF */
|
||||
JOINING_TYPE_R, /* 0624; WAW WITH HAMZA ABOVE; R; WAW */
|
||||
JOINING_TYPE_R, /* 0625; ALEF WITH HAMZA BELOW; R; ALEF */
|
||||
JOINING_TYPE_D, /* 0626; DOTLESS YEH WITH HAMZA ABOVE; D; YEH */
|
||||
JOINING_TYPE_R, /* 0627; ALEF; R; ALEF */
|
||||
JOINING_TYPE_D, /* 0628; BEH; D; BEH */
|
||||
JOINING_TYPE_R, /* 0629; TEH MARBUTA; R; TEH MARBUTA */
|
||||
JOINING_TYPE_D, /* 062A; DOTLESS BEH WITH 2 DOTS ABOVE; D; BEH */
|
||||
JOINING_TYPE_D, /* 062B; DOTLESS BEH WITH 3 DOTS ABOVE; D; BEH */
|
||||
JOINING_TYPE_D, /* 062C; HAH WITH DOT BELOW; D; HAH */
|
||||
JOINING_TYPE_D, /* 062D; HAH; D; HAH */
|
||||
JOINING_TYPE_D, /* 062E; HAH WITH DOT ABOVE; D; HAH */
|
||||
JOINING_TYPE_R, /* 062F; DAL; R; DAL */
|
||||
JOINING_TYPE_R, /* 0630; DAL WITH DOT ABOVE; R; DAL */
|
||||
JOINING_TYPE_R, /* 0631; REH; R; REH */
|
||||
JOINING_TYPE_R, /* 0632; REH WITH DOT ABOVE; R; REH */
|
||||
JOINING_TYPE_D, /* 0633; SEEN; D; SEEN */
|
||||
JOINING_TYPE_D, /* 0634; SEEN WITH 3 DOTS ABOVE; D; SEEN */
|
||||
JOINING_TYPE_D, /* 0635; SAD; D; SAD */
|
||||
JOINING_TYPE_D, /* 0636; SAD WITH DOT ABOVE; D; SAD */
|
||||
JOINING_TYPE_D, /* 0637; TAH; D; TAH */
|
||||
JOINING_TYPE_D, /* 0638; TAH WITH DOT ABOVE; D; TAH */
|
||||
JOINING_TYPE_D, /* 0639; AIN; D; AIN */
|
||||
JOINING_TYPE_D, /* 063A; AIN WITH DOT ABOVE; D; AIN */
|
||||
JOINING_TYPE_D, /* 063B; KEHEH WITH 2 DOTS ABOVE; D; GAF */
|
||||
JOINING_TYPE_D, /* 063C; KEHEH WITH 3 DOTS BELOW; D; GAF */
|
||||
JOINING_TYPE_D, /* 063D; FARSI YEH WITH INVERTED V ABOVE; D; FARSI YEH */
|
||||
JOINING_TYPE_D, /* 063E; FARSI YEH WITH 2 DOTS ABOVE; D; FARSI YEH */
|
||||
JOINING_TYPE_D, /* 063F; FARSI YEH WITH 3 DOTS ABOVE; D; FARSI YEH */
|
||||
JOINING_TYPE_C, /* 0640; TATWEEL; C; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0641; FEH; D; FEH */
|
||||
JOINING_TYPE_D, /* 0642; QAF; D; QAF */
|
||||
JOINING_TYPE_D, /* 0643; KAF; D; KAF */
|
||||
JOINING_TYPE_D, /* 0644; LAM; D; LAM */
|
||||
JOINING_TYPE_D, /* 0645; MEEM; D; MEEM */
|
||||
JOINING_TYPE_D, /* 0646; NOON; D; NOON */
|
||||
JOINING_TYPE_D, /* 0647; HEH; D; HEH */
|
||||
JOINING_TYPE_R, /* 0648; WAW; R; WAW */
|
||||
JOINING_TYPE_D, /* 0649; DOTLESS YEH; D; YEH */
|
||||
JOINING_TYPE_D, /* 064A; YEH; D; YEH */
|
||||
JOINING_TYPE_X, /* 064B */
|
||||
JOINING_TYPE_X, /* 064C */
|
||||
JOINING_TYPE_X, /* 064D */
|
||||
JOINING_TYPE_X, /* 064E */
|
||||
JOINING_TYPE_X, /* 064F */
|
||||
JOINING_TYPE_X, /* 0650 */
|
||||
JOINING_TYPE_X, /* 0651 */
|
||||
JOINING_TYPE_X, /* 0652 */
|
||||
JOINING_TYPE_X, /* 0653 */
|
||||
JOINING_TYPE_X, /* 0654 */
|
||||
JOINING_TYPE_X, /* 0655 */
|
||||
JOINING_TYPE_X, /* 0656 */
|
||||
JOINING_TYPE_X, /* 0657 */
|
||||
JOINING_TYPE_X, /* 0658 */
|
||||
JOINING_TYPE_X, /* 0659 */
|
||||
JOINING_TYPE_X, /* 065A */
|
||||
JOINING_TYPE_X, /* 065B */
|
||||
JOINING_TYPE_X, /* 065C */
|
||||
JOINING_TYPE_X, /* 065D */
|
||||
JOINING_TYPE_X, /* 065E */
|
||||
JOINING_TYPE_X, /* 065F */
|
||||
JOINING_TYPE_X, /* 0660 */
|
||||
JOINING_TYPE_X, /* 0661 */
|
||||
JOINING_TYPE_X, /* 0662 */
|
||||
JOINING_TYPE_X, /* 0663 */
|
||||
JOINING_TYPE_X, /* 0664 */
|
||||
JOINING_TYPE_X, /* 0665 */
|
||||
JOINING_TYPE_X, /* 0666 */
|
||||
JOINING_TYPE_X, /* 0667 */
|
||||
JOINING_TYPE_X, /* 0668 */
|
||||
JOINING_TYPE_X, /* 0669 */
|
||||
JOINING_TYPE_X, /* 066A */
|
||||
JOINING_TYPE_X, /* 066B */
|
||||
JOINING_TYPE_X, /* 066C */
|
||||
JOINING_TYPE_X, /* 066D */
|
||||
JOINING_TYPE_D, /* 066E; DOTLESS BEH; D; BEH */
|
||||
JOINING_TYPE_D, /* 066F; DOTLESS QAF; D; QAF */
|
||||
JOINING_TYPE_X, /* 0670 */
|
||||
JOINING_TYPE_R, /* 0671; ALEF WITH WASLA ABOVE; R; ALEF */
|
||||
JOINING_TYPE_R, /* 0672; ALEF WITH WAVY HAMZA ABOVE; R; ALEF */
|
||||
JOINING_TYPE_R, /* 0673; ALEF WITH WAVY HAMZA BELOW; R; ALEF */
|
||||
JOINING_TYPE_U, /* 0674; HIGH HAMZA; U; No_Joining_Group */
|
||||
JOINING_TYPE_R, /* 0675; HIGH HAMZA ALEF; R; ALEF */
|
||||
JOINING_TYPE_R, /* 0676; HIGH HAMZA WAW; R; WAW */
|
||||
JOINING_TYPE_R, /* 0677; HIGH HAMZA WAW WITH DAMMA ABOVE; R; WAW */
|
||||
JOINING_TYPE_D, /* 0678; HIGH HAMZA DOTLESS YEH; D; YEH */
|
||||
JOINING_TYPE_D, /* 0679; DOTLESS BEH WITH TAH ABOVE; D; BEH */
|
||||
JOINING_TYPE_D, /* 067A; DOTLESS BEH WITH VERTICAL 2 DOTS ABOVE; D; BEH */
|
||||
JOINING_TYPE_D, /* 067B; DOTLESS BEH WITH VERTICAL 2 DOTS BELOW; D; BEH */
|
||||
JOINING_TYPE_D, /* 067C; DOTLESS BEH WITH ATTACHED RING BELOW AND 2 DOTS ABOVE; D; BEH */
|
||||
JOINING_TYPE_D, /* 067D; DOTLESS BEH WITH INVERTED 3 DOTS ABOVE; D; BEH */
|
||||
JOINING_TYPE_D, /* 067E; DOTLESS BEH WITH 3 DOTS BELOW; D; BEH */
|
||||
JOINING_TYPE_D, /* 067F; DOTLESS BEH WITH 4 DOTS ABOVE; D; BEH */
|
||||
JOINING_TYPE_D, /* 0680; DOTLESS BEH WITH 4 DOTS BELOW; D; BEH */
|
||||
JOINING_TYPE_D, /* 0681; HAH WITH HAMZA ABOVE; D; HAH */
|
||||
JOINING_TYPE_D, /* 0682; HAH WITH VERTICAL 2 DOTS ABOVE; D; HAH */
|
||||
JOINING_TYPE_D, /* 0683; HAH WITH 2 DOTS BELOW; D; HAH */
|
||||
JOINING_TYPE_D, /* 0684; HAH WITH VERTICAL 2 DOTS BELOW; D; HAH */
|
||||
JOINING_TYPE_D, /* 0685; HAH WITH 3 DOTS ABOVE; D; HAH */
|
||||
JOINING_TYPE_D, /* 0686; HAH WITH 3 DOTS BELOW; D; HAH */
|
||||
JOINING_TYPE_D, /* 0687; HAH WITH 4 DOTS BELOW; D; HAH */
|
||||
JOINING_TYPE_R, /* 0688; DAL WITH TAH ABOVE; R; DAL */
|
||||
JOINING_TYPE_R, /* 0689; DAL WITH ATTACHED RING BELOW; R; DAL */
|
||||
JOINING_TYPE_R, /* 068A; DAL WITH DOT BELOW; R; DAL */
|
||||
JOINING_TYPE_R, /* 068B; DAL WITH DOT BELOW AND TAH ABOVE; R; DAL */
|
||||
JOINING_TYPE_R, /* 068C; DAL WITH 2 DOTS ABOVE; R; DAL */
|
||||
JOINING_TYPE_R, /* 068D; DAL WITH 2 DOTS BELOW; R; DAL */
|
||||
JOINING_TYPE_R, /* 068E; DAL WITH 3 DOTS ABOVE; R; DAL */
|
||||
JOINING_TYPE_R, /* 068F; DAL WITH INVERTED 3 DOTS ABOVE; R; DAL */
|
||||
JOINING_TYPE_R, /* 0690; DAL WITH 4 DOTS ABOVE; R; DAL */
|
||||
JOINING_TYPE_R, /* 0691; REH WITH TAH ABOVE; R; REH */
|
||||
JOINING_TYPE_R, /* 0692; REH WITH V ABOVE; R; REH */
|
||||
JOINING_TYPE_R, /* 0693; REH WITH ATTACHED RING BELOW; R; REH */
|
||||
JOINING_TYPE_R, /* 0694; REH WITH DOT BELOW; R; REH */
|
||||
JOINING_TYPE_R, /* 0695; REH WITH V BELOW; R; REH */
|
||||
JOINING_TYPE_R, /* 0696; REH WITH DOT BELOW AND DOT WITHIN; R; REH */
|
||||
JOINING_TYPE_R, /* 0697; REH WITH 2 DOTS ABOVE; R; REH */
|
||||
JOINING_TYPE_R, /* 0698; REH WITH 3 DOTS ABOVE; R; REH */
|
||||
JOINING_TYPE_R, /* 0699; REH WITH 4 DOTS ABOVE; R; REH */
|
||||
JOINING_TYPE_D, /* 069A; SEEN WITH DOT BELOW AND DOT ABOVE; D; SEEN */
|
||||
JOINING_TYPE_D, /* 069B; SEEN WITH 3 DOTS BELOW; D; SEEN */
|
||||
JOINING_TYPE_D, /* 069C; SEEN WITH 3 DOTS BELOW AND 3 DOTS ABOVE; D; SEEN */
|
||||
JOINING_TYPE_D, /* 069D; SAD WITH 2 DOTS BELOW; D; SAD */
|
||||
JOINING_TYPE_D, /* 069E; SAD WITH 3 DOTS ABOVE; D; SAD */
|
||||
JOINING_TYPE_D, /* 069F; TAH WITH 3 DOTS ABOVE; D; TAH */
|
||||
JOINING_TYPE_D, /* 06A0; AIN WITH 3 DOTS ABOVE; D; AIN */
|
||||
JOINING_TYPE_D, /* 06A1; DOTLESS FEH; D; FEH */
|
||||
JOINING_TYPE_D, /* 06A2; DOTLESS FEH WITH DOT BELOW; D; FEH */
|
||||
JOINING_TYPE_D, /* 06A3; FEH WITH DOT BELOW; D; FEH */
|
||||
JOINING_TYPE_D, /* 06A4; DOTLESS FEH WITH 3 DOTS ABOVE; D; FEH */
|
||||
JOINING_TYPE_D, /* 06A5; DOTLESS FEH WITH 3 DOTS BELOW; D; FEH */
|
||||
JOINING_TYPE_D, /* 06A6; DOTLESS FEH WITH 4 DOTS ABOVE; D; FEH */
|
||||
JOINING_TYPE_D, /* 06A7; DOTLESS QAF WITH DOT ABOVE; D; QAF */
|
||||
JOINING_TYPE_D, /* 06A8; DOTLESS QAF WITH 3 DOTS ABOVE; D; QAF */
|
||||
JOINING_TYPE_D, /* 06A9; KEHEH; D; GAF */
|
||||
JOINING_TYPE_D, /* 06AA; SWASH KAF; D; SWASH KAF */
|
||||
JOINING_TYPE_D, /* 06AB; KEHEH WITH ATTACHED RING BELOW; D; GAF */
|
||||
JOINING_TYPE_D, /* 06AC; KAF WITH DOT ABOVE; D; KAF */
|
||||
JOINING_TYPE_D, /* 06AD; KAF WITH 3 DOTS ABOVE; D; KAF */
|
||||
JOINING_TYPE_D, /* 06AE; KAF WITH 3 DOTS BELOW; D; KAF */
|
||||
JOINING_TYPE_D, /* 06AF; GAF; D; GAF */
|
||||
JOINING_TYPE_D, /* 06B0; GAF WITH ATTACHED RING BELOW; D; GAF */
|
||||
JOINING_TYPE_D, /* 06B1; GAF WITH 2 DOTS ABOVE; D; GAF */
|
||||
JOINING_TYPE_D, /* 06B2; GAF WITH 2 DOTS BELOW; D; GAF */
|
||||
JOINING_TYPE_D, /* 06B3; GAF WITH VERTICAL 2 DOTS BELOW; D; GAF */
|
||||
JOINING_TYPE_D, /* 06B4; GAF WITH 3 DOTS ABOVE; D; GAF */
|
||||
JOINING_TYPE_D, /* 06B5; LAM WITH V ABOVE; D; LAM */
|
||||
JOINING_TYPE_D, /* 06B6; LAM WITH DOT ABOVE; D; LAM */
|
||||
JOINING_TYPE_D, /* 06B7; LAM WITH 3 DOTS ABOVE; D; LAM */
|
||||
JOINING_TYPE_D, /* 06B8; LAM WITH 3 DOTS BELOW; D; LAM */
|
||||
JOINING_TYPE_D, /* 06B9; NOON WITH DOT BELOW; D; NOON */
|
||||
JOINING_TYPE_D, /* 06BA; DOTLESS NOON; D; NOON */
|
||||
JOINING_TYPE_D, /* 06BB; DOTLESS NOON WITH TAH ABOVE; D; NOON */
|
||||
JOINING_TYPE_D, /* 06BC; NOON WITH ATTACHED RING BELOW; D; NOON */
|
||||
JOINING_TYPE_D, /* 06BD; NYA; D; NYA */
|
||||
JOINING_TYPE_D, /* 06BE; KNOTTED HEH; D; KNOTTED HEH */
|
||||
JOINING_TYPE_D, /* 06BF; HAH WITH 3 DOTS BELOW AND DOT ABOVE; D; HAH */
|
||||
JOINING_TYPE_R, /* 06C0; DOTLESS TEH MARBUTA WITH HAMZA ABOVE; R; TEH MARBUTA */
|
||||
JOINING_TYPE_D, /* 06C1; HEH GOAL; D; HEH GOAL */
|
||||
JOINING_TYPE_D, /* 06C2; HEH GOAL WITH HAMZA ABOVE; D; HEH GOAL */
|
||||
JOINING_TYPE_R, /* 06C3; TEH MARBUTA GOAL; R; TEH MARBUTA GOAL */
|
||||
JOINING_TYPE_R, /* 06C4; WAW WITH ATTACHED RING WITHIN; R; WAW */
|
||||
JOINING_TYPE_R, /* 06C5; WAW WITH BAR; R; WAW */
|
||||
JOINING_TYPE_R, /* 06C6; WAW WITH V ABOVE; R; WAW */
|
||||
JOINING_TYPE_R, /* 06C7; WAW WITH DAMMA ABOVE; R; WAW */
|
||||
JOINING_TYPE_R, /* 06C8; WAW WITH ALEF ABOVE; R; WAW */
|
||||
JOINING_TYPE_R, /* 06C9; WAW WITH INVERTED V ABOVE; R; WAW */
|
||||
JOINING_TYPE_R, /* 06CA; WAW WITH 2 DOTS ABOVE; R; WAW */
|
||||
JOINING_TYPE_R, /* 06CB; WAW WITH 3 DOTS ABOVE; R; WAW */
|
||||
JOINING_TYPE_D, /* 06CC; FARSI YEH; D; FARSI YEH */
|
||||
JOINING_TYPE_R, /* 06CD; YEH WITH TAIL; R; YEH WITH TAIL */
|
||||
JOINING_TYPE_D, /* 06CE; FARSI YEH WITH V ABOVE; D; FARSI YEH */
|
||||
JOINING_TYPE_R, /* 06CF; WAW WITH DOT ABOVE; R; WAW */
|
||||
JOINING_TYPE_D, /* 06D0; DOTLESS YEH WITH VERTICAL 2 DOTS BELOW; D; YEH */
|
||||
JOINING_TYPE_D, /* 06D1; DOTLESS YEH WITH 3 DOTS BELOW; D; YEH */
|
||||
JOINING_TYPE_R, /* 06D2; YEH BARREE; R; YEH BARREE */
|
||||
JOINING_TYPE_R, /* 06D3; YEH BARREE WITH HAMZA ABOVE; R; YEH BARREE */
|
||||
JOINING_TYPE_X, /* 06D4 */
|
||||
JOINING_TYPE_R, /* 06D5; DOTLESS TEH MARBUTA; R; TEH MARBUTA */
|
||||
JOINING_TYPE_X, /* 06D6 */
|
||||
JOINING_TYPE_X, /* 06D7 */
|
||||
JOINING_TYPE_X, /* 06D8 */
|
||||
JOINING_TYPE_X, /* 06D9 */
|
||||
JOINING_TYPE_X, /* 06DA */
|
||||
JOINING_TYPE_X, /* 06DB */
|
||||
JOINING_TYPE_X, /* 06DC */
|
||||
JOINING_TYPE_U, /* 06DD; ARABIC END OF AYAH; U; No_Joining_Group */
|
||||
JOINING_TYPE_X, /* 06DE */
|
||||
JOINING_TYPE_X, /* 06DF */
|
||||
JOINING_TYPE_X, /* 06E0 */
|
||||
JOINING_TYPE_X, /* 06E1 */
|
||||
JOINING_TYPE_X, /* 06E2 */
|
||||
JOINING_TYPE_X, /* 06E3 */
|
||||
JOINING_TYPE_X, /* 06E4 */
|
||||
JOINING_TYPE_X, /* 06E5 */
|
||||
JOINING_TYPE_X, /* 06E6 */
|
||||
JOINING_TYPE_X, /* 06E7 */
|
||||
JOINING_TYPE_X, /* 06E8 */
|
||||
JOINING_TYPE_X, /* 06E9 */
|
||||
JOINING_TYPE_X, /* 06EA */
|
||||
JOINING_TYPE_X, /* 06EB */
|
||||
JOINING_TYPE_X, /* 06EC */
|
||||
JOINING_TYPE_X, /* 06ED */
|
||||
JOINING_TYPE_R, /* 06EE; DAL WITH INVERTED V ABOVE; R; DAL */
|
||||
JOINING_TYPE_R, /* 06EF; REH WITH INVERTED V ABOVE; R; REH */
|
||||
JOINING_TYPE_X, /* 06F0 */
|
||||
JOINING_TYPE_X, /* 06F1 */
|
||||
JOINING_TYPE_X, /* 06F2 */
|
||||
JOINING_TYPE_X, /* 06F3 */
|
||||
JOINING_TYPE_X, /* 06F4 */
|
||||
JOINING_TYPE_X, /* 06F5 */
|
||||
JOINING_TYPE_X, /* 06F6 */
|
||||
JOINING_TYPE_X, /* 06F7 */
|
||||
JOINING_TYPE_X, /* 06F8 */
|
||||
JOINING_TYPE_X, /* 06F9 */
|
||||
JOINING_TYPE_D, /* 06FA; SEEN WITH DOT BELOW AND 3 DOTS ABOVE; D; SEEN */
|
||||
JOINING_TYPE_D, /* 06FB; SAD WITH DOT BELOW AND DOT ABOVE; D; SAD */
|
||||
JOINING_TYPE_D, /* 06FC; AIN WITH DOT BELOW AND DOT ABOVE; D; AIN */
|
||||
JOINING_TYPE_X, /* 06FD */
|
||||
JOINING_TYPE_X, /* 06FE */
|
||||
JOINING_TYPE_D, /* 06FF; KNOTTED HEH WITH INVERTED V ABOVE; D; KNOTTED HEH */
|
||||
|
||||
/* Syriac Characters */
|
||||
|
||||
JOINING_TYPE_X, /* 0700 */
|
||||
JOINING_TYPE_X, /* 0701 */
|
||||
JOINING_TYPE_X, /* 0702 */
|
||||
JOINING_TYPE_X, /* 0703 */
|
||||
JOINING_TYPE_X, /* 0704 */
|
||||
JOINING_TYPE_X, /* 0705 */
|
||||
JOINING_TYPE_X, /* 0706 */
|
||||
JOINING_TYPE_X, /* 0707 */
|
||||
JOINING_TYPE_X, /* 0708 */
|
||||
JOINING_TYPE_X, /* 0709 */
|
||||
JOINING_TYPE_X, /* 070A */
|
||||
JOINING_TYPE_X, /* 070B */
|
||||
JOINING_TYPE_X, /* 070C */
|
||||
JOINING_TYPE_X, /* 070D */
|
||||
JOINING_TYPE_X, /* 070E */
|
||||
JOINING_TYPE_X, /* 070F */
|
||||
JOINING_GROUP_ALAPH, /* 0710; ALAPH; R; ALAPH */
|
||||
JOINING_TYPE_X, /* 0711 */
|
||||
JOINING_TYPE_D, /* 0712; BETH; D; BETH */
|
||||
JOINING_TYPE_D, /* 0713; GAMAL; D; GAMAL */
|
||||
JOINING_TYPE_D, /* 0714; GAMAL GARSHUNI; D; GAMAL */
|
||||
JOINING_GROUP_DALATH_RISH, /* 0715; DALATH; R; DALATH RISH */
|
||||
JOINING_GROUP_DALATH_RISH, /* 0716; DOTLESS DALATH RISH; R; DALATH RISH */
|
||||
JOINING_TYPE_R, /* 0717; HE; R; HE */
|
||||
JOINING_TYPE_R, /* 0718; WAW; R; SYRIAC WAW */
|
||||
JOINING_TYPE_R, /* 0719; ZAIN; R; ZAIN */
|
||||
JOINING_TYPE_D, /* 071A; HETH; D; HETH */
|
||||
JOINING_TYPE_D, /* 071B; TETH; D; TETH */
|
||||
JOINING_TYPE_D, /* 071C; TETH GARSHUNI; D; TETH */
|
||||
JOINING_TYPE_D, /* 071D; YUDH; D; YUDH */
|
||||
JOINING_TYPE_R, /* 071E; YUDH HE; R; YUDH HE */
|
||||
JOINING_TYPE_D, /* 071F; KAPH; D; KAPH */
|
||||
JOINING_TYPE_D, /* 0720; LAMADH; D; LAMADH */
|
||||
JOINING_TYPE_D, /* 0721; MIM; D; MIM */
|
||||
JOINING_TYPE_D, /* 0722; NUN; D; NUN */
|
||||
JOINING_TYPE_D, /* 0723; SEMKATH; D; SEMKATH */
|
||||
JOINING_TYPE_D, /* 0724; FINAL SEMKATH; D; FINAL SEMKATH */
|
||||
JOINING_TYPE_D, /* 0725; E; D; E */
|
||||
JOINING_TYPE_D, /* 0726; PE; D; PE */
|
||||
JOINING_TYPE_D, /* 0727; REVERSED PE; D; REVERSED PE */
|
||||
JOINING_TYPE_R, /* 0728; SADHE; R; SADHE */
|
||||
JOINING_TYPE_D, /* 0729; QAPH; D; QAPH */
|
||||
JOINING_GROUP_DALATH_RISH, /* 072A; RISH; R; DALATH RISH */
|
||||
JOINING_TYPE_D, /* 072B; SHIN; D; SHIN */
|
||||
JOINING_TYPE_R, /* 072C; TAW; R; TAW */
|
||||
JOINING_TYPE_D, /* 072D; PERSIAN BHETH; D; BETH */
|
||||
JOINING_TYPE_D, /* 072E; PERSIAN GHAMAL; D; GAMAL */
|
||||
JOINING_GROUP_DALATH_RISH, /* 072F; PERSIAN DHALATH; R; DALATH RISH */
|
||||
JOINING_TYPE_X, /* 0730 */
|
||||
JOINING_TYPE_X, /* 0731 */
|
||||
JOINING_TYPE_X, /* 0732 */
|
||||
JOINING_TYPE_X, /* 0733 */
|
||||
JOINING_TYPE_X, /* 0734 */
|
||||
JOINING_TYPE_X, /* 0735 */
|
||||
JOINING_TYPE_X, /* 0736 */
|
||||
JOINING_TYPE_X, /* 0737 */
|
||||
JOINING_TYPE_X, /* 0738 */
|
||||
JOINING_TYPE_X, /* 0739 */
|
||||
JOINING_TYPE_X, /* 073A */
|
||||
JOINING_TYPE_X, /* 073B */
|
||||
JOINING_TYPE_X, /* 073C */
|
||||
JOINING_TYPE_X, /* 073D */
|
||||
JOINING_TYPE_X, /* 073E */
|
||||
JOINING_TYPE_X, /* 073F */
|
||||
JOINING_TYPE_X, /* 0740 */
|
||||
JOINING_TYPE_X, /* 0741 */
|
||||
JOINING_TYPE_X, /* 0742 */
|
||||
JOINING_TYPE_X, /* 0743 */
|
||||
JOINING_TYPE_X, /* 0744 */
|
||||
JOINING_TYPE_X, /* 0745 */
|
||||
JOINING_TYPE_X, /* 0746 */
|
||||
JOINING_TYPE_X, /* 0747 */
|
||||
JOINING_TYPE_X, /* 0748 */
|
||||
JOINING_TYPE_X, /* 0749 */
|
||||
JOINING_TYPE_X, /* 074A */
|
||||
JOINING_TYPE_X, /* 074B */
|
||||
JOINING_TYPE_X, /* 074C */
|
||||
JOINING_TYPE_R, /* 074D; SOGDIAN ZHAIN; R; ZHAIN */
|
||||
JOINING_TYPE_D, /* 074E; SOGDIAN KHAPH; D; KHAPH */
|
||||
JOINING_TYPE_D, /* 074F; SOGDIAN FE; D; FE */
|
||||
|
||||
/* Arabic Supplement Characters */
|
||||
|
||||
JOINING_TYPE_D, /* 0750; DOTLESS BEH WITH HORIZONTAL 3 DOTS BELOW; D; BEH */
|
||||
JOINING_TYPE_D, /* 0751; BEH WITH 3 DOTS ABOVE; D; BEH */
|
||||
JOINING_TYPE_D, /* 0752; DOTLESS BEH WITH INVERTED 3 DOTS BELOW; D; BEH */
|
||||
JOINING_TYPE_D, /* 0753; DOTLESS BEH WITH INVERTED 3 DOTS BELOW AND 2 DOTS ABOVE; D; BEH */
|
||||
JOINING_TYPE_D, /* 0754; DOTLESS BEH WITH 2 DOTS BELOW AND DOT ABOVE; D; BEH */
|
||||
JOINING_TYPE_D, /* 0755; DOTLESS BEH WITH INVERTED V BELOW; D; BEH */
|
||||
JOINING_TYPE_D, /* 0756; DOTLESS BEH WITH V ABOVE; D; BEH */
|
||||
JOINING_TYPE_D, /* 0757; HAH WITH 2 DOTS ABOVE; D; HAH */
|
||||
JOINING_TYPE_D, /* 0758; HAH WITH INVERTED 3 DOTS BELOW; D; HAH */
|
||||
JOINING_TYPE_R, /* 0759; DAL WITH VERTICAL 2 DOTS BELOW AND TAH ABOVE; R; DAL */
|
||||
JOINING_TYPE_R, /* 075A; DAL WITH INVERTED V BELOW; R; DAL */
|
||||
JOINING_TYPE_R, /* 075B; REH WITH BAR; R; REH */
|
||||
JOINING_TYPE_D, /* 075C; SEEN WITH 4 DOTS ABOVE; D; SEEN */
|
||||
JOINING_TYPE_D, /* 075D; AIN WITH 2 DOTS ABOVE; D; AIN */
|
||||
JOINING_TYPE_D, /* 075E; AIN WITH INVERTED 3 DOTS ABOVE; D; AIN */
|
||||
JOINING_TYPE_D, /* 075F; AIN WITH VERTICAL 2 DOTS ABOVE; D; AIN */
|
||||
JOINING_TYPE_D, /* 0760; DOTLESS FEH WITH 2 DOTS BELOW; D; FEH */
|
||||
JOINING_TYPE_D, /* 0761; DOTLESS FEH WITH INVERTED 3 DOTS BELOW; D; FEH */
|
||||
JOINING_TYPE_D, /* 0762; KEHEH WITH DOT ABOVE; D; GAF */
|
||||
JOINING_TYPE_D, /* 0763; KEHEH WITH 3 DOTS ABOVE; D; GAF */
|
||||
JOINING_TYPE_D, /* 0764; KEHEH WITH INVERTED 3 DOTS BELOW; D; GAF */
|
||||
JOINING_TYPE_D, /* 0765; MEEM WITH DOT ABOVE; D; MEEM */
|
||||
JOINING_TYPE_D, /* 0766; MEEM WITH DOT BELOW; D; MEEM */
|
||||
JOINING_TYPE_D, /* 0767; NOON WITH 2 DOTS BELOW; D; NOON */
|
||||
JOINING_TYPE_D, /* 0768; NOON WITH TAH ABOVE; D; NOON */
|
||||
JOINING_TYPE_D, /* 0769; NOON WITH V ABOVE; D; NOON */
|
||||
JOINING_TYPE_D, /* 076A; LAM WITH BAR; D; LAM */
|
||||
JOINING_TYPE_R, /* 076B; REH WITH VERTICAL 2 DOTS ABOVE; R; REH */
|
||||
JOINING_TYPE_R, /* 076C; REH WITH HAMZA ABOVE; R; REH */
|
||||
JOINING_TYPE_D, /* 076D; SEEN WITH VERTICAL 2 DOTS ABOVE; D; SEEN */
|
||||
JOINING_TYPE_D, /* 076E; HAH WITH TAH BELOW; D; HAH */
|
||||
JOINING_TYPE_D, /* 076F; HAH WITH TAH AND 2 DOTS BELOW; D; HAH */
|
||||
JOINING_TYPE_D, /* 0770; SEEN WITH 2 DOTS AND TAH ABOVE; D; SEEN */
|
||||
JOINING_TYPE_R, /* 0771; REH WITH 2 DOTS AND TAH ABOVE; R; REH */
|
||||
JOINING_TYPE_D, /* 0772; HAH WITH TAH ABOVE; D; HAH */
|
||||
JOINING_TYPE_R, /* 0773; ALEF WITH DIGIT TWO ABOVE; R; ALEF */
|
||||
JOINING_TYPE_R, /* 0774; ALEF WITH DIGIT THREE ABOVE; R; ALEF */
|
||||
JOINING_TYPE_D, /* 0775; FARSI YEH WITH DIGIT TWO ABOVE; D; FARSI YEH */
|
||||
JOINING_TYPE_D, /* 0776; FARSI YEH WITH DIGIT THREE ABOVE; D; FARSI YEH */
|
||||
JOINING_TYPE_D, /* 0777; DOTLESS YEH WITH DIGIT FOUR BELOW; D; YEH */
|
||||
JOINING_TYPE_R, /* 0778; WAW WITH DIGIT TWO ABOVE; R; WAW */
|
||||
JOINING_TYPE_R, /* 0779; WAW WITH DIGIT THREE ABOVE; R; WAW */
|
||||
JOINING_TYPE_D, /* 077A; BURUSHASKI YEH BARREE WITH DIGIT TWO ABOVE; D; BURUSHASKI YEH BARREE */
|
||||
JOINING_TYPE_D, /* 077B; BURUSHASKI YEH BARREE WITH DIGIT THREE ABOVE; D; BURUSHASKI YEH BARREE */
|
||||
JOINING_TYPE_D, /* 077C; HAH WITH DIGIT FOUR BELOW; D; HAH */
|
||||
JOINING_TYPE_D, /* 077D; SEEN WITH DIGIT FOUR ABOVE; D; SEEN */
|
||||
JOINING_TYPE_D, /* 077E; SEEN WITH INVERTED V ABOVE; D; SEEN */
|
||||
JOINING_TYPE_D, /* 077F; KAF WITH 2 DOTS ABOVE; D; KAF */
|
||||
|
||||
/* N'Ko Characters */
|
||||
|
||||
JOINING_TYPE_X, /* 0780 */
|
||||
JOINING_TYPE_X, /* 0781 */
|
||||
JOINING_TYPE_X, /* 0782 */
|
||||
JOINING_TYPE_X, /* 0783 */
|
||||
JOINING_TYPE_X, /* 0784 */
|
||||
JOINING_TYPE_X, /* 0785 */
|
||||
JOINING_TYPE_X, /* 0786 */
|
||||
JOINING_TYPE_X, /* 0787 */
|
||||
JOINING_TYPE_X, /* 0788 */
|
||||
JOINING_TYPE_X, /* 0789 */
|
||||
JOINING_TYPE_X, /* 078A */
|
||||
JOINING_TYPE_X, /* 078B */
|
||||
JOINING_TYPE_X, /* 078C */
|
||||
JOINING_TYPE_X, /* 078D */
|
||||
JOINING_TYPE_X, /* 078E */
|
||||
JOINING_TYPE_X, /* 078F */
|
||||
JOINING_TYPE_X, /* 0790 */
|
||||
JOINING_TYPE_X, /* 0791 */
|
||||
JOINING_TYPE_X, /* 0792 */
|
||||
JOINING_TYPE_X, /* 0793 */
|
||||
JOINING_TYPE_X, /* 0794 */
|
||||
JOINING_TYPE_X, /* 0795 */
|
||||
JOINING_TYPE_X, /* 0796 */
|
||||
JOINING_TYPE_X, /* 0797 */
|
||||
JOINING_TYPE_X, /* 0798 */
|
||||
JOINING_TYPE_X, /* 0799 */
|
||||
JOINING_TYPE_X, /* 079A */
|
||||
JOINING_TYPE_X, /* 079B */
|
||||
JOINING_TYPE_X, /* 079C */
|
||||
JOINING_TYPE_X, /* 079D */
|
||||
JOINING_TYPE_X, /* 079E */
|
||||
JOINING_TYPE_X, /* 079F */
|
||||
JOINING_TYPE_X, /* 07A0 */
|
||||
JOINING_TYPE_X, /* 07A1 */
|
||||
JOINING_TYPE_X, /* 07A2 */
|
||||
JOINING_TYPE_X, /* 07A3 */
|
||||
JOINING_TYPE_X, /* 07A4 */
|
||||
JOINING_TYPE_X, /* 07A5 */
|
||||
JOINING_TYPE_X, /* 07A6 */
|
||||
JOINING_TYPE_X, /* 07A7 */
|
||||
JOINING_TYPE_X, /* 07A8 */
|
||||
JOINING_TYPE_X, /* 07A9 */
|
||||
JOINING_TYPE_X, /* 07AA */
|
||||
JOINING_TYPE_X, /* 07AB */
|
||||
JOINING_TYPE_X, /* 07AC */
|
||||
JOINING_TYPE_X, /* 07AD */
|
||||
JOINING_TYPE_X, /* 07AE */
|
||||
JOINING_TYPE_X, /* 07AF */
|
||||
JOINING_TYPE_X, /* 07B0 */
|
||||
JOINING_TYPE_X, /* 07B1 */
|
||||
JOINING_TYPE_X, /* 07B2 */
|
||||
JOINING_TYPE_X, /* 07B3 */
|
||||
JOINING_TYPE_X, /* 07B4 */
|
||||
JOINING_TYPE_X, /* 07B5 */
|
||||
JOINING_TYPE_X, /* 07B6 */
|
||||
JOINING_TYPE_X, /* 07B7 */
|
||||
JOINING_TYPE_X, /* 07B8 */
|
||||
JOINING_TYPE_X, /* 07B9 */
|
||||
JOINING_TYPE_X, /* 07BA */
|
||||
JOINING_TYPE_X, /* 07BB */
|
||||
JOINING_TYPE_X, /* 07BC */
|
||||
JOINING_TYPE_X, /* 07BD */
|
||||
JOINING_TYPE_X, /* 07BE */
|
||||
JOINING_TYPE_X, /* 07BF */
|
||||
JOINING_TYPE_X, /* 07C0 */
|
||||
JOINING_TYPE_X, /* 07C1 */
|
||||
JOINING_TYPE_X, /* 07C2 */
|
||||
JOINING_TYPE_X, /* 07C3 */
|
||||
JOINING_TYPE_X, /* 07C4 */
|
||||
JOINING_TYPE_X, /* 07C5 */
|
||||
JOINING_TYPE_X, /* 07C6 */
|
||||
JOINING_TYPE_X, /* 07C7 */
|
||||
JOINING_TYPE_X, /* 07C8 */
|
||||
JOINING_TYPE_X, /* 07C9 */
|
||||
JOINING_TYPE_D, /* 07CA; NKO A; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07CB; NKO EE; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07CC; NKO I; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07CD; NKO E; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07CE; NKO U; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07CF; NKO OO; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07D0; NKO O; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07D1; NKO DAGBASINNA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07D2; NKO N; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07D3; NKO BA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07D4; NKO PA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07D5; NKO TA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07D6; NKO JA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07D7; NKO CHA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07D8; NKO DA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07D9; NKO RA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07DA; NKO RRA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07DB; NKO SA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07DC; NKO GBA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07DD; NKO FA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07DE; NKO KA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07DF; NKO LA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07E0; NKO NA WOLOSO; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07E1; NKO MA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07E2; NKO NYA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07E3; NKO NA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07E4; NKO HA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07E5; NKO WA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07E6; NKO YA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07E7; NKO NYA WOLOSO; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07E8; NKO JONA JA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07E9; NKO JONA CHA; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 07EA; NKO JONA RA; D; No_Joining_Group */
|
||||
JOINING_TYPE_X, /* 07EB */
|
||||
JOINING_TYPE_X, /* 07EC */
|
||||
JOINING_TYPE_X, /* 07ED */
|
||||
JOINING_TYPE_X, /* 07EE */
|
||||
JOINING_TYPE_X, /* 07EF */
|
||||
JOINING_TYPE_X, /* 07F0 */
|
||||
JOINING_TYPE_X, /* 07F1 */
|
||||
JOINING_TYPE_X, /* 07F2 */
|
||||
JOINING_TYPE_X, /* 07F3 */
|
||||
JOINING_TYPE_X, /* 07F4 */
|
||||
JOINING_TYPE_X, /* 07F5 */
|
||||
JOINING_TYPE_X, /* 07F6 */
|
||||
JOINING_TYPE_X, /* 07F7 */
|
||||
JOINING_TYPE_X, /* 07F8 */
|
||||
JOINING_TYPE_X, /* 07F9 */
|
||||
JOINING_TYPE_C, /* 07FA; NKO LAJANYALAN; C; No_Joining_Group */
|
||||
|
||||
/* Mandaic Characters */
|
||||
|
||||
JOINING_TYPE_X, /* 07FB */
|
||||
JOINING_TYPE_X, /* 07FC */
|
||||
JOINING_TYPE_X, /* 07FD */
|
||||
JOINING_TYPE_X, /* 07FE */
|
||||
JOINING_TYPE_X, /* 07FF */
|
||||
JOINING_TYPE_X, /* 0800 */
|
||||
JOINING_TYPE_X, /* 0801 */
|
||||
JOINING_TYPE_X, /* 0802 */
|
||||
JOINING_TYPE_X, /* 0803 */
|
||||
JOINING_TYPE_X, /* 0804 */
|
||||
JOINING_TYPE_X, /* 0805 */
|
||||
JOINING_TYPE_X, /* 0806 */
|
||||
JOINING_TYPE_X, /* 0807 */
|
||||
JOINING_TYPE_X, /* 0808 */
|
||||
JOINING_TYPE_X, /* 0809 */
|
||||
JOINING_TYPE_X, /* 080A */
|
||||
JOINING_TYPE_X, /* 080B */
|
||||
JOINING_TYPE_X, /* 080C */
|
||||
JOINING_TYPE_X, /* 080D */
|
||||
JOINING_TYPE_X, /* 080E */
|
||||
JOINING_TYPE_X, /* 080F */
|
||||
JOINING_TYPE_X, /* 0810 */
|
||||
JOINING_TYPE_X, /* 0811 */
|
||||
JOINING_TYPE_X, /* 0812 */
|
||||
JOINING_TYPE_X, /* 0813 */
|
||||
JOINING_TYPE_X, /* 0814 */
|
||||
JOINING_TYPE_X, /* 0815 */
|
||||
JOINING_TYPE_X, /* 0816 */
|
||||
JOINING_TYPE_X, /* 0817 */
|
||||
JOINING_TYPE_X, /* 0818 */
|
||||
JOINING_TYPE_X, /* 0819 */
|
||||
JOINING_TYPE_X, /* 081A */
|
||||
JOINING_TYPE_X, /* 081B */
|
||||
JOINING_TYPE_X, /* 081C */
|
||||
JOINING_TYPE_X, /* 081D */
|
||||
JOINING_TYPE_X, /* 081E */
|
||||
JOINING_TYPE_X, /* 081F */
|
||||
JOINING_TYPE_X, /* 0820 */
|
||||
JOINING_TYPE_X, /* 0821 */
|
||||
JOINING_TYPE_X, /* 0822 */
|
||||
JOINING_TYPE_X, /* 0823 */
|
||||
JOINING_TYPE_X, /* 0824 */
|
||||
JOINING_TYPE_X, /* 0825 */
|
||||
JOINING_TYPE_X, /* 0826 */
|
||||
JOINING_TYPE_X, /* 0827 */
|
||||
JOINING_TYPE_X, /* 0828 */
|
||||
JOINING_TYPE_X, /* 0829 */
|
||||
JOINING_TYPE_X, /* 082A */
|
||||
JOINING_TYPE_X, /* 082B */
|
||||
JOINING_TYPE_X, /* 082C */
|
||||
JOINING_TYPE_X, /* 082D */
|
||||
JOINING_TYPE_X, /* 082E */
|
||||
JOINING_TYPE_X, /* 082F */
|
||||
JOINING_TYPE_X, /* 0830 */
|
||||
JOINING_TYPE_X, /* 0831 */
|
||||
JOINING_TYPE_X, /* 0832 */
|
||||
JOINING_TYPE_X, /* 0833 */
|
||||
JOINING_TYPE_X, /* 0834 */
|
||||
JOINING_TYPE_X, /* 0835 */
|
||||
JOINING_TYPE_X, /* 0836 */
|
||||
JOINING_TYPE_X, /* 0837 */
|
||||
JOINING_TYPE_X, /* 0838 */
|
||||
JOINING_TYPE_X, /* 0839 */
|
||||
JOINING_TYPE_X, /* 083A */
|
||||
JOINING_TYPE_X, /* 083B */
|
||||
JOINING_TYPE_X, /* 083C */
|
||||
JOINING_TYPE_X, /* 083D */
|
||||
JOINING_TYPE_X, /* 083E */
|
||||
JOINING_TYPE_X, /* 083F */
|
||||
JOINING_TYPE_R, /* 0840; MANDAIC HALQA; R; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0841; MANDAIC AB; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0842; MANDAIC AG; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0843; MANDAIC AD; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0844; MANDAIC AH; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0845; MANDAIC USHENNA; D; No_Joining_Group */
|
||||
JOINING_TYPE_R, /* 0846; MANDAIC AZ; R; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0847; MANDAIC IT; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0848; MANDAIC ATT; D; No_Joining_Group */
|
||||
JOINING_TYPE_R, /* 0849; MANDAIC AKSA; R; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 084A; MANDAIC AK; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 084B; MANDAIC AL; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 084C; MANDAIC AM; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 084D; MANDAIC AN; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 084E; MANDAIC AS; D; No_Joining_Group */
|
||||
JOINING_TYPE_R, /* 084F; MANDAIC IN; R; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0850; MANDAIC AP; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0851; MANDAIC ASZ; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0852; MANDAIC AQ; D; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0853; MANDAIC AR; D; No_Joining_Group */
|
||||
JOINING_TYPE_R, /* 0854; MANDAIC ASH; R; No_Joining_Group */
|
||||
JOINING_TYPE_D, /* 0855; MANDAIC AT; D; No_Joining_Group */
|
||||
JOINING_TYPE_U, /* 0856; MANDAIC DUSHENNA; U; No_Joining_Group */
|
||||
JOINING_TYPE_U, /* 0857; MANDAIC KAD; U; No_Joining_Group */
|
||||
JOINING_TYPE_U, /* 0858; MANDAIC AIN; U; No_Joining_Group */
|
||||
|
||||
/* Arabic Extended-A Characters */
|
||||
|
||||
JOINING_TYPE_X, /* 0859 */
|
||||
JOINING_TYPE_X, /* 085A */
|
||||
JOINING_TYPE_X, /* 085B */
|
||||
JOINING_TYPE_X, /* 085C */
|
||||
JOINING_TYPE_X, /* 085D */
|
||||
JOINING_TYPE_X, /* 085E */
|
||||
JOINING_TYPE_X, /* 085F */
|
||||
JOINING_TYPE_X, /* 0860 */
|
||||
JOINING_TYPE_X, /* 0861 */
|
||||
JOINING_TYPE_X, /* 0862 */
|
||||
JOINING_TYPE_X, /* 0863 */
|
||||
JOINING_TYPE_X, /* 0864 */
|
||||
JOINING_TYPE_X, /* 0865 */
|
||||
JOINING_TYPE_X, /* 0866 */
|
||||
JOINING_TYPE_X, /* 0867 */
|
||||
JOINING_TYPE_X, /* 0868 */
|
||||
JOINING_TYPE_X, /* 0869 */
|
||||
JOINING_TYPE_X, /* 086A */
|
||||
JOINING_TYPE_X, /* 086B */
|
||||
JOINING_TYPE_X, /* 086C */
|
||||
JOINING_TYPE_X, /* 086D */
|
||||
JOINING_TYPE_X, /* 086E */
|
||||
JOINING_TYPE_X, /* 086F */
|
||||
JOINING_TYPE_X, /* 0870 */
|
||||
JOINING_TYPE_X, /* 0871 */
|
||||
JOINING_TYPE_X, /* 0872 */
|
||||
JOINING_TYPE_X, /* 0873 */
|
||||
JOINING_TYPE_X, /* 0874 */
|
||||
JOINING_TYPE_X, /* 0875 */
|
||||
JOINING_TYPE_X, /* 0876 */
|
||||
JOINING_TYPE_X, /* 0877 */
|
||||
JOINING_TYPE_X, /* 0878 */
|
||||
JOINING_TYPE_X, /* 0879 */
|
||||
JOINING_TYPE_X, /* 087A */
|
||||
JOINING_TYPE_X, /* 087B */
|
||||
JOINING_TYPE_X, /* 087C */
|
||||
JOINING_TYPE_X, /* 087D */
|
||||
JOINING_TYPE_X, /* 087E */
|
||||
JOINING_TYPE_X, /* 087F */
|
||||
JOINING_TYPE_X, /* 0880 */
|
||||
JOINING_TYPE_X, /* 0881 */
|
||||
JOINING_TYPE_X, /* 0882 */
|
||||
JOINING_TYPE_X, /* 0883 */
|
||||
JOINING_TYPE_X, /* 0884 */
|
||||
JOINING_TYPE_X, /* 0885 */
|
||||
JOINING_TYPE_X, /* 0886 */
|
||||
JOINING_TYPE_X, /* 0887 */
|
||||
JOINING_TYPE_X, /* 0888 */
|
||||
JOINING_TYPE_X, /* 0889 */
|
||||
JOINING_TYPE_X, /* 088A */
|
||||
JOINING_TYPE_X, /* 088B */
|
||||
JOINING_TYPE_X, /* 088C */
|
||||
JOINING_TYPE_X, /* 088D */
|
||||
JOINING_TYPE_X, /* 088E */
|
||||
JOINING_TYPE_X, /* 088F */
|
||||
JOINING_TYPE_X, /* 0890 */
|
||||
JOINING_TYPE_X, /* 0891 */
|
||||
JOINING_TYPE_X, /* 0892 */
|
||||
JOINING_TYPE_X, /* 0893 */
|
||||
JOINING_TYPE_X, /* 0894 */
|
||||
JOINING_TYPE_X, /* 0895 */
|
||||
JOINING_TYPE_X, /* 0896 */
|
||||
JOINING_TYPE_X, /* 0897 */
|
||||
JOINING_TYPE_X, /* 0898 */
|
||||
JOINING_TYPE_X, /* 0899 */
|
||||
JOINING_TYPE_X, /* 089A */
|
||||
JOINING_TYPE_X, /* 089B */
|
||||
JOINING_TYPE_X, /* 089C */
|
||||
JOINING_TYPE_X, /* 089D */
|
||||
JOINING_TYPE_X, /* 089E */
|
||||
JOINING_TYPE_X, /* 089F */
|
||||
JOINING_TYPE_D, /* 08A0; DOTLESS BEH WITH V BELOW; D; BEH */
|
||||
JOINING_TYPE_X, /* 08A1 */
|
||||
JOINING_TYPE_D, /* 08A2; HAH WITH DOT BELOW AND 2 DOTS ABOVE; D; HAH */
|
||||
JOINING_TYPE_D, /* 08A3; TAH WITH 2 DOTS ABOVE; D; TAH */
|
||||
JOINING_TYPE_D, /* 08A4; DOTLESS FEH WITH DOT BELOW AND 3 DOTS ABOVE; D; FEH */
|
||||
JOINING_TYPE_D, /* 08A5; QAF WITH DOT BELOW; D; QAF */
|
||||
JOINING_TYPE_D, /* 08A6; LAM WITH DOUBLE BAR; D; LAM */
|
||||
JOINING_TYPE_D, /* 08A7; MEEM WITH 3 DOTS ABOVE; D; MEEM */
|
||||
JOINING_TYPE_D, /* 08A8; YEH WITH HAMZA ABOVE; D; YEH */
|
||||
JOINING_TYPE_D, /* 08A9; YEH WITH DOT ABOVE; D; YEH */
|
||||
JOINING_TYPE_R, /* 08AA; REH WITH LOOP; R; REH */
|
||||
JOINING_TYPE_R, /* 08AB; WAW WITH DOT WITHIN; R; WAW */
|
||||
JOINING_TYPE_R, /* 08AC; ROHINGYA YEH; R; ROHINGYA YEH */
|
||||
|
||||
};
|
||||
|
||||
#define JOINING_TABLE_FIRST 0x0600
|
||||
#define JOINING_TABLE_LAST 0x08AC
|
||||
|
||||
|
||||
static const uint16_t shaping_table[][4] =
|
||||
{
|
||||
{0x0000, 0x0000, 0x0000, 0xFE80}, /* U+0621 ARABIC LETTER HAMZA ISOLATED FORM */
|
||||
{0x0000, 0x0000, 0xFE82, 0xFE81}, /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */
|
||||
{0x0000, 0x0000, 0xFE84, 0xFE83}, /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */
|
||||
{0x0000, 0x0000, 0xFE86, 0xFE85}, /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */
|
||||
{0x0000, 0x0000, 0xFE88, 0xFE87}, /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */
|
||||
{0xFE8B, 0xFE8C, 0xFE8A, 0xFE89}, /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */
|
||||
{0x0000, 0x0000, 0xFE8E, 0xFE8D}, /* U+0627 ARABIC LETTER ALEF */
|
||||
{0xFE91, 0xFE92, 0xFE90, 0xFE8F}, /* U+0628 ARABIC LETTER BEH */
|
||||
{0x0000, 0x0000, 0xFE94, 0xFE93}, /* U+0629 ARABIC LETTER TEH MARBUTA */
|
||||
{0xFE97, 0xFE98, 0xFE96, 0xFE95}, /* U+062A ARABIC LETTER TEH */
|
||||
{0xFE9B, 0xFE9C, 0xFE9A, 0xFE99}, /* U+062B ARABIC LETTER THEH */
|
||||
{0xFE9F, 0xFEA0, 0xFE9E, 0xFE9D}, /* U+062C ARABIC LETTER JEEM */
|
||||
{0xFEA3, 0xFEA4, 0xFEA2, 0xFEA1}, /* U+062D ARABIC LETTER HAH */
|
||||
{0xFEA7, 0xFEA8, 0xFEA6, 0xFEA5}, /* U+062E ARABIC LETTER KHAH */
|
||||
{0x0000, 0x0000, 0xFEAA, 0xFEA9}, /* U+062F ARABIC LETTER DAL */
|
||||
{0x0000, 0x0000, 0xFEAC, 0xFEAB}, /* U+0630 ARABIC LETTER THAL */
|
||||
{0x0000, 0x0000, 0xFEAE, 0xFEAD}, /* U+0631 ARABIC LETTER REH */
|
||||
{0x0000, 0x0000, 0xFEB0, 0xFEAF}, /* U+0632 ARABIC LETTER ZAIN */
|
||||
{0xFEB3, 0xFEB4, 0xFEB2, 0xFEB1}, /* U+0633 ARABIC LETTER SEEN */
|
||||
{0xFEB7, 0xFEB8, 0xFEB6, 0xFEB5}, /* U+0634 ARABIC LETTER SHEEN */
|
||||
{0xFEBB, 0xFEBC, 0xFEBA, 0xFEB9}, /* U+0635 ARABIC LETTER SAD */
|
||||
{0xFEBF, 0xFEC0, 0xFEBE, 0xFEBD}, /* U+0636 ARABIC LETTER DAD */
|
||||
{0xFEC3, 0xFEC4, 0xFEC2, 0xFEC1}, /* U+0637 ARABIC LETTER TAH */
|
||||
{0xFEC7, 0xFEC8, 0xFEC6, 0xFEC5}, /* U+0638 ARABIC LETTER ZAH */
|
||||
{0xFECB, 0xFECC, 0xFECA, 0xFEC9}, /* U+0639 ARABIC LETTER AIN */
|
||||
{0xFECF, 0xFED0, 0xFECE, 0xFECD}, /* U+063A ARABIC LETTER GHAIN */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+063B */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+063C */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+063D */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+063E */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+063F */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0640 */
|
||||
{0xFED3, 0xFED4, 0xFED2, 0xFED1}, /* U+0641 ARABIC LETTER FEH */
|
||||
{0xFED7, 0xFED8, 0xFED6, 0xFED5}, /* U+0642 ARABIC LETTER QAF */
|
||||
{0xFEDB, 0xFEDC, 0xFEDA, 0xFED9}, /* U+0643 ARABIC LETTER KAF */
|
||||
{0xFEDF, 0xFEE0, 0xFEDE, 0xFEDD}, /* U+0644 ARABIC LETTER LAM */
|
||||
{0xFEE3, 0xFEE4, 0xFEE2, 0xFEE1}, /* U+0645 ARABIC LETTER MEEM */
|
||||
{0xFEE7, 0xFEE8, 0xFEE6, 0xFEE5}, /* U+0646 ARABIC LETTER NOON */
|
||||
{0xFEEB, 0xFEEC, 0xFEEA, 0xFEE9}, /* U+0647 ARABIC LETTER HEH */
|
||||
{0x0000, 0x0000, 0xFEEE, 0xFEED}, /* U+0648 ARABIC LETTER WAW */
|
||||
{0xFBE8, 0xFBE9, 0xFEF0, 0xFEEF}, /* U+0649 ARABIC LETTER */
|
||||
{0xFEF3, 0xFEF4, 0xFEF2, 0xFEF1}, /* U+064A ARABIC LETTER YEH */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+064B */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+064C */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+064D */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+064E */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+064F */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0650 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0651 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0652 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0653 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0654 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0655 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0656 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0657 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0658 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0659 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+065A */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+065B */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+065C */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+065D */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+065E */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+065F */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0660 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0661 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0662 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0663 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0664 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0665 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0666 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0667 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0668 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0669 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+066A */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+066B */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+066C */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+066D */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+066E */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+066F */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0670 */
|
||||
{0x0000, 0x0000, 0xFB51, 0xFB50}, /* U+0671 ARABIC LETTER ALEF WASLA */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0672 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0673 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0674 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0675 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0676 */
|
||||
{0x0000, 0x0000, 0x0000, 0xFBDD}, /* U+0677 ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0678 */
|
||||
{0xFB68, 0xFB69, 0xFB67, 0xFB66}, /* U+0679 ARABIC LETTER TTEH */
|
||||
{0xFB60, 0xFB61, 0xFB5F, 0xFB5E}, /* U+067A ARABIC LETTER TTEHEH */
|
||||
{0xFB54, 0xFB55, 0xFB53, 0xFB52}, /* U+067B ARABIC LETTER BEEH */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+067C */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+067D */
|
||||
{0xFB58, 0xFB59, 0xFB57, 0xFB56}, /* U+067E ARABIC LETTER PEH */
|
||||
{0xFB64, 0xFB65, 0xFB63, 0xFB62}, /* U+067F ARABIC LETTER TEHEH */
|
||||
{0xFB5C, 0xFB5D, 0xFB5B, 0xFB5A}, /* U+0680 ARABIC LETTER BEHEH */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0681 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0682 */
|
||||
{0xFB78, 0xFB79, 0xFB77, 0xFB76}, /* U+0683 ARABIC LETTER NYEH */
|
||||
{0xFB74, 0xFB75, 0xFB73, 0xFB72}, /* U+0684 ARABIC LETTER DYEH */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0685 */
|
||||
{0xFB7C, 0xFB7D, 0xFB7B, 0xFB7A}, /* U+0686 ARABIC LETTER TCHEH */
|
||||
{0xFB80, 0xFB81, 0xFB7F, 0xFB7E}, /* U+0687 ARABIC LETTER TCHEHEH */
|
||||
{0x0000, 0x0000, 0xFB89, 0xFB88}, /* U+0688 ARABIC LETTER DDAL */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0689 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+068A */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+068B */
|
||||
{0x0000, 0x0000, 0xFB85, 0xFB84}, /* U+068C ARABIC LETTER DAHAL */
|
||||
{0x0000, 0x0000, 0xFB83, 0xFB82}, /* U+068D ARABIC LETTER DDAHAL */
|
||||
{0x0000, 0x0000, 0xFB87, 0xFB86}, /* U+068E ARABIC LETTER DUL */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+068F */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0690 */
|
||||
{0x0000, 0x0000, 0xFB8D, 0xFB8C}, /* U+0691 ARABIC LETTER RREH */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0692 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0693 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0694 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0695 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0696 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0697 */
|
||||
{0x0000, 0x0000, 0xFB8B, 0xFB8A}, /* U+0698 ARABIC LETTER JEH */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+0699 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+069A */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+069B */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+069C */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+069D */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+069E */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+069F */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A0 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A1 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A2 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A3 */
|
||||
{0xFB6C, 0xFB6D, 0xFB6B, 0xFB6A}, /* U+06A4 ARABIC LETTER VEH */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A5 */
|
||||
{0xFB70, 0xFB71, 0xFB6F, 0xFB6E}, /* U+06A6 ARABIC LETTER PEHEH */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A7 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06A8 */
|
||||
{0xFB90, 0xFB91, 0xFB8F, 0xFB8E}, /* U+06A9 ARABIC LETTER KEHEH */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06AA */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06AB */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06AC */
|
||||
{0xFBD5, 0xFBD6, 0xFBD4, 0xFBD3}, /* U+06AD ARABIC LETTER NG */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06AE */
|
||||
{0xFB94, 0xFB95, 0xFB93, 0xFB92}, /* U+06AF ARABIC LETTER GAF */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B0 */
|
||||
{0xFB9C, 0xFB9D, 0xFB9B, 0xFB9A}, /* U+06B1 ARABIC LETTER NGOEH */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B2 */
|
||||
{0xFB98, 0xFB99, 0xFB97, 0xFB96}, /* U+06B3 ARABIC LETTER GUEH */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B4 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B5 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B6 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B7 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B8 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06B9 */
|
||||
{0x0000, 0x0000, 0xFB9F, 0xFB9E}, /* U+06BA ARABIC LETTER NOON GHUNNA */
|
||||
{0xFBA2, 0xFBA3, 0xFBA1, 0xFBA0}, /* U+06BB ARABIC LETTER RNOON */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06BC */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06BD */
|
||||
{0xFBAC, 0xFBAD, 0xFBAB, 0xFBAA}, /* U+06BE ARABIC LETTER HEH DOACHASHMEE */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06BF */
|
||||
{0x0000, 0x0000, 0xFBA5, 0xFBA4}, /* U+06C0 ARABIC LETTER HEH WITH YEH ABOVE */
|
||||
{0xFBA8, 0xFBA9, 0xFBA7, 0xFBA6}, /* U+06C1 ARABIC LETTER HEH GOAL */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06C2 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06C3 */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06C4 */
|
||||
{0x0000, 0x0000, 0xFBE1, 0xFBE0}, /* U+06C5 ARABIC LETTER KIRGHIZ OE */
|
||||
{0x0000, 0x0000, 0xFBDA, 0xFBD9}, /* U+06C6 ARABIC LETTER OE */
|
||||
{0x0000, 0x0000, 0xFBD8, 0xFBD7}, /* U+06C7 ARABIC LETTER U */
|
||||
{0x0000, 0x0000, 0xFBDC, 0xFBDB}, /* U+06C8 ARABIC LETTER YU */
|
||||
{0x0000, 0x0000, 0xFBE3, 0xFBE2}, /* U+06C9 ARABIC LETTER KIRGHIZ YU */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06CA */
|
||||
{0x0000, 0x0000, 0xFBDF, 0xFBDE}, /* U+06CB ARABIC LETTER VE */
|
||||
{0xFBFE, 0xFBFF, 0xFBFD, 0xFBFC}, /* U+06CC ARABIC LETTER FARSI YEH */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06CD */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06CE */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06CF */
|
||||
{0xFBE6, 0xFBE7, 0xFBE5, 0xFBE4}, /* U+06D0 ARABIC LETTER E */
|
||||
{0x0000, 0x0000, 0x0000, 0x0000}, /* U+06D1 */
|
||||
{0x0000, 0x0000, 0xFBAF, 0xFBAE}, /* U+06D2 ARABIC LETTER YEH BARREE */
|
||||
{0x0000, 0x0000, 0xFBB1, 0xFBB0}, /* U+06D3 ARABIC LETTER YEH BARREE WITH HAMZA ABOVE */
|
||||
};
|
||||
|
||||
#define SHAPING_TABLE_FIRST 0x0621
|
||||
#define SHAPING_TABLE_LAST 0x06D3
|
||||
|
||||
|
||||
static const struct ligature_set_t {
|
||||
uint16_t first;
|
||||
struct ligature_pairs_t {
|
||||
uint16_t second;
|
||||
uint16_t ligature;
|
||||
} ligatures[4];
|
||||
} ligature_table[] =
|
||||
{
|
||||
{ 0xFEDF, {
|
||||
{ 0xFE88, 0xFEF9 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
|
||||
{ 0xFE82, 0xFEF5 }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
|
||||
{ 0xFE8E, 0xFEFB }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
|
||||
{ 0xFE84, 0xFEF7 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
|
||||
}},
|
||||
{ 0xFEE0, {
|
||||
{ 0xFE88, 0xFEFA }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
|
||||
{ 0xFE82, 0xFEF6 }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
|
||||
{ 0xFE8E, 0xFEFC }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
|
||||
{ 0xFE84, 0xFEF8 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
|
||||
}},
|
||||
};
|
||||
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */
|
||||
|
||||
/* == End of generated table == */
|
356
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
vendored
Normal file
356
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
vendored
Normal file
@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright © 2010,2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-complex-private.hh"
|
||||
#include "hb-ot-shape-private.hh"
|
||||
|
||||
|
||||
/* buffer var allocations */
|
||||
#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
|
||||
|
||||
|
||||
/*
|
||||
* Bits used in the joining tables
|
||||
*/
|
||||
enum {
|
||||
JOINING_TYPE_U = 0,
|
||||
JOINING_TYPE_L = 1,
|
||||
JOINING_TYPE_R = 2,
|
||||
JOINING_TYPE_D = 3,
|
||||
JOINING_TYPE_C = JOINING_TYPE_D,
|
||||
JOINING_GROUP_ALAPH = 4,
|
||||
JOINING_GROUP_DALATH_RISH = 5,
|
||||
NUM_STATE_MACHINE_COLS = 6,
|
||||
|
||||
JOINING_TYPE_T = 7,
|
||||
JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Joining types:
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-complex-arabic-table.hh"
|
||||
|
||||
static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat)
|
||||
{
|
||||
if (likely (hb_in_range<hb_codepoint_t> (u, JOINING_TABLE_FIRST, JOINING_TABLE_LAST))) {
|
||||
unsigned int j_type = joining_table[u - JOINING_TABLE_FIRST];
|
||||
if (likely (j_type != JOINING_TYPE_X))
|
||||
return j_type;
|
||||
}
|
||||
|
||||
/* Mongolian joining data is not in ArabicJoining.txt yet. */
|
||||
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1800, 0x18AF)))
|
||||
{
|
||||
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1880, 0x1886)))
|
||||
return JOINING_TYPE_U;
|
||||
|
||||
/* All letters, SIBE SYLLABLE BOUNDARY MARKER, and NIRUGU are D */
|
||||
if ((FLAG(gen_cat) & (FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) |
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER)))
|
||||
|| u == 0x1807 || u == 0x180A)
|
||||
return JOINING_TYPE_D;
|
||||
}
|
||||
|
||||
/* 'Phags-pa joining data is not in ArabicJoining.txt yet. */
|
||||
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xA840, 0xA872)))
|
||||
{
|
||||
if (unlikely (u == 0xA872))
|
||||
return JOINING_TYPE_L;
|
||||
|
||||
return JOINING_TYPE_D;
|
||||
}
|
||||
|
||||
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x200C, 0x200D)))
|
||||
{
|
||||
return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C;
|
||||
}
|
||||
|
||||
return (FLAG(gen_cat) & (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT))) ?
|
||||
JOINING_TYPE_T : JOINING_TYPE_U;
|
||||
}
|
||||
|
||||
static const hb_tag_t arabic_features[] =
|
||||
{
|
||||
HB_TAG('i','n','i','t'),
|
||||
HB_TAG('m','e','d','i'),
|
||||
HB_TAG('f','i','n','a'),
|
||||
HB_TAG('i','s','o','l'),
|
||||
/* Syriac */
|
||||
HB_TAG('m','e','d','2'),
|
||||
HB_TAG('f','i','n','2'),
|
||||
HB_TAG('f','i','n','3'),
|
||||
HB_TAG_NONE
|
||||
};
|
||||
|
||||
|
||||
/* Same order as the feature array */
|
||||
enum {
|
||||
INIT,
|
||||
MEDI,
|
||||
FINA,
|
||||
ISOL,
|
||||
|
||||
/* Syriac */
|
||||
MED2,
|
||||
FIN2,
|
||||
FIN3,
|
||||
|
||||
NONE,
|
||||
|
||||
ARABIC_NUM_FEATURES = NONE
|
||||
};
|
||||
|
||||
static const struct arabic_state_table_entry {
|
||||
uint8_t prev_action;
|
||||
uint8_t curr_action;
|
||||
uint16_t next_state;
|
||||
} arabic_state_table[][NUM_STATE_MACHINE_COLS] =
|
||||
{
|
||||
/* jt_U, jt_L, jt_R, jt_D, jg_ALAPH, jg_DALATH_RISH */
|
||||
|
||||
/* State 0: prev was U, not willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, },
|
||||
|
||||
/* State 1: prev was R or ISOL/ALAPH, not willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, },
|
||||
|
||||
/* State 2: prev was D/L in ISOL form, willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, },
|
||||
|
||||
/* State 3: prev was D in FINA form, willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, },
|
||||
|
||||
/* State 4: prev was FINA ALAPH, not willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, },
|
||||
|
||||
/* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, },
|
||||
|
||||
/* State 6: prev was DALATH/RISH, not willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, }
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
static void
|
||||
collect_features_arabic (hb_ot_shape_planner_t *plan)
|
||||
{
|
||||
hb_ot_map_builder_t *map = &plan->map;
|
||||
|
||||
/* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init together,
|
||||
* then rlig and calt each in their own stage. This makes IranNastaliq's ALLAH
|
||||
* ligature work correctly. It's unfortunate though...
|
||||
*
|
||||
* This also makes Arial Bold in Windows7 work. See:
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=644184
|
||||
*
|
||||
* TODO: Add test cases for these two.
|
||||
*/
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
|
||||
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
|
||||
|
||||
map->add_gsub_pause (NULL);
|
||||
|
||||
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
|
||||
map->add_feature (arabic_features[i], 1, i < 4 ? F_HAS_FALLBACK : F_NONE); /* The first four features have fallback. */
|
||||
|
||||
map->add_gsub_pause (NULL);
|
||||
|
||||
map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
|
||||
map->add_gsub_pause (arabic_fallback_shape);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
|
||||
map->add_gsub_pause (NULL);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('c','s','w','h'));
|
||||
map->add_global_bool_feature (HB_TAG('m','s','e','t'));
|
||||
}
|
||||
|
||||
#include "hb-ot-shape-complex-arabic-fallback.hh"
|
||||
|
||||
struct arabic_shape_plan_t
|
||||
{
|
||||
ASSERT_POD ();
|
||||
|
||||
/* The "+ 1" in the next array is to accommodate for the "NONE" command,
|
||||
* which is not an OpenType feature, but this simplifies the code by not
|
||||
* having to do a "if (... < NONE) ..." and just rely on the fact that
|
||||
* mask_array[NONE] == 0. */
|
||||
hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1];
|
||||
|
||||
bool do_fallback;
|
||||
arabic_fallback_plan_t *fallback_plan;
|
||||
};
|
||||
|
||||
static void *
|
||||
data_create_arabic (const hb_ot_shape_plan_t *plan)
|
||||
{
|
||||
arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof (arabic_shape_plan_t));
|
||||
if (unlikely (!arabic_plan))
|
||||
return NULL;
|
||||
|
||||
arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC;
|
||||
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) {
|
||||
arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]);
|
||||
if (i < 4)
|
||||
arabic_plan->do_fallback = arabic_plan->do_fallback && plan->map.needs_fallback (arabic_features[i]);
|
||||
}
|
||||
|
||||
return arabic_plan;
|
||||
}
|
||||
|
||||
static void
|
||||
data_destroy_arabic (void *data)
|
||||
{
|
||||
arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) data;
|
||||
|
||||
arabic_fallback_plan_destroy (arabic_plan->fallback_plan);
|
||||
|
||||
free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
arabic_joining (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
unsigned int prev = (unsigned int) -1, state = 0;
|
||||
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action);
|
||||
|
||||
/* Check pre-context */
|
||||
if (!(buffer->flags & HB_BUFFER_FLAG_BOT))
|
||||
for (unsigned int i = 0; i < buffer->context_len[0]; i++)
|
||||
{
|
||||
unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i]));
|
||||
|
||||
if (unlikely (this_type == JOINING_TYPE_T))
|
||||
continue;
|
||||
|
||||
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
||||
state = entry->next_state;
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
unsigned int this_type = get_joining_type (buffer->info[i].codepoint, _hb_glyph_info_get_general_category (&buffer->info[i]));
|
||||
|
||||
if (unlikely (this_type == JOINING_TYPE_T)) {
|
||||
buffer->info[i].arabic_shaping_action() = NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
||||
|
||||
if (entry->prev_action != NONE && prev != (unsigned int) -1)
|
||||
buffer->info[prev].arabic_shaping_action() = entry->prev_action;
|
||||
|
||||
buffer->info[i].arabic_shaping_action() = entry->curr_action;
|
||||
|
||||
prev = i;
|
||||
state = entry->next_state;
|
||||
}
|
||||
|
||||
if (!(buffer->flags & HB_BUFFER_FLAG_EOT))
|
||||
for (unsigned int i = 0; i < buffer->context_len[1]; i++)
|
||||
{
|
||||
unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[1][i]));
|
||||
|
||||
if (unlikely (this_type == JOINING_TYPE_T))
|
||||
continue;
|
||||
|
||||
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
||||
if (entry->prev_action != NONE && prev != (unsigned int) -1)
|
||||
buffer->info[prev].arabic_shaping_action() = entry->prev_action;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_masks_arabic (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font HB_UNUSED)
|
||||
{
|
||||
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
|
||||
|
||||
arabic_joining (buffer);
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
buffer->info[i].mask |= arabic_plan->mask_array[buffer->info[i].arabic_shaping_action()];
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
|
||||
|
||||
if (!arabic_plan->do_fallback)
|
||||
return;
|
||||
|
||||
retry:
|
||||
arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) hb_atomic_ptr_get (&arabic_plan->fallback_plan);
|
||||
if (unlikely (!fallback_plan))
|
||||
{
|
||||
/* This sucks. We need a font to build the fallback plan... */
|
||||
fallback_plan = arabic_fallback_plan_create (plan, font);
|
||||
if (unlikely (!hb_atomic_ptr_cmpexch (&(const_cast<arabic_shape_plan_t *> (arabic_plan))->fallback_plan, NULL, fallback_plan))) {
|
||||
arabic_fallback_plan_destroy (fallback_plan);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
arabic_fallback_plan_shape (fallback_plan, font, buffer);
|
||||
}
|
||||
|
||||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
|
||||
{
|
||||
"arabic",
|
||||
collect_features_arabic,
|
||||
NULL, /* override_features */
|
||||
data_create_arabic,
|
||||
data_destroy_arabic,
|
||||
NULL, /* preprocess_text_arabic */
|
||||
NULL, /* normalization_preference */
|
||||
NULL, /* decompose */
|
||||
NULL, /* compose */
|
||||
setup_masks_arabic,
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
|
||||
true, /* fallback_position */
|
||||
};
|
220
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
vendored
Normal file
220
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
vendored
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright © 2010,2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-complex-private.hh"
|
||||
|
||||
|
||||
/* TODO Add kana, and other small shapers here */
|
||||
|
||||
|
||||
/* The default shaper *only* adds additional per-script features.*/
|
||||
|
||||
static const hb_tag_t hangul_features[] =
|
||||
{
|
||||
HB_TAG('l','j','m','o'),
|
||||
HB_TAG('v','j','m','o'),
|
||||
HB_TAG('t','j','m','o'),
|
||||
HB_TAG_NONE
|
||||
};
|
||||
|
||||
static const hb_tag_t tibetan_features[] =
|
||||
{
|
||||
HB_TAG('a','b','v','s'),
|
||||
HB_TAG('b','l','w','s'),
|
||||
HB_TAG('a','b','v','m'),
|
||||
HB_TAG('b','l','w','m'),
|
||||
HB_TAG_NONE
|
||||
};
|
||||
|
||||
static void
|
||||
collect_features_default (hb_ot_shape_planner_t *plan)
|
||||
{
|
||||
const hb_tag_t *script_features = NULL;
|
||||
|
||||
switch ((hb_tag_t) plan->props.script)
|
||||
{
|
||||
/* Unicode-1.1 additions */
|
||||
case HB_SCRIPT_HANGUL:
|
||||
script_features = hangul_features;
|
||||
break;
|
||||
|
||||
/* Unicode-2.0 additions */
|
||||
case HB_SCRIPT_TIBETAN:
|
||||
script_features = tibetan_features;
|
||||
break;
|
||||
}
|
||||
|
||||
for (; script_features && *script_features; script_features++)
|
||||
plan->map.add_global_bool_feature (*script_features);
|
||||
}
|
||||
|
||||
static hb_ot_shape_normalization_mode_t
|
||||
normalization_preference_default (const hb_segment_properties_t *props)
|
||||
{
|
||||
return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
|
||||
}
|
||||
|
||||
static bool
|
||||
compose_default (const hb_ot_shape_normalize_context_t *c,
|
||||
hb_codepoint_t a,
|
||||
hb_codepoint_t b,
|
||||
hb_codepoint_t *ab)
|
||||
{
|
||||
/* Hebrew presentation-form shaping.
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=728866
|
||||
* Hebrew presentation forms with dagesh, for characters 0x05D0..0x05EA;
|
||||
* Note that some letters do not have a dagesh presForm encoded.
|
||||
*/
|
||||
static const hb_codepoint_t sDageshForms[0x05EA - 0x05D0 + 1] = {
|
||||
0xFB30, /* ALEF */
|
||||
0xFB31, /* BET */
|
||||
0xFB32, /* GIMEL */
|
||||
0xFB33, /* DALET */
|
||||
0xFB34, /* HE */
|
||||
0xFB35, /* VAV */
|
||||
0xFB36, /* ZAYIN */
|
||||
0x0000, /* HET */
|
||||
0xFB38, /* TET */
|
||||
0xFB39, /* YOD */
|
||||
0xFB3A, /* FINAL KAF */
|
||||
0xFB3B, /* KAF */
|
||||
0xFB3C, /* LAMED */
|
||||
0x0000, /* FINAL MEM */
|
||||
0xFB3E, /* MEM */
|
||||
0x0000, /* FINAL NUN */
|
||||
0xFB40, /* NUN */
|
||||
0xFB41, /* SAMEKH */
|
||||
0x0000, /* AYIN */
|
||||
0xFB43, /* FINAL PE */
|
||||
0xFB44, /* PE */
|
||||
0x0000, /* FINAL TSADI */
|
||||
0xFB46, /* TSADI */
|
||||
0xFB47, /* QOF */
|
||||
0xFB48, /* RESH */
|
||||
0xFB49, /* SHIN */
|
||||
0xFB4A /* TAV */
|
||||
};
|
||||
|
||||
bool found = c->unicode->compose (a, b, ab);
|
||||
|
||||
if (!found && (b & ~0x7F) == 0x0580) {
|
||||
/* Special-case Hebrew presentation forms that are excluded from
|
||||
* standard normalization, but wanted for old fonts. */
|
||||
switch (b) {
|
||||
case 0x05B4: /* HIRIQ */
|
||||
if (a == 0x05D9) { /* YOD */
|
||||
*ab = 0xFB1D;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 0x05B7: /* patah */
|
||||
if (a == 0x05F2) { /* YIDDISH YOD YOD */
|
||||
*ab = 0xFB1F;
|
||||
found = true;
|
||||
} else if (a == 0x05D0) { /* ALEF */
|
||||
*ab = 0xFB2E;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 0x05B8: /* QAMATS */
|
||||
if (a == 0x05D0) { /* ALEF */
|
||||
*ab = 0xFB2F;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 0x05B9: /* HOLAM */
|
||||
if (a == 0x05D5) { /* VAV */
|
||||
*ab = 0xFB4B;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 0x05BC: /* DAGESH */
|
||||
if (a >= 0x05D0 && a <= 0x05EA) {
|
||||
*ab = sDageshForms[a - 0x05D0];
|
||||
found = (*ab != 0);
|
||||
} else if (a == 0xFB2A) { /* SHIN WITH SHIN DOT */
|
||||
*ab = 0xFB2C;
|
||||
found = true;
|
||||
} else if (a == 0xFB2B) { /* SHIN WITH SIN DOT */
|
||||
*ab = 0xFB2D;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 0x05BF: /* RAFE */
|
||||
switch (a) {
|
||||
case 0x05D1: /* BET */
|
||||
*ab = 0xFB4C;
|
||||
found = true;
|
||||
break;
|
||||
case 0x05DB: /* KAF */
|
||||
*ab = 0xFB4D;
|
||||
found = true;
|
||||
break;
|
||||
case 0x05E4: /* PE */
|
||||
*ab = 0xFB4E;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x05C1: /* SHIN DOT */
|
||||
if (a == 0x05E9) { /* SHIN */
|
||||
*ab = 0xFB2A;
|
||||
found = true;
|
||||
} else if (a == 0xFB49) { /* SHIN WITH DAGESH */
|
||||
*ab = 0xFB2C;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 0x05C2: /* SIN DOT */
|
||||
if (a == 0x05E9) { /* SHIN */
|
||||
*ab = 0xFB2B;
|
||||
found = true;
|
||||
} else if (a == 0xFB49) { /* SHIN WITH DAGESH */
|
||||
*ab = 0xFB2D;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
|
||||
{
|
||||
"default",
|
||||
collect_features_default,
|
||||
NULL, /* override_features */
|
||||
NULL, /* data_create */
|
||||
NULL, /* data_destroy */
|
||||
NULL, /* preprocess_text */
|
||||
normalization_preference_default,
|
||||
NULL, /* decompose */
|
||||
compose_default,
|
||||
NULL, /* setup_masks */
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
|
||||
true, /* fallback_position */
|
||||
};
|
1443
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
vendored
Normal file
1443
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
vendored
Normal file
File diff suppressed because it is too large
Load Diff
151
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
vendored
Normal file
151
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
#include "hb-ot-shape-complex-private.hh"
|
||||
#include "hb-ot-shape-private.hh" /* XXX Remove */
|
||||
|
||||
|
||||
#define INDIC_TABLE_ELEMENT_TYPE uint16_t
|
||||
|
||||
/* Cateories used in the OpenType spec:
|
||||
* https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx
|
||||
*/
|
||||
/* Note: This enum is duplicated in the -machine.rl source file.
|
||||
* Not sure how to avoid duplication. */
|
||||
enum indic_category_t {
|
||||
OT_X = 0,
|
||||
OT_C,
|
||||
OT_V,
|
||||
OT_N,
|
||||
OT_H,
|
||||
OT_ZWNJ,
|
||||
OT_ZWJ,
|
||||
OT_M,
|
||||
OT_SM,
|
||||
OT_VD,
|
||||
OT_A,
|
||||
OT_NBSP,
|
||||
OT_DOTTEDCIRCLE, /* Not in the spec, but special in Uniscribe. /Very very/ special! */
|
||||
OT_RS, /* Register Shifter, used in Khmer OT spec */
|
||||
OT_Coeng,
|
||||
OT_Repha,
|
||||
OT_Ra, /* Not explicitly listed in the OT spec, but used in the grammar. */
|
||||
OT_CM
|
||||
};
|
||||
|
||||
/* Visual positions in a syllable from left to right. */
|
||||
enum indic_position_t {
|
||||
POS_START,
|
||||
|
||||
POS_RA_TO_BECOME_REPH,
|
||||
POS_PRE_M,
|
||||
POS_PRE_C,
|
||||
|
||||
POS_BASE_C,
|
||||
POS_AFTER_MAIN,
|
||||
|
||||
POS_ABOVE_C,
|
||||
|
||||
POS_BEFORE_SUB,
|
||||
POS_BELOW_C,
|
||||
POS_AFTER_SUB,
|
||||
|
||||
POS_BEFORE_POST,
|
||||
POS_POST_C,
|
||||
POS_AFTER_POST,
|
||||
|
||||
POS_FINAL_C,
|
||||
POS_SMVD,
|
||||
|
||||
POS_END
|
||||
};
|
||||
|
||||
/* Categories used in IndicSyllabicCategory.txt from UCD. */
|
||||
enum indic_syllabic_category_t {
|
||||
INDIC_SYLLABIC_CATEGORY_OTHER = OT_X,
|
||||
|
||||
INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_X,
|
||||
INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_CM,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_CM,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_NBSP,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_C,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA = OT_Repha,
|
||||
INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X,
|
||||
INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N,
|
||||
INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_RS,
|
||||
INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X,
|
||||
INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_N,
|
||||
INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H,
|
||||
INDIC_SYLLABIC_CATEGORY_VISARGA = OT_SM,
|
||||
INDIC_SYLLABIC_CATEGORY_VOWEL = OT_V,
|
||||
INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT = OT_M,
|
||||
INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT = OT_V
|
||||
};
|
||||
|
||||
/* Categories used in IndicSMatraCategory.txt from UCD */
|
||||
enum indic_matra_category_t {
|
||||
INDIC_MATRA_CATEGORY_NOT_APPLICABLE = POS_END,
|
||||
|
||||
INDIC_MATRA_CATEGORY_LEFT = POS_PRE_C,
|
||||
INDIC_MATRA_CATEGORY_TOP = POS_ABOVE_C,
|
||||
INDIC_MATRA_CATEGORY_BOTTOM = POS_BELOW_C,
|
||||
INDIC_MATRA_CATEGORY_RIGHT = POS_POST_C,
|
||||
|
||||
/* These should resolve to the position of the last part of the split sequence. */
|
||||
INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||
INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||
INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = INDIC_MATRA_CATEGORY_BOTTOM,
|
||||
INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||
INDIC_MATRA_CATEGORY_TOP_AND_LEFT = INDIC_MATRA_CATEGORY_TOP,
|
||||
INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||
INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||
|
||||
INDIC_MATRA_CATEGORY_INVISIBLE = INDIC_MATRA_CATEGORY_NOT_APPLICABLE,
|
||||
INDIC_MATRA_CATEGORY_OVERSTRUCK = POS_AFTER_MAIN,
|
||||
INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = POS_PRE_M
|
||||
};
|
||||
|
||||
/* Note: We use ASSERT_STATIC_EXPR_ZERO() instead of ASSERT_STATIC_EXPR() and the comma operation
|
||||
* because gcc fails to optimize the latter and fills the table in at runtime. */
|
||||
#define INDIC_COMBINE_CATEGORIES(S,M) \
|
||||
(ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || (S == INDIC_SYLLABIC_CATEGORY_VIRAMA || S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT)) + \
|
||||
ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \
|
||||
((M << 8) | S))
|
||||
|
||||
HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE
|
||||
hb_indic_get_categories (hb_codepoint_t u);
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH */
|
869
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc
vendored
Normal file
869
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc
vendored
Normal file
@ -0,0 +1,869 @@
|
||||
/* == Start of generated table == */
|
||||
/*
|
||||
* The following table is generated by running:
|
||||
*
|
||||
* ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt
|
||||
*
|
||||
* on files with these headers:
|
||||
*
|
||||
* # IndicSyllabicCategory-6.2.0.txt
|
||||
* # Date: 2012-05-15, 21:12:00 GMT [KW]
|
||||
* # IndicMatraCategory-6.2.0.txt
|
||||
* # Date: 2012-05-15, 21:10:00 GMT [KW]
|
||||
* # Blocks-6.2.0.txt
|
||||
* # Date: 2012-05-14, 22:42:00 GMT [KW, LI]
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-complex-indic-private.hh"
|
||||
|
||||
|
||||
#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 11 chars; Avagraha */
|
||||
#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 34 chars; Bindu */
|
||||
#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 123 chars; Consonant */
|
||||
#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 2 chars; Consonant_Dead */
|
||||
#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 17 chars; Consonant_Final */
|
||||
#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 1 chars; Consonant_Head_Letter */
|
||||
#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 12 chars; Consonant_Medial */
|
||||
#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 4 chars; Consonant_Placeholder */
|
||||
#define ISC_CR INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA /* 5 chars; Consonant_Repha */
|
||||
#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 10 chars; Consonant_Subjoined */
|
||||
#define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */
|
||||
#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 12 chars; Nukta */
|
||||
#define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */
|
||||
#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 1 chars; Register_Shifter */
|
||||
#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 3 chars; Tone_Letter */
|
||||
#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 16 chars; Tone_Mark */
|
||||
#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 34 chars; Virama */
|
||||
#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 25 chars; Visarga */
|
||||
#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 5 chars; Vowel */
|
||||
#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 165 chars; Vowel_Dependent */
|
||||
#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 59 chars; Vowel_Independent */
|
||||
|
||||
#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 65 chars; Bottom */
|
||||
#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */
|
||||
#define IMC_I INDIC_MATRA_CATEGORY_INVISIBLE /* 6 chars; Invisible */
|
||||
#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 30 chars; Left */
|
||||
#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 8 chars; Left_And_Right */
|
||||
#define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */
|
||||
#define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 2 chars; Overstruck */
|
||||
#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 75 chars; Right */
|
||||
#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 83 chars; Top */
|
||||
#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 6 chars; Top_And_Bottom */
|
||||
#define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */
|
||||
#define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 4 chars; Top_And_Left */
|
||||
#define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 2 chars; Top_And_Left_And_Right */
|
||||
#define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT /* 8 chars; Top_And_Right */
|
||||
#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT /* 5 chars; Visual_Order_Left */
|
||||
|
||||
#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)
|
||||
|
||||
|
||||
static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
|
||||
|
||||
|
||||
#define indic_offset_0x0900 0
|
||||
|
||||
|
||||
/* Devanagari (0900..097F) */
|
||||
|
||||
/* 0900 */ _(Bi,x), _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0908 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0910 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0920 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0928 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0938 */ _(C,x), _(C,x), _(M,T), _(M,R), _(N,x), _(A,x), _(M,R), _(M,L),
|
||||
/* 0940 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T),
|
||||
/* 0948 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(M,L), _(M,R),
|
||||
/* 0950 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(M,B),
|
||||
/* 0958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0960 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0968 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0970 */ _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0978 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
|
||||
/* Bengali (0980..09FF) */
|
||||
|
||||
/* 0980 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0988 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x),
|
||||
/* 0990 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 09A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 09A8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 09B0 */ _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x),
|
||||
/* 09B8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,L),
|
||||
/* 09C0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L),
|
||||
/* 09C8 */ _(M,L), _(x,x), _(x,x), _(M,LR), _(M,LR), _(V,B), _(CD,x), _(x,x),
|
||||
/* 09D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
|
||||
/* 09D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x),
|
||||
/* 09E0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 09E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 09F0 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 09F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Gurmukhi (0A00..0A7F) */
|
||||
|
||||
/* 0A00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0A08 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x),
|
||||
/* 0A10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0A18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0A28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0A30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(x,x),
|
||||
/* 0A38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(x,x), _(M,R), _(M,L),
|
||||
/* 0A40 */ _(M,R), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T),
|
||||
/* 0A48 */ _(M,T), _(x,x), _(x,x), _(M,T), _(M,T), _(V,B), _(x,x), _(x,x),
|
||||
/* 0A50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0A58 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x),
|
||||
/* 0A60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0A68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0A70 */ _(Bi,x), _(x,x), _(CP,x), _(CP,x), _(x,x), _(CM,x), _(x,x), _(x,x),
|
||||
/* 0A78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Gujarati (0A80..0AFF) */
|
||||
|
||||
/* 0A80 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0A88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x),
|
||||
/* 0A90 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0A98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0AA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0AA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0AB0 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0AB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,L),
|
||||
/* 0AC0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(x,x), _(M,T),
|
||||
/* 0AC8 */ _(M,T), _(M,TR), _(x,x), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x),
|
||||
/* 0AD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0AD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0AE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0AE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0AF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0AF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Oriya (0B00..0B7F) */
|
||||
|
||||
/* 0B00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x),
|
||||
/* 0B10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0B20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0B28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0B30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0B38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,T),
|
||||
/* 0B40 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L),
|
||||
/* 0B48 */ _(M,TL), _(x,x), _(x,x), _(M,LR),_(M,TLR), _(V,B), _(x,x), _(x,x),
|
||||
/* 0B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,TR),
|
||||
/* 0B58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x),
|
||||
/* 0B60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0B68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0B70 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0B78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Tamil (0B80..0BFF) */
|
||||
|
||||
/* 0B80 */ _(x,x), _(x,x), _(Bi,x), _(ML,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0B88 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(VI,x), _(VI,x),
|
||||
/* 0B90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(x,x), _(x,x),
|
||||
/* 0B98 */ _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(C,x), _(C,x),
|
||||
/* 0BA0 */ _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0BA8 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x),
|
||||
/* 0BB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0BB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R),
|
||||
/* 0BC0 */ _(M,T), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(M,L), _(M,L),
|
||||
/* 0BC8 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T), _(x,x), _(x,x),
|
||||
/* 0BD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
|
||||
/* 0BD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0BE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0BE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0BF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0BF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Telugu (0C00..0C7F) */
|
||||
|
||||
/* 0C00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0C08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
|
||||
/* 0C10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0C28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0C30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0C38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(A,x), _(M,T), _(M,T),
|
||||
/* 0C40 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,T),
|
||||
/* 0C48 */ _(M,TB), _(x,x), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x), _(x,x),
|
||||
/* 0C50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(x,x),
|
||||
/* 0C58 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0C60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0C68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0C70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0C78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Kannada (0C80..0CFF) */
|
||||
|
||||
/* 0C80 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0C88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
|
||||
/* 0C90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0C98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0CA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0CA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0CB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0CB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,T),
|
||||
/* 0CC0 */ _(M,TR), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,TR),
|
||||
/* 0CC8 */ _(M,TR), _(x,x), _(M,TR), _(M,TR), _(M,T), _(V,T), _(x,x), _(x,x),
|
||||
/* 0CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R), _(x,x),
|
||||
/* 0CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(x,x),
|
||||
/* 0CE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0CE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0CF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0CF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Malayalam (0D00..0D7F) */
|
||||
|
||||
/* 0D00 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0D08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
|
||||
/* 0D10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0D18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0D20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0D28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0D30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0D38 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(A,x), _(M,R), _(M,R),
|
||||
/* 0D40 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(x,x), _(M,L), _(M,L),
|
||||
/* 0D48 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T), _(CR,x), _(x,x),
|
||||
/* 0D50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
|
||||
/* 0D58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0D60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0D68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0D70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0D78 */ _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x),
|
||||
|
||||
/* Sinhala (0D80..0DFF) */
|
||||
|
||||
/* 0D80 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0D88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0D90 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x),
|
||||
/* 0D98 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0DA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0DA8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0DB0 */ _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0DB8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(x,x),
|
||||
/* 0DC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x),
|
||||
/* 0DC8 */ _(x,x), _(x,x), _(V,T), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
|
||||
/* 0DD0 */ _(M,R), _(M,R), _(M,T), _(M,T), _(M,B), _(x,x), _(M,B), _(x,x),
|
||||
/* 0DD8 */ _(M,R), _(M,L), _(M,TL), _(M,L), _(M,LR), _(M,LR), _(M,LR), _(M,R),
|
||||
/* 0DE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0DE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0DF0 */ _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0DF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Thai (0E00..0E7F) */
|
||||
|
||||
/* 0E00 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0E08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0E10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0E18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0E20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0E28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x),
|
||||
/* 0E30 */ _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T), _(M,T),
|
||||
/* 0E38 */ _(M,B), _(M,B), _(V,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0E40 */_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL), _(M,R), _(x,x), _(M,T),
|
||||
/* 0E48 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(Bi,x), _(V,T), _(x,x),
|
||||
/* 0E50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0E58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0E60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0E68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0E70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0E78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Lao (0E80..0EFF) */
|
||||
|
||||
/* 0E80 */ _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(C,x),
|
||||
/* 0E88 */ _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(C,x), _(x,x), _(x,x),
|
||||
/* 0E90 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0E98 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0EA0 */ _(x,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(C,x),
|
||||
/* 0EA8 */ _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(x,x),
|
||||
/* 0EB0 */ _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T), _(M,T),
|
||||
/* 0EB8 */ _(M,B), _(M,B), _(x,x), _(M,T), _(CM,x), _(CM,x), _(x,x), _(x,x),
|
||||
/* 0EC0 */_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL), _(x,x), _(x,x), _(x,x),
|
||||
/* 0EC8 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(Bi,x), _(x,x), _(x,x),
|
||||
/* 0ED0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0ED8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(x,x),
|
||||
/* 0EE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0EE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0EF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0EF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Tibetan (0F00..0FFF) */
|
||||
|
||||
/* 0F00 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0F08 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0F10 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0F18 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0F20 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0F28 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0F30 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0F38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0F40 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0F48 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0F50 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0F58 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0F60 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0F68 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0F70 */ _(x,x), _(M,B), _(M,T), _(M,TB), _(M,B), _(M,B), _(M,TB), _(M,TB),
|
||||
/* 0F78 */ _(M,TB), _(M,TB), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,x), _(Vs,x),
|
||||
/* 0F80 */ _(M,T), _(M,TB), _(Bi,x), _(Bi,x), _(V,B), _(A,x), _(x,x), _(x,x),
|
||||
/* 0F88 */_(CHL,x),_(CHL,x),_(CHL,x),_(CHL,x),_(CHL,x), _(CS,x), _(CS,x), _(CS,x),
|
||||
/* 0F90 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
|
||||
/* 0F98 */ _(x,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
|
||||
/* 0FA0 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
|
||||
/* 0FA8 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
|
||||
/* 0FB0 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
|
||||
/* 0FB8 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0FC0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0FC8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0FD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0FD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0FE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0FE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0FF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0FF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Myanmar (1000..109F) */
|
||||
|
||||
/* 1000 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1008 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1010 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1018 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1020 */ _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 1028 */ _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), _(M,T), _(M,T), _(M,B),
|
||||
/* 1030 */ _(M,B), _(M,L), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,x), _(TM,x),
|
||||
/* 1038 */ _(Vs,x), _(V,I), _(V,T), _(CM,x), _(CM,x), _(CM,x), _(CM,x), _(C,x),
|
||||
/* 1040 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1048 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1050 */ _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R),
|
||||
/* 1058 */ _(M,B), _(M,B), _(C,x), _(C,x), _(C,x), _(C,x), _(CM,x), _(CM,x),
|
||||
/* 1060 */ _(CM,x), _(C,x), _(M,R), _(TM,x), _(TM,x), _(C,x), _(C,x), _(M,R),
|
||||
/* 1068 */ _(M,R), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(C,x), _(C,x),
|
||||
/* 1070 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(C,x), _(C,x), _(C,x),
|
||||
/* 1078 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1080 */ _(C,x), _(C,x), _(CM,x), _(M,R), _(M,L), _(M,T), _(M,T), _(TM,x),
|
||||
/* 1088 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(C,x), _(TM,x),
|
||||
/* 1090 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1098 */ _(x,x), _(x,x), _(TM,x), _(TM,x), _(M,R), _(M,T), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x1700 1952
|
||||
|
||||
|
||||
/* Tagalog (1700..171F) */
|
||||
|
||||
/* 1700 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1708 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x),
|
||||
/* 1710 */ _(C,x), _(C,x), _(M,T), _(M,B), _(V,B), _(x,x), _(x,x), _(x,x),
|
||||
/* 1718 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Hanunoo (1720..173F) */
|
||||
|
||||
/* 1720 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1728 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1730 */ _(C,x), _(C,x), _(M,T), _(M,B), _(V,B), _(x,x), _(x,x), _(x,x),
|
||||
/* 1738 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Buhid (1740..175F) */
|
||||
|
||||
/* 1740 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1748 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1750 */ _(C,x), _(C,x), _(M,T), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1758 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Tagbanwa (1760..177F) */
|
||||
|
||||
/* 1760 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1768 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x),
|
||||
/* 1770 */ _(C,x), _(x,x), _(M,T), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1778 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Khmer (1780..17FF) */
|
||||
|
||||
/* 1780 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1788 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1790 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1798 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 17A0 */ _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 17A8 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 17B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(M,R), _(M,T),
|
||||
/* 17B8 */ _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,TL),_(M,TLR),
|
||||
/* 17C0 */ _(M,LR), _(M,L), _(M,L), _(M,L), _(M,LR), _(M,LR), _(Bi,x), _(Vs,x),
|
||||
/* 17C8 */ _(M,R), _(RS,x), _(RS,x), _(x,x), _(CR,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 17D0 */ _(x,x), _(V,T), _(V,I), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 17D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(A,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 17E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 17E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 17F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 17F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x1900 2208
|
||||
|
||||
|
||||
/* Limbu (1900..194F) */
|
||||
|
||||
/* 1900 */ _(CP,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1908 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1910 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1920 */ _(M,T), _(M,T), _(M,B), _(M,R), _(M,R), _(M,TR), _(M,TR), _(M,T),
|
||||
/* 1928 */ _(M,T), _(CS,x), _(CS,x), _(CS,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1930 */ _(CF,x), _(CF,x), _(Bi,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
|
||||
/* 1938 */ _(CF,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1940 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1948 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Tai Le (1950..197F) */
|
||||
|
||||
/* 1950 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1960 */ _(C,x), _(C,x), _(C,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x),
|
||||
/* 1968 */ _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(x,x), _(x,x),
|
||||
/* 1970 */ _(TL,x), _(TL,x), _(TL,x), _(TL,x), _(TL,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1978 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* New Tai Lue (1980..19DF) */
|
||||
|
||||
/* 1980 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1988 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1990 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 19A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 19A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 19B0 */ _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,L), _(M,L), _(M,L),
|
||||
/* 19B8 */ _(M,R), _(M,R), _(M,L), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R),
|
||||
/* 19C0 */ _(M,R), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
|
||||
/* 19C8 */ _(TM,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 19D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 19D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* FILLER (19E0..19FF) */
|
||||
|
||||
/* 19E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 19E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 19F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 19F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Buginese (1A00..1A1F) */
|
||||
|
||||
/* 1A00 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1A08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1A10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T),
|
||||
/* 1A18 */ _(M,B), _(M,L), _(M,R), _(M,L), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Tai Tham (1A20..1AAF) */
|
||||
|
||||
/* 1A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1A28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1A30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1A38 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1A40 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1A48 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 1A50 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(CM,x), _(CM,x), _(CF,x),
|
||||
/* 1A58 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(x,x),
|
||||
/* 1A60 */ _(V,I), _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T),
|
||||
/* 1A68 */ _(M,T), _(M,B), _(M,B), _(M,T), _(M,B), _(M,R), _(M,L), _(M,L),
|
||||
/* 1A70 */ _(M,L), _(M,L), _(M,L), _(M,T), _(M,T), _(TM,x), _(TM,x), _(TM,x),
|
||||
/* 1A78 */ _(TM,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1A80 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1A88 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1A90 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1A98 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1AA0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1AA8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x1b00 2640
|
||||
|
||||
|
||||
/* Balinese (1B00..1B7F) */
|
||||
|
||||
/* 1B00 */ _(Bi,x), _(Bi,x), _(Bi,x), _(CR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 1B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 1B10 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1B20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1B28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1B30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(N,x), _(M,R), _(M,T), _(M,T),
|
||||
/* 1B38 */ _(M,B), _(M,B), _(M,B), _(M,BR), _(M,TB),_(M,TBR), _(M,L), _(M,L),
|
||||
/* 1B40 */ _(M,LR), _(M,LR), _(M,T), _(M,TR), _(V,R), _(C,x), _(C,x), _(C,x),
|
||||
/* 1B48 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1B58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1B60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1B68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1B70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1B78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Sundanese (1B80..1BBF) */
|
||||
|
||||
/* 1B80 */ _(Bi,x), _(CR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 1B88 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1B90 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1B98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1BA0 */ _(C,x), _(CS,x), _(CS,x), _(CS,x), _(M,T), _(M,B), _(M,L), _(M,R),
|
||||
/* 1BA8 */ _(M,T), _(M,T), _(V,R), _(V,x), _(CS,x), _(CS,x), _(C,x), _(C,x),
|
||||
/* 1BB0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1BB8 */ _(x,x), _(x,x), _(A,x), _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x),
|
||||
|
||||
/* Batak (1BC0..1BFF) */
|
||||
|
||||
/* 1BC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1BC8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1BD0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1BD8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1BE0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(N,x), _(M,x),
|
||||
/* 1BE8 */ _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), _(M,x),
|
||||
/* 1BF0 */ _(CF,x), _(CF,x), _(V,R), _(V,R), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1BF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Lepcha (1C00..1C4F) */
|
||||
|
||||
/* 1C00 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1C08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1C10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(CS,x), _(CS,x), _(M,R), _(M,L),
|
||||
/* 1C28 */ _(M,L), _(M,TL), _(M,R), _(M,R), _(M,B), _(CF,x), _(CF,x), _(CF,x),
|
||||
/* 1C30 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(Bi,x), _(Bi,x), _(x,x), _(N,x),
|
||||
/* 1C38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1C40 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1C48 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
||||
|
||||
#define indic_offset_0x1cd0 2976
|
||||
|
||||
|
||||
/* Vedic Extensions (1CD0..1CFF) */
|
||||
|
||||
/* 1CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1CE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1CE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 1CF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0xa800 3024
|
||||
|
||||
|
||||
/* Syloti Nagri (A800..A82F) */
|
||||
|
||||
/* A800 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(V,T), _(C,x),
|
||||
/* A808 */ _(C,x), _(C,x), _(C,x), _(Bi,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A810 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A818 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A820 */ _(C,x), _(C,x), _(C,x), _(M,R), _(M,R), _(M,B), _(M,T), _(M,R),
|
||||
/* A828 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* FILLER (A830..A83F) */
|
||||
|
||||
/* A830 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A838 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Phags-pa (A840..A87F) */
|
||||
|
||||
/* A840 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A848 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A850 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A858 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(Vo,x), _(Vo,x),
|
||||
/* A860 */ _(Vo,x), _(Vo,x), _(C,x), _(C,x), _(C,x), _(C,x), _(Vo,x), _(CS,x),
|
||||
/* A868 */ _(CS,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A870 */ _(C,x), _(CS,x), _(C,x), _(Bi,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A878 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Saurashtra (A880..A8DF) */
|
||||
|
||||
/* A880 */ _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* A888 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* A890 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A898 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A8A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A8A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A8B0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(CF,x), _(M,R), _(M,R), _(M,R),
|
||||
/* A8B8 */ _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R),
|
||||
/* A8C0 */ _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x), _(x,x),
|
||||
/* A8C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A8D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A8D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* FILLER (A8E0..A8FF) */
|
||||
|
||||
/* A8E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A8E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A8F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A8F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Kayah Li (A900..A92F) */
|
||||
|
||||
/* A900 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A908 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A910 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A920 */ _(C,x), _(C,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x),
|
||||
/* A928 */ _(Vo,x), _(Vo,x), _(Vo,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(x,x),
|
||||
|
||||
/* Rejang (A930..A95F) */
|
||||
|
||||
/* A930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A938 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A940 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,B),
|
||||
/* A948 */ _(M,B), _(M,B), _(M,T), _(M,B), _(M,B), _(M,B), _(M,B), _(CF,x),
|
||||
/* A950 */ _(CF,x), _(CF,x), _(CF,x), _(V,R), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A958 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* FILLER (A960..A97F) */
|
||||
|
||||
/* A960 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A968 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A970 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A978 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Javanese (A980..A9DF) */
|
||||
|
||||
/* A980 */ _(Bi,x), _(Bi,x), _(CR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* A988 */ _(VI,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(C,x),
|
||||
/* A990 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A9A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A9A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A9B0 */ _(C,x), _(C,x), _(C,x), _(N,x), _(M,R), _(M,R), _(M,T), _(M,T),
|
||||
/* A9B8 */ _(M,B), _(M,B), _(M,L), _(M,L), _(M,T), _(CS,x), _(CM,x), _(CM,x),
|
||||
/* A9C0 */ _(V,BR), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A9C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A9D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A9D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* FILLER (A9E0..A9FF) */
|
||||
|
||||
/* A9E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A9E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A9F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* A9F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Cham (AA00..AA5F) */
|
||||
|
||||
/* AA00 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x),
|
||||
/* AA08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AA10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AA18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AA20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AA28 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(M,B), _(M,T), _(M,L),
|
||||
/* AA30 */ _(M,L), _(M,T), _(M,B), _(CM,x), _(CM,x), _(CM,x), _(CM,x), _(x,x),
|
||||
/* AA38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* AA40 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
|
||||
/* AA48 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(x,x), _(x,x),
|
||||
/* AA50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* AA58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Myanmar Extended-A (AA60..AA7F) */
|
||||
|
||||
/* AA60 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AA68 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AA70 */ _(x,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Tai Viet (AA80..AADF) */
|
||||
|
||||
/* AA80 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AA88 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AA90 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AA98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AAA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AAA8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AAB0 */ _(M,T), _(M,R), _(M,T), _(M,T), _(M,B),_(M,VOL),_(M,VOL), _(M,T),
|
||||
/* AAB8 */ _(M,T),_(M,VOL), _(M,R),_(M,VOL),_(M,VOL), _(M,R), _(M,T), _(TM,x),
|
||||
/* AAC0 */ _(TL,x), _(TM,x), _(TL,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* AAC8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* AAD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* AAD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Meetei Mayek Extensions (AAE0..AAFF) */
|
||||
|
||||
/* AAE0 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AAE8 */ _(C,x), _(C,x), _(C,x), _(M,L), _(M,B), _(M,T), _(M,L), _(M,R),
|
||||
/* AAF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Vs,x), _(V,I), _(x,x),
|
||||
/* AAF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0xabc0 3792
|
||||
|
||||
|
||||
/* Meetei Mayek (ABC0..ABFF) */
|
||||
|
||||
/* ABC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* ABC8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x),
|
||||
/* ABD0 */ _(C,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* ABD8 */ _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
|
||||
/* ABE0 */ _(CF,x), _(CF,x), _(CF,x), _(M,R), _(M,R), _(M,T), _(M,R), _(M,R),
|
||||
/* ABE8 */ _(M,B), _(M,R), _(M,R), _(x,x), _(TM,x), _(V,B), _(x,x), _(x,x),
|
||||
/* ABF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* ABF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x10a00 3856
|
||||
|
||||
|
||||
/* Kharoshthi (10A00..10A5F) */
|
||||
|
||||
/* 10A00 */ _(C,x), _(M,O), _(M,B), _(M,B), _(x,x), _(M,T), _(M,O), _(x,x),
|
||||
/* 10A08 */ _(x,x), _(x,x), _(x,x), _(x,x), _(M,B), _(x,x), _(Bi,x), _(Vs,x),
|
||||
/* 10A10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 10A18 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 10A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 10A28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 10A30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 10A38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(V,I),
|
||||
/* 10A40 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 10A48 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 10A50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 10A58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x11000 3952
|
||||
|
||||
|
||||
/* Brahmi (11000..1107F) */
|
||||
|
||||
/* 11000 */ _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 11008 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 11010 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11018 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11020 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11028 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11030 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11038 */ _(M,T), _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,B),
|
||||
/* 11040 */ _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x),
|
||||
/* 11048 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 11050 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 11058 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 11060 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 11068 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 11070 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 11078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Kaithi (11080..110CF) */
|
||||
|
||||
/* 11080 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 11088 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11090 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11098 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 110A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 110A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 110B0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,T), _(M,T), _(M,R),
|
||||
/* 110B8 */ _(M,R), _(V,B), _(N,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 110C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 110C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x11100 4160
|
||||
|
||||
|
||||
/* Chakma (11100..1114F) */
|
||||
|
||||
/* 11100 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x),
|
||||
/* 11108 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11110 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11118 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11120 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T),
|
||||
/* 11128 */ _(M,T), _(M,T), _(M,B), _(M,B), _(M,L), _(M,T), _(M,TB), _(M,TB),
|
||||
/* 11130 */ _(M,T), _(M,B), _(M,B), _(V,I), _(V,T), _(x,x), _(x,x), _(x,x),
|
||||
/* 11138 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 11140 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 11148 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x11180 4240
|
||||
|
||||
|
||||
/* Sharada (11180..111DF) */
|
||||
|
||||
/* 11180 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 11188 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 11190 */ _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11198 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 111A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 111A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 111B0 */ _(C,x), _(C,x), _(C,x), _(M,R), _(M,L), _(M,R), _(M,B), _(M,B),
|
||||
/* 111B8 */ _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,TR),
|
||||
/* 111C0 */ _(V,R), _(A,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 111C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 111D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 111D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x11680 4336
|
||||
|
||||
|
||||
/* Takri (11680..116CF) */
|
||||
|
||||
/* 11680 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 11688 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11690 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 11698 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 116A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 116A8 */ _(C,x), _(C,x), _(C,x), _(Bi,x), _(Vs,x), _(M,T), _(M,L), _(M,R),
|
||||
/* 116B0 */ _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,T), _(V,T), _(N,x),
|
||||
/* 116B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 116C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 116C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_total 4416
|
||||
|
||||
}; /* Table occupancy: 60% */
|
||||
|
||||
INDIC_TABLE_ELEMENT_TYPE
|
||||
hb_indic_get_categories (hb_codepoint_t u)
|
||||
{
|
||||
if (0x0900 <= u && u <= 0x10A0) return indic_table[u - 0x0900 + indic_offset_0x0900];
|
||||
if (0x1700 <= u && u <= 0x1800) return indic_table[u - 0x1700 + indic_offset_0x1700];
|
||||
if (0x1900 <= u && u <= 0x1AB0) return indic_table[u - 0x1900 + indic_offset_0x1900];
|
||||
if (0x1B00 <= u && u <= 0x1C50) return indic_table[u - 0x1B00 + indic_offset_0x1b00];
|
||||
if (0x1CD0 <= u && u <= 0x1D00) return indic_table[u - 0x1CD0 + indic_offset_0x1cd0];
|
||||
if (0xA800 <= u && u <= 0xAB00) return indic_table[u - 0xA800 + indic_offset_0xa800];
|
||||
if (0xABC0 <= u && u <= 0xAC00) return indic_table[u - 0xABC0 + indic_offset_0xabc0];
|
||||
if (0x10A00 <= u && u <= 0x10A60) return indic_table[u - 0x10A00 + indic_offset_0x10a00];
|
||||
if (0x11000 <= u && u <= 0x110D0) return indic_table[u - 0x11000 + indic_offset_0x11000];
|
||||
if (0x11100 <= u && u <= 0x11150) return indic_table[u - 0x11100 + indic_offset_0x11100];
|
||||
if (0x11180 <= u && u <= 0x111E0) return indic_table[u - 0x11180 + indic_offset_0x11180];
|
||||
if (0x11680 <= u && u <= 0x116D0) return indic_table[u - 0x11680 + indic_offset_0x11680];
|
||||
if (unlikely (u == 0x00A0)) return _(CP,x);
|
||||
if (unlikely (u == 0x25CC)) return _(CP,x);
|
||||
return _(x,x);
|
||||
}
|
||||
|
||||
#undef _
|
||||
|
||||
#undef ISC_A
|
||||
#undef ISC_Bi
|
||||
#undef ISC_C
|
||||
#undef ISC_CD
|
||||
#undef ISC_CF
|
||||
#undef ISC_CHL
|
||||
#undef ISC_CM
|
||||
#undef ISC_CP
|
||||
#undef ISC_CR
|
||||
#undef ISC_CS
|
||||
#undef ISC_ML
|
||||
#undef ISC_N
|
||||
#undef ISC_x
|
||||
#undef ISC_RS
|
||||
#undef ISC_TL
|
||||
#undef ISC_TM
|
||||
#undef ISC_V
|
||||
#undef ISC_Vs
|
||||
#undef ISC_Vo
|
||||
#undef ISC_M
|
||||
#undef ISC_VI
|
||||
|
||||
#undef IMC_B
|
||||
#undef IMC_BR
|
||||
#undef IMC_I
|
||||
#undef IMC_L
|
||||
#undef IMC_LR
|
||||
#undef IMC_x
|
||||
#undef IMC_O
|
||||
#undef IMC_R
|
||||
#undef IMC_T
|
||||
#undef IMC_TB
|
||||
#undef IMC_TBR
|
||||
#undef IMC_TL
|
||||
#undef IMC_TLR
|
||||
#undef IMC_TR
|
||||
#undef IMC_VOL
|
||||
|
||||
/* == End of generated table == */
|
1673
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
vendored
Normal file
1673
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
391
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh
vendored
Normal file
391
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh
vendored
Normal file
@ -0,0 +1,391 @@
|
||||
|
||||
#line 1 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
/*
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
#line 36 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
|
||||
1u, 30u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
|
||||
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
|
||||
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u,
|
||||
5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
|
||||
3u, 30u, 3u, 29u, 1u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
|
||||
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 0
|
||||
};
|
||||
|
||||
static const char _myanmar_syllable_machine_key_spans[] = {
|
||||
30, 28, 25, 4, 25, 23, 21, 21,
|
||||
27, 27, 27, 27, 16, 27, 27, 27,
|
||||
27, 27, 27, 27, 27, 27, 25, 4,
|
||||
25, 23, 21, 21, 27, 27, 27, 27,
|
||||
28, 27, 30, 27, 27, 27, 27, 27,
|
||||
27, 27, 27, 27
|
||||
};
|
||||
|
||||
static const short _myanmar_syllable_machine_index_offsets[] = {
|
||||
0, 31, 60, 86, 91, 117, 141, 163,
|
||||
185, 213, 241, 269, 297, 314, 342, 370,
|
||||
398, 426, 454, 482, 510, 538, 566, 592,
|
||||
597, 623, 647, 669, 691, 719, 747, 775,
|
||||
803, 832, 860, 891, 919, 947, 975, 1003,
|
||||
1031, 1059, 1087, 1115
|
||||
};
|
||||
|
||||
static const char _myanmar_syllable_machine_indicies[] = {
|
||||
1, 1, 2, 3, 4, 4, 0, 5,
|
||||
0, 6, 0, 1, 0, 0, 0, 7,
|
||||
0, 8, 1, 0, 9, 10, 11, 12,
|
||||
13, 14, 15, 16, 17, 18, 0, 20,
|
||||
21, 22, 22, 19, 23, 19, 24, 19,
|
||||
19, 19, 19, 19, 19, 19, 25, 19,
|
||||
19, 26, 27, 28, 29, 30, 31, 32,
|
||||
33, 34, 35, 19, 22, 22, 19, 23,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 36, 19, 19, 19, 19, 19, 19,
|
||||
30, 19, 19, 19, 34, 19, 22, 22,
|
||||
19, 23, 19, 22, 22, 19, 23, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 30,
|
||||
19, 19, 19, 34, 19, 37, 19, 22,
|
||||
22, 19, 23, 19, 30, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 30, 19, 22, 22, 19,
|
||||
23, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 38, 19, 19, 19, 19, 19,
|
||||
19, 30, 19, 22, 22, 19, 23, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 30,
|
||||
19, 20, 19, 22, 22, 19, 23, 19,
|
||||
24, 19, 19, 19, 19, 19, 19, 19,
|
||||
39, 19, 19, 39, 19, 19, 19, 30,
|
||||
40, 19, 19, 34, 19, 20, 19, 22,
|
||||
22, 19, 23, 19, 24, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 30, 19, 19, 19, 34,
|
||||
19, 20, 19, 22, 22, 19, 23, 19,
|
||||
24, 19, 19, 19, 19, 19, 19, 19,
|
||||
39, 19, 19, 19, 19, 19, 19, 30,
|
||||
40, 19, 19, 34, 19, 20, 19, 22,
|
||||
22, 19, 23, 19, 24, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 30, 40, 19, 19, 34,
|
||||
19, 1, 1, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
1, 19, 20, 19, 22, 22, 19, 23,
|
||||
19, 24, 19, 19, 19, 19, 19, 19,
|
||||
19, 25, 19, 19, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 19, 20, 19,
|
||||
22, 22, 19, 23, 19, 24, 19, 19,
|
||||
19, 19, 19, 19, 19, 33, 19, 19,
|
||||
19, 19, 19, 19, 30, 31, 32, 33,
|
||||
34, 19, 20, 19, 22, 22, 19, 23,
|
||||
19, 24, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
30, 31, 32, 33, 34, 19, 20, 19,
|
||||
22, 22, 19, 23, 19, 24, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 30, 31, 32, 19,
|
||||
34, 19, 20, 19, 22, 22, 19, 23,
|
||||
19, 24, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
30, 19, 32, 19, 34, 19, 20, 19,
|
||||
22, 22, 19, 23, 19, 24, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
26, 19, 28, 19, 30, 31, 32, 33,
|
||||
34, 19, 20, 19, 22, 22, 19, 23,
|
||||
19, 24, 19, 19, 19, 19, 19, 19,
|
||||
19, 33, 19, 19, 26, 19, 19, 19,
|
||||
30, 31, 32, 33, 34, 19, 20, 19,
|
||||
22, 22, 19, 23, 19, 24, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
26, 27, 28, 19, 30, 31, 32, 33,
|
||||
34, 19, 20, 21, 22, 22, 19, 23,
|
||||
19, 24, 19, 19, 19, 19, 19, 19,
|
||||
19, 25, 19, 19, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 19, 3, 3,
|
||||
41, 5, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 42, 41, 41, 41, 41,
|
||||
41, 41, 13, 41, 41, 41, 17, 41,
|
||||
3, 3, 41, 5, 41, 3, 3, 41,
|
||||
5, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 13, 41, 41, 41, 17, 41, 43,
|
||||
41, 3, 3, 41, 5, 41, 13, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 13, 41, 3,
|
||||
3, 41, 5, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 44, 41, 41, 41,
|
||||
41, 41, 41, 13, 41, 3, 3, 41,
|
||||
5, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 13, 41, 2, 41, 3, 3, 41,
|
||||
5, 41, 6, 41, 41, 41, 41, 41,
|
||||
41, 41, 45, 41, 41, 45, 41, 41,
|
||||
41, 13, 46, 41, 41, 17, 41, 2,
|
||||
41, 3, 3, 41, 5, 41, 6, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 13, 41, 41,
|
||||
41, 17, 41, 2, 41, 3, 3, 41,
|
||||
5, 41, 6, 41, 41, 41, 41, 41,
|
||||
41, 41, 45, 41, 41, 41, 41, 41,
|
||||
41, 13, 46, 41, 41, 17, 41, 2,
|
||||
41, 3, 3, 41, 5, 41, 6, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 13, 46, 41,
|
||||
41, 17, 41, 20, 21, 22, 22, 19,
|
||||
23, 19, 24, 19, 19, 19, 19, 19,
|
||||
19, 19, 47, 19, 19, 26, 27, 28,
|
||||
29, 30, 31, 32, 33, 34, 35, 19,
|
||||
20, 48, 22, 22, 19, 23, 19, 24,
|
||||
19, 19, 19, 19, 19, 19, 19, 25,
|
||||
19, 19, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 19, 1, 1, 2, 3,
|
||||
3, 3, 41, 5, 41, 6, 41, 1,
|
||||
41, 41, 41, 1, 41, 8, 1, 41,
|
||||
9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 41, 2, 41, 3, 3, 41,
|
||||
5, 41, 6, 41, 41, 41, 41, 41,
|
||||
41, 41, 8, 41, 41, 9, 10, 11,
|
||||
12, 13, 14, 15, 16, 17, 41, 2,
|
||||
41, 3, 3, 41, 5, 41, 6, 41,
|
||||
41, 41, 41, 41, 41, 41, 16, 41,
|
||||
41, 41, 41, 41, 41, 13, 14, 15,
|
||||
16, 17, 41, 2, 41, 3, 3, 41,
|
||||
5, 41, 6, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 13, 14, 15, 16, 17, 41, 2,
|
||||
41, 3, 3, 41, 5, 41, 6, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 13, 14, 15,
|
||||
41, 17, 41, 2, 41, 3, 3, 41,
|
||||
5, 41, 6, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 13, 41, 15, 41, 17, 41, 2,
|
||||
41, 3, 3, 41, 5, 41, 6, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 9, 41, 11, 41, 13, 14, 15,
|
||||
16, 17, 41, 2, 41, 3, 3, 41,
|
||||
5, 41, 6, 41, 41, 41, 41, 41,
|
||||
41, 41, 16, 41, 41, 9, 41, 41,
|
||||
41, 13, 14, 15, 16, 17, 41, 2,
|
||||
41, 3, 3, 41, 5, 41, 6, 41,
|
||||
41, 41, 41, 41, 41, 41, 41, 41,
|
||||
41, 9, 10, 11, 41, 13, 14, 15,
|
||||
16, 17, 41, 2, 3, 3, 3, 41,
|
||||
5, 41, 6, 41, 41, 41, 41, 41,
|
||||
41, 41, 8, 41, 41, 9, 10, 11,
|
||||
12, 13, 14, 15, 16, 17, 41, 0
|
||||
};
|
||||
|
||||
static const char _myanmar_syllable_machine_trans_targs[] = {
|
||||
0, 1, 22, 0, 0, 23, 29, 32,
|
||||
35, 36, 40, 41, 42, 25, 38, 39,
|
||||
37, 28, 43, 0, 2, 12, 0, 3,
|
||||
9, 13, 14, 18, 19, 20, 5, 16,
|
||||
17, 15, 8, 21, 4, 6, 7, 10,
|
||||
11, 0, 24, 26, 27, 30, 31, 33,
|
||||
34
|
||||
};
|
||||
|
||||
static const char _myanmar_syllable_machine_trans_actions[] = {
|
||||
3, 0, 0, 4, 5, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0,
|
||||
0
|
||||
};
|
||||
|
||||
static const char _myanmar_syllable_machine_to_state_actions[] = {
|
||||
1, 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 _myanmar_syllable_machine_from_state_actions[] = {
|
||||
2, 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 _myanmar_syllable_machine_eof_trans[] = {
|
||||
0, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 42, 42,
|
||||
42, 42, 42, 42, 42, 42, 42, 42,
|
||||
20, 20, 42, 42, 42, 42, 42, 42,
|
||||
42, 42, 42, 42
|
||||
};
|
||||
|
||||
static const int myanmar_syllable_machine_start = 0;
|
||||
static const int myanmar_syllable_machine_first_final = 0;
|
||||
static const int myanmar_syllable_machine_error = -1;
|
||||
|
||||
static const int myanmar_syllable_machine_en_main = 0;
|
||||
|
||||
|
||||
#line 36 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
|
||||
|
||||
|
||||
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
|
||||
|
||||
#define found_syllable(syllable_type) \
|
||||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
|
||||
for (unsigned int i = last; i < p+1; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
last = p+1; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
|
||||
int cs;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
|
||||
#line 288 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
{
|
||||
cs = myanmar_syllable_machine_start;
|
||||
ts = 0;
|
||||
te = 0;
|
||||
act = 0;
|
||||
}
|
||||
|
||||
#line 111 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
|
||||
|
||||
p = 0;
|
||||
pe = eof = buffer->len;
|
||||
|
||||
unsigned int last = 0;
|
||||
unsigned int syllable_serial = 1;
|
||||
|
||||
#line 305 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
const unsigned char *_keys;
|
||||
const char *_inds;
|
||||
if ( p == pe )
|
||||
goto _test_eof;
|
||||
_resume:
|
||||
switch ( _myanmar_syllable_machine_from_state_actions[cs] ) {
|
||||
case 2:
|
||||
#line 1 "NONE"
|
||||
{ts = p;}
|
||||
break;
|
||||
#line 319 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
}
|
||||
|
||||
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
|
||||
_inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs];
|
||||
|
||||
_slen = _myanmar_syllable_machine_key_spans[cs];
|
||||
_trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) &&
|
||||
( info[p].myanmar_category()) <= _keys[1] ?
|
||||
( info[p].myanmar_category()) - _keys[0] : _slen ];
|
||||
|
||||
_eof_trans:
|
||||
cs = _myanmar_syllable_machine_trans_targs[_trans];
|
||||
|
||||
if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 )
|
||||
goto _again;
|
||||
|
||||
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
|
||||
case 7:
|
||||
#line 83 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p+1;{ found_syllable (consonant_syllable); }}
|
||||
break;
|
||||
case 5:
|
||||
#line 84 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
|
||||
break;
|
||||
case 4:
|
||||
#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p+1;{ found_syllable (broken_cluster); }}
|
||||
break;
|
||||
case 3:
|
||||
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
|
||||
break;
|
||||
case 6:
|
||||
#line 83 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p;p--;{ found_syllable (consonant_syllable); }}
|
||||
break;
|
||||
case 8:
|
||||
#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p;p--;{ found_syllable (broken_cluster); }}
|
||||
break;
|
||||
#line 361 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
switch ( _myanmar_syllable_machine_to_state_actions[cs] ) {
|
||||
case 1:
|
||||
#line 1 "NONE"
|
||||
{ts = 0;}
|
||||
break;
|
||||
#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
}
|
||||
|
||||
if ( ++p != pe )
|
||||
goto _resume;
|
||||
_test_eof: {}
|
||||
if ( p == eof )
|
||||
{
|
||||
if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) {
|
||||
_trans = _myanmar_syllable_machine_eof_trans[cs] - 1;
|
||||
goto _eof_trans;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#line 120 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
|
||||
}
|
||||
|
||||
#undef found_syllable
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */
|
534
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
vendored
Normal file
534
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
vendored
Normal file
@ -0,0 +1,534 @@
|
||||
/*
|
||||
* Copyright © 2011,2012,2013 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-complex-indic-private.hh"
|
||||
|
||||
/* buffer var allocations */
|
||||
#define myanmar_category() complex_var_u8_0() /* myanmar_category_t */
|
||||
#define myanmar_position() complex_var_u8_1() /* myanmar_position_t */
|
||||
|
||||
|
||||
/*
|
||||
* Myanmar shaper.
|
||||
*/
|
||||
|
||||
static const hb_tag_t
|
||||
basic_features[] =
|
||||
{
|
||||
/*
|
||||
* Basic features.
|
||||
* These features are applied in order, one at a time, after initial_reordering.
|
||||
*/
|
||||
HB_TAG('r','p','h','f'),
|
||||
HB_TAG('p','r','e','f'),
|
||||
HB_TAG('b','l','w','f'),
|
||||
HB_TAG('p','s','t','f'),
|
||||
};
|
||||
static const hb_tag_t
|
||||
other_features[] =
|
||||
{
|
||||
/*
|
||||
* Other features.
|
||||
* These features are applied all at once, after final_reordering.
|
||||
*/
|
||||
HB_TAG('p','r','e','s'),
|
||||
HB_TAG('a','b','v','s'),
|
||||
HB_TAG('b','l','w','s'),
|
||||
HB_TAG('p','s','t','s'),
|
||||
/* Positioning features, though we don't care about the types. */
|
||||
HB_TAG('d','i','s','t'),
|
||||
};
|
||||
|
||||
static void
|
||||
setup_syllables (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
initial_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
final_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
static void
|
||||
collect_features_myanmar (hb_ot_shape_planner_t *plan)
|
||||
{
|
||||
hb_ot_map_builder_t *map = &plan->map;
|
||||
|
||||
/* Do this before any lookups have been applied. */
|
||||
map->add_gsub_pause (setup_syllables);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
|
||||
/* The Indic specs do not require ccmp, but we apply it here since if
|
||||
* there is a use of it, it's typically at the beginning. */
|
||||
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
|
||||
|
||||
|
||||
map->add_gsub_pause (initial_reordering);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
|
||||
{
|
||||
map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
|
||||
map->add_gsub_pause (NULL);
|
||||
}
|
||||
map->add_gsub_pause (final_reordering);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
|
||||
map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
|
||||
}
|
||||
|
||||
static void
|
||||
override_features_myanmar (hb_ot_shape_planner_t *plan)
|
||||
{
|
||||
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
|
||||
}
|
||||
|
||||
|
||||
enum syllable_type_t {
|
||||
consonant_syllable,
|
||||
broken_cluster,
|
||||
non_myanmar_cluster,
|
||||
};
|
||||
|
||||
#include "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
|
||||
|
||||
/* Note: This enum is duplicated in the -machine.rl source file.
|
||||
* Not sure how to avoid duplication. */
|
||||
enum myanmar_category_t {
|
||||
OT_As = 18, /* Asat */
|
||||
OT_D = 19, /* Digits except zero */
|
||||
OT_D0 = 20, /* Digit zero */
|
||||
OT_DB = OT_N, /* Dot below */
|
||||
OT_GB = OT_DOTTEDCIRCLE,
|
||||
OT_MH = 21, /* Various consonant medial types */
|
||||
OT_MR = 22, /* Various consonant medial types */
|
||||
OT_MW = 23, /* Various consonant medial types */
|
||||
OT_MY = 24, /* Various consonant medial types */
|
||||
OT_PT = 25, /* Pwo and other tones */
|
||||
OT_VAbv = 26,
|
||||
OT_VBlw = 27,
|
||||
OT_VPre = 28,
|
||||
OT_VPst = 29,
|
||||
OT_VS = 30 /* Variation selectors */
|
||||
};
|
||||
|
||||
|
||||
static inline bool
|
||||
is_one_of (const hb_glyph_info_t &info, unsigned int flags)
|
||||
{
|
||||
/* If it ligated, all bets are off. */
|
||||
if (is_a_ligature (info)) return false;
|
||||
return !!(FLAG (info.myanmar_category()) & flags);
|
||||
}
|
||||
|
||||
/* Note:
|
||||
*
|
||||
* We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
|
||||
* cannot happen in a consonant syllable. The plus side however is, we can call the
|
||||
* consonant syllable logic from the vowel syllable function and get it all right! */
|
||||
#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CM) | FLAG (OT_Ra) | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_GB))
|
||||
static inline bool
|
||||
is_consonant (const hb_glyph_info_t &info)
|
||||
{
|
||||
return is_one_of (info, CONSONANT_FLAGS);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
set_myanmar_properties (hb_glyph_info_t &info)
|
||||
{
|
||||
hb_codepoint_t u = info.codepoint;
|
||||
unsigned int type = hb_indic_get_categories (u);
|
||||
indic_category_t cat = (indic_category_t) (type & 0x7F);
|
||||
indic_position_t pos = (indic_position_t) (type >> 8);
|
||||
|
||||
/* Myanmar
|
||||
* http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze
|
||||
*/
|
||||
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00, 0xFE0F)))
|
||||
cat = (indic_category_t) OT_VS;
|
||||
else if (unlikely (u == 0x200C)) cat = (indic_category_t) OT_ZWNJ;
|
||||
else if (unlikely (u == 0x200D)) cat = (indic_category_t) OT_ZWJ;
|
||||
|
||||
switch (u)
|
||||
{
|
||||
case 0x002D: case 0x00A0: case 0x00D7: case 0x2012:
|
||||
case 0x2013: case 0x2014: case 0x2015: case 0x2022:
|
||||
case 0x25CC: case 0x25FB: case 0x25FC: case 0x25FD:
|
||||
case 0x25FE:
|
||||
cat = (indic_category_t) OT_GB;
|
||||
break;
|
||||
|
||||
case 0x1004: case 0x101B: case 0x105A:
|
||||
cat = (indic_category_t) OT_Ra;
|
||||
break;
|
||||
|
||||
case 0x1032: case 0x1036:
|
||||
cat = (indic_category_t) OT_A;
|
||||
break;
|
||||
|
||||
case 0x103A:
|
||||
cat = (indic_category_t) OT_As;
|
||||
break;
|
||||
|
||||
case 0x1041: case 0x1042: case 0x1043: case 0x1044:
|
||||
case 0x1045: case 0x1046: case 0x1047: case 0x1048:
|
||||
case 0x1049: case 0x1090: case 0x1091: case 0x1092:
|
||||
case 0x1093: case 0x1094: case 0x1095: case 0x1096:
|
||||
case 0x1097: case 0x1098: case 0x1099:
|
||||
cat = (indic_category_t) OT_D;
|
||||
break;
|
||||
|
||||
case 0x1040:
|
||||
cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */
|
||||
break;
|
||||
|
||||
case 0x103E: case 0x1060:
|
||||
cat = (indic_category_t) OT_MH;
|
||||
break;
|
||||
|
||||
case 0x103C:
|
||||
cat = (indic_category_t) OT_MR;
|
||||
break;
|
||||
|
||||
case 0x103D: case 0x1082:
|
||||
cat = (indic_category_t) OT_MW;
|
||||
break;
|
||||
|
||||
case 0x103B: case 0x105E: case 0x105F:
|
||||
cat = (indic_category_t) OT_MY;
|
||||
break;
|
||||
|
||||
case 0x1063: case 0x1064: case 0x1069: case 0x106A:
|
||||
case 0x106B: case 0x106C: case 0x106D: case 0xAA7B:
|
||||
cat = (indic_category_t) OT_PT;
|
||||
break;
|
||||
|
||||
case 0x1038: case 0x1087: case 0x1088: case 0x1089:
|
||||
case 0x108A: case 0x108B: case 0x108C: case 0x108D:
|
||||
case 0x108F: case 0x109A: case 0x109B: case 0x109C:
|
||||
cat = (indic_category_t) OT_SM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cat == OT_M)
|
||||
{
|
||||
switch ((int) pos)
|
||||
{
|
||||
case POS_PRE_C: cat = (indic_category_t) OT_VPre;
|
||||
pos = POS_PRE_M; break;
|
||||
case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break;
|
||||
case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break;
|
||||
case POS_POST_C: cat = (indic_category_t) OT_VPst; break;
|
||||
}
|
||||
}
|
||||
|
||||
info.myanmar_category() = (myanmar_category_t) cat;
|
||||
info.myanmar_position() = pos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font HB_UNUSED)
|
||||
{
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_category);
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_position);
|
||||
|
||||
/* We cannot setup masks here. We save information about characters
|
||||
* and setup masks later on in a pause-callback. */
|
||||
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
set_myanmar_properties (buffer->info[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
find_syllables (buffer);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
|
||||
{
|
||||
int a = pa->myanmar_position();
|
||||
int b = pb->myanmar_position();
|
||||
|
||||
return a < b ? -1 : a == b ? 0 : +1;
|
||||
}
|
||||
|
||||
|
||||
/* Rules from:
|
||||
* http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm */
|
||||
|
||||
static void
|
||||
initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
|
||||
unsigned int base = end;
|
||||
bool has_reph = false;
|
||||
|
||||
{
|
||||
unsigned int limit = start;
|
||||
if (start + 3 <= end &&
|
||||
info[start ].myanmar_category() == OT_Ra &&
|
||||
info[start+1].myanmar_category() == OT_As &&
|
||||
info[start+2].myanmar_category() == OT_H)
|
||||
{
|
||||
limit += 3;
|
||||
base = start;
|
||||
has_reph = true;
|
||||
}
|
||||
|
||||
{
|
||||
if (!has_reph)
|
||||
base = limit;
|
||||
|
||||
for (unsigned int i = limit; i < end; i++)
|
||||
if (is_consonant (info[i]))
|
||||
{
|
||||
base = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reorder! */
|
||||
{
|
||||
unsigned int i = start;
|
||||
for (; i < start + (has_reph ? 3 : 0); i++)
|
||||
info[i].myanmar_position() = POS_AFTER_MAIN;
|
||||
for (; i < base; i++)
|
||||
info[i].myanmar_position() = POS_PRE_C;
|
||||
if (i < end)
|
||||
{
|
||||
info[i].myanmar_position() = POS_BASE_C;
|
||||
i++;
|
||||
}
|
||||
indic_position_t pos = POS_AFTER_MAIN;
|
||||
/* The following loop may be ugly, but it implements all of
|
||||
* Myanmar reordering! */
|
||||
for (; i < end; i++)
|
||||
{
|
||||
if (info[i].myanmar_category() == OT_MR) /* Pre-base reordering */
|
||||
{
|
||||
info[i].myanmar_position() = POS_PRE_C;
|
||||
continue;
|
||||
}
|
||||
if (info[i].myanmar_position() < POS_BASE_C) /* Left matra */
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pos == POS_AFTER_MAIN && info[i].myanmar_category() == OT_VBlw)
|
||||
{
|
||||
pos = POS_BELOW_C;
|
||||
info[i].myanmar_position() = pos;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_A)
|
||||
{
|
||||
info[i].myanmar_position() = POS_BEFORE_SUB;
|
||||
continue;
|
||||
}
|
||||
if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_VBlw)
|
||||
{
|
||||
info[i].myanmar_position() = pos;
|
||||
continue;
|
||||
}
|
||||
if (pos == POS_BELOW_C && info[i].myanmar_category() != OT_A)
|
||||
{
|
||||
pos = POS_AFTER_SUB;
|
||||
info[i].myanmar_position() = pos;
|
||||
continue;
|
||||
}
|
||||
info[i].myanmar_position() = pos;
|
||||
}
|
||||
}
|
||||
|
||||
buffer->merge_clusters (start, end);
|
||||
/* Sit tight, rock 'n roll! */
|
||||
hb_bubble_sort (info + start, end - start, compare_myanmar_order);
|
||||
}
|
||||
|
||||
static void
|
||||
initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
/* We already inserted dotted-circles, so just call the consonant_syllable. */
|
||||
initial_reordering_consonant_syllable (plan, face, buffer, start, end);
|
||||
}
|
||||
|
||||
static void
|
||||
initial_reordering_non_myanmar_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_face_t *face HB_UNUSED,
|
||||
hb_buffer_t *buffer HB_UNUSED,
|
||||
unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
|
||||
{
|
||||
/* Nothing to do right now. If we ever switch to using the output
|
||||
* buffer in the reordering process, we'd need to next_glyph() here. */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
|
||||
switch (syllable_type) {
|
||||
case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
|
||||
case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
|
||||
case non_myanmar_cluster: initial_reordering_non_myanmar_cluster (plan, face, buffer, start, end); return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
/* Note: This loop is extra overhead, but should not be measurable. */
|
||||
bool has_broken_syllables = false;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) {
|
||||
has_broken_syllables = true;
|
||||
break;
|
||||
}
|
||||
if (likely (!has_broken_syllables))
|
||||
return;
|
||||
|
||||
|
||||
hb_codepoint_t dottedcircle_glyph;
|
||||
if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
|
||||
return;
|
||||
|
||||
hb_glyph_info_t dottedcircle = {0};
|
||||
dottedcircle.codepoint = 0x25CC;
|
||||
set_myanmar_properties (dottedcircle);
|
||||
dottedcircle.codepoint = dottedcircle_glyph;
|
||||
|
||||
buffer->clear_output ();
|
||||
|
||||
buffer->idx = 0;
|
||||
unsigned int last_syllable = 0;
|
||||
while (buffer->idx < buffer->len)
|
||||
{
|
||||
unsigned int syllable = buffer->cur().syllable();
|
||||
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
|
||||
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
|
||||
{
|
||||
last_syllable = syllable;
|
||||
|
||||
hb_glyph_info_t info = dottedcircle;
|
||||
info.cluster = buffer->cur().cluster;
|
||||
info.mask = buffer->cur().mask;
|
||||
info.syllable() = buffer->cur().syllable();
|
||||
|
||||
buffer->output_info (info);
|
||||
}
|
||||
else
|
||||
buffer->next_glyph ();
|
||||
}
|
||||
|
||||
buffer->swap_buffers ();
|
||||
}
|
||||
|
||||
static void
|
||||
initial_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
insert_dotted_circles (plan, font, buffer);
|
||||
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
if (unlikely (!count)) return;
|
||||
unsigned int last = 0;
|
||||
unsigned int last_syllable = info[0].syllable();
|
||||
for (unsigned int i = 1; i < count; i++)
|
||||
if (last_syllable != info[i].syllable()) {
|
||||
initial_reordering_syllable (plan, font->face, buffer, last, i);
|
||||
last = i;
|
||||
last_syllable = info[last].syllable();
|
||||
}
|
||||
initial_reordering_syllable (plan, font->face, buffer, last, count);
|
||||
}
|
||||
|
||||
static void
|
||||
final_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
|
||||
/* Zero syllables now... */
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
info[i].syllable() = 0;
|
||||
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category);
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
|
||||
}
|
||||
|
||||
|
||||
static hb_ot_shape_normalization_mode_t
|
||||
normalization_preference_myanmar (const hb_segment_properties_t *props HB_UNUSED)
|
||||
{
|
||||
return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
|
||||
}
|
||||
|
||||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
|
||||
{
|
||||
"myanmar",
|
||||
collect_features_myanmar,
|
||||
override_features_myanmar,
|
||||
NULL, /* data_create */
|
||||
NULL, /* data_destroy */
|
||||
NULL, /* preprocess_text */
|
||||
normalization_preference_myanmar,
|
||||
NULL, /* decompose */
|
||||
NULL, /* compose */
|
||||
setup_masks_myanmar,
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
|
||||
false, /* fallback_position */
|
||||
};
|
359
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
vendored
Normal file
359
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
vendored
Normal file
@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright © 2010,2011,2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_SHAPE_COMPLEX_PRIVATE_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-ot-shape-private.hh"
|
||||
#include "hb-ot-shape-normalize-private.hh"
|
||||
|
||||
|
||||
|
||||
/* buffer var allocations, used by complex shapers */
|
||||
#define complex_var_u8_0() var2.u8[2]
|
||||
#define complex_var_u8_1() var2.u8[3]
|
||||
|
||||
|
||||
enum hb_ot_shape_zero_width_marks_type_t {
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
|
||||
// HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY,
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE
|
||||
};
|
||||
|
||||
|
||||
/* Master OT shaper list */
|
||||
#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
|
||||
HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \
|
||||
HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
|
||||
HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
|
||||
HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
|
||||
HB_COMPLEX_SHAPER_IMPLEMENT (sea) \
|
||||
HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
|
||||
/* ^--- Add new shapers here */
|
||||
|
||||
|
||||
struct hb_ot_complex_shaper_t
|
||||
{
|
||||
char name[8];
|
||||
|
||||
/* collect_features()
|
||||
* Called during shape_plan().
|
||||
* Shapers should use plan->map to add their features and callbacks.
|
||||
* May be NULL.
|
||||
*/
|
||||
void (*collect_features) (hb_ot_shape_planner_t *plan);
|
||||
|
||||
/* override_features()
|
||||
* Called during shape_plan().
|
||||
* Shapers should use plan->map to override features and add callbacks after
|
||||
* common features are added.
|
||||
* May be NULL.
|
||||
*/
|
||||
void (*override_features) (hb_ot_shape_planner_t *plan);
|
||||
|
||||
|
||||
/* data_create()
|
||||
* Called at the end of shape_plan().
|
||||
* Whatever shapers return will be accessible through plan->data later.
|
||||
* If NULL is returned, means a plan failure.
|
||||
*/
|
||||
void *(*data_create) (const hb_ot_shape_plan_t *plan);
|
||||
|
||||
/* data_destroy()
|
||||
* Called when the shape_plan is being destroyed.
|
||||
* plan->data is passed here for destruction.
|
||||
* If NULL is returned, means a plan failure.
|
||||
* May be NULL.
|
||||
*/
|
||||
void (*data_destroy) (void *data);
|
||||
|
||||
|
||||
/* preprocess_text()
|
||||
* Called during shape().
|
||||
* Shapers can use to modify text before shaping starts.
|
||||
* May be NULL.
|
||||
*/
|
||||
void (*preprocess_text) (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font);
|
||||
|
||||
|
||||
/* normalization_preference()
|
||||
* Called during shape().
|
||||
* May be NULL.
|
||||
*/
|
||||
hb_ot_shape_normalization_mode_t
|
||||
(*normalization_preference) (const hb_segment_properties_t *props);
|
||||
|
||||
/* decompose()
|
||||
* Called during shape()'s normalization.
|
||||
* May be NULL.
|
||||
*/
|
||||
bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
|
||||
hb_codepoint_t ab,
|
||||
hb_codepoint_t *a,
|
||||
hb_codepoint_t *b);
|
||||
|
||||
/* compose()
|
||||
* Called during shape()'s normalization.
|
||||
* May be NULL.
|
||||
*/
|
||||
bool (*compose) (const hb_ot_shape_normalize_context_t *c,
|
||||
hb_codepoint_t a,
|
||||
hb_codepoint_t b,
|
||||
hb_codepoint_t *ab);
|
||||
|
||||
/* setup_masks()
|
||||
* Called during shape().
|
||||
* Shapers should use map to get feature masks and set on buffer.
|
||||
* Shapers may NOT modify characters.
|
||||
* May be NULL.
|
||||
*/
|
||||
void (*setup_masks) (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font);
|
||||
|
||||
hb_ot_shape_zero_width_marks_type_t zero_width_marks;
|
||||
|
||||
bool fallback_position;
|
||||
};
|
||||
|
||||
#define HB_COMPLEX_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_complex_shaper_t _hb_ot_complex_shaper_##name;
|
||||
HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
|
||||
#undef HB_COMPLEX_SHAPER_IMPLEMENT
|
||||
|
||||
|
||||
static inline const hb_ot_complex_shaper_t *
|
||||
hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
|
||||
{
|
||||
switch ((hb_tag_t) planner->props.script)
|
||||
{
|
||||
default:
|
||||
return &_hb_ot_complex_shaper_default;
|
||||
|
||||
|
||||
/* Unicode-1.1 additions */
|
||||
case HB_SCRIPT_ARABIC:
|
||||
|
||||
/* Unicode-3.0 additions */
|
||||
case HB_SCRIPT_MONGOLIAN:
|
||||
case HB_SCRIPT_SYRIAC:
|
||||
|
||||
/* Unicode-5.0 additions */
|
||||
case HB_SCRIPT_NKO:
|
||||
case HB_SCRIPT_PHAGS_PA:
|
||||
|
||||
/* Unicode-6.0 additions */
|
||||
case HB_SCRIPT_MANDAIC:
|
||||
|
||||
/* For Arabic script, use the Arabic shaper even if no OT script tag was found.
|
||||
* This is because we do fallback shaping for Arabic script (and not others). */
|
||||
if (planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT ||
|
||||
planner->props.script == HB_SCRIPT_ARABIC)
|
||||
return &_hb_ot_complex_shaper_arabic;
|
||||
else
|
||||
return &_hb_ot_complex_shaper_default;
|
||||
|
||||
|
||||
/* Unicode-1.1 additions */
|
||||
case HB_SCRIPT_THAI:
|
||||
case HB_SCRIPT_LAO:
|
||||
|
||||
return &_hb_ot_complex_shaper_thai;
|
||||
|
||||
|
||||
#if 0
|
||||
/* Note:
|
||||
* Currently we don't have a separate Hangul shaper. The default shaper handles
|
||||
* Hangul by enabling jamo features. We may want to implement a separate shaper
|
||||
* in the future. See this thread for details of what such a shaper would do:
|
||||
*
|
||||
* http://lists.freedesktop.org/archives/harfbuzz/2013-April/003070.html
|
||||
*/
|
||||
/* Unicode-1.1 additions */
|
||||
case HB_SCRIPT_HANGUL:
|
||||
|
||||
return &_hb_ot_complex_shaper_hangul;
|
||||
#endif
|
||||
|
||||
|
||||
/* ^--- Add new shapers here */
|
||||
|
||||
|
||||
#if 0
|
||||
/* Note:
|
||||
*
|
||||
* These disabled scripts are listed in ucd/IndicSyllabicCategory.txt, but according
|
||||
* to Martin Hosken and Jonathan Kew do not require complex shaping.
|
||||
*
|
||||
* TODO We should automate figuring out which scripts do not need complex shaping
|
||||
*
|
||||
* TODO We currently keep data for these scripts in our indic table. Need to fix the
|
||||
* generator to not do that.
|
||||
*/
|
||||
|
||||
|
||||
/* Simple? */
|
||||
|
||||
/* Unicode-3.2 additions */
|
||||
case HB_SCRIPT_BUHID:
|
||||
case HB_SCRIPT_HANUNOO:
|
||||
|
||||
/* Unicode-5.1 additions */
|
||||
case HB_SCRIPT_SAURASHTRA:
|
||||
|
||||
/* Unicode-6.0 additions */
|
||||
case HB_SCRIPT_BATAK:
|
||||
case HB_SCRIPT_BRAHMI:
|
||||
|
||||
|
||||
/* Simple */
|
||||
|
||||
/* Unicode-1.1 additions */
|
||||
/* These have their own shaper now. */
|
||||
case HB_SCRIPT_LAO:
|
||||
case HB_SCRIPT_THAI:
|
||||
|
||||
/* Unicode-2.0 additions */
|
||||
case HB_SCRIPT_TIBETAN:
|
||||
|
||||
/* Unicode-3.2 additions */
|
||||
case HB_SCRIPT_TAGALOG:
|
||||
case HB_SCRIPT_TAGBANWA:
|
||||
|
||||
/* Unicode-4.0 additions */
|
||||
case HB_SCRIPT_LIMBU:
|
||||
case HB_SCRIPT_TAI_LE:
|
||||
|
||||
/* Unicode-4.1 additions */
|
||||
case HB_SCRIPT_KHAROSHTHI:
|
||||
case HB_SCRIPT_SYLOTI_NAGRI:
|
||||
|
||||
/* Unicode-5.1 additions */
|
||||
case HB_SCRIPT_KAYAH_LI:
|
||||
|
||||
/* Unicode-5.2 additions */
|
||||
case HB_SCRIPT_TAI_VIET:
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* Unicode-1.1 additions */
|
||||
case HB_SCRIPT_BENGALI:
|
||||
case HB_SCRIPT_DEVANAGARI:
|
||||
case HB_SCRIPT_GUJARATI:
|
||||
case HB_SCRIPT_GURMUKHI:
|
||||
case HB_SCRIPT_KANNADA:
|
||||
case HB_SCRIPT_MALAYALAM:
|
||||
case HB_SCRIPT_ORIYA:
|
||||
case HB_SCRIPT_TAMIL:
|
||||
case HB_SCRIPT_TELUGU:
|
||||
|
||||
/* Unicode-3.0 additions */
|
||||
case HB_SCRIPT_SINHALA:
|
||||
|
||||
/* Unicode-4.1 additions */
|
||||
case HB_SCRIPT_BUGINESE:
|
||||
|
||||
/* Unicode-5.0 additions */
|
||||
case HB_SCRIPT_BALINESE:
|
||||
|
||||
/* Unicode-5.1 additions */
|
||||
case HB_SCRIPT_LEPCHA:
|
||||
case HB_SCRIPT_REJANG:
|
||||
case HB_SCRIPT_SUNDANESE:
|
||||
|
||||
/* Unicode-5.2 additions */
|
||||
case HB_SCRIPT_JAVANESE:
|
||||
case HB_SCRIPT_KAITHI:
|
||||
case HB_SCRIPT_MEETEI_MAYEK:
|
||||
|
||||
/* Unicode-6.0 additions */
|
||||
|
||||
/* Unicode-6.1 additions */
|
||||
case HB_SCRIPT_CHAKMA:
|
||||
case HB_SCRIPT_SHARADA:
|
||||
case HB_SCRIPT_TAKRI:
|
||||
|
||||
/* If the designer designed the font for the 'DFLT' script,
|
||||
* use the default shaper. Otherwise, use the Indic shaper.
|
||||
* Note that for some simple scripts, there may not be *any*
|
||||
* GSUB/GPOS needed, so there may be no scripts found! */
|
||||
if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T'))
|
||||
return &_hb_ot_complex_shaper_default;
|
||||
else
|
||||
return &_hb_ot_complex_shaper_indic;
|
||||
|
||||
case HB_SCRIPT_KHMER:
|
||||
/* A number of Khmer fonts in the wild don't have a 'pref' feature,
|
||||
* and as such won't shape properly via the Indic shaper;
|
||||
* however, they typically have 'liga' / 'clig' features that implement
|
||||
* the necessary "reordering" by means of ligature substitutions.
|
||||
* So we send such pref-less fonts through the generic shaper instead. */
|
||||
if (planner->map.found_script[0] &&
|
||||
hb_ot_layout_language_find_feature (planner->face, HB_OT_TAG_GSUB,
|
||||
planner->map.script_index[0],
|
||||
planner->map.language_index[0],
|
||||
HB_TAG ('p','r','e','f'),
|
||||
NULL))
|
||||
return &_hb_ot_complex_shaper_indic;
|
||||
else
|
||||
return &_hb_ot_complex_shaper_default;
|
||||
|
||||
case HB_SCRIPT_MYANMAR:
|
||||
/* For Myanmar, we only want to use the Myanmar shaper if the "new" script
|
||||
* tag is found. For "old" script tag we want to use the default shaper. */
|
||||
if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2'))
|
||||
return &_hb_ot_complex_shaper_myanmar;
|
||||
else
|
||||
return &_hb_ot_complex_shaper_default;
|
||||
|
||||
/* Unicode-4.1 additions */
|
||||
case HB_SCRIPT_NEW_TAI_LUE:
|
||||
|
||||
/* Unicode-5.1 additions */
|
||||
case HB_SCRIPT_CHAM:
|
||||
|
||||
/* Unicode-5.2 additions */
|
||||
case HB_SCRIPT_TAI_THAM:
|
||||
|
||||
/* If the designer designed the font for the 'DFLT' script,
|
||||
* use the default shaper. Otherwise, use the Indic shaper.
|
||||
* Note that for some simple scripts, there may not be *any*
|
||||
* GSUB/GPOS needed, so there may be no scripts found! */
|
||||
if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T'))
|
||||
return &_hb_ot_complex_shaper_default;
|
||||
else
|
||||
return &_hb_ot_complex_shaper_sea;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_PRIVATE_HH */
|
224
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea-machine.hh
vendored
Normal file
224
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea-machine.hh
vendored
Normal file
@ -0,0 +1,224 @@
|
||||
|
||||
#line 1 "hb-ot-shape-complex-sea-machine.rl"
|
||||
/*
|
||||
* Copyright © 2011,2012,2013 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
#line 36 "hb-ot-shape-complex-sea-machine.hh"
|
||||
static const unsigned char _sea_syllable_machine_trans_keys[] = {
|
||||
1u, 1u, 1u, 1u, 1u, 29u, 3u, 29u, 3u, 29u, 1u, 1u, 0
|
||||
};
|
||||
|
||||
static const char _sea_syllable_machine_key_spans[] = {
|
||||
1, 1, 29, 27, 27, 1
|
||||
};
|
||||
|
||||
static const char _sea_syllable_machine_index_offsets[] = {
|
||||
0, 2, 4, 34, 62, 90
|
||||
};
|
||||
|
||||
static const char _sea_syllable_machine_indicies[] = {
|
||||
1, 0, 3, 2, 1, 1, 3, 5,
|
||||
4, 4, 4, 4, 4, 3, 4, 1,
|
||||
4, 4, 4, 4, 3, 4, 4, 4,
|
||||
4, 3, 4, 4, 4, 3, 3, 3,
|
||||
3, 4, 1, 7, 6, 6, 6, 6,
|
||||
6, 1, 6, 6, 6, 6, 6, 6,
|
||||
1, 6, 6, 6, 6, 1, 6, 6,
|
||||
6, 1, 1, 1, 1, 6, 3, 9,
|
||||
8, 8, 8, 8, 8, 3, 8, 8,
|
||||
8, 8, 8, 8, 3, 8, 8, 8,
|
||||
8, 3, 8, 8, 8, 3, 3, 3,
|
||||
3, 8, 3, 10, 0
|
||||
};
|
||||
|
||||
static const char _sea_syllable_machine_trans_targs[] = {
|
||||
2, 3, 2, 4, 2, 5, 2, 0,
|
||||
2, 1, 2
|
||||
};
|
||||
|
||||
static const char _sea_syllable_machine_trans_actions[] = {
|
||||
1, 2, 3, 2, 6, 0, 7, 0,
|
||||
8, 0, 9
|
||||
};
|
||||
|
||||
static const char _sea_syllable_machine_to_state_actions[] = {
|
||||
0, 0, 4, 0, 0, 0
|
||||
};
|
||||
|
||||
static const char _sea_syllable_machine_from_state_actions[] = {
|
||||
0, 0, 5, 0, 0, 0
|
||||
};
|
||||
|
||||
static const char _sea_syllable_machine_eof_trans[] = {
|
||||
1, 3, 0, 7, 9, 11
|
||||
};
|
||||
|
||||
static const int sea_syllable_machine_start = 2;
|
||||
static const int sea_syllable_machine_first_final = 2;
|
||||
static const int sea_syllable_machine_error = -1;
|
||||
|
||||
static const int sea_syllable_machine_en_main = 2;
|
||||
|
||||
|
||||
#line 36 "hb-ot-shape-complex-sea-machine.rl"
|
||||
|
||||
|
||||
|
||||
#line 67 "hb-ot-shape-complex-sea-machine.rl"
|
||||
|
||||
|
||||
#define found_syllable(syllable_type) \
|
||||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
|
||||
for (unsigned int i = last; i < p+1; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
last = p+1; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
|
||||
int cs;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
|
||||
#line 117 "hb-ot-shape-complex-sea-machine.hh"
|
||||
{
|
||||
cs = sea_syllable_machine_start;
|
||||
ts = 0;
|
||||
te = 0;
|
||||
act = 0;
|
||||
}
|
||||
|
||||
#line 88 "hb-ot-shape-complex-sea-machine.rl"
|
||||
|
||||
|
||||
p = 0;
|
||||
pe = eof = buffer->len;
|
||||
|
||||
unsigned int last = 0;
|
||||
unsigned int syllable_serial = 1;
|
||||
|
||||
#line 134 "hb-ot-shape-complex-sea-machine.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
const unsigned char *_keys;
|
||||
const char *_inds;
|
||||
if ( p == pe )
|
||||
goto _test_eof;
|
||||
_resume:
|
||||
switch ( _sea_syllable_machine_from_state_actions[cs] ) {
|
||||
case 5:
|
||||
#line 1 "NONE"
|
||||
{ts = p;}
|
||||
break;
|
||||
#line 148 "hb-ot-shape-complex-sea-machine.hh"
|
||||
}
|
||||
|
||||
_keys = _sea_syllable_machine_trans_keys + (cs<<1);
|
||||
_inds = _sea_syllable_machine_indicies + _sea_syllable_machine_index_offsets[cs];
|
||||
|
||||
_slen = _sea_syllable_machine_key_spans[cs];
|
||||
_trans = _inds[ _slen > 0 && _keys[0] <=( info[p].sea_category()) &&
|
||||
( info[p].sea_category()) <= _keys[1] ?
|
||||
( info[p].sea_category()) - _keys[0] : _slen ];
|
||||
|
||||
_eof_trans:
|
||||
cs = _sea_syllable_machine_trans_targs[_trans];
|
||||
|
||||
if ( _sea_syllable_machine_trans_actions[_trans] == 0 )
|
||||
goto _again;
|
||||
|
||||
switch ( _sea_syllable_machine_trans_actions[_trans] ) {
|
||||
case 2:
|
||||
#line 1 "NONE"
|
||||
{te = p+1;}
|
||||
break;
|
||||
case 6:
|
||||
#line 63 "hb-ot-shape-complex-sea-machine.rl"
|
||||
{te = p+1;{ found_syllable (non_sea_cluster); }}
|
||||
break;
|
||||
case 7:
|
||||
#line 61 "hb-ot-shape-complex-sea-machine.rl"
|
||||
{te = p;p--;{ found_syllable (consonant_syllable); }}
|
||||
break;
|
||||
case 8:
|
||||
#line 62 "hb-ot-shape-complex-sea-machine.rl"
|
||||
{te = p;p--;{ found_syllable (broken_cluster); }}
|
||||
break;
|
||||
case 9:
|
||||
#line 63 "hb-ot-shape-complex-sea-machine.rl"
|
||||
{te = p;p--;{ found_syllable (non_sea_cluster); }}
|
||||
break;
|
||||
case 1:
|
||||
#line 61 "hb-ot-shape-complex-sea-machine.rl"
|
||||
{{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
|
||||
break;
|
||||
case 3:
|
||||
#line 62 "hb-ot-shape-complex-sea-machine.rl"
|
||||
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
|
||||
break;
|
||||
#line 194 "hb-ot-shape-complex-sea-machine.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
switch ( _sea_syllable_machine_to_state_actions[cs] ) {
|
||||
case 4:
|
||||
#line 1 "NONE"
|
||||
{ts = 0;}
|
||||
break;
|
||||
#line 203 "hb-ot-shape-complex-sea-machine.hh"
|
||||
}
|
||||
|
||||
if ( ++p != pe )
|
||||
goto _resume;
|
||||
_test_eof: {}
|
||||
if ( p == eof )
|
||||
{
|
||||
if ( _sea_syllable_machine_eof_trans[cs] > 0 ) {
|
||||
_trans = _sea_syllable_machine_eof_trans[cs] - 1;
|
||||
goto _eof_trans;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#line 97 "hb-ot-shape-complex-sea-machine.rl"
|
||||
|
||||
}
|
||||
|
||||
#undef found_syllable
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH */
|
384
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
vendored
Normal file
384
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
vendored
Normal file
@ -0,0 +1,384 @@
|
||||
/*
|
||||
* Copyright © 2011,2012,2013 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-complex-indic-private.hh"
|
||||
|
||||
/* buffer var allocations */
|
||||
#define sea_category() complex_var_u8_0() /* indic_category_t */
|
||||
#define sea_position() complex_var_u8_1() /* indic_position_t */
|
||||
|
||||
|
||||
/*
|
||||
* South-East Asian shaper.
|
||||
* Loosely based on the Myanmar spec / shaper.
|
||||
* There is no OpenType spec for this.
|
||||
*/
|
||||
|
||||
static const hb_tag_t
|
||||
basic_features[] =
|
||||
{
|
||||
/*
|
||||
* Basic features.
|
||||
* These features are applied in order, one at a time, after initial_reordering.
|
||||
*/
|
||||
HB_TAG('p','r','e','f'),
|
||||
HB_TAG('a','b','v','f'),
|
||||
HB_TAG('b','l','w','f'),
|
||||
HB_TAG('p','s','t','f'),
|
||||
};
|
||||
static const hb_tag_t
|
||||
other_features[] =
|
||||
{
|
||||
/*
|
||||
* Other features.
|
||||
* These features are applied all at once, after final_reordering.
|
||||
*/
|
||||
HB_TAG('p','r','e','s'),
|
||||
HB_TAG('a','b','v','s'),
|
||||
HB_TAG('b','l','w','s'),
|
||||
HB_TAG('p','s','t','s'),
|
||||
/* Positioning features, though we don't care about the types. */
|
||||
HB_TAG('d','i','s','t'),
|
||||
};
|
||||
|
||||
static void
|
||||
setup_syllables (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
initial_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
final_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
static void
|
||||
collect_features_sea (hb_ot_shape_planner_t *plan)
|
||||
{
|
||||
hb_ot_map_builder_t *map = &plan->map;
|
||||
|
||||
/* Do this before any lookups have been applied. */
|
||||
map->add_gsub_pause (setup_syllables);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
|
||||
/* The Indic specs do not require ccmp, but we apply it here since if
|
||||
* there is a use of it, it's typically at the beginning. */
|
||||
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
|
||||
|
||||
map->add_gsub_pause (initial_reordering);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
|
||||
{
|
||||
map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
|
||||
map->add_gsub_pause (NULL);
|
||||
}
|
||||
map->add_gsub_pause (final_reordering);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
|
||||
map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
|
||||
}
|
||||
|
||||
static void
|
||||
override_features_sea (hb_ot_shape_planner_t *plan)
|
||||
{
|
||||
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
|
||||
}
|
||||
|
||||
|
||||
enum syllable_type_t {
|
||||
consonant_syllable,
|
||||
broken_cluster,
|
||||
non_sea_cluster,
|
||||
};
|
||||
|
||||
#include "hb-ot-shape-complex-sea-machine.hh"
|
||||
|
||||
|
||||
/* Note: This enum is duplicated in the -machine.rl source file.
|
||||
* Not sure how to avoid duplication. */
|
||||
enum sea_category_t {
|
||||
// OT_C = 1,
|
||||
OT_GB = 12, /* Generic Base XXX DOTTED CIRCLE only for now */
|
||||
// OT_H = 4, /* Halant */
|
||||
OT_IV = 2, /* Independent Vowel */
|
||||
OT_MR = 22, /* Medial Ra */
|
||||
// OT_CM = 17, /* Consonant Medial */
|
||||
OT_VAbv = 26,
|
||||
OT_VBlw = 27,
|
||||
OT_VPre = 28,
|
||||
OT_VPst = 29,
|
||||
OT_T = 3, /* Tone Marks */
|
||||
// OT_A = 10, /* Anusvara */
|
||||
};
|
||||
|
||||
static inline void
|
||||
set_sea_properties (hb_glyph_info_t &info)
|
||||
{
|
||||
hb_codepoint_t u = info.codepoint;
|
||||
unsigned int type = hb_indic_get_categories (u);
|
||||
indic_category_t cat = (indic_category_t) (type & 0x7F);
|
||||
indic_position_t pos = (indic_position_t) (type >> 8);
|
||||
|
||||
/* Medial Ra */
|
||||
if (u == 0x1A55 || u == 0xAA34)
|
||||
cat = (indic_category_t) OT_MR;
|
||||
|
||||
if (cat == OT_M)
|
||||
{
|
||||
switch ((int) pos)
|
||||
{
|
||||
case POS_PRE_C: cat = (indic_category_t) OT_VPre; break;
|
||||
case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break;
|
||||
case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break;
|
||||
case POS_POST_C: cat = (indic_category_t) OT_VPst; break;
|
||||
}
|
||||
}
|
||||
|
||||
info.sea_category() = (sea_category_t) cat;
|
||||
info.sea_position() = pos;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_masks_sea (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font HB_UNUSED)
|
||||
{
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, sea_category);
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, sea_position);
|
||||
|
||||
/* We cannot setup masks here. We save information about characters
|
||||
* and setup masks later on in a pause-callback. */
|
||||
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
set_sea_properties (buffer->info[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
find_syllables (buffer);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_sea_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
|
||||
{
|
||||
int a = pa->sea_position();
|
||||
int b = pb->sea_position();
|
||||
|
||||
return a < b ? -1 : a == b ? 0 : +1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int base = start;
|
||||
|
||||
/* Reorder! */
|
||||
unsigned int i = start;
|
||||
for (; i < base; i++)
|
||||
info[i].sea_position() = POS_PRE_C;
|
||||
if (i < end)
|
||||
{
|
||||
info[i].sea_position() = POS_BASE_C;
|
||||
i++;
|
||||
}
|
||||
for (; i < end; i++)
|
||||
{
|
||||
if (info[i].sea_category() == OT_MR) /* Pre-base reordering */
|
||||
{
|
||||
info[i].sea_position() = POS_PRE_C;
|
||||
continue;
|
||||
}
|
||||
if (info[i].sea_category() == OT_VPre) /* Left matra */
|
||||
{
|
||||
info[i].sea_position() = POS_PRE_M;
|
||||
continue;
|
||||
}
|
||||
|
||||
info[i].sea_position() = POS_AFTER_MAIN;
|
||||
}
|
||||
|
||||
buffer->merge_clusters (start, end);
|
||||
/* Sit tight, rock 'n roll! */
|
||||
hb_bubble_sort (info + start, end - start, compare_sea_order);
|
||||
}
|
||||
|
||||
static void
|
||||
initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
/* We already inserted dotted-circles, so just call the consonant_syllable. */
|
||||
initial_reordering_consonant_syllable (plan, face, buffer, start, end);
|
||||
}
|
||||
|
||||
static void
|
||||
initial_reordering_non_sea_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_face_t *face HB_UNUSED,
|
||||
hb_buffer_t *buffer HB_UNUSED,
|
||||
unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
|
||||
{
|
||||
/* Nothing to do right now. If we ever switch to using the output
|
||||
* buffer in the reordering process, we'd need to next_glyph() here. */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
|
||||
switch (syllable_type) {
|
||||
case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
|
||||
case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
|
||||
case non_sea_cluster: initial_reordering_non_sea_cluster (plan, face, buffer, start, end); return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
/* Note: This loop is extra overhead, but should not be measurable. */
|
||||
bool has_broken_syllables = false;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) {
|
||||
has_broken_syllables = true;
|
||||
break;
|
||||
}
|
||||
if (likely (!has_broken_syllables))
|
||||
return;
|
||||
|
||||
|
||||
hb_codepoint_t dottedcircle_glyph;
|
||||
if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
|
||||
return;
|
||||
|
||||
hb_glyph_info_t dottedcircle = {0};
|
||||
dottedcircle.codepoint = 0x25CC;
|
||||
set_sea_properties (dottedcircle);
|
||||
dottedcircle.codepoint = dottedcircle_glyph;
|
||||
|
||||
buffer->clear_output ();
|
||||
|
||||
buffer->idx = 0;
|
||||
unsigned int last_syllable = 0;
|
||||
while (buffer->idx < buffer->len)
|
||||
{
|
||||
unsigned int syllable = buffer->cur().syllable();
|
||||
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
|
||||
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
|
||||
{
|
||||
last_syllable = syllable;
|
||||
|
||||
hb_glyph_info_t info = dottedcircle;
|
||||
info.cluster = buffer->cur().cluster;
|
||||
info.mask = buffer->cur().mask;
|
||||
info.syllable() = buffer->cur().syllable();
|
||||
|
||||
buffer->output_info (info);
|
||||
}
|
||||
else
|
||||
buffer->next_glyph ();
|
||||
}
|
||||
|
||||
buffer->swap_buffers ();
|
||||
}
|
||||
|
||||
static void
|
||||
initial_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
insert_dotted_circles (plan, font, buffer);
|
||||
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
if (unlikely (!count)) return;
|
||||
unsigned int last = 0;
|
||||
unsigned int last_syllable = info[0].syllable();
|
||||
for (unsigned int i = 1; i < count; i++)
|
||||
if (last_syllable != info[i].syllable()) {
|
||||
initial_reordering_syllable (plan, font->face, buffer, last, i);
|
||||
last = i;
|
||||
last_syllable = info[last].syllable();
|
||||
}
|
||||
initial_reordering_syllable (plan, font->face, buffer, last, count);
|
||||
}
|
||||
|
||||
static void
|
||||
final_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
|
||||
/* Zero syllables now... */
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
info[i].syllable() = 0;
|
||||
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, sea_category);
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, sea_position);
|
||||
}
|
||||
|
||||
|
||||
static hb_ot_shape_normalization_mode_t
|
||||
normalization_preference_sea (const hb_segment_properties_t *props HB_UNUSED)
|
||||
{
|
||||
return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
|
||||
}
|
||||
|
||||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_sea =
|
||||
{
|
||||
"sea",
|
||||
collect_features_sea,
|
||||
override_features_sea,
|
||||
NULL, /* data_create */
|
||||
NULL, /* data_destroy */
|
||||
NULL, /* preprocess_text */
|
||||
normalization_preference_sea,
|
||||
NULL, /* decompose */
|
||||
NULL, /* compose */
|
||||
setup_masks_sea,
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
|
||||
false, /* fallback_position */
|
||||
};
|
378
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
vendored
Normal file
378
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
vendored
Normal file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright © 2010,2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-complex-private.hh"
|
||||
|
||||
|
||||
/* Thai / Lao shaper */
|
||||
|
||||
|
||||
/* PUA shaping */
|
||||
|
||||
|
||||
enum thai_consonant_type_t
|
||||
{
|
||||
NC,
|
||||
AC,
|
||||
RC,
|
||||
DC,
|
||||
NOT_CONSONANT,
|
||||
NUM_CONSONANT_TYPES = NOT_CONSONANT
|
||||
};
|
||||
|
||||
static thai_consonant_type_t
|
||||
get_consonant_type (hb_codepoint_t u)
|
||||
{
|
||||
if (u == 0x0E1B || u == 0x0E1D || u == 0x0E1F/* || u == 0x0E2C*/)
|
||||
return AC;
|
||||
if (u == 0x0E0D || u == 0x0E10)
|
||||
return RC;
|
||||
if (u == 0x0E0E || u == 0x0E0F)
|
||||
return DC;
|
||||
if (hb_in_range<hb_codepoint_t> (u, 0x0E01, 0x0E2E))
|
||||
return NC;
|
||||
return NOT_CONSONANT;
|
||||
}
|
||||
|
||||
|
||||
enum thai_mark_type_t
|
||||
{
|
||||
AV,
|
||||
BV,
|
||||
T,
|
||||
NOT_MARK,
|
||||
NUM_MARK_TYPES = NOT_MARK
|
||||
};
|
||||
|
||||
static thai_mark_type_t
|
||||
get_mark_type (hb_codepoint_t u)
|
||||
{
|
||||
if (u == 0x0E31 || hb_in_range<hb_codepoint_t> (u, 0x0E34, 0x0E37) ||
|
||||
u == 0x0E47 || hb_in_range<hb_codepoint_t> (u, 0x0E4D, 0x0E4E))
|
||||
return AV;
|
||||
if (hb_in_range<hb_codepoint_t> (u, 0x0E38, 0x0E3A))
|
||||
return BV;
|
||||
if (hb_in_range<hb_codepoint_t> (u, 0x0E48, 0x0E4C))
|
||||
return T;
|
||||
return NOT_MARK;
|
||||
}
|
||||
|
||||
|
||||
enum thai_action_t
|
||||
{
|
||||
NOP,
|
||||
SD, /* Shift combining-mark down */
|
||||
SL, /* Shift combining-mark left */
|
||||
SDL, /* Shift combining-mark down-left */
|
||||
RD /* Remove descender from base */
|
||||
};
|
||||
|
||||
static hb_codepoint_t
|
||||
thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font)
|
||||
{
|
||||
struct thai_pua_mapping_t {
|
||||
hb_codepoint_t u;
|
||||
hb_codepoint_t win_pua;
|
||||
hb_codepoint_t mac_pua;
|
||||
} const *pua_mappings = NULL;
|
||||
static const thai_pua_mapping_t SD_mappings[] = {
|
||||
{0x0E48, 0xF70A, 0xF88B}, /* MAI EK */
|
||||
{0x0E49, 0xF70B, 0xF88E}, /* MAI THO */
|
||||
{0x0E4A, 0xF70C, 0xF891}, /* MAI TRI */
|
||||
{0x0E4B, 0xF70D, 0xF894}, /* MAI CHATTAWA */
|
||||
{0x0E4C, 0xF70E, 0xF897}, /* THANTHAKHAT */
|
||||
{0x0E38, 0xF718, 0xF89B}, /* SARA U */
|
||||
{0x0E39, 0xF719, 0xF89C}, /* SARA UU */
|
||||
{0x0E3A, 0xF71A, 0xF89D}, /* PHINTHU */
|
||||
{0x0000, 0x0000, 0x0000}
|
||||
};
|
||||
static const thai_pua_mapping_t SDL_mappings[] = {
|
||||
{0x0E48, 0xF705, 0xF88C}, /* MAI EK */
|
||||
{0x0E49, 0xF706, 0xF88F}, /* MAI THO */
|
||||
{0x0E4A, 0xF707, 0xF892}, /* MAI TRI */
|
||||
{0x0E4B, 0xF708, 0xF895}, /* MAI CHATTAWA */
|
||||
{0x0E4C, 0xF709, 0xF898}, /* THANTHAKHAT */
|
||||
{0x0000, 0x0000, 0x0000}
|
||||
};
|
||||
static const thai_pua_mapping_t SL_mappings[] = {
|
||||
{0x0E48, 0xF713, 0xF88A}, /* MAI EK */
|
||||
{0x0E49, 0xF714, 0xF88D}, /* MAI THO */
|
||||
{0x0E4A, 0xF715, 0xF890}, /* MAI TRI */
|
||||
{0x0E4B, 0xF716, 0xF893}, /* MAI CHATTAWA */
|
||||
{0x0E4C, 0xF717, 0xF896}, /* THANTHAKHAT */
|
||||
{0x0E31, 0xF710, 0xF884}, /* MAI HAN-AKAT */
|
||||
{0x0E34, 0xF701, 0xF885}, /* SARA I */
|
||||
{0x0E35, 0xF702, 0xF886}, /* SARA II */
|
||||
{0x0E36, 0xF703, 0xF887}, /* SARA UE */
|
||||
{0x0E37, 0xF704, 0xF888}, /* SARA UEE */
|
||||
{0x0E47, 0xF712, 0xF889}, /* MAITAIKHU */
|
||||
{0x0E4D, 0xF711, 0xF899}, /* NIKHAHIT */
|
||||
{0x0000, 0x0000, 0x0000}
|
||||
};
|
||||
static const thai_pua_mapping_t RD_mappings[] = {
|
||||
{0x0E0D, 0xF70F, 0xF89A}, /* YO YING */
|
||||
{0x0E10, 0xF700, 0xF89E}, /* THO THAN */
|
||||
{0x0000, 0x0000, 0x0000}
|
||||
};
|
||||
|
||||
switch (action) {
|
||||
default: assert (false); /* Fallthrough */
|
||||
case NOP: return u;
|
||||
case SD: pua_mappings = SD_mappings; break;
|
||||
case SDL: pua_mappings = SDL_mappings; break;
|
||||
case SL: pua_mappings = SL_mappings; break;
|
||||
case RD: pua_mappings = RD_mappings; break;
|
||||
}
|
||||
for (; pua_mappings->u; pua_mappings++)
|
||||
if (pua_mappings->u == u)
|
||||
{
|
||||
hb_codepoint_t glyph;
|
||||
if (hb_font_get_glyph (font, pua_mappings->win_pua, 0, &glyph))
|
||||
return pua_mappings->win_pua;
|
||||
if (hb_font_get_glyph (font, pua_mappings->mac_pua, 0, &glyph))
|
||||
return pua_mappings->mac_pua;
|
||||
break;
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
|
||||
static enum thai_above_state_t
|
||||
{ /* Cluster above looks like: */
|
||||
T0, /* ⣤ */
|
||||
T1, /* ⣼ */
|
||||
T2, /* ⣾ */
|
||||
T3, /* ⣿ */
|
||||
NUM_ABOVE_STATES
|
||||
} thai_above_start_state[NUM_CONSONANT_TYPES + 1/* For NOT_CONSONANT */] =
|
||||
{
|
||||
T0, /* NC */
|
||||
T1, /* AC */
|
||||
T0, /* RC */
|
||||
T0, /* DC */
|
||||
T3, /* NOT_CONSONANT */
|
||||
};
|
||||
|
||||
static const struct thai_above_state_machine_edge_t {
|
||||
thai_action_t action;
|
||||
thai_above_state_t next_state;
|
||||
} thai_above_state_machine[NUM_ABOVE_STATES][NUM_MARK_TYPES] =
|
||||
{ /*AV*/ /*BV*/ /*T*/
|
||||
/*T0*/ {{NOP,T3}, {NOP,T0}, {SD, T3}},
|
||||
/*T1*/ {{SL, T2}, {NOP,T1}, {SDL,T2}},
|
||||
/*T2*/ {{NOP,T3}, {NOP,T2}, {SL, T3}},
|
||||
/*T3*/ {{NOP,T3}, {NOP,T3}, {NOP,T3}},
|
||||
};
|
||||
|
||||
|
||||
static enum thai_below_state_t
|
||||
{
|
||||
B0, /* No descender */
|
||||
B1, /* Removable descender */
|
||||
B2, /* Strict descender */
|
||||
NUM_BELOW_STATES
|
||||
} thai_below_start_state[NUM_CONSONANT_TYPES + 1/* For NOT_CONSONANT */] =
|
||||
{
|
||||
B0, /* NC */
|
||||
B0, /* AC */
|
||||
B1, /* RC */
|
||||
B2, /* DC */
|
||||
B2, /* NOT_CONSONANT */
|
||||
};
|
||||
|
||||
static const struct thai_below_state_machine_edge_t {
|
||||
thai_action_t action;
|
||||
thai_below_state_t next_state;
|
||||
} thai_below_state_machine[NUM_BELOW_STATES][NUM_MARK_TYPES] =
|
||||
{ /*AV*/ /*BV*/ /*T*/
|
||||
/*B0*/ {{NOP,B0}, {NOP,B2}, {NOP, B0}},
|
||||
/*B1*/ {{NOP,B1}, {RD, B2}, {NOP, B1}},
|
||||
/*B2*/ {{NOP,B2}, {SD, B2}, {NOP, B2}},
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font)
|
||||
{
|
||||
thai_above_state_t above_state = thai_above_start_state[NOT_CONSONANT];
|
||||
thai_below_state_t below_state = thai_below_start_state[NOT_CONSONANT];
|
||||
unsigned int base = 0;
|
||||
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
thai_mark_type_t mt = get_mark_type (info[i].codepoint);
|
||||
|
||||
if (mt == NOT_MARK) {
|
||||
thai_consonant_type_t ct = get_consonant_type (info[i].codepoint);
|
||||
above_state = thai_above_start_state[ct];
|
||||
below_state = thai_below_start_state[ct];
|
||||
base = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
const thai_above_state_machine_edge_t &above_edge = thai_above_state_machine[above_state][mt];
|
||||
const thai_below_state_machine_edge_t &below_edge = thai_below_state_machine[below_state][mt];
|
||||
above_state = above_edge.next_state;
|
||||
below_state = below_edge.next_state;
|
||||
|
||||
/* At least one of the above/below actions is NOP. */
|
||||
thai_action_t action = above_edge.action != NOP ? above_edge.action : below_edge.action;
|
||||
|
||||
if (action == RD)
|
||||
info[base].codepoint = thai_pua_shape (info[base].codepoint, action, font);
|
||||
else
|
||||
info[i].codepoint = thai_pua_shape (info[i].codepoint, action, font);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
preprocess_text_thai (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font)
|
||||
{
|
||||
/* This function implements the shaping logic documented here:
|
||||
*
|
||||
* http://linux.thai.net/~thep/th-otf/shaping.html
|
||||
*
|
||||
* The first shaping rule listed there is needed even if the font has Thai
|
||||
* OpenType tables. The rest do fallback positioning based on PUA codepoints.
|
||||
* We implement that only if there exist no Thai GSUB in the font.
|
||||
*/
|
||||
|
||||
/* The following is NOT specified in the MS OT Thai spec, however, it seems
|
||||
* to be what Uniscribe and other engines implement. According to Eric Muller:
|
||||
*
|
||||
* When you have a SARA AM, decompose it in NIKHAHIT + SARA AA, *and* move the
|
||||
* NIKHAHIT backwards over any tone mark (0E48-0E4B).
|
||||
*
|
||||
* <0E14, 0E4B, 0E33> -> <0E14, 0E4D, 0E4B, 0E32>
|
||||
*
|
||||
* This reordering is legit only when the NIKHAHIT comes from a SARA AM, not
|
||||
* when it's there to start with. The string <0E14, 0E4B, 0E4D> is probably
|
||||
* not what a user wanted, but the rendering is nevertheless nikhahit above
|
||||
* chattawa.
|
||||
*
|
||||
* Same for Lao.
|
||||
*
|
||||
* Note:
|
||||
*
|
||||
* Uniscribe also does some below-marks reordering. Namely, it positions U+0E3A
|
||||
* after U+0E38 and U+0E39. We do that by modifying the ccc for U+0E3A.
|
||||
* See unicode->modified_combining_class (). Lao does NOT have a U+0E3A
|
||||
* equivalent.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Here are the characters of significance:
|
||||
*
|
||||
* Thai Lao
|
||||
* SARA AM: U+0E33 U+0EB3
|
||||
* SARA AA: U+0E32 U+0EB2
|
||||
* Nikhahit: U+0E4D U+0ECD
|
||||
*
|
||||
* Testing shows that Uniscribe reorder the following marks:
|
||||
* Thai: <0E31,0E34..0E37,0E47..0E4E>
|
||||
* Lao: <0EB1,0EB4..0EB7,0EC7..0ECE>
|
||||
*
|
||||
* Note how the Lao versions are the same as Thai + 0x80.
|
||||
*/
|
||||
|
||||
/* We only get one script at a time, so a script-agnostic implementation
|
||||
* is adequate here. */
|
||||
#define IS_SARA_AM(x) (((x) & ~0x0080) == 0x0E33)
|
||||
#define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0xE33 + 0xE4D)
|
||||
#define SARA_AA_FROM_SARA_AM(x) ((x) - 1)
|
||||
#define IS_TONE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080, 0x0E34, 0x0E37, 0x0E47, 0x0E4E, 0x0E31, 0x0E31))
|
||||
|
||||
buffer->clear_output ();
|
||||
unsigned int count = buffer->len;
|
||||
for (buffer->idx = 0; buffer->idx < count;)
|
||||
{
|
||||
hb_codepoint_t u = buffer->cur().codepoint;
|
||||
if (likely (!IS_SARA_AM (u))) {
|
||||
buffer->next_glyph ();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Is SARA AM. Decompose and reorder. */
|
||||
hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)),
|
||||
hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))};
|
||||
buffer->replace_glyphs (1, 2, decomposed);
|
||||
if (unlikely (buffer->in_error))
|
||||
return;
|
||||
|
||||
/* Ok, let's see... */
|
||||
unsigned int end = buffer->out_len;
|
||||
unsigned int start = end - 2;
|
||||
while (start > 0 && IS_TONE_MARK (buffer->out_info[start - 1].codepoint))
|
||||
start--;
|
||||
|
||||
if (start + 2 < end)
|
||||
{
|
||||
/* Move Nikhahit (end-2) to the beginning */
|
||||
buffer->merge_out_clusters (start, end);
|
||||
hb_glyph_info_t t = buffer->out_info[end - 2];
|
||||
memmove (buffer->out_info + start + 1,
|
||||
buffer->out_info + start,
|
||||
sizeof (buffer->out_info[0]) * (end - start - 2));
|
||||
buffer->out_info[start] = t;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Since we decomposed, and NIKHAHIT is combining, merge clusters with the
|
||||
* previous cluster. */
|
||||
if (start)
|
||||
buffer->merge_out_clusters (start - 1, end);
|
||||
}
|
||||
}
|
||||
buffer->swap_buffers ();
|
||||
|
||||
/* If font has Thai GSUB, we are done. */
|
||||
if (plan->props.script == HB_SCRIPT_THAI && !plan->map.found_script[0])
|
||||
do_thai_pua_shaping (plan, buffer, font);
|
||||
}
|
||||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
|
||||
{
|
||||
"thai",
|
||||
NULL, /* collect_features */
|
||||
NULL, /* override_features */
|
||||
NULL, /* data_create */
|
||||
NULL, /* data_destroy */
|
||||
preprocess_text_thai,
|
||||
NULL, /* normalization_preference */
|
||||
NULL, /* decompose */
|
||||
NULL, /* compose */
|
||||
NULL, /* setup_masks */
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
|
||||
false,/* fallback_position */
|
||||
};
|
49
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh
vendored
Normal file
49
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_SHAPE_FALLBACK_PRIVATE_HH
|
||||
#define HB_OT_SHAPE_FALLBACK_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-ot-shape-private.hh"
|
||||
|
||||
|
||||
HB_INTERNAL void _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
HB_INTERNAL void _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
|
||||
HB_INTERNAL void _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
|
||||
#endif /* HB_OT_SHAPE_FALLBACK_PRIVATE_HH */
|
456
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
vendored
Normal file
456
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
vendored
Normal file
@ -0,0 +1,456 @@
|
||||
/*
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-fallback-private.hh"
|
||||
#include "hb-ot-layout-gsubgpos-private.hh"
|
||||
|
||||
static unsigned int
|
||||
recategorize_combining_class (hb_codepoint_t u,
|
||||
unsigned int klass)
|
||||
{
|
||||
if (klass >= 200)
|
||||
return klass;
|
||||
|
||||
/* Thai / Lao need some per-character work. */
|
||||
if ((u & ~0xFF) == 0x0E00)
|
||||
{
|
||||
if (unlikely (klass == 0))
|
||||
{
|
||||
switch (u)
|
||||
{
|
||||
case 0x0E31:
|
||||
case 0x0E34:
|
||||
case 0x0E35:
|
||||
case 0x0E36:
|
||||
case 0x0E37:
|
||||
case 0x0E47:
|
||||
case 0x0E4C:
|
||||
case 0x0E4D:
|
||||
case 0x0E4E:
|
||||
klass = HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
|
||||
break;
|
||||
|
||||
case 0x0EB1:
|
||||
case 0x0EB4:
|
||||
case 0x0EB5:
|
||||
case 0x0EB6:
|
||||
case 0x0EB7:
|
||||
case 0x0EBB:
|
||||
case 0x0ECC:
|
||||
case 0x0ECD:
|
||||
klass = HB_UNICODE_COMBINING_CLASS_ABOVE;
|
||||
break;
|
||||
|
||||
case 0x0EBC:
|
||||
klass = HB_UNICODE_COMBINING_CLASS_BELOW;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Thai virama is below-right */
|
||||
if (u == 0x0E3A)
|
||||
klass = HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
switch (klass)
|
||||
{
|
||||
|
||||
/* Hebrew */
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC10: /* sheva */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC11: /* hataf segol */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC12: /* hataf patah */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC13: /* hataf qamats */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC14: /* hiriq */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC15: /* tsere */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC16: /* segol */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC17: /* patah */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC18: /* qamats */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC20: /* qubuts */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC22: /* meteg */
|
||||
return HB_UNICODE_COMBINING_CLASS_BELOW;
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC23: /* rafe */
|
||||
return HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE;
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC24: /* shin dot */
|
||||
return HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC25: /* sin dot */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC19: /* holam */
|
||||
return HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT;
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC26: /* point varika */
|
||||
return HB_UNICODE_COMBINING_CLASS_ABOVE;
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC21: /* dagesh */
|
||||
break;
|
||||
|
||||
|
||||
/* Arabic and Syriac */
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC27: /* fathatan */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC28: /* dammatan */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC30: /* fatha */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC31: /* damma */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC33: /* shadda */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC34: /* sukun */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC35: /* superscript alef */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC36: /* superscript alaph */
|
||||
return HB_UNICODE_COMBINING_CLASS_ABOVE;
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC29: /* kasratan */
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC32: /* kasra */
|
||||
return HB_UNICODE_COMBINING_CLASS_BELOW;
|
||||
|
||||
|
||||
/* Thai */
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC103: /* sara u / sara uu */
|
||||
return HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT;
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC107: /* mai */
|
||||
return HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
|
||||
|
||||
|
||||
/* Lao */
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC118: /* sign u / sign uu */
|
||||
return HB_UNICODE_COMBINING_CLASS_BELOW;
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC122: /* mai */
|
||||
return HB_UNICODE_COMBINING_CLASS_ABOVE;
|
||||
|
||||
|
||||
/* Tibetan */
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC129: /* sign aa */
|
||||
return HB_UNICODE_COMBINING_CLASS_BELOW;
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC130: /* sign i*/
|
||||
return HB_UNICODE_COMBINING_CLASS_ABOVE;
|
||||
|
||||
case HB_MODIFIED_COMBINING_CLASS_CCC132: /* sign u */
|
||||
return HB_UNICODE_COMBINING_CLASS_BELOW;
|
||||
|
||||
}
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) {
|
||||
unsigned int combining_class = _hb_glyph_info_get_modified_combining_class (&buffer->info[i]);
|
||||
combining_class = recategorize_combining_class (buffer->info[i].codepoint, combining_class);
|
||||
_hb_glyph_info_set_modified_combining_class (&buffer->info[i], combining_class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
zero_mark_advances (hb_buffer_t *buffer,
|
||||
unsigned int start,
|
||||
unsigned int end)
|
||||
{
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
||||
{
|
||||
buffer->pos[i].x_advance = 0;
|
||||
buffer->pos[i].y_advance = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
position_mark (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
hb_glyph_extents_t &base_extents,
|
||||
unsigned int i,
|
||||
unsigned int combining_class)
|
||||
{
|
||||
hb_glyph_extents_t mark_extents;
|
||||
if (!font->get_glyph_extents (buffer->info[i].codepoint,
|
||||
&mark_extents))
|
||||
return;
|
||||
|
||||
hb_position_t y_gap = font->y_scale / 16;
|
||||
|
||||
hb_glyph_position_t &pos = buffer->pos[i];
|
||||
pos.x_offset = pos.y_offset = 0;
|
||||
|
||||
|
||||
/* We dont position LEFT and RIGHT marks. */
|
||||
|
||||
/* X positioning */
|
||||
switch (combining_class)
|
||||
{
|
||||
case HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW:
|
||||
case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE:
|
||||
if (buffer->props.direction == HB_DIRECTION_LTR) {
|
||||
pos.x_offset += base_extents.x_bearing - mark_extents.width / 2 - mark_extents.x_bearing;
|
||||
break;
|
||||
} else if (buffer->props.direction == HB_DIRECTION_RTL) {
|
||||
pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width / 2 - mark_extents.x_bearing;
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
|
||||
default:
|
||||
case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW:
|
||||
case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE:
|
||||
case HB_UNICODE_COMBINING_CLASS_BELOW:
|
||||
case HB_UNICODE_COMBINING_CLASS_ABOVE:
|
||||
/* Center align. */
|
||||
pos.x_offset += base_extents.x_bearing + (base_extents.width - mark_extents.width) / 2 - mark_extents.x_bearing;
|
||||
break;
|
||||
|
||||
case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT:
|
||||
case HB_UNICODE_COMBINING_CLASS_BELOW_LEFT:
|
||||
case HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT:
|
||||
/* Left align. */
|
||||
pos.x_offset += base_extents.x_bearing - mark_extents.x_bearing;
|
||||
break;
|
||||
|
||||
case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT:
|
||||
case HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT:
|
||||
case HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT:
|
||||
/* Right align. */
|
||||
pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width - mark_extents.x_bearing;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Y positioning */
|
||||
switch (combining_class)
|
||||
{
|
||||
case HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW:
|
||||
case HB_UNICODE_COMBINING_CLASS_BELOW_LEFT:
|
||||
case HB_UNICODE_COMBINING_CLASS_BELOW:
|
||||
case HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT:
|
||||
/* Add gap, fall-through. */
|
||||
base_extents.height -= y_gap;
|
||||
|
||||
case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT:
|
||||
case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW:
|
||||
pos.y_offset += base_extents.y_bearing + base_extents.height - mark_extents.y_bearing;
|
||||
base_extents.height += mark_extents.height;
|
||||
break;
|
||||
|
||||
case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE:
|
||||
case HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT:
|
||||
case HB_UNICODE_COMBINING_CLASS_ABOVE:
|
||||
case HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT:
|
||||
/* Add gap, fall-through. */
|
||||
base_extents.y_bearing += y_gap;
|
||||
base_extents.height -= y_gap;
|
||||
|
||||
case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE:
|
||||
case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT:
|
||||
pos.y_offset += base_extents.y_bearing - (mark_extents.y_bearing + mark_extents.height);
|
||||
base_extents.y_bearing -= mark_extents.height;
|
||||
base_extents.height += mark_extents.height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
position_around_base (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int base,
|
||||
unsigned int end)
|
||||
{
|
||||
hb_direction_t horiz_dir = HB_DIRECTION_INVALID;
|
||||
hb_glyph_extents_t base_extents;
|
||||
if (!font->get_glyph_extents (buffer->info[base].codepoint,
|
||||
&base_extents))
|
||||
{
|
||||
/* If extents don't work, zero marks and go home. */
|
||||
zero_mark_advances (buffer, base + 1, end);
|
||||
return;
|
||||
}
|
||||
base_extents.x_bearing += buffer->pos[base].x_offset;
|
||||
base_extents.y_bearing += buffer->pos[base].y_offset;
|
||||
|
||||
unsigned int lig_id = get_lig_id (buffer->info[base]);
|
||||
unsigned int num_lig_components = get_lig_num_comps (buffer->info[base]);
|
||||
|
||||
hb_position_t x_offset = 0, y_offset = 0;
|
||||
if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
|
||||
x_offset -= buffer->pos[base].x_advance;
|
||||
y_offset -= buffer->pos[base].y_advance;
|
||||
}
|
||||
|
||||
hb_glyph_extents_t component_extents = base_extents;
|
||||
unsigned int last_lig_component = (unsigned int) -1;
|
||||
unsigned int last_combining_class = 255;
|
||||
hb_glyph_extents_t cluster_extents = base_extents; /* Initialization is just to shut gcc up. */
|
||||
for (unsigned int i = base + 1; i < end; i++)
|
||||
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]))
|
||||
{
|
||||
if (num_lig_components > 1) {
|
||||
unsigned int this_lig_id = get_lig_id (buffer->info[i]);
|
||||
unsigned int this_lig_component = get_lig_comp (buffer->info[i]) - 1;
|
||||
/* Conditions for attaching to the last component. */
|
||||
if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components)
|
||||
this_lig_component = num_lig_components - 1;
|
||||
if (last_lig_component != this_lig_component)
|
||||
{
|
||||
last_lig_component = this_lig_component;
|
||||
last_combining_class = 255;
|
||||
component_extents = base_extents;
|
||||
if (unlikely (horiz_dir == HB_DIRECTION_INVALID)) {
|
||||
if (HB_DIRECTION_IS_HORIZONTAL (plan->props.direction))
|
||||
horiz_dir = plan->props.direction;
|
||||
else
|
||||
horiz_dir = hb_script_get_horizontal_direction (plan->props.script);
|
||||
}
|
||||
if (horiz_dir == HB_DIRECTION_LTR)
|
||||
component_extents.x_bearing += (this_lig_component * component_extents.width) / num_lig_components;
|
||||
else
|
||||
component_extents.x_bearing += ((num_lig_components - 1 - this_lig_component) * component_extents.width) / num_lig_components;
|
||||
component_extents.width /= num_lig_components;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int this_combining_class = _hb_glyph_info_get_modified_combining_class (&buffer->info[i]);
|
||||
if (last_combining_class != this_combining_class)
|
||||
{
|
||||
last_combining_class = this_combining_class;
|
||||
cluster_extents = component_extents;
|
||||
}
|
||||
|
||||
position_mark (plan, font, buffer, cluster_extents, i, this_combining_class);
|
||||
|
||||
buffer->pos[i].x_advance = 0;
|
||||
buffer->pos[i].y_advance = 0;
|
||||
buffer->pos[i].x_offset += x_offset;
|
||||
buffer->pos[i].y_offset += y_offset;
|
||||
|
||||
} else {
|
||||
if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
|
||||
x_offset -= buffer->pos[i].x_advance;
|
||||
y_offset -= buffer->pos[i].y_advance;
|
||||
} else {
|
||||
x_offset += buffer->pos[i].x_advance;
|
||||
y_offset += buffer->pos[i].y_advance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
position_cluster (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start,
|
||||
unsigned int end)
|
||||
{
|
||||
if (end - start < 2)
|
||||
return;
|
||||
|
||||
/* Find the base glyph */
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i])))
|
||||
{
|
||||
/* Find mark glyphs */
|
||||
unsigned int j;
|
||||
for (j = i + 1; j < end; j++)
|
||||
if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[j])))
|
||||
break;
|
||||
|
||||
position_around_base (plan, font, buffer, i, j);
|
||||
|
||||
i = j - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int start = 0;
|
||||
unsigned int last_cluster = buffer->info[0].cluster;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 1; i < count; i++)
|
||||
if (buffer->info[i].cluster != last_cluster) {
|
||||
position_cluster (plan, font, buffer, start, i);
|
||||
start = i;
|
||||
last_cluster = buffer->info[i].cluster;
|
||||
}
|
||||
position_cluster (plan, font, buffer, start, count);
|
||||
}
|
||||
|
||||
|
||||
/* Performs old-style TrueType kerning. */
|
||||
void
|
||||
_hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
hb_mask_t kern_mask = plan->map.get_1_mask (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
|
||||
HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
|
||||
|
||||
OT::hb_apply_context_t c (1, font, buffer);
|
||||
c.set_lookup_mask (kern_mask);
|
||||
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
|
||||
|
||||
for (buffer->idx = 0; buffer->idx < count;)
|
||||
{
|
||||
OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, buffer->idx, 1);
|
||||
if (!skippy_iter.next ())
|
||||
{
|
||||
buffer->idx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
hb_position_t x_kern, y_kern, kern1, kern2;
|
||||
font->get_glyph_kerning_for_direction (buffer->info[buffer->idx].codepoint,
|
||||
buffer->info[skippy_iter.idx].codepoint,
|
||||
buffer->props.direction,
|
||||
&x_kern, &y_kern);
|
||||
|
||||
kern1 = x_kern >> 1;
|
||||
kern2 = x_kern - kern1;
|
||||
buffer->pos[buffer->idx].x_advance += kern1;
|
||||
buffer->pos[skippy_iter.idx].x_advance += kern2;
|
||||
buffer->pos[skippy_iter.idx].x_offset += kern2;
|
||||
|
||||
kern1 = y_kern >> 1;
|
||||
kern2 = y_kern - kern1;
|
||||
buffer->pos[buffer->idx].y_advance += kern1;
|
||||
buffer->pos[skippy_iter.idx].y_advance += kern2;
|
||||
buffer->pos[skippy_iter.idx].y_offset += kern2;
|
||||
|
||||
buffer->idx = skippy_iter.idx;
|
||||
}
|
||||
}
|
70
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
vendored
Normal file
70
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_SHAPE_NORMALIZE_PRIVATE_HH
|
||||
#define HB_OT_SHAPE_NORMALIZE_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-font.h"
|
||||
#include "hb-buffer.h"
|
||||
|
||||
/* buffer var allocations, used during the normalization process */
|
||||
#define glyph_index() var1.u32
|
||||
|
||||
struct hb_ot_shape_plan_t;
|
||||
|
||||
enum hb_ot_shape_normalization_mode_t {
|
||||
HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
|
||||
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */
|
||||
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* always fully decomposes and then recompose back */
|
||||
|
||||
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS
|
||||
};
|
||||
|
||||
HB_INTERNAL void _hb_ot_shape_normalize (const hb_ot_shape_plan_t *shaper,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font);
|
||||
|
||||
|
||||
struct hb_ot_shape_normalize_context_t
|
||||
{
|
||||
const hb_ot_shape_plan_t *plan;
|
||||
hb_buffer_t *buffer;
|
||||
hb_font_t *font;
|
||||
hb_unicode_funcs_t *unicode;
|
||||
bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
|
||||
hb_codepoint_t ab,
|
||||
hb_codepoint_t *a,
|
||||
hb_codepoint_t *b);
|
||||
bool (*compose) (const hb_ot_shape_normalize_context_t *c,
|
||||
hb_codepoint_t a,
|
||||
hb_codepoint_t b,
|
||||
hb_codepoint_t *ab);
|
||||
};
|
||||
|
||||
|
||||
#endif /* HB_OT_SHAPE_NORMALIZE_PRIVATE_HH */
|
408
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
vendored
Normal file
408
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
vendored
Normal file
@ -0,0 +1,408 @@
|
||||
/*
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-normalize-private.hh"
|
||||
#include "hb-ot-shape-complex-private.hh"
|
||||
#include "hb-ot-shape-private.hh"
|
||||
|
||||
|
||||
/*
|
||||
* HIGHLEVEL DESIGN:
|
||||
*
|
||||
* This file exports one main function: _hb_ot_shape_normalize().
|
||||
*
|
||||
* This function closely reflects the Unicode Normalization Algorithm,
|
||||
* yet it's different.
|
||||
*
|
||||
* Each shaper specifies whether it prefers decomposed (NFD) or composed (NFC).
|
||||
* The logic however tries to use whatever the font can support.
|
||||
*
|
||||
* In general what happens is that: each grapheme is decomposed in a chain
|
||||
* of 1:2 decompositions, marks reordered, and then recomposed if desired,
|
||||
* so far it's like Unicode Normalization. However, the decomposition and
|
||||
* recomposition only happens if the font supports the resulting characters.
|
||||
*
|
||||
* The goals are:
|
||||
*
|
||||
* - Try to render all canonically equivalent strings similarly. To really
|
||||
* achieve this we have to always do the full decomposition and then
|
||||
* selectively recompose from there. It's kinda too expensive though, so
|
||||
* we skip some cases. For example, if composed is desired, we simply
|
||||
* don't touch 1-character clusters that are supported by the font, even
|
||||
* though their NFC may be different.
|
||||
*
|
||||
* - When a font has a precomposed character for a sequence but the 'ccmp'
|
||||
* feature in the font is not adequate, use the precomposed character
|
||||
* which typically has better mark positioning.
|
||||
*
|
||||
* - When a font does not support a combining mark, but supports it precomposed
|
||||
* with previous base, use that. This needs the itemizer to have this
|
||||
* knowledge too. We need to provide assistance to the itemizer.
|
||||
*
|
||||
* - When a font does not support a character but supports its decomposition,
|
||||
* well, use the decomposition (preferring the canonical decomposition, but
|
||||
* falling back to the compatibility decomposition if necessary). The
|
||||
* compatibility decomposition is really nice to have, for characters like
|
||||
* ellipsis, or various-sized space characters.
|
||||
*
|
||||
* - The complex shapers can customize the compose and decompose functions to
|
||||
* offload some of their requirements to the normalizer. For example, the
|
||||
* Indic shaper may want to disallow recomposing of two matras.
|
||||
*
|
||||
* - We try compatibility decomposition if decomposing through canonical
|
||||
* decomposition alone failed to find a sequence that the font supports.
|
||||
* We don't try compatibility decomposition recursively during the canonical
|
||||
* decomposition phase. This has minimal impact. There are only a handful
|
||||
* of Greek letter that have canonical decompositions that include characters
|
||||
* with compatibility decomposition. Those can be found using this command:
|
||||
*
|
||||
* egrep "`echo -n ';('; grep ';<' UnicodeData.txt | cut -d';' -f1 | tr '\n' '|'; echo ') '`" UnicodeData.txt
|
||||
*/
|
||||
|
||||
static bool
|
||||
decompose_unicode (const hb_ot_shape_normalize_context_t *c,
|
||||
hb_codepoint_t ab,
|
||||
hb_codepoint_t *a,
|
||||
hb_codepoint_t *b)
|
||||
{
|
||||
return c->unicode->decompose (ab, a, b);
|
||||
}
|
||||
|
||||
static bool
|
||||
compose_unicode (const hb_ot_shape_normalize_context_t *c,
|
||||
hb_codepoint_t a,
|
||||
hb_codepoint_t b,
|
||||
hb_codepoint_t *ab)
|
||||
{
|
||||
return c->unicode->compose (a, b, ab);
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_glyph (hb_glyph_info_t &info, hb_font_t *font)
|
||||
{
|
||||
font->get_glyph (info.codepoint, 0, &info.glyph_index());
|
||||
}
|
||||
|
||||
static inline void
|
||||
output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
|
||||
{
|
||||
buffer->cur().glyph_index() = glyph;
|
||||
buffer->output_glyph (unichar);
|
||||
_hb_glyph_info_set_unicode_props (&buffer->prev(), buffer->unicode);
|
||||
}
|
||||
|
||||
static inline void
|
||||
next_char (hb_buffer_t *buffer, hb_codepoint_t glyph)
|
||||
{
|
||||
buffer->cur().glyph_index() = glyph;
|
||||
buffer->next_glyph ();
|
||||
}
|
||||
|
||||
static inline void
|
||||
skip_char (hb_buffer_t *buffer)
|
||||
{
|
||||
buffer->skip_glyph ();
|
||||
}
|
||||
|
||||
/* Returns 0 if didn't decompose, number of resulting characters otherwise. */
|
||||
static inline unsigned int
|
||||
decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint_t ab)
|
||||
{
|
||||
hb_codepoint_t a, b, a_glyph, b_glyph;
|
||||
|
||||
if (!c->decompose (c, ab, &a, &b) ||
|
||||
(b && !c->font->get_glyph (b, 0, &b_glyph)))
|
||||
return 0;
|
||||
|
||||
bool has_a = c->font->get_glyph (a, 0, &a_glyph);
|
||||
if (shortest && has_a) {
|
||||
/* Output a and b */
|
||||
output_char (c->buffer, a, a_glyph);
|
||||
if (likely (b)) {
|
||||
output_char (c->buffer, b, b_glyph);
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int ret;
|
||||
if ((ret = decompose (c, shortest, a))) {
|
||||
if (b) {
|
||||
output_char (c->buffer, b, b_glyph);
|
||||
return ret + 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (has_a) {
|
||||
output_char (c->buffer, a, a_glyph);
|
||||
if (likely (b)) {
|
||||
output_char (c->buffer, b, b_glyph);
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns 0 if didn't decompose, number of resulting characters otherwise. */
|
||||
static inline unsigned int
|
||||
decompose_compatibility (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t u)
|
||||
{
|
||||
unsigned int len, i;
|
||||
hb_codepoint_t decomposed[HB_UNICODE_MAX_DECOMPOSITION_LEN];
|
||||
hb_codepoint_t glyphs[HB_UNICODE_MAX_DECOMPOSITION_LEN];
|
||||
|
||||
len = c->buffer->unicode->decompose_compatibility (u, decomposed);
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (!c->font->get_glyph (decomposed[i], 0, &glyphs[i]))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
output_char (c->buffer, decomposed[i], glyphs[i]);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline void
|
||||
decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shortest)
|
||||
{
|
||||
hb_buffer_t * const buffer = c->buffer;
|
||||
hb_codepoint_t glyph;
|
||||
|
||||
/* Kind of a cute waterfall here... */
|
||||
if (shortest && c->font->get_glyph (buffer->cur().codepoint, 0, &glyph))
|
||||
next_char (buffer, glyph);
|
||||
else if (decompose (c, shortest, buffer->cur().codepoint))
|
||||
skip_char (buffer);
|
||||
else if (!shortest && c->font->get_glyph (buffer->cur().codepoint, 0, &glyph))
|
||||
next_char (buffer, glyph);
|
||||
else if (decompose_compatibility (c, buffer->cur().codepoint))
|
||||
skip_char (buffer);
|
||||
else
|
||||
next_char (buffer, glyph); /* glyph is initialized in earlier branches. */
|
||||
}
|
||||
|
||||
static inline void
|
||||
handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
|
||||
{
|
||||
hb_buffer_t * const buffer = c->buffer;
|
||||
for (; buffer->idx < end - 1;) {
|
||||
if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) {
|
||||
/* The next two lines are some ugly lines... But work. */
|
||||
if (c->font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
|
||||
{
|
||||
buffer->replace_glyphs (2, 1, &buffer->cur().codepoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just pass on the two characters separately, let GSUB do its magic. */
|
||||
set_glyph (buffer->cur(), c->font);
|
||||
buffer->next_glyph ();
|
||||
set_glyph (buffer->cur(), c->font);
|
||||
buffer->next_glyph ();
|
||||
}
|
||||
/* Skip any further variation selectors. */
|
||||
while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
|
||||
{
|
||||
set_glyph (buffer->cur(), c->font);
|
||||
buffer->next_glyph ();
|
||||
}
|
||||
} else {
|
||||
set_glyph (buffer->cur(), c->font);
|
||||
buffer->next_glyph ();
|
||||
}
|
||||
}
|
||||
if (likely (buffer->idx < end)) {
|
||||
set_glyph (buffer->cur(), c->font);
|
||||
buffer->next_glyph ();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
|
||||
{
|
||||
hb_buffer_t * const buffer = c->buffer;
|
||||
/* TODO Currently if there's a variation-selector we give-up, it's just too hard. */
|
||||
for (unsigned int i = buffer->idx; i < end; i++)
|
||||
if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) {
|
||||
handle_variation_selector_cluster (c, end);
|
||||
return;
|
||||
}
|
||||
|
||||
while (buffer->idx < end)
|
||||
decompose_current_character (c, false);
|
||||
}
|
||||
|
||||
static inline void
|
||||
decompose_cluster (const hb_ot_shape_normalize_context_t *c, bool short_circuit, unsigned int end)
|
||||
{
|
||||
if (likely (c->buffer->idx + 1 == end))
|
||||
decompose_current_character (c, short_circuit);
|
||||
else
|
||||
decompose_multi_char_cluster (c, end);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
|
||||
{
|
||||
unsigned int a = _hb_glyph_info_get_modified_combining_class (pa);
|
||||
unsigned int b = _hb_glyph_info_get_modified_combining_class (pb);
|
||||
|
||||
return a < b ? -1 : a == b ? 0 : +1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font)
|
||||
{
|
||||
hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference ?
|
||||
plan->shaper->normalization_preference (&buffer->props) :
|
||||
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT;
|
||||
const hb_ot_shape_normalize_context_t c = {
|
||||
plan,
|
||||
buffer,
|
||||
font,
|
||||
buffer->unicode,
|
||||
plan->shaper->decompose ? plan->shaper->decompose : decompose_unicode,
|
||||
plan->shaper->compose ? plan->shaper->compose : compose_unicode
|
||||
};
|
||||
|
||||
bool short_circuit = mode != HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED &&
|
||||
mode != HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
|
||||
unsigned int count;
|
||||
|
||||
/* We do a fairly straightforward yet custom normalization process in three
|
||||
* separate rounds: decompose, reorder, recompose (if desired). Currently
|
||||
* this makes two buffer swaps. We can make it faster by moving the last
|
||||
* two rounds into the inner loop for the first round, but it's more readable
|
||||
* this way. */
|
||||
|
||||
|
||||
/* First round, decompose */
|
||||
|
||||
buffer->clear_output ();
|
||||
count = buffer->len;
|
||||
for (buffer->idx = 0; buffer->idx < count;)
|
||||
{
|
||||
unsigned int end;
|
||||
for (end = buffer->idx + 1; end < count; end++)
|
||||
if (buffer->cur().cluster != buffer->info[end].cluster)
|
||||
break;
|
||||
|
||||
decompose_cluster (&c, short_circuit, end);
|
||||
}
|
||||
buffer->swap_buffers ();
|
||||
|
||||
|
||||
/* Second round, reorder (inplace) */
|
||||
|
||||
count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
|
||||
continue;
|
||||
|
||||
unsigned int end;
|
||||
for (end = i + 1; end < count; end++)
|
||||
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
|
||||
break;
|
||||
|
||||
/* We are going to do a bubble-sort. Only do this if the
|
||||
* sequence is short. Doing it on long sequences can result
|
||||
* in an O(n^2) DoS. */
|
||||
if (end - i > 10) {
|
||||
i = end;
|
||||
continue;
|
||||
}
|
||||
|
||||
hb_bubble_sort (buffer->info + i, end - i, compare_combining_class);
|
||||
|
||||
i = end;
|
||||
}
|
||||
|
||||
|
||||
if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
|
||||
return;
|
||||
|
||||
/* Third round, recompose */
|
||||
|
||||
/* As noted in the comment earlier, we don't try to combine
|
||||
* ccc=0 chars with their previous Starter. */
|
||||
|
||||
buffer->clear_output ();
|
||||
count = buffer->len;
|
||||
unsigned int starter = 0;
|
||||
buffer->next_glyph ();
|
||||
while (buffer->idx < count)
|
||||
{
|
||||
hb_codepoint_t composed, glyph;
|
||||
if (/* We don't try to compose a non-mark character with it's preceding starter.
|
||||
* This is both an optimization to avoid trying to compose every two neighboring
|
||||
* glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul
|
||||
* fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
|
||||
HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())) &&
|
||||
/* If there's anything between the starter and this char, they should have CCC
|
||||
* smaller than this character's. */
|
||||
(starter == buffer->out_len - 1 ||
|
||||
_hb_glyph_info_get_modified_combining_class (&buffer->prev()) < _hb_glyph_info_get_modified_combining_class (&buffer->cur())) &&
|
||||
/* And compose. */
|
||||
c.compose (&c,
|
||||
buffer->out_info[starter].codepoint,
|
||||
buffer->cur().codepoint,
|
||||
&composed) &&
|
||||
/* And the font has glyph for the composite. */
|
||||
font->get_glyph (composed, 0, &glyph))
|
||||
{
|
||||
/* Composes. */
|
||||
buffer->next_glyph (); /* Copy to out-buffer. */
|
||||
if (unlikely (buffer->in_error))
|
||||
return;
|
||||
buffer->merge_out_clusters (starter, buffer->out_len);
|
||||
buffer->out_len--; /* Remove the second composable. */
|
||||
buffer->out_info[starter].codepoint = composed; /* Modify starter and carry on. */
|
||||
set_glyph (buffer->out_info[starter], font);
|
||||
_hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer->unicode);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Blocked, or doesn't compose. */
|
||||
buffer->next_glyph ();
|
||||
|
||||
if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)
|
||||
starter = buffer->out_len - 1;
|
||||
}
|
||||
buffer->swap_buffers ();
|
||||
|
||||
}
|
87
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
vendored
Normal file
87
src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright © 2010 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_SHAPE_PRIVATE_HH
|
||||
#define HB_OT_SHAPE_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-ot-map-private.hh"
|
||||
#include "hb-ot-layout-private.hh"
|
||||
|
||||
|
||||
|
||||
struct hb_ot_shape_plan_t
|
||||
{
|
||||
hb_segment_properties_t props;
|
||||
const struct hb_ot_complex_shaper_t *shaper;
|
||||
hb_ot_map_t map;
|
||||
const void *data;
|
||||
|
||||
inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
|
||||
{
|
||||
unsigned int table_index;
|
||||
switch (table_tag) {
|
||||
case HB_OT_TAG_GSUB: table_index = 0; break;
|
||||
case HB_OT_TAG_GPOS: table_index = 1; break;
|
||||
default: return;
|
||||
}
|
||||
map.collect_lookups (table_index, lookups);
|
||||
}
|
||||
inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); }
|
||||
inline void position (hb_font_t *font, hb_buffer_t *buffer) const { map.position (this, font, buffer); }
|
||||
|
||||
void finish (void) { map.finish (); }
|
||||
};
|
||||
|
||||
struct hb_ot_shape_planner_t
|
||||
{
|
||||
/* In the order that they are filled in. */
|
||||
hb_face_t *face;
|
||||
hb_segment_properties_t props;
|
||||
const struct hb_ot_complex_shaper_t *shaper;
|
||||
hb_ot_map_builder_t map;
|
||||
|
||||
hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
|
||||
face (master_plan->face),
|
||||
props (master_plan->props),
|
||||
shaper (NULL),
|
||||
map (face, &props) {}
|
||||
~hb_ot_shape_planner_t (void) { map.finish (); }
|
||||
|
||||
inline void compile (hb_ot_shape_plan_t &plan)
|
||||
{
|
||||
plan.props = props;
|
||||
plan.shaper = shaper;
|
||||
map.compile (plan.map);
|
||||
}
|
||||
|
||||
private:
|
||||
NO_COPY (hb_ot_shape_planner_t);
|
||||
};
|
||||
|
||||
|
||||
#endif /* HB_OT_SHAPE_PRIVATE_HH */
|
667
src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
vendored
Normal file
667
src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
vendored
Normal file
@ -0,0 +1,667 @@
|
||||
/*
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2010,2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#define HB_SHAPER ot
|
||||
#define hb_ot_shaper_face_data_t hb_ot_layout_t
|
||||
#define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t
|
||||
#include "hb-shaper-impl-private.hh"
|
||||
|
||||
#include "hb-ot-shape-private.hh"
|
||||
#include "hb-ot-shape-complex-private.hh"
|
||||
#include "hb-ot-shape-fallback-private.hh"
|
||||
#include "hb-ot-shape-normalize-private.hh"
|
||||
|
||||
#include "hb-ot-layout-private.hh"
|
||||
#include "hb-set-private.hh"
|
||||
|
||||
|
||||
static hb_tag_t common_features[] = {
|
||||
HB_TAG('c','c','m','p'),
|
||||
HB_TAG('l','i','g','a'),
|
||||
HB_TAG('l','o','c','l'),
|
||||
HB_TAG('m','a','r','k'),
|
||||
HB_TAG('m','k','m','k'),
|
||||
HB_TAG('r','l','i','g'),
|
||||
};
|
||||
|
||||
|
||||
static hb_tag_t horizontal_features[] = {
|
||||
HB_TAG('c','a','l','t'),
|
||||
HB_TAG('c','l','i','g'),
|
||||
HB_TAG('c','u','r','s'),
|
||||
HB_TAG('k','e','r','n'),
|
||||
HB_TAG('r','c','l','t'),
|
||||
};
|
||||
|
||||
static hb_tag_t vertical_features[] = {
|
||||
HB_TAG('v','e','r','t'),
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void
|
||||
hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
|
||||
const hb_segment_properties_t *props,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features)
|
||||
{
|
||||
hb_ot_map_builder_t *map = &planner->map;
|
||||
|
||||
switch (props->direction) {
|
||||
case HB_DIRECTION_LTR:
|
||||
map->add_global_bool_feature (HB_TAG ('l','t','r','a'));
|
||||
map->add_global_bool_feature (HB_TAG ('l','t','r','m'));
|
||||
break;
|
||||
case HB_DIRECTION_RTL:
|
||||
map->add_global_bool_feature (HB_TAG ('r','t','l','a'));
|
||||
map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE);
|
||||
break;
|
||||
case HB_DIRECTION_TTB:
|
||||
case HB_DIRECTION_BTT:
|
||||
case HB_DIRECTION_INVALID:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (planner->shaper->collect_features)
|
||||
planner->shaper->collect_features (planner);
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++)
|
||||
map->add_global_bool_feature (common_features[i]);
|
||||
|
||||
if (HB_DIRECTION_IS_HORIZONTAL (props->direction))
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++)
|
||||
map->add_feature (horizontal_features[i], 1, F_GLOBAL |
|
||||
(horizontal_features[i] == HB_TAG('k','e','r','n') ?
|
||||
F_HAS_FALLBACK : F_NONE));
|
||||
else
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (vertical_features); i++)
|
||||
map->add_feature (vertical_features[i], 1, F_GLOBAL |
|
||||
(vertical_features[i] == HB_TAG('v','k','r','n') ?
|
||||
F_HAS_FALLBACK : F_NONE));
|
||||
|
||||
if (planner->shaper->override_features)
|
||||
planner->shaper->override_features (planner);
|
||||
|
||||
for (unsigned int i = 0; i < num_user_features; i++) {
|
||||
const hb_feature_t *feature = &user_features[i];
|
||||
map->add_feature (feature->tag, feature->value,
|
||||
(feature->start == 0 && feature->end == (unsigned int) -1) ?
|
||||
F_GLOBAL : F_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper face data
|
||||
*/
|
||||
|
||||
hb_ot_shaper_face_data_t *
|
||||
_hb_ot_shaper_face_data_create (hb_face_t *face)
|
||||
{
|
||||
return _hb_ot_layout_create (face);
|
||||
}
|
||||
|
||||
void
|
||||
_hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
|
||||
{
|
||||
_hb_ot_layout_destroy (data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper font data
|
||||
*/
|
||||
|
||||
struct hb_ot_shaper_font_data_t {};
|
||||
|
||||
hb_ot_shaper_font_data_t *
|
||||
_hb_ot_shaper_font_data_create (hb_font_t *font)
|
||||
{
|
||||
return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper shape_plan data
|
||||
*/
|
||||
|
||||
hb_ot_shaper_shape_plan_data_t *
|
||||
_hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features)
|
||||
{
|
||||
hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
|
||||
if (unlikely (!plan))
|
||||
return NULL;
|
||||
|
||||
hb_ot_shape_planner_t planner (shape_plan);
|
||||
|
||||
planner.shaper = hb_ot_shape_complex_categorize (&planner);
|
||||
|
||||
hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features);
|
||||
|
||||
planner.compile (*plan);
|
||||
|
||||
if (plan->shaper->data_create) {
|
||||
plan->data = plan->shaper->data_create (plan);
|
||||
if (unlikely (!plan->data))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return plan;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan)
|
||||
{
|
||||
if (plan->shaper->data_destroy)
|
||||
plan->shaper->data_destroy (const_cast<void *> (plan->data));
|
||||
|
||||
plan->finish ();
|
||||
|
||||
free (plan);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper
|
||||
*/
|
||||
|
||||
struct hb_ot_shape_context_t
|
||||
{
|
||||
hb_ot_shape_plan_t *plan;
|
||||
hb_font_t *font;
|
||||
hb_face_t *face;
|
||||
hb_buffer_t *buffer;
|
||||
const hb_feature_t *user_features;
|
||||
unsigned int num_user_features;
|
||||
|
||||
/* Transient stuff */
|
||||
hb_direction_t target_direction;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Main shaper */
|
||||
|
||||
|
||||
/* Prepare */
|
||||
|
||||
static void
|
||||
hb_set_unicode_props (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
_hb_glyph_info_set_unicode_props (&buffer->info[i], buffer->unicode);
|
||||
}
|
||||
|
||||
static void
|
||||
hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
|
||||
{
|
||||
if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
|
||||
_hb_glyph_info_get_general_category (&buffer->info[0]) !=
|
||||
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
||||
return;
|
||||
|
||||
hb_codepoint_t dottedcircle_glyph;
|
||||
if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
|
||||
return;
|
||||
|
||||
hb_glyph_info_t dottedcircle;
|
||||
dottedcircle.codepoint = 0x25CC;
|
||||
_hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode);
|
||||
|
||||
buffer->clear_output ();
|
||||
|
||||
buffer->idx = 0;
|
||||
hb_glyph_info_t info = dottedcircle;
|
||||
info.cluster = buffer->cur().cluster;
|
||||
info.mask = buffer->cur().mask;
|
||||
buffer->output_info (info);
|
||||
while (buffer->idx < buffer->len)
|
||||
buffer->next_glyph ();
|
||||
|
||||
buffer->swap_buffers ();
|
||||
}
|
||||
|
||||
static void
|
||||
hb_form_clusters (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 1; i < count; i++)
|
||||
if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i])))
|
||||
buffer->merge_clusters (i - 1, i + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
hb_ensure_native_direction (hb_buffer_t *buffer)
|
||||
{
|
||||
hb_direction_t direction = buffer->props.direction;
|
||||
|
||||
/* TODO vertical:
|
||||
* The only BTT vertical script is Ogham, but it's not clear to me whether OpenType
|
||||
* Ogham fonts are supposed to be implemented BTT or not. Need to research that
|
||||
* first. */
|
||||
if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (buffer->props.script)) ||
|
||||
(HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB))
|
||||
{
|
||||
hb_buffer_reverse_clusters (buffer);
|
||||
buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Substitute */
|
||||
|
||||
static inline void
|
||||
hb_ot_mirror_chars (hb_ot_shape_context_t *c)
|
||||
{
|
||||
if (HB_DIRECTION_IS_FORWARD (c->target_direction))
|
||||
return;
|
||||
|
||||
hb_unicode_funcs_t *unicode = c->buffer->unicode;
|
||||
hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m'));
|
||||
|
||||
unsigned int count = c->buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
hb_codepoint_t codepoint = unicode->mirroring (c->buffer->info[i].codepoint);
|
||||
if (likely (codepoint == c->buffer->info[i].codepoint))
|
||||
c->buffer->info[i].mask |= rtlm_mask;
|
||||
else
|
||||
c->buffer->info[i].codepoint = codepoint;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
|
||||
{
|
||||
hb_ot_map_t *map = &c->plan->map;
|
||||
|
||||
hb_mask_t global_mask = map->get_global_mask ();
|
||||
c->buffer->reset_masks (global_mask);
|
||||
|
||||
if (c->plan->shaper->setup_masks)
|
||||
c->plan->shaper->setup_masks (c->plan, c->buffer, c->font);
|
||||
|
||||
for (unsigned int i = 0; i < c->num_user_features; i++)
|
||||
{
|
||||
const hb_feature_t *feature = &c->user_features[i];
|
||||
if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
|
||||
unsigned int shift;
|
||||
hb_mask_t mask = map->get_mask (feature->tag, &shift);
|
||||
c->buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
|
||||
{
|
||||
/* Normalization process sets up glyph_index(), we just copy it. */
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
buffer->info[i].codepoint = buffer->info[i].glyph_index();
|
||||
}
|
||||
|
||||
static inline void
|
||||
hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
|
||||
{
|
||||
unsigned int count = c->buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
c->buffer->info[i].glyph_props() = _hb_glyph_info_get_general_category (&c->buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ?
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_MARK :
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
|
||||
}
|
||||
|
||||
static inline void
|
||||
hb_ot_substitute_default (hb_ot_shape_context_t *c)
|
||||
{
|
||||
if (c->plan->shaper->preprocess_text)
|
||||
c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font);
|
||||
|
||||
hb_ot_mirror_chars (c);
|
||||
|
||||
HB_BUFFER_ALLOCATE_VAR (c->buffer, glyph_index);
|
||||
|
||||
_hb_ot_shape_normalize (c->plan, c->buffer, c->font);
|
||||
|
||||
hb_ot_shape_setup_masks (c);
|
||||
|
||||
/* This is unfortunate to go here, but necessary... */
|
||||
if (!hb_ot_layout_has_positioning (c->face))
|
||||
_hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, c->buffer);
|
||||
|
||||
hb_ot_map_glyphs_fast (c->buffer);
|
||||
|
||||
HB_BUFFER_DEALLOCATE_VAR (c->buffer, glyph_index);
|
||||
}
|
||||
|
||||
static inline void
|
||||
hb_ot_substitute_complex (hb_ot_shape_context_t *c)
|
||||
{
|
||||
hb_ot_layout_substitute_start (c->font, c->buffer);
|
||||
|
||||
if (!hb_ot_layout_has_glyph_classes (c->face))
|
||||
hb_synthesize_glyph_classes (c);
|
||||
|
||||
c->plan->substitute (c->font, c->buffer);
|
||||
|
||||
hb_ot_layout_substitute_finish (c->font, c->buffer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void
|
||||
hb_ot_substitute (hb_ot_shape_context_t *c)
|
||||
{
|
||||
hb_ot_substitute_default (c);
|
||||
hb_ot_substitute_complex (c);
|
||||
}
|
||||
|
||||
/* Position */
|
||||
|
||||
static inline void
|
||||
zero_mark_widths_by_unicode (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
||||
{
|
||||
buffer->pos[i].x_advance = 0;
|
||||
buffer->pos[i].y_advance = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
zero_mark_widths_by_gdef (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if ((buffer->info[i].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
|
||||
{
|
||||
buffer->pos[i].x_advance = 0;
|
||||
buffer->pos[i].y_advance = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
hb_ot_position_default (hb_ot_shape_context_t *c)
|
||||
{
|
||||
hb_ot_layout_position_start (c->font, c->buffer);
|
||||
|
||||
unsigned int count = c->buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint,
|
||||
c->buffer->props.direction,
|
||||
&c->buffer->pos[i].x_advance,
|
||||
&c->buffer->pos[i].y_advance);
|
||||
c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
|
||||
c->buffer->props.direction,
|
||||
&c->buffer->pos[i].x_offset,
|
||||
&c->buffer->pos[i].y_offset);
|
||||
|
||||
}
|
||||
|
||||
switch (c->plan->shaper->zero_width_marks)
|
||||
{
|
||||
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
|
||||
zero_mark_widths_by_gdef (c->buffer);
|
||||
break;
|
||||
|
||||
/* Not currently used for any shaper:
|
||||
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY:
|
||||
zero_mark_widths_by_unicode (c->buffer);
|
||||
break;
|
||||
*/
|
||||
|
||||
default:
|
||||
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
|
||||
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
|
||||
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hb_ot_position_complex (hb_ot_shape_context_t *c)
|
||||
{
|
||||
bool ret = false;
|
||||
unsigned int count = c->buffer->len;
|
||||
|
||||
if (hb_ot_layout_has_positioning (c->face))
|
||||
{
|
||||
/* Change glyph origin to what GPOS expects, apply GPOS, change it back. */
|
||||
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
c->font->add_glyph_origin_for_direction (c->buffer->info[i].codepoint,
|
||||
HB_DIRECTION_LTR,
|
||||
&c->buffer->pos[i].x_offset,
|
||||
&c->buffer->pos[i].y_offset);
|
||||
}
|
||||
|
||||
c->plan->position (c->font, c->buffer);
|
||||
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
|
||||
HB_DIRECTION_LTR,
|
||||
&c->buffer->pos[i].x_offset,
|
||||
&c->buffer->pos[i].y_offset);
|
||||
}
|
||||
|
||||
ret = true;
|
||||
}
|
||||
|
||||
switch (c->plan->shaper->zero_width_marks)
|
||||
{
|
||||
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
|
||||
zero_mark_widths_by_unicode (c->buffer);
|
||||
break;
|
||||
|
||||
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
|
||||
zero_mark_widths_by_gdef (c->buffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
|
||||
//case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY:
|
||||
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
|
||||
break;
|
||||
}
|
||||
|
||||
hb_ot_layout_position_finish (c->font, c->buffer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
hb_ot_position (hb_ot_shape_context_t *c)
|
||||
{
|
||||
hb_ot_position_default (c);
|
||||
|
||||
hb_bool_t fallback = !hb_ot_position_complex (c);
|
||||
|
||||
if (fallback && c->plan->shaper->fallback_position)
|
||||
_hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
|
||||
|
||||
if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
|
||||
hb_buffer_reverse (c->buffer);
|
||||
|
||||
/* Visual fallback goes here. */
|
||||
|
||||
if (fallback)
|
||||
_hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
|
||||
}
|
||||
|
||||
|
||||
/* Post-process */
|
||||
|
||||
static void
|
||||
hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
|
||||
{
|
||||
if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
|
||||
return;
|
||||
|
||||
hb_codepoint_t space = 0;
|
||||
|
||||
unsigned int count = c->buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (unlikely (!is_a_ligature (c->buffer->info[i]) &&
|
||||
_hb_glyph_info_is_default_ignorable (&c->buffer->info[i])))
|
||||
{
|
||||
if (!space) {
|
||||
/* We assume that the space glyph is not gid0. */
|
||||
if (unlikely (!c->font->get_glyph (' ', 0, &space)) || !space)
|
||||
return; /* No point! */
|
||||
}
|
||||
c->buffer->info[i].codepoint = space;
|
||||
c->buffer->pos[i].x_advance = 0;
|
||||
c->buffer->pos[i].y_advance = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Pull it all together! */
|
||||
|
||||
static void
|
||||
hb_ot_shape_internal (hb_ot_shape_context_t *c)
|
||||
{
|
||||
c->buffer->deallocate_var_all ();
|
||||
|
||||
/* Save the original direction, we use it later. */
|
||||
c->target_direction = c->buffer->props.direction;
|
||||
|
||||
HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props0);
|
||||
HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props1);
|
||||
|
||||
c->buffer->clear_output ();
|
||||
|
||||
hb_set_unicode_props (c->buffer);
|
||||
hb_insert_dotted_circle (c->buffer, c->font);
|
||||
hb_form_clusters (c->buffer);
|
||||
|
||||
hb_ensure_native_direction (c->buffer);
|
||||
|
||||
hb_ot_substitute (c);
|
||||
hb_ot_position (c);
|
||||
|
||||
hb_ot_hide_default_ignorables (c);
|
||||
|
||||
HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1);
|
||||
HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0);
|
||||
|
||||
c->buffer->props.direction = c->target_direction;
|
||||
|
||||
c->buffer->deallocate_var_all ();
|
||||
}
|
||||
|
||||
|
||||
hb_bool_t
|
||||
_hb_ot_shape (hb_shape_plan_t *shape_plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features)
|
||||
{
|
||||
hb_ot_shape_context_t c = {HB_SHAPER_DATA_GET (shape_plan), font, font->face, buffer, features, num_features};
|
||||
hb_ot_shape_internal (&c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
|
||||
hb_tag_t table_tag,
|
||||
hb_set_t *lookup_indexes /* OUT */)
|
||||
{
|
||||
/* XXX Does the first part always succeed? */
|
||||
HB_SHAPER_DATA_GET (shape_plan)->collect_lookups (table_tag, lookup_indexes);
|
||||
}
|
||||
|
||||
|
||||
/* TODO Move this to hb-ot-shape-normalize, make it do decompose, and make it public. */
|
||||
static void
|
||||
add_char (hb_font_t *font,
|
||||
hb_unicode_funcs_t *unicode,
|
||||
hb_bool_t mirror,
|
||||
hb_codepoint_t u,
|
||||
hb_set_t *glyphs)
|
||||
{
|
||||
hb_codepoint_t glyph;
|
||||
if (font->get_glyph (u, 0, &glyph))
|
||||
glyphs->add (glyph);
|
||||
if (mirror)
|
||||
{
|
||||
hb_codepoint_t m = unicode->mirroring (u);
|
||||
if (m != u && font->get_glyph (m, 0, &glyph))
|
||||
glyphs->add (glyph);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hb_ot_shape_glyphs_closure (hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features,
|
||||
hb_set_t *glyphs)
|
||||
{
|
||||
hb_ot_shape_plan_t plan;
|
||||
|
||||
const char *shapers[] = {"ot", NULL};
|
||||
hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props,
|
||||
features, num_features, shapers);
|
||||
|
||||
bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL;
|
||||
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
add_char (font, buffer->unicode, mirror, buffer->info[i].codepoint, glyphs);
|
||||
|
||||
hb_set_t lookups;
|
||||
lookups.init ();
|
||||
hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups);
|
||||
|
||||
/* And find transitive closure. */
|
||||
hb_set_t copy;
|
||||
copy.init ();
|
||||
do {
|
||||
copy.set (glyphs);
|
||||
for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index);)
|
||||
hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
|
||||
} while (!copy.is_equal (glyphs));
|
||||
|
||||
hb_shape_plan_destroy (shape_plan);
|
||||
}
|
722
src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
vendored
Normal file
722
src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
vendored
Normal file
@ -0,0 +1,722 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2011 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod, Roozbeh Pournader
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-ot.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
/* hb_script_t */
|
||||
|
||||
static hb_tag_t
|
||||
hb_ot_old_tag_from_script (hb_script_t script)
|
||||
{
|
||||
/* This seems to be accurate as of end of 2012. */
|
||||
|
||||
switch ((hb_tag_t) script) {
|
||||
case HB_SCRIPT_INVALID: return HB_OT_TAG_DEFAULT_SCRIPT;
|
||||
|
||||
/* KATAKANA and HIRAGANA both map to 'kana' */
|
||||
case HB_SCRIPT_HIRAGANA: return HB_TAG('k','a','n','a');
|
||||
|
||||
/* Spaces at the end are preserved, unlike ISO 15924 */
|
||||
case HB_SCRIPT_LAO: return HB_TAG('l','a','o',' ');
|
||||
case HB_SCRIPT_YI: return HB_TAG('y','i',' ',' ');
|
||||
/* Unicode-5.0 additions */
|
||||
case HB_SCRIPT_NKO: return HB_TAG('n','k','o',' ');
|
||||
/* Unicode-5.1 additions */
|
||||
case HB_SCRIPT_VAI: return HB_TAG('v','a','i',' ');
|
||||
/* Unicode-5.2 additions */
|
||||
/* Unicode-6.0 additions */
|
||||
}
|
||||
|
||||
/* Else, just change first char to lowercase and return */
|
||||
return ((hb_tag_t) script) | 0x20000000;
|
||||
}
|
||||
|
||||
static hb_script_t
|
||||
hb_ot_old_tag_to_script (hb_tag_t tag)
|
||||
{
|
||||
if (unlikely (tag == HB_OT_TAG_DEFAULT_SCRIPT))
|
||||
return HB_SCRIPT_INVALID;
|
||||
|
||||
/* This side of the conversion is fully algorithmic. */
|
||||
|
||||
/* Any spaces at the end of the tag are replaced by repeating the last
|
||||
* letter. Eg 'nko ' -> 'Nkoo' */
|
||||
if (unlikely ((tag & 0x0000FF00) == 0x00002000))
|
||||
tag |= (tag >> 8) & 0x0000FF00; /* Copy second letter to third */
|
||||
if (unlikely ((tag & 0x000000FF) == 0x00000020))
|
||||
tag |= (tag >> 8) & 0x000000FF; /* Copy third letter to fourth */
|
||||
|
||||
/* Change first char to uppercase and return */
|
||||
return (hb_script_t) (tag & ~0x20000000);
|
||||
}
|
||||
|
||||
static hb_tag_t
|
||||
hb_ot_new_tag_from_script (hb_script_t script)
|
||||
{
|
||||
switch ((hb_tag_t) script) {
|
||||
case HB_SCRIPT_BENGALI: return HB_TAG('b','n','g','2');
|
||||
case HB_SCRIPT_DEVANAGARI: return HB_TAG('d','e','v','2');
|
||||
case HB_SCRIPT_GUJARATI: return HB_TAG('g','j','r','2');
|
||||
case HB_SCRIPT_GURMUKHI: return HB_TAG('g','u','r','2');
|
||||
case HB_SCRIPT_KANNADA: return HB_TAG('k','n','d','2');
|
||||
case HB_SCRIPT_MALAYALAM: return HB_TAG('m','l','m','2');
|
||||
case HB_SCRIPT_ORIYA: return HB_TAG('o','r','y','2');
|
||||
case HB_SCRIPT_TAMIL: return HB_TAG('t','m','l','2');
|
||||
case HB_SCRIPT_TELUGU: return HB_TAG('t','e','l','2');
|
||||
case HB_SCRIPT_MYANMAR: return HB_TAG('m','y','m','2');
|
||||
}
|
||||
|
||||
return HB_OT_TAG_DEFAULT_SCRIPT;
|
||||
}
|
||||
|
||||
static hb_script_t
|
||||
hb_ot_new_tag_to_script (hb_tag_t tag)
|
||||
{
|
||||
switch (tag) {
|
||||
case HB_TAG('b','n','g','2'): return HB_SCRIPT_BENGALI;
|
||||
case HB_TAG('d','e','v','2'): return HB_SCRIPT_DEVANAGARI;
|
||||
case HB_TAG('g','j','r','2'): return HB_SCRIPT_GUJARATI;
|
||||
case HB_TAG('g','u','r','2'): return HB_SCRIPT_GURMUKHI;
|
||||
case HB_TAG('k','n','d','2'): return HB_SCRIPT_KANNADA;
|
||||
case HB_TAG('m','l','m','2'): return HB_SCRIPT_MALAYALAM;
|
||||
case HB_TAG('o','r','y','2'): return HB_SCRIPT_ORIYA;
|
||||
case HB_TAG('t','m','l','2'): return HB_SCRIPT_TAMIL;
|
||||
case HB_TAG('t','e','l','2'): return HB_SCRIPT_TELUGU;
|
||||
case HB_TAG('m','y','m','2'): return HB_SCRIPT_MYANMAR;
|
||||
}
|
||||
|
||||
return HB_SCRIPT_UNKNOWN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Complete list at:
|
||||
* https://www.microsoft.com/typography/otspec/scripttags.htm
|
||||
* https://www.microsoft.com/typography/otspec160/scripttagsProposed.htm
|
||||
*
|
||||
* Most of the script tags are the same as the ISO 15924 tag but lowercased.
|
||||
* So we just do that, and handle the exceptional cases in a switch.
|
||||
*/
|
||||
|
||||
void
|
||||
hb_ot_tags_from_script (hb_script_t script,
|
||||
hb_tag_t *script_tag_1,
|
||||
hb_tag_t *script_tag_2)
|
||||
{
|
||||
hb_tag_t new_tag;
|
||||
|
||||
*script_tag_2 = HB_OT_TAG_DEFAULT_SCRIPT;
|
||||
*script_tag_1 = hb_ot_old_tag_from_script (script);
|
||||
|
||||
new_tag = hb_ot_new_tag_from_script (script);
|
||||
if (unlikely (new_tag != HB_OT_TAG_DEFAULT_SCRIPT)) {
|
||||
*script_tag_2 = *script_tag_1;
|
||||
*script_tag_1 = new_tag;
|
||||
}
|
||||
}
|
||||
|
||||
hb_script_t
|
||||
hb_ot_tag_to_script (hb_tag_t tag)
|
||||
{
|
||||
if (unlikely ((tag & 0x000000FF) == '2'))
|
||||
return hb_ot_new_tag_to_script (tag);
|
||||
|
||||
return hb_ot_old_tag_to_script (tag);
|
||||
}
|
||||
|
||||
|
||||
/* hb_language_t */
|
||||
|
||||
typedef struct {
|
||||
char language[6];
|
||||
hb_tag_t tag;
|
||||
} LangTag;
|
||||
|
||||
/*
|
||||
* Complete list at:
|
||||
* http://www.microsoft.com/typography/otspec/languagetags.htm
|
||||
*
|
||||
* Generated by intersecting the OpenType language tag list from
|
||||
* Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
|
||||
* 2008/08/04, matching on name, and finally adjusted manually.
|
||||
*
|
||||
* Updated on 2012/12/07 with more research into remaining codes.
|
||||
*
|
||||
* Some items still missing. Those are commented out at the end.
|
||||
* Keep sorted for bsearch.
|
||||
*/
|
||||
|
||||
static const LangTag ot_languages[] = {
|
||||
{"aa", HB_TAG('A','F','R',' ')}, /* Afar */
|
||||
{"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */
|
||||
{"abq", HB_TAG('A','B','A',' ')}, /* Abaza */
|
||||
{"ada", HB_TAG('D','N','G',' ')}, /* Dangme */
|
||||
{"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */
|
||||
{"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */
|
||||
{"aii", HB_TAG('S','W','A',' ')}, /* Swadaya Aramaic */
|
||||
{"aiw", HB_TAG('A','R','I',' ')}, /* Aari */
|
||||
{"alt", HB_TAG('A','L','T',' ')}, /* [Southern] Altai */
|
||||
{"am", HB_TAG('A','M','H',' ')}, /* Amharic */
|
||||
{"amf", HB_TAG('H','B','N',' ')}, /* Hammer-Banna */
|
||||
{"ar", HB_TAG('A','R','A',' ')}, /* Arabic */
|
||||
{"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */
|
||||
{"as", HB_TAG('A','S','M',' ')}, /* Assamese */
|
||||
{"ath", HB_TAG('A','T','H',' ')}, /* Athapaskan [family] */
|
||||
{"atv", HB_TAG('A','L','T',' ')}, /* [Northern] Altai */
|
||||
{"av", HB_TAG('A','V','R',' ')}, /* Avaric */
|
||||
{"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */
|
||||
{"ay", HB_TAG('A','Y','M',' ')}, /* Aymara */
|
||||
{"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani */
|
||||
{"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */
|
||||
{"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */
|
||||
{"bal", HB_TAG('B','L','I',' ')}, /* Baluchi */
|
||||
{"bci", HB_TAG('B','A','U',' ')}, /* Baule */
|
||||
{"bcq", HB_TAG('B','C','H',' ')}, /* Bench */
|
||||
{"be", HB_TAG('B','E','L',' ')}, /* Belarussian */
|
||||
{"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */
|
||||
{"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */
|
||||
{"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */
|
||||
{"bft", HB_TAG('B','L','T',' ')}, /* Balti */
|
||||
{"bfy", HB_TAG('B','A','G',' ')}, /* Baghelkhandi */
|
||||
{"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */
|
||||
{"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */
|
||||
{"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */
|
||||
{"bik", HB_TAG('B','I','K',' ')}, /* Bikol */
|
||||
{"bin", HB_TAG('E','D','O',' ')}, /* Bini */
|
||||
{"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja */
|
||||
{"bla", HB_TAG('B','K','F',' ')}, /* Blackfoot */
|
||||
{"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe */
|
||||
{"bm", HB_TAG('B','M','B',' ')}, /* Bambara */
|
||||
{"bn", HB_TAG('B','E','N',' ')}, /* Bengali */
|
||||
{"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */
|
||||
{"br", HB_TAG('B','R','E',' ')}, /* Breton */
|
||||
{"bra", HB_TAG('B','R','I',' ')}, /* Braj Bhasha */
|
||||
{"brh", HB_TAG('B','R','H',' ')}, /* Brahui */
|
||||
{"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */
|
||||
{"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) */
|
||||
{"bxr", HB_TAG('R','B','U',' ')}, /* Russian Buriat */
|
||||
{"byn", HB_TAG('B','I','L',' ')}, /* Bilen */
|
||||
{"ca", HB_TAG('C','A','T',' ')}, /* Catalan */
|
||||
{"ce", HB_TAG('C','H','E',' ')}, /* Chechen */
|
||||
{"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */
|
||||
{"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
|
||||
{"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */
|
||||
{"ckt", HB_TAG('C','H','K',' ')}, /* Chukchi */
|
||||
{"cop", HB_TAG('C','O','P',' ')}, /* Coptic */
|
||||
{"cr", HB_TAG('C','R','E',' ')}, /* Cree */
|
||||
{"crh", HB_TAG('C','R','T',' ')}, /* Crimean Tatar */
|
||||
{"crj", HB_TAG('E','C','R',' ')}, /* [Southern] East Cree */
|
||||
{"crl", HB_TAG('E','C','R',' ')}, /* [Northern] East Cree */
|
||||
{"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
|
||||
{"crx", HB_TAG('C','R','R',' ')}, /* Carrier */
|
||||
{"cs", HB_TAG('C','S','Y',' ')}, /* Czech */
|
||||
{"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */
|
||||
{"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */
|
||||
{"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */
|
||||
{"cy", HB_TAG('W','E','L',' ')}, /* Welsh */
|
||||
{"da", HB_TAG('D','A','N',' ')}, /* Danish */
|
||||
{"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) */
|
||||
{"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */
|
||||
{"de", HB_TAG('D','E','U',' ')}, /* German */
|
||||
{"din", HB_TAG('D','N','K',' ')}, /* Dinka */
|
||||
{"dje", HB_TAG('D','J','R',' ')}, /* Djerma */
|
||||
{"dng", HB_TAG('D','U','N',' ')}, /* Dungan */
|
||||
{"doi", HB_TAG('D','G','R',' ')}, /* Dogri */
|
||||
{"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */
|
||||
{"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi */
|
||||
{"dyu", HB_TAG('J','U','L',' ')}, /* Jula */
|
||||
{"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */
|
||||
{"ee", HB_TAG('E','W','E',' ')}, /* Ewe */
|
||||
{"efi", HB_TAG('E','F','I',' ')}, /* Efik */
|
||||
{"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) */
|
||||
{"en", HB_TAG('E','N','G',' ')}, /* English */
|
||||
{"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */
|
||||
{"eot", HB_TAG('B','T','I',' ')}, /* Beti (Côte d'Ivoire) */
|
||||
{"es", HB_TAG('E','S','P',' ')}, /* Spanish */
|
||||
{"et", HB_TAG('E','T','I',' ')}, /* Estonian */
|
||||
{"eu", HB_TAG('E','U','Q',' ')}, /* Basque */
|
||||
{"eve", HB_TAG('E','V','N',' ')}, /* Even */
|
||||
{"evn", HB_TAG('E','V','K',' ')}, /* Evenki */
|
||||
{"fa", HB_TAG('F','A','R',' ')}, /* Persian */
|
||||
{"ff", HB_TAG('F','U','L',' ')}, /* Fulah */
|
||||
{"fi", HB_TAG('F','I','N',' ')}, /* Finnish */
|
||||
{"fil", HB_TAG('P','I','L',' ')}, /* Filipino */
|
||||
{"fj", HB_TAG('F','J','I',' ')}, /* Fijian */
|
||||
{"fo", HB_TAG('F','O','S',' ')}, /* Faroese */
|
||||
{"fon", HB_TAG('F','O','N',' ')}, /* Fon */
|
||||
{"fr", HB_TAG('F','R','A',' ')}, /* French */
|
||||
{"fur", HB_TAG('F','R','L',' ')}, /* Friulian */
|
||||
{"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian */
|
||||
{"ga", HB_TAG('I','R','I',' ')}, /* Irish */
|
||||
{"gaa", HB_TAG('G','A','D',' ')}, /* Ga */
|
||||
{"gag", HB_TAG('G','A','G',' ')}, /* Gagauz */
|
||||
{"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */
|
||||
{"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */
|
||||
{"gez", HB_TAG('G','E','Z',' ')}, /* Ge'ez */
|
||||
{"gl", HB_TAG('G','A','L',' ')}, /* Galician */
|
||||
{"gld", HB_TAG('N','A','N',' ')}, /* Nanai */
|
||||
{"gn", HB_TAG('G','U','A',' ')}, /* Guarani */
|
||||
{"gon", HB_TAG('G','O','N',' ')}, /* Gondi */
|
||||
{"grt", HB_TAG('G','R','O',' ')}, /* Garo */
|
||||
{"gru", HB_TAG('S','O','G',' ')}, /* Sodo Gurage */
|
||||
{"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */
|
||||
{"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */
|
||||
{"gv", HB_TAG('M','N','X',' ')}, /* Manx Gaelic */
|
||||
{"ha", HB_TAG('H','A','U',' ')}, /* Hausa */
|
||||
{"har", HB_TAG('H','R','I',' ')}, /* Harari */
|
||||
{"haw", HB_TAG('H','A','W',' ')}, /* Hawaiin */
|
||||
{"he", HB_TAG('I','W','R',' ')}, /* Hebrew */
|
||||
{"hi", HB_TAG('H','I','N',' ')}, /* Hindi */
|
||||
{"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */
|
||||
{"hnd", HB_TAG('H','N','D',' ')}, /* [Southern] Hindko */
|
||||
{"hne", HB_TAG('C','H','H',' ')}, /* Chattisgarhi */
|
||||
{"hno", HB_TAG('H','N','D',' ')}, /* [Northern] Hindko */
|
||||
{"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */
|
||||
{"hoj", HB_TAG('H','A','R',' ')}, /* Harauti */
|
||||
{"hr", HB_TAG('H','R','V',' ')}, /* Croatian */
|
||||
{"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */
|
||||
{"ht", HB_TAG('H','A','I',' ')}, /* Haitian */
|
||||
{"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */
|
||||
{"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */
|
||||
{"id", HB_TAG('I','N','D',' ')}, /* Indonesian */
|
||||
{"ig", HB_TAG('I','B','O',' ')}, /* Igbo */
|
||||
{"igb", HB_TAG('E','B','I',' ')}, /* Ebira */
|
||||
{"ijo", HB_TAG('I','J','O',' ')}, /* Ijo [family] */
|
||||
{"ilo", HB_TAG('I','L','O',' ')}, /* Ilokano */
|
||||
{"inh", HB_TAG('I','N','G',' ')}, /* Ingush */
|
||||
{"is", HB_TAG('I','S','L',' ')}, /* Icelandic */
|
||||
{"it", HB_TAG('I','T','A',' ')}, /* Italian */
|
||||
{"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut */
|
||||
{"ja", HB_TAG('J','A','N',' ')}, /* Japanese */
|
||||
{"jv", HB_TAG('J','A','V',' ')}, /* Javanese */
|
||||
{"ka", HB_TAG('K','A','T',' ')}, /* Georgian */
|
||||
{"kaa", HB_TAG('K','R','K',' ')}, /* Karakalpak */
|
||||
{"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
|
||||
{"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */
|
||||
{"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */
|
||||
{"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */
|
||||
{"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */
|
||||
{"kex", HB_TAG('K','K','N',' ')}, /* Kokni */
|
||||
{"kfr", HB_TAG('K','A','C',' ')}, /* Kachchi */
|
||||
{"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */
|
||||
{"kha", HB_TAG('K','S','I',' ')}, /* Khasi */
|
||||
{"khb", HB_TAG('X','B','D',' ')}, /* Tai Lue */
|
||||
{"khw", HB_TAG('K','H','W',' ')}, /* Khowar */
|
||||
{"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu */
|
||||
{"kjh", HB_TAG('K','H','A',' ')}, /* Khakass */
|
||||
{"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */
|
||||
{"kl", HB_TAG('G','R','N',' ')}, /* Kalaallisut */
|
||||
{"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin */
|
||||
{"km", HB_TAG('K','H','M',' ')}, /* Central Khmer */
|
||||
{"kmb", HB_TAG('M','B','N',' ')}, /* [North] Mbundu */
|
||||
{"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */
|
||||
{"kn", HB_TAG('K','A','N',' ')}, /* Kannada */
|
||||
{"ko", HB_TAG('K','O','R',' ')}, /* Korean */
|
||||
{"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */
|
||||
{"kok", HB_TAG('K','O','K',' ')}, /* Konkani */
|
||||
{"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle */
|
||||
{"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */
|
||||
{"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */
|
||||
{"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */
|
||||
{"kr", HB_TAG('K','N','R',' ')}, /* Kanuri */
|
||||
{"kri", HB_TAG('K','R','I',' ')}, /* Krio */
|
||||
{"krl", HB_TAG('K','R','L',' ')}, /* Karelian */
|
||||
{"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */
|
||||
{"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */
|
||||
{"ku", HB_TAG('K','U','R',' ')}, /* Kurdish */
|
||||
{"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */
|
||||
{"kvd", HB_TAG('K','U','I',' ')}, /* Kui (Indonesia) */
|
||||
{"kxc", HB_TAG('K','M','S',' ')}, /* Komso */
|
||||
{"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */
|
||||
{"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz */
|
||||
{"la", HB_TAG('L','A','T',' ')}, /* Latin */
|
||||
{"lad", HB_TAG('J','U','D',' ')}, /* Ladino */
|
||||
{"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */
|
||||
{"lbe", HB_TAG('L','A','K',' ')}, /* Lak */
|
||||
{"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */
|
||||
{"lez", HB_TAG('L','E','Z',' ')}, /* Lezgi */
|
||||
{"lg", HB_TAG('L','U','G',' ')}, /* Luganda */
|
||||
{"lif", HB_TAG('L','M','B',' ')}, /* Limbu */
|
||||
{"lld", HB_TAG('L','A','D',' ')}, /* Ladin */
|
||||
{"lmn", HB_TAG('L','A','M',' ')}, /* Lambani */
|
||||
{"ln", HB_TAG('L','I','N',' ')}, /* Lingala */
|
||||
{"lo", HB_TAG('L','A','O',' ')}, /* Lao */
|
||||
{"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */
|
||||
{"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */
|
||||
{"lua", HB_TAG('L','U','B',' ')}, /* Luba-Kasai */
|
||||
{"luo", HB_TAG('L','U','O',' ')}, /* Luo (Kenya and Tanzania) */
|
||||
{"lus", HB_TAG('M','I','Z',' ')}, /* Mizo */
|
||||
{"luy", HB_TAG('L','U','H',' ')}, /* Luhya [macrolanguage] */
|
||||
{"lv", HB_TAG('L','V','I',' ')}, /* Latvian */
|
||||
{"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */
|
||||
{"mai", HB_TAG('M','T','H',' ')}, /* Maithili */
|
||||
{"mdc", HB_TAG('M','L','E',' ')}, /* Male (Papua New Guinea) */
|
||||
{"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */
|
||||
{"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */
|
||||
{"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */
|
||||
{"mg", HB_TAG('M','L','G',' ')}, /* Malagasy */
|
||||
{"mhr", HB_TAG('L','M','A',' ')}, /* Low Mari */
|
||||
{"mi", HB_TAG('M','R','I',' ')}, /* Maori */
|
||||
{"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */
|
||||
{"ml", HB_TAG('M','L','R',' ')}, /* Malayalam */
|
||||
{"mn", HB_TAG('M','N','G',' ')}, /* Mongolian */
|
||||
{"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */
|
||||
{"mni", HB_TAG('M','N','I',' ')}, /* Manipuri */
|
||||
{"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */
|
||||
{"mns", HB_TAG('M','A','N',' ')}, /* Mansi */
|
||||
{"mnw", HB_TAG('M','O','N',' ')}, /* Mon */
|
||||
{"mo", HB_TAG('M','O','L',' ')}, /* Moldavian */
|
||||
{"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */
|
||||
{"mpe", HB_TAG('M','A','J',' ')}, /* Majang */
|
||||
{"mr", HB_TAG('M','A','R',' ')}, /* Marathi */
|
||||
{"mrj", HB_TAG('H','M','A',' ')}, /* High Mari */
|
||||
{"ms", HB_TAG('M','L','Y',' ')}, /* Malay */
|
||||
{"mt", HB_TAG('M','T','S',' ')}, /* Maltese */
|
||||
{"mwr", HB_TAG('M','A','W',' ')}, /* Marwari */
|
||||
{"my", HB_TAG('B','R','M',' ')}, /* Burmese */
|
||||
{"mym", HB_TAG('M','E','N',' ')}, /* Me'en */
|
||||
{"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */
|
||||
{"nag", HB_TAG('N','A','G',' ')}, /* Naga-Assamese */
|
||||
{"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål */
|
||||
{"nco", HB_TAG('S','I','B',' ')}, /* Sibe */
|
||||
{"nd", HB_TAG('N','D','B',' ')}, /* [North] Ndebele */
|
||||
{"ne", HB_TAG('N','E','P',' ')}, /* Nepali */
|
||||
{"new", HB_TAG('N','E','W',' ')}, /* Newari */
|
||||
{"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */
|
||||
{"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */
|
||||
{"niu", HB_TAG('N','I','U',' ')}, /* Niuean */
|
||||
{"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */
|
||||
{"nl", HB_TAG('N','L','D',' ')}, /* Dutch */
|
||||
{"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk */
|
||||
{"no", HB_TAG('N','O','R',' ')}, /* Norwegian (deprecated) */
|
||||
{"nod", HB_TAG('N','T','A',' ')}, /* Northern Tai */
|
||||
{"nog", HB_TAG('N','O','G',' ')}, /* Nogai */
|
||||
{"nqo", HB_TAG('N','K','O',' ')}, /* N'Ko */
|
||||
{"nr", HB_TAG('N','D','B',' ')}, /* [South] Ndebele */
|
||||
{"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */
|
||||
{"nso", HB_TAG('S','O','T',' ')}, /* [Northern] Sotho */
|
||||
{"ny", HB_TAG('C','H','I',' ')}, /* Nyanja */
|
||||
{"nyn", HB_TAG('N','K','L',' ')}, /* Nkole */
|
||||
{"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */
|
||||
{"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa */
|
||||
{"ojs", HB_TAG('O','C','R',' ')}, /* Oji-Cree */
|
||||
{"om", HB_TAG('O','R','O',' ')}, /* Oromo */
|
||||
{"or", HB_TAG('O','R','I',' ')}, /* Oriya */
|
||||
{"os", HB_TAG('O','S','S',' ')}, /* Ossetian */
|
||||
{"pa", HB_TAG('P','A','N',' ')}, /* Panjabi */
|
||||
{"pce", HB_TAG('P','L','G',' ')}, /* [Ruching] Palaung */
|
||||
{"pi", HB_TAG('P','A','L',' ')}, /* Pali */
|
||||
{"pl", HB_TAG('P','L','K',' ')}, /* Polish */
|
||||
{"pll", HB_TAG('P','L','G',' ')}, /* [Shwe] Palaung */
|
||||
{"plp", HB_TAG('P','A','P',' ')}, /* Palpa */
|
||||
{"prs", HB_TAG('D','R','I',' ')}, /* Dari */
|
||||
{"ps", HB_TAG('P','A','S',' ')}, /* Pushto */
|
||||
{"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */
|
||||
{"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani */
|
||||
{"rbb", HB_TAG('P','L','G',' ')}, /* [Rumai] Palaung */
|
||||
{"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */
|
||||
{"ril", HB_TAG('R','I','A',' ')}, /* Riang (Myanmar) */
|
||||
{"rki", HB_TAG('A','R','K',' ')}, /* Arakanese */
|
||||
{"rm", HB_TAG('R','M','S',' ')}, /* Rhaeto-Romanic */
|
||||
{"ro", HB_TAG('R','O','M',' ')}, /* Romanian */
|
||||
{"rom", HB_TAG('R','O','Y',' ')}, /* Romany */
|
||||
{"ru", HB_TAG('R','U','S',' ')}, /* Russian */
|
||||
{"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */
|
||||
{"rw", HB_TAG('R','U','A',' ')}, /* Ruanda */
|
||||
{"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */
|
||||
{"sah", HB_TAG('Y','A','K',' ')}, /* Yakut */
|
||||
{"sat", HB_TAG('S','A','T',' ')}, /* Santali */
|
||||
{"sck", HB_TAG('S','A','D',' ')}, /* Sadri */
|
||||
{"scs", HB_TAG('S','L','A',' ')}, /* [North] Slavey */
|
||||
{"sd", HB_TAG('S','N','D',' ')}, /* Sindhi */
|
||||
{"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */
|
||||
{"seh", HB_TAG('S','N','A',' ')}, /* Sena */
|
||||
{"sel", HB_TAG('S','E','L',' ')}, /* Selkup */
|
||||
{"sg", HB_TAG('S','G','O',' ')}, /* Sango */
|
||||
{"shn", HB_TAG('S','H','N',' ')}, /* Shan */
|
||||
{"si", HB_TAG('S','N','H',' ')}, /* Sinhala */
|
||||
{"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */
|
||||
{"sjd", HB_TAG('K','S','M',' ')}, /* Kildin Sami */
|
||||
{"sk", HB_TAG('S','K','Y',' ')}, /* Slovak */
|
||||
{"skr", HB_TAG('S','R','K',' ')}, /* Seraiki */
|
||||
{"sl", HB_TAG('S','L','V',' ')}, /* Slovenian */
|
||||
{"sm", HB_TAG('S','M','O',' ')}, /* Samoan */
|
||||
{"sma", HB_TAG('S','S','M',' ')}, /* Southern Sami */
|
||||
{"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */
|
||||
{"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */
|
||||
{"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */
|
||||
{"snk", HB_TAG('S','N','K',' ')}, /* Soninke */
|
||||
{"so", HB_TAG('S','M','L',' ')}, /* Somali */
|
||||
{"sq", HB_TAG('S','Q','I',' ')}, /* Albanian */
|
||||
{"sr", HB_TAG('S','R','B',' ')}, /* Serbian */
|
||||
{"srr", HB_TAG('S','R','R',' ')}, /* Serer */
|
||||
{"ss", HB_TAG('S','W','Z',' ')}, /* Swazi */
|
||||
{"st", HB_TAG('S','O','T',' ')}, /* [Southern] Sotho */
|
||||
{"suq", HB_TAG('S','U','R',' ')}, /* Suri */
|
||||
{"sv", HB_TAG('S','V','E',' ')}, /* Swedish */
|
||||
{"sva", HB_TAG('S','V','A',' ')}, /* Svan */
|
||||
{"sw", HB_TAG('S','W','K',' ')}, /* Swahili */
|
||||
{"swb", HB_TAG('C','M','R',' ')}, /* Comorian */
|
||||
{"syr", HB_TAG('S','Y','R',' ')}, /* Syriac */
|
||||
{"ta", HB_TAG('T','A','M',' ')}, /* Tamil */
|
||||
{"tab", HB_TAG('T','A','B',' ')}, /* Tabasaran */
|
||||
{"tcy", HB_TAG('T','U','L',' ')}, /* Tulu */
|
||||
{"te", HB_TAG('T','E','L',' ')}, /* Telugu */
|
||||
{"tem", HB_TAG('T','M','N',' ')}, /* Temne */
|
||||
{"tg", HB_TAG('T','A','J',' ')}, /* Tajik */
|
||||
{"th", HB_TAG('T','H','A',' ')}, /* Thai */
|
||||
{"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */
|
||||
{"tig", HB_TAG('T','G','R',' ')}, /* Tigre */
|
||||
{"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */
|
||||
{"tn", HB_TAG('T','N','A',' ')}, /* Tswana */
|
||||
{"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) */
|
||||
{"tr", HB_TAG('T','R','K',' ')}, /* Turkish */
|
||||
{"tru", HB_TAG('T','U','A',' ')}, /* Turoyo Aramaic */
|
||||
{"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */
|
||||
{"tt", HB_TAG('T','A','T',' ')}, /* Tatar */
|
||||
{"tw", HB_TAG('T','W','I',' ')}, /* Twi */
|
||||
{"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */
|
||||
{"tyv", HB_TAG('T','U','V',' ')}, /* Tuvin */
|
||||
{"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */
|
||||
{"ug", HB_TAG('U','Y','G',' ')}, /* Uighur */
|
||||
{"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */
|
||||
{"umb", HB_TAG('M','B','N',' ')}, /* [South] Mbundu */
|
||||
{"unr", HB_TAG('M','U','N',' ')}, /* Mundari */
|
||||
{"ur", HB_TAG('U','R','D',' ')}, /* Urdu */
|
||||
{"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek */
|
||||
{"ve", HB_TAG('V','E','N',' ')}, /* Venda */
|
||||
{"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */
|
||||
{"vmw", HB_TAG('M','A','K',' ')}, /* Makua */
|
||||
{"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */
|
||||
{"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */
|
||||
{"wo", HB_TAG('W','L','F',' ')}, /* Wolof */
|
||||
{"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */
|
||||
{"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */
|
||||
{"xom", HB_TAG('K','M','O',' ')}, /* Komo (Sudan) */
|
||||
{"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */
|
||||
{"yi", HB_TAG('J','I','I',' ')}, /* Yiddish */
|
||||
{"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */
|
||||
{"yso", HB_TAG('N','I','S',' ')}, /* Nisi (China) */
|
||||
{"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
|
||||
{"zu", HB_TAG('Z','U','L',' ')} /* Zulu */
|
||||
|
||||
/* The corresponding languages IDs for the following IDs are unclear,
|
||||
* overlap, or are architecturally weird. Needs more research. */
|
||||
|
||||
/*{"ahg/awn/xan?", HB_TAG('A','G','W',' ')},*/ /* Agaw */
|
||||
/*{"gsw?/gsw-FR?", HB_TAG('A','L','S',' ')},*/ /* Alsatian */
|
||||
/*{"krc", HB_TAG('B','A','L',' ')},*/ /* Balkar */
|
||||
/*{"??", HB_TAG('B','C','R',' ')},*/ /* Bible Cree */
|
||||
/*{"sgw?", HB_TAG('C','H','G',' ')},*/ /* Chaha Gurage */
|
||||
/*{"acf/gcf?", HB_TAG('F','A','N',' ')},*/ /* French Antillean */
|
||||
/*{"vls/nl-be", HB_TAG('F','L','E',' ')},*/ /* Flemish */
|
||||
/*{"enf?/yrk?", HB_TAG('F','N','E',' ')},*/ /* Forest Nenets */
|
||||
/*{"fuf?", HB_TAG('F','T','A',' ')},*/ /* Futa */
|
||||
/*{"ar-Syrc?", HB_TAG('G','A','R',' ')},*/ /* Garshuni */
|
||||
/*{"cfm/rnl?", HB_TAG('H','A','L',' ')},*/ /* Halam */
|
||||
/*{"ga-Latg?/Latg?", HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */
|
||||
/*{"krc", HB_TAG('K','A','R',' ')},*/ /* Karachay */
|
||||
/*{"alw?/ktb?", HB_TAG('K','E','B',' ')},*/ /* Kebena */
|
||||
/*{"Geok", HB_TAG('K','G','E',' ')},*/ /* Khutsuri Georgian */
|
||||
/*{"kca", HB_TAG('K','H','K',' ')},*/ /* Khanty-Kazim */
|
||||
/*{"kca", HB_TAG('K','H','S',' ')},*/ /* Khanty-Shurishkar */
|
||||
/*{"kca", HB_TAG('K','H','V',' ')},*/ /* Khanty-Vakhi */
|
||||
/*{"guz?/kqs?/kss?", HB_TAG('K','I','S',' ')},*/ /* Kisii */
|
||||
/*{"kfa/kfi?/kpb?/xua?/xuj?", HB_TAG('K','O','D',' ')},*/ /* Kodagu */
|
||||
/*{"okm?/oko?", HB_TAG('K','O','H',' ')},*/ /* Korean Old Hangul */
|
||||
/*{"kon?/ktu?/...", HB_TAG('K','O','N',' ')},*/ /* Kikongo */
|
||||
/*{"kfx?", HB_TAG('K','U','L',' ')},*/ /* Kulvi */
|
||||
/*{"??", HB_TAG('L','A','H',' ')},*/ /* Lahuli */
|
||||
/*{"??", HB_TAG('L','C','R',' ')},*/ /* L-Cree */
|
||||
/*{"??", HB_TAG('M','A','L',' ')},*/ /* Malayalam Traditional */
|
||||
/*{"mnk?/mlq?/...", HB_TAG('M','L','N',' ')},*/ /* Malinke */
|
||||
/*{"man?/myq?/mku?/msc?/...", HB_TAG('M','N','K',' ')},*/ /* Maninka */
|
||||
/*{"??", HB_TAG('M','O','R',' ')},*/ /* Moroccan */
|
||||
/*{"??", HB_TAG('N','C','R',' ')},*/ /* N-Cree */
|
||||
/*{"??", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */
|
||||
/*{"jpa?/sam?", HB_TAG('P','A','A',' ')},*/ /* Palestinian Aramaic */
|
||||
/*{"polyton", HB_TAG('P','G','R',' ')},*/ /* Polytonic Greek */
|
||||
/*{"??", HB_TAG('Q','I','N',' ')},*/ /* Asho Chin */
|
||||
/*{"??", HB_TAG('R','C','R',' ')},*/ /* R-Cree */
|
||||
/*{"chp?", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */
|
||||
/*{"xan?", HB_TAG('S','E','K',' ')},*/ /* Sekota */
|
||||
/*{"stv/wle?/xst?", HB_TAG('S','I','G',' ')},*/ /* Silte Gurage */
|
||||
/*{"ngo?", HB_TAG('S','X','T',' ')},*/ /* Sutu */
|
||||
/*{"??", HB_TAG('T','C','R',' ')},*/ /* TH-Cree */
|
||||
/*{"tnz?/tog?/toi?", HB_TAG('T','N','G',' ')},*/ /* Tonga */
|
||||
/*{"enh?/yrk?", HB_TAG('T','N','E',' ')},*/ /* Tundra Nenets */
|
||||
/*{"??", HB_TAG('T','O','D',' ')},*/ /* Todo */
|
||||
/*{"??", HB_TAG('W','C','R',' ')},*/ /* West-Cree */
|
||||
/*{"??", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */
|
||||
/*{"??", HB_TAG('Y','I','C',' ')},*/ /* Yi Classic */
|
||||
/*{"ii?/Yiii?", HB_TAG('Y','I','M',' ')},*/ /* Yi Modern */
|
||||
/*{"??", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */
|
||||
};
|
||||
|
||||
static const LangTag ot_languages_zh[] = {
|
||||
{"zh-cn", HB_TAG('Z','H','S',' ')}, /* Chinese (China) */
|
||||
{"zh-hk", HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */
|
||||
{"zh-mo", HB_TAG('Z','H','T',' ')}, /* Chinese (Macao) */
|
||||
{"zh-sg", HB_TAG('Z','H','S',' ')}, /* Chinese (Singapore) */
|
||||
{"zh-tw", HB_TAG('Z','H','T',' ')} /* Chinese (Taiwan) */
|
||||
};
|
||||
|
||||
static int
|
||||
lang_compare_first_component (const char *a,
|
||||
const char *b)
|
||||
{
|
||||
unsigned int da, db;
|
||||
const char *p;
|
||||
|
||||
p = strchr (a, '-');
|
||||
da = p ? (unsigned int) (p - a) : strlen (a);
|
||||
|
||||
p = strchr (b, '-');
|
||||
db = p ? (unsigned int) (p - b) : strlen (b);
|
||||
|
||||
return strncmp (a, b, MAX (da, db));
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
lang_matches (const char *lang_str, const char *spec)
|
||||
{
|
||||
unsigned int len = strlen (spec);
|
||||
|
||||
return strncmp (lang_str, spec, len) == 0 &&
|
||||
(lang_str[len] == '\0' || lang_str[len] == '-');
|
||||
}
|
||||
|
||||
hb_tag_t
|
||||
hb_ot_tag_from_language (hb_language_t language)
|
||||
{
|
||||
const char *lang_str, *s;
|
||||
const LangTag *lang_tag;
|
||||
|
||||
if (language == HB_LANGUAGE_INVALID)
|
||||
return HB_OT_TAG_DEFAULT_LANGUAGE;
|
||||
|
||||
lang_str = hb_language_to_string (language);
|
||||
|
||||
s = strstr (lang_str, "x-hbot");
|
||||
if (s) {
|
||||
char tag[4];
|
||||
int i;
|
||||
s += 6;
|
||||
for (i = 0; i < 4 && ISALPHA (s[i]); i++)
|
||||
tag[i] = TOUPPER (s[i]);
|
||||
if (i) {
|
||||
for (; i < 4; i++)
|
||||
tag[i] = ' ';
|
||||
return HB_TAG_CHAR4 (tag);
|
||||
}
|
||||
}
|
||||
|
||||
/* Find a language matching in the first component */
|
||||
lang_tag = (LangTag *) bsearch (lang_str, ot_languages,
|
||||
ARRAY_LENGTH (ot_languages), sizeof (LangTag),
|
||||
(hb_compare_func_t) lang_compare_first_component);
|
||||
if (lang_tag)
|
||||
return lang_tag->tag;
|
||||
|
||||
/* Otherwise, check the Chinese ones */
|
||||
if (0 == lang_compare_first_component (lang_str, "zh"))
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH (ot_languages_zh); i++)
|
||||
{
|
||||
lang_tag = &ot_languages_zh[i];
|
||||
if (lang_matches (lang_tag->language, lang_str))
|
||||
return lang_tag->tag;
|
||||
}
|
||||
|
||||
/* Otherwise just return 'ZHS ' */
|
||||
return HB_TAG('Z','H','S',' ');
|
||||
}
|
||||
|
||||
s = strchr (lang_str, '-');
|
||||
if (!s)
|
||||
s = lang_str + strlen (lang_str);
|
||||
if (s - lang_str == 3) {
|
||||
/* Assume it's ISO-639-3 and upper-case and use it. */
|
||||
return hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000;
|
||||
}
|
||||
|
||||
return HB_OT_TAG_DEFAULT_LANGUAGE;
|
||||
}
|
||||
|
||||
hb_language_t
|
||||
hb_ot_tag_to_language (hb_tag_t tag)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (tag == HB_OT_TAG_DEFAULT_LANGUAGE)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH (ot_languages); i++)
|
||||
if (ot_languages[i].tag == tag)
|
||||
return hb_language_from_string (ot_languages[i].language, -1);
|
||||
|
||||
/* If tag starts with ZH, it's Chinese */
|
||||
if ((tag & 0xFFFF0000) == 0x5A480000) {
|
||||
switch (tag) {
|
||||
case HB_TAG('Z','H','H',' '): return hb_language_from_string ("zh-hk", -1); /* Hong Kong */
|
||||
default: {
|
||||
/* Encode the tag... */
|
||||
unsigned char buf[14] = "zh-x-hbot";
|
||||
buf[9] = tag >> 24;
|
||||
buf[10] = (tag >> 16) & 0xFF;
|
||||
buf[11] = (tag >> 8) & 0xFF;
|
||||
buf[12] = tag & 0xFF;
|
||||
if (buf[12] == 0x20)
|
||||
buf[12] = '\0';
|
||||
buf[13] = '\0';
|
||||
return hb_language_from_string ((char *) buf, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Else return a custom language in the form of "x-hbotABCD" */
|
||||
{
|
||||
unsigned char buf[11] = "x-hbot";
|
||||
buf[6] = tag >> 24;
|
||||
buf[7] = (tag >> 16) & 0xFF;
|
||||
buf[8] = (tag >> 8) & 0xFF;
|
||||
buf[9] = tag & 0xFF;
|
||||
if (buf[9] == 0x20)
|
||||
buf[9] = '\0';
|
||||
buf[10] = '\0';
|
||||
return hb_language_from_string ((char *) buf, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
59
src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h
vendored
Normal file
59
src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_H_IN
|
||||
#error "Include <hb-ot.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_OT_TAG_H
|
||||
#define HB_OT_TAG_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
#define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T')
|
||||
#define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't')
|
||||
|
||||
void
|
||||
hb_ot_tags_from_script (hb_script_t script,
|
||||
hb_tag_t *script_tag_1,
|
||||
hb_tag_t *script_tag_2);
|
||||
|
||||
hb_script_t
|
||||
hb_ot_tag_to_script (hb_tag_t tag);
|
||||
|
||||
hb_tag_t
|
||||
hb_ot_tag_from_language (hb_language_t language);
|
||||
|
||||
hb_language_t
|
||||
hb_ot_tag_to_language (hb_tag_t tag);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_OT_TAG_H */
|
49
src/3rdparty/harfbuzz-ng/src/hb-ot.h
vendored
Normal file
49
src/3rdparty/harfbuzz-ng/src/hb-ot.h
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_H
|
||||
#define HB_OT_H
|
||||
#define HB_OT_H_IN
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
#include "hb-ot-layout.h"
|
||||
#include "hb-ot-tag.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
/* TODO remove */
|
||||
void
|
||||
hb_ot_shape_glyphs_closure (hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features,
|
||||
hb_set_t *glyphs);
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#undef HB_OT_H_IN
|
||||
#endif /* HB_OT_H */
|
909
src/3rdparty/harfbuzz-ng/src/hb-private.hh
vendored
Normal file
909
src/3rdparty/harfbuzz-ng/src/hb-private.hh
vendored
Normal file
@ -0,0 +1,909 @@
|
||||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_PRIVATE_HH
|
||||
#define HB_PRIVATE_HH
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "hb.h"
|
||||
#define HB_H_IN
|
||||
#ifdef HAVE_OT
|
||||
#include "hb-ot.h"
|
||||
#define HB_OT_H_IN
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* We only use these two for debug output. However, the debug code is
|
||||
* always seen by the compiler (and optimized out in non-debug builds.
|
||||
* If including these becomes a problem, we can start thinking about
|
||||
* someway around that. */
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
|
||||
/* Essentials */
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL ((void *) 0)
|
||||
#endif
|
||||
|
||||
|
||||
/* Void! */
|
||||
struct _hb_void_t {};
|
||||
typedef const _hb_void_t &hb_void_t;
|
||||
#define HB_VOID (* (const _hb_void_t *) NULL)
|
||||
|
||||
|
||||
/* Basics */
|
||||
|
||||
|
||||
#undef MIN
|
||||
template <typename Type>
|
||||
static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
|
||||
|
||||
#undef MAX
|
||||
template <typename Type>
|
||||
static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
|
||||
|
||||
|
||||
#undef ARRAY_LENGTH
|
||||
template <typename Type, unsigned int n>
|
||||
static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
|
||||
/* A const version, but does not detect erratically being called on pointers. */
|
||||
#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
|
||||
|
||||
#define HB_STMT_START do
|
||||
#define HB_STMT_END while (0)
|
||||
|
||||
#define _ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1]
|
||||
#define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond))
|
||||
#define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond))
|
||||
|
||||
#define ASSERT_STATIC_EXPR(_cond)((void) sizeof (char[(_cond) ? 1 : -1]))
|
||||
#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * sizeof (char[(_cond) ? 1 : -1]))
|
||||
|
||||
#define _PASTE1(a,b) a##b
|
||||
#define PASTE(a,b) _PASTE1(a,b)
|
||||
|
||||
/* Lets assert int types. Saves trouble down the road. */
|
||||
|
||||
ASSERT_STATIC (sizeof (int8_t) == 1);
|
||||
ASSERT_STATIC (sizeof (uint8_t) == 1);
|
||||
ASSERT_STATIC (sizeof (int16_t) == 2);
|
||||
ASSERT_STATIC (sizeof (uint16_t) == 2);
|
||||
ASSERT_STATIC (sizeof (int32_t) == 4);
|
||||
ASSERT_STATIC (sizeof (uint32_t) == 4);
|
||||
ASSERT_STATIC (sizeof (int64_t) == 8);
|
||||
ASSERT_STATIC (sizeof (uint64_t) == 8);
|
||||
|
||||
ASSERT_STATIC (sizeof (hb_codepoint_t) == 4);
|
||||
ASSERT_STATIC (sizeof (hb_position_t) == 4);
|
||||
ASSERT_STATIC (sizeof (hb_mask_t) == 4);
|
||||
ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
|
||||
|
||||
|
||||
/* We like our types POD */
|
||||
|
||||
#define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; }
|
||||
#define _ASSERT_TYPE_POD0(_line, _type) _ASSERT_TYPE_POD1 (_line, _type)
|
||||
#define ASSERT_TYPE_POD(_type) _ASSERT_TYPE_POD0 (__LINE__, _type)
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define _ASSERT_INSTANCE_POD1(_line, _instance) \
|
||||
HB_STMT_START { \
|
||||
typedef __typeof__(_instance) _type_##_line; \
|
||||
_ASSERT_TYPE_POD1 (_line, _type_##_line); \
|
||||
} HB_STMT_END
|
||||
#else
|
||||
# define _ASSERT_INSTANCE_POD1(_line, _instance) typedef int _assertion_on_line_##_line##_not_tested
|
||||
#endif
|
||||
# define _ASSERT_INSTANCE_POD0(_line, _instance) _ASSERT_INSTANCE_POD1 (_line, _instance)
|
||||
# define ASSERT_INSTANCE_POD(_instance) _ASSERT_INSTANCE_POD0 (__LINE__, _instance)
|
||||
|
||||
/* Check _assertion in a method environment */
|
||||
#define _ASSERT_POD1(_line) \
|
||||
inline void _static_assertion_on_line_##_line (void) const \
|
||||
{ _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ }
|
||||
# define _ASSERT_POD0(_line) _ASSERT_POD1 (_line)
|
||||
# define ASSERT_POD() _ASSERT_POD0 (__LINE__)
|
||||
|
||||
|
||||
|
||||
/* Misc */
|
||||
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
|
||||
#define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0)
|
||||
#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1))
|
||||
#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0))
|
||||
#else
|
||||
#define likely(expr) (expr)
|
||||
#define unlikely(expr) (expr)
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC__
|
||||
#undef __attribute__
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#define HB_PURE_FUNC __attribute__((pure))
|
||||
#define HB_CONST_FUNC __attribute__((const))
|
||||
#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
|
||||
#else
|
||||
#define HB_PURE_FUNC
|
||||
#define HB_CONST_FUNC
|
||||
#define HB_PRINTF_FUNC(format_idx, arg_idx)
|
||||
#endif
|
||||
#if __GNUC__ >= 4
|
||||
#define HB_UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define HB_UNUSED
|
||||
#endif
|
||||
|
||||
#ifndef HB_INTERNAL
|
||||
# ifndef __MINGW32__
|
||||
# define HB_INTERNAL __attribute__((__visibility__("hidden")))
|
||||
# else
|
||||
# define HB_INTERNAL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#undef inline
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#ifdef __STRICT_ANSI__
|
||||
#undef inline
|
||||
#define inline __inline__
|
||||
#endif
|
||||
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#define HB_FUNC __PRETTY_FUNCTION__
|
||||
#elif defined(_MSC_VER)
|
||||
#define HB_FUNC __FUNCSIG__
|
||||
#else
|
||||
#define HB_FUNC __func__
|
||||
#endif
|
||||
|
||||
|
||||
/* Return the number of 1 bits in mask. */
|
||||
static inline HB_CONST_FUNC unsigned int
|
||||
_hb_popcount32 (uint32_t mask)
|
||||
{
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
return __builtin_popcount (mask);
|
||||
#else
|
||||
/* "HACKMEM 169" */
|
||||
register uint32_t y;
|
||||
y = (mask >> 1) &033333333333;
|
||||
y = mask - y - ((y >>1) & 033333333333);
|
||||
return (((y + (y >> 3)) & 030707070707) % 077);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Returns the number of bits needed to store number */
|
||||
static inline HB_CONST_FUNC unsigned int
|
||||
_hb_bit_storage (unsigned int number)
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
|
||||
return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0;
|
||||
#else
|
||||
register unsigned int n_bits = 0;
|
||||
while (number) {
|
||||
n_bits++;
|
||||
number >>= 1;
|
||||
}
|
||||
return n_bits;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Returns the number of zero bits in the least significant side of number */
|
||||
static inline HB_CONST_FUNC unsigned int
|
||||
_hb_ctz (unsigned int number)
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
|
||||
return likely (number) ? __builtin_ctz (number) : 0;
|
||||
#else
|
||||
register unsigned int n_bits = 0;
|
||||
if (unlikely (!number)) return 0;
|
||||
while (!(number & 1)) {
|
||||
n_bits++;
|
||||
number >>= 1;
|
||||
}
|
||||
return n_bits;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size)
|
||||
{
|
||||
return (size > 0) && (count >= ((unsigned int) -1) / size);
|
||||
}
|
||||
|
||||
|
||||
/* Type of bsearch() / qsort() compare function */
|
||||
typedef int (*hb_compare_func_t) (const void *, const void *);
|
||||
|
||||
|
||||
|
||||
|
||||
/* arrays and maps */
|
||||
|
||||
|
||||
#define HB_PREALLOCED_ARRAY_INIT {0}
|
||||
template <typename Type, unsigned int StaticSize>
|
||||
struct hb_prealloced_array_t
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned int allocated;
|
||||
Type *array;
|
||||
Type static_array[StaticSize];
|
||||
|
||||
void init (void) { memset (this, 0, sizeof (*this)); }
|
||||
|
||||
inline Type& operator [] (unsigned int i) { return array[i]; }
|
||||
inline const Type& operator [] (unsigned int i) const { return array[i]; }
|
||||
|
||||
inline Type *push (void)
|
||||
{
|
||||
if (!array) {
|
||||
array = static_array;
|
||||
allocated = ARRAY_LENGTH (static_array);
|
||||
}
|
||||
if (likely (len < allocated))
|
||||
return &array[len++];
|
||||
|
||||
/* Need to reallocate */
|
||||
unsigned int new_allocated = allocated + (allocated >> 1) + 8;
|
||||
Type *new_array = NULL;
|
||||
|
||||
if (array == static_array) {
|
||||
new_array = (Type *) calloc (new_allocated, sizeof (Type));
|
||||
if (new_array)
|
||||
memcpy (new_array, array, len * sizeof (Type));
|
||||
} else {
|
||||
bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type));
|
||||
if (likely (!overflows)) {
|
||||
new_array = (Type *) realloc (array, new_allocated * sizeof (Type));
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely (!new_array))
|
||||
return NULL;
|
||||
|
||||
array = new_array;
|
||||
allocated = new_allocated;
|
||||
return &array[len++];
|
||||
}
|
||||
|
||||
inline void pop (void)
|
||||
{
|
||||
len--;
|
||||
}
|
||||
|
||||
inline void remove (unsigned int i)
|
||||
{
|
||||
if (unlikely (i >= len))
|
||||
return;
|
||||
memmove (static_cast<void *> (&array[i]),
|
||||
static_cast<void *> (&array[i + 1]),
|
||||
(len - i - 1) * sizeof (Type));
|
||||
len--;
|
||||
}
|
||||
|
||||
inline void shrink (unsigned int l)
|
||||
{
|
||||
if (l < len)
|
||||
len = l;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Type *find (T v) {
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
if (array[i] == v)
|
||||
return &array[i];
|
||||
return NULL;
|
||||
}
|
||||
template <typename T>
|
||||
inline const Type *find (T v) const {
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
if (array[i] == v)
|
||||
return &array[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline void sort (void)
|
||||
{
|
||||
qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
|
||||
}
|
||||
|
||||
inline void sort (unsigned int start, unsigned int end)
|
||||
{
|
||||
qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Type *bsearch (T *key)
|
||||
{
|
||||
return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
|
||||
}
|
||||
template <typename T>
|
||||
inline const Type *bsearch (T *key) const
|
||||
{
|
||||
return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
|
||||
}
|
||||
|
||||
inline void finish (void)
|
||||
{
|
||||
if (array != static_array)
|
||||
free (array);
|
||||
array = NULL;
|
||||
allocated = len = 0;
|
||||
}
|
||||
};
|
||||
|
||||
#define HB_AUTO_ARRAY_PREALLOCED 16
|
||||
template <typename Type>
|
||||
struct hb_auto_array_t : hb_prealloced_array_t <Type, HB_AUTO_ARRAY_PREALLOCED>
|
||||
{
|
||||
hb_auto_array_t (void) { hb_prealloced_array_t<Type, HB_AUTO_ARRAY_PREALLOCED>::init (); }
|
||||
~hb_auto_array_t (void) { hb_prealloced_array_t<Type, HB_AUTO_ARRAY_PREALLOCED>::finish (); }
|
||||
};
|
||||
|
||||
|
||||
#define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT}
|
||||
template <typename item_t, typename lock_t>
|
||||
struct hb_lockable_set_t
|
||||
{
|
||||
hb_prealloced_array_t <item_t, 2> items;
|
||||
|
||||
inline void init (void) { items.init (); }
|
||||
|
||||
template <typename T>
|
||||
inline item_t *replace_or_insert (T v, lock_t &l, bool replace)
|
||||
{
|
||||
l.lock ();
|
||||
item_t *item = items.find (v);
|
||||
if (item) {
|
||||
if (replace) {
|
||||
item_t old = *item;
|
||||
*item = v;
|
||||
l.unlock ();
|
||||
old.finish ();
|
||||
}
|
||||
else {
|
||||
item = NULL;
|
||||
l.unlock ();
|
||||
}
|
||||
} else {
|
||||
item = items.push ();
|
||||
if (likely (item))
|
||||
*item = v;
|
||||
l.unlock ();
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void remove (T v, lock_t &l)
|
||||
{
|
||||
l.lock ();
|
||||
item_t *item = items.find (v);
|
||||
if (item) {
|
||||
item_t old = *item;
|
||||
*item = items[items.len - 1];
|
||||
items.pop ();
|
||||
l.unlock ();
|
||||
old.finish ();
|
||||
} else {
|
||||
l.unlock ();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool find (T v, item_t *i, lock_t &l)
|
||||
{
|
||||
l.lock ();
|
||||
item_t *item = items.find (v);
|
||||
if (item)
|
||||
*i = *item;
|
||||
l.unlock ();
|
||||
return !!item;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline item_t *find_or_insert (T v, lock_t &l)
|
||||
{
|
||||
l.lock ();
|
||||
item_t *item = items.find (v);
|
||||
if (!item) {
|
||||
item = items.push ();
|
||||
if (likely (item))
|
||||
*item = v;
|
||||
}
|
||||
l.unlock ();
|
||||
return item;
|
||||
}
|
||||
|
||||
inline void finish (lock_t &l)
|
||||
{
|
||||
if (!items.len) {
|
||||
/* No need for locking. */
|
||||
items.finish ();
|
||||
return;
|
||||
}
|
||||
l.lock ();
|
||||
while (items.len) {
|
||||
item_t old = items[items.len - 1];
|
||||
items.pop ();
|
||||
l.unlock ();
|
||||
old.finish ();
|
||||
l.lock ();
|
||||
}
|
||||
items.finish ();
|
||||
l.unlock ();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* Big-endian handling */
|
||||
|
||||
static inline uint16_t hb_be_uint16 (const uint16_t v)
|
||||
{
|
||||
const uint8_t *V = (const uint8_t *) &v;
|
||||
return (V[0] << 8) | V[1];
|
||||
}
|
||||
|
||||
static inline uint16_t hb_uint16_swap (const uint16_t v)
|
||||
{
|
||||
return (v >> 8) | (v << 8);
|
||||
}
|
||||
|
||||
static inline uint32_t hb_uint32_swap (const uint32_t v)
|
||||
{
|
||||
return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16);
|
||||
}
|
||||
|
||||
/* Note, of the following macros, uint16_get is the one called many many times.
|
||||
* If there is any optimizations to be done, it's in that macro. However, I
|
||||
* already confirmed that on my T400 ThinkPad at least, using bswap_16(), which
|
||||
* results in a single ror instruction, does NOT speed this up. In fact, it
|
||||
* resulted in a minor slowdown. At any rate, note that v may not be correctly
|
||||
* aligned, so I think the current implementation is optimal.
|
||||
*/
|
||||
|
||||
#define hb_be_uint16_put(v,V) HB_STMT_START { v[0] = (V>>8); v[1] = (V); } HB_STMT_END
|
||||
#define hb_be_uint16_get(v) (uint16_t) ((v[0] << 8) + v[1])
|
||||
#define hb_be_uint16_eq(a,b) (a[0] == b[0] && a[1] == b[1])
|
||||
|
||||
#define hb_be_uint32_put(v,V) HB_STMT_START { v[0] = (V>>24); v[1] = (V>>16); v[2] = (V>>8); v[3] = (V); } HB_STMT_END
|
||||
#define hb_be_uint32_get(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3])
|
||||
#define hb_be_uint32_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3])
|
||||
|
||||
#define hb_be_uint24_put(v,V) HB_STMT_START { v[0] = (V>>16); v[1] = (V>>8); v[2] = (V); } HB_STMT_END
|
||||
#define hb_be_uint24_get(v) (uint32_t) ((v[0] << 16) + (v[1] << 8) + v[2])
|
||||
#define hb_be_uint24_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2])
|
||||
|
||||
|
||||
/* ASCII tag/character handling */
|
||||
|
||||
static inline bool ISALPHA (unsigned char c)
|
||||
{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
|
||||
static inline bool ISALNUM (unsigned char c)
|
||||
{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
|
||||
static inline bool ISSPACE (unsigned char c)
|
||||
{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
|
||||
static inline unsigned char TOUPPER (unsigned char c)
|
||||
{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
|
||||
static inline unsigned char TOLOWER (unsigned char c)
|
||||
{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
|
||||
|
||||
#define HB_TAG_CHAR4(s) (HB_TAG(((const char *) s)[0], \
|
||||
((const char *) s)[1], \
|
||||
((const char *) s)[2], \
|
||||
((const char *) s)[3]))
|
||||
|
||||
|
||||
/* C++ helpers */
|
||||
|
||||
/* Makes class uncopyable. Use in private: section. */
|
||||
#define NO_COPY(T) \
|
||||
T (const T &o); \
|
||||
T &operator = (const T &o)
|
||||
|
||||
|
||||
/* Debug */
|
||||
|
||||
|
||||
#ifndef HB_DEBUG
|
||||
#define HB_DEBUG 0
|
||||
#endif
|
||||
|
||||
static inline bool
|
||||
_hb_debug (unsigned int level,
|
||||
unsigned int max_level)
|
||||
{
|
||||
return level < max_level;
|
||||
}
|
||||
|
||||
#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
|
||||
#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0))
|
||||
|
||||
template <int max_level> static inline void
|
||||
_hb_debug_msg_va (const char *what,
|
||||
const void *obj,
|
||||
const char *func,
|
||||
bool indented,
|
||||
unsigned int level,
|
||||
int level_dir,
|
||||
const char *message,
|
||||
va_list ap)
|
||||
{
|
||||
if (!_hb_debug (level, max_level))
|
||||
return;
|
||||
|
||||
fprintf (stderr, "%-10s", what ? what : "");
|
||||
|
||||
if (obj)
|
||||
fprintf (stderr, "(%0*lx) ", (unsigned int) (2 * sizeof (void *)), (unsigned long) obj);
|
||||
else
|
||||
fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), "");
|
||||
|
||||
if (indented) {
|
||||
/* One may want to add ASCII version of these. See:
|
||||
* https://bugs.freedesktop.org/show_bug.cgi?id=50970 */
|
||||
#define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
|
||||
#define VRBAR "\342\224\234" /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
|
||||
#define DLBAR "\342\225\256" /* U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT */
|
||||
#define ULBAR "\342\225\257" /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */
|
||||
#define LBAR "\342\225\264" /* U+2574 BOX DRAWINGS LIGHT LEFT */
|
||||
static const char bars[] = VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR;
|
||||
fprintf (stderr, "%2u %s" VRBAR "%s",
|
||||
level,
|
||||
bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars), (unsigned int) (sizeof (VBAR) - 1) * level),
|
||||
level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR);
|
||||
} else
|
||||
fprintf (stderr, " " VRBAR LBAR);
|
||||
|
||||
if (func)
|
||||
{
|
||||
unsigned int func_len = strlen (func);
|
||||
#ifndef HB_DEBUG_VERBOSE
|
||||
/* Skip "typename" */
|
||||
if (0 == strncmp (func, "typename ", 9))
|
||||
func += 9;
|
||||
/* Skip return type */
|
||||
const char *space = strchr (func, ' ');
|
||||
if (space)
|
||||
func = space + 1;
|
||||
/* Skip parameter list */
|
||||
const char *paren = strchr (func, '(');
|
||||
if (paren)
|
||||
func_len = paren - func;
|
||||
#endif
|
||||
fprintf (stderr, "%.*s: ", func_len, func);
|
||||
}
|
||||
|
||||
if (message)
|
||||
vfprintf (stderr, message, ap);
|
||||
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
template <> inline void
|
||||
_hb_debug_msg_va<0> (const char *what HB_UNUSED,
|
||||
const void *obj HB_UNUSED,
|
||||
const char *func HB_UNUSED,
|
||||
bool indented HB_UNUSED,
|
||||
unsigned int level HB_UNUSED,
|
||||
int level_dir HB_UNUSED,
|
||||
const char *message HB_UNUSED,
|
||||
va_list ap HB_UNUSED) {}
|
||||
|
||||
template <int max_level> static inline void
|
||||
_hb_debug_msg (const char *what,
|
||||
const void *obj,
|
||||
const char *func,
|
||||
bool indented,
|
||||
unsigned int level,
|
||||
int level_dir,
|
||||
const char *message,
|
||||
...) HB_PRINTF_FUNC(7, 8);
|
||||
template <int max_level> static inline void
|
||||
_hb_debug_msg (const char *what,
|
||||
const void *obj,
|
||||
const char *func,
|
||||
bool indented,
|
||||
unsigned int level,
|
||||
int level_dir,
|
||||
const char *message,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, message);
|
||||
_hb_debug_msg_va<max_level> (what, obj, func, indented, level, level_dir, message, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
template <> inline void
|
||||
_hb_debug_msg<0> (const char *what HB_UNUSED,
|
||||
const void *obj HB_UNUSED,
|
||||
const char *func HB_UNUSED,
|
||||
bool indented HB_UNUSED,
|
||||
unsigned int level HB_UNUSED,
|
||||
int level_dir HB_UNUSED,
|
||||
const char *message HB_UNUSED,
|
||||
...) HB_PRINTF_FUNC(7, 8);
|
||||
template <> inline void
|
||||
_hb_debug_msg<0> (const char *what HB_UNUSED,
|
||||
const void *obj HB_UNUSED,
|
||||
const char *func HB_UNUSED,
|
||||
bool indented HB_UNUSED,
|
||||
unsigned int level HB_UNUSED,
|
||||
int level_dir HB_UNUSED,
|
||||
const char *message HB_UNUSED,
|
||||
...) {}
|
||||
|
||||
#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL, true, (LEVEL), (LEVEL_DIR), __VA_ARGS__)
|
||||
#define DEBUG_MSG(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL, false, 0, 0, __VA_ARGS__)
|
||||
#define DEBUG_MSG_FUNC(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__)
|
||||
|
||||
|
||||
/*
|
||||
* Printer
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
struct hb_printer_t {};
|
||||
|
||||
template <>
|
||||
struct hb_printer_t<bool> {
|
||||
const char *print (bool v) { return v ? "true" : "false"; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hb_printer_t<hb_void_t> {
|
||||
const char *print (hb_void_t) { return ""; }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Trace
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
static inline void _hb_warn_no_return (bool returned)
|
||||
{
|
||||
if (unlikely (!returned)) {
|
||||
fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN. This is a bug, please report.\n");
|
||||
}
|
||||
}
|
||||
template <>
|
||||
inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
|
||||
{}
|
||||
|
||||
template <int max_level, typename ret_t>
|
||||
struct hb_auto_trace_t {
|
||||
explicit inline hb_auto_trace_t (unsigned int *plevel_,
|
||||
const char *what_,
|
||||
const void *obj_,
|
||||
const char *func,
|
||||
const char *message,
|
||||
...) : plevel (plevel_), what (what_), obj (obj_), returned (false)
|
||||
{
|
||||
if (plevel) ++*plevel;
|
||||
|
||||
va_list ap;
|
||||
va_start (ap, message);
|
||||
_hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
inline ~hb_auto_trace_t (void)
|
||||
{
|
||||
_hb_warn_no_return<ret_t> (returned);
|
||||
if (!returned) {
|
||||
_hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, " ");
|
||||
}
|
||||
if (plevel) --*plevel;
|
||||
}
|
||||
|
||||
inline ret_t ret (ret_t v, unsigned int line = 0)
|
||||
{
|
||||
if (unlikely (returned)) {
|
||||
fprintf (stderr, "OUCH, double calls to TRACE_RETURN. This is a bug, please report.\n");
|
||||
return v;
|
||||
}
|
||||
|
||||
_hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1,
|
||||
"return %s (line %d)",
|
||||
hb_printer_t<ret_t>().print (v), line);
|
||||
if (plevel) --*plevel;
|
||||
plevel = NULL;
|
||||
returned = true;
|
||||
return v;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int *plevel;
|
||||
const char *what;
|
||||
const void *obj;
|
||||
bool returned;
|
||||
};
|
||||
template <typename ret_t> /* Optimize when tracing is disabled */
|
||||
struct hb_auto_trace_t<0, ret_t> {
|
||||
explicit inline hb_auto_trace_t (unsigned int *plevel_ HB_UNUSED,
|
||||
const char *what HB_UNUSED,
|
||||
const void *obj HB_UNUSED,
|
||||
const char *func HB_UNUSED,
|
||||
const char *message HB_UNUSED,
|
||||
...) {}
|
||||
|
||||
inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
|
||||
};
|
||||
|
||||
#define TRACE_RETURN(RET) trace.ret (RET, __LINE__)
|
||||
|
||||
/* Misc */
|
||||
|
||||
|
||||
/* Pre-mature optimization:
|
||||
* Checks for lo <= u <= hi but with an optimization if lo and hi
|
||||
* are only different in a contiguous set of lower-most bits.
|
||||
*/
|
||||
template <typename T> static inline bool
|
||||
hb_in_range (T u, T lo, T hi)
|
||||
{
|
||||
if ( ((lo^hi) & lo) == 0 &&
|
||||
((lo^hi) & hi) == (lo^hi) &&
|
||||
((lo^hi) & ((lo^hi) + 1)) == 0 )
|
||||
return (u & ~(lo^hi)) == lo;
|
||||
else
|
||||
return lo <= u && u <= hi;
|
||||
}
|
||||
|
||||
template <typename T> static inline bool
|
||||
hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
|
||||
{
|
||||
return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
|
||||
}
|
||||
|
||||
|
||||
/* Useful for set-operations on small enums.
|
||||
* For example, for testing "x ∈ {x1, x2, x3}" use:
|
||||
* (FLAG(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
|
||||
*/
|
||||
#define FLAG(x) (1<<(x))
|
||||
#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x))
|
||||
|
||||
|
||||
template <typename T, typename T2> inline void
|
||||
hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2)
|
||||
{
|
||||
if (unlikely (!len))
|
||||
return;
|
||||
|
||||
unsigned int k = len - 1;
|
||||
do {
|
||||
unsigned int new_k = 0;
|
||||
|
||||
for (unsigned int j = 0; j < k; j++)
|
||||
if (compar (&array[j], &array[j+1]) > 0)
|
||||
{
|
||||
{
|
||||
T t;
|
||||
t = array[j];
|
||||
array[j] = array[j + 1];
|
||||
array[j + 1] = t;
|
||||
}
|
||||
if (array2)
|
||||
{
|
||||
T2 t;
|
||||
t = array2[j];
|
||||
array2[j] = array2[j + 1];
|
||||
array2[j + 1] = t;
|
||||
}
|
||||
|
||||
new_k = j;
|
||||
}
|
||||
k = new_k;
|
||||
} while (k);
|
||||
}
|
||||
|
||||
template <typename T> inline void
|
||||
hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
|
||||
{
|
||||
hb_bubble_sort (array, len, compar, (int *) NULL);
|
||||
}
|
||||
|
||||
static inline hb_bool_t
|
||||
hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
|
||||
{
|
||||
/* Pain because we don't know whether s is nul-terminated. */
|
||||
char buf[64];
|
||||
len = MIN (ARRAY_LENGTH (buf) - 1, len);
|
||||
strncpy (buf, s, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
char *end;
|
||||
errno = 0;
|
||||
unsigned long v = strtoul (buf, &end, base);
|
||||
if (errno) return false;
|
||||
if (*end) return false;
|
||||
*out = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Global runtime options. */
|
||||
|
||||
struct hb_options_t
|
||||
{
|
||||
int initialized : 1;
|
||||
int uniscribe_bug_compatible : 1;
|
||||
};
|
||||
|
||||
union hb_options_union_t {
|
||||
int i;
|
||||
hb_options_t opts;
|
||||
};
|
||||
ASSERT_STATIC (sizeof (int) == sizeof (hb_options_union_t));
|
||||
|
||||
HB_INTERNAL void
|
||||
_hb_options_init (void);
|
||||
|
||||
extern HB_INTERNAL hb_options_union_t _hb_options;
|
||||
|
||||
static inline hb_options_t
|
||||
hb_options (void)
|
||||
{
|
||||
if (unlikely (!_hb_options.i))
|
||||
_hb_options_init ();
|
||||
|
||||
return _hb_options.opts;
|
||||
}
|
||||
|
||||
|
||||
#endif /* HB_PRIVATE_HH */
|
335
src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
vendored
Normal file
335
src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
vendored
Normal file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_SET_PRIVATE_HH
|
||||
#define HB_SET_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-set.h"
|
||||
#include "hb-object-private.hh"
|
||||
|
||||
|
||||
/*
|
||||
* The set digests here implement various "filters" that support
|
||||
* "approximate member query". Conceptually these are like Bloom
|
||||
* Filter and Quotient Filter, however, much smaller, faster, and
|
||||
* designed to fit the requirements of our uses for glyph coverage
|
||||
* queries. As a result, our filters have much higher.
|
||||
*/
|
||||
|
||||
template <typename mask_t, unsigned int shift>
|
||||
struct hb_set_digest_lowest_bits_t
|
||||
{
|
||||
ASSERT_POD ();
|
||||
|
||||
static const unsigned int mask_bytes = sizeof (mask_t);
|
||||
static const unsigned int mask_bits = sizeof (mask_t) * 8;
|
||||
static const unsigned int num_bits = 0
|
||||
+ (mask_bytes >= 1 ? 3 : 0)
|
||||
+ (mask_bytes >= 2 ? 1 : 0)
|
||||
+ (mask_bytes >= 4 ? 1 : 0)
|
||||
+ (mask_bytes >= 8 ? 1 : 0)
|
||||
+ (mask_bytes >= 16? 1 : 0)
|
||||
+ 0;
|
||||
|
||||
ASSERT_STATIC (shift < sizeof (hb_codepoint_t) * 8);
|
||||
ASSERT_STATIC (shift + num_bits <= sizeof (hb_codepoint_t) * 8);
|
||||
|
||||
inline void init (void) {
|
||||
mask = 0;
|
||||
}
|
||||
|
||||
inline void add (hb_codepoint_t g) {
|
||||
mask |= mask_for (g);
|
||||
}
|
||||
|
||||
inline void add_range (hb_codepoint_t a, hb_codepoint_t b) {
|
||||
if ((b >> shift) - (a >> shift) >= mask_bits - 1)
|
||||
mask = (mask_t) -1;
|
||||
else {
|
||||
mask_t ma = mask_for (a);
|
||||
mask_t mb = mask_for (b);
|
||||
mask |= mb + (mb - ma) - (mb < ma);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool may_have (hb_codepoint_t g) const {
|
||||
return !!(mask & mask_for (g));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static inline mask_t mask_for (hb_codepoint_t g) {
|
||||
return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1));
|
||||
}
|
||||
mask_t mask;
|
||||
};
|
||||
|
||||
template <typename head_t, typename tail_t>
|
||||
struct hb_set_digest_combiner_t
|
||||
{
|
||||
ASSERT_POD ();
|
||||
|
||||
inline void init (void) {
|
||||
head.init ();
|
||||
tail.init ();
|
||||
}
|
||||
|
||||
inline void add (hb_codepoint_t g) {
|
||||
head.add (g);
|
||||
tail.add (g);
|
||||
}
|
||||
|
||||
inline void add_range (hb_codepoint_t a, hb_codepoint_t b) {
|
||||
head.add_range (a, b);
|
||||
tail.add_range (a, b);
|
||||
}
|
||||
|
||||
inline bool may_have (hb_codepoint_t g) const {
|
||||
return head.may_have (g) && tail.may_have (g);
|
||||
}
|
||||
|
||||
private:
|
||||
head_t head;
|
||||
tail_t tail;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* hb_set_digest_t
|
||||
*
|
||||
* This is a combination of digests that performs "best".
|
||||
* There is not much science to this: it's a result of intuition
|
||||
* and testing.
|
||||
*/
|
||||
typedef hb_set_digest_combiner_t
|
||||
<
|
||||
hb_set_digest_lowest_bits_t<unsigned long, 4>,
|
||||
hb_set_digest_combiner_t
|
||||
<
|
||||
hb_set_digest_lowest_bits_t<unsigned long, 0>,
|
||||
hb_set_digest_lowest_bits_t<unsigned long, 9>
|
||||
>
|
||||
> hb_set_digest_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* hb_set_t
|
||||
*/
|
||||
|
||||
|
||||
/* TODO Make this faster and memmory efficient. */
|
||||
|
||||
struct hb_set_t
|
||||
{
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
bool in_error;
|
||||
|
||||
inline void init (void) {
|
||||
header.init ();
|
||||
clear ();
|
||||
}
|
||||
inline void fini (void) {
|
||||
}
|
||||
inline void clear (void) {
|
||||
if (unlikely (hb_object_is_inert (this)))
|
||||
return;
|
||||
in_error = false;
|
||||
memset (elts, 0, sizeof elts);
|
||||
}
|
||||
inline bool is_empty (void) const {
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (elts); i++)
|
||||
if (elts[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
inline void add (hb_codepoint_t g)
|
||||
{
|
||||
if (unlikely (in_error)) return;
|
||||
if (unlikely (g == SENTINEL)) return;
|
||||
if (unlikely (g > MAX_G)) return;
|
||||
elt (g) |= mask (g);
|
||||
}
|
||||
inline void add_range (hb_codepoint_t a, hb_codepoint_t b)
|
||||
{
|
||||
if (unlikely (in_error)) return;
|
||||
/* TODO Speedup */
|
||||
for (unsigned int i = a; i < b + 1; i++)
|
||||
add (i);
|
||||
}
|
||||
inline void del (hb_codepoint_t g)
|
||||
{
|
||||
if (unlikely (in_error)) return;
|
||||
if (unlikely (g > MAX_G)) return;
|
||||
elt (g) &= ~mask (g);
|
||||
}
|
||||
inline void del_range (hb_codepoint_t a, hb_codepoint_t b)
|
||||
{
|
||||
if (unlikely (in_error)) return;
|
||||
/* TODO Speedup */
|
||||
for (unsigned int i = a; i < b + 1; i++)
|
||||
del (i);
|
||||
}
|
||||
inline bool has (hb_codepoint_t g) const
|
||||
{
|
||||
if (unlikely (g > MAX_G)) return false;
|
||||
return !!(elt (g) & mask (g));
|
||||
}
|
||||
inline bool intersects (hb_codepoint_t first,
|
||||
hb_codepoint_t last) const
|
||||
{
|
||||
if (unlikely (first > MAX_G)) return false;
|
||||
if (unlikely (last > MAX_G)) last = MAX_G;
|
||||
unsigned int end = last + 1;
|
||||
for (hb_codepoint_t i = first; i < end; i++)
|
||||
if (has (i))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
inline bool is_equal (const hb_set_t *other) const
|
||||
{
|
||||
for (unsigned int i = 0; i < ELTS; i++)
|
||||
if (elts[i] != other->elts[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
inline void set (const hb_set_t *other)
|
||||
{
|
||||
if (unlikely (in_error)) return;
|
||||
for (unsigned int i = 0; i < ELTS; i++)
|
||||
elts[i] = other->elts[i];
|
||||
}
|
||||
inline void union_ (const hb_set_t *other)
|
||||
{
|
||||
if (unlikely (in_error)) return;
|
||||
for (unsigned int i = 0; i < ELTS; i++)
|
||||
elts[i] |= other->elts[i];
|
||||
}
|
||||
inline void intersect (const hb_set_t *other)
|
||||
{
|
||||
if (unlikely (in_error)) return;
|
||||
for (unsigned int i = 0; i < ELTS; i++)
|
||||
elts[i] &= other->elts[i];
|
||||
}
|
||||
inline void subtract (const hb_set_t *other)
|
||||
{
|
||||
if (unlikely (in_error)) return;
|
||||
for (unsigned int i = 0; i < ELTS; i++)
|
||||
elts[i] &= ~other->elts[i];
|
||||
}
|
||||
inline void symmetric_difference (const hb_set_t *other)
|
||||
{
|
||||
if (unlikely (in_error)) return;
|
||||
for (unsigned int i = 0; i < ELTS; i++)
|
||||
elts[i] ^= other->elts[i];
|
||||
}
|
||||
inline void invert (void)
|
||||
{
|
||||
if (unlikely (in_error)) return;
|
||||
for (unsigned int i = 0; i < ELTS; i++)
|
||||
elts[i] = ~elts[i];
|
||||
}
|
||||
inline bool next (hb_codepoint_t *codepoint) const
|
||||
{
|
||||
if (unlikely (*codepoint == SENTINEL)) {
|
||||
hb_codepoint_t i = get_min ();
|
||||
if (i != SENTINEL) {
|
||||
*codepoint = i;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
for (hb_codepoint_t i = *codepoint + 1; i < MAX_G + 1; i++)
|
||||
if (has (i)) {
|
||||
*codepoint = i;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const
|
||||
{
|
||||
hb_codepoint_t i;
|
||||
|
||||
i = *last;
|
||||
if (!next (&i))
|
||||
return false;
|
||||
|
||||
*last = *first = i;
|
||||
while (next (&i) && i == *last + 1)
|
||||
(*last)++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline unsigned int get_population (void) const
|
||||
{
|
||||
unsigned int count = 0;
|
||||
for (unsigned int i = 0; i < ELTS; i++)
|
||||
count += _hb_popcount32 (elts[i]);
|
||||
return count;
|
||||
}
|
||||
inline hb_codepoint_t get_min (void) const
|
||||
{
|
||||
for (unsigned int i = 0; i < ELTS; i++)
|
||||
if (elts[i])
|
||||
for (unsigned int j = 0; j < BITS; j++)
|
||||
if (elts[i] & (1 << j))
|
||||
return i * BITS + j;
|
||||
return SENTINEL;
|
||||
}
|
||||
inline hb_codepoint_t get_max (void) const
|
||||
{
|
||||
for (unsigned int i = ELTS; i; i--)
|
||||
if (elts[i - 1])
|
||||
for (unsigned int j = BITS; j; j--)
|
||||
if (elts[i - 1] & (1 << (j - 1)))
|
||||
return (i - 1) * BITS + (j - 1);
|
||||
return SENTINEL;
|
||||
}
|
||||
|
||||
typedef uint32_t elt_t;
|
||||
static const unsigned int MAX_G = 65536 - 1; /* XXX Fix this... */
|
||||
static const unsigned int SHIFT = 5;
|
||||
static const unsigned int BITS = (1 << SHIFT);
|
||||
static const unsigned int MASK = BITS - 1;
|
||||
static const unsigned int ELTS = (MAX_G + 1 + (BITS - 1)) / BITS;
|
||||
static const hb_codepoint_t SENTINEL = (hb_codepoint_t) -1;
|
||||
|
||||
elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
|
||||
elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
|
||||
elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
|
||||
|
||||
elt_t elts[ELTS]; /* XXX 8kb */
|
||||
|
||||
ASSERT_STATIC (sizeof (elt_t) * 8 == BITS);
|
||||
ASSERT_STATIC (sizeof (elt_t) * 8 * ELTS > MAX_G);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* HB_SET_PRIVATE_HH */
|
227
src/3rdparty/harfbuzz-ng/src/hb-set.cc
vendored
Normal file
227
src/3rdparty/harfbuzz-ng/src/hb-set.cc
vendored
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-set-private.hh"
|
||||
|
||||
|
||||
/* Public API */
|
||||
|
||||
|
||||
hb_set_t *
|
||||
hb_set_create (void)
|
||||
{
|
||||
hb_set_t *set;
|
||||
|
||||
if (!(set = hb_object_create<hb_set_t> ()))
|
||||
return hb_set_get_empty ();
|
||||
|
||||
set->clear ();
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
hb_set_t *
|
||||
hb_set_get_empty (void)
|
||||
{
|
||||
static const hb_set_t _hb_set_nil = {
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
true, /* in_error */
|
||||
|
||||
{0} /* elts */
|
||||
};
|
||||
|
||||
return const_cast<hb_set_t *> (&_hb_set_nil);
|
||||
}
|
||||
|
||||
hb_set_t *
|
||||
hb_set_reference (hb_set_t *set)
|
||||
{
|
||||
return hb_object_reference (set);
|
||||
}
|
||||
|
||||
void
|
||||
hb_set_destroy (hb_set_t *set)
|
||||
{
|
||||
if (!hb_object_destroy (set)) return;
|
||||
|
||||
set->fini ();
|
||||
|
||||
free (set);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_set_set_user_data (hb_set_t *set,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
return hb_object_set_user_data (set, key, data, destroy, replace);
|
||||
}
|
||||
|
||||
void *
|
||||
hb_set_get_user_data (hb_set_t *set,
|
||||
hb_user_data_key_t *key)
|
||||
{
|
||||
return hb_object_get_user_data (set, key);
|
||||
}
|
||||
|
||||
|
||||
hb_bool_t
|
||||
hb_set_allocation_successful (const hb_set_t *set HB_UNUSED)
|
||||
{
|
||||
return !set->in_error;
|
||||
}
|
||||
|
||||
void
|
||||
hb_set_clear (hb_set_t *set)
|
||||
{
|
||||
set->clear ();
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_set_is_empty (const hb_set_t *set)
|
||||
{
|
||||
return set->is_empty ();
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_set_has (const hb_set_t *set,
|
||||
hb_codepoint_t codepoint)
|
||||
{
|
||||
return set->has (codepoint);
|
||||
}
|
||||
|
||||
void
|
||||
hb_set_add (hb_set_t *set,
|
||||
hb_codepoint_t codepoint)
|
||||
{
|
||||
set->add (codepoint);
|
||||
}
|
||||
|
||||
void
|
||||
hb_set_add_range (hb_set_t *set,
|
||||
hb_codepoint_t first,
|
||||
hb_codepoint_t last)
|
||||
{
|
||||
set->add_range (first, last);
|
||||
}
|
||||
|
||||
void
|
||||
hb_set_del (hb_set_t *set,
|
||||
hb_codepoint_t codepoint)
|
||||
{
|
||||
set->del (codepoint);
|
||||
}
|
||||
|
||||
void
|
||||
hb_set_del_range (hb_set_t *set,
|
||||
hb_codepoint_t first,
|
||||
hb_codepoint_t last)
|
||||
{
|
||||
set->del_range (first, last);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_set_is_equal (const hb_set_t *set,
|
||||
const hb_set_t *other)
|
||||
{
|
||||
return set->is_equal (other);
|
||||
}
|
||||
|
||||
void
|
||||
hb_set_set (hb_set_t *set,
|
||||
const hb_set_t *other)
|
||||
{
|
||||
set->set (other);
|
||||
}
|
||||
|
||||
void
|
||||
hb_set_union (hb_set_t *set,
|
||||
const hb_set_t *other)
|
||||
{
|
||||
set->union_ (other);
|
||||
}
|
||||
|
||||
void
|
||||
hb_set_intersect (hb_set_t *set,
|
||||
const hb_set_t *other)
|
||||
{
|
||||
set->intersect (other);
|
||||
}
|
||||
|
||||
void
|
||||
hb_set_subtract (hb_set_t *set,
|
||||
const hb_set_t *other)
|
||||
{
|
||||
set->subtract (other);
|
||||
}
|
||||
|
||||
void
|
||||
hb_set_symmetric_difference (hb_set_t *set,
|
||||
const hb_set_t *other)
|
||||
{
|
||||
set->symmetric_difference (other);
|
||||
}
|
||||
|
||||
void
|
||||
hb_set_invert (hb_set_t *set)
|
||||
{
|
||||
set->invert ();
|
||||
}
|
||||
|
||||
unsigned int
|
||||
hb_set_get_population (const hb_set_t *set)
|
||||
{
|
||||
return set->get_population ();
|
||||
}
|
||||
|
||||
hb_codepoint_t
|
||||
hb_set_get_min (const hb_set_t *set)
|
||||
{
|
||||
return set->get_min ();
|
||||
}
|
||||
|
||||
hb_codepoint_t
|
||||
hb_set_get_max (const hb_set_t *set)
|
||||
{
|
||||
return set->get_max ();
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_set_next (const hb_set_t *set,
|
||||
hb_codepoint_t *codepoint)
|
||||
{
|
||||
return set->next (codepoint);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_set_next_range (const hb_set_t *set,
|
||||
hb_codepoint_t *first,
|
||||
hb_codepoint_t *last)
|
||||
{
|
||||
return set->next_range (first, last);
|
||||
}
|
152
src/3rdparty/harfbuzz-ng/src/hb-set.h
vendored
Normal file
152
src/3rdparty/harfbuzz-ng/src/hb-set.h
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_SET_H
|
||||
#define HB_SET_H
|
||||
|
||||
#include "hb-common.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
typedef struct hb_set_t hb_set_t;
|
||||
|
||||
|
||||
hb_set_t *
|
||||
hb_set_create (void);
|
||||
|
||||
hb_set_t *
|
||||
hb_set_get_empty (void);
|
||||
|
||||
hb_set_t *
|
||||
hb_set_reference (hb_set_t *set);
|
||||
|
||||
void
|
||||
hb_set_destroy (hb_set_t *set);
|
||||
|
||||
hb_bool_t
|
||||
hb_set_set_user_data (hb_set_t *set,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
void *
|
||||
hb_set_get_user_data (hb_set_t *set,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
|
||||
/* Returns false if allocation has failed before */
|
||||
hb_bool_t
|
||||
hb_set_allocation_successful (const hb_set_t *set);
|
||||
|
||||
void
|
||||
hb_set_clear (hb_set_t *set);
|
||||
|
||||
hb_bool_t
|
||||
hb_set_is_empty (const hb_set_t *set);
|
||||
|
||||
hb_bool_t
|
||||
hb_set_has (const hb_set_t *set,
|
||||
hb_codepoint_t codepoint);
|
||||
|
||||
/* Right now limited to 16-bit integers. Eventually will do full codepoint range, sans -1
|
||||
* which we will use as a sentinel. */
|
||||
void
|
||||
hb_set_add (hb_set_t *set,
|
||||
hb_codepoint_t codepoint);
|
||||
|
||||
void
|
||||
hb_set_add_range (hb_set_t *set,
|
||||
hb_codepoint_t first,
|
||||
hb_codepoint_t last);
|
||||
|
||||
void
|
||||
hb_set_del (hb_set_t *set,
|
||||
hb_codepoint_t codepoint);
|
||||
|
||||
void
|
||||
hb_set_del_range (hb_set_t *set,
|
||||
hb_codepoint_t first,
|
||||
hb_codepoint_t last);
|
||||
|
||||
hb_bool_t
|
||||
hb_set_is_equal (const hb_set_t *set,
|
||||
const hb_set_t *other);
|
||||
|
||||
void
|
||||
hb_set_set (hb_set_t *set,
|
||||
const hb_set_t *other);
|
||||
|
||||
void
|
||||
hb_set_union (hb_set_t *set,
|
||||
const hb_set_t *other);
|
||||
|
||||
void
|
||||
hb_set_intersect (hb_set_t *set,
|
||||
const hb_set_t *other);
|
||||
|
||||
void
|
||||
hb_set_subtract (hb_set_t *set,
|
||||
const hb_set_t *other);
|
||||
|
||||
void
|
||||
hb_set_symmetric_difference (hb_set_t *set,
|
||||
const hb_set_t *other);
|
||||
|
||||
void
|
||||
hb_set_invert (hb_set_t *set);
|
||||
|
||||
unsigned int
|
||||
hb_set_get_population (const hb_set_t *set);
|
||||
|
||||
/* Returns -1 if set empty. */
|
||||
hb_codepoint_t
|
||||
hb_set_get_min (const hb_set_t *set);
|
||||
|
||||
/* Returns -1 if set empty. */
|
||||
hb_codepoint_t
|
||||
hb_set_get_max (const hb_set_t *set);
|
||||
|
||||
/* Pass -1 in to get started. */
|
||||
hb_bool_t
|
||||
hb_set_next (const hb_set_t *set,
|
||||
hb_codepoint_t *codepoint);
|
||||
|
||||
/* Pass -1 for first and last to get started. */
|
||||
hb_bool_t
|
||||
hb_set_next_range (const hb_set_t *set,
|
||||
hb_codepoint_t *first,
|
||||
hb_codepoint_t *last);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_SET_H */
|
60
src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh
vendored
Normal file
60
src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_SHAPE_PLAN_PRIVATE_HH
|
||||
#define HB_SHAPE_PLAN_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-shape-plan.h"
|
||||
#include "hb-object-private.hh"
|
||||
#include "hb-shaper-private.hh"
|
||||
|
||||
|
||||
struct hb_shape_plan_t
|
||||
{
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
||||
hb_bool_t default_shaper_list;
|
||||
hb_face_t *face;
|
||||
hb_segment_properties_t props;
|
||||
|
||||
hb_shape_func_t *shaper_func;
|
||||
const char *shaper_name;
|
||||
|
||||
struct hb_shaper_data_t shaper_data;
|
||||
};
|
||||
|
||||
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS \
|
||||
, const hb_feature_t *user_features \
|
||||
, unsigned int num_user_features
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, shape_plan);
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
||||
|
||||
|
||||
#endif /* HB_SHAPE_PLAN_PRIVATE_HH */
|
314
src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
vendored
Normal file
314
src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
vendored
Normal file
@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-shape-plan-private.hh"
|
||||
#include "hb-shaper-private.hh"
|
||||
#include "hb-font-private.hh"
|
||||
#include "hb-buffer-private.hh"
|
||||
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) \
|
||||
HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face) \
|
||||
HB_SHAPER_DATA_ENSURE_DECLARE(shaper, font)
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
|
||||
|
||||
static void
|
||||
hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
const char * const *shaper_list)
|
||||
{
|
||||
const hb_shaper_pair_t *shapers = _hb_shapers_get ();
|
||||
|
||||
#define HB_SHAPER_PLAN(shaper) \
|
||||
HB_STMT_START { \
|
||||
if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face)) { \
|
||||
HB_SHAPER_DATA (shaper, shape_plan) = \
|
||||
HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \
|
||||
shape_plan->shaper_func = _hb_##shaper##_shape; \
|
||||
shape_plan->shaper_name = #shaper; \
|
||||
return; \
|
||||
} \
|
||||
} HB_STMT_END
|
||||
|
||||
if (likely (!shaper_list)) {
|
||||
for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
|
||||
if (0)
|
||||
;
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) \
|
||||
else if (shapers[i].func == _hb_##shaper##_shape) \
|
||||
HB_SHAPER_PLAN (shaper);
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
} else {
|
||||
for (; *shaper_list; shaper_list++)
|
||||
if (0)
|
||||
;
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) \
|
||||
else if (0 == strcmp (*shaper_list, #shaper)) \
|
||||
HB_SHAPER_PLAN (shaper);
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
}
|
||||
|
||||
#undef HB_SHAPER_PLAN
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hb_shape_plan_t
|
||||
*/
|
||||
|
||||
hb_shape_plan_t *
|
||||
hb_shape_plan_create (hb_face_t *face,
|
||||
const hb_segment_properties_t *props,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
const char * const *shaper_list)
|
||||
{
|
||||
assert (props->direction != HB_DIRECTION_INVALID);
|
||||
|
||||
hb_shape_plan_t *shape_plan;
|
||||
|
||||
if (unlikely (!face))
|
||||
face = hb_face_get_empty ();
|
||||
if (unlikely (!props || hb_object_is_inert (face)))
|
||||
return hb_shape_plan_get_empty ();
|
||||
if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
|
||||
return hb_shape_plan_get_empty ();
|
||||
|
||||
hb_face_make_immutable (face);
|
||||
shape_plan->default_shaper_list = shaper_list == NULL;
|
||||
shape_plan->face = hb_face_reference (face);
|
||||
shape_plan->props = *props;
|
||||
|
||||
hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list);
|
||||
|
||||
return shape_plan;
|
||||
}
|
||||
|
||||
hb_shape_plan_t *
|
||||
hb_shape_plan_get_empty (void)
|
||||
{
|
||||
static const hb_shape_plan_t _hb_shape_plan_nil = {
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
|
||||
true, /* default_shaper_list */
|
||||
NULL, /* face */
|
||||
HB_SEGMENT_PROPERTIES_DEFAULT, /* props */
|
||||
|
||||
NULL, /* shaper_func */
|
||||
NULL, /* shaper_name */
|
||||
|
||||
{
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
}
|
||||
};
|
||||
|
||||
return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil);
|
||||
}
|
||||
|
||||
hb_shape_plan_t *
|
||||
hb_shape_plan_reference (hb_shape_plan_t *shape_plan)
|
||||
{
|
||||
return hb_object_reference (shape_plan);
|
||||
}
|
||||
|
||||
void
|
||||
hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
|
||||
{
|
||||
if (!hb_object_destroy (shape_plan)) return;
|
||||
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan);
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
|
||||
hb_face_destroy (shape_plan->face);
|
||||
|
||||
free (shape_plan);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
return hb_object_set_user_data (shape_plan, key, data, destroy, replace);
|
||||
}
|
||||
|
||||
void *
|
||||
hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
|
||||
hb_user_data_key_t *key)
|
||||
{
|
||||
return hb_object_get_user_data (shape_plan, key);
|
||||
}
|
||||
|
||||
|
||||
hb_bool_t
|
||||
hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features)
|
||||
{
|
||||
if (unlikely (hb_object_is_inert (shape_plan) ||
|
||||
hb_object_is_inert (font) ||
|
||||
hb_object_is_inert (buffer)))
|
||||
return false;
|
||||
|
||||
assert (shape_plan->face == font->face);
|
||||
assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props));
|
||||
|
||||
#define HB_SHAPER_EXECUTE(shaper) \
|
||||
HB_STMT_START { \
|
||||
return HB_SHAPER_DATA (shaper, shape_plan) && \
|
||||
hb_##shaper##_shaper_font_data_ensure (font) && \
|
||||
_hb_##shaper##_shape (shape_plan, font, buffer, features, num_features); \
|
||||
} HB_STMT_END
|
||||
|
||||
if (0)
|
||||
;
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) \
|
||||
else if (shape_plan->shaper_func == _hb_##shaper##_shape) \
|
||||
HB_SHAPER_EXECUTE (shaper);
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
|
||||
#undef HB_SHAPER_EXECUTE
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caching
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static unsigned int
|
||||
hb_shape_plan_hash (const hb_shape_plan_t *shape_plan)
|
||||
{
|
||||
return hb_segment_properties_hash (&shape_plan->props) +
|
||||
shape_plan->default_shaper_list ? 0 : (intptr_t) shape_plan->shaper_func;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TODO no user-feature caching for now. */
|
||||
struct hb_shape_plan_proposal_t
|
||||
{
|
||||
const hb_segment_properties_t props;
|
||||
const char * const *shaper_list;
|
||||
hb_shape_func_t *shaper_func;
|
||||
};
|
||||
|
||||
static hb_bool_t
|
||||
hb_shape_plan_matches (const hb_shape_plan_t *shape_plan,
|
||||
const hb_shape_plan_proposal_t *proposal)
|
||||
{
|
||||
return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
|
||||
((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
|
||||
(shape_plan->shaper_func == proposal->shaper_func));
|
||||
}
|
||||
|
||||
hb_shape_plan_t *
|
||||
hb_shape_plan_create_cached (hb_face_t *face,
|
||||
const hb_segment_properties_t *props,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
const char * const *shaper_list)
|
||||
{
|
||||
if (num_user_features)
|
||||
return hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
|
||||
|
||||
hb_shape_plan_proposal_t proposal = {
|
||||
*props,
|
||||
shaper_list,
|
||||
NULL
|
||||
};
|
||||
|
||||
if (shaper_list) {
|
||||
/* Choose shaper. Adapted from hb_shape_plan_plan(). */
|
||||
#define HB_SHAPER_PLAN(shaper) \
|
||||
HB_STMT_START { \
|
||||
if (hb_##shaper##_shaper_face_data_ensure (face)) \
|
||||
proposal.shaper_func = _hb_##shaper##_shape; \
|
||||
} HB_STMT_END
|
||||
|
||||
for (const char * const *shaper_item = shaper_list; *shaper_item; shaper_item++)
|
||||
if (0)
|
||||
;
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) \
|
||||
else if (0 == strcmp (*shaper_item, #shaper)) \
|
||||
HB_SHAPER_PLAN (shaper);
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
|
||||
#undef HB_SHAPER_PLAN
|
||||
|
||||
if (unlikely (!proposal.shaper_list))
|
||||
return hb_shape_plan_get_empty ();
|
||||
}
|
||||
|
||||
|
||||
retry:
|
||||
hb_face_t::plan_node_t *cached_plan_nodes = (hb_face_t::plan_node_t *) hb_atomic_ptr_get (&face->shape_plans);
|
||||
for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next)
|
||||
if (hb_shape_plan_matches (node->shape_plan, &proposal))
|
||||
return hb_shape_plan_reference (node->shape_plan);
|
||||
|
||||
/* Not found. */
|
||||
|
||||
hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
|
||||
|
||||
hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
|
||||
if (unlikely (!node))
|
||||
return shape_plan;
|
||||
|
||||
node->shape_plan = shape_plan;
|
||||
node->next = cached_plan_nodes;
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&face->shape_plans, cached_plan_nodes, node)) {
|
||||
hb_shape_plan_destroy (shape_plan);
|
||||
free (node);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/* Release our reference on face. */
|
||||
hb_face_destroy (face);
|
||||
|
||||
return hb_shape_plan_reference (shape_plan);
|
||||
}
|
||||
|
||||
const char *
|
||||
hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
|
||||
{
|
||||
return shape_plan->shaper_name;
|
||||
}
|
89
src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h
vendored
Normal file
89
src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_SHAPE_PLAN_H
|
||||
#define HB_SHAPE_PLAN_H
|
||||
|
||||
#include "hb-common.h"
|
||||
#include "hb-font.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
typedef struct hb_shape_plan_t hb_shape_plan_t;
|
||||
|
||||
hb_shape_plan_t *
|
||||
hb_shape_plan_create (hb_face_t *face,
|
||||
const hb_segment_properties_t *props,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
const char * const *shaper_list);
|
||||
|
||||
hb_shape_plan_t *
|
||||
hb_shape_plan_create_cached (hb_face_t *face,
|
||||
const hb_segment_properties_t *props,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
const char * const *shaper_list);
|
||||
|
||||
hb_shape_plan_t *
|
||||
hb_shape_plan_get_empty (void);
|
||||
|
||||
hb_shape_plan_t *
|
||||
hb_shape_plan_reference (hb_shape_plan_t *shape_plan);
|
||||
|
||||
void
|
||||
hb_shape_plan_destroy (hb_shape_plan_t *shape_plan);
|
||||
|
||||
hb_bool_t
|
||||
hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
void *
|
||||
hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
|
||||
hb_bool_t
|
||||
hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features);
|
||||
|
||||
const char *
|
||||
hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_SHAPE_PLAN_H */
|
275
src/3rdparty/harfbuzz-ng/src/hb-shape.cc
vendored
Normal file
275
src/3rdparty/harfbuzz-ng/src/hb-shape.cc
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-shaper-private.hh"
|
||||
#include "hb-shape-plan-private.hh"
|
||||
#include "hb-buffer-private.hh"
|
||||
#include "hb-font-private.hh"
|
||||
|
||||
|
||||
static void
|
||||
parse_space (const char **pp, const char *end)
|
||||
{
|
||||
char c;
|
||||
while (*pp < end && (c = **pp, ISSPACE (c)))
|
||||
(*pp)++;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
parse_char (const char **pp, const char *end, char c)
|
||||
{
|
||||
parse_space (pp, end);
|
||||
|
||||
if (*pp == end || **pp != c)
|
||||
return false;
|
||||
|
||||
(*pp)++;
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
parse_uint (const char **pp, const char *end, unsigned int *pv)
|
||||
{
|
||||
char buf[32];
|
||||
unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
|
||||
strncpy (buf, *pp, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
char *p = buf;
|
||||
char *pend = p;
|
||||
unsigned int v;
|
||||
|
||||
/* Intentionally use strtol instead of strtoul, such that
|
||||
* -1 turns into "big number"... */
|
||||
errno = 0;
|
||||
v = strtol (p, &pend, 0);
|
||||
if (errno || p == pend)
|
||||
return false;
|
||||
|
||||
*pv = v;
|
||||
*pp += pend - p;
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature)
|
||||
{
|
||||
if (parse_char (pp, end, '-'))
|
||||
feature->value = 0;
|
||||
else {
|
||||
parse_char (pp, end, '+');
|
||||
feature->value = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature)
|
||||
{
|
||||
const char *p = *pp;
|
||||
char c;
|
||||
|
||||
parse_space (pp, end);
|
||||
|
||||
#define ISALNUM(c) (('a' <= (c) && (c) <= 'z') || ('A' <= (c) && (c) <= 'Z') || ('0' <= (c) && (c) <= '9'))
|
||||
while (*pp < end && (c = **pp, ISALNUM(c)))
|
||||
(*pp)++;
|
||||
#undef ISALNUM
|
||||
|
||||
if (p == *pp)
|
||||
return false;
|
||||
|
||||
feature->tag = hb_tag_from_string (p, *pp - p);
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature)
|
||||
{
|
||||
parse_space (pp, end);
|
||||
|
||||
hb_bool_t has_start;
|
||||
|
||||
feature->start = 0;
|
||||
feature->end = (unsigned int) -1;
|
||||
|
||||
if (!parse_char (pp, end, '['))
|
||||
return true;
|
||||
|
||||
has_start = parse_uint (pp, end, &feature->start);
|
||||
|
||||
if (parse_char (pp, end, ':')) {
|
||||
parse_uint (pp, end, &feature->end);
|
||||
} else {
|
||||
if (has_start)
|
||||
feature->end = feature->start + 1;
|
||||
}
|
||||
|
||||
return parse_char (pp, end, ']');
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature)
|
||||
{
|
||||
return !parse_char (pp, end, '=') || parse_uint (pp, end, &feature->value);
|
||||
}
|
||||
|
||||
|
||||
static hb_bool_t
|
||||
parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
|
||||
{
|
||||
return parse_feature_value_prefix (pp, end, feature) &&
|
||||
parse_feature_tag (pp, end, feature) &&
|
||||
parse_feature_indices (pp, end, feature) &&
|
||||
parse_feature_value_postfix (pp, end, feature) &&
|
||||
*pp == end;
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_feature_from_string (const char *str, int len,
|
||||
hb_feature_t *feature)
|
||||
{
|
||||
if (len < 0)
|
||||
len = strlen (str);
|
||||
|
||||
return parse_one_feature (&str, str + len, feature);
|
||||
}
|
||||
|
||||
void
|
||||
hb_feature_to_string (hb_feature_t *feature,
|
||||
char *buf, unsigned int size)
|
||||
{
|
||||
if (unlikely (!size)) return;
|
||||
|
||||
char s[128];
|
||||
unsigned int len = 0;
|
||||
if (feature->value == 0)
|
||||
s[len++] = '-';
|
||||
hb_tag_to_string (feature->tag, s + len);
|
||||
len += 4;
|
||||
while (len && s[len - 1] == ' ')
|
||||
len--;
|
||||
if (feature->start != 0 || feature->end != (unsigned int) -1)
|
||||
{
|
||||
s[len++] = '[';
|
||||
if (feature->start)
|
||||
len += snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->start);
|
||||
if (feature->end != feature->start + 1) {
|
||||
s[len++] = ':';
|
||||
if (feature->end != (unsigned int) -1)
|
||||
len += snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->end);
|
||||
}
|
||||
s[len++] = ']';
|
||||
}
|
||||
if (feature->value > 1)
|
||||
{
|
||||
s[len++] = '=';
|
||||
len += snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->value);
|
||||
}
|
||||
assert (len < ARRAY_LENGTH (s));
|
||||
len = MIN (len, size - 1);
|
||||
memcpy (buf, s, len);
|
||||
buf[len] = '\0';
|
||||
}
|
||||
|
||||
|
||||
static const char **static_shaper_list;
|
||||
|
||||
static inline
|
||||
void free_static_shaper_list (void)
|
||||
{
|
||||
free (static_shaper_list);
|
||||
}
|
||||
|
||||
const char **
|
||||
hb_shape_list_shapers (void)
|
||||
{
|
||||
retry:
|
||||
const char **shaper_list = (const char **) hb_atomic_ptr_get (&static_shaper_list);
|
||||
|
||||
if (unlikely (!shaper_list))
|
||||
{
|
||||
/* Not found; allocate one. */
|
||||
shaper_list = (const char **) calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *));
|
||||
if (unlikely (!shaper_list)) {
|
||||
static const char *nil_shaper_list[] = {NULL};
|
||||
return nil_shaper_list;
|
||||
}
|
||||
|
||||
const hb_shaper_pair_t *shapers = _hb_shapers_get ();
|
||||
unsigned int i;
|
||||
for (i = 0; i < HB_SHAPERS_COUNT; i++)
|
||||
shaper_list[i] = shapers[i].name;
|
||||
shaper_list[i] = NULL;
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&static_shaper_list, NULL, shaper_list)) {
|
||||
free (shaper_list);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ATEXIT
|
||||
atexit (free_static_shaper_list); /* First person registers atexit() callback. */
|
||||
#endif
|
||||
}
|
||||
|
||||
return shaper_list;
|
||||
}
|
||||
|
||||
|
||||
hb_bool_t
|
||||
hb_shape_full (hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features,
|
||||
const char * const *shaper_list)
|
||||
{
|
||||
if (unlikely (!buffer->len))
|
||||
return true;
|
||||
|
||||
assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
|
||||
|
||||
hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list);
|
||||
hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
|
||||
hb_shape_plan_destroy (shape_plan);
|
||||
|
||||
if (res)
|
||||
buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
hb_shape (hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features)
|
||||
{
|
||||
hb_shape_full (font, buffer, features, num_features, NULL);
|
||||
}
|
81
src/3rdparty/harfbuzz-ng/src/hb-shape.h
vendored
Normal file
81
src/3rdparty/harfbuzz-ng/src/hb-shape.h
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_SHAPE_H
|
||||
#define HB_SHAPE_H
|
||||
|
||||
#include "hb-common.h"
|
||||
#include "hb-buffer.h"
|
||||
#include "hb-font.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
typedef struct hb_feature_t {
|
||||
hb_tag_t tag;
|
||||
uint32_t value;
|
||||
unsigned int start;
|
||||
unsigned int end;
|
||||
} hb_feature_t;
|
||||
|
||||
/* len=-1 means str is NUL-terminated */
|
||||
hb_bool_t
|
||||
hb_feature_from_string (const char *str, int len,
|
||||
hb_feature_t *feature);
|
||||
|
||||
/* Something like 128 bytes is more than enough.
|
||||
* nul-terminates. */
|
||||
void
|
||||
hb_feature_to_string (hb_feature_t *feature,
|
||||
char *buf, unsigned int size);
|
||||
|
||||
|
||||
void
|
||||
hb_shape (hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features);
|
||||
|
||||
hb_bool_t
|
||||
hb_shape_full (hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features,
|
||||
const char * const *shaper_list);
|
||||
|
||||
const char **
|
||||
hb_shape_list_shapers (void);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_SHAPE_H */
|
43
src/3rdparty/harfbuzz-ng/src/hb-shaper-impl-private.hh
vendored
Normal file
43
src/3rdparty/harfbuzz-ng/src/hb-shaper-impl-private.hh
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_SHAPER_IMPL_PRIVATE_HH
|
||||
#define HB_SHAPER_IMPL_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-shaper-private.hh"
|
||||
#include "hb-shape-plan-private.hh"
|
||||
#include "hb-font-private.hh"
|
||||
#include "hb-buffer-private.hh"
|
||||
|
||||
|
||||
#ifdef HB_SHAPER
|
||||
#define HB_SHAPER_DATA_GET(object) HB_SHAPER_DATA (HB_SHAPER, object)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HB_SHAPER_IMPL_PRIVATE_HH */
|
55
src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
vendored
Normal file
55
src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_SHAPER_LIST_HH
|
||||
#define HB_SHAPER_LIST_HH
|
||||
#endif /* HB_SHAPER_LIST_HH */ /* Dummy header guards */
|
||||
|
||||
/* v--- Add new shapers in the right place here. */
|
||||
|
||||
#ifdef HAVE_GRAPHITE2
|
||||
/* Only picks up fonts that have a "Silf" table. */
|
||||
HB_SHAPER_IMPLEMENT (graphite2)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OT
|
||||
HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HB_OLD
|
||||
HB_SHAPER_IMPLEMENT (old)
|
||||
#endif
|
||||
#ifdef HAVE_ICU_LE
|
||||
HB_SHAPER_IMPLEMENT (icu_le)
|
||||
#endif
|
||||
#ifdef HAVE_UNISCRIBE
|
||||
HB_SHAPER_IMPLEMENT (uniscribe)
|
||||
#endif
|
||||
#ifdef HAVE_CORETEXT
|
||||
HB_SHAPER_IMPLEMENT (coretext)
|
||||
#endif
|
||||
|
||||
HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */
|
109
src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh
vendored
Normal file
109
src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_SHAPER_PRIVATE_HH
|
||||
#define HB_SHAPER_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features);
|
||||
|
||||
#define HB_SHAPER_IMPLEMENT(name) \
|
||||
extern "C" HB_INTERNAL hb_shape_func_t _hb_##name##_shape;
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
|
||||
struct hb_shaper_pair_t {
|
||||
char name[16];
|
||||
hb_shape_func_t *func;
|
||||
};
|
||||
|
||||
HB_INTERNAL const hb_shaper_pair_t *
|
||||
_hb_shapers_get (void);
|
||||
|
||||
|
||||
/* For embedding in face / font / ... */
|
||||
struct hb_shaper_data_t {
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) void *shaper;
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
};
|
||||
|
||||
#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
|
||||
|
||||
/* Means: succeeded, but don't need to keep any data. */
|
||||
#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
|
||||
|
||||
/* Means: tried but failed to create. */
|
||||
#define HB_SHAPER_DATA_INVALID ((void *) -1)
|
||||
#define HB_SHAPER_DATA_IS_INVALID(data) ((void *) (data) == HB_SHAPER_DATA_INVALID)
|
||||
|
||||
#define HB_SHAPER_DATA_TYPE(shaper, object) struct hb_##shaper##_shaper_##object##_data_t
|
||||
#define HB_SHAPER_DATA_INSTANCE(shaper, object, instance) (* (HB_SHAPER_DATA_TYPE(shaper, object) **) &(instance)->shaper_data.shaper)
|
||||
#define HB_SHAPER_DATA(shaper, object) HB_SHAPER_DATA_INSTANCE (shaper, object, object)
|
||||
#define HB_SHAPER_DATA_CREATE_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_create
|
||||
#define HB_SHAPER_DATA_DESTROY_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_destroy
|
||||
|
||||
#define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \
|
||||
HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
|
||||
extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \
|
||||
HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS); \
|
||||
extern "C" HB_INTERNAL void \
|
||||
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data)
|
||||
|
||||
#define HB_SHAPER_DATA_DESTROY(shaper, object) \
|
||||
if (object->shaper_data.shaper && \
|
||||
object->shaper_data.shaper != HB_SHAPER_DATA_INVALID && \
|
||||
object->shaper_data.shaper != HB_SHAPER_DATA_SUCCEEDED) \
|
||||
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA (shaper, object));
|
||||
|
||||
#define HB_SHAPER_DATA_ENSURE_DECLARE(shaper, object) \
|
||||
static inline bool \
|
||||
hb_##shaper##_shaper_##object##_data_ensure (hb_##object##_t *object) \
|
||||
{\
|
||||
retry: \
|
||||
HB_SHAPER_DATA_TYPE (shaper, object) *data = (HB_SHAPER_DATA_TYPE (shaper, object) *) hb_atomic_ptr_get (&HB_SHAPER_DATA (shaper, object)); \
|
||||
if (unlikely (!data)) { \
|
||||
data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \
|
||||
if (unlikely (!data)) \
|
||||
data = (HB_SHAPER_DATA_TYPE (shaper, object) *) HB_SHAPER_DATA_INVALID; \
|
||||
if (!hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), NULL, data)) { \
|
||||
if (data && \
|
||||
data != HB_SHAPER_DATA_INVALID && \
|
||||
data != HB_SHAPER_DATA_SUCCEEDED) \
|
||||
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
|
||||
goto retry; \
|
||||
} \
|
||||
} \
|
||||
return data != NULL && !HB_SHAPER_DATA_IS_INVALID (data); \
|
||||
}
|
||||
|
||||
|
||||
#endif /* HB_SHAPER_PRIVATE_HH */
|
109
src/3rdparty/harfbuzz-ng/src/hb-shaper.cc
vendored
Normal file
109
src/3rdparty/harfbuzz-ng/src/hb-shaper.cc
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-shaper-private.hh"
|
||||
#include "hb-atomic-private.hh"
|
||||
|
||||
|
||||
static const hb_shaper_pair_t all_shapers[] = {
|
||||
#define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape},
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
};
|
||||
|
||||
|
||||
/* Thread-safe, lock-free, shapers */
|
||||
|
||||
static const hb_shaper_pair_t *static_shapers;
|
||||
|
||||
static inline
|
||||
void free_static_shapers (void)
|
||||
{
|
||||
if (unlikely (static_shapers != all_shapers))
|
||||
free ((void *) static_shapers);
|
||||
}
|
||||
|
||||
const hb_shaper_pair_t *
|
||||
_hb_shapers_get (void)
|
||||
{
|
||||
retry:
|
||||
hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) hb_atomic_ptr_get (&static_shapers);
|
||||
|
||||
if (unlikely (!shapers))
|
||||
{
|
||||
char *env = getenv ("HB_SHAPER_LIST");
|
||||
if (!env || !*env) {
|
||||
(void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
|
||||
return (const hb_shaper_pair_t *) all_shapers;
|
||||
}
|
||||
|
||||
/* Not found; allocate one. */
|
||||
shapers = (hb_shaper_pair_t *) malloc (sizeof (all_shapers));
|
||||
if (unlikely (!shapers)) {
|
||||
(void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
|
||||
return (const hb_shaper_pair_t *) all_shapers;
|
||||
}
|
||||
|
||||
memcpy (shapers, all_shapers, sizeof (all_shapers));
|
||||
|
||||
/* Reorder shaper list to prefer requested shapers. */
|
||||
unsigned int i = 0;
|
||||
char *end, *p = env;
|
||||
for (;;) {
|
||||
end = strchr (p, ',');
|
||||
if (!end)
|
||||
end = p + strlen (p);
|
||||
|
||||
for (unsigned int j = i; j < ARRAY_LENGTH (all_shapers); j++)
|
||||
if (end - p == (int) strlen (shapers[j].name) &&
|
||||
0 == strncmp (shapers[j].name, p, end - p))
|
||||
{
|
||||
/* Reorder this shaper to position i */
|
||||
struct hb_shaper_pair_t t = shapers[j];
|
||||
memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
|
||||
shapers[i] = t;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!*end)
|
||||
break;
|
||||
else
|
||||
p = end + 1;
|
||||
}
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&static_shapers, NULL, shapers)) {
|
||||
free (shapers);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ATEXIT
|
||||
atexit (free_static_shapers); /* First person registers atexit() callback. */
|
||||
#endif
|
||||
}
|
||||
|
||||
return shapers;
|
||||
}
|
317
src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
vendored
Normal file
317
src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
vendored
Normal file
@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2011 Codethink Limited
|
||||
* Copyright © 2010,2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Codethink Author(s): Ryan Lortie
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_UNICODE_PRIVATE_HH
|
||||
#define HB_UNICODE_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-unicode.h"
|
||||
#include "hb-object-private.hh"
|
||||
|
||||
|
||||
extern HB_INTERNAL const uint8_t _hb_modified_combining_class[256];
|
||||
|
||||
/*
|
||||
* hb_unicode_funcs_t
|
||||
*/
|
||||
|
||||
#define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (combining_class) \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (eastasian_width) \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (general_category) \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (mirroring) \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (script) \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (compose) \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (decompose) \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (decompose_compatibility) \
|
||||
/* ^--- Add new callbacks here */
|
||||
|
||||
/* Simple callbacks are those taking a hb_codepoint_t and returning a hb_codepoint_t */
|
||||
#define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_combining_class_t, combining_class) \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width) \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_general_category_t, general_category) \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (hb_codepoint_t, mirroring) \
|
||||
HB_UNICODE_FUNC_IMPLEMENT (hb_script_t, script) \
|
||||
/* ^--- Add new simple callbacks here */
|
||||
|
||||
struct hb_unicode_funcs_t {
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
||||
hb_unicode_funcs_t *parent;
|
||||
|
||||
bool immutable;
|
||||
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name) \
|
||||
inline return_type name (hb_codepoint_t unicode) { return func.name (this, unicode, user_data.name); }
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
|
||||
inline hb_bool_t compose (hb_codepoint_t a, hb_codepoint_t b,
|
||||
hb_codepoint_t *ab)
|
||||
{
|
||||
*ab = 0;
|
||||
if (unlikely (!a || !b)) return false;
|
||||
return func.compose (this, a, b, ab, user_data.compose);
|
||||
}
|
||||
|
||||
inline hb_bool_t decompose (hb_codepoint_t ab,
|
||||
hb_codepoint_t *a, hb_codepoint_t *b)
|
||||
{
|
||||
*a = ab; *b = 0;
|
||||
return func.decompose (this, ab, a, b, user_data.decompose);
|
||||
}
|
||||
|
||||
inline unsigned int decompose_compatibility (hb_codepoint_t u,
|
||||
hb_codepoint_t *decomposed)
|
||||
{
|
||||
unsigned int ret = func.decompose_compatibility (this, u, decomposed, user_data.decompose_compatibility);
|
||||
if (ret == 1 && u == decomposed[0]) {
|
||||
decomposed[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
decomposed[ret] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
modified_combining_class (hb_codepoint_t unicode)
|
||||
{
|
||||
/* XXX This hack belongs to the Myanmar shaper. */
|
||||
if (unicode == 0x1037) unicode = 0x103A;
|
||||
|
||||
return _hb_modified_combining_class[combining_class (unicode)];
|
||||
}
|
||||
|
||||
inline hb_bool_t
|
||||
is_variation_selector (hb_codepoint_t unicode)
|
||||
{
|
||||
return unlikely (hb_in_ranges<hb_codepoint_t> (unicode,
|
||||
0x180B, 0x180D, /* MONGOLIAN FREE VARIATION SELECTOR ONE..THREE */
|
||||
0xFE00, 0xFE0F, /* VARIATION SELECTOR-1..16 */
|
||||
0xE0100, 0xE01EF)); /* VARIATION SELECTOR-17..256 */
|
||||
}
|
||||
|
||||
/* Default_Ignorable codepoints:
|
||||
*
|
||||
* Note that as of Oct 2012 (Unicode 6.2), U+180E MONGOLIAN VOWEL SEPARATOR
|
||||
* is NOT Default_Ignorable, but it really behaves in a way that it should
|
||||
* be. That has been reported to the Unicode Technical Committee for
|
||||
* consideration. As such, we include it here, since Uniscribe removes it.
|
||||
* It *is* in Unicode 6.3 however. U+061C ARABIC LETTER MARK from Unicode
|
||||
* 6.3 is also added manually. The new Unicode 6.3 bidi formatting
|
||||
* characters are encoded in a block that was Default_Ignorable already.
|
||||
*
|
||||
* Note: While U+115F and U+1160 are Default_Ignorable, we do NOT want to
|
||||
* hide them, as the way Uniscribe has implemented them is with regular
|
||||
* spacing glyphs, and that's the way fonts are made to work. As such,
|
||||
* we make exceptions for those two.
|
||||
*
|
||||
* Gathered from:
|
||||
* http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:DI:]&abb=on&ucd=on&esc=on
|
||||
*
|
||||
* Last updated to the page with the following versions:
|
||||
* Version 3.6; ICU version: 50.0.1.0; Unicode version: 6.1.0.0
|
||||
*
|
||||
* 4,167 Code Points
|
||||
*
|
||||
* [\u00AD\u034F\u115F\u1160\u17B4\u17B5\u180B-\u180D\u200B-\u200F\u202A-\u202E\u2060-\u206F\u3164\uFE00-\uFE0F\uFEFF\uFFA0\uFFF0-\uFFF8\U0001D173-\U0001D17A\U000E0000-\U000E0FFF]
|
||||
*
|
||||
* 00AD ;SOFT HYPHEN
|
||||
* 034F ;COMBINING GRAPHEME JOINER
|
||||
* #115F ;HANGUL CHOSEONG FILLER
|
||||
* #1160 ;HANGUL JUNGSEONG FILLER
|
||||
* 17B4 ;KHMER VOWEL INHERENT AQ
|
||||
* 17B5 ;KHMER VOWEL INHERENT AA
|
||||
* 180B..180D ;MONGOLIAN FREE VARIATION SELECTOR THREE
|
||||
* 200B..200F ;RIGHT-TO-LEFT MARK
|
||||
* 202A..202E ;RIGHT-TO-LEFT OVERRIDE
|
||||
* 2060..206F ;NOMINAL DIGIT SHAPES
|
||||
* 3164 ;HANGUL FILLER
|
||||
* FE00..FE0F ;VARIATION SELECTOR-16
|
||||
* FEFF ;ZERO WIDTH NO-BREAK SPACE
|
||||
* FFA0 ;HALFWIDTH HANGUL FILLER
|
||||
* FFF0..FFF8 ;<unassigned-FFF8>
|
||||
* 1D173..1D17A ;MUSICAL SYMBOL END PHRASE
|
||||
* E0000..E0FFF ;<unassigned-E0FFF>
|
||||
*/
|
||||
inline hb_bool_t
|
||||
is_default_ignorable (hb_codepoint_t ch)
|
||||
{
|
||||
hb_codepoint_t plane = ch >> 16;
|
||||
if (likely (plane == 0))
|
||||
{
|
||||
/* BMP */
|
||||
hb_codepoint_t page = ch >> 8;
|
||||
switch (page) {
|
||||
case 0x00: return unlikely (ch == 0x00AD);
|
||||
case 0x03: return unlikely (ch == 0x034F);
|
||||
case 0x06: return unlikely (ch == 0x061C);
|
||||
case 0x17: return hb_in_range<hb_codepoint_t> (ch, 0x17B4, 0x17B5);
|
||||
case 0x18: return hb_in_range<hb_codepoint_t> (ch, 0x180B, 0x180E);
|
||||
case 0x20: return hb_in_ranges<hb_codepoint_t> (ch, 0x200B, 0x200F,
|
||||
0x202A, 0x202E,
|
||||
0x2060, 0x206F);
|
||||
case 0x31: return unlikely (ch == 0x3164);
|
||||
case 0xFE: return hb_in_range<hb_codepoint_t> (ch, 0xFE00, 0xFE0F) || ch == 0xFEFF;
|
||||
case 0xFF: return hb_in_range<hb_codepoint_t> (ch, 0xFFF0, 0xFFF8) || ch == 0xFFA0;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Other planes */
|
||||
switch (plane) {
|
||||
case 0x01: return hb_in_range<hb_codepoint_t> (ch, 0x0001D173, 0x0001D17A);
|
||||
case 0x0E: return hb_in_range<hb_codepoint_t> (ch, 0x000E0000, 0x000E0FFF);
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct {
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name;
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
} func;
|
||||
|
||||
struct {
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) void *name;
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
} user_data;
|
||||
|
||||
struct {
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
} destroy;
|
||||
};
|
||||
|
||||
|
||||
extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil;
|
||||
|
||||
|
||||
/* Modified combining marks */
|
||||
|
||||
/* Hebrew
|
||||
*
|
||||
* We permute the "fixed-position" classes 10-26 into the order
|
||||
* described in the SBL Hebrew manual:
|
||||
*
|
||||
* http://www.sbl-site.org/Fonts/SBLHebrewUserManual1.5x.pdf
|
||||
*
|
||||
* (as recommended by:
|
||||
* http://forum.fontlab.com/archive-old-microsoft-volt-group/vista-and-diacritic-ordering-t6751.0.html)
|
||||
*
|
||||
* More details here:
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=662055
|
||||
*/
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC10 22 /* sheva */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC11 15 /* hataf segol */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC12 16 /* hataf patah */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC13 17 /* hataf qamats */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC14 23 /* hiriq */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC15 18 /* tsere */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC16 19 /* segol */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC17 20 /* patah */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC18 21 /* qamats */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC19 14 /* holam */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC20 24 /* qubuts */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC21 12 /* dagesh */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC22 25 /* meteg */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC23 13 /* rafe */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC24 10 /* shin dot */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC25 11 /* sin dot */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC26 26 /* point varika */
|
||||
|
||||
/*
|
||||
* Arabic
|
||||
*
|
||||
* Modify to move Shadda (ccc=33) before other marks. See:
|
||||
* http://unicode.org/faq/normalization.html#8
|
||||
* http://unicode.org/faq/normalization.html#9
|
||||
*/
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC27 28 /* fathatan */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC28 29 /* dammatan */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC29 30 /* kasratan */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC30 31 /* fatha */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC31 32 /* damma */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC32 33 /* kasra */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC33 27 /* shadda */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC34 34 /* sukun */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC35 35 /* superscript alef */
|
||||
|
||||
/* Syriac */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC36 36 /* superscript alaph */
|
||||
|
||||
/* Telugu
|
||||
*
|
||||
* Modify Telugu length marks (ccc=84, ccc=91).
|
||||
* These are the only matras in the main Indic scripts range that have
|
||||
* a non-zero ccc. That makes them reorder with the Halant that is
|
||||
* ccc=9. Just zero them, we don't need them in our Indic shaper.
|
||||
*/
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC84 0 /* length mark */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC91 0 /* ai length mark */
|
||||
|
||||
/* Thai
|
||||
*
|
||||
* Modify U+0E38 and U+0E39 (ccc=103) to be reordered before U+0E3A (ccc=9).
|
||||
* Assign 3, which is unassigned otherwise.
|
||||
* Uniscribe does this reordering too.
|
||||
*/
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC103 3 /* sara u / sara uu */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC107 107 /* mai * */
|
||||
|
||||
/* Lao */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC118 118 /* sign u / sign uu */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC122 122 /* mai * */
|
||||
|
||||
/* Tibetan */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC129 129 /* sign aa */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC130 130 /* sign i */
|
||||
#define HB_MODIFIED_COMBINING_CLASS_CCC132 132 /* sign u */
|
||||
|
||||
|
||||
/* Misc */
|
||||
|
||||
#define HB_UNICODE_GENERAL_CATEGORY_IS_MARK(gen_cat) \
|
||||
(FLAG (gen_cat) & \
|
||||
(FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
|
||||
|
||||
|
||||
#endif /* HB_UNICODE_PRIVATE_HH */
|
435
src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
vendored
Normal file
435
src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
vendored
Normal file
@ -0,0 +1,435 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2011 Codethink Limited
|
||||
* Copyright © 2010,2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Codethink Author(s): Ryan Lortie
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-unicode-private.hh"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* hb_unicode_funcs_t
|
||||
*/
|
||||
|
||||
static hb_unicode_combining_class_t
|
||||
hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode HB_UNUSED,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode HB_UNUSED,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static hb_unicode_general_category_t
|
||||
hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode HB_UNUSED,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
|
||||
}
|
||||
|
||||
static hb_codepoint_t
|
||||
hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode HB_UNUSED,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
return unicode;
|
||||
}
|
||||
|
||||
static hb_script_t
|
||||
hb_unicode_script_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode HB_UNUSED,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
return HB_SCRIPT_UNKNOWN;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t a HB_UNUSED,
|
||||
hb_codepoint_t b HB_UNUSED,
|
||||
hb_codepoint_t *ab HB_UNUSED,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t ab HB_UNUSED,
|
||||
hb_codepoint_t *a HB_UNUSED,
|
||||
hb_codepoint_t *b HB_UNUSED,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int
|
||||
hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t u HB_UNUSED,
|
||||
hb_codepoint_t *decomposed HB_UNUSED,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define HB_UNICODE_FUNCS_IMPLEMENT_SET \
|
||||
HB_UNICODE_FUNCS_IMPLEMENT (glib) \
|
||||
HB_UNICODE_FUNCS_IMPLEMENT (icu) \
|
||||
HB_UNICODE_FUNCS_IMPLEMENT (ucdn) \
|
||||
HB_UNICODE_FUNCS_IMPLEMENT (nil) \
|
||||
/* ^--- Add new callbacks before nil */
|
||||
|
||||
#define hb_nil_get_unicode_funcs hb_unicode_funcs_get_empty
|
||||
|
||||
/* Prototype them all */
|
||||
#define HB_UNICODE_FUNCS_IMPLEMENT(set) \
|
||||
extern "C" hb_unicode_funcs_t *hb_##set##_get_unicode_funcs (void);
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_SET
|
||||
#undef HB_UNICODE_FUNCS_IMPLEMENT
|
||||
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_unicode_funcs_get_default (void)
|
||||
{
|
||||
#define HB_UNICODE_FUNCS_IMPLEMENT(set) \
|
||||
return hb_##set##_get_unicode_funcs ();
|
||||
|
||||
#ifdef HAVE_GLIB
|
||||
HB_UNICODE_FUNCS_IMPLEMENT(glib)
|
||||
#elif 0 && defined(HAVE_ICU)
|
||||
HB_UNICODE_FUNCS_IMPLEMENT(icu)
|
||||
#elif defined(HAVE_UCDN)
|
||||
HB_UNICODE_FUNCS_IMPLEMENT(ucdn)
|
||||
#else
|
||||
#define HB_UNICODE_FUNCS_NIL 1
|
||||
HB_UNICODE_FUNCS_IMPLEMENT(nil)
|
||||
#endif
|
||||
|
||||
#undef HB_UNICODE_FUNCS_IMPLEMENT
|
||||
}
|
||||
|
||||
#if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
|
||||
#pragma message("Could not find any Unicode functions implementation, you have to provide your own.")
|
||||
#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS.")
|
||||
#endif
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
|
||||
{
|
||||
hb_unicode_funcs_t *ufuncs;
|
||||
|
||||
if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
|
||||
return hb_unicode_funcs_get_empty ();
|
||||
|
||||
if (!parent)
|
||||
parent = hb_unicode_funcs_get_empty ();
|
||||
|
||||
hb_unicode_funcs_make_immutable (parent);
|
||||
ufuncs->parent = hb_unicode_funcs_reference (parent);
|
||||
|
||||
ufuncs->func = parent->func;
|
||||
|
||||
/* We can safely copy user_data from parent since we hold a reference
|
||||
* onto it and it's immutable. We should not copy the destroy notifiers
|
||||
* though. */
|
||||
ufuncs->user_data = parent->user_data;
|
||||
|
||||
return ufuncs;
|
||||
}
|
||||
|
||||
|
||||
const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
|
||||
NULL, /* parent */
|
||||
true, /* immutable */
|
||||
{
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
}
|
||||
};
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_unicode_funcs_get_empty (void)
|
||||
{
|
||||
return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
|
||||
}
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
|
||||
{
|
||||
return hb_object_reference (ufuncs);
|
||||
}
|
||||
|
||||
void
|
||||
hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
|
||||
{
|
||||
if (!hb_object_destroy (ufuncs)) return;
|
||||
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
|
||||
if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
|
||||
hb_unicode_funcs_destroy (ufuncs->parent);
|
||||
|
||||
free (ufuncs);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
|
||||
}
|
||||
|
||||
void *
|
||||
hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
|
||||
hb_user_data_key_t *key)
|
||||
{
|
||||
return hb_object_get_user_data (ufuncs, key);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
|
||||
{
|
||||
if (hb_object_is_inert (ufuncs))
|
||||
return;
|
||||
|
||||
ufuncs->immutable = true;
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
|
||||
{
|
||||
return ufuncs->immutable;
|
||||
}
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
|
||||
{
|
||||
return ufuncs->parent ? ufuncs->parent : hb_unicode_funcs_get_empty ();
|
||||
}
|
||||
|
||||
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
|
||||
\
|
||||
void \
|
||||
hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \
|
||||
hb_unicode_##name##_func_t func, \
|
||||
void *user_data, \
|
||||
hb_destroy_func_t destroy) \
|
||||
{ \
|
||||
if (ufuncs->immutable) \
|
||||
return; \
|
||||
\
|
||||
if (ufuncs->destroy.name) \
|
||||
ufuncs->destroy.name (ufuncs->user_data.name); \
|
||||
\
|
||||
if (func) { \
|
||||
ufuncs->func.name = func; \
|
||||
ufuncs->user_data.name = user_data; \
|
||||
ufuncs->destroy.name = destroy; \
|
||||
} else { \
|
||||
ufuncs->func.name = ufuncs->parent->func.name; \
|
||||
ufuncs->user_data.name = ufuncs->parent->user_data.name; \
|
||||
ufuncs->destroy.name = NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
|
||||
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name) \
|
||||
\
|
||||
return_type \
|
||||
hb_unicode_##name (hb_unicode_funcs_t *ufuncs, \
|
||||
hb_codepoint_t unicode) \
|
||||
{ \
|
||||
return ufuncs->name (unicode); \
|
||||
}
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
|
||||
hb_bool_t
|
||||
hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t a,
|
||||
hb_codepoint_t b,
|
||||
hb_codepoint_t *ab)
|
||||
{
|
||||
return ufuncs->compose (a, b, ab);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t ab,
|
||||
hb_codepoint_t *a,
|
||||
hb_codepoint_t *b)
|
||||
{
|
||||
return ufuncs->decompose (ab, a, b);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t u,
|
||||
hb_codepoint_t *decomposed)
|
||||
{
|
||||
return ufuncs->decompose_compatibility (u, decomposed);
|
||||
}
|
||||
|
||||
|
||||
/* See hb-unicode-private.hh for details. */
|
||||
const uint8_t
|
||||
_hb_modified_combining_class[256] =
|
||||
{
|
||||
0, /* HB_UNICODE_COMBINING_CLASS_NOT_REORDERED */
|
||||
1, /* HB_UNICODE_COMBINING_CLASS_OVERLAY */
|
||||
2, 3, 4, 5, 6,
|
||||
7, /* HB_UNICODE_COMBINING_CLASS_NUKTA */
|
||||
8, /* HB_UNICODE_COMBINING_CLASS_KANA_VOICING */
|
||||
9, /* HB_UNICODE_COMBINING_CLASS_VIRAMA */
|
||||
|
||||
/* Hebrew */
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC10,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC11,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC12,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC13,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC14,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC15,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC16,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC17,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC18,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC19,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC20,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC21,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC22,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC23,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC24,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC25,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC26,
|
||||
|
||||
/* Arabic */
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC27,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC28,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC29,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC30,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC31,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC32,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC33,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC34,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC35,
|
||||
|
||||
/* Syriac */
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC36,
|
||||
|
||||
37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83,
|
||||
|
||||
/* Telugu */
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC84,
|
||||
85, 86, 87, 88, 89, 90,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC91,
|
||||
92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
|
||||
|
||||
/* Thai */
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC103,
|
||||
104, 105, 106,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC107,
|
||||
108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
|
||||
|
||||
/* Lao */
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC118,
|
||||
119, 120, 121,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC122,
|
||||
123, 124, 125, 126, 127, 128,
|
||||
|
||||
/* Tibetan */
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC129,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC130,
|
||||
131,
|
||||
HB_MODIFIED_COMBINING_CLASS_CCC132,
|
||||
133, 134, 135, 136, 137, 138, 139,
|
||||
|
||||
|
||||
140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
|
||||
150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
|
||||
160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
|
||||
170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
|
||||
180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
|
||||
190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
|
||||
|
||||
200, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT */
|
||||
201,
|
||||
202, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW */
|
||||
203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
|
||||
214, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE */
|
||||
215,
|
||||
216, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT */
|
||||
217,
|
||||
218, /* HB_UNICODE_COMBINING_CLASS_BELOW_LEFT */
|
||||
219,
|
||||
220, /* HB_UNICODE_COMBINING_CLASS_BELOW */
|
||||
221,
|
||||
222, /* HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT */
|
||||
223,
|
||||
224, /* HB_UNICODE_COMBINING_CLASS_LEFT */
|
||||
225,
|
||||
226, /* HB_UNICODE_COMBINING_CLASS_RIGHT */
|
||||
227,
|
||||
228, /* HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT */
|
||||
229,
|
||||
230, /* HB_UNICODE_COMBINING_CLASS_ABOVE */
|
||||
231,
|
||||
232, /* HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT */
|
||||
233, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW */
|
||||
234, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE */
|
||||
235, 236, 237, 238, 239,
|
||||
240, /* HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT */
|
||||
241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
|
||||
255, /* HB_UNICODE_COMBINING_CLASS_INVALID */
|
||||
};
|
357
src/3rdparty/harfbuzz-ng/src/hb-unicode.h
vendored
Normal file
357
src/3rdparty/harfbuzz-ng/src/hb-unicode.h
vendored
Normal file
@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2011 Codethink Limited
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Codethink Author(s): Ryan Lortie
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_UNICODE_H
|
||||
#define HB_UNICODE_H
|
||||
|
||||
#include "hb-common.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
/* hb_unicode_general_category_t */
|
||||
|
||||
/* Unicode Character Database property: General_Category (gc) */
|
||||
typedef enum
|
||||
{
|
||||
HB_UNICODE_GENERAL_CATEGORY_CONTROL, /* Cc */
|
||||
HB_UNICODE_GENERAL_CATEGORY_FORMAT, /* Cf */
|
||||
HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED, /* Cn */
|
||||
HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE, /* Co */
|
||||
HB_UNICODE_GENERAL_CATEGORY_SURROGATE, /* Cs */
|
||||
HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER, /* Ll */
|
||||
HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER, /* Lm */
|
||||
HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER, /* Lo */
|
||||
HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER, /* Lt */
|
||||
HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER, /* Lu */
|
||||
HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK, /* Mc */
|
||||
HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK, /* Me */
|
||||
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK, /* Mn */
|
||||
HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER, /* Nd */
|
||||
HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER, /* Nl */
|
||||
HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER, /* No */
|
||||
HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION, /* Pc */
|
||||
HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION, /* Pd */
|
||||
HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION, /* Pe */
|
||||
HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION, /* Pf */
|
||||
HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION, /* Pi */
|
||||
HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION, /* Po */
|
||||
HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION, /* Ps */
|
||||
HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL, /* Sc */
|
||||
HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL, /* Sk */
|
||||
HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL, /* Sm */
|
||||
HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL, /* So */
|
||||
HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR, /* Zl */
|
||||
HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR, /* Zp */
|
||||
HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR /* Zs */
|
||||
} hb_unicode_general_category_t;
|
||||
|
||||
/* hb_unicode_combining_class_t */
|
||||
|
||||
/* Note: newer versions of Unicode may add new values. Clients should be ready to handle
|
||||
* any value in the 0..254 range being returned from hb_unicode_combining_class().
|
||||
*/
|
||||
|
||||
/* Unicode Character Database property: Canonical_Combining_Class (ccc) */
|
||||
typedef enum
|
||||
{
|
||||
HB_UNICODE_COMBINING_CLASS_NOT_REORDERED = 0,
|
||||
HB_UNICODE_COMBINING_CLASS_OVERLAY = 1,
|
||||
HB_UNICODE_COMBINING_CLASS_NUKTA = 7,
|
||||
HB_UNICODE_COMBINING_CLASS_KANA_VOICING = 8,
|
||||
HB_UNICODE_COMBINING_CLASS_VIRAMA = 9,
|
||||
|
||||
/* Hebrew */
|
||||
HB_UNICODE_COMBINING_CLASS_CCC10 = 10,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC11 = 11,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC12 = 12,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC13 = 13,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC14 = 14,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC15 = 15,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC16 = 16,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC17 = 17,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC18 = 18,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC19 = 19,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC20 = 20,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC21 = 21,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC22 = 22,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC23 = 23,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC24 = 24,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC25 = 25,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC26 = 26,
|
||||
|
||||
/* Arabic */
|
||||
HB_UNICODE_COMBINING_CLASS_CCC27 = 27,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC28 = 28,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC29 = 29,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC30 = 30,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC31 = 31,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC32 = 32,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC33 = 33,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC34 = 34,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC35 = 35,
|
||||
|
||||
/* Syriac */
|
||||
HB_UNICODE_COMBINING_CLASS_CCC36 = 36,
|
||||
|
||||
/* Telugu */
|
||||
HB_UNICODE_COMBINING_CLASS_CCC84 = 84,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC91 = 91,
|
||||
|
||||
/* Thai */
|
||||
HB_UNICODE_COMBINING_CLASS_CCC103 = 103,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC107 = 107,
|
||||
|
||||
/* Lao */
|
||||
HB_UNICODE_COMBINING_CLASS_CCC118 = 118,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC122 = 122,
|
||||
|
||||
/* Tibetan */
|
||||
HB_UNICODE_COMBINING_CLASS_CCC129 = 129,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC130 = 130,
|
||||
HB_UNICODE_COMBINING_CLASS_CCC133 = 132,
|
||||
|
||||
|
||||
HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT = 200,
|
||||
HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW = 202,
|
||||
HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE = 214,
|
||||
HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT = 216,
|
||||
HB_UNICODE_COMBINING_CLASS_BELOW_LEFT = 218,
|
||||
HB_UNICODE_COMBINING_CLASS_BELOW = 220,
|
||||
HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT = 222,
|
||||
HB_UNICODE_COMBINING_CLASS_LEFT = 224,
|
||||
HB_UNICODE_COMBINING_CLASS_RIGHT = 226,
|
||||
HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT = 228,
|
||||
HB_UNICODE_COMBINING_CLASS_ABOVE = 230,
|
||||
HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT = 232,
|
||||
HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW = 233,
|
||||
HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE = 234,
|
||||
|
||||
HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT = 240,
|
||||
|
||||
HB_UNICODE_COMBINING_CLASS_INVALID = 255
|
||||
} hb_unicode_combining_class_t;
|
||||
|
||||
|
||||
/*
|
||||
* hb_unicode_funcs_t
|
||||
*/
|
||||
|
||||
typedef struct hb_unicode_funcs_t hb_unicode_funcs_t;
|
||||
|
||||
|
||||
/*
|
||||
* just give me the best implementation you've got there.
|
||||
*/
|
||||
hb_unicode_funcs_t *
|
||||
hb_unicode_funcs_get_default (void);
|
||||
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_unicode_funcs_create (hb_unicode_funcs_t *parent);
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_unicode_funcs_get_empty (void);
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs);
|
||||
|
||||
void
|
||||
hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs);
|
||||
|
||||
hb_bool_t
|
||||
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
|
||||
void *
|
||||
hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
|
||||
void
|
||||
hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs);
|
||||
|
||||
hb_bool_t
|
||||
hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs);
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs);
|
||||
|
||||
|
||||
/*
|
||||
* funcs
|
||||
*/
|
||||
|
||||
/* typedefs */
|
||||
|
||||
typedef hb_unicode_combining_class_t (*hb_unicode_combining_class_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data);
|
||||
typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data);
|
||||
typedef hb_unicode_general_category_t (*hb_unicode_general_category_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data);
|
||||
typedef hb_codepoint_t (*hb_unicode_mirroring_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data);
|
||||
typedef hb_script_t (*hb_unicode_script_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data);
|
||||
|
||||
typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t a,
|
||||
hb_codepoint_t b,
|
||||
hb_codepoint_t *ab,
|
||||
void *user_data);
|
||||
typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t ab,
|
||||
hb_codepoint_t *a,
|
||||
hb_codepoint_t *b,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* hb_unicode_decompose_compatibility_func_t:
|
||||
* @ufuncs: Unicode function structure
|
||||
* @u: codepoint to decompose
|
||||
* @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
|
||||
* @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
|
||||
*
|
||||
* Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
|
||||
* The complete length of the decomposition will be returned.
|
||||
*
|
||||
* If @u has no compatibility decomposition, zero should be returned.
|
||||
*
|
||||
* The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
|
||||
* compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations
|
||||
* of this function type must ensure that they do not write past the provided array.
|
||||
*
|
||||
* Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available.
|
||||
*/
|
||||
typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t u,
|
||||
hb_codepoint_t *decomposed,
|
||||
void *user_data);
|
||||
|
||||
/* See Unicode 6.1 for details on the maximum decomposition length. */
|
||||
#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */
|
||||
|
||||
/* setters */
|
||||
|
||||
void
|
||||
hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
|
||||
hb_unicode_combining_class_func_t combining_class_func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
|
||||
hb_unicode_eastasian_width_func_t eastasian_width_func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
|
||||
hb_unicode_general_category_func_t general_category_func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
|
||||
hb_unicode_mirroring_func_t mirroring_func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
|
||||
hb_unicode_script_func_t script_func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
|
||||
hb_unicode_compose_func_t compose_func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
|
||||
hb_unicode_decompose_func_t decompose_func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
|
||||
hb_unicode_decompose_compatibility_func_t decompose_compatibility_func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/* accessors */
|
||||
|
||||
hb_unicode_combining_class_t
|
||||
hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t unicode);
|
||||
|
||||
unsigned int
|
||||
hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t unicode);
|
||||
|
||||
hb_unicode_general_category_t
|
||||
hb_unicode_general_category (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t unicode);
|
||||
|
||||
hb_codepoint_t
|
||||
hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t unicode);
|
||||
|
||||
hb_script_t
|
||||
hb_unicode_script (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t unicode);
|
||||
|
||||
hb_bool_t
|
||||
hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t a,
|
||||
hb_codepoint_t b,
|
||||
hb_codepoint_t *ab);
|
||||
hb_bool_t
|
||||
hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t ab,
|
||||
hb_codepoint_t *a,
|
||||
hb_codepoint_t *b);
|
||||
|
||||
unsigned int
|
||||
hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
|
||||
hb_codepoint_t u,
|
||||
hb_codepoint_t *decomposed);
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_UNICODE_H */
|
204
src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh
vendored
Normal file
204
src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh
vendored
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_UTF_PRIVATE_HH
|
||||
#define HB_UTF_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
/* UTF-8 */
|
||||
|
||||
#define HB_UTF8_COMPUTE(Char, Mask, Len) \
|
||||
if (Char < 128) { Len = 1; Mask = 0x7f; } \
|
||||
else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \
|
||||
else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \
|
||||
else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \
|
||||
else Len = 0;
|
||||
|
||||
static inline const uint8_t *
|
||||
hb_utf_next (const uint8_t *text,
|
||||
const uint8_t *end,
|
||||
hb_codepoint_t *unicode)
|
||||
{
|
||||
hb_codepoint_t c = *text, mask;
|
||||
unsigned int len;
|
||||
|
||||
/* TODO check for overlong sequences? */
|
||||
|
||||
HB_UTF8_COMPUTE (c, mask, len);
|
||||
if (unlikely (!len || (unsigned int) (end - text) < len)) {
|
||||
*unicode = -1;
|
||||
return text + 1;
|
||||
} else {
|
||||
hb_codepoint_t result;
|
||||
unsigned int i;
|
||||
result = c & mask;
|
||||
for (i = 1; i < len; i++)
|
||||
{
|
||||
if (unlikely ((text[i] & 0xc0) != 0x80))
|
||||
{
|
||||
*unicode = -1;
|
||||
return text + 1;
|
||||
}
|
||||
result <<= 6;
|
||||
result |= (text[i] & 0x3f);
|
||||
}
|
||||
*unicode = result;
|
||||
return text + len;
|
||||
}
|
||||
}
|
||||
|
||||
static inline const uint8_t *
|
||||
hb_utf_prev (const uint8_t *text,
|
||||
const uint8_t *start,
|
||||
hb_codepoint_t *unicode)
|
||||
{
|
||||
const uint8_t *end = text--;
|
||||
while (start < text && (*text & 0xc0) == 0x80 && end - text < 4)
|
||||
text--;
|
||||
|
||||
hb_codepoint_t c = *text, mask;
|
||||
unsigned int len;
|
||||
|
||||
/* TODO check for overlong sequences? */
|
||||
|
||||
HB_UTF8_COMPUTE (c, mask, len);
|
||||
if (unlikely (!len || (unsigned int) (end - text) != len)) {
|
||||
*unicode = -1;
|
||||
return end - 1;
|
||||
} else {
|
||||
hb_codepoint_t result;
|
||||
unsigned int i;
|
||||
result = c & mask;
|
||||
for (i = 1; i < len; i++)
|
||||
{
|
||||
result <<= 6;
|
||||
result |= (text[i] & 0x3f);
|
||||
}
|
||||
*unicode = result;
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned int
|
||||
hb_utf_strlen (const uint8_t *text)
|
||||
{
|
||||
return strlen ((const char *) text);
|
||||
}
|
||||
|
||||
|
||||
/* UTF-16 */
|
||||
|
||||
static inline const uint16_t *
|
||||
hb_utf_next (const uint16_t *text,
|
||||
const uint16_t *end,
|
||||
hb_codepoint_t *unicode)
|
||||
{
|
||||
hb_codepoint_t c = *text++;
|
||||
|
||||
if (unlikely (hb_in_range<hb_codepoint_t> (c, 0xd800, 0xdbff)))
|
||||
{
|
||||
/* high surrogate */
|
||||
hb_codepoint_t l;
|
||||
if (text < end && ((l = *text), likely (hb_in_range<hb_codepoint_t> (l, 0xdc00, 0xdfff))))
|
||||
{
|
||||
/* low surrogate */
|
||||
*unicode = (c << 10) + l - ((0xd800 << 10) - 0x10000 + 0xdc00);
|
||||
text++;
|
||||
} else
|
||||
*unicode = -1;
|
||||
} else
|
||||
*unicode = c;
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
static inline const uint16_t *
|
||||
hb_utf_prev (const uint16_t *text,
|
||||
const uint16_t *start,
|
||||
hb_codepoint_t *unicode)
|
||||
{
|
||||
hb_codepoint_t c = *--text;
|
||||
|
||||
if (unlikely (hb_in_range<hb_codepoint_t> (c, 0xdc00, 0xdfff)))
|
||||
{
|
||||
/* low surrogate */
|
||||
hb_codepoint_t h;
|
||||
if (start < text && ((h = *(text - 1)), likely (hb_in_range<hb_codepoint_t> (h, 0xd800, 0xdbff))))
|
||||
{
|
||||
/* high surrogate */
|
||||
*unicode = (h << 10) + c - ((0xd800 << 10) - 0x10000 + 0xdc00);
|
||||
text--;
|
||||
} else
|
||||
*unicode = -1;
|
||||
} else
|
||||
*unicode = c;
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned int
|
||||
hb_utf_strlen (const uint16_t *text)
|
||||
{
|
||||
unsigned int l = 0;
|
||||
while (*text++) l++;
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
/* UTF-32 */
|
||||
|
||||
static inline const uint32_t *
|
||||
hb_utf_next (const uint32_t *text,
|
||||
const uint32_t *end HB_UNUSED,
|
||||
hb_codepoint_t *unicode)
|
||||
{
|
||||
*unicode = *text++;
|
||||
return text;
|
||||
}
|
||||
|
||||
static inline const uint32_t *
|
||||
hb_utf_prev (const uint32_t *text,
|
||||
const uint32_t *start HB_UNUSED,
|
||||
hb_codepoint_t *unicode)
|
||||
{
|
||||
*unicode = *--text;
|
||||
return text;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
hb_utf_strlen (const uint32_t *text)
|
||||
{
|
||||
unsigned int l = 0;
|
||||
while (*text++) l++;
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
#endif /* HB_UTF_PRIVATE_HH */
|
66
src/3rdparty/harfbuzz-ng/src/hb-version.h
vendored
Normal file
66
src/3rdparty/harfbuzz-ng/src/hb-version.h
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright © 2011 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_VERSION_H
|
||||
#define HB_VERSION_H
|
||||
|
||||
#include "hb-common.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
#define HB_VERSION_MAJOR 0
|
||||
#define HB_VERSION_MINOR 9
|
||||
#define HB_VERSION_MICRO 19
|
||||
|
||||
#define HB_VERSION_STRING "0.9.19"
|
||||
|
||||
#define HB_VERSION_CHECK(major,minor,micro) \
|
||||
((major)*10000+(minor)*100+(micro) >= \
|
||||
HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO)
|
||||
|
||||
|
||||
void
|
||||
hb_version (unsigned int *major,
|
||||
unsigned int *minor,
|
||||
unsigned int *micro);
|
||||
|
||||
const char *
|
||||
hb_version_string (void);
|
||||
|
||||
hb_bool_t
|
||||
hb_version_check (unsigned int major,
|
||||
unsigned int minor,
|
||||
unsigned int micro);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_VERSION_H */
|
66
src/3rdparty/harfbuzz-ng/src/hb-warning.cc
vendored
Normal file
66
src/3rdparty/harfbuzz-ng/src/hb-warning.cc
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-atomic-private.hh"
|
||||
#include "hb-mutex-private.hh"
|
||||
|
||||
|
||||
#if defined(HB_ATOMIC_INT_NIL)
|
||||
#ifdef _MSC_VER
|
||||
#pragma message("Could not find any system to define atomic_int macros, library may NOT be thread-safe")
|
||||
#else
|
||||
#warning "Could not find any system to define atomic_int macros, library may NOT be thread-safe"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HB_MUTEX_IMPL_NIL)
|
||||
#ifdef _MSC_VER
|
||||
#pragma message("Could not find any system to define mutex macros, library may NOT be thread-safe")
|
||||
#else
|
||||
#warning "Could not find any system to define mutex macros, library may NOT be thread-safe"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HB_ATOMIC_INT_NIL) || defined(HB_MUTEX_IMPL_NIL)
|
||||
#ifdef _MSC_VER
|
||||
#pragma message("To suppress these warnings, define HB_NO_MT")
|
||||
#else
|
||||
#warning "To suppress these warnings, define HB_NO_MT"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#include "hb-unicode-private.hh"
|
||||
|
||||
#if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
|
||||
#ifdef _MSC_VER
|
||||
#pragma message("Could not find any Unicode functions implementation, you have to provide your own")
|
||||
#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS")
|
||||
#else
|
||||
#warning "Could not find any Unicode functions implementation, you have to provide your own"
|
||||
#warning "To suppress this warning, define HB_NO_UNICODE_FUNCS"
|
||||
#endif
|
||||
#endif
|
45
src/3rdparty/harfbuzz-ng/src/hb.h
vendored
Normal file
45
src/3rdparty/harfbuzz-ng/src/hb.h
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H
|
||||
#define HB_H
|
||||
#define HB_H_IN
|
||||
|
||||
#include "hb-blob.h"
|
||||
#include "hb-buffer.h"
|
||||
#include "hb-common.h"
|
||||
#include "hb-font.h"
|
||||
#include "hb-set.h"
|
||||
#include "hb-shape.h"
|
||||
#include "hb-shape-plan.h"
|
||||
#include "hb-unicode.h"
|
||||
#include "hb-version.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
HB_END_DECLS
|
||||
|
||||
#undef HB_H_IN
|
||||
#endif /* HB_H */
|
Loading…
Reference in New Issue
Block a user