Snap for 9728260 from 037d385269fdf902e814214e7515ed39bf2318cd to udc-release
Change-Id: Ib758b10a4ec3e984d49e20e1e2ab71ed04475cdb
diff --git a/.ci/build-win32.sh b/.ci/build-win32.sh
index a1ca53d..067e222 100755
--- a/.ci/build-win32.sh
+++ b/.ci/build-win32.sh
@@ -6,8 +6,9 @@
-Dtests=disabled \
-Dcairo=enabled \
-Dcairo:fontconfig=disabled \
+ -Dcairo:freetype=disabled \
-Dglib=enabled \
- -Dfreetype=enabled \
+ -Dfreetype=disabled \
-Dgdi=enabled \
-Ddirectwrite=enabled \
-Dcairo=enabled \
diff --git a/.ci/build-win64.sh b/.ci/build-win64.sh
index 385d559..946d245 100644
--- a/.ci/build-win64.sh
+++ b/.ci/build-win64.sh
@@ -6,8 +6,9 @@
-Dtests=disabled \
-Dcairo=enabled \
-Dcairo:fontconfig=disabled \
+ -Dcairo:freetype=disabled \
-Dglib=enabled \
- -Dfreetype=enabled \
+ -Dfreetype=disabled \
-Dgdi=enabled \
-Ddirectwrite=enabled \
-Dcairo=enabled \
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 9525c4a..b013b55 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -136,7 +136,7 @@
steps:
- checkout
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build gtk-doc-tools python3 python3-pip git g++-mingw-w64-i686 zip
- - run: pip3 install meson==0.56.0 --upgrade
+ - run: pip3 install meson==0.60.0
- run: .ci/build-win32.sh
- store_artifacts:
path: harfbuzz-win32.zip
@@ -159,7 +159,7 @@
steps:
- checkout
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build gtk-doc-tools python3 python3-pip git g++-mingw-w64-x86-64 zip
- - run: pip3 install meson==0.56.0 --upgrade
+ - run: pip3 install meson==0.60.0
- run: bash .ci/build-win64.sh
- store_artifacts:
path: harfbuzz-win64.zip
diff --git a/.github/workflows/arm-ci.yml b/.github/workflows/arm-ci.yml
new file mode 100644
index 0000000..3df1316
--- /dev/null
+++ b/.github/workflows/arm-ci.yml
@@ -0,0 +1,25 @@
+name: arm
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+permissions:
+ contents: read
+
+jobs:
+ arm-none-eabi:
+ runs-on: ubuntu-22.04
+ container:
+ image: devkitpro/devkitarm:latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Configure CMake
+ run: |
+ cmake -S . -B build \
+ -DCMAKE_TOOLCHAIN_FILE=${DEVKITPRO}/cmake/3DS.cmake
+ - name: Build
+ run: make CXX_FLAGS="-w -DHB_NO_MT"
+ working-directory: build
diff --git a/.github/workflows/configs-build.yml b/.github/workflows/configs-build.yml
index 9f4fd78..b81ce92 100644
--- a/.github/workflows/configs-build.yml
+++ b/.github/workflows/configs-build.yml
@@ -11,7 +11,7 @@
jobs:
build:
- runs-on: ubuntu-18.04
+ runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml
index f67f5d3..3a95e9b 100644
--- a/.github/workflows/linux-ci.yml
+++ b/.github/workflows/linux-ci.yml
@@ -12,7 +12,7 @@
jobs:
build:
- runs-on: ubuntu-18.04
+ runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml
index a6b6d3d..6a0b793 100644
--- a/.github/workflows/macos-ci.yml
+++ b/.github/workflows/macos-ci.yml
@@ -16,15 +16,9 @@
steps:
- uses: actions/checkout@v3
- name: install dependencies
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config freetype glib glib-utils cairo icu4c graphite2 gobject-introspection gtk-doc ninja
- - run: pip3 install fonttools meson==0.56.0 gcovr==5.0
+ run: HOMEBREW_NO_AUTO_UPDATE=1 brew install meson pkg-config freetype glib glib-utils cairo icu4c graphite2 gobject-introspection gtk-doc ninja
+ - run: pip3 install fonttools
- name: run
- run: PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" meson build -Db_coverage=true -Dcoretext=enabled -Dgraphite=enabled -Dauto_features=enabled -Dchafa=disabled -Doptimization=2
+ run: PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" meson build -Dcoretext=enabled -Dgraphite=enabled -Dauto_features=enabled -Dchafa=disabled -Doptimization=2
- name: ci
run: meson test --print-errorlogs -Cbuild
-
- - name: cov
- run: ninja -Cbuild coverage-xml
- - uses: codecov/codecov-action@v3
- with:
- file: build/meson-logs/coverage.xml
diff --git a/.github/workflows/msvc-ci.yml b/.github/workflows/msvc-ci.yml
index 57aef04..79be9f6 100644
--- a/.github/workflows/msvc-ci.yml
+++ b/.github/workflows/msvc-ci.yml
@@ -14,6 +14,7 @@
runs-on: ${{ matrix.os }}
strategy:
+ fail-fast: false
matrix:
os: [windows-2019, windows-latest]
include:
@@ -45,7 +46,7 @@
$env:path = ($env:path.Split(';') | Where-Object { $_ -ne 'C:\Strawberry\perl\bin' }) -join ';'
meson setup build `
- --wrap-mode=default `
+ --wrap-mode=forcefallback `
--buildtype=release `
-Dglib=enabled `
-Dfreetype=enabled `
diff --git a/.github/workflows/msys2-ci.yml b/.github/workflows/msys2-ci.yml
index 0704f4c..d5bddb4 100644
--- a/.github/workflows/msys2-ci.yml
+++ b/.github/workflows/msys2-ci.yml
@@ -14,6 +14,7 @@
runs-on: windows-latest
strategy:
+ fail-fast: false
matrix:
include:
- MSYSTEM: MINGW32
@@ -22,6 +23,11 @@
MSYS2_ARCH: x86_64
name: ${{ matrix.MSYSTEM }}
+ env:
+ # XXX: For some reason enabling jit debugging "fixes" random python crashes
+ # see https://github.com/msys2/MINGW-packages/issues/11864
+ MSYS: "winjitdebug"
+
defaults:
run:
shell: msys2 {0}
diff --git a/LICENSE b/LICENSE
index 2c60343..7e75ed0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -935,6 +935,12 @@
Licensed under the Apache License, Version 2.0
+-------------------------------------------------------------------
+
+Copyright 2011 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0
+
http://www.apache.org/licenses/LICENSE-2.0
-------------------------------------------------------------------
@@ -4445,6 +4451,30 @@
-------------------------------------------------------------------
+Copyright © 2022 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.
+
+-------------------------------------------------------------------
+
Copyright ©1993–2016 by The Font Bureau, Inc. with Reserved Font Name “Zycon”
https://opensource.org/licenses/OFL-1.1
diff --git a/NEWS b/NEWS
index 8d4389f..73dcef0 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,65 @@
+Overview of changes leading to 6.0.0
+Friday, December 16, 2022
+====================================
+- A new API have been added to pre-process the face and speed up future
+ subsetting operations on that face. Provides up to a 95% reduction in
+ subsetting times when the same face is subset more than once.
+
+ For more details and benchmarks, see:
+ https://github.com/harfbuzz/harfbuzz/blob/main/docs/subset-preprocessing.md
+
+ (Garret Rieger, Behdad Esfahbod)
+
+- Shaping have been speedup by skipping entire lookups when the buffer contents
+ don't intersect with the lookup. Shows up to a 10% speedup in shaping some
+ fonts. (Behdad Esfahbod)
+
+- A new experimental feature, “Variable Composites” (enabled by passing
+ -Dexperimental_api=true to meson), is also featured in this release.
+ This technology enables drastic compression of fonts in the Chinese,
+ Japanese, Korean, and other writing systems, by reusing the OpenType Font
+ Variations technology for encoding “smart components” into the font.
+
+ The specification for these extensions to the font format can be found in:
+ https://github.com/harfbuzz/boring-expansion-spec/blob/glyf1/glyf1.md
+
+ A test variable-font with ~7160 Hangul syllables derived from the
+ NotoSerifKR-VF font has been built, with existing OpenType technology, as
+ well as with the new Variable Composites (VarComposites) technology. The
+ VarComposites font is over 90% smaller than the OpenType version of the font!
+ Both fonts can be obtained from the “smarties” repository:
+ https://github.com/behdad/smarties/tree/3.0/fonts/hangul/serif
+
+ When building HarfBuzz with experimental features enabled, you can test
+ the “smarties” font with a sample character like this:
+
+ $ hb-view butchered-hangul-serif-smarties-variable.ttf -u AE01 --variations=wght=700
+
+ (Behdad Esfahbod)
+
+- The HarfBuzz subsetter can now drop axes by pinning them to specific values
+ (also referred to as instancing). There are a couple of restrictions
+ currently:
+
+ - Only works with TrueType (“glyf”) based fonts. “CFF2” fonts are not yet
+ supported.
+ - Only supports the case where all axes in a font are pinned.
+
+ (Garret Rieger, Qunxin Liu)
+
+- Miscellaneous fixes and improvements.
+
+ (Behdad Esfahbod, Christoph Reiter, David Corbett, Eli Schwartz, Garret
+ Rieger, Joel Auterson, Jordan Petridis, Khaled Hosny, Lorenz Wildberg,
+ Marco Rebhan, Martin Storsjö, Matthias Clasen, Qunxin Liu, Satadru Pramanik)
+
+
+- New API
++hb_subset_input_pin_axis_location()
++hb_subset_input_pin_axis_to_default()
++hb_subset_preprocess()
+
+
Overview of changes leading to 5.3.1
Wednesday, October 19, 2022
====================================
diff --git a/configure.ac b/configure.ac
index f2480c3..abe86ed 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
AC_PREREQ([2.64])
AC_INIT([HarfBuzz],
- [5.3.1],
+ [6.0.0],
[https://github.com/harfbuzz/harfbuzz/issues/new],
[harfbuzz],
[http://harfbuzz.org/])
diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml
index 652a5e4..2d2827a 100644
--- a/docs/harfbuzz-docs.xml
+++ b/docs/harfbuzz-docs.xml
@@ -117,6 +117,7 @@
<index id="api-index-full"><title>API Index</title><xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include></index>
<index id="deprecated-api-index" role="deprecated"><title>Index of deprecated API</title><xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include></index>
+ <index id="api-index-6-0-0" role="6.0.0"><title>Index of new symbols in 6.0.0</title><xi:include href="xml/api-index-6.0.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-5-3-0" role="5.3.0"><title>Index of new symbols in 5.3.0</title><xi:include href="xml/api-index-5.3.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-5-0-0" role="5.0.0"><title>Index of new symbols in 5.0.0</title><xi:include href="xml/api-index-5.0.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-4-4-0" role="4.4.0"><title>Index of new symbols in 4.4.0</title><xi:include href="xml/api-index-4.4.0.xml"><xi:fallback /></xi:include></index>
diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 3a7aa35..a35d3aa 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -26,33 +26,33 @@
hb_blob_create_from_file_or_fail
hb_blob_create_sub_blob
hb_blob_copy_writable_or_fail
+hb_blob_get_empty
+hb_blob_reference
hb_blob_destroy
+hb_blob_set_user_data
+hb_blob_get_user_data
+hb_blob_make_immutable
+hb_blob_is_immutable
hb_blob_get_data
hb_blob_get_data_writable
-hb_blob_get_empty
hb_blob_get_length
-hb_blob_get_user_data
-hb_blob_is_immutable
-hb_blob_make_immutable
-hb_blob_reference
-hb_blob_set_user_data
hb_blob_t
hb_memory_mode_t
</SECTION>
<SECTION>
<FILE>hb-buffer</FILE>
-HB_SEGMENT_PROPERTIES_DEFAULT
-HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT
hb_buffer_create
+hb_buffer_allocation_successful
hb_buffer_create_similar
-hb_buffer_reference
hb_buffer_get_empty
+hb_buffer_reference
hb_buffer_destroy
+hb_buffer_set_user_data
+hb_buffer_get_user_data
hb_buffer_reset
hb_buffer_clear_contents
hb_buffer_pre_allocate
-hb_buffer_allocation_successful
hb_buffer_add
hb_buffer_add_codepoints
hb_buffer_add_utf32
@@ -79,15 +79,14 @@
hb_buffer_guess_segment_properties
hb_buffer_set_unicode_funcs
hb_buffer_get_unicode_funcs
-hb_buffer_set_user_data
-hb_buffer_get_user_data
hb_buffer_get_glyph_infos
+hb_glyph_info_get_glyph_flags
hb_buffer_get_glyph_positions
hb_buffer_has_positions
-hb_buffer_get_invisible_glyph
hb_buffer_set_invisible_glyph
-hb_buffer_get_not_found_glyph
+hb_buffer_get_invisible_glyph
hb_buffer_set_not_found_glyph
+hb_buffer_get_not_found_glyph
hb_buffer_set_replacement_codepoint
hb_buffer_get_replacement_codepoint
hb_buffer_normalize_glyphs
@@ -106,9 +105,11 @@
hb_segment_properties_hash
hb_segment_properties_overlay
hb_buffer_diff
+hb_buffer_message_func_t
hb_buffer_set_message_func
+HB_SEGMENT_PROPERTIES_DEFAULT
+HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT
hb_buffer_t
-hb_glyph_info_get_glyph_flags
hb_glyph_info_t
hb_glyph_flags_t
hb_glyph_position_t
@@ -119,18 +120,25 @@
hb_buffer_serialize_format_t
hb_buffer_serialize_flags_t
hb_buffer_diff_flags_t
-hb_buffer_message_func_t
</SECTION>
<SECTION>
<FILE>hb-common</FILE>
+HB_TAG
+HB_UNTAG
hb_tag_from_string
hb_tag_to_string
hb_direction_from_string
hb_direction_to_string
+HB_DIRECTION_REVERSE
+HB_DIRECTION_IS_BACKWARD
+HB_DIRECTION_IS_FORWARD
+HB_DIRECTION_IS_HORIZONTAL
+HB_DIRECTION_IS_VALID
+HB_DIRECTION_IS_VERTICAL
hb_script_from_iso15924_tag
-hb_script_from_string
hb_script_to_iso15924_tag
+hb_script_from_string
hb_script_get_horizontal_direction
hb_language_from_string
hb_language_to_string
@@ -152,20 +160,16 @@
hb_tag_t
hb_script_t
hb_user_data_key_t
-HB_TAG
HB_TAG_NONE
HB_TAG_MAX
HB_TAG_MAX_SIGNED
-HB_UNTAG
-HB_DIRECTION_REVERSE
-HB_DIRECTION_IS_BACKWARD
-HB_DIRECTION_IS_FORWARD
-HB_DIRECTION_IS_HORIZONTAL
-HB_DIRECTION_IS_VALID
-HB_DIRECTION_IS_VERTICAL
HB_LANGUAGE_INVALID
HB_FEATURE_GLOBAL_END
HB_FEATURE_GLOBAL_START
+HB_HAS_CORETEXT
+HB_HAS_FREETYPE
+HB_HAS_GLIB
+HB_HAS_GRAPHITE
<SUBSECTION Private>
HB_BEGIN_DECLS
HB_END_DECLS
@@ -179,7 +183,6 @@
uint32_t
uint64_t
uint8_t
-<SUBSECTION Private>
HB_EXTERN
HB_DEPRECATED
HB_DEPRECATED_FOR
@@ -187,12 +190,11 @@
<SECTION>
<FILE>hb-draw</FILE>
-hb_draw_funcs_t
hb_draw_funcs_create
-hb_draw_funcs_destroy
hb_draw_funcs_reference
-hb_draw_funcs_is_immutable
+hb_draw_funcs_destroy
hb_draw_funcs_make_immutable
+hb_draw_funcs_is_immutable
hb_draw_move_to_func_t
hb_draw_funcs_set_move_to_func
hb_draw_line_to_func_t
@@ -203,13 +205,14 @@
hb_draw_funcs_set_cubic_to_func
hb_draw_close_path_func_t
hb_draw_funcs_set_close_path_func
-hb_draw_state_t
-HB_DRAW_STATE_DEFAULT
hb_draw_move_to
hb_draw_line_to
hb_draw_quadratic_to
hb_draw_cubic_to
hb_draw_close_path
+HB_DRAW_STATE_DEFAULT
+hb_draw_funcs_t
+hb_draw_state_t
</SECTION>
<SECTION>
@@ -264,22 +267,22 @@
hb_face_t
hb_face_create
hb_face_create_for_tables
-hb_face_destroy
hb_face_get_empty
-hb_face_get_table_tags
-hb_face_get_glyph_count
-hb_face_get_index
-hb_face_get_upem
-hb_face_get_user_data
-hb_face_is_immutable
-hb_face_make_immutable
hb_face_reference
+hb_face_destroy
+hb_face_set_user_data
+hb_face_get_user_data
+hb_face_make_immutable
+hb_face_is_immutable
+hb_face_get_table_tags
+hb_face_set_glyph_count
+hb_face_get_glyph_count
+hb_face_set_index
+hb_face_get_index
+hb_face_set_upem
+hb_face_get_upem
hb_face_reference_blob
hb_face_reference_table
-hb_face_set_glyph_count
-hb_face_set_index
-hb_face_set_upem
-hb_face_set_user_data
hb_face_collect_unicodes
hb_face_collect_variation_selectors
hb_face_collect_variation_unicodes
@@ -293,113 +296,113 @@
hb_font_add_glyph_origin_for_direction
hb_font_create
hb_font_create_sub_font
-hb_font_destroy
-hb_font_funcs_create
-hb_font_funcs_destroy
-hb_font_funcs_get_empty
-hb_font_funcs_get_user_data
-hb_font_funcs_is_immutable
-hb_font_funcs_make_immutable
-hb_font_funcs_reference
-hb_font_funcs_set_glyph_contour_point_func
-hb_font_funcs_set_glyph_extents_func
-hb_font_funcs_set_glyph_from_name_func
-hb_font_funcs_set_glyph_h_advance_func
-hb_font_funcs_set_glyph_h_advances_func
-hb_font_funcs_set_glyph_h_kerning_func
-hb_font_funcs_set_glyph_h_origin_func
-hb_font_funcs_set_glyph_name_func
-hb_font_funcs_set_glyph_shape_func
-hb_font_funcs_set_glyph_v_advance_func
-hb_font_funcs_set_glyph_v_advances_func
-hb_font_funcs_set_glyph_v_origin_func
-hb_font_funcs_set_nominal_glyph_func
-hb_font_funcs_set_nominal_glyphs_func
-hb_font_funcs_set_user_data
-hb_font_funcs_set_variation_glyph_func
-hb_font_funcs_t
hb_font_get_empty
+hb_font_reference
+hb_font_destroy
+hb_font_set_user_data
+hb_font_get_user_data
+hb_font_make_immutable
+hb_font_is_immutable
+hb_font_set_face
hb_font_get_face
hb_font_get_glyph
hb_font_get_glyph_advance_for_direction
-hb_font_get_glyph_advance_func_t
hb_font_get_glyph_advances_for_direction
-hb_font_get_glyph_advances_func_t
hb_font_get_glyph_contour_point
hb_font_get_glyph_contour_point_for_origin
-hb_font_get_glyph_contour_point_func_t
hb_font_get_glyph_extents
hb_font_get_glyph_extents_for_origin
-hb_font_get_glyph_extents_func_t
hb_font_get_glyph_from_name
-hb_font_get_glyph_from_name_func_t
hb_font_get_glyph_h_advance
-hb_font_get_glyph_h_advance_func_t
-hb_font_get_glyph_h_advances
-hb_font_get_glyph_h_advances_func_t
-hb_font_get_glyph_h_kerning
-hb_font_get_glyph_h_kerning_func_t
-hb_font_get_glyph_h_origin
-hb_font_get_glyph_h_origin_func_t
-hb_font_get_glyph_kerning_for_direction
-hb_font_get_glyph_kerning_func_t
-hb_font_get_glyph_name
-hb_font_get_glyph_name_func_t
-hb_font_get_glyph_origin_for_direction
-hb_font_get_glyph_origin_func_t
-hb_font_get_glyph_shape
-hb_font_get_glyph_shape_func_t
hb_font_get_glyph_v_advance
-hb_font_get_glyph_v_advance_func_t
+hb_font_get_glyph_h_advances
hb_font_get_glyph_v_advances
-hb_font_get_glyph_v_advances_func_t
+hb_font_get_glyph_h_kerning
+hb_font_get_glyph_kerning_for_direction
+hb_font_get_glyph_h_origin
hb_font_get_glyph_v_origin
-hb_font_get_glyph_v_origin_func_t
+hb_font_get_glyph_origin_for_direction
+hb_font_get_glyph_name
+hb_font_get_glyph_shape
hb_font_get_nominal_glyph
-hb_font_get_nominal_glyph_func_t
hb_font_get_nominal_glyphs
-hb_font_get_nominal_glyphs_func_t
-hb_font_get_parent
-hb_font_get_ppem
-hb_font_get_ptem
-hb_font_get_scale
-hb_font_get_synthetic_slant
-hb_font_get_user_data
hb_font_get_variation_glyph
-hb_font_get_variation_glyph_func_t
+hb_font_set_parent
+hb_font_get_parent
+hb_font_set_ppem
+hb_font_get_ppem
+hb_font_set_ptem
+hb_font_get_ptem
+hb_font_set_scale
+hb_font_get_scale
+hb_font_set_synthetic_slant
+hb_font_get_synthetic_slant
+hb_font_set_variations
+hb_font_set_var_named_instance
+hb_font_set_var_coords_design
hb_font_get_var_coords_design
+hb_font_set_var_coords_normalized
hb_font_get_var_coords_normalized
hb_font_glyph_from_string
hb_font_glyph_to_string
-hb_font_is_immutable
-hb_font_make_immutable
hb_font_get_serial
hb_font_changed
-hb_font_reference
-hb_font_set_face
hb_font_set_funcs
hb_font_set_funcs_data
-hb_font_set_parent
-hb_font_set_ppem
-hb_font_set_ptem
-hb_font_set_scale
-hb_font_set_synthetic_slant
-hb_font_set_user_data
-hb_font_set_variations
-hb_font_set_var_coords_design
-hb_font_set_var_coords_normalized
-hb_font_set_var_named_instance
hb_font_subtract_glyph_origin_for_direction
+hb_font_funcs_create
+hb_font_funcs_get_empty
+hb_font_funcs_reference
+hb_font_funcs_destroy
+hb_font_funcs_set_user_data
+hb_font_funcs_get_user_data
+hb_font_funcs_make_immutable
+hb_font_funcs_is_immutable
+hb_font_get_glyph_contour_point_func_t
+hb_font_funcs_set_glyph_contour_point_func
+hb_font_get_glyph_extents_func_t
+hb_font_funcs_set_glyph_extents_func
+hb_font_get_glyph_from_name_func_t
+hb_font_funcs_set_glyph_from_name_func
+hb_font_get_glyph_advance_func_t
+hb_font_get_glyph_h_advance_func_t
+hb_font_funcs_set_glyph_h_advance_func
+hb_font_get_glyph_v_advance_func_t
+hb_font_funcs_set_glyph_v_advance_func
+hb_font_get_glyph_advances_func_t
+hb_font_get_glyph_h_advances_func_t
+hb_font_funcs_set_glyph_h_advances_func
+hb_font_get_glyph_v_advances_func_t
+hb_font_funcs_set_glyph_v_advances_func
+hb_font_get_glyph_kerning_func_t
+hb_font_get_glyph_h_kerning_func_t
+hb_font_funcs_set_glyph_h_kerning_func
+hb_font_get_glyph_origin_func_t
+hb_font_get_glyph_h_origin_func_t
+hb_font_funcs_set_glyph_h_origin_func
+hb_font_get_glyph_v_origin_func_t
+hb_font_funcs_set_glyph_v_origin_func
+hb_font_get_glyph_name_func_t
+hb_font_funcs_set_glyph_name_func
+hb_font_get_glyph_shape_func_t
+hb_font_funcs_set_glyph_shape_func
+hb_font_get_nominal_glyph_func_t
+hb_font_funcs_set_nominal_glyph_func
+hb_font_get_nominal_glyphs_func_t
+hb_font_funcs_set_nominal_glyphs_func
+hb_font_get_variation_glyph_func_t
+hb_font_funcs_set_variation_glyph_func
+hb_font_funcs_t
hb_font_t
hb_reference_table_func_t
-hb_font_funcs_set_font_h_extents_func
-hb_font_funcs_set_font_v_extents_func
-hb_font_get_extents_for_direction
hb_font_get_font_extents_func_t
hb_font_get_font_h_extents_func_t
+hb_font_funcs_set_font_h_extents_func
hb_font_get_font_v_extents_func_t
+hb_font_funcs_set_font_v_extents_func
hb_font_get_h_extents
hb_font_get_v_extents
+hb_font_get_extents_for_direction
hb_font_extents_t
hb_glyph_extents_t
</SECTION>
@@ -450,30 +453,29 @@
<SECTION>
<FILE>hb-map</FILE>
-HB_MAP_VALUE_INVALID
-hb_map_allocation_successful
-hb_map_clear
-hb_map_copy
hb_map_create
-hb_map_del
-hb_map_destroy
-hb_map_get
+hb_map_allocation_successful
+hb_map_copy
+hb_map_clear
hb_map_get_empty
-hb_map_get_population
-hb_map_is_equal
-hb_map_get_user_data
-hb_map_has
-hb_map_hash
-hb_map_is_empty
hb_map_reference
-hb_map_set
+hb_map_destroy
hb_map_set_user_data
+hb_map_get_user_data
+hb_map_set
+hb_map_get
+hb_map_del
+hb_map_has
+hb_map_get_population
+hb_map_is_empty
+hb_map_is_equal
+hb_map_hash
+HB_MAP_VALUE_INVALID
hb_map_t
</SECTION>
<SECTION>
<FILE>hb-ot-color</FILE>
-hb_color_t
HB_COLOR
hb_color_get_alpha
hb_color_get_blue
@@ -486,13 +488,14 @@
hb_ot_color_has_palettes
hb_ot_color_has_png
hb_ot_color_has_svg
-hb_ot_color_layer_t
hb_ot_color_palette_color_get_name_id
-hb_ot_color_palette_flags_t
hb_ot_color_palette_get_colors
hb_ot_color_palette_get_count
hb_ot_color_palette_get_flags
hb_ot_color_palette_get_name_id
+hb_color_t
+hb_ot_color_layer_t
+hb_ot_color_palette_flags_t
</SECTION>
<SECTION>
@@ -502,35 +505,21 @@
<SECTION>
<FILE>hb-ot-name</FILE>
-hb_ot_name_id_t
-HB_OT_NAME_ID_INVALID
-hb_ot_name_entry_t
hb_ot_name_list_names
hb_ot_name_get_utf16
hb_ot_name_get_utf32
hb_ot_name_get_utf8
+HB_OT_NAME_ID_INVALID
+hb_ot_name_id_t
+hb_ot_name_entry_t
</SECTION>
<SECTION>
<FILE>hb-ot-layout</FILE>
-HB_OT_MAX_TAGS_PER_LANGUAGE
-HB_OT_MAX_TAGS_PER_SCRIPT
-HB_OT_TAG_DEFAULT_LANGUAGE
-HB_OT_TAG_DEFAULT_SCRIPT
hb_ot_tag_to_language
hb_ot_tag_to_script
hb_ot_tags_from_script_and_language
hb_ot_tags_to_script_and_language
-HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX
-HB_OT_LAYOUT_NO_FEATURE_INDEX
-HB_OT_LAYOUT_NO_SCRIPT_INDEX
-HB_OT_LAYOUT_NO_VARIATIONS_INDEX
-HB_OT_TAG_BASE
-HB_OT_TAG_GDEF
-HB_OT_TAG_GPOS
-HB_OT_TAG_GSUB
-HB_OT_TAG_JSTF
-hb_ot_layout_baseline_tag_t
hb_ot_layout_collect_lookups
hb_ot_layout_collect_features
hb_ot_layout_feature_get_characters
@@ -545,7 +534,6 @@
hb_ot_layout_get_glyphs_in_class
hb_ot_layout_get_ligature_carets
hb_ot_layout_get_size_params
-hb_ot_layout_glyph_class_t
hb_ot_layout_has_glyph_classes
hb_ot_layout_has_positioning
hb_ot_layout_has_substitution
@@ -569,18 +557,25 @@
hb_ot_layout_table_select_script
hb_ot_shape_plan_collect_lookups
hb_ot_layout_language_get_required_feature_index
+HB_OT_MAX_TAGS_PER_LANGUAGE
+HB_OT_MAX_TAGS_PER_SCRIPT
+HB_OT_TAG_DEFAULT_LANGUAGE
+HB_OT_TAG_DEFAULT_SCRIPT
+HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX
+HB_OT_LAYOUT_NO_FEATURE_INDEX
+HB_OT_LAYOUT_NO_SCRIPT_INDEX
+HB_OT_LAYOUT_NO_VARIATIONS_INDEX
+HB_OT_TAG_BASE
+HB_OT_TAG_GDEF
+HB_OT_TAG_GPOS
+HB_OT_TAG_GSUB
+HB_OT_TAG_JSTF
+hb_ot_layout_baseline_tag_t
+hb_ot_layout_glyph_class_t
</SECTION>
<SECTION>
<FILE>hb-ot-math</FILE>
-HB_OT_TAG_MATH
-HB_OT_TAG_MATH_SCRIPT
-hb_ot_math_constant_t
-hb_ot_math_kern_t
-hb_ot_math_kern_entry_t
-hb_ot_math_glyph_variant_t
-hb_ot_math_glyph_part_flags_t
-hb_ot_math_glyph_part_t
hb_ot_math_has_data
hb_ot_math_get_constant
hb_ot_math_get_glyph_italics_correction
@@ -591,23 +586,31 @@
hb_ot_math_get_glyph_variants
hb_ot_math_get_min_connector_overlap
hb_ot_math_get_glyph_assembly
+HB_OT_TAG_MATH
+HB_OT_TAG_MATH_SCRIPT
+hb_ot_math_constant_t
+hb_ot_math_kern_t
+hb_ot_math_kern_entry_t
+hb_ot_math_glyph_variant_t
+hb_ot_math_glyph_part_flags_t
+hb_ot_math_glyph_part_t
</SECTION>
<SECTION>
<FILE>hb-ot-meta</FILE>
-hb_ot_meta_tag_t
hb_ot_meta_get_entry_tags
hb_ot_meta_reference_entry
+hb_ot_meta_tag_t
</SECTION>
<SECTION>
<FILE>hb-ot-metrics</FILE>
-hb_ot_metrics_tag_t
hb_ot_metrics_get_position
hb_ot_metrics_get_position_with_fallback
hb_ot_metrics_get_variation
hb_ot_metrics_get_x_variation
hb_ot_metrics_get_y_variation
+hb_ot_metrics_tag_t
</SECTION>
<SECTION>
@@ -617,14 +620,7 @@
<SECTION>
<FILE>hb-ot-var</FILE>
-HB_OT_TAG_VAR_AXIS_ITALIC
-HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE
-HB_OT_TAG_VAR_AXIS_SLANT
-HB_OT_TAG_VAR_AXIS_WEIGHT
-HB_OT_TAG_VAR_AXIS_WIDTH
hb_ot_var_has_data
-hb_ot_var_axis_flags_t
-hb_ot_var_axis_info_t
hb_ot_var_find_axis_info
hb_ot_var_get_axis_count
hb_ot_var_get_axis_infos
@@ -634,31 +630,43 @@
hb_ot_var_named_instance_get_design_coords
hb_ot_var_normalize_variations
hb_ot_var_normalize_coords
+HB_OT_TAG_VAR_AXIS_ITALIC
+HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE
+HB_OT_TAG_VAR_AXIS_SLANT
+HB_OT_TAG_VAR_AXIS_WEIGHT
+HB_OT_TAG_VAR_AXIS_WIDTH
+hb_ot_var_axis_flags_t
+hb_ot_var_axis_info_t
</SECTION>
<SECTION>
<FILE>hb-set</FILE>
-HB_SET_VALUE_INVALID
+hb_set_create
+hb_set_allocation_successful
+hb_set_copy
+hb_set_get_empty
+hb_set_reference
+hb_set_destroy
+hb_set_set_user_data
+hb_set_get_user_data
+hb_set_clear
+hb_set_set
+hb_set_has
hb_set_add
hb_set_add_range
hb_set_add_sorted_array
-hb_set_allocation_successful
-hb_set_copy
-hb_set_clear
-hb_set_create
hb_set_del
hb_set_del_range
-hb_set_destroy
-hb_set_get_empty
hb_set_get_max
hb_set_get_min
hb_set_get_population
-hb_set_get_user_data
-hb_set_has
-hb_set_hash
-hb_set_intersect
-hb_set_invert
hb_set_is_empty
+hb_set_hash
+hb_set_subtract
+hb_set_intersect
+hb_set_union
+hb_set_symmetric_difference
+hb_set_invert
hb_set_is_equal
hb_set_is_subset
hb_set_next
@@ -666,13 +674,8 @@
hb_set_next_many
hb_set_previous
hb_set_previous_range
-hb_set_reference
-hb_set_set
-hb_set_set_user_data
-hb_set_subtract
-hb_set_symmetric_difference
+HB_SET_VALUE_INVALID
hb_set_t
-hb_set_union
</SECTION>
<SECTION>
@@ -688,50 +691,50 @@
hb_shape_plan_create_cached
hb_shape_plan_create2
hb_shape_plan_create_cached2
-hb_shape_plan_destroy
-hb_shape_plan_execute
hb_shape_plan_get_empty
-hb_shape_plan_get_shaper
-hb_shape_plan_get_user_data
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_shape_plan_t
</SECTION>
<SECTION>
<FILE>hb-unicode</FILE>
-HB_UNICODE_MAX
-hb_unicode_combining_class
-hb_unicode_combining_class_func_t
-hb_unicode_combining_class_t
-hb_unicode_compose
-hb_unicode_compose_func_t
-hb_unicode_decompose
-hb_unicode_decompose_func_t
-hb_unicode_funcs_create
-hb_unicode_funcs_destroy
-hb_unicode_funcs_get_default
-hb_unicode_funcs_get_empty
-hb_unicode_funcs_get_parent
-hb_unicode_funcs_get_user_data
-hb_unicode_funcs_is_immutable
-hb_unicode_funcs_make_immutable
-hb_unicode_funcs_reference
-hb_unicode_funcs_set_combining_class_func
-hb_unicode_funcs_set_compose_func
-hb_unicode_funcs_set_decompose_func
-hb_unicode_funcs_set_general_category_func
-hb_unicode_funcs_set_mirroring_func
-hb_unicode_funcs_set_script_func
-hb_unicode_funcs_set_user_data
-hb_unicode_funcs_t
hb_unicode_general_category
-hb_unicode_general_category_func_t
-hb_unicode_general_category_t
+hb_unicode_combining_class
hb_unicode_mirroring
-hb_unicode_mirroring_func_t
hb_unicode_script
+hb_unicode_compose
+hb_unicode_decompose
+hb_unicode_funcs_create
+hb_unicode_funcs_get_empty
+hb_unicode_funcs_reference
+hb_unicode_funcs_destroy
+hb_unicode_funcs_set_user_data
+hb_unicode_funcs_get_user_data
+hb_unicode_funcs_make_immutable
+hb_unicode_funcs_is_immutable
+hb_unicode_funcs_get_default
+hb_unicode_funcs_get_parent
+hb_unicode_general_category_func_t
+hb_unicode_funcs_set_general_category_func
+hb_unicode_combining_class_func_t
+hb_unicode_funcs_set_combining_class_func
+hb_unicode_mirroring_func_t
+hb_unicode_funcs_set_mirroring_func
hb_unicode_script_func_t
+hb_unicode_funcs_set_script_func
+hb_unicode_compose_func_t
+hb_unicode_funcs_set_compose_func
+hb_unicode_decompose_func_t
+hb_unicode_funcs_set_decompose_func
+HB_UNICODE_MAX
+hb_unicode_combining_class_t
+hb_unicode_general_category_t
+hb_unicode_funcs_t
</SECTION>
<SECTION>
@@ -743,13 +746,13 @@
<SECTION>
<FILE>hb-version</FILE>
HB_VERSION_ATLEAST
+hb_version
+hb_version_atleast
+hb_version_string
HB_VERSION_MAJOR
HB_VERSION_MICRO
HB_VERSION_MINOR
HB_VERSION_STRING
-hb_version
-hb_version_atleast
-hb_version_string
</SECTION>
<SECTION>
@@ -760,20 +763,18 @@
<SECTION>
<FILE>hb-subset</FILE>
-hb_subset_flags_t
-hb_subset_input_t
-hb_subset_sets_t
-hb_subset_plan_t
hb_subset_input_create_or_fail
hb_subset_input_reference
hb_subset_input_destroy
hb_subset_input_set_user_data
hb_subset_input_get_user_data
-hb_subset_input_get_flags
hb_subset_input_set_flags
+hb_subset_input_get_flags
hb_subset_input_unicode_set
hb_subset_input_glyph_set
hb_subset_input_set
+hb_subset_input_pin_axis_location
+hb_subset_input_pin_axis_to_default
hb_subset_or_fail
hb_subset_plan_create_or_fail
hb_subset_plan_reference
@@ -784,11 +785,14 @@
hb_subset_plan_unicode_to_old_glyph_mapping
hb_subset_plan_new_to_old_glyph_mapping
hb_subset_plan_old_to_new_glyph_mapping
+hb_subset_preprocess
+hb_subset_flags_t
+hb_subset_input_t
+hb_subset_sets_t
+hb_subset_plan_t
<SUBSECTION Private>
hb_link_t
hb_object_t
hb_subset_repack_or_fail
-hb_subset_preprocess
-hb_subset_input_pin_axis_location
-hb_subset_input_pin_axis_to_default
+hb_subset_input_override_name_table
</SECTION>
diff --git a/docs/subset-preprocessing.md b/docs/subset-preprocessing.md
new file mode 100644
index 0000000..637da28
--- /dev/null
+++ b/docs/subset-preprocessing.md
@@ -0,0 +1,228 @@
+# Introduction
+
+Subset preprocessing is a mechanism which can significantly speed up font subsetting operations.
+It works by prepopulating datastructures from the source font which can be used in later subsetting
+operations to more quickly produce the subset. Preprocessing is useful in cases where multiple subsets
+will be cut from the same source font.
+
+# Usage
+
+```c++
+hb_face_t* preprocessed = hb_subset_preprocess (source_face);
+
+...
+
+hb_face_t* subset = hb_subset_or_fail (preprocessed, subset_input);
+```
+
+# Additional Details
+
+* A subset produced from a preprocessed face should be identical to a subset produced from only the
+ original face. The preprocessor does not change the functionality of the subsetter, just speeds
+ things up.
+
+* The preprocessing operation may take longer than the time it takes to produce a subset from the
+ source font. Thus the main performance gains are made when a preprocessed face is reused for
+ multiple subsetting operations.
+
+* Currently the largest performance gains are seen when using a preprocessed face for CFF subsetting.
+
+* The preprocessed face may contain references to the memory backing the source face. If this memory
+ is fully owned by a harfbuzz hb_blob_t* then it will automatically be kept alive for the lifetime
+ of the preprocessed face. However, if this memory is not fully owned by a harfbuzz hb_blob_t* then
+ it is necessary to ensure that the memory is kept alive for the lifetime of the preprocessed face.
+
+
+# Performance Improvements
+
+Here is the performance difference of producing a subset with a preprocessed face vs producing
+a subset with the source face:
+
+Benchmark | Delta Time (%)
+----------|-----------------
+BM_subset/subset_glyphs/Roboto-Regular.ttf/10_median|-56%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/64_median|-33%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/512_median|-28%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/1000_median|-11%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/nohinting/10_median|-56%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/nohinting/64_median|-33%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/nohinting/512_median|-21%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/nohinting/1000_median|-9%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/10_median|-67%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/64_median|-48%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/512_median|-21%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/4096_median|-9%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/nohinting/10_median|-66%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/nohinting/64_median|-50%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/nohinting/512_median|-8%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/nohinting/4096_median|-9%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/10_median|-85%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/64_median|-71%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/512_median|-3%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/1400_median|4%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/nohinting/10_median|-84%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/nohinting/64_median|-72%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/nohinting/512_median|0%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/nohinting/1400_median|0%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/10_median|-30%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/64_median|-24%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/512_median|-3%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/1000_median|-3%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/nohinting/10_median|-30%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/nohinting/64_median|-24%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/nohinting/512_median|-3%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/nohinting/1000_median|-5%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/10_median|-96%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/64_median|-90%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/512_median|-74%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/4096_median|-25%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/10000_median|-23%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/10_median|-95%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/64_median|-90%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/512_median|-73%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/4096_median|-24%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/10000_median|-11%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/10_median|-84%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/64_median|-77%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/512_median|-70%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/4096_median|-80%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/10000_median|-86%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/10_median|-84%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/64_median|-78%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/512_median|-71%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/4096_median|-86%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/10000_median|-88%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/10_median|-59%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/64_median|-55%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/512_median|-67%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/2000_median|-68%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/nohinting/10_median|-60%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/nohinting/64_median|-58%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/nohinting/512_median|-72%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/nohinting/2000_median|-71%
+BM_subset/subset_glyphs/AdobeVFPrototype.otf/10_median|-70%
+BM_subset/subset_glyphs/AdobeVFPrototype.otf/64_median|-64%
+BM_subset/subset_glyphs/AdobeVFPrototype.otf/300_median|-73%
+BM_subset/subset_glyphs/AdobeVFPrototype.otf/nohinting/10_median|-71%
+BM_subset/subset_glyphs/AdobeVFPrototype.otf/nohinting/64_median|-68%
+BM_subset/subset_glyphs/AdobeVFPrototype.otf/nohinting/300_median|-72%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/10_median|-90%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/64_median|-82%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/512_median|-31%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/4096_median|-9%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/6000_median|-22%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/10_median|-88%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/64_median|-83%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/512_median|-31%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/4096_median|-16%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/6000_median|-18%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/10_median|-44%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/64_median|-18%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/512_median|-2%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/900_median|-6%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/nohinting/10_median|-45%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/nohinting/64_median|-17%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/nohinting/512_median|-15%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/nohinting/900_median|-3%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/10_median|-20%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/64_median|-16%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/512_median|-12%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/1000_median|-10%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/10_median|-24%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/64_median|-14%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/512_median|-15%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/1000_median|-9%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/10_median|-51%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/64_median|-37%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/512_median|-12%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/4096_median|-1%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/10_median|-49%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/64_median|-35%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/512_median|-6%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/4096_median|-1%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/10_median|-82%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/64_median|-9%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/512_median|0%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/1400_median|0%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/10_median|-82%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/64_median|-13%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/512_median|-3%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/1400_median|2%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/10_median|-40%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/64_median|-26%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/512_median|-5%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/1000_median|3%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/10_median|-43%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/64_median|-24%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/512_median|-2%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/1000_median|2%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/10_median|-83%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/64_median|-67%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/512_median|-39%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/4096_median|-20%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/10000_median|-25%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/10_median|-83%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/64_median|-65%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/512_median|-42%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/4096_median|-34%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/10000_median|-21%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/10_median|-69%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/64_median|-69%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/512_median|-70%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/4096_median|-84%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/10000_median|-83%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/10_median|-71%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/64_median|-68%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/512_median|-70%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/4096_median|-86%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/10000_median|-88%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/10_median|-45%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/64_median|-48%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/512_median|-57%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/2000_median|-66%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/10_median|-43%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/64_median|-50%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/512_median|-63%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/2000_median|-72%
+BM_subset/subset_codepoints/AdobeVFPrototype.otf/10_median|-69%
+BM_subset/subset_codepoints/AdobeVFPrototype.otf/64_median|-66%
+BM_subset/subset_codepoints/AdobeVFPrototype.otf/300_median|-74%
+BM_subset/subset_codepoints/AdobeVFPrototype.otf/nohinting/10_median|-70%
+BM_subset/subset_codepoints/AdobeVFPrototype.otf/nohinting/64_median|-71%
+BM_subset/subset_codepoints/AdobeVFPrototype.otf/nohinting/300_median|-75%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/10_median|-66%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/64_median|-46%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/512_median|-15%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/4096_median|-5%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/6000_median|-16%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/10_median|-66%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/64_median|-45%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/512_median|-14%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/4096_median|-11%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/6000_median|-27%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/10_median|-38%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/64_median|-9%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/512_median|-3%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/900_median|-16%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/10_median|-39%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/64_median|-12%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/512_median|-4%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/900_median|-2%
+BM_subset/instance/MPLUS1-Variable.ttf/10_median|-68%
+BM_subset/instance/MPLUS1-Variable.ttf/64_median|-45%
+BM_subset/instance/MPLUS1-Variable.ttf/512_median|-18%
+BM_subset/instance/MPLUS1-Variable.ttf/4096_median|-2%
+BM_subset/instance/MPLUS1-Variable.ttf/6000_median|4%
+BM_subset/instance/MPLUS1-Variable.ttf/nohinting/10_median|-69%
+BM_subset/instance/MPLUS1-Variable.ttf/nohinting/64_median|-46%
+BM_subset/instance/MPLUS1-Variable.ttf/nohinting/512_median|-11%
+BM_subset/instance/MPLUS1-Variable.ttf/nohinting/4096_median|4%
+BM_subset/instance/MPLUS1-Variable.ttf/nohinting/6000_median|-5%
+BM_subset/instance/RobotoFlex-Variable.ttf/10_median|-34%
+BM_subset/instance/RobotoFlex-Variable.ttf/64_median|-12%
+BM_subset/instance/RobotoFlex-Variable.ttf/512_median|6%
+BM_subset/instance/RobotoFlex-Variable.ttf/900_median|-6%
+BM_subset/instance/RobotoFlex-Variable.ttf/nohinting/10_median|-33%
+BM_subset/instance/RobotoFlex-Variable.ttf/nohinting/64_median|-11%
+BM_subset/instance/RobotoFlex-Variable.ttf/nohinting/512_median|3%
+BM_subset/instance/RobotoFlex-Variable.ttf/nohinting/900_median|0%
diff --git a/generate_notice.py b/generate_notice.py
index 354dc3d..fab61cb 100644
--- a/generate_notice.py
+++ b/generate_notice.py
@@ -58,6 +58,7 @@
".codecov.yml",
".editorconfig",
".github/dependabot.yml",
+ ".github/workflows/arm-ci.yml",
".github/workflows/cifuzz.yml",
".github/workflows/configs-build.yml",
".github/workflows/coverity-scan.yml",
@@ -94,6 +95,7 @@
"docs/meson.build",
"docs/repacker.md",
"docs/serializer.md",
+ "docs/subset-preprocessing.md",
"docs/usermanual-buffers-language-script-and-direction.xml",
"docs/usermanual-clusters.xml",
"docs/usermanual-fonts-and-faces.xml",
@@ -175,6 +177,9 @@
"src/OT/glyf/GlyphHeader.hh",
"src/OT/glyf/SimpleGlyph.hh",
"src/OT/glyf/SubsetGlyph.hh",
+ "src/OT/glyf/VarCompositeGlyph.hh",
+ "src/OT/glyf/composite-iter.hh",
+ "src/OT/glyf/coord-setter.hh",
"src/OT/glyf/glyf-helpers.hh",
"src/OT/glyf/glyf.hh",
"src/OT/glyf/loca.hh",
@@ -231,6 +236,7 @@
"subprojects/google-benchmark.wrap",
"subprojects/packagefiles/ragel/meson.build",
"subprojects/ragel.wrap",
+ "subprojects/zlib.wrap",
"util/Makefile.am",
"util/Makefile.sources",
"util/meson.build",
diff --git a/meson.build b/meson.build
index b80679d..cc802f2 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
project('harfbuzz', 'c', 'cpp',
meson_version: '>= 0.55.0',
- version: '5.3.1',
+ version: '6.0.0',
default_options: [
'cpp_rtti=false', # Just to support msvc, we are passing -fno-exceptions also anyway
'cpp_std=c++11',
@@ -83,20 +83,35 @@
m_dep = cpp.find_library('m', required: false)
-
-# Try pkgconfig name
-freetype_dep = dependency('freetype2', required: false)
-if not freetype_dep.found()
- # Try cmake name
- freetype_dep = dependency('freetype', required: false)
-endif
-if not freetype_dep.found()
- # Subproject fallback, `allow_fallback: true` means the fallback will be
- # tried even if the freetype option is set to `auto`.
- freetype_dep = dependency('freetype2',
+if meson.version().version_compare('>=0.60.0')
+ # pkg-config: freetype2, cmake: Freetype
+ freetype_dep = dependency('freetype2', 'Freetype',
required: get_option('freetype'),
default_options: ['harfbuzz=disabled'],
allow_fallback: true)
+else
+ # painful hack to handle multiple dependencies but also respect options
+ freetype_opt = get_option('freetype')
+ # we want to handle enabled manually after fallbacks, but also handle disabled normally
+ if freetype_opt.enabled()
+ freetype_opt = false
+ endif
+ # try pkg-config name
+ freetype_dep = dependency('freetype2', method: 'pkg-config', required: freetype_opt)
+ # when disabled, leave it not-found
+ if not freetype_dep.found() and not get_option('freetype').disabled()
+ # Try cmake name
+ freetype_dep = dependency('Freetype', method: 'cmake', required: false)
+ # Subproject fallback, `allow_fallback: true` means the fallback will be
+ # tried even if the freetype option is set to `auto`.
+ if not freetype_dep.found()
+ freetype_dep = dependency('freetype2',
+ method: 'pkg-config',
+ required: get_option('freetype'),
+ default_options: ['harfbuzz=disabled'],
+ allow_fallback: true)
+ endif
+ endif
endif
glib_dep = dependency('glib-2.0', required: get_option('glib'))
@@ -104,18 +119,36 @@
graphite2_dep = dependency('graphite2', required: get_option('graphite2'))
graphite_dep = dependency('graphite2', required: get_option('graphite'))
-# Try pkgconfig name
-icu_dep = dependency('icu-uc', required: false)
-if not icu_dep.found()
- # Try cmake name
- icu_dep = dependency('ICU',
- required: false,
- components: 'uc',
- method: 'cmake')
-endif
-if not icu_dep.found()
- # Subproject fallback if icu option is enabled
- icu_dep = dependency('icu-uc', required: get_option('icu'))
+if meson.version().version_compare('>=0.60.0')
+ # pkg-config: icu-uc, cmake: ICU but with components
+ icu_dep = dependency('icu-uc', 'ICU',
+ components: 'uc',
+ required: get_option('icu'),
+ default_options: ['harfbuzz=disabled'],
+ allow_fallback: true)
+else
+ # painful hack to handle multiple dependencies but also respect options
+ icu_opt = get_option('icu')
+ # we want to handle enabled manually after fallbacks, but also handle disabled normally
+ if icu_opt.enabled()
+ icu_opt = false
+ endif
+ # try pkg-config name
+ icu_dep = dependency('icu-uc', method: 'pkg-config', required: icu_opt)
+ # when disabled, leave it not-found
+ if not icu_dep.found() and not get_option('icu').disabled()
+ # Try cmake name
+ icu_dep = dependency('ICU', method: 'cmake', components: 'uc', required: false)
+ # Try again with subproject fallback. `allow_fallback: true` means the
+ # fallback will be tried even if the icu option is set to `auto`, but
+ # we cannot pass this option until Meson 0.59.0, because no wrap file
+ # is checked into git.
+ if not icu_dep.found()
+ icu_dep = dependency('icu-uc',
+ method: 'pkg-config',
+ required: get_option('icu'))
+ endif
+ endif
endif
if icu_dep.found() and icu_dep.type_name() == 'pkgconfig'
@@ -148,7 +181,8 @@
# harfbuzz support disabled, so when cairo will lookup freetype2 dependency
# it will be forced to use that one.
cairo_dep = dependency('cairo', required: get_option('cairo'))
- cairo_ft_dep = dependency('cairo-ft', required: get_option('cairo'))
+ cairo_ft_required = get_option('cairo').enabled() and get_option('freetype').enabled()
+ cairo_ft_dep = dependency('cairo-ft', required: cairo_ft_required)
endif
endif
diff --git a/perf/benchmark-shape.cc b/perf/benchmark-shape.cc
index 626a597..f44b3e5 100644
--- a/perf/benchmark-shape.cc
+++ b/perf/benchmark-shape.cc
@@ -27,10 +27,18 @@
"perf/texts/fa-thelittleprince.txt",
false},
+ {"perf/fonts/NotoNastaliqUrdu-Regular.ttf",
+ "perf/texts/fa-words.txt",
+ false},
+
{"perf/fonts/Amiri-Regular.ttf",
"perf/texts/fa-thelittleprince.txt",
false},
+ {SUBSET_FONT_BASE_PATH "NotoSansDevanagari-Regular.ttf",
+ "perf/texts/hi-words.txt",
+ false},
+
{"perf/fonts/Roboto-Regular.ttf",
"perf/texts/en-thelittleprince.txt",
false},
diff --git a/perf/benchmark-subset.cc b/perf/benchmark-subset.cc
index 0451c11..9b51b79 100644
--- a/perf/benchmark-subset.cc
+++ b/perf/benchmark-subset.cc
@@ -54,18 +54,19 @@
struct test_input_t
{
const char *font_path;
- const unsigned max_subset_size;
+ unsigned max_subset_size;
const axis_location_t *instance_opts;
- const unsigned num_instance_opts;
-} tests[] =
+ unsigned num_instance_opts;
+} default_tests[] =
{
- {SUBSET_FONT_BASE_PATH "Roboto-Regular.ttf", 4000, nullptr, 0},
- {SUBSET_FONT_BASE_PATH "Amiri-Regular.ttf", 4000, nullptr, 0},
- {SUBSET_FONT_BASE_PATH "NotoNastaliqUrdu-Regular.ttf", 1000, nullptr, 0},
+ {SUBSET_FONT_BASE_PATH "Roboto-Regular.ttf", 1000, nullptr, 0},
+ {SUBSET_FONT_BASE_PATH "Amiri-Regular.ttf", 4096, nullptr, 0},
+ {SUBSET_FONT_BASE_PATH "NotoNastaliqUrdu-Regular.ttf", 1400, nullptr, 0},
{SUBSET_FONT_BASE_PATH "NotoSansDevanagari-Regular.ttf", 1000, nullptr, 0},
{SUBSET_FONT_BASE_PATH "Mplus1p-Regular.ttf", 10000, nullptr, 0},
{SUBSET_FONT_BASE_PATH "SourceHanSans-Regular_subset.otf", 10000, nullptr, 0},
{SUBSET_FONT_BASE_PATH "SourceSansPro-Regular.otf", 2000, nullptr, 0},
+ {SUBSET_FONT_BASE_PATH "AdobeVFPrototype.otf", 300, nullptr, 0},
{SUBSET_FONT_BASE_PATH "MPLUS1-Variable.ttf", 6000, _mplus_instance_opts, ARRAY_LEN (_mplus_instance_opts)},
{SUBSET_FONT_BASE_PATH "RobotoFlex-Variable.ttf", 900, _roboto_flex_instance_opts, ARRAY_LEN (_roboto_flex_instance_opts)},
#if 0
@@ -73,6 +74,10 @@
#endif
};
+static test_input_t *tests = default_tests;
+static unsigned num_tests = sizeof (default_tests) / sizeof (default_tests[0]);
+
+
void AddCodepoints(const hb_set_t* codepoints_in_font,
unsigned subset_size,
hb_subset_input_t* input)
@@ -101,23 +106,25 @@
// the subsetting operations.
static hb_face_t* preprocess_face(hb_face_t* face)
{
- #ifdef HB_EXPERIMENTAL_API
hb_face_t* new_face = hb_subset_preprocess(face);
hb_face_destroy(face);
return new_face;
- #else
- return face;
- #endif
}
/* benchmark for subsetting a font */
static void BM_subset (benchmark::State &state,
operation_t operation,
- const test_input_t &test_input)
+ const test_input_t &test_input,
+ bool hinting)
{
unsigned subset_size = state.range(0);
- hb_face_t *face;
+ hb_face_t *face = nullptr;
+
+ static hb_face_t *cached_face;
+ static const char *cached_font_path;
+
+ if (!cached_font_path || strcmp (cached_font_path, test_input.font_path))
{
hb_blob_t *blob = hb_blob_create_from_file_or_fail (test_input.font_path);
assert (blob);
@@ -125,11 +132,22 @@
hb_blob_destroy (blob);
face = preprocess_face (face);
+
+ if (cached_face)
+ hb_face_destroy (cached_face);
+
+ cached_face = hb_face_reference (face);
+ cached_font_path = test_input.font_path;
}
+ else
+ face = hb_face_reference (cached_face);
hb_subset_input_t* input = hb_subset_input_create_or_fail ();
assert (input);
+ if (!hinting)
+ hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_NO_HINTING);
+
switch (operation)
{
case subset_codepoints:
@@ -149,7 +167,6 @@
break;
case instance:
-#ifdef HB_EXPERIMENTAL_API
{
hb_set_t* all_codepoints = hb_set_create ();
hb_face_collect_unicodes (face, all_codepoints);
@@ -161,7 +178,6 @@
test_input.instance_opts[i].axis_tag,
test_input.instance_opts[i].axis_value);
}
-#endif
break;
}
@@ -178,6 +194,7 @@
static void test_subset (operation_t op,
const char *op_name,
+ bool hinting,
benchmark::TimeUnit time_unit,
const test_input_t &test_input)
{
@@ -186,36 +203,57 @@
char name[1024] = "BM_subset/";
strcat (name, op_name);
- strcat (name, strrchr (test_input.font_path, '/'));
+ strcat (name, "/");
+ const char *p = strrchr (test_input.font_path, '/');
+ strcat (name, p ? p + 1 : test_input.font_path);
+ if (!hinting)
+ strcat (name, "/nohinting");
- benchmark::RegisterBenchmark (name, BM_subset, op, test_input)
+ benchmark::RegisterBenchmark (name, BM_subset, op, test_input, hinting)
->Range(10, test_input.max_subset_size)
->Unit(time_unit);
}
static void test_operation (operation_t op,
const char *op_name,
+ const test_input_t *tests,
+ unsigned num_tests,
benchmark::TimeUnit time_unit)
{
- for (auto& test_input : tests)
+ for (unsigned i = 0; i < num_tests; i++)
{
- test_subset (op, op_name, time_unit, test_input);
+ auto& test_input = tests[i];
+ test_subset (op, op_name, true, time_unit, test_input);
+ test_subset (op, op_name, false, time_unit, test_input);
}
}
int main(int argc, char** argv)
{
-#define TEST_OPERATION(op, time_unit) test_operation (op, #op, time_unit)
+ benchmark::Initialize(&argc, argv);
+
+ if (argc > 1)
+ {
+ num_tests = (argc - 1) / 2;
+ tests = (test_input_t *) calloc (num_tests, sizeof (test_input_t));
+ for (unsigned i = 0; i < num_tests; i++)
+ {
+ tests[i].font_path = argv[1 + i * 2];
+ tests[i].max_subset_size = atoi (argv[2 + i * 2]);
+ }
+ }
+
+#define TEST_OPERATION(op, time_unit) test_operation (op, #op, tests, num_tests, time_unit)
TEST_OPERATION (subset_glyphs, benchmark::kMillisecond);
TEST_OPERATION (subset_codepoints, benchmark::kMillisecond);
-#ifdef HB_EXPERIMENTAL_API
TEST_OPERATION (instance, benchmark::kMillisecond);
-#endif
#undef TEST_OPERATION
- benchmark::Initialize(&argc, argv);
benchmark::RunSpecifiedBenchmarks();
benchmark::Shutdown();
+
+ if (tests != default_tests)
+ free (tests);
}
diff --git a/perf/run.sh b/perf/run.sh
deleted file mode 100755
index c7dc6e0..0000000
--- a/perf/run.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-CXX=clang++
-FONT=fonts/NotoNastaliqUrdu-Regular.ttf
-TEXT=texts/fa-monologue.txt
-
-$CXX ../util/hb-shape.cc ../util/options.cc ../src/harfbuzz.cc \
- -lm -fno-rtti -fno-exceptions -fno-omit-frame-pointer -DHB_NO_MT \
- -I../src $FLAGS $SOURCES \
- -DPACKAGE_NAME='""' -DPACKAGE_VERSION='""' \
- -DHAVE_GLIB $(pkg-config --cflags --libs glib-2.0) \
- -o hb-shape -g -O2 # -O3 \
- #-march=native -mtune=native \
- #-Rpass=loop-vectorize -Rpass-missed=loop-vectorize \
- #-Rpass-analysis=loop-vectorize -fsave-optimization-record
-
-# -march=native: enable all vector instructions current CPU can offer
-# -Rpass*: https://llvm.org/docs/Vectorizers.html#diagnostics
-
-#sudo rm capture.syscap > /dev/null
-#sysprof-cli -c "./a.out $@"
-#sysprof capture.syscap
-
-perf stat ./hb-shape -o /dev/null $FONT --text-file $TEXT --num-iterations=100 --font-funcs=ot
-#perf record -g ./hb-shape -O '' -o /dev/null $FONT --text-file $TEXT --num-iterations=100 --font-funcs=ot
-#perf report -g
diff --git a/perf/texts/fa-words.txt b/perf/texts/fa-words.txt
new file mode 100644
index 0000000..4937544
--- /dev/null
+++ b/perf/texts/fa-words.txt
@@ -0,0 +1,10000 @@
+و
+در
+به
+از
+ویکیپدیا
+که
+را
+این
+با
+است
+رده
+برای
+کاربر
+،
+بحث
+تصویر
+میلادی
+ایران
+تاریخ
+نام
+پرونده
+آن
+یک
+ساعت
+صفحهٔ
+کنید
+پیوند
+مقاله
+صفحه
+شما
+اصلی
+عنوان
+یا
+تا
+سال
+هم
+من
+استفاده
+بر
+خود
+شده
+شد
+تغییرمسیر
+شهرستان
+کار
+راهنمای
+اگر
+تکثیر
+چه
+ویرایش
+حق
+مقالههای
+می
+فارسی
+نیست
+دیگر
+نوشتن
+پنج
+بود
+زبان
+سیارک
+امضا
+کمک
+شیوهنامه
+منابع
+ملی
+ثبت
+آثار
+پانویس
+۱۱
+میز
+خودآموز
+بخش
+دارد
+خرد
+انگلیسی
+او
+لطفاً
+نیز
+۱۵
+شماره
+پهنا
+بنیاد
+استان
+هر
+اثر
+میشود
+مورد
+کرد
+یادکرد
+امیدوارم
+راهنما
+کنیم
+خوش
+۱
+ویکی
+چیزی
+پس
+۰
+۲
+شهر
+پیش
+فهرست
+مرجع
+خط
+آمدید
+اطلاعات
+اینجا
+تاریخی
+زیر
+منبع
+جعبه
+جدید
+دوره
+بیشتر
+اینکه
+بهتر
+یکی
+شود
+دو
+سپتامبر
+راهنمایی
+پیوندهای
+۵
+حذف
+۲۰۰۰
+خوب
+۳
+نظر
+آزاد
+قرار
+خواهد
+تمرین
+باشد
+بله
+پیرامون
+سلام
+آموزش
+۴
+اصل
+۱۰
+نه
+صفحات
+۱۹
+۱۲
+۲۰۱۱،
+های
+پاس
+ولی
+توسط
+چگونه
+برگزیده
+بداریم
+فقط
+ویکیپروژه
+۲۰۰۱
+روی
+سریع
+اکتبر
+صورت
+دست
+قهوهخانه
+۱۴
+دانشگاه
+بنیادی
+اما
+بیاید
+ناشر
+داشتید،
+باید
+بروید
+الگو
+چهار
+اول
+مارس
+کتاب
+ایجاد
+بازدید
+توجه
+آنها
+پایه
+۲۰
+کشور
+ساختار
+سخ
+خوشآمدید
+مقالهٔ
+شدهاست
+سازمان
+فارسینویسی
+بودن
+مرکزی
+باز
+آمریکا
+وب
+ب
+۱۶
+نویسنده
+کادر
+دسامبر
+صورتی
+۲۰۰۷
+۱۸
+۲۰۱۰،
+کند
+فنی
+تصمیم
+۱۳
+تهران
+وجود
+۱۷
+نشانی
+چطور
+چند
+کشف
+اوت
+دانشنامهای
+فوتبال
+علمی
+۲۰۰۸،
+درج
+۲۰۰۲
+هستند
+بگیرید
+۲۱
+۲۰۱۱
+نوامبر
+مطالب
+آزمایش
+وی
+کاربران
+فیلم
+ها
+ماندن
+مقالات
+بپرسید
+حروف
+لذت
+جمعیت
+بحثم
+۶
+ببرید
+خوشتان
+۸
+مدک
+وابسته
+ویکیپدیانویس
+ویکیپدیانویسان
+۷
+۲۰۰۹،
+اسلام
+۲۲
+ی
+مسایل
+آوریل
+بنویسیم
+۱۹۹۹
+کاربری
+علامت
+واقع
+شوید
+اهمیت
+۲۳
+کلاس
+کردن
+ای
+آشنا
+باشید
+نگاهی
+کوچک
+نکنید
+وبگاه
+پروژههای
+کرده
+۲۸
+میتوانید
+انتخاب
+۹
+مکنید
+بعد
+روز
+است،
+جستارهای
+شدن
+نوع
+نمونههای
+۲۴
+نفر
+دارید،
+بیندازید
+خودکار
+۲۰۰۶
+نوشته
+مطالعهٔ
+انبار
+عجله
+غفلت
+فهرستشده
+مشارکت
+اهل
+۲۵
+سوال
+محمد
+بوده
+۳۰
+بسیار
+بزرگ
+میراث
+میان
+زمان
+منابعی
+اثباتپذیری
+جلالی
+سیارکهای
+دهستان
+مرکز
+انجام
+فوریه
+میکند
+۲۶
+نامهای
+ما
+یعنی
+ایرانی
+ژوئن
+غیر
+پایان
+یونسکو
+حال
+پرحجم
+چپ
+میگویم
+داشته
+جمله
+پیام
+عمومی
+گردشگری
+قبل
+همین
+همچنین
+همان
+مالک
+سپاسگزارم
+سالهای
+همه
+اندازه
+مربوط
+ویکیانبار
+قدر
+چون
+بیرون
+ویکینویسی
+داده
+کسب
+دوم
+ویژه
+هیچ
+فرهنگ
+کسی
+بروید،
+تنها
+۲۰۰۳
+دارای
+ساخت
+افراد
+رتب
+تازهواردان،
+مه
+محلی
+بصب
+بین
+پتوپ
+مقالهها
+نیازمند
+اسلامی
+۲۷
+بی
+مرگ
+علی
+۲۰۰۵
+متون
+مطلق
+سه
+میباشد
+نیاز
+شرکت
+۲۹
+۲۰۰۹
+باشگاه
+دلیل
+زندگی
+چاپ
+موجود
+۲۰۰۸
+نقل
+گروه
+۲۰۰۴
+انتهای
+دارند
+محتویات
+شاد
+موضوعات
+جستجوی
+۱۹۹۸
+مردم
+نشان
+موسیقی
+ویکیمدیا
+همراه
+ویکیگفتاورد
+تپه
+شورای
+دانشنامه
+ویکیواژه
+بدون
+مانند
+راه
+شهرهای
+فرهنگی
+سیاره
+ویکینبشته
+ترجمه
+فراویکی
+حجم
+کنونی
+طبق
+ژانویهٔ
+بار
+اجرام
+روستای
+ویکینَسک
+تغییر
+خوشامد
+سرعت
+۲۰۱۲،
+جنگ
+برابر
+محل
+سر
+سپس
+سیارکها
+عربی
+بازیابی
+داشت
+بازی
+ماه
+میتواند
+رو
+کنید،
+ژانویه
+معرفی
+بنا
+مشترک
+چندین
+دوران
+ندارد
+جهان
+حقوق
+کنم
+بالا
+ضمن
+داد
+وبگاه
+البته
+آب
+قدیمی
+امکان
+جمهوری
+قسمت
+۰۹
+مفیدند
+پیدا
+وپ
+پروژه
+بن
+همکاری
+۰۸
+تغییرات
+كه
+منطقه
+معماری
+چموخم
+معرفیشده
+کنند
+هزار
+عرضجغرافیایی
+طولجغرافیایی
+۰۷
+روینقشه
+برخی
+آیپی
+آمار
+ویکیپدیای
+۲۰۱۰
+جای
+موضوع
+تمام
+گرفته
+شرقی
+فوریهٔ
+اخیر
+قمری
+متوسط
+دیگری
+غربی
+درگاه
+ربات
+راستی
+اولین
+۳۱
+باستانی
+امنیت
+چنین
+آلمان
+کم
+رسمی
+جهانی
+مطالعه
+بررسی
+ژوئیه
+فعالیت
+آغاز
+آذربایجان
+فکر
+اين
+الگوی
+تیم
+لطفا
+ژوئیهٔ
+صنایع
+درود
+نامه
+تلفن
+اقدام
+روستا
+ایشان
+میکنند
+فارس
+حتی
+تعداد
+دربارهٔ
+فعلی
+درست
+مدیران
+گفتگو
+حجت
+دستی
+ستاره
+بسیاری
+اند
+نقش
+کلیک
+بودند
+۰۶
+تولد
+کردم
+زادگان
+شاه
+متحده
+توضیح
+طول
+دوست
+ذکر
+رسیده
+مقالهای
+قابل
+ا
+اضافه
+مسائل
+ایالات
+همهٔ
+اینترنتی
+نامگذاری
+سیاسی
+طور
+خیلی
+رضا
+روستاهای
+چپچین
+تولید
+م
+صفحههای
+ص
+برچسب
+خانه
+شکل
+دولت
+میتوان
+شامل
+مینویسید
+یادتان
+موسسه
+جنوب
+نرود
+نشریه
+باشند
+۰۰
+آمد
+وارد
+ه
+فرانسه
+جوایز
+مجموعه
+قانون
+بهعنوان
+متن
+د
+۰۵
+جایزه
+خبری
+سید
+ویکیخبر
+گفته
+اساس
+سیاستهای
+جنوبی
+سایت
+آری
+ممکن
+نمی
+بنویسید
+روسیه
+فیلمهای
+مهٔ
+سوم
+تشکر
+جام
+۱۳۸۵
+حدود
+کامل
+عرض
+شمارهٔ
+قاجار
+ماني
+عکس
+اجازه
+تصحیح
+آرش
+علوم
+نظری
+جایهای
+اشاره
+دانشنامهٔ
+گرفت
+کردند
+جان
+فرهنگی،
+مختلف
+بانی
+توضیحات
+ارتفاع
+موارد
+میلاد
+مثل
+مرمت
+ژورنال
+شعر
+محتوای
+بیش
+چرا
+شمال
+خواهر
+میکنم
+خم
+فصل
+شروع
+تشکیل
+چم
+سرشماری
+دهه
+مشکل
+ساخته
+زبانها
+گونههای
+مدت
+مجموعهای
+زیادی
+بهترین
+درباره
+موافق
+دیرینگی
+نتیجه
+هست
+آلبوم
+ادامه
+جهت
+خراسان
+شرح
+ایرانشهر
+زیستی
+پیشرفته
+میدهد
+راهنماهای
+صفحهی
+افغانستان
+هماهنگی
+قلعه
+اصفهان
+بالای
+جغرافیایی
+شخصی
+نسبت
+میشوند
+تصنيف
+مطرح
+عناوین
+بودهاست
+۰۱
+۱۳۸۶
+زمین
+سازی
+حزب
+سی
+آنها
+سرشناسی
+انقلاب
+مي
+واژهها
+مهم
+سایر
+میآید،
+دکتر
+مساحت
+قطعنامه
+۰۴
+شدند
+مرد
+درگذشتگان
+پروندههای
+باعث
+نکاتی
+اعلام
+نامگذاری
+پروژهای
+زبانه
+سیستم
+انتفاعی
+یادداشتی
+کتابچه
+پرسیدن
+۰۳
+چندرسانهای
+قولها
+هرکسی،
+ویکیگونه
+خوانندگانش
+کیلومتر
+سطح
+زمینه
+اهالی
+ر
+سؤال،
+حسین
+اصطلاحنامه
+موقت
+سندباد
+بود،
+تبدیل
+سبک
+بنویسیم؟
+روش
+میثم
+زمانی
+۱۳۸۷
+دسترسی
+کد
+انگلستان
+برنامه
+رنگ
+تحت
+هاروارد
+ن
+مدیر
+امیروبات
+جرم
+جلد
+وقتی
+گودال
+نگاره
+شمالی
+۰۲
+پاسخ
+آیا
+تر
+منتشر
+شوند
+انتشارات
+مخالف
+مسجد
+بایگانی
+هماهنگکننده
+کپی
+متر
+مجلس
+۴۰
+دهید
+شاید
+آنجا
+گل
+کاربرهای
+ناسا
+دوستان
+جناب
+پیشنهاد
+ان
+دی
+یافت
+آسمانی
+۱۳۸۸
+هنوز
+نخستین
+مذهب
+نویسندگان
+زنده
+ایالت
+ماسهبازی
+احمد
+آنهاست
+کنار
+شبکه
+بازیهای
+مشخص
+ژاپن
+نمود
+وقت
+کشورهای
+خواندن
+معروف
+اروپا
+اشتباه
+کرمان
+سن
+معرف
+پهلوی
+درجه
+سوی
+ام
+محیط
+بحثتان
+روزنامه
+گونه
+۱۹۹۷
+طرف
+کل
+داستان
+علت
+الگوهای
+آمریکایی
+تو
+آمده
+بینالمللی
+داتک
+امیر
+انتشار
+قوانین
+شمارهدار
+دادگان
+موفق
+رشته
+خاطر
+دارم
+خورشیدی
+حسن
+معنی
+ک
+زنان
+انتقال
+پی
+حکومت
+لازم
+بهآفرید
+تپههای
+نامصفحه
+شابک
+زن
+قرن
+دهد
+عمل
+بازیگر
+تصاویر
+رئیس
+ممنون
+عزیز
+یاد
+گفت
+هفته
+دین
+رای
+وضعیت
+فرار
+درخواست
+سیاست
+سمت
+حالت
+پسر
+کوه
+پرچم
+طی
+ادبیات
+الله
+کلی
+کشفشده
+بازیابیشده
+غرب
+فرودگاه
+۱۳۹۰
+سپاس
+واژه
+توابع
+ابعاد
+کمربند
+دور
+مدرک
+مبدا
+مازندران
+کننده
+مدیریت
+دوستدار
+وجه
+مهدی
+نمایش
+هجری
+هنر
+ابتدا
+ده
+رسید
+اعضای
+انسان
+امام
+مثال
+دادن
+آخرین
+اسرائیل
+قول
+نمایید
+حضور
+رود
+خودتان
+زیاد
+جا
+توصیه
+مناطق
+عراق
+مطلب
+پرسش
+خان
+عضو
+حسام
+حداقل
+باستان
+ارائه
+۵۰
+مواد
+کمی
+خارج
+دما
+چین
+وزارت
+اوج
+خروج
+طبیعی
+پزشکی
+ستارهشناسی
+فراموش
+پایین
+کاری
+اکنون
+بعضی
+میانگین
+نشده
+هزاره
+نشر
+مهندسی
+شد،
+آباد
+خودم
+اسپانیا
+خاص
+دورانهای
+۱۳۸۹
+جریان
+منظور
+طریق
+ترتیب
+بناهای
+بیان
+دارید
+روستایی
+سطحی
+شیخ
+نسخه
+حرکت
+بنده
+سده
+اجتماعی
+طراحی
+حرف
+خودروهای
+ویکیگزارش
+نو
+هند
+استاد
+بهشما
+دوباره
+توان
+نظامی
+بلکه
+سری
+همسر
+هنری
+شیراز
+مفیدی
+جمع
+علم
+خانواده
+انتخابات
+آلمانی
+فاصله
+نیروی
+مرتبط
+نمونه
+پدیا
+فرمایید؛
+شناخته
+چگالی
+دیده
+معتبر
+مناسب
+قرآن
+میلیون
+واحد
+۴۵
+مهر
+تبریز
+هنگام
+گسترش
+طبقهبندی
+۱۹۹۶
+فلسفه
+کرمانشاه
+گردید
+گذشته
+دنیا
+زیرا
+قدرت
+مثلا
+ببینید
+لیگ
+دریافت
+انحراف
+نامرسمی
+میآید
+حمله
+گرانش
+توسعه
+افزایش
+چشم
+مکان
+عدد
+ابهامزدایی
+دانش
+موضوعی
+نزدیک
+شخص
+آنان
+دیگران
+بازیکنان
+آقای
+کاشف
+تلویزیونی
+زاده
+بسته
+جایی
+خدا
+حاضر
+شرق
+میشد
+حساب
+پدر
+داشتید
+نقض
+پیششماره
+ایتالیا
+کاربرد
+سعی
+رفت
+برد
+بودن
+کاربردها
+تناوب
+۳۵
+معمولاً
+زبانهای
+بهمن
+۳۲
+عباس
+حضیض
+پدیدآور
+انجمن
+فیزیک
+نگاه
+فعال
+نور
+نسخهها
+ریاست
+هستم
+فلکی
+فرد
+مسیر
+اجازهنامه
+جامعه
+آلبدو
+مصر
+آنومالی
+کلمه
+نیممحور
+بریتانیا
+۱۹۹۵
+پر
+پاک
+ت
+۱۹۹۳
+بازیگران
+بخشی
+فرانسوی
+داخلی
+خبر
+سئوال
+محمود
+باشد،
+امروز
+کردهاست
+ارتباط
+درصد
+؟
+تاریخچه
+ملل
+اصلاح
+معیارهای
+همچون
+؛
+طرح
+شدهاند
+هدف
+عالی
+وقایع
+میدان
+محسوب
+حل
+باغ
+استانهای
+خودش
+قطع
+ایران،
+۳۳
+۳۴
+اش
+دنبال
+شهری
+تعریف
+دانشکده
+انواع
+دار
+ورزشگاه
+نقشه
+کوتاه
+شمار
+ق
+مدرسه
+کمتر
+آرامگاه
+عصر
+عبارت
+بیست
+تن
+خرابکاری
+المپیک
+تیر
+میرود
+خیابان
+بازار
+نامزد
+میرزا
+داخل
+اندازهتصویر
+پایگاه
+رضوی
+سؤال
+۱۹۹۰
+الان
+گرامی
+نبود
+خوبی
+۳۷
+خارجی
+گیری
+آورد
+برچسبتصویر
+۴۸
+سیستان
+۱۹۹۴
+آزادی
+رشد
+نباید
+پرسشی
+۱۳۸۴
+حد
+۳۶
+ملیت
+رشدجمعیت
+تازه
+میانگیندما
+عدم
+نیروهای
+تراکمجمعیت
+سؤالی
+نامهایقدیمی
+بنابراین
+ارتش
+شب
+داشتن
+علاوه
+ابن
+شمارروزهاییخبندان
+میانگینبارشسالانه
+پل
+تصویب
+میانه
+خرداد
+گیلان
+سنگ
+کنترل
+بهزاد
+کیفیت
+مینویسید
+۴۱
+درگذشت
+علیه
+گزارش
+شیعه
+خور
+۳۸
+جزیره
+رهآورد
+دسترس
+دستگاه
+ناممحلی
+تگزاس
+جز
+همیشه
+۴۲
+اجرا
+کوشش
+پخش
+رد
+۴۶
+متحد
+اسفند
+وزیر
+خواننده
+بهبود
+اثبات
+سفید
+نظرخواهی
+شرایط
+جملهخوشامد
+ترکیه
+۴۴
+همدان
+قم
+۳۹
+میگیرد
+۴۳
+بلوچستان
+چیز
+دسته
+خوزستان
+گنو
+ترانه
+کدام
+خودرو
+۵۵
+۴۷
+باقی
+بندی
+۵۱
+بخوانید
+۱۹۹۲
+خواهند
+صد
+ناحیه
+۵۳
+کاهش
+۱۹۹۱
+میشود
+مذهبی
+۴۹
+ساختمان
+اولیه
+مقابل
+۵۲
+سبز
+وحید
+۵۷
+مشهور
+متوجه
+تهیه
+کافی
+آنچه
+ترک
+افزودن
+میشود،
+جدا
+۱۳۸۲
+چهارم
+تقسیم
+نژاد
+معنای
+کشاورزی
+صفوی
+براساس
+سیاه
+هایی
+آسیا
+تمامی
+تحقیق
+۱۹۶۰
+ساسانیان
+نوشتار
+رادیو
+۵۶
+۵۴
+اسم
+ارزش
+دهانه
+اقتصادی
+ابراهیم
+نخست
+فرزندان
+۵۹
+هاي
+شهرها
+دقیقه
+حالا
+دستور
+امور
+رابطه
+پارک
+جنبش
+دختر
+ج
+قالب
+بیماری
+نامهایدیگر
+محوطه
+بازیکن
+کشته
+دارد،
+مشهد
+منتقل
+شهریور
+مرداد
+کیلومتری
+پرداخت
+۵۸
+تخصصی
+۲۰۱۲
+مرده
+دهیار
+صنعتی
+ش
+خدمت
+پشت
+فشار
+میکرد
+تلاش
+مدیاویکی
+تلویزیون
+میزان
+سالبنیاد
+قبلی
+انرژی
+بدست
+نظام
+حوزه
+پا
+بودم
+یزد
+پ
+هفت
+ازدواج
+است؟
+فضای
+نظریه
+اختلاف
+حمایت
+خواهم
+مجله
+رفته
+اجرای
+میگردد
+برتر
+متولد
+کره
+خاک
+برگزار
+سرزمین
+بدن
+کردهاید
+مسابقات
+اقتصاد
+ندارم
+بعدی
+قبول
+خلیج
+آخر
+کمیته
+فروردین
+مادر
+کارگردان
+میکنید
+سالها
+کسانی
+مصرف
+جدول
+جشنواره
+آنرا
+دید
+فرزند
+عرب
+کاملا
+آمل
+پادشاه
+دیدگاه
+آذر
+اشکانیان
+سفر
+متفاوت
+وزن
+نیویورک
+داشتند
+بیشتری
+موزه
+یه
+میرسد
+خاصی
+دل
+دهستانهای
+آنکه
+استقلال
+پنهان
+مجوز
+نوعی
+کردید
+لرستان
+جغرافیا
+ترکی
+محسن
+هوایی
+۱۹۸۱
+فروش
+مقام
+مقدار
+۱۶۱۵
+قزوین
+حالی
+عمر
+لزوم
+میل
+آبی
+دقت
+اصلا
+اطلاع
+رخ
+شکست
+اعمال
+اینترنت
+موتور
+دومین
+شهید
+تحقیقات
+تاسیس
+برخورد
+روم
+ماده
+محله
+لینک
+راست
+امروزه
+کردهاند
+بازگشت
+جواب
+پارس
+یونان
+رتبه
+ز
+شده،
+۱۳۸۱
+اساسی
+نقطه
+گردد
+موجب
+سخن
+تقویم
+نکته
+میدهند
+مستقل
+جامع
+اردیبهشت
+هستید
+سینما
+مدل
+کانادا
+گاه
+آورده
+حفظ
+ثابت
+ـ
+احترام
+بوشهر
+مربع
+۱۹۸۸
+روابط
+سیمرغ
+درون
+زیرنویس
+کن
+نظرم
+ترکیب
+بهار
+بد
+پادشاهی
+دلار
+شیمی
+تعیین
+بابل
+نفت
+دولتی
+مدتی
+نظرات
+درستش
+کاتالوگ
+گاهشماری
+لحاظ
+ساده
+بخشهای
+شوروی
+باب
+بیبیسی
+گرفتن
+دادم
+مثلاً
+گروههای
+ندارند
+کردستان
+حاصل
+شود،
+انسانی
+گرم
+روشن
+مسکن
+خون
+۱۳۸۰
+رسیدگی
+مفهوم
+خمینی
+گیاهان
+ساز
+آهنگ
+ترین
+هرمزگان
+۱۹۸۹
+صاحب
+کارهای
+اغلب
+عبدالله
+مشغول
+۱۰۰
+شناسی
+محمديان
+گفتم
+مختصات
+دهند
+یونانی
+رایانهای
+یکم
+ستارگان
+کتابهای
+ایرانیان
+آوردن
+صنعت
+کند،
+صحبت
+فناوری
+نمیشود
+آینده
+واگردانی
+کتابخانه
+برجسته
+امر
+نقد
+مخصوص
+بزرگی
+آبان
+نتایج
+براي
+یافته
+لقب
+متاسفانه
+مالکیت
+مشاهده
+عرضه
+کارت
+گاهی
+شش
+دفاع
+مایکل
+اداره
+خبرگزاری
+دره
+مسئله
+صحیح
+ولایت
+گروهی
+رودخانه
+مقدس
+مراسم
+کشورها
+باد
+تاکنون
+خلاف
+علاقه
+ارومیه
+مرحله
+ورود
+۲۰۰۷،
+تکمیل
+موقعیت
+رویدادها
+تفاوت
+ایستگاه
+شیمیایی
+مگر
+ضد
+ژاپنی
+استاندارد
+دریای
+۱۹۸۰
+معاصر
+زندان
+غیرقابل
+عملیات
+دریایی
+خصوص
+برخوردار
+لندن
+شیوه
+آقا
+مشابه
+سخت
+خلاصه
+دفتر
+برنده
+سنت
+پاپ
+جلوگیری
+قدیم
+ورودی
+اسکار
+بطور
+چر
+بندر
+مرا
+راک
+نیشابور
+نیستند
+۱۵۱
+مشکلی
+آتش
+کشوری
+تابستانی
+امپراتوری
+بررسیهای
+آن،
+اس
+میکنم
+پارسی
+تشخیص
+شاعر
+خدمات
+س
+عهده
+نیمه
+مشکلات
+نیست،
+آشنایی
+بصورت
+تأسیس
+درمان
+ابزار
+آموزشی
+نوروز
+بروجرد
+تواند
+قتل
+تحصیل
+دیدم
+مدرس
+دانشگاههای
+جمهور
+محدود
+برج
+آبشار
+دانشجویان
+احتمال
+رفتار
+اعتماد
+اطراف
+هشدار
+همواره
+قطعنامههای
+محمدرضا
+پاریس
+ساله
+کالیفرنیا
+وسیله
+اصول
+درخت
+سالگی
+۱۹۷۷
+پیشه
+داریم
+شخصیت
+قصد
+نداشته
+میگوید
+جشن
+ویرایشهای
+ادبی
+بهره
+سنتی
+فوق
+کنید؛
+تام
+آ
+بانک
+دهم
+استرالیا
+دقیق
+نامیده
+نفوس
+فراهم
+میتوانند
+بدین
+اختیار
+چشمه
+دادند
+يا
+اردبیل
+پست
+خانوار
+قهرمانی
+منصور
+سرخ
+روسی
+۱۳۸۳
+شبیه
+بشر
+قرمز
+قطر
+سبب
+کشتی
+برده
+صدا
+یکسان
+شمسی
+مجدد
+اکثر
+جالب
+تک
+گلستان
+پنجم
+فراوان
+يك
+نرمافزار
+توهین
+اتحادیه
+عشق
+ظهیری
+گورستان
+بلژیک
+بکار
+رستم
+سرشناس
+ها
+هیئت
+علیا
+مقالاتی
+رباتیکی
+هنگامی
+لطف
+بختیاری
+روح
+ارجاع
+تقریبا
+۱۹۷۳
+ع
+سپاه
+های
+یکدیگر
+نموده
+رمان
+کرد،
+جنسی
+بزرگترین
+پیشرفت
+دعوت
+بقیه
+کلمات
+شهرت
+مرکزی،
+رایانه
+یمن
+تخت
+معادل
+صادق
+وسط
+خوانندگان
+تلفظ
+اتفاق
+امامزاده
+تحصیلات
+خانوادگی
+حقیقت
+خورشید
+نوری
+نقاط
+پایتخت
+بند
+گوگل
+مانده
+نزدیکی
+سعید
+امید
+نشود
+نر
+مسعود
+سلطان
+ادغام
+سفلی
+دریا
+لاتین
+اجماع
+خوانده
+سابق
+ریاضی
+درستی
+فضایی
+دلایل
+برندگان
+بعدها
+متعلق
+پیشین
+شدم
+هنرمند
+درس
+ذخیره
+کارگردانی
+نباشد
+دانقولا
+اون
+تابع
+مالی
+صدای
+بلند
+بارگذاری
+بخشها
+اینگونه
+اواخر
+ریشه
+نشد
+کاخ
+ریز
+فرض
+قانونی
+برق
+جلوی
+کودکان
+نزد
+قاسم
+آهن
+زنجان
+نگارش
+شدت
+میگویند
+جایگزین
+جاده
+میکردند
+مفید
+زرشک
+لیست
+محور
+ویکیپدیا
+رایج
+مناسبتها
+خلق
+مراکز
+ساری
+عامل
+نقاشی
+رسیدن
+کارشناسی
+۱۹۸۴
+خ
+زده
+رعایت
+انگلیس
+اطلاعاتی
+ورزشی
+مقایسه
+منبعی
+بازبینی
+حافظه
+حتما
+عربستان
+مستقیم
+گیرد
+الدین
+۱۹۸۲
+علیرضا
+تعدادی
+ورزش
+برادر
+گذاشته
+تهران،
+محصولات
+زندگینامه
+هوا
+۱۹۸۶
+۶۰
+کس
+پوشش
+حکم
+قهرمان
+خانههای
+حاج
+خواهش
+گردآفرید
+نوبل
+نرم
+رهبری
+خیر
+تجاری
+نوشت
+۱۹۸۵
+جوان
+واقعی
+نظیر
+سند
+سرانجام
+منجر
+اعداد
+فی
+واقعا
+نبرد
+مردان
+جغرافیای
+شدید
+روند
+ویرایشی
+دشت
+ردهبندی
+پرحجم،
+گذاری
+افشار
+۱۹۷۸
+زدن
+سوئد
+خویش
+ماهی
+خالی
+درآمد
+آمریکای
+مسلمانان
+کجا
+میباشند
+طوری
+اید
+دکمهٔ
+احمدی
+درد
+۱۹۸۷
+شاعران
+گویا
+نداشت
+هـ
+سالهای
+ششم
+شیر
+دچار
+تاثیر
+زیست
+دینی
+سریال
+نماد
+راجع
+مطالعات
+مراجعه
+لحن
+خطر
+پرسپولیس
+حضرت
+مکتب
+دامنه
+بروید؛
+زیبا
+بافت
+مسلمان
+کامیار
+محافظت
+ناوبری
+نهایت
+کلیسای
+هشت
+تکرار
+پرورش
+توزیع
+معمولا
+وبلاگ
+طولانی
+تجربه
+ظاهر
+گسترده
+ممنوع
+پیروزی
+چهل
+گاز
+عکاسی
+کاملاً
+احساس
+همچنان
+تفسیر
+چک
+مترجم
+مشخصات
+اینها
+تایید
+۱۹۷۹
+توکیو
+ال
+سمنان
+۲۰۰
+رهبر
+بیت
+سومین
+خوردهاست
+پاکستان
+۹۰
+همانند
+فردی
+ملحق
+کامپیوتر
+سوریه
+پدرش
+اوایل
+پول
+سوره
+تقویمهای
+آفریقا
+کتابها
+دنیای
+همانطور
+دودمان
+هدایت
+باره
+سلسله
+موسوی
+قضیه
+غیره
+صرف
+آید
+ايران
+پک
+طبقه
+حاکم
+داریوش
+گوناگون
+زهرا
+اسماعیل
+زمینلرزه
+اعتبار
+بعنوان
+مُروا
+توانست
+۱۳۷۹
+تدوین
+اهواز
+سبزوار
+جکسون
+نمایندگان
+مقاومت
+آی
+برداشت
+گشت
+قلم
+تنظیم
+نگاری
+هلند
+باور
+نهاد
+سینمای
+تمدن
+فرهنگستان
+کردی
+ویندوز
+سوئیس
+کانی
+نویسی
+ممتنع
+مانی
+پشتیبانی
+جو
+ردهها
+ساکن
+شهرک
+روزی
+صحنه
+اصطلاح
+تئاتر
+جستجو
+جلو
+فردا
+جیمز
+کی
+هرگز
+چیست؟
+حمل
+توصیف
+گیتار
+ری
+والدین
+۱۹۷۶
+حفاظت
+رشت
+سابقه
+کودک
+کنون
+فعالیتهای
+عوض
+اعتراض
+نسل
+دریاچه
+مرز
+باشگاههای
+کهگیلویه
+میکند
+دادگاه
+تصویری
+خانم
+مخالفت
+نصب
+آل
+افرادی
+چاه
+نماینده
+نگه
+عملکرد
+جدیدی
+۱۹۷۰
+ي
+مهمترین
+آمدهاست
+محمدعلی
+بدهید
+اتحاد
+شرکتهای
+موج
+رم
+کشیده
+تحلیل
+نظارت
+تابلوی
+شهرداری
+محصول
+متعدد
+نماید
+قوم
+مصطفی
+جزایر
+گرمی
+عقب
+صلح
+شعار
+ارسال
+جی
+نوشتههای
+غلط
+۱۹۷۱
+سازنده
+نکرده
+مواردی
+جوانان
+حمام
+دورهٔ
+تبریک
+بگذارید
+دانشگاهی
+مس
+ماند
+خداوند
+مهاجرت
+ضبط
+ست
+احتمالا
+لبنان
+دوربین
+خودشان
+عبور
+ارشد
+بنام
+فرمان
+عبارتند
+مطابق
+خرمآباد
+بالاتر
+سد
+تقریباً
+اکبر
+دیدن
+موفقیت
+مدرن
+نگهداری
+۷۰
+عوامل
+پای
+جایگاه
+۸۰
+ف
+زادروز
+پرواز
+خلیفه
+هفتم
+ماشین
+هرچند
+هستهای
+عناصر
+اسناد
+گنبد
+لا
+نهایی
+تدریس
+طلایی
+زابل
+چندان
+اروپایی
+ظاهری
+صفر
+اول،
+اشعار
+دبیرستان
+معلوم
+برنامههای
+نخواهد
+زد
+بیفزایید
+خصوصی
+وظیفه
+ادعا
+عزیزی
+عمده
+انتظار
+آنلاین
+قبلا
+مبارزه
+هستند،
+خسته
+فرصت
+رفتن
+مشارکتها
+گرامی،
+سراسر
+۱۹۸۳
+پیروز
+گویش
+رفع
+جزو
+گفتاورد
+متال
+مکزیک
+۱۳۵۷
+امپراتور
+اطلس
+اسپانیایی
+پنجاه
+شاپا
+بیمارستان
+پیامبر
+بستک
+میکنیم
+اشکال
+تقسیمات
+الکتریکی
+درک
+سلطنت
+لباس
+دهنده
+نشست
+اعدام
+اقوام
+شاخه
+سلام،
+الگوریتم
+چپچین
+شان
+خواست
+مدال
+امارات
+جبهه
+باشم
+مطبوعات
+مستعار
+نیازی
+عادی
+چینی
+افتخار
+کهن
+نا
+مثبت
+شخصیتهای
+خطوط
+ویلیام
+سلطنتی
+منطقی
+اطمینان
+جعفر
+سقوط
+روزهای
+گرفتهاست
+طبیعت
+باشیم
+ردههای
+ترتیبپیشفرض
+شبه
+موافقم
+یهودیان
+تربیت
+دیوید
+معاون
+پرندگان
+ملت
+دیوان
+تی
+پلیس
+ملک
+نيز
+هنرمندان
+عین
+تماس
+حرفهای
+آستانه
+بماند
+واکنش
+٬
+زحمت
+عمان
+حافظ
+نیم
+منفی
+آسیای
+تابستان
+جدی
+قابلیت
+ساختن
+آسیایی
+رجوع
+شهرستانهای
+معین
+نیستم
+ناشی
+تهیهکننده
+داشتهاست
+دانشمندان
+صبح
+اعتقاد
+مبارک
+سورنا
+اساطیر
+اصلاً
+تذکر
+خطی
+کاربردی
+داشتم
+آدم
+کتابی
+مختلفی
+کاربرانی
+سرباز
+جذب
+متغیر
+وضع
+روزبه
+مجازی
+گذاشت
+بابت
+اعلانات
+مهمی
+فلان
+آماده
+مصاحبه
+باتجربهتر
+رقص
+کلاسیک
+گیاه
+سامانه
+مجبور
+نحوه
+نبوده
+نفوذ
+متری
+کانال
+حیات
+گفتمان
+جلسه
+ارادتمند
+درفش
+حومه
+تصور
+خاندان
+بهرام
+لحظه
+برزیل
+یهودی
+دهخدا
+ایتالیایی
+رسانه
+ل
+۱۹۷۵
+مسابقه
+خواستم
+کابل
+نی
+اوکراین
+موسی
+شما،
+بگیرد
+زرد
+هوای
+فلسطین
+اهداف
+است؛
+ولسوالی
+غار
+بنای
+نوشتارهای
+مربوطه
+اخبار
+بودند،
+مهمترین
+سینمایی
+پیمان
+۸۸
+همزمان
+ها،
+احتمالاً
+آسمان
+شهرکهای
+ابتدای
+ندهید
+بوجود
+آیدا
+جانوران
+سدههای
+بازداشت
+هسته
+یادداشت
+ایلام
+نامی
+مجموع
+هنرهای
+میدانند
+ادعای
+سرویس
+بگویم
+ظهور
+هزینه
+کاویانی
+الگوها
+ضروری
+آرام
+حذفی
+اقیانوس
+یی
+امتیاز
+زمینی
+آدرس
+باشه
+امکانات
+بیشترین
+طراح
+نواحی
+مطالبی
+مقالات،
+بخاطر
+لی
+آفتاب
+بفرمایید
+دقیقا
+هشتم
+توانایی
+آیتالله
+مسیحیت
+تبلیغات
+محوطههای
+بارها
+ته
+سنچولی
+يک
+الف
+متصل
+ساسانی
+بویراحمد
+سروش
+نظرتان
+ربطی
+روایت
+بروز
+دیگه
+پژوهشی
+زبانی
+۱۳۷۸
+ثانیه
+برگزاری
+تبلیغ
+شاهنامه
+نزاکت
+قوی
+خواجه
+پوست
+پژوهش
+شروین
+سنی
+میباشد
+سرد
+بگویید
+شکایت
+بنی
+صدر
+مطلبی
+اسید
+کلید
+خسرو
+گذشت
+طلا
+شیرازی
+اي
+شناسایی
+تأثیر
+شیرین
+میکند،
+رأی
+فردوسی
+اگرچه
+چهارمین
+نمیکند
+زاپاس
+خشک
+جنگی
+برداری
+قادر
+بومی
+بنابر
+ديگر
+تقدیم
+حاشیه
+نگارههای
+۱۹۷۲
+اختصاص
+یونایتد
+بردن
+اندیشه
+حتماً
+بودجه
+داشت،
+افزوده
+۱۹۷۴
+بیرجند
+عضویت
+مستند
+بحثی
+الکترونیک
+امروزی
+بیرونی
+فتح
+معمول
+واژگان
+ادب
+نمیتوان
+مرتضی
+اتصال
+مخالفان
+گویند
+ناقص
+سفارت
+۱۳۷۷
+المللی
+قسمتی
+چنان
+مدفن
+فضا
+گرچه
+ويکيپديا
+آمدن
+زیبایی
+نوشتم
+عهد
+رایگیری
+سرمایه
+نامعلوم
+ردیف
+تجارت
+نیک
+ایل
+یافتن
+اظهار
+گرد
+مایل
+اعراب
+قیمت
+چی
+مقدمه
+خرید
+عمق
+گمان
+هری
+معتقد
+دادهاست
+یوسف
+مردتنها
+بزرگترین
+فراوانی
+مرور
+جزء
+ناصر
+موشک
+رومانی
+دانست
+نادرست
+خود،
+فایل
+تلقی
+مشاهیر
+بودهاند
+آواز
+ضمنا
+بشود
+عثمانی
+مبنای
+قلب
+گوش
+جمعه
+آیت
+ویرایشات
+هاشمی
+دارند،
+استادان
+فرق
+همگی
+پرتغال
+ذهن
+پیر
+زیستشناسی
+پرنده
+بتواند
+ارمنستان
+اتریش
+اندکی
+آیین
+اتاق
+قطعه
+شناخت
+تغییری
+۱۹۶۸
+عبری
+معیار
+هفتاد
+روشهای
+نکردن
+فاقد
+آیه
+دم
+عید
+مکانیک
+تکآهنگ
+نوبت
+دیوار
+گشتن
+درمانی
+مطمئن
+نصفالنهار
+جنس
+تیره
+منظومه
+بایستی
+ریاضیات
+مهندس
+رییس
+بارگذار
+هواپیما
+میشه
+آرژانتین
+کلا
+کریم
+شاهد
+گر
+سنگی
+مسئول
+نشانه
+فیلمبرداری
+نوکیا
+جمشید
+تغییراتی
+کتب
+کرج
+استناد
+شریف
+ایرلند
+اف
+نسخهٔ
+چهره
+نوید
+کنگره
+منچستر
+رابرت
+نباشید
+پرویز
+مى
+نماز
+کمال
+گونهای
+ژان
+دلیلی
+داری
+عالم
+اسب
+حمید
+قرارداد
+پیشینه
+قره
+خروجی
+کمونیست
+قاسمیان
+میگیرند
+شصت
+زمستان
+کلمبیا
+راهی
+محدوده
+نامها
+میر
+لینوکس
+میلادی،
+بهداشت
+اگه
+سدهٔ
+۵۰۰
+بجای
+مغز
+پوستر
+حاوی
+لغت
+رسانی
+لوگو
+مسیح
+فرزاد
+فرمول
+مؤسسه
+مفصل
+پدید
+درام
+اردشیر
+آفریقای
+خرابکار
+تامین
+داره
+اتمی
+بزرگان
+محکوم
+نجات
+یادبودهای
+ریچارد
+رومی
+مدار
+تخریب
+بدانید
+درگیری
+بیستم
+افتاد
+محترم
+خودروها
+نوین
+مطابقت
+تاجیکستان
+نقشهای
+افزار
+مراجع
+اتومبیلهای
+عزیز،
+ضعیف
+امضاء
+بیگانه
+فرا
+اکثریت
+هرات
+مییابد
+پنجمین
+میکنند
+کنندگان
+فعلا
+۸۵
+نکات
+ارتباطات
+خواهید
+مجمع
+کنی
+یابد
+منطق
+دیدار
+دویست
+دوستانه
+آوری
+آلبومهای
+اتهام
+بینی
+مسیحی
+گری
+آنلاین
+ویژگی
+ادوارد
+امنیتی
+برایتان
+كرد
+دیگر،
+عام
+اصرار
+بودید
+تبلیغاتی
+حاجی
+هرچه
+۱۹۶۴
+انتقاد
+برسد
+شک
+توانید
+ویژگیهای
+خوی
+۶۴
+زادگاه
+مساله
+فیزیکی
+هخامنشی
+غذایی
+نمیدانم
+سامسونگ
+گرفتند
+تاج
+موقع
+۱۹۶۹
+فاطمه
+سخنرانی
+سختی
+استدلال
+۱۳۷۶
+شهردار
+ار
+سلیمان
+متهم
+مذکور
+عملی
+چندی
+پدیای
+صادر
+منتظر
+٪
+ضرب
+تیمهای
+تل
+حسینی
+گیر
+سراب
+تیرداد
+ویکیسازی
+تان
+مشروطه
+کوچکی
+مردمان
+ویکیپدیا،
+مجاز
+محاسبه
+بزنید
+جنگل
+مجموعههای
+واقعیت
+سان
+قومی
+صفحهها
+قطب
+تالار
+خواب
+تاکید
+گاهشماری
+امین
+لذا
+آسیب
+هیات
+قد
+میلیارد
+کوچولو
+برقرار
+بالایی
+شیعیان
+قاضی
+برگرفته
+عنصر
+معانی
+ارتباطی
+شبکههای
+درود،
+۳۰۰
+مراحل
+لهستان
+معمولی
+نوار
+محس
+۸۹
+قبیل
+سیر
+دهیم
+شاخص
+عیسی
+ترور
+دمای
+تکامل
+کبیر
+درگیر
+سونی
+یاری
+۱۹۵۰
+آگاهی
+نیوز
+پیوست
+رچ
+خدای
+کودکی
+مرتب
+رژیم
+روبات
+ابتدایی
+میتوان
+هشتاد
+زادهٔ
+کشت
+بازسازی
+وسایل
+بتوان
+مجارستان
+پیاده
+میانویکی
+فرمانده
+۸۷
+تهدید
+ویک
+محرم
+نهم
+احمدینژاد
+۶۵
+خورد
+رسول
+تمیزکاری
+بندانگشتی
+گیاهی
+سیاستها
+اینکه
+کلیه
+بهشت
+هندی
+مشکوک
+فکری
+عقیده
+اشغال
+نویس
+ستون
+خارجه
+۱۳۸۶،
+۸۶
+نمیگیرد
+کارخانه
+دانشجو
+پیوسته
+خاطرات
+پادشاهان
+۱۹۶۷
+غذا
+زرتشت
+سود
+خوشحال
+رساند
+آر
+فیلمی
+میپردازد
+تری
+لایه
+سپهرنوش
+ظاهرا
+مصدق
+کویت
+مال
+احداث
+کانون
+مد
+فرماندهی
+مرحوم
+مواجه
+۱۳۹۰،
+بايد
+افتاده
+دوم،
+گردیده
+کارل
+وگرنه
+ندارد،
+ترجمهٔ
+ساحل
+جم
+طرفی
+نگهدار
+شرط
+روان
+آبتین
+جوانبخت
+سازهای
+الکترونیکی
+پور
+نود
+جمعی
+راحتی
+حیوانات
+داروهای
+دستگیر
+بابک
+حداکثر
+دانشآموختگان
+حلقه
+راستای
+اراک
+نادر
+اثری
+زبانهای
+برندارید
+رشتههای
+بستن
+برگردان
+آبشارها
+ریزی
+مراغه
+دروازه
+پذیرش
+نمایی
+مدیریتی
+منصفانه
+واژهٔ
+جانب
+متعددی
+رسد
+گوید
+شغل
+زاهدان
+نمای
+رواج
+واضح
+عدهای
+میمانند
+ایوان
+چوب
+نکند
+فلسفی
+معنا
+نمیتواند
+خورده
+سو
+باند
+ماهواره
+مرغ
+دشمن
+کوههای
+سرطان
+دبی
+پرداخته
+ایکس
+آشکار
+کاشان
+بغداد
+ببخشید
+ششمین
+منظورم
+جلب
+دیر
+مـهـران
+زند
+مناسبی
+خانگی
+تجزیه
+بالغ
+میداند
+علامه
+جولای
+برگ
+سیستمهای
+سیستمعامل
+کاوه
+۷۵
+دراپر
+مدارس
+ظاهراً
+رنگی
+دههها
+چیست
+تظاهرات
+مربی
+سازمانهای
+برپایه
+متشکرم
+دوازده
+ایراد
+گیتاشناسی
+میبرد
+اسامی
+او،
+دارد؟
+بورکینافاسو
+تجهیزات
+شاهزاده
+دربار
+دانم
+زاویه
+قاره
+رهبران
+گ
+سرود
+ابهام
+۱۳۷۵
+ایمیل
+پیغام
+فرآیند
+دالبا
+ح
+پستی
+ظرفیت
+بشه
+سیتی
+هستیم
+پرتاب
+کمدی
+توی
+فجر
+اینجا
+گرگان
+میدانم
+جواد
+شاتل
+خطاب
+الهی
+گرایش
+ملا
+دانشمند
+فیلتر
+نسبی
+شوم
+داستانهای
+نمایشگاه
+تربت
+ممنونم
+آگوست
+پایدار
+مشارکتهایتان
+منطقهای
+تنگ
+مقیاس
+شریک
+جزئی
+هویت
+بدهد
+نوشتهٔ
+بابا
+ادیان
+۱۹۶۵
+جورج
+هفتمین
+تصرف
+آهنگساز
+پاورقی
+دلیلتان
+حس
+کوچه
+رقابت
+نمایند
+رها
+مقامات
+منطقهٔ
+قلعههای
+فن
+مادرش
+متخصص
+تکنولوژی
+سالی
+کیفیتی
+زمینشناسی
+میدهم
+مک
+کشتار
+سنگین
+مینویسد
+نکردم
+ید
+پرو
+بدان
+باران
+دخالت
+درختان
+جوانی
+آنگاه
+حسب
+حرفه
+سندی
+چگونگی
+تبار
+توافق
+کتابهای
+اطلاق
+نامناسب
+مایکروسافت
+۱۹۶۶
+ارشاد
+فردوس
+صوتی
+روزگار
+نمودند
+سگ
+دارو
+خاورمیانه
+معلم
+گره
+ون
+سوخت
+مترو
+آموخت
+نشدهاست
+شماست
+هتل
+حدیث
+نداریم
+پیدایش
+۱۳۷۰
+میانی
+کنند،
+عقاید
+پیچیده
+غ
+قهوه
+فرشته
+نحوهٔ
+عجیب
+جداگانه
+هشتمین
+جزئیات
+همشهری
+مبنی
+کاتولیک
+اصفهانی
+حملات
+جاری
+پویان
+انگلیسی،
+برخلاف
+نيست
+اشخاص
+مجید
+سیمای
+کانیهای
+تغذیه
+مربیگری
+برنامهنویسی
+پدیا
+فدراسیون
+اجرایی
+سیصد
+احمدآباد
+میخواهید
+جنگهای
+پیگیری
+حوادث
+اخیراً
+دیجیتال
+تکیه
+مریم
+الی
+۱۹۴۸
+كند
+عده
+اقدامات
+شعاع
+تخیلی
+ماههای
+۶۶
+آزمایشی
+شدهاست،
+واژههای
+دشتی
+موافقت
+قهرمانان
+جلال
+اچدی
+الفبای
+نفس
+پایانی
+پانصد
+برایش
+ترجیح
+خواند
+سلول
+عصبی
+کوخرد
+آبانبار
+۶۲
+مفاهیم
+شنبه
+بالاخره
+دانسته
+هواپیمای
+نهمین
+ایالتی
+مو
+فارغ
+پلی
+دروغ
+اداری
+استقبال
+مسئولیت
+دادهاند
+فدرال
+ترانههای
+نوازندگان
+چای
+دههٔ
+تراکم
+فهرستهای
+مردی
+زمرہ
+گورستانهای
+سوالات
+عباسی
+سردار
+محک
+ترکیبی
+رقم
+سعودی
+نرمافزارهای
+بازرگانی
+برلین
+نروژ
+مارتین
+فوت
+دیدنی
+کنفرانس
+فارسی،
+اهر
+نجف
+پذیرفته
+اینست
+ملکه
+سرخط
+كرده
+زنی
+قلمرو
+بخصوص
+امی
+بهائی
+نقاش
+کازرون
+تار
+گرفته،
+نظم
+۷۲
+خودداری
+شمس
+صفحهای
+بیمار
+واقعه
+هادی
+۸۴
+خاتمی
+بارسلونا
+سرچشمه
+زنز
+برچسبهای
+منتخب
+بحرین
+واشنگتن
+پاتر
+کردهام
+شاهین
+زرین
+مارک
+توپ
+وقوع
+حدی
+آذری
+شاگردان
+معبد
+آرمان
+۱۹۶۲
+بیماریهای
+بچه
+فعالان
+کوروش
+دارویی
+اوقات
+اوست
+میکنند،
+قضاوت
+ین
+دستاول
+فریدون
+تئوری
+نمیتوانید
+دوستی
+حقیقی
+زندانی
+مقطع
+راستش
+۱۹۶۳
+شاپور
+۱۹۵۶
+آکادمی
+بازنویسی
+ارمنی
+۱۹۶۱
+مهران
+مردمی
+ندارید
+گذاشتن
+کوتاهی
+فقه
+تنکابن
+درجهبندی
+ژنرال
+مایع
+طرفداران
+مدارک
+بدلیل
+پیشنهادی
+باشند،
+ذرات
+دانشجویی
+نگارخانه
+نیت
+کیلوگرم
+سردشت
+ایده
+تسلیم
+برادران
+هزاران
+حادثه
+مرتضا
+خواستار
+نهضت
+نرسی
+آمیز
+استودیو
+قدمت
+مجموعهٔ
+مغناطیسی
+قطعات
+عمران
+توجهی
+فیلمها
+كار
+۶۳
+رسم
+درب
+مبتنی
+امواج
+تمایل
+احزاب
+روحانی
+ء
+اردن
+۶۱
+عمارت
+میدانید
+گفتار
+دزفول
+داوری
+کا
+حقوقی
+زمستانی
+فولاد
+امریکا
+مزرعه
+بوده،
+رساله
+رامین
+جراحی
+محقق
+ابزارهای
+ویکی
+پزشک
+قبلاً
+ضلع
+سرور
+مجاهدین
+اخلاق
+گراف
+مانع
+مشارکتکنندگان
+قشلاق
+نوازنده
+پرده
+۱۹۵۳
+شیروان
+کاظم
+اریکسون
+طیف
+مسکو
+۱۹۳۰
+۶۸
+مقابله
+لوله
+علیآباد
+واقعاً
+معدنی
+طباطبایی
+شاهان
+تاريخ
+ودر
+ماهان
+یوشیمیتسو
+۱۹۴۵
+نمونههایی
+البرز
+چهارمحال
+مالزی
+۱۹۵۸
+خودرویی
+بیاورید
+آبادی
+مخابرات
+میدهید
+رودبار
+جور
+یحیی
+كتاب
+وین
+میداد
+غلامرضا
+طایفه
+سطر
+خواهیم
+جانشین
+اقامت
+توده
+مشارکتهای
+برود
+جویا
+میروند
+نتیجهٔ
+اختیاری
+اساتید
+آگاه
+ساوه
+قدس
+ناخالص
+چرخ
+پردازش
+خرم
+به
+کاربردهای
+فیلسوفان
+طب
+زمانه
+وحدت
+افغان
+منوچهر
+طرز
+بوسیله
+مدیری
+اخذ
+اصلاحات
+فرهاد
+۱۳۷۳
+بایرن
+تور
+۸۲
+بست
+راحت
+تقلید
+لهجه
+قرون
+افسانه
+۶۷
+منزل
+۰۰۰
+رکوردز
+تأثیرات
+افتتاح
+بزرگتر
+هندوستان
+نقره
+بهشتی
+پذیر
+عظیم
+سیم
+خواص
+اعتراضات
+سخنان
+رزیدنت
+مسجدهای
+هرگونه
+میآورد
+اینها
+دقیقاً
+بسکتبال
+صوت
+بوئین
+۱۲۰
+۱۵۰
+شور
+زودی
+توانند
+سربازان
+رویداد
+خب
+بنیان
+چلسی
+زیبای
+شورش
+خامنهای
+برایم
+درخواستی
+روانشناسی
+جسم
+ممنوعیت
+اهورا
+چقدر
+ابوالحسن
+سالن
+صحت
+میخواهد
+۹۶۴
+نرخ
+اختلال
+رویدادهای
+خراب
+تونی
+دایره
+دبیر
+۸۱
+۱۳۶۸
+دانشگاهها
+تقویت
+زلزله
+دهانههای
+کوهستانی
+محض
+۱۹۵۴
+نبودن
+بين
+کارکنان
+جملات
+خاکستری
+دادید
+فرایند
+دارا
+وفيات
+چهارصد
+خصوصیات
+چارلز
+گفتند
+ستاد
+۱۰۰۰
+پیتر
+انگلیسیزبان
+مجتمع
+وسعت
+میشدند
+۱۳۷۴
+نیروگاه
+گذار
+قوچان
+تحصیلی
+دهی
+میلان
+نمیکنم
+فرم
+پستانداران
+گردن
+۱۳۷۲
+۱۹۴۰
+جناح
+شوشتر
+پذیری
+لیبی
+اسلامی،
+بحثهای
+سوء
+همسرش
+قفل
+اسکندر
+تحلیلی
+تحمل
+فعلاً
+۱۳۵۴
+میوه
+مصنوعی
+ارزیابی
+روزانه
+مدعی
+دانمارک
+فرستاده
+شناسه
+صبر
+شطرنج
+گفتید
+وسیع
+گام
+گوشت
+کرده،
+رصد
+کوهدشت
+اینطور
+نوجوانی
+ملتهای
+محمدی
+۶۹
+لشکر
+بزرگراه
+۱۹۵۲
+پاینده
+۴۰۰
+جانبی
+ایول
+تجدید
+نیست؟
+حامد
+نشریات
+توماس
+مجازات
+قیام
+گپ
+سینا
+۷۸
+بس
+وظایف
+کوهستان
+اینجاست
+میدهد
+کارها
+سالها
+یادبود
+آبادان
+طبس
+خوردن
+روزه
+مسکونی
+اعظم
+دموکرات
+خشونت
+۸۳
+هوشنگ
+تخصص
+سیما
+منظر
+علمیه
+سالم
+پیکسل
+کمکی
+خواسته
+ایرج
+مدنی
+گفتن
+آذربایجانی
+ره
+اتمام
+آلاباما
+۱۹۲۰
+ابی
+بام
+فقیه
+کیلومترمربع
+عوارض
+۱۳۵۰
+ترس
+بازگردانی
+سعدی
+موثر
+کلیبر
+انقلابی
+وبسایت
+روانی
+موردی
+دختران
+روس
+بم
+پاککن
+داشتهاند
+یوتیسی
+صدها
+پانویسها
+نفتی
+ورزقان
+کمبود
+نابود
+فرانک
+دان
+۷۶
+جرج
+جدایی
+کیهان
+نامش
+تبریزی
+کتیبه
+حکومتی
+قسمتهای
+صرفا
+ك
+۷۱
+اندازی
+قدم
+منحصر
+عموم
+پهنای
+پدیده
+روغن
+رسانههای
+اطلاعات،
+سایتها
+اکران
+سلامت
+بالاترین
+پیروی
+۱۹۵۱
+مصداق
+۷۳
+شکار
+مباحث
+پوویا
+٭
+فاصلهٔ
+فاز
+۷۷
+حالیکه
+شهریار
+۱۹۵۷
+درخشان
+آنجا
+تنهایی
+نکرد
+عدالت
+مینماید
+مقبره
+سانسور
+دادهها
+شاهرود
+تخمین
+نشستهای
+۱۹۳۶
+جین
+روبرو
+پسزمینه
+نیرو
+اخلاقی
+داستانی
+سینه
+چ
+شاهنشاهی
+مولانا
+گاو
+استخوان
+گرگ
+دکتری
+اند،
+کشفهای
+سنندج
+۷۴
+ساحلی
+برهان
+پیشنمایش
+کردم،
+دورههای
+۱۳۵۶
+آغازین
+سالانه
+بستگی
+تخم
+۹۹
+سیگنال
+ویکیپروژهٔ
+ناقض
+خودمان
+کرد؟
+ویرایشگران
+داوران
+برداشته
+۱۳۷۱
+یکمین
+ریزشگاه
+سوار
+سلاح
+شایسته
+سفیدپر
+غزه
+ترکیبات
+لاله
+اولی
+گذر
+جک
+ذیل
+دراز
+۹۵
+پان
+درصورت
+ایرانشهر
+عرصه
+پیروان
+پردازنده
+زایش
+مدینه
+انفجار
+کمپانی
+فرشتهٔ
+واحدهای
+حرارت
+بعداً
+۱۹۴۹
+همینطور
+استخراج
+ملاقات
+فرو
+پارامتر
+منتقدان
+آزمایشگاه
+نوشتهشده
+اصطلاحات
+بتوانند
+مشتری
+متوقف
+اجباری
+مسلح
+سلجوقیان
+کندی
+اسکاتلند
+فیلسوف
+میسازد
+زود
+۷۹
+رجبی
+هفتصد
+تقی
+معدن
+مار
+فراز
+ایالتهای
+ایمان
+ابراز
+ممسنی
+رادیویی
+سرکوب
+پیوندها
+۱۹۵۹
+توزیعکننده
+کشید
+بال
+۱۳۵۸
+۱۹۵۵
+شفاف
+کلام
+یکبار
+رصدخانه
+موسوم
+صلاح
+اخیرتان
+کالج
+واز
+شیکاگو
+جنبه
+۱۳۶۹
+عاشق
+کک
+خنثی
+امیرکبیر
+آنقدر
+زبانشناسی
+مشاور
+نمایشگر
+دا
+مِنْ
+آرزوی
+آئین
+میآیند
+شکلی
+۱۳۶۰
+سقف
+فرامرز
+بحثها
+همت
+خیام
+تصادفی
+میتواند
+تجاوز
+روحالله
+روستاها
+هواپیمایی
+گلدن
+منظورتان
+کرمانی
+قله
+ضربه
+ساکنان
+اورشلیم
+مجدد،
+ویکیپ
+معتقدند
+۱۹۳۸
+محیطی
+جعفری
+خطا
+ویروس
+نگار
+ث
+سالف
+ابراهیمی
+هشتصد
+نکنم
+ذوب
+رایت
+هاست
+متنی
+نان
+اضافی
+باله
+اصغر
+تایلند
+را،
+پیانو
+سکونت
+تالیف
+اختصاصی
+بهتری
+ترابری
+چو
+دیو
+زندگینامه
+شیشه
+قلبی
+تحریک
+کیش
+ستارهای
+اختراع
+برآورد
+سزار
+دهستانی
+مجسمه
+برطرف
+سپرده
+پارلمان
+رمز
+درسی
+سپاهان
+منصوب
+۱۹۴۱
+پروانه
+جمعبندی
+فعل
+کربن
+دژ
+تفکیک
+قفقاز
+ۚ
+همراهی
+عبدالحسین
+بسيار
+مواليد
+۲۵۰
+پیرو
+معاونت
+پیرانشهر
+۹۱
+معنوی
+کاروانسرای
+دفن
+سیزدهم
+ند
+اینقدر
+هخامنشیان
+دستگیری
+گلهای
+میخواهم
+گیرند
+متفاوتی
+شیلی
+مراکش
+کنسرت
+بدهم
+تومان
+کهکشان
+اوضاع
+اندونزی
+چنانچه
+جایزهٔ
+بدهند
+کروبی
+سکه
+گرفتهاند
+میشوم
+تضاد
+ملایر
+شیطان
+سهم
+اخطار
+حرم
+موافق،
+هیتلر
+واسطه
+ناظر
+نمودار
+بگوید
+تیمور
+قصر
+مکانی
+فرودگاههای
+۱۹۴۶
+جهاد
+مقداری
+داد،
+اندک
+دکترای
+فیلیپ
+۱۹۳۳
+کارگران
+آماری
+۹۸
+تست
+ى
+هستی
+میزبان
+تقاضای
+اوبلاست
+شیوهنامهٔ
+من،
+محتوا
+مربیان
+دیسک
+معتبری
+زدایی
+صعود
+حکمت
+مخفی
+زمینهٔ
+دهان
+گو
+رمضان
+ششصد
+هماکنون
+شکسته
+است
+حرفی
+۹۶
+هواداران
+تبعید
+نشین
+توجیه
+مکه
+جاذبههای
+منافع
+بیفزایید،
+عرفان
+کشی
+آمریکاییهای
+عقل
+وفات
+سیب
+پربارتر
+کنه
+تألیف
+بنیانگذار
+دموکراسی
+نهصد
+یادم
+سراسری
+تفکر
+لارستان
+برگزیدگی
+رباط
+لس
+حساس
+حبیب
+ویکیپدی
+فرود
+همکاران
+تشویق
+تحویل
+باقری
+دادههای
+معرض
+گلوب
+کلیسا
+ویکیپد
+کف
+۱۳۶۷
+امضای
+بخواهیم
+خالد
+فلزی
+نظرخواهیها
+آیات
+درگذشته
+شباهت
+همچنین
+تعلق
+بگیرند
+گوناگونی
+نایب
+حساسیت
+کارگردانان
+مغول
+سازمانی
+دیا
+داغ
+خواهی
+فشرده
+ماجرای
+زندانیان
+تصاویری
+بیماران
+کهنه
+مکمل
+بخواهید
+رایگان
+رویه
+ماری
+فرمایید
+بلورین
+فورد
+درخواستهای
+سازد
+پروتکل
+راس
+فرقه
+وفق
+نازی
+احتمالی
+طلب
+اقماری
+محدودیت
+همایون
+۱۱۰
+هیأت
+احسان
+ابرخس
+بخواهد
+له
+مهرداد
+میشوند،
+سکوت
+مهاجر
+صدور
+بازیگری
+آسان
+سراغ
+اولا
+محلول
+وان
+کوی
+الکساندر
+لیسانس
+خزر
+۹۲
+شکنجه
+امیررضا
+گرجستان
+بازرسی
+عکاس
+۱۳۶۲
+آسیاب
+گویی
+شود؟
+حیاط
+موجهی
+ارکستر
+ارباب
+نویسندهٔ
+یخ
+السلام
+نسب
+بوی
+۱۹۴۷
+نمي
+اعضا
+خانوادهٔ
+ویکیپدیای
+سحابی
+شاهی
+شیوهٔ
+زیارت
+تحقیقاتی
+فعالیتهای
+کاغذ
+تهرانی
+پروفسور
+بریتانیایی
+اخیرا
+ایرنا
+مادرید
+۱۳۵۵
+زمینههای
+ببینم
+۱۹۳۴
+میبینید،
+فیفا
+صالح
+متداول
+ربط
+سطوح
+یپدیا
+خواهدشد
+بحران
+۱۹۳۹
+افکار
+پیراهن
+۱۹۳۲
+انتظامی
+بلافاصله
+ارایه
+کمیسیون
+راز
+محمدحسین
+آبیلا
+محبوب
+سایه
+جوامع
+داور
+۱۹۰۰
+زودتر
+ولز
+سوخته
+تأیید
+ابوالقاسم
+برادرش
+بمب
+امتحان
+آرتور
+فرستاد
+صص
+دانشجوی
+کارگر
+هوش
+اتفاقا
+غلامحسین
+قربانی
+میخورد
+احکام
+سرزمینهای
+ضمناً
+فینال
+قبرستان
+ضعف
+نامهای
+گندم
+قواعد
+تند
+تایپ
+ماموریت
+موسیقیدانان
+گوشه
+دری
+مناسبت
+ارقام
+چاراویماق
+مبانی
+گذاشتهاید
+ابر
+مدخل
+یو
+شناس
+اندازهٔ
+غالب
+قنات
+مبتلا
+ویکیفا
+نوزدهم
+مونیخ
+کابینه
+میرحسین
+باقر
+۱۹۳۵
+سامان
+هلندی
+موجودات
+فنلاند
+برعهده
+مدافع
+قطار
+تغییرات،
+فرمانروایی
+واگذار
+حکیم
+آهنگسازان
+شوند،
+تحول
+مرکب
+مقادیر
+اختیارات
+نوشتاری
+چندانی
+جان،
+هکتار
+رازی
+محلههای
+آوردند
+صف
+مقاله،
+تدریج
+نیستید
+تسلط
+اسلامآباد
+آزمون
+ویرایشاتشان
+اصولا
+صفت
+۱۹۳۷
+میشد،
+سفیر
+تمرکز
+شهروند
+نمودن
+ویتنام
+نمایندگی
+گردش
+سران
+فر
+ایمنی
+خو
+مشارکت،
+پسرش
+میماند
+متروی
+ختم
+علمای
+۱۳۶۴
+ران
+کودتای
+قهوهای
+دایرةالمعارف
+لنگه
+درونی
+سرا
+خاموش
+منصب
+ماد
+دومی
+کشور،
+سوادکوه
+خدایان
+بیطرف
+ماجرا
+دماوند
+بردسکن
+ویکینویس
+ماهنامه
+یادگیری
+قابل
+هاشم
+همگان
+روانشناسی
+محمدآباد
+نگهبان
+آفرید
+گیرنده
+۱۳۵۲
+۱۳۸۹،
+ترکان
+هوی
+دندان
+خوشآمد
+گرفتم
+پایهٔ
+دانلود
+جفت
+فهم
+گوشزد
+متشکل
+رسمیت
+مقدماتی
+جویباری
+پيش
+کنیم،
+استانداردهای
+سرجعبه
+آنجایی
+خیریه
+بیشتر
+في
+دکمه
+ماندگار
+فیروزآباد
+بخار
+فیلیپین
+جلگه
+آرامش
+۹۳
+رونق
+پاسداران
+میتوانید
+کاووس
+۱۳۵۳
+۶۰۰
+مرو
+نیافتید،
+نداره
+نجفی
+الهام
+میکنید
+ناصرالدین
+قصه
+آمدند
+پراکنده
+خواهان
+روي
+مرودشت
+مسیحیان
+عبدالهی
+حسابی
+پاییز
+جانبدارانه
+کیپدیا
+حین
+پلیاستیشن
+اعصاب
+میتوانیم
+فرح
+نمک
+بهطور
+۹۷
+۱۳۵۹
+گرافیک
+زمینلرزههای
+منتهی
+مستقر
+تقدیر
+۱۹۳۱
+میرفت
+افسانهای
+برخطاند
+آبشارهای
+برخوردی
+عکسی
+خاور
+مورخ
+جمال
+باتجربهترند
+بهکار
+مطالبتان
+راهآهن
+نفع
+پاجعبه
+نسخههای
+بدی
+آکادمیک
+امتداد
+یوشیچی
+رضاشاه
+تأمین
+خواهشمندیم
+لو
+رئال
+خراسانی
+سردر
+آشپزی
+ایرانیکا
+شاگرد
+سرای
+یزدی
+نامزدهای
+وکیل
+نقشهٔ
+اکسیژن
+شفافیت
+یکیپدیا
+مقیم
+ویل
+یادآوری
+بلوری
+شعاعی
+قائم
+آلن
+استانبول
+بکنید
+عمیق
+تایمز
+سلماس
+بیطرفی
+بیل
+ۖ
+بویژه
+تکآهنگهای
+میباشد،
+جماهیر
+وحشی
+نمایشنامه
+روایات
+غنی
+کسروی
+بازتاب
+شاملو
+اروپای
+برنج
+بيشتر
+اخراج
+جمعیتی
+اخترسنجی
+شوش
+خوشنویسی
+تقاضا
+مکانهای
+کریمی
+۱۹۲۹
+دفاعی
+برگشت
+کنید؟
+معمار
+خوشحال
+قوه
+۱۳۶۵
+اکسید
+لاهیجان
+آئیله
+عقاب
+پائین
+سوالی
+کنم،
+مان
+خواف
+انجیل
+محاکمه
+ور
+كنيد
+میخی
+مرزهای
+روشی
+بل
+آداب
+زرتشتی
+باشی
+جهرم
+آور
+شهادت
+رسیدهاست
+سادات
+زحمات
+بنویسم
+شریعتی
+بان
+مرتبه
+آثاری
+شه
+کابلی
+تویوهارا
+بیجار
+میزند
+نگران
+کر
+سیرجان
+اماکن
+ایلخانی
+ماست
+گزینه
+دوشنبه
+شواهد
+قاعده
+موازی
+شتاب
+۱۳۶۶
+حال،
+ویا
+میبرند
+۱۹۲۴
+نت
+نجومی
+تعارض
+سادگی
+۱۳۰
+خلافت
+تأثیرپذیرفته
+طبری
+تعقیب
+کاشانی
+منع
+توضیحی
+دورود
+حبس
+بهایی
+محاسبات
+بگوییم
+تنوع
+معادله
+۱۳۵۱
+کوچکتر
+جوی
+دورنما
+شرایطی
+فرماندار
+هریوا
+پیگیری
+۱۹۲۸
+مینامند
+ط
+فومن
+الجزایر
+سیاستمداران
+۹۴
+مقدم
+طرفین
+چمن
+صفویه
+یر
+نابودی
+رفسنجانی
+معادن
+۱۳۴۷
+نیل
+سانتی
+دام
+نامهای
+ات
+یافتهاست
+میدارد
+بقعه
+۸۰۰
+پرتو
+قید
+ظرف
+لری
+قدیمیترین
+انسانها
+برنامهریزی
+وسطی
+مسلم
+چالوس
+پیشتر
+پوشیده
+فرزان
+میشوند
+منظم
+تلفنهای
+خوشحالم
+تجمع
+رنج
+آباد،
+مختصر
+هماهنگ
+روشهای
+لفظ
+چوبی
+همين
+شادی
+وسیعی
+گور
+کردیم
+تندیس
+مواقع
+الیگودرز
+نسبتاً
+هٔ
+مخصوصا
+شی
+مشهورترین
+میخواستم
+انها
+نهنگ
+حرکات
+دنباله
+قانع
+۱۹۴۲
+داوود
+میکردم
+جاوا
+تعادل
+پزشکان
+نحوی
+مادی
+ردهٔ
+گذاشتم
+۱۳۶۳
+کمان
+بعدا
+شرمنده
+ویراستار
+ایام
+اسلواکی
+ناراحت
+متحرک
+تجربی
+خاصیت
+گیلانغرب
+کشتن
+مرزی
+پرچمها
+ذهنی
+لر
+مساوی
+رستمی
+کرم
+ازبکستان
+رضایی
+احیا
+هنگ
+توانم
+شکر
+مند
+کمتری
+بردارید
+قبر
+فرعی
+ایم
+معارف
+پیوندی
+اطلاعرسانی
+بسازید
+کردند،
+کلیدی
+سيستم
+لغو
+بسیج
+سرنوشت
+شاخههای
+طرفدار
+سیاوش
+کشیدن
+پناه
+هشترود
+ورزشگاههای
+صفحه،
+عارف
+ابرکوه
+،خرد
+دراین
+بایر
+قلی
+دشوار
+بیزانس
+بهانه
+جالبی
+قبیله
+بیژن
+چنانکه
+می
+بیانیه
+آلفا
+کارگاه
+استوار
+کش
+پویا
+چیزهایی
+نمیکنند
+رهنمود
+وصل
+کریس
+پسوند
+مهاجم
+جامعهشناسی
+مجددا
+ایر
+احتیاج
+متأسفانه
+خودکشی
+۱۳۴۸
+مراتب
+یازدهم
+خام
+نوجوانان
+بدانم
+طنز
+چهرههای
+شبانه
+دامغان
+مقصد
+وزیران
+لوح
+شهرام
+بده
+جلا
+دشتستان
+روزنامهٔ
+چهارشنبه
+دالاهو
+ضریب
+تکنیک
+سرخس
+ولي
+دکترا
+آنجلس
+خرس
+مجتبی
+نهاوند
+مسیه
+حسینیه
+كنند
+ملاک
+۳۶۰
+هندسه
+ابو
+کامپیوتری
+۱۳۴۵
+۱۰۱
+صندوق
+بلی
+آقایی
+قالی
+۱۹۲۵
+اشتغال
+اوستا
+خاش
+باتری
+قربان
+رمانهای
+زير
+خالص
+زدم
+باشد؟
+توقف
+دوستانی
+اجتماع
+کوهی
+کلاه
+قائل
+فلز
+مطلوب
+گربه
+نگرانی
+زوج
+یار
+سرپل
+نوروزی
+۱۹۲۶
+الآن
+اختلالات
+بریتانیکا
+ايجاد
+آزار
+سا
+پروتئین
+بادی
+مجزا
+سانتیمتر
+اله
+پسران
+۱۳۴۶
+دروس
+کور
+مطلع
+نستعلیق
+خطرناک
+لوگوی
+دنده
+ویژهای
+بهینه
+الکترون
+سقز
+عددی
+کاش
+جیرفت
+راسته
+بتوانم
+نسبتا
+یازده
+کمیل
+مانفی
+انتخابی
+نداشتن
+حرکتی
+کمترین
+مرورگر
+مقالهی
+برنز
+انشای
+فراتر
+وسیلهٔ
+انزلی
+سوم،
+آشور
+اجزای
+روزنامههای
+نداشتند
+برتری
+توقیف
+گنجایش
+نویسندگی
+واشینگتن
+وَ
+عبد
+ماهیت
+ترکمن
+تابش
+برف
+اثرات
+نمایشی
+است
+حدس
+بینالملل
+۱۹۲۳
+راوی
+بامداد
+تنگه
+گذراند
+اتفاقی
+هالیوود
+گشته
+اسمیت
+باش
+آلی
+ترکمنستان
+سوسیالیستی
+مجلات
+۱۹۱۸
+بدنه
+قاهره
+خانهٔ
+بید
+ایرانی،
+۱۳۴۰
+پری
+اشتباهی
+نهاده
+وبسایت
+شهروندان
+همایش
+خوان
+نژادی
+عملیاتی
+افزود
+مخلوط
+رودسر
+الیزابت
+نمونهای
+مغزی
+قضایی
+یان
+گالری
+بگو
+ملقب
+ایفا
+انیمیشن
+بخشهایی
+شکستگی
+سوپر
+کانیشناسی
+ویتامین
+میدادند
+پرجمعیت
+درسال
+۱۰۵
+ستارههای
+مدیا
+بندپی
+تردید
+كشور
+ماهیان
+پوزش
+انگار
+اسلام،
+ايشان
+سرپرستی
+تاکستان
+۱۹۲۷
+۱،
+پذیرفت
+نما
+مشتق
+باستانشناسی
+امامی
+اتم
+ندیدم
+نوشهر
+گزیدن
+۱۹۱۹
+حیوان
+بنظر
+کورش
+اواسط
+رفتند
+تبادل
+میلی
+استون
+دانستن
+آمریکا،
+حصار
+آینه
+گرایی
+قبایل
+کبیسه
+۱۹۴۳
+۱۹۱۲
+۱۹۱۷
+برقراری
+فيلم
+نداشتم
+سرده
+فعالیتها
+بوستان
+خیال
+کارش
+کربلا
+کنم؟
+سیاستمدار
+معنایی
+آلودگی
+شماری
+کودتا
+پانزده
+المعارف
+کالبدشناسی
+عظیمی
+علائم
+کنسول
+نحو
+سوئدی
+گرفت،
+مازندرانی
+مثال،
+منسوب
+نشدم
+ویران
+درخشندگی
+بندرعباس
+ارگ
+سامانههای
+بیمه
+انجامید
+اردکان
+متمرکز
+سلولی
+مرسوم
+صادقی
+هيچ
+امثال
+ولتاژ
+مقررات
+رکورد
+بلخ
+نامزدی
+پردیس
+راههای
+ای
+ماندهاست
+هدیه
+خاکی
+کلاً
+كنم
+جویبار
+گرجی
+سنجش
+بو
+مثلث
+جمهوریهای
+خاتمه
+رشتهٔ
+بوش
+حسینآباد
+۱۳۴۹
+جنگلی
+عزل
+مزار
+اختلافات
+زاکسن
+عشایر
+دشمنان
+کنگ
+یهودیت
+الگویی
+فرکانس
+تحریف
+پژوهشهای
+شام
+لار
+میبینید
+مریخ
+علیاکبر
+عامه
+روزها
+زخمی
+عبارتاند
+ویکیهای
+بری
+کارائیب
+ردهفرد
+رحیم
+نگاشته
+القاب
+قاتل
+مکرر
+محمد،
+ابداع
+ویدئو
+اسطوره
+جامد
+ژنتیک
+مجاور
+سیاسی،
+رفسنجان
+بعید
+مرند
+روحانیون
+اریک
+قریب
+نثر
+تحریم
+موزیک
+برداشتن
+ارتفاعات
+اشکالی
+غذاهای
+شهاب
+بورس
+سال،
+نقشههای
+عروس
+نخل
+محلات
+آلبرت
+فا
+دشمنی
+۱۹۴۴
+يكي
+جایگزینی
+تفاصیل
+خدابنده
+اقلیت
+مشخصی
+محاصره
+زین
+افتخارات
+این،
+بي
+سواحل
+اندام
+فرماندهان
+دانند
+دوازدهم
+بجز
+آرا
+بهائیت
+۱۹۲۱
+کالا
+استقرار
+تلخ
+تکه
+جلوه
+امان
+نگونبانگونی
+فیلمنامه
+مترجمان
+کتاب،
+بستر
+تولیدی
+باغهای
+نباشند
+انصاری
+محمدتقی
+انجیسی
+سلمان
+پهن
+گستره
+سودان
+پرهیز
+همون
+موسسات
+جاهای
+اشرف
+سواد
+مصوب
+دانه
+اينكه
+شعبه
+تشیع
+اپرا
+مجری
+موضع
+۱۴۰
+گلوله
+دارایی
+آوردم
+۱۸۰
+بلد
+سیروس
+گرمسار
+مهارت
+پیشاپیش
+ساختمانی
+باختر
+نامید
+ایفای
+باریک
+تعجب
+عقد
+فرمودید
+وطن
+گوی
+قبرس
+محبوبیت
+کوچ
+جدید،
+اخترشناسی
+کلمهٔ
+ایذه
+احوال
+پراکندگی
+ویرایشها
+سانتا
+نپال
+چرخش
+فخرالدین
+دستگاههای
+پاراگراف
+میتوانم
+پیکر
+بعد،
+جایها
+یاران
+بیگ
+پنجره
+رامسر
+خواه
+انکار
+میکشد
+۱۹۲۲
+برعکس
+پاره
+اکشن
+لغات
+گردآوری
+سهراب
+نیز،
+عراقی
+پاسارگاد
+نوجوان
+مخفف
+هیچگاه
+کاندید
+بهروز
+بناب
+تهمت
+آفریقایی
+جسد
+پژوهشگران
+موسس
+بلاگ
+آبخواره
+مایه
+مجدداً
+لقبها
+تلسکوپ
+استانی
+منتقد
+داراب
+دلخواه
+فرش
+بارگذاریشده
+صحرای
+نوک
+فارسي
+رسانهها
+ماکو
+۱۳۶۱
+استفادهٔ
+دستیابی
+سرو
+بردار
+آلبومها
+مکعب
+تب
+میگرفت
+وی،
+قطعی
+اقبال
+پلاک
+برابری
+جوش
+التحصیل
+بردند
+شارل
+خشم
+سارا
+گناه
+حوصله
+بیافزایید
+اصیل
+خودمختار
+نمیدهد
+داند
+سراوان
+صور
+یعقوب
+شنیدن
+اشتراک
+دفع
+اد
+ه
+وستفالن
+بهائیان
+پناهگاه
+مسیرهای
+هست،
+مذاهب
+گران
+تابعیت
+یابی
+ولسوالیهای
+اسرائیلی
+تاریکی
+تعطیل
+همکار
+زور
+خلیل
+شوخی
+سلولهای
+تنش
+کرسی
+نصف
+میافتد
+بیات
+فضل
+نامشخص
+تعبیر
+۷۰۰
+شو
+سوسیالیسم
+اب
+پرچمک
+دموکراتیک
+تحولات
+بگیریم
+گستردهای
+آریایی
+کیلو
+والی
+براون
+ناچار
+گنج
+بلندترین
+انگشت
+محتواهای
+۱۳۸۵،
+نه؟
+یهود
+وضوح
+بلوک
+بلور
+باکیفیت
+غير
+بدل
+نادیده
+لاریجان
+دلفین
+جاز
+حاکمان
+دوری
+آرای
+خاوری
+شناختی
+ماریا
+شیب
+نیوزیلند
+مشکین
+منتظری
+خریداری
+۱۱۵
+جانی
+بهشمار
+تعلیم
+تأکید
+اندازهگیری
+یافتند
+مادری
+فون
+بادن
+کدهای
+بدنی
+لوئیس
+ادامهٔ
+مبلغ
+صلیب
+میبایست
+آریا
+۱۲۵
+بفرمائید
+قراردادی
+شر
+گفتوگو
+گرینویچ
+مولکولی
+نیو
+سايت
+۱۹۱۴
+جزیرههای
+رسیدند
+فرمت
+قائمشهر
+تفرش
+نظریهٔ
+خواستید
+هافبک
+دائمی
+تنیس
+میدهد،
+ماتریس
+باخت
+سیا
+مغرب
+سل
+اسلحه
+ذهاب
+دهد،
+فرقی
+صرفاً
+وبلاگها
+نمیشود
+راضی
+آتن
+چراغ
+حالتی
+شلیک
+الیور
+اینکار
+برپا
+آهنگرکلا
+لویی
+نیما
+بجنورد
+نهادهای
+محروم
+نکا
+لب
+وحش
+اعتراضی
+ژن
+ويكي
+عثمان
+نیشابوری
+بلک
+کنندهٔ
+موتورهای
+رئیسجمهور
+حکایت
+حاکمیت
+نفره
+هرسین
+مالیات
+انجامدادنیها
+خودت
+مناقشه
+کارهایی
+غذای
+نوردراین
+علل
+دیپلم
+دادگستری
+پیچ
+لیورپول
+سرپرست
+گلی
+تفت
+جنسیت
+امری
+صبا
+اسفراین
+ریخته
+برا
+ناپلئون
+دبستان
+ویدئویی
+خمیر
+انتخاباتی
+گفتهاست
+ورزشکاران
+عادت
+آرایه
+اعتراف
+استخدام
+آرامگاههای
+دوتایی
+ارنست
+عمدتا
+مجهز
+زدند
+۱۳۳۰
+۱۳۸
+۱۳۳۲
+آلبانی
+نشانههای
+باغین
+شعبان
+فارسیزبان
+نیمی
+سازگار
+زبانان
+پیست
+کارایی
+گرافیکی
+کوره
+اتیوپی
+ساوجبلاغ
+مشرق
+فِي
+سیزده
+۱۰۳
+مردمشناسی
+بلندی
+محمودآباد
+بتا
+۱۰۲
+مراد
+افتخاری
+سهام
+امیدان
+دلایلی
+غول
+۲،
+مازیار
+عمدتاً
+مملکت
+۱۳۴۲
+انگیزه
+فرنگی
+مینودشت
+بقایای
+ابوالفضل
+فاکس
+میگوید
+همچنين
+شعری
+لسآنجلس
+تائید
+تاریک
+تونس
+بستانآباد
+کارمندان
+اسحاق
+۱۶۰
+کارگری
+پتانسیل
+سحر
+۱۰۹
+نیازهای
+آرسنال
+افزون
+نظریات
+کوبا
+فهرستی
+آزادگان
+کارشناسان
+تزریق
+کاپیتان
+حدودی
+فیل
+والیبال
+ازای
+اینگونه
+همانگونه
+نداده
+سردبیر
+تالش
+سام
+میگذرد
+آنتی
+مجلهٔ
+بازیها
+رجال
+همدرازا
+دختری
+رفتهاست
+ابریشم
+فلوریدا
+بلغارستان
+مصری
+بلوار
+دليل
+راهاندازی
+۱۰۴
+شمشیر
+ندا
+صادرات
+دانیل
+هریس
+کله
+حوزهٔ
+نشسته
+بیاندازید
+۱۲۸
+وبه
+تازگی
+شورا
+سروده
+درمورد
+شدند،
+قطعا
+اراضی
+میگویید
+حامی
+خوراکی
+جایزهها
+کویر
+مفهومی
+رودهای
+زمان،
+کمیاب
+مخاطب
+سوابق
+سلامتی
+علوی
+خواندم
+نهایتا
+هوشمند
+همیشگی
+همدیگر
+سازه
+ترویج
+مقر
+قشم
+تغيير
+دیروز
+مخالفم
+نجوم
+آرزو
+عموماً
+افقی
+گوشیهای
+رباتیک
+کلاته
+لورنس
+وزیری
+پرداختند
+رجب
+جوزف
+سپری
+تایوان
+مقالههایی
+بود؟
+بزند
+مرسی
+باختری
+صلاحیت
+نمیآید
+بهشهر
+جماعت
+خونی
+نوشتهاست
+ازنا
+مکانیکی
+فضاهای
+فرمانروایان
+رزمی
+همسایه
+همدانی
+۱۹۰۸
+۱۹۰۵
+هردو
+۱۱۴
+هرم
+شهرکرد
+۱۰۷
+آبهای
+متقاعد
+شویم
+نبود،
+نویسان
+همزمان
+شهر،
+صخرهای
+ارزشمند
+۱۳۲۰
+حذفش
+سامی
+ثانویه
+دن
+احساسات
+بوئینگ
+نام،
+شبکهٔ
+شمرده
+طوایف
+باری
+جبر
+اجازهٔ
+بزرگ،
+بهم
+۱۱۱
+جهان،
+مولوی
+تفریحی
+ماساچوست
+آنها،
+اجتماعی،
+طاق
+خوشامدید
+نیامده
+اچ
+ملاحظه
+کمبریج
+زی
+برش
+میگذارد
+شدگان
+بدو
+درحال
+چارچوب
+شدهاند،
+قطبی
+لئون
+هیدروژن
+کاردانی
+درمیان
+نقاشان
+شنیده
+چنين
+آتشکده
+کوههای
+قروه
+هجوم
+سرهنگ
+عکسهای
+تاجگذاری
+خرج
+۱۳۴۴
+جعلی
+آمیزش
+راهپیمایی
+سرشار
+فیروز
+دوک
+بهداشتی
+شکی
+ماهوارهای
+طاهره
+زیرصفحه
+تسخیر
+مخزن
+حیدر
+اتفاقات
+غزل
+زهج
+بولیوی
+کردها
+۱۹۰۱
+قند
+نخستوزیر
+بازهم
+عصب
+مهاباد
+پرس
+گازی
+ابزاری
+مبدل
+۱۳۵
+میشل
+مستقیما
+صدام
+محکم
+فلزات
+طنابداران
+پروژهٔ
+امّا
+صحرا
+۱۰۸
+جملهٔ
+شوهر
+هواپیماهای
+سعادت
+جعل
+صفحهکلید
+اوباما
+۱۹۰۶
+انب
+اپل
+مرخصی
+معیارها
+دانید
+دعا
+تلفات
+تضمین
+آرامی
+دائم
+شد؛
+چرخه
+شجرهنامه
+آفرینش
+معادلات
+رسما
+مزبور
+بارش
+برکه
+نبی
+مصالح
+والتر
+سدیم
+بحثش
+پیشگیری
+پروین
+نشود،
+میگردند
+مسافر
+راین
+بتن
+خوشه
+طوسی
+جونز
+وابستگی
+اسیر
+خیابانی
+بت
+اینجانب
+ببینیم
+لیکن
+بگذاریم
+شراب
+انگیز
+برروی
+حاجیآباد
+پارسک
+اعزام
+اعطا
+فقر
+علي
+کارنامه
+حجاب
+اینک
+جمعآوری
+درهم
+خواهشمندم
+اینه
+گانه
+پارچه
+گردیدهاست
+مداوم
+آلوده
+حقایق
+جعبهدندهٔ
+بشری
+چهارده
+۱۳۰۰
+لیلا
+بدیهی
+مابین
+مثنوی
+ویدیویی
+محققان
+رابط
+تلمبه
+پرفروشترین
+استیو
+ساختمانهای
+وانتشار
+معترضان
+وحی
+برنامهٔ
+بگم
+عسل
+پرتغالی
+فصلنامه
+عجب
+رفتارهای
+وورتمبرگ
+امپراطوری
+برون
+شانزدهم
+مدلهای
+آکسفورد
+فساد
+چیزها
+خبرنگار
+ذره
+کان
+کنیم؟
+دامداری
+هی
+عبدالکریم
+کوهرنگ
+آنتونیو
+ایرادی
+۱۱۶
+دریافتی
+هرمز
+آب،
+گـپ
+ویکیپدیاییها
+۱۰۶
+غریب
+دلفان
+راسل
+۱۹۰۷
+گویم
+قزاقستان
+وحشت
+منشور
+انتقام
+مشروطیت
+کیفی
+بپردازد
+براى
+شركت
+تعصب
+ویلهلم
+خطای
+متقابل
+۲۰۱
+اشکانی
+میکرد،
+بروجردی
+طبقات
+طالبان
+سفارش
+فیلمهای
+آهنگهای
+کنستانتین
+پیوستن
+دیدگاههای
+چالش
+ستایش
+نقشی
+کهریز
+منطقههای
+خلبان
+تنگستان
+فروند
+حج
+خاتم
+۱۳۴۱
+گردند
+پایتون
+گفتهاند
+دانستهاند
+دانشکدهٔ
+تکلیف
+بازرگان
+نتوانست
+بیوگرافی
+۱۵۰۰
+بنت
+مری
+نقص
+فانتزی
+پژوهشگر
+دویچه
+کنت
+قاجاریه
+دوام
+حیدریه
+جیمی
+پویانمایی
+قوای
+میآورند
+کامران
+متنوع
+استراتژی
+شمارش
+۱۹۰۴
+اعم
+داراي
+بهبهان
+الدوله
+تخلف
+فراری
+ایزد
+رأس
+انداخت
+چرداول
+پیشفرض
+رهنمودهای
+بافتا
+شناسان
+اردو
+آبیاری
+ترانهسرا
+روحی
+ادیب
+فلات
+ایست
+سلیقه
+ماجراهای
+باکو
+همارس
+تراکتورسازی
+گم
+رابطهٔ
+داشتند،
+رپ
+گز
+بگذارد
+۱۱۲
+مستندات
+زمینهای
+سایتهای
+مبحث
+مشکلاتی
+بوکان
+ابزارها
+جبران
+تقریبی
+زیان
+گلپایگان
+خوشنویسان
+۱۲۲
+بارز
+مَا
+بوک
+اشتباهات
+تانک
+میشده
+دهههای
+واژهنامه
+خشکی
+ایی
+اللَّهِ
+عفونت
+۱۲۳
+باده
+نامتصویر
+بیس
+كردن
+گچ
+زدهٔ
+طلای
+معکوس
+نبودند
+رضایت
+ثروت
+انار
+کشاورز
+کوانتومی
+اژدها
+سوراخ
+بیلبورد
+شاهیندژ
+بره
+اهدا
+زیرزمینی
+تکراری
+صربستان
+مراقبت
+تروریستی
+۱۹۱۱
+متمایز
+آملی
+برساند
+عن
+ابهر
+معتدل
+گفتگوی
+املش
+میبینم
+میآمد
+۱۹۱۳
+ناشناس
+وله
+جایش
+جنبشهای
+توليد
+موزههای
+نمائید
+دهمین
+برند
+تاریخچهٔ
+میشدهاست
+پاسخی
+پشتی
+تشریح
+نمیشوند
+خویشاوندان
+انگشتدان
+دكتر
+ژانر
+فریاد
+اخلال
+تمشک
+سعد
+پارسا
+۹۰۰
+نامدار
+نظامیان
+قدری
+حمامهای
+مستوفی
+گرما
+گرا
+یادگار
+عاشورا
+دفعه
+بیانی
+شنا
+استعفا
+رسانهای
+انحلال
+بزرگداشت
+فایرفاکس
+بتوانید
+مؤلف
+حامیان
+ناحیهٔ
+مور
+۱۹۱۰
+حیاتی
+هرگاه
+آنا
+جاسوسی
+منتج
+جابجایی
+تولیدات
+هاى
+قدردانی
+۱۷۰
+راست۱
+لیلی
+عملاً
+میشد
+کشورهایی
+درجهٔ
+حامل
+ابوبکر
+خصوصا
+اختصار
+مجاورت
+پدیدآورنده
+آراء
+چپ۱
+گله
+یکپارچه
+عبارات
+جمینای
+جزیرهٔ
+اسرار
+خانوادههای
+بلوز
+مونتهنگرو
+بیابان
+بهصورت
+دارید؟
+نقطهٔ
+ضرورت
+وي
+کارکرد
+هوانوردی
+محبت
+پارکهای
+واژهای
+امامزادههای
+هریک
+کوچکترین
+طاهر
+حوالی
+مطهری
+کنگاور
+شدهٔ
+شبکهها
+شیوههای
+تیراندازی
+۱۱۸
+جست
+آژانس
+سایز
+بدن۱
+تکذیب
+نقدی
+متناسب
+دال
+بابی
+شانزده
+هرکدام
+ادعاهای
+العاده
+عنایت
+مزدیسنا
+انقراض
+مقدونیه
+۱۲۷
+ندیده
+رأیگیری
+دلو
+هندسی
+موبایل
+تورم
+رفتاری
+پیامدهای
+زید
+زادروزها
+حیدری
+بتوانیم
+فوری
+علایم
+نویسه
+غم
+خلال
+اریل
+کاشمر
+بز
+بردسیر
+۱۹۱۵
+حتا
+برخط
+خرمشهر
+همچین
+نفری
+سالگرد
+متخصصان
+شاهرخ
+صحن
+جنین
+جشنهای
+یکشنبه
+تمیز
+ارامنه
+چپ۲
+جلسات
+مهمان
+کجای
+روال
+۱۳۴۳
+پینک
+سبکهای
+هان
+بدن۲
+عمودی
+افسران
+شجریان
+نوسنگی
+الاسلام
+مساجد
+صاف
+مروارید
+جانور
+آنهایی
+راست۲
+اسکی
+ناشناخته
+اعتقادات
+یم
+انگور
+ويرايش
+گروههای
+ترانهٔ
+شد؟
+دقیقی
+استادیوم
+مختلف،
+عتیق
+توطئه
+بالا،
+مین
+همگانی
+تلفنی
+میدانست
+ود
+ميان
+تشکیلات
+روده
+مدیره
+ونزوئلا
+مخصوصاً
+مشتمل
+انتقادی
+تفنگ
+برایشان
+طالقان
+فرانسیس
+بازارهای
+پایینتر
+کاروان
+بهجای
+الیاف
+خامنه
+خصوصاً
+ظهر
+سکس
+چهاردهم
+ایزو
+مسجدسلیمان
+الکل
+فلاندری
+محمدیان
+شکوه
+کردهاید،
+اسلامي
+سم
+کناره
+لوازم
+نمیدانم
+پیامی
+فارغالتحصیل
+باس
+کام
+بنویسد
+بازنشسته
+نصر
+کاشی
+شکارچی
+پستهای
+ویلیامز
+دهکده
+اندر
+۱۵۴
+جهانگیر
+ملکان
+میتوانست
+عبارتی
+مسئولان
+هلال
+مهندسان
+غارهای
+بیلی
+۱۹۱۶
+بنگلادش
+حملهٔ
+توانستند
+پارینهسنگی
+پولی
+خوشبختانه
+نمودهاست
+امینی
+نه،
+هما
+مشورت
+نامحدود
+آندره
+پلنگ
+مخدر
+مضمون
+برمی
+هم،
+لاس
+دهید،
+ویکتوریا
+موثق
+داود
+عذرخواهی
+یاهو
+رنگهای
+۱۱۷
+تناوبی
+نوشتید
+لااقل
+شتر
+مرکزیت
+امن
+ترسیم
+سیستمها
+اتومبیل
+آفی
+جون
+خالق
+حرارتی
+رسوم
+موریس
+مارشال
+یورو
+بانو
+اولين
+منشورات
+غیبت
+نوشتهاند
+قدرتمند
+شکم
+هایش
+انداز
+رویکرد
+علاقهمند
+خانوادهای
+دمشق
+دربند
+برو
+آرشیو
+۱۹۰۹
+رویش
+استخر
+آنالیز
+گچساران
+بکنم
+مولا
+متفرقه
+رحمت
+شاخ
+۱۳۱۰
+اتفاقاً
+اسمش
+سهامی
+دبلیو
+بخشهای
+سرتاسر
+ویکیها
+خیالی
+نکنند
+تناسلی
+مانفی
+جديد
+۱۳۲۴
+کار،
+برندهٔ
+پیچیدگی
+گواهی
+زرتشتیان
+ناصری
+همانجا
+رغم
+گفتهٔ
+۱۱۳
+گرمسیری
+طلوع
+برترین
+درآورد
+بهدست
+برقی
+سپاهیان
+ویژگیها
+مر
+۱۲۴
+چهاردانگه
+جامعهٔ
+تحقق
+مجاری
+میگفتند
+فروپاشی
+چشمههای
+ساختاری
+مسافرت
+پیکان
+نرمافزاری
+جد
+روشنی
+معرفت
+تله
+میکنم،
+محرک
+مشتریان
+بیانگر
+سازمانهای
+چیزهای
+رقیب
+فرعون
+بیروت
+منعکس
+تابناک
+مشرف
+آوردهاست
+نمیتوانم
+۱۱۹
+مولکول
+نعمت
+میرساند
+فرمانداری
+دستکاری
+۱۳۳۹
+مت
+اردبیلی
+مسدود
+بله،
+رانندگی
+۱۲۱
+سایپا
+استعداد
+پیامبران
+داماد
+واجب
+نسخ
+فاضل
+عرفانی
+بزرگتر
+حقتکثیر
+شخصاً
+دگرگونی
+عكس
+انبوه
+آپولو
+فنون
+افلاطون
+حمزه
+میانجیگری
+نظرسنجی
+آنتونی
+اکوادور
+آنچه
+قذافی
+اسکن
+خاتون
+ناگهان
+گونهها
+تونل
+بهویژه
+ناگهانی
+بدهیم
+دوشیزه
+آباده
+نمیتوانند
+شلوغ
+ی،
+۱۳۳۵
+خلع
+فلوید
+ابومسلم
+بایت
+اعطای
+جاسک
+پوند
+پایداری
+تیتر
+واپسین
+استالین
+تعطیلات
+آستین
+مختلط
+تابلو
+خنده
+نویسههای
+ثمر
+۲۰۰۰،
+بازاریابی
+حسابداری
+تکلم
+رنگرزی
+نهبندان
+۱۳۳۶
+نیلوفر
+شرقی،
+بداند
+فسا
+آلیکانته
+دیلمی
+اجتناب
+نیر
+سطحبالای
+اينجا
+میزنند
+کیم
+لغتنامه
+عاشقانه
+فتحعلی
+اشیاء
+تعمیر
+فلانی
+استیون
+سازماندهی
+ویرجینیا
+راجر
+بگویند
+روزنامهنگاران
+هندو
+دیوانسالار
+ایستاده
+۱۳۳۷
+کرانه
+کلسیم
+هایدلبرگ
+کرواسی
+سرانه
+الملک
+سنگهای
+ژنتیکی
+نیکی
+هجرت
+مامور
+خنک
+نمایان
+بهرامی
+شبستر
+واسط
+آرایش
+مبهم
+بسی
+بریتانیای
+محدودهٔ
+بحث
+گاما
+دهها
+نواختن
+فروشگاه
+خمین
+صنعاء،
+کنفدراسیون
+اموال
+هنرپیشه
+پارسیان
+متوسطه
+دامن
+۱۲۶
+لک
+شیشهای
+ابراهیم،
+آمادگی
+هو
+زنجیرهای
+۱۳۲۸
+بازیهای
+سنقر
+بدر
+آورند
+مرجعیت
+آلت
+اسدآباد
+کارلوس
+سودمند
+نشانگر
+رسید،
+حوزههای
+دیار
+کنگو
+میهن
+کلانی
+۱۲۹
+افسر
+باکتری
+معماران
+۱۳۲
+سیدنی
+کفش
+ارادت
+میخواهند
+خر
+۳۵۰
+بدترین
+تاریخ،
+فلسطینی
+زاگرس
+بیاورد
+یانگ
+شخصا
+تشدید
+آدمی
+ماهیها
+هیچکدام
+میناب
+بوسنی
+ایندیانا
+دنبالهدار
+ملوان
+روزنامهنگار
+مؤثر
+دستورات
+رطوبت
+تعامل
+کلان
+عباسآباد
+کاملی
+احادیث
+مدرکی
+پاکسازی
+۱۳۷
+تفاوتی
+ورزشکار
+جنبههای
+غالباً
+بود؛
+چنگ
+مهاجران
+پله
+تراز
+آمد،
+وا
+ژ
+کوثر
+وادی
+اتوبوس
+کاظمی
+خبرگان
+موس
+تکمیلی
+لهستانی
+درویش
+منم
+جعفرآباد
+نیا
+جاذبه
+گیلانی
+طلاق
+تروریسم
+بهخاطر
+آيا
+گرفتار
+اشعه
+میپردازند
+شخصیتی
+آقایان
+رفتم
+جریمه
+مهره
+خاستگاه
+میانویکیها
+بالینی
+یزدگرد
+ببرد
+دوش
+چغازنبیل
+۳۰۰۰
+فوقانی
+۱۳۳۱
+گیلکی
+خطبهخط
+کاترین
+بختیار
+کردید،
+گردان
+ادی
+طاها
+مدیترانه
+ارس
+حسنآباد
+پوشاک
+بابلسر
+رساندن
+کند؟
+بهش
+وست
+خوشامدگویی
+مهار
+میبد
+فلسفهٔ
+وند
+آش
+سیمین
+خوراک
+خوزه
+ساختند
+نياز
+عروسی
+میگردد
+جلفا
+بودیم
+بکند
+۱۳۸۸،
+روحانیان
+حماسه
+پایتختهای
+مبارزات
+احمد،
+ارث
+محمّد
+۱۳۳۳
+کوشک
+سنگها
+زشت
+دنا
+دستیار
+گرمایی
+ایشون
+نامهٔ
+تحمیل
+گوشی
+دورهای
+ققنوس
+بدانند
+شن
+انداختن
+هفدهم
+غالبا
+اسدالله
+۱۳۴
+شدیدی
+ناپذیر
+۱۴۴
+گینه
+سرمربی
+نطنز
+کیبورد
+محفوظ
+آیند
+انفرادی
+آنکه
+گمانم
+توانسته
+سالشهرشدن
+علمجو
+خرده
+درگز
+ایستگاههای
+بکشید
+پیشبینی
+حالات
+هرکس
+بزودی
+کایروس
+اوستایی
+صفات
+مارکسیست
+خشت
+جنب
+عذر
+ونیز
+آسانی
+کریستین
+صفویان
+اسدی
+۱۹۰۳
+تاخیر
+خیانت
+قوس
+قطره
+آثارش
+سیل
+اسکات
+مشاغل
+شم
+بخارا
+چاپی
+مکتوب
+دیدید
+انتها
+موزیکال
+كاربر
+منشأ
+سمی
+لَا
+پهلوان
+پوسته
+درختی
+مشابهی
+کنیا
+عاملی
+۱۳۹
+گویید
+۱۳۳
+تلاشهای
+اهمیتی
+عازم
+اسمی
+پکن
+تصوف
+تکاب
+حاکی
+برت
+کنيد
+نوروزتان
+ببیند
+کبوتر
+سفرنامه
+۱۳۳۴
+تخلیه
+آق
+زنجیره
+انتقادات
+کوک
+همانطور
+غربی،
+جنجال
+فیزیولوژی
+سانتیمتر
+بسط
+زخم
+۱۴۱
+ویکتور
+آران
+یك
+التهاب
+دستهبندی
+جنگنده
+ایفتا
+ژاک
+طاهری
+فیض
+بهتره
+ادعایی
+اسد
+بودنش
+پیک
+مسأله
+بانوان
+بنفش
+گشود
+باغی
+هیدوچ
+جسمی
+انگشتی
+یوهان
+لنز
+چراکه
+رهایی
+نگرفته
+مقصود
+جوراب۱
+آنهم
+قمی
+سکته
+کو
+سره
+زبانها
+برجهای
+مکانها
+نشدن
+چابهار
+پاراگوئه
+کتابها
+طولانیترین
+اولویت
+مبارز
+استراحت
+مشت
+حرام
+فرمود
+نقلیه
+کمر
+پستان
+سرچ
+فعاليت
+ارتقاء
+شانس
+خودی
+فاتح
+مطالب،
+گوسفند
+میگویند
+غلام
+وصف
+دلم
+اظهارات
+انتگرال
+سوسیالیست
+گذارد
+ماموران
+بادام
+چال
+ساگه
+ایسنا
+معده
+ریشتر
+اعلان
+تکنفره
+بلو
+مناطقی
+شافعی
+میگفت
+میخواند
+ثانی
+هست؟
+منو
+لوثشدن
+جنایت
+برخاست
+بودهاست،
+نمیباشد
+اشراف
+نداد
+مهربان
+الهیات
+همهی
+زمين
+کینگ
+رول
+والتوزیع،
+مدرسهٔ
+ترافیک
+اتهامات
+وای
+بهنام
+شجاع
+سیار
+ترسناک
+ذات
+مختار
+عموما
+اینتر
+فرزندش
+داروشناسی
+ریسک
+۱۹۹
+نیجریه
+مظفر
+حشرات
+میدانید
+جبل
+آریزونا
+نارنجی
+کتابخانههای
+میدانم
+آرم
+بشمار
+اعتباری
+کرهای
+عکسها
+پیکچرز
+تخته
+متمایل
+رفاه
+شهبازی
+میخائیل
+تطبیق
+نظریههای
+بلوغ
+عزیزم
+۱۳۹۱
+محاسباتی
+سنجی
+مکانیسم
+سریعتر
+آبشاری
+کالاهای
+اشک
+خانی
+سازگاری
+مارچ
+گرین
+قرص
+خوانندهٔ
+صفی
+نازک
+داروها
+۳،
+۱۳۶
+هماهنگکنندهٔ
+لینکلن
+بانوی
+خودروی
+پلهای
+۱۳۳۸
+دیوارهای
+ورامین
+۱۴۵
+اتخاذ
+کمیت
+دارم،
+مذاکرات
+حول
+برگزید
+کارشناس
+نامعتبر
+سفرهای
+رومیان
+رباتها
+غیراینصورت
+انیمه
+بهوسیله
+استعمال
+صریح
+سازهها
+رامهرمز
+اندیس
+رازقنــدی
+تثبیت
+۱۰،
+تصوير
+گویشهای
+کتک
+طالب
+حماس
+۱۳۲۹
+علیرغم
+۱۴۸
+حزبی
+استونی
+اوین
+غروب
+حریف
+استراتژیک
+شگفت
+مرگش
+جانسون
+پانزدهم
+موشکهای
+گنآباد
+ارتقا
+باطل
+خورشیدی،
+آلفرد
+ساموئل
+بحرانی
+قندهار
+كردم
+ماکس
+گی
+میخواستم
+بچههای
+۱۳۲۵
+شرطی
+گشایش
+زندگي
+دایی
+یون
+فرانس
+تورات
+گزارشی
+۲۲۰
+فیلم،
+دهلی
+مسافران
+سنگر
+نخواهم
+موش
+ریشهٔ
+سخنگوی
+زنگ
+نینتندو
+دیوانه
+بمباران
+مسئولین
+استودیویی
+شدیدا
+تیلور
+۱۲۰۰
+قزوینی
+لاست
+مسلما
+ورق
+شهرزاد
+لطفی
+کلات
+بارداری
+دیواره
+باشگاهی
+شکستن
+تریلر
+ممتاز
+پرانتز
+یوتیوب
+بیهوده
+ابدی
+نباشد،
+کیوان
+طرحهای
+بدم
+کاریکاتور
+بدتر
+داش
+میرسید
+میانجی
+بيش
+اختریان
+سربیشه
+روشنایی
+تبیان
+بکشد
+اراده
+چربی
+خرما
+سلطانی
+شيخ
+مقا
+مستخدم
+وبگاهها،
+نشینی
+نرگس
+۱۷۵
+تویسرکان
+خاطره
+برکنار
+غیرقانونی
+ساواک
+نگارهای
+سین
+شناسنامه
+بناها
+ها،
+غرق
+شعرهای
+مسلط
+سرش
+اه
+برکت
+جنگلهای
+سلطه
+اقیانوسیه
+علما
+بنفشه
+یال
+هولوکاست
+دادستان
+حلی
+اجسام
+غواصی
+احاطه
+والا
+بیماریهای
+صدوق
+ریو
+دیویس
+ناهید
+دهها
+نتوانستم
+ایکسباکس
+ول
+منبعها
+تاریخی،
+٫
+کثیر
+لیتوانی
+شده
+بپرسم
+قربانیان
+جانشینی
+سیریلیک
+بوستون
+یونانیان
+دوبار
+فرضیه
+امروز،
+دیدهام
+عزيز
+۱۴۲
+میگیرد
+شلوارک۱
+مِنَ
+ارسطو
+ومبلی
+بخواند
+۱۹۰
+صوفی
+صدق
+کارب
+گذاشتند
+هزینههای
+فردریک
+نوشتهاید
+آو
+عمدهای
+م
+هیچگونه
+حسی
+اللَّهُ
+معدود
+مارکس
+سنگاپور
+رایانش
+عادل
+ریگان
+میرسد
+الگوریتمهای
+ائتلاف
+فریدونکنار
+بازگا
+نگرش
+هرحال
+بدانیم
+کفایت
+فین
+۱۳۲۷
+باورهای
+بازگیر
+لردگان
+چرا؟
+تعویض
+سلجوقی
+جستار
+نخواهند
+مینمایند
+دهستانها
+فرمانروای
+خودتون
+منتقدین
+کلاردشت
+اره
+لزومی
+مرتفع
+ویر
+سندرم
+نیاید
+آجر
+دانشکدههای
+نمین
+مق
+تن
+اینچ
+فوتسال
+ساکنین
+ه
+فرانسه،
+صفحاتی
+۱۹۰۲
+طالقانی
+جعبهٔ
+غارت
+بزرگسالان
+لین
+۱۶۵
+قیاس
+افغانی
+نگذاشتهاید
+ساید
+نادری
+امامان
+سنا
+سرگذشت
+رایش
+توجیهتان
+بروند
+سمفونی
+آهنگها
+توس
+تم
+پنسیلوانیا
+خرچنگ
+مغان
+سجاد
+پایینی
+تحریر
+لوث
+شانه
+طوفان
+اصولاً
+کبودرآهنگ
+تسمیه
+عامیانه
+بیشینه
+فضاپیمای
+بودایی
+۱۸۹۰
+اقلیم
+مثالی
+جشنوارههای
+برایان
+میرود
+پین
+آم
+سرگرمی
+مزایای
+ریال
+رسماً
+ناحیههای
+تازهای
+میدهیم
+هارد
+مقال
+فراهان
+دلیلش
+میلیمتر
+۱۸۰۰
+ماهنشان
+سالار
+جت
+مردگان
+فقیر
+۱۵۵
+راستا
+میکنیم
+جوری
+شلوارک۲
+پژوهشگاه
+نیستند،
+۱۴۶
+اینشتین
+یخچال
+روزمره
+ارم
+سنین
+تحسین
+سکههای
+۱۳۱
+فحاشی
+پاپهای
+عینی
+رسانده
+رز
+بودم،
+ارزشی
+ستان
+باراک
+اصلي
+الکتریک
+نامههای
+عطار
+علمي
+بخشید
+السلطنه
+يعني
+غلبه
+مستقیماً
+منش
+رستاق
+افراطی
+بگیرم
+سيد
+۱۴۷
+ندارند،
+الَّذِينَ
+نمونهٔ
+کریستال
+قایق
+نوادگان
+سالیانه
+میپذیرد
+احترامات
+شیری
+سیاهکل
+سرب
+نصرالله
+مانه
+گیم
+ببر
+آستان
+زیستگاه
+ای،
+دادهام
+لوئی
+شریعت
+آموز
+رتبهٔ
+کمکهای
+نقدها
+حلقهها
+ارتقای
+هال
+انسانها
+پشتو
+امیرحسین
+سینآباد
+رشید
+۱۴۳
+شیرینی
+مذاکره
+تعدیل
+کارمند
+اعضاء
+روانه
+بنر
+معروفترین
+خیابانهای
+مشاوره
+اکثرا
+افت
+کنگان
+بگذارند
+دامنههای
+رحم
+بیدار
+تیپ
+تنفس
+افغانستان،
+میشیگان
+استعمار
+فرخ
+گذرگاه
+توالی
+تایم
+جملهای
+ولادیمیر
+دستوری
+تساوی
+ساختارهای
+جانوری
+قسم
+۱۳۱۶
+هفده
+یقین
+صوفیان
+مینویسند
+رومرکز
+بک
+انگشته
+مولف
+نگفتم
+یورش
+ثبات
+بیایند
+بپرهیزید
+وبا
+اسجیاچ
+جن
+ورزشهای
+لامرد
+سپیدان
+کبک
+عزت
+افشین
+کامرون
+فیلمشناسی
+پاول
+نکنیم
+درگیریهای
+رخداد
+کیا
+عرف
+شازند
+یکصد
+استهبان
+میگیرد،
+نرسیده
+ویژهٔ
+ابتلا
+اینطوری
+گارد
+بزن
+مدتها
+وعده
+شرف
+پيدا
+نیدرزاکسن
+زواریجان
+اسدخانی
+هندواروپایی
+تصویرگر
+مختص
+استادی
+هیپ
+امشب
+احیای
+بنو
+امامت
+خونریزی
+سیگار
+کاسه
+غرض
+معتقدم
+ساختم
+صفح
+روایتی
+نمادهای
+متوالی
+خدایی
+نمود،
+عجم
+آبهای
+آمدهاند
+نمودهاید
+لاریجانی
+شیوع
+زمينه
+الا
+بیا
+آزمایشگاهی
+آنتن
+قرآنی
+بیستون
+فاجعه
+۱۵۸
+ریه
+انعکاس
+تقلب
+هجدهم
+طبرستان
+تناقض
+مدتها
+علمی،
+تصنیف
+فروغ
+دایرةالمعارف
+آلمریا
+تاسیسات
+گونهٔ
+هیچکس
+ایدز
+آوا
+۱۴۹
+مديريت
+بیاد
+پایگاههای
+زیرصفحههای
+مقاوم
+گمشده
+نشدید
+نوزاد
+سیف
+دیفرانسیل
+موافقان
+بانه
+فونت
+صفا
+واتیکان
+اصالت
+کتابخانهٔ
+یگانه
+کیت
+ترجیحات
+کنوانسیون
+نانو
+۱۵۳
+آنزیم
+كردند
+تیمی
+۱۸۵
+هستید،
+حوض
+نویسنده،
+ورد
+حسنی
+پديا
+بویین
+مادها
+ناوگان
+بنگاه
+اردلان
+صومعه
+تورنتو
+کارولینای
+۵۰۰۰
+اشکالات
+مسائلی
+انداخته
+نماند
+دستمزد
+بخواهم
+سرقت
+میدانی
+ریتم
+خوبیدگی
+پوستی
+اندی
+الماس
+بزنم
+مقدونی
+هسن
+گروهها
+بروجن
+تگ
+منشی
+ملکی
+تبعیض
+ببین
+افق
+خشن
+کورین
+دوی
+قوام
+ایلینوی
+بچهها
+تکاملی
+دخترش
+برانگیز
+اصطلاحی
+مل
+یکان
+داراست
+عربها
+ناموفق
+کبد
+کوفی
+رودها
+پشته
+رسالت
+مرتکب
+معروفترین
+نشوند
+نبودم
+بنیانگذاری
+لیبرال
+فرید
+حوضه
+ربع
+نوح
+سیاهه
+تای
+خستگی
+پدری
+برنامهها
+فرستادن
+بیطرفی
+نواب
+نزول
+استیشن
+رادار
+پخشکننده
+سازند
+عضلات
+سعیدی
+کوین
+بنویسند
+برم
+بیایید
+حجازی
+شده؟
+تالیفات
+حسینعلی
+نیست؛
+مزاحم
+فروشی
+آموزان
+میکرد
+۲۴۰
+بحث،
+وارنر
+کوری
+واکنشهای
+فستیوال
+قارچ
+لغتنامه
+تاجیک
+شرکتهای
+هروی
+ویژگیهای
+عکسهای
+چارلی
+باشيد
+داشتیم
+بومیان
+باقیمانده
+یافت،
+اشارهای
+فصلی
+عبدی
+بزرگوار
+بیتی
+مُعجَم
+نازل
+امپراتوران
+مهمتر
+کانیها
+۱۸۹۶
+محمدباقر
+شایع
+ادریس
+که
+دهندگان
+اعلامیه
+بهنظر
+داروی
+لیک
+اتوماتیک
+ميشود
+فروغی
+برآورده
+بلا
+آدولف
+قشقایی
+تنفسی
+اردوگاه
+زنجانی
+تنه
+گزیده
+مریوان
+پورنو
+کامبوج
+تلهای
+رمزنگاری
+دامپزشکی
+شاهنشاه
+قرقیزستان
+ارابهران
+نمودم
+ضرر
+بازنگری
+دگرگون
+بررسي
+شدهبود
+ناپدید
+متاسفم
+نسخهای
+اشنویه
+پیاپی
+عبدالعزیز
+۱۶۸
+اسباب
+نسبیت
+کعبه
+مردم،
+ذوبآهن
+آنچنان
+ادرار
+رنسانس
+سوسیال
+دهخدا،
+تختی
+فاطمی
+ماشینهای
+پاسکال
+مینا
+تابعی
+سایتی
+توانیم
+ترين
+توران
+ادارهٔ
+فهرستها
+خوشی
+معینی
+یادآور
+مخالفین
+دود
+مدام
+انی
+تقاطع
+پتاسیم
+نساجی
+ارد
+اندیمشک
+داده،
+مخالفتی
+دونفره
+اندیشههای
+علیزاده
+آجری
+برسیم
+اقدامی
+فقهی
+اشکان
+همبستگی
+فرادیرینهسنگی
+گناوه
+کوفه
+۱۸۹۹
+اینصورت
+عبدالرحمن
+لبه
+بیپایان
+میدهند
+منشا
+مرحلهٔ
+بیطرف
+کردید؟
+مسخره
+مشخصه
+عضلانی
+اسارت
+عنوانی
+۱۵۲
+ندارم،
+برچسبها
+اچآیپی
+منصوری
+۲۱۰
+بینم
+مجنون
+تعاریف
+تعهد
+اقتباس
+جلیل
+میکنید؟
+رزن
+مسئلهٔ
+فرستنده
+گان
+قاب
+کمونیسم
+تناسب
+ندای
+توحید
+هواشناسی
+کردهاند،
+منتها
+روز،
+شوال
+لیزر
+پساز
+دزدان
+دارد؛
+جنگافزار
+جایزههای
+واحدی
+تیموریان
+ذكر
+کنده
+ترش
+میخوانند
+ریش
+تمایز
+پیشبرد
+زندگانی
+دلتا
+پیشاز
+نقده
+ایرلندی
+هنرستان
+قبال
+فرصتی
+دودویی
+عليه
+زیباترین
+شاعری
+سرما
+ایلینوی
+شهبانو
+پنالتی
+بهاری
+افتد
+فیروزکوه
+فایده
+۱۶۳
+بروس
+نیسان
+نکردند
+نمیتوان
+۱۶۲
+روباه
+سقراط
+کشتهشدگان
+اورانیوم
+عملا
+طراحان
+ماهیچه
+سرم
+اوهایو
+علاقمند
+نویسد
+الجزیره
+گذشته،
+مزارع
+گزینش
+جنگهای
+اطلاعی
+نوشتهها
+پارلمانی
+۱۱،
+جنابعالی
+اسفندیار
+امیدوار
+کگ
+گازهای
+کبود
+زمین،
+تلگراف
+لئونیداس
+گرمای
+کتابخانهها
+آشوری
+طعم
+راد
+زنانه
+عربی،
+جادو
+حمیدرضا
+جنگ،
+جابجا
+ماکیان
+بیابید
+شکاف
+گلزار
+متفقین
+متاخر
+سایتهای
+بایگانیها
+بهرهبرداری
+جنایی
+کارون
+شهدای
+میامی
+پدیدههای
+هستم،
+برکلی
+نایین
+ببینند
+استانداری
+۱۶۱
+پسری
+شوالیه
+کت
+شاخهای
+مقاطع
+آنوقت
+اسکو
+۱۸۹۲
+نده
+رسانید
+۲۳۰
+تاسف
+هايي
+پلدختر
+تاجیکی
+جاجرم
+وضعکننده
+استر
+همنشین
+زحمتی
+کانادایی
+تبلیغات،
+زهک
+دولتهای
+ترمودینامیک
+سوری
+خلفای
+درآن
+فراگیری
+ختنه
+امیرآباد
+تروث
+بوم
+زاد
+خنج
+بروم
+سومالی
+جیم
+دیجیتالی
+عفو
+سوشی
+اصفهان،
+بلاندی
+کوچکتر
+گمنام
+سکوی
+نزاع
+احتیاط
+گردید،
+بزنند
+علنی
+ویلا
+۱۳۲۶
+الهه
+هدر
+ظلم
+ناو
+میکردند،
+الحکمة،
+یاقوت
+حتي
+شرکتها
+تعلیق
+خواستند
+کاروانسرا
+نکتهٔ
+رشتهای
+باهم
+بپردازند
+درجات
+وجودی
+بودا
+نیوتن
+منطبق
+نصرت
+الجی
+سومی
+فلش
+۱۳۸۵جمعیت
+فریم
+دوما
+ساقه
+اسماعیلی
+دینامیک
+المقحفی،
+المُدُن
+فیلمهایی
+فیزیکدان
+محضر
+آخوند
+فراهانی
+صید
+بسا
+الیَمَنِیَة
+بنایی
+۱۷۳
+میگوییم
+درآمده
+مورخان
+یونیکس
+جاها
+وام
+کوتوله
+۱۷۶
+ژرفای
+موجودی
+مرادی
+بدنیا
+پمپ
+پرستاری
+میشوید
+مناره
+انقلاب،
+برجستهٔ
+جذاب
+نوشتارها
+نمیشه
+مایک
+امیری
+چناران
+ــ
+گردو
+تفویض
+دخیل
+۱۵۹
+بنیادین
+بدیع
+سالیان
+مواضع
+وَالقَبائِل
+۱۶۹
+میبیند
+درگذشتهٔ
+داشته،
+قنطورس
+۱۸۹۸
+تصمیمگیری
+مشمول
+رودان
+فراگیر
+آمده،
+نفهمیدم
+۱۸۸۹
+شدهاید
+نفی
+افسردگی
+میدانستند
+آلات
+قوت
+دانههای
+محمدحسن
+عزيزی
+جامی
+نجم
+طرحی
+گاندی
+جنوبی،
+بصره
+اروگوئه
+شرکتها،
+پورت
+خجسته
+زمانیکه
+ریشههای
+فمینیسم
+گاردین
+بایست
+وار
+دیوانسالار
+فوتبالیست
+۱۶۷
+آلمان،
+شعله
+آناتولی
+على
+شمالی،
+سیمون
+ظروف
+رستوران
+دایر
+میگذارند
+تفاهم
+آناتومی
+گذراندن
+شكل
+مرگها
+آهنگسازی
+لیتر
+دزدی
+فرموده
+معصوم
+اطاعت
+تارنمای
+فارس،
+پلان
+هانس
+فریدریش
+ملی،
+روحانیت
+اوّل
+نتيجه
+وادار
+صورت،
+۱۳۰۴
+ترتیبی
+مبارکه
+بنیانگذار
+۱۷۹
+ژوزف
+اردستان
+افزودم
+مطبوعاتی
+ارز
+جنجالی
+نوازندگی
+سوزان
+دارن
+افتادن
+هایشان
+تحقیقی
+سهند
+سپاسگذارم
+فیزیوتراپی
+محافظ
+ماشینی
+ربر
+یدالله
+میمون
+سیاستهای
+نگارهٔ
+چه؟
+صراحت
+رسته
+تجویز
+توفیق
+مغولستان
+کین
+وال
+ساکورا
+پیشروی
+متوفی
+تازی
+دیلم
+پلدختر
+میخواست
+صدیق
+نمیبینم
+ایلات
+درحالی
+غلات
+نوه
+هاله
+سیستمهای
+کتیبههای
+سیال
+منبر
+بیک
+۱۳۱۴
+۱۳۱۸
+حسين
+۱۷۱
+درشت
+سوق
+برنامهای
+گهواره
+دستآوردهای
+تعبیه
+رادیوی
+ساسان
+درامز
+۱۲۹۹
+تجسمی
+سیمان
+گنجی
+کشش
+اسلوونی
+ویلسون
+داماش
+إِنَّ
+کارتوگرافی
+کاشت
+دستان
+لید
+نوازندهٔ
+نمیشد
+قران
+ایدئولوژی
+کامپکت
+ناغان
+قرائت
+کاراکتر
+خانهها
+شفاهی
+فلهای
+شهرسازی
+اعتصاب
+۱۸۱
+ویدیو
+شايد
+ویرایشگر
+پردازد
+دادهاید
+حاد
+اجتهاد
+مرطوب
+کلماتی
+مهریز
+حلال
+بیافزایید،
+۱۵۷
+همجنسگرایان
+لینکی
+تطابق
+باورند
+دالاس
+إِلَّا
+اصولی
+کپیرایت
+الفبا
+کیهانی
+تاب
+شرعی
+محتوی
+هانری
+میدهند،
+یوگسلاوی
+بگذارم
+تداوم
+گریز
+نشدهاند
+شناختهشده
+انعطاف
+اندک،
+دعوا
+کری
+تبیین
+احساسی
+ساعات
+معاصر،
+پیشوند
+طبع
+میاندوآب
+اخترفیزیک
+مطمئنا
+پرسید
+انگل
+برکناری
+رولینگ
+حفاری
+زیارتگاه
+منتسب
+پیامهای
+گسسته
+طريق
+باخ
+۱۳۲۳
+کلیساهای
+معصومه
+شهروز
+متناوب
+۱۸۹۵
+پن
+ابراهيم
+۱۳۱۳
+بطوریکه
+رابین
+آموخته
+میدانهای
+تاریخنگاران
+بکر
+میش
+پخته
+قلمداد
+رویا
+باشید،
+سیستانی
+قومیت
+جرمی
+لوس
+آفرین
+تلف
+خوارزمی
+محتوایی
+سول
+دبط
+جُستارهای
+مینمود
+روزنامهها
+یت
+دگر
+بانکی
+سدان
+متغیرهای
+یابند
+بکارگیری
+انتاریو
+کوسه
+۱۶۴
+بلخی
+بیم
+خلخال
+حائری
+۱۸۹۳
+آوردهاند
+نقطهای
+علمجو
+استیل
+سلولهای
+گوگرد
+میتوانند
+گوارش
+سبزی
+۱۶۰۰
+جوراب۲
+زیرین
+ميشود
+پنبه
+آورد،
+حرفهای
+لنگرود
+فریمان
+سلاحهای
+میانگینجریان
+غبار
+مردانه
+مؤسسهٔ
+اسراییل
+تکنواز
+۱۶۶
+لکی
+خبرنگاران
+پالایشگاه
+مصلحت
+۱۷۷
+مجروح
+پرستش
+دوگانه
+مدفون
+ولیعهد
+سرزمینی
+آققلا
+اساسا
+بهر
+ملي
+كنار
+روستاي
+کلاسهای
+سفره
+نرمال
+وری
+کیف
+۱۸۸۰
+۱۹۸
+زدید
+زراعت
+رهنمودها
+توضيح
+۱۷۲
+۱۹۲
+پدیدار
+وایت
+بمانند
+لرد
+دستم
+ایسلند
+لیقوان
+نیافتم
+باتشکر
+تئودور
+عبادت
+تبديل
+نکردید
+مسلحانه
+دیزنی
+رانش
+فرهنگهای
+مخاطبان
+دول
+کتابت
+سلیم
+ایرانیتبار
+غلظت
+شونده
+۱۲،
+اوراق
+سامانی
+اقتصادی،
+۲۵۰۰
+شخصیتها
+فحش
+سربازی
+هشداردهنده
+ندرت
+۳۲۰
+میشه
+۱۸۹۷
+فروهر
+صلی
+سیوند
+انجمنهای
+بعلاوه
+ترشح
+فرج
+جاي
+بخیر
+محراب
+کارتان
+هجده
+قریه
+ربیعالاول
+ضخامت
+بارندگی
+بح
+نسیم
+زهره
+جادویی
+تالاب
+جنون
+بروی
+۱۳،
+فیلد
+کریسمس
+میزبانی
+میکنید،
+آپلود
+برگزیدگان
+یش
+خانوادهاش
+کریستوفر
+بیننده
+توکلی
+میسازند
+لنگ
+تداخل
+مقدمات
+۱۸۹۴
+الوند
+مع
+گناباد
+مزدا
+رکن
+عیلام
+ترقی
+منکر
+معامله
+اینچنین
+کول
+سازمانها
+مأموریت
+موعود
+دولتآباد
+بلبل
+طولی
+میرسند
+اجاقکندی
+ديگري
+ندارد؟
+براین
+مصور
+اعتقادی
+فرخزاد
+دربارهی
+خداآفرین
+گفتاری
+خوانی
+پارامترهای
+تهاجم
+آیوی
+توضیحاتی
+بشرویه
+۹۷۸
+کیست
+نداشت،
+شهروندی
+برخي
+۱۵۶
+سمرقند
+نوا
+كمك
+لامپ
+عماد
+رام
+اينکه
+ضمیمه
+بنابراین،
+تصویربرداری
+سیبری
+یوفا
+کلر
+گوجه
+حیف
+سواری
+۱۳۱۲
+طارم
+۲۶۰
+اباد
+عنوانهای
+مركز
+مقوله
+گوستاو
+مرعشی
+بحر
+تون
+انصار
+جداسازی
+تصفیه
+سازندگان
+ببنید
+محافل
+نقرهای
+تیرماه
+پیاز
+سرسبز
+انه
+چشمان
+تایباد
+اشیا
+طرد
+گوهر
+نکن
+هرزگوین
+اقلید
+خاص،
+ثالث
+علیرضا
+آنگونه
+مستمر
+عضوی
+هامبورگ
+پورتال
+تویوتا
+رامیان
+هخامنش
+اردل
+قاطع
+گنجینه
+روشنفکران
+تصادف
+۱۹۷
+جزیی
+مؤسس
+روبروی
+آلاسکا
+خوشهمهر
+آرد
+صالحی
+سونامی
+کشیش
+پروس
+انحصاری
+کاسته
+دوستانش
+گاوران
+دلالت
+۱۸۴
+اصحاب
+جزیرهها
+مهدوی
+آبیک
+افزايش
+مزیت
+جوابی
+صغیر
+منحنی
+رمین
+سانتیگراد
+دبیرکل
+غریبدوست
+بنزین
+اپیزود
+استانهای
+بهاءالله
+سپید
+کمونیستی
+سوگند
+شهباز
+اکتشاف
+استحکام
+مفاد
+بسازد
+اسکناس
+۱۴۰۰
+مبدأ
+بخورد
+مناظر
+زا
+پرستی
+تمبکا
+محرمانه
+سکنه
+زیتون
+رومانیایی
+جسارت
+عمومی،
+دات
+آهنی
+بینید
+مخابراتی
+نظرش
+مولداوی
+العظمی
+ولف
+ممکنه
+راننده
+اولاً
+وَمَا
+وسیلهای
+موی
+بادلو
+چرب
+مسافت
+مکس
+۱۷۸
+پودر
+عوام
+که،
+پنجم،
+گرگوری
+میسر
+مفصلی
+استبداد
+حیدرآباد
+آلیس
+فیروزه
+ریخت
+اینان
+کروی
+وقف
+شعارهای
+۱۹۶
+سملقان
+فروخته
+۱۷۴
+نبودهاست
+دیکتاتوری
+میدهم
+ظریف
+معتبرترین
+سیاسر
+ایرادات
+اجماعی
+۱۹۳
+منحل
+زاید
+میخواهم
+صاحبان
+مهلت
+میپرداخت
+ماهه
+جری
+بازرس
+وَلَا
+گلشن
+برهنه
+نوشتهام
+میشود؟
+صخره
+عمو
+ابد
+بیداری
+۱۸۸۸
+۲۷۰
+بعلت
+پنیر
+حاتمی
+خانقاه
+رس
+شکسپیر
+معذرت
+پايان
+ساختگی
+آموختن
+فقدان
+پاسخگویی
+زانو
+كوه
+لزوما
+قمر
+شهریاری
+بيان
+واین
+صورتیکه
+بدنبال
+پارهای
+ارمغان
+میشود؛
+شغلی
+دیگ
+عنبرآباد
+امریکایی
+پیشرو
+تجربیات
+علوم،
+پیریکندی
+ازجمله
+بهنام
+صومای
+۳۳۰
+۲۶،
+اسطورههای
+منفجره
+دستتان
+رشتهکوه
+۱۹۵
+برن
+بلده
+شیعی
+رحیمی
+رجایی
+کجور
+۱۵،
+تاون
+آموزگار
+آستارا
+هیل
+ترانهها
+یوری
+کلاله
+محو
+خوانندگی
+زار
+عیب
+افسانههای
+پخت
+نامبرده
+پنجشنبه
+سور
+نروژی
+تکنیکهای
+دریاچههای
+مالدیو
+سوسن
+کیسه
+کاوش
+دابودشت
+کردن،
+زندگان
+مقدمهای
+موزهٔ
+۱۸۸
+برپایی
+داگلاس
+فضلالله
+زینب
+اللَّهَ
+صحرایی
+کرت
+اذیت
+نمیرسد
+آتشفشان
+۱۳۲۱
+بلاروس
+انگ
+ارگان
+بسامد
+نشوید
+بزرگای
+کلارک
+۲۱،
+بشدت
+نقوش
+خوشنویس
+الفبایی
+نخ
+رفیق
+ناراحتی
+رسی
+بخواهند
+طرفداری
+دردسر
+۴۵۰
+۱۸۳
+ایرباس
+پرت
+فرآیندهای
+گردشگران
+مخرب
+میگم
+کارتون
+نوژن
+سفری
+صندلی
+میکرده
+نزنید
+ج۱
+میخواهید
+گنگ
+میریزد
+پشتکوه
+ویکیپدیاست
+دلاری
+ویکیفا
+خيلي
+بازگشایی
+چشمگیری
+نیتروژن
+بافی
+لانه
+بدید
+آشتیانی
+باشد؛
+محققین
+۲۴،
+یوتا
+طرفه
+توسعهٔ
+کشتیهای
+۲۰۶
+جاستین
+شوشتری
+اسمیتسونیان
+طوطی
+عباسیان
+ردهای
+زرند
+میرود،
+ابتکار
+دهلران
+بستان
+برجای
+۳۸۰
+رمانتیک
+ترجمههای
+کاربرها
+بندری
+پرداختن
+منهتن
+پاتریک
+طناب
+چهارم،
+نتواند
+بور
+دانستههای
+روحیه
+میلاد،
+برزنجیر
+مرجان
+دهند،
+شهرستانها
+سپرد
+داران
+استوارت
+دوچرخه
+طراحي
+۱۱۰۰
+خانهای
+نوآوری
+نامنظم
+کامپیوترهای
+دیوانسالاری
+وفادار
+هرودوت
+امسال
+استثنا
+فرانکفورت
+مجالس
+خدمتتان
+کتابداری
+لاین
+پوران
+آنالوگ
+برادوست
+۲۰۸
+شادباش
+میشناسند
+بولکیمده
+مینویسم
+چالدران
+کهنوج
+تطبیقی
+۱۶،
+دیدگاهی
+منحرف
+شنوایی
+تیز
+تیغ
+موشکی
+پرشیانا
+امیل
+ایزدان
+سهگانه
+پنجه
+۱۸۹۱
+۱۳۲۲
+دين
+قبله
+جهنم
+خدماتی
+ببرند
+مأمور
+نیستیم
+کلمهای
+اعتیاد
+فرانکلین
+معجزه
+ذهنم
+بازماندگان
+مصوبه
+کلینتون
+برسند
+معاهده
+نمیکنم
+چندگانه
+شهرستانی
+لاک
+موضوعاتی
+خوسف
+اسک
+خروس
+لتونی
+وات
+کرد؛
+رودکی
+خدمتم
+تاری
+مجلسی
+فهمید
+هفتگی
+کروز
+برگرداننده
+قیصر
+معروفی
+فكر
+نو،
+فضانورد
+فتحآباد
+هورمون
+الفاظ
+آمازون
+بیاوریم
+دستهٔ
+میکردید
+بینایی
+پافشاری
+بردم
+دیپلماتیک
+سنگینی
+ض
+نمره
+غیرآزاد
+فریب
+پذیرد
+حیطه
+اصلی،
+تربیتی
+محال
+ارجمند
+مییابند
+فلج
+اربر
+اینجا،
+آوای
+دودانگه
+چاهبهار
+همزه
+۲۳۸
+تمبر
+انوشیروان
+متنهای
+پشتوانه
+عجبشیر
+قسمتها
+آشوب
+بدرود
+نظرشان
+ههای
+روزتان
+استفان
+گیتاریست
+نشده،
+دینار
+چاره
+تیموری
+زهی
+مغولی
+۲۵۶
+هیوستون
+الموت
+۱۸۷۹
+راگبی
+لوکزامبورگ
+حیث
+عاج
+سختافزار
+رمانی
+نگهبانی
+پتروشیمی
+چادر
+صلیبی
+کنکور
+کانسار
+بلوچ
+زاهدی
+هستید؟
+دوبله
+طیفی
+نشریههای
+زنبور
+حزبالله
+اخوان
+اجزاء
+ژنو
+دعای
+مزمن
+سخنی
+نهایتاً
+اندرو
+میشوم
+۱۸،
+دارمشترانگ
+میدارند
+سهشنبه
+حفره
+زرندیه
+ذخایر
+۱۳۱۹
+زنجیر
+سبکی
+قیمتی
+جنیفر
+۲۰،
+تعمید
+آبگرم
+حکمرانی
+پلاستیک
+بینزاکتی
+تماشاگر
+لایحه
+بازه
+تحکیم
+موضعی
+جویی
+محافظة
+شاه،
+ما،
+۳۰،
+آمبرلا
+کلرادو
+هیجانی
+مجتهد
+گیاهشناسی
+اضطراب
+جنگافزارهای
+۱۹،
+ادوار
+مسیری
+چمران
+پایههای
+گیتاشناسی،
+نمیکنید
+گیل
+متین
+آدلر
+۱۷،
+بعدش
+باکس
+یاس
+حکمیت
+کیلوبایت
+بریده
+هموار
+معقول
+کروم
+۱۸۸۶
+غزنوی
+نوش
+بازنشستگی
+گوینده
+یکنمونه
+هنر،
+میاد
+عظمت
+جهش
+جانبداری
+شبكه
+آسا
+استاندار
+۲۰۹
+فرانسیسکو
+بریتنی
+محدودیتهای
+بشکه
+بنگرید
+تاثیرات
+آسفالت
+گیج
+کاروانسراهای
+فراموشی
+گلدار
+ترتیب،
+يافت
+همینجا
+بدخشان
+۲۵،
+تمدید
+زيادي
+هستش
+رضا۱۶۱۵
+بودی
+مهرماه
+اسکندریه
+لزوماً
+سیستمی
+هارون
+نگفته
+میدانیم
+سایوز
+آنرا
+نوزده
+بمبئی
+فان
+میدانند
+۱۸۷
+دانستند
+اجاره
+فورت
+مراقب
+نفرت
+نوی
+۲۰۴
+تدریجی
+تهی
+نورآباد
+گزاره
+کلامی
+نتیجهای
+پانک
+هاكل
+عفونی
+بسر
+پیشگامان
+بلاغ
+زئوس
+بريفين
+گزارشهای
+نمایندهٔ
+سیالات
+۱۸۲
+فارسان
+جلدی
+فلک
+تحقیر
+فهمیدم
+ناتو
+سایرین
+شناور
+انستیتو
+نیکو
+مارکسیسم
+تبعیت
+تفریح
+زبان،
+گلوگاه
+بقیهٔ
+کمپین
+احراز
+بودن،
+محکومیت
+کماکان
+بستری
+تروریست
+سرواژهٔ
+دانمارکی
+آمستردام
+همی
+داوید
+کافیست
+دنی
+رون
+۶۰۰۰
+لابد
+کانتری
+سس
+کسری
+میفرمایید
+سیاستمدار
+حریم
+معنویت
+عسکری
+بخشیدن
+محصور
+مدافعان
+گرایشهای
+واگن
+حجر
+سرداران
+مشهود
+یافتم
+تنسی
+نهر
+دارالفنون
+نمايش
+بسياري
+سابقهٔ
+یتیم
+توپولوژی
+۱۴،
+نگارشی
+جمعيت
+تنبیه
+کیو
+سقط
+شریفی
+کما
+میکروبیولوژی
+دیابت
+تاتنهام
+منقرض
+تاتی
+محمددین
+انگليسي
+فارسیسازی
+زمینهای
+شهدا
+۰۸،
+متکی
+کوهها
+دزد
+کنایه
+مشایخ
+ارزان
+ماسه
+هرمان
+تنظیمات
+اونجا
+خار
+هیلاری
+چنار
+خزانه
+شکاری
+عجایب
+رنو
+قراردادن
+جابر
+سروستان
+مستطیل
+مجموعهها
+بهمیی
+یکسال
+سرخرگ
+نادرشاه
+لیاقت
+دوستار
+وارده
+کاستیا
+لرزه
+اى
+بجا
+نم
+مغولان
+امارت
+کشاورزان
+طبی
+کجاست؟
+نبح
+نمایم
+للطباعة
+بکنند
+داستانها
+آمیخته
+تاريخي
+اندازهای
+پیکار
+مستعمره
+کوهپایه
+تصدیق
+۱۳۱۵
+فیلترینگ
+۰۹،
+آدینه
+توبه
+بصری
+بکنیم
+هوتک
+فیلمنامه
+پشتون
+زمره
+حبیبی
+اسکندری
+نیایش
+هائی
+رقابتهای
+داوطلب
+ازش
+بنظرم
+دلیجان
+رضی
+مصاحب
+پرون
+بازگو
+آگهی
+قولی
+سیسیل
+انگلیسیها
+مکاتب
+حبیبالله
+سانسکریت
+توکلآباد
+نمودهاند
+حیوانی
+پروژهها
+گیتی
+فالتز
+سنگسار
+بخت
+میلانی
+مارکوس
+نید
+شدیم
+۲۲۴
+مش
+فصول
+کتابش
+میخواهیم
+مشی
+آنی
+مادهٔ
+میکردند
+یکا
+طلبان
+عهدنامه
+الملل
+ارکان
+کاربریتان
+جلالالدین
+ایرونی
+یونس
+آبراهام
+فرشتگان
+فارسیزبانان
+۲۰۳
+۳۵،
+ناتمام
+موظف
+ایت
+میزنم
+ییلاق
+منی
+كم
+گریه
+بسازیم
+سیبک
+انجا
+موفقترین
+۱۳۰۷
+ثروتمند
+گریخت
+زماندار
+تروا
+ژرمنی
+برنارد
+تشكر
+ژنریک
+راهبردی
+گرههای
+پارسیگوی
+بندهای
+مبادله
+اسفندیاری
+سرتیپ
+خوارزم
+کلاغ
+ياد
+ايراني
+نجفآباد
+سولفات
+كامل
+ناظری
+شهرستانهای
+أَنْ
+میگ
+پادگان
+مرتضوی
+زياد
+کلود
+مقاصد
+بهارستان
+دیکتاتور
+باستان،
+۳۱،
+اسکای
+الکلی
+میباشند
+پارتی
+بیاورند
+لایههای
+پرتقال
+آمیزی
+۴۰،
+۱۸۶
+رستاخیز
+خرگوش
+فیبر
+لیبرالیسم
+مخترع
+ۗ
+تعمیم
+برمیگردد
+تلآویو
+خورش
+مولد
+ستم
+باغات
+نژادهای
+ضربات
+آنست
+ارواح
+جوار
+اپرای
+تحتانی
+آنتوان
+زحمتش
+۱۸۸۲
+بازگشتی
+رفت،
+۱۸۹
+هوگو
+گیلاس
+۲۰۵
+دستاوردهای
+قضائیه
+۴۰۰۰
+مستقلی
+رعنا
+بخوان
+۵۶،
+سوزی
+تلاشی
+هرکسی
+میلیمتر
+هفتهنامه
+برومند
+کباب
+سرمایهگذاری
+پلاتین
+دنیس
+وگاس
+قرآن،
+نصرتآباد
+۲۲۵
+۱۹۱
+بافق
+ژاله
+آبریز
+صدد
+املاک
+مقاله
+بوانات
+پژو
+زمانها
+کامیاران
+پگاه
+۲۰۲
+حرفهای
+ترغیب
+حک
+مسطح
+دیویدی
+جانبه
+سفیران
+غدد
+هستند؟
+مدرسههای
+۵۲،
+منبعدار
+چاله
+نائین
+مدير
+عکاسان
+آبخورده
+فیات
+خبرنامه
+مشهدی
+استرالیایی
+سیامک
+بگیر
+شایان
+درسته
+نامند
+ویرایشهای
+گلها
+مایا
+گروه،
+آتشفشانی
+کردهاست،
+نیمهٔ
+آزادشهر
+رانده
+علاقهای
+ثریا
+متشکر
+ولت
+فرزانه
+صورتهای
+دانشگاههای
+وز
+ویدئوی
+جنازه
+برتون
+جلوههای
+تغییرمسیرهای
+بیانیهای
+دون
+نبوی
+یکبار
+رک
+حزبهای
+مدارهای
+میگویم
+كنيم
+معلق
+تماشاگران
+نش
+نصیر
+۱۹۴
+رضاخان
+گردد،
+کنسولهای
+قسمتهای
+شورشیان
+دقیقتر
+مداخله
+علاءالدین
+استنباط
+مصرفی
+باردار
+اهورامزدا
+ادبيات
+باهنر
+مقرر
+عزاداری
+كلمه
+خونین
+محدودی
+نمیدارد
+ذوق
+پرسشهای
+بریم
+قشر
+۳۸،
+صالحآباد
+محسنی
+تخلص
+شکلهای
+شوی
+رنگها
+توربین
+مگابایت
+فسفات
+واجد
+اهانت
+محفل
+برحسب
+گیگا
+گيرد
+۱۸۷۰
+صنفی
+تنتن
+برگردانده
+دایناسور
+لای
+میبینیم
+۰۴،
+فرمائید
+سیارات
+۵۱،
+تص
+سرودهای
+معترض
+ممكن
+متا
+میشویم
+ثلاث
+گفتههای
+بیطرفانه
+هاپ
+نهان
+ادارات
+عجیبی
+جنایات
+دستورالعمل
+پارا
+نهادند
+ام،
+فتنه
+فواصل
+۱۸۵۰
+توریستی
+مرمر
+دیتابیس
+۴۲،
+کلیات
+۱۸۸۳
+لنین
+بلكه
+کاتوزیان
+میسیسیپی
+معاویه
+یوونتوس
+کشاورزی،
+هوافضا
+كوخرد
+فاریاب
+محيط
+نکنید،
+میترا
+رنگین
+آلپ
+آلومینیوم
+ملودی
+سیاستمداران
+گمر
+اسکان
+مختصری
+قشون
+جوادی
+رباتی
+۲۱۱
+جایز
+۲۷،
+محمودی
+كاربران
+یافتهاند
+بگذریم
+محوری
+زمانهای
+۲۲،
+انصراف
+میلا
+ساير
+۲۱۴
+تصریح
+۳۶،
+۲۸،
+آلباسته
+وظیفهٔ
+آذرشهر
+خدمه
+بارانی
+فیزیکدانان
+۱۸۸۴
+تماشای
+۱۳۱۱
+نويسنده
+علامرودشت
+افزاری
+گلشیری
+عملیاتهای
+داس
+ناخواسته
+هوتن
+واسه
+ثانیا
+لینه
+سنج
+اروپا،
+ایلیا
+بازمانده
+بشریت
+شناسی،
+۱۷۰۰
+کالیفرنیا،
+نکردهام
+سیلیکات
+آزاده
+کامنت
+یونیکد
+آمدم
+احضار
+تودهای
+فرایندهای
+بیماریها
+آخه
+تبلور
+۰۷،
+۲۰۷
+مونوبوک
+تصمیمات
+اختراعات
+جشنوارهٔ
+مشاهدات
+ریزشگاهها
+۲۹،
+فیلادلفیا
+یزید
+سکولار
+خشایارشا
+سنتور
+محافظه
+کاپ
+نادرستی
+علی،
+محیطهای
+منفرد
+اهتمام
+القاعده
+علاقهٔ
+لرزش
+عصبانی
+پسند
+لیل
+۲۲۶
+جدای
+جواهر
+ژولیوسی
+کوچک،
+شمیرانات
+بخوانند
+ربیعالثانی
+۵۰،
+۲۳۵
+توپخانه
+نیکلاس
+ویستا
+فردیناند
+۲۸۰
+تشییع
+نمیکند
+موسیقی،
+نیرومند
+۱۸۷۸
+غفاری
+بفتا
+هویدا
+صدیقی
+سلیمانی
+سياسي
+شهرضا
+جوانرود
+انتشاراتی
+شخصه
+۵۵،
+آسیابهای
+خوب،
+راههای
+والنشر
+حماسی
+عکسها
+۲۱۲
+۱۸۸۵
+تعریفی
+قاسمی
+مصادف
+مفرغ
+گشتاور
+۱۸۷۵
+شکلگیری
+طهماسب
+موجودیت
+ستارهها
+آوردید
+سازههای
+۲۱۷
+ببریم
+ارسنجان
+بیدگل
+مگه
+عبادی
+فایلهای
+۱۸۷۶
+تبریز،
+رهنما
+سپر
+قارهای
+وو
+جعبهای
+دانشنامه
+اجتماعي
+هیجان
+کارتر
+نرسید
+۳۳،
+کارم
+نمیشود،
+نسلکشی
+نمونه،
+صمد
+دریک
+میله
+پلاسما
+زاغده
+داروین
+۴۴،
+ویس
+قاچاق
+املای
+نامیدن
+گنجانده
+شادگان
+نیبید
+۲۲۲
+تسهیل
+هلن
+ناپدیدشدن
+خطها
+ابلاغ
+شمع
+بازی،
+فندقاع
+جوهر
+پترزبورگ
+هخ
+سکو
+۴۱،
+یاسر
+۵۷،
+مستلزم
+آلبومی
+کلک
+ضخیم
+پاشا
+۲۳،
+۱۸۸۱
+دیانای
+حسابهای
+غلامعلی
+خواندند
+معلمان
+همیلتون
+مداری
+مست
+تصویرها
+اندیشهٔ
+شدیداً
+دیواندره
+کنن
+بشوند
+نیامد
+مانگا
+۱۳۱۷
+چسب
+شجاعت
+مشتاق
+ایرا
+دانا
+بریتیش
+ویکیپدیاها
+مهمتر
+روبرت
+کافه
+ئی
+ارضی
+دستکم
+دندانپزشکی
+مهرآباد
+كننده
+رضوانشهر
+پراگ
+پال
+فرسایش
+درگاهها
+راور
+میکروسکوپ
+فشارهای
+آرزومندم
+مصاحبهای
+ویولن
+دریافتکنندگان
+نجیب
+سئول
diff --git a/perf/texts/hi-words.txt b/perf/texts/hi-words.txt
new file mode 100644
index 0000000..1dc18dc
--- /dev/null
+++ b/perf/texts/hi-words.txt
@@ -0,0 +1,10000 @@
+के
+में
+की
+है
+का
+और
+से
+को
+है।
+एक
+पर
+श्रेणी
+वार्ता
+भारत
+हैं
+भी
+यह
+शीर्षक
+पूर्व
+लिए
+गाँव
+ईसा
+उत्तराखण्ड
+किया
+ने
+इस
+संवत
+कि
+हिन्दी
+जो
+।
+जाता
+गया
+या
+जिले
+वर्ष
+जिला
+नहीं
+कर
+साँचा
+ही
+हैं।
+करने
+हो
+रूप
+था
+साथ
+द्वारा
+जन्म
+तहसील
+फ़िल्म
+होता
+तथा
+बाद
+विकिपीडिया
+आधार
+अन्य
+प्राचीन
+कुछ
+सदस्य
+अपने
+इसके
+प्रदेश
+तो
+एवं
+तक
+चित्र
+बाहरी
+राज्य
+जा
+प्रकार
+सरकार
+नाम
+दिया
+होती
+स्वागत
+कई
+वह
+बिहार
+करते
+सप्तर्षि
+जैसे
+थे
+समय
+अनुसार
+आदि
+वे
+सकते
+अधिक
+वाले
+किसी
+आधिकारिक
+सकता
+कड़ियाँ
+भारतीय
+उत्तर
+मण्डल
+हुए
+न
+जाती
+प्रखण्ड
+हुआ
+क्षेत्र
+लेख
+द
+बनी
+होने
+उसके
+करता
+इन
+अंग्रेज़ी
+संदर्भ
+थी
+था।
+शक
+कारण
+भाषा
+बहुत
+स्थित
+पहले
+उनके
+प्रसिद्ध
+सहायता
+जब
+दो
+अपनी
+कोई
+सबसे
+अलावा
+स्थान
+होते
+कम
+विश्व
+लिये
+ये
+जाने
+बारे
+लेकिन
+प्रयोग
+उन्होंने
+राष्ट्रीय
+वर्षों
+कहा
+पृष्ठ
+गए
+रहा
+आप
+देखें
+व
+एक्स्प्रेस
+तरह
+मे
+करना
+शामिल
+सभी
+प्रमुख
+आंध्र
+इसी
+अमेरिका
+प्राप्त
+करें
+अन्तर्गत
+इसे
+माना
+सितंबर
+उस
+५७
+इसका
+जानकारी
+नगर
+मुख्य
+हुई
+शिक्षा
+उन्हें
+संस्कृत
+कलियुग
+बीच
+गई
+विक्रमी
+रहे
+उपयोग
+मार्च
+पोर्टल
+काम
+वेबसाइट
+जनवरी
+कुमाऊँ
+उसे
+शहर
+जाते
+उनकी
+लोग
+जिसमें
+देश
+दी
+संघ
+थे।
+भाग
+लोगों
+जीवन
+१
+कार्य
+जी
+फिल्म
+विशेष
+बार
+ओर
+२
+इतिहास
+कभी
+दोनों
+अब
+निर्माण
+२००९
+पुरस्कार
+वाली
+शब्द
+पताका
+अधिकांश
+चिह्न
+विकास
+धर्म
+केवल
+लिया
+ए
+दक्षिण
+पुराने
+जुलाई
+यहाँ
+नया
+स्टेशन
+फिर
+लगभग
+संयुक्त
+अलग
+आन्ध्रप्रदेश
+गढ़वाल
+स्थल
+दिल्ली
+ई
+आरम्भ
+अपना
+जून
+विस्तृत
+यदि
+प्रान्त
+इसकी
+सूत्र
+शुरु
+मंदिर
+जालपृष्ठ
+जिसे
+घटनाएँ
+कृषि
+दौरान
+करती
+निधन
+दिन
+संगीत
+यहां
+तीन
+क्योंकि
+इसमें
+साहित्य
+ऑफ़
+मूल
+भूगोल
+॥
+पास
+पटना
+नए
+हालांकि
+सिंह
+प्रदर्शित
+प्रतिरूप
+अप्रैल
+बात
+विषय
+टेनिस
+२०१०
+प्रतियोगिता
+प्रचलित
+कहते
+विज्ञान
+विभिन्न
+अगस्त
+ऑफ
+पद्धति
+छत्तीसगढ़
+सन्
+जाना
+शुरू
+बना
+समूह
+अनेक
+थी।
+ता
+प्रामाणिक
+मध्य
+रही
+सूची
+संख्या
+व्यक्ति
+ऐसा
+गणना
+प्रति
+आज
+तब
+उनका
+क
+इलाहाबाद
+ऐसे
+मैं
+काल
+हम
+युद्ध
+गया।
+वाला
+श्री
+आदर्श
+स्थिति
+सी
+सकती
+दिसंबर
+प्रदान
+विक्रम
+विश्वविद्यालय
+रेलवे
+बड़े
+सामूहिक
+किया।
+किए
+राज्यक्षेत्र
+यातायात
+उन
+चार
+उपरोक्त
+दर्शाता
+बन
+अर्थ
+अलीगढ़
+दूसरे
+तौर
+गयी
+५८
+अन्तर
+उत्तरा
+राजा
+प्रभा
+क्या
+घटित
+मानकर
+विभाग
+कैलेंडर
+देने
+बनाने
+खेल
+प्रथम
+हिंदी
+इन्हें
+एकल
+उसकी
+एंड
+मसीह
+अथवा
+अमेरिकी
+जहां
+उदाहरण
+कलाकार
+निकाले
+आवश्यक
+७८
+महत्वपूर्ण
+पुरुष
+मई
+नदी
+जिसके
+प्रभाव
+आम
+जूलियन
+योगदान
+किये
+अधारित
+ले
+अधार
+इस्तेमाल
+सेवा
+३०७६
+जिसका
+३१०२
+पंचाग
+६६७६
+चर्चा
+भोजपुरी
+कैसे
+उर्दु
+कलेण्डर
+करके
+चाहिए
+स
+कला
+उपलब्ध
+जनसांख्यिकी
+साल
+काफी
+फर्रुखाबाद
+आगरा
+कंपनी
+३
+उच्च
+अक्तूबर
+आ
+मेरा
+स्तर
+नवंबर
+नीचे
+देता
+अध्ययन
+जारी
+कोड
+पहली
+प्रणाली
+अगर
+ओपन
+ध्यान
+उसका
+नामक
+बड़ी
+जल
+नैनीताल
+अक्सर
+अंग्रेजी
+सरकारी
+वर्तमान
+रंग
+जिससे
+मेल
+पुलिस
+रखा
+प्रत्येक
+हर
+बनाया
+ट्रेन
+सामान्य
+दुनिया
+भूमिका
+लिंक
+दे
+जबकि
+सन्देश
+शरीर
+पता
+भागलपुर
+विचार
+जहाँ
+लगा
+लेकर
+बड़ा
+वर्ग
+आगे
+छोटे
+तथ्य
+समाज
+पानी
+इससे
+उसने
+देशों
+महिला
+इसलिए
+देना
+पर्यटन
+एस
+परिणाम
+अल्मोड़ा
+सब
+स्थापना
+बाह्य
+स्थापित
+पौड़ी
+दल
+माध्यम
+आधारित
+पश्चिम
+प्रदर्शन
+सर्वश्रेष्ठ
+चीन
+शक्ति
+बाहर
+बी
+ऊपर
+बेगूसराय
+उत्पन्न
+हेतु
+डी
+आशीष
+अतिरिक्त
+समान
+वीं
+हिन्दू
+गये
+परिवर्तन
+आधुनिक
+लिखा
+कुमार
+देखा
+अंत
+मार्ग
+मानव
+रेल
+अक्टूबर
+आपको
+घर
+प्रश्न
+दूर
+कन्नौज
+भटनागर
+सामाजिक
+प्रकाशित
+अभिनेता
+देते
+कुल
+अभी
+जिस
+होना
+आई
+४
+पूरी
+संबंधित
+रहता
+ज्ञान
+ब्रिटिश
+कृपया
+हस्ताक्षर
+व्यक्तिगत
+बिना
+नई
+रोग
+१०
+दशक
+अधिकार
+परिवार
+शैली
+लेखक
+संस्करण
+जिनमें
+सेना
+संबंधी
+औरंगाबाद
+प्रक्रिया
+यात्रा
+२००८
+नये
+आवश्यकता
+ऐसी
+स्वयं
+होगा
+संबंध
+चिकित्सा
+मात्रा
+परियोजना
+प्रबंधक
+१५
+विकसित
+संदेशों
+होकर
+प्रकाश
+पहाड़ी
+पहला
+आकार
+सुधार
+जगह
+पन्ना
+सही
+मैथिली
+तैयार
+नवम्बर
+पिता
+मुक्त
+क्षेत्रों
+रचना
+१२
+२००७
+पूरा
+पी
+संस्थान
+५
+लोक
+१३
+चरित्र
+तुलना
+हुआ।
+लाल
+उत्पादन
+जनसंख्या
+रहते
+उसी
+इनके
+ा
+१४
+संदेश
+ज्यादा
+शताब्दी
+मृत्यु
+साधारण
+पाकिस्तान
+मास्टर्स
+दूसरी
+पुस्तक
+भगवान
+इनमें
+पूर्ण
+लाभ
+टीम
+बैंक
+अवधि
+भिन्न
+खिलाड़ी
+ली
+सदस्यों
+आने
+प्रयोक्ता
+कार्यक्रम
+सीमा
+समर्थन
+संस्कृति
+े
+अंतिम
+स्कूल
+बने
+विकि
+टी
+अ
+पाया
+नही
+र
+सदी
+फरवरी
+मुझे
+सन
+परिचय
+लेने
+मेरे
+पार्टी
+उत्तरी
+लिखने
+१८
+दिसम्बर
+राम
+भर
+विशिष्ट
+मी
+क्षमता
+प्रयास
+सहित
+पश्चिमी
+सिद्धांत
+दर्शन
+सभा
+किंतु
+वर्णन
+विधि
+श्रृंखला
+बजे
+संगठन
+गीत
+एम
+बेबल
+राजधानी
+प्रभावित
+पौडी
+ठीक
+सुझाव
+गति
+प्रबंधन
+व्यापार
+सामग्री
+ना
+एन
+दृष्टि
+दिया।
+पद
+ब्रजभाषा
+म
+सूचना
+शोध
+नामांकन
+अवधी
+लोकप्रिय
+आन्ध्र
+हाथ
+रहने
+विस्तार
+ऑस्ट्रेलिया
+वृद्धि
+फ़रवरी
+११
+जैसा
+आर
+कहानी
+व्यवस्था
+क्रिकेट
+बागेश्वर
+पृथ्वी
+चमोली
+गांव
+युग
+यौगिक
+कहीं
+पूर्वी
+२०
+सुरक्षा
+मुखपृष्ठ
+स्पष्ट
+१६
+मिलता
+देवी
+यही
+बुंदेली
+सामने
+प्रवेश
+यूरोप
+रखने
+दिए
+जॉन
+जिन्हें
+दूसरा
+पूरे
+स्थानीय
+आते
+नियंत्रण
+चीनी
+दिखाई
+प्रकाशन
+ऊर्जा
+प्राकृतिक
+की।
+जैन
+लगता
+बनाए
+अमरीकी
+कवि
+व्यापक
+दर
+वजह
+वहाँ
+परीक्षण
+लंदन
+प
+ी
+बदल
+जाए
+अदिलाबादु
+शासक
+खोज
+द्वितीय
+बस्तर
+मदद
+योजना
+ब्रिटेन
+प्रस्तुत
+जे
+धार्मिक
+आर्थिक
+सहायक
+लेखन
+शुरुआत
+मिल
+डॉ
+प्रौद्योगिकी
+शासन
+स्रोत
+रायगढ़
+वैज्ञानिक
+कमी
+आपके
+मिनट
+पत्र
+निर्वाचन
+रक्त
+ऑफिस
+गूगल
+संग्रह
+उद्योग
+राष्ट्र
+एशिया
+सांस्कृतिक
+पदार्थ
+इनका
+आपका
+मुंबई
+हिस्सा
+दृष्टिकोण
+उद्देश्य
+वी
+ह
+दूरी
+आता
+अनुवाद
+वो
+पीछे
+भूषण
+क्रिया
+स्वास्थ्य
+पैदा
+केंद्र
+२०११
+अच्छे
+पद्म
+शब्दों
+ऐतिहासिक
+गैर
+पिथोरागढ
+छोटी
+६
+सार्वजनिक
+कपूर
+प्रेम
+मुंगेर
+रहती
+चैनल
+समस्या
+कनाडा
+अंतर्गत
+देवनागरी
+राष्ट्रपति
+जिसने
+बैंड
+साम्राज्य
+कॉलेज
+मगही
+प्रयुक्त
+पुत्र
+अनुसंधान
+पहचान
+निर्मित
+किमी
+बंद
+प्रतिशत
+लगे
+अंतर्राष्ट्रीय
+ताकि
+भूमि
+मानक
+इंग्लैंड
+सके
+प्रारंभिक
+सन्दर्भ
+थीं
+अंगिका
+दिशा
+जर्मनी
+१९
+संकेत
+बच्चों
+द्वीप
+समाचार
+अफ्रीका
+घोषणा
+रह
+बंगाल
+भाषाओं
+घंटे
+हाल
+राजस्थान
+वहां
+आया
+उपन्यास
+कानून
+दिनों
+अभिनेत्री
+खिलाफ
+सदर
+अनुमति
+हवाई
+टीवी
+समाप्त
+मीडिया
+उपचार
+हमारे
+जनता
+नियम
+संक्षेप
+मन
+मिलियन
+चौपाल
+उपकरण
+राज
+भीतर
+चेन्नई
+२८
+कृष्ण
+क्लिक
+३०
+कविता
+कथा
+सूर्य
+प्रेस
+वीडियो
+स्वतंत्रता
+वन
+राजनीतिक
+आमतौर
+देती
+दृश्य
+न्यू
+योग्य
+लागू
+मिला
+बताया
+मैच
+जिसकी
+सा
+मीटर
+नेटवर्क
+रोचक
+भोजन
+हूँ
+मौजूद
+धीरे
+१७
+संभव
+माता
+नृत्य
+७
+महत्व
+परन्तु
+आशा
+डॉलर
+शायद
+आयोजित
+सम्मान
+युगल
+कांग्रेस
+सफल
+उर्दू
+उनमें
+वापस
+चाहिए।
+दें
+मनुष्य
+लाख
+महान
+निजी
+उल्लेख
+जैसी
+इनकी
+व्यवहार
+पन्ने
+नीति
+जाति
+एल
+पोस्टर
+विशाल
+बल्कि
+संचालित
+देखने
+विवाह
+अच्छा
+ख़ान
+२६
+इ
+कृष्णा
+वंश
+जापान
+केन्द्र
+मेरी
+तमिल
+देख
+विजेता
+वेब
+शिव
+सिर्फ
+न्यूयॉर्क
+भाई
+यूरोपीय
+राजीव
+प्रयोगस्थल
+उत्पाद
+मंच
+पांच
+०५
+पंजाब
+०४
+राजमार्ग
+मॉडल
+कंप्यूटर
+स्वीकार
+अंतर
+कार्बनिक
+सक्रिय
+परंतु
+लखीसराय
+किलोमीटर
+यमकेश्वर
+चला
+आलेख
+पड़ता
+उसमें
+ज्ञानसन्दूक
+आपने
+हमें
+मान
+इंजन
+तहत
+पत्रिका
+अवस्था
+९
+चम्पावत
+ं
+सहयोग
+मौलिक
+मामले
+अच्छी
+तिथि
+आरंभ
+स्वतंत्र
+बल
+बाजार
+८
+प्रारंभ
+मूल्य
+सरल
+वास्तव
+यू
+उससे
+तुम
+मैंने
+पुनः
+सागर
+पक्ष
+०६
+छोड़
+खाना
+अनुभव
+टू
+तरफ
+बस
+विजय
+महाराष्ट्र
+समुद्र
+उचित
+रेडियो
+चल
+हटाने
+खुद
+समीक्षाएँ
+जीव
+तेल
+दिल
+उम्र
+जर्मन
+ग्रंथ
+रूस
+संपर्क
+बौक्स
+रखें
+गंगा
+एल्बम
+राय
+पाठ
+हासिल
+निश्चित
+सीमित
+सात
+प्रांत
+गई।
+नेपाल
+दक्षिणी
+काव्य
+निर्णय
+छोटा
+२५
+डिजाइन
+रात
+हों
+लगाया
+वास्तविक
+पूछे
+ज्ञात
+प्रकृति
+कार
+गए।
+निर्वाचित
+तरीके
+त
+ज
+चुनाव
+किन्तु
+बढ़
+२१
+हो।
+जीत
+विपरीत
+दस
+वर्मन
+औसत
+इंडिया
+सम्मानित
+२२
+नाटक
+अधिनियम
+वस्तु
+संरचना
+मत
+सर्वाधिक
+लेखों
+विश्वास
+मास
+संकिपा
+वायु
+शीघ्र
+घटना
+निम्न
+विरोध
+सप्ताह
+स्वरूप
+प्रवेशद्वार
+सितम्बर
+गुरु
+सॉफ्टवेयर
+निर्धारित
+विद्युत
+रक्षा
+पूर्णिमा
+पड़ा
+बावजूद
+बेहतर
+वर्ल्ड
+चुका
+भारी
+मगध
+समुदाय
+क्यों
+ऑस्ट्रेलियाई
+जनगणना
+लीग
+अंक
+मिलती
+भागों
+बाल
+भेज
+कप
+कोरिया
+कर्नाटक
+मात्र
+हुई।
+अत्यंत
+तत्व
+महाभारत
+ओ
+अरब
+पूजा
+निर्माता
+रोमन
+विदेशी
+अल
+पर्वत
+पिछले
+इनसे
+पार्क
+स्थानों
+जिन
+धारा
+चुके
+मिली
+जाकर
+बदलने
+स्वामी
+सम्मेलन
+२३
+बनाये
+अल्मोडा
+शो
+जंक्शन
+मन्दिर
+गलत
+सफलता
+लिपि
+पाए
+योग
+निर्भर
+सिस्टम
+प्रसाद
+गांधी
+प्रचार
+फ्रांस
+वर्मा
+जिन्होंने
+रहें
+बौद्ध
+बच्चे
+आंदोलन
+एच
+तंत्र
+मोबाइल
+कोशिश
+अध्यक्ष
+गैस
+प्यार
+सारे
+ल
+लक्ष्य
+अवश्य
+लेते
+आसपास
+चरण
+पर्याप्त
+आयु
+शर्मा
+कार्बन
+सुरक्षित
+कोलकाता
+शीर्ष
+२७
+मै
+समिति
+धन
+विवरण
+सुविधा
+खान
+आती
+जिनके
+यद्यपि
+मामलों
+प्रशिक्षण
+सिटी
+कैंसर
+पात्र
+इतना
+रिपोर्ट
+नेतृत्व
+महिलाओं
+फल
+महीने
+सड़क
+देव
+मान्यता
+क्लब
+अनंतपुर
+क्रम
+य
+बजाय
+साँचे
+उप
+२४
+विश्लेषण
+आनन्द
+यूनानी
+चाहते
+राज्यों
+फाइनल
+अवार्ड
+जुड़े
+अत्यधिक
+तकनीक
+अज्ञात
+निकट
+सेंट
+चलता
+रेखा
+निर्देशक
+इंडियन
+मानते
+देवता
+जांच
+हे
+पत्नी
+इंटरनेट
+केरल
+जोखिम
+रिकॉर्ड
+बदलाव
+डिग्री
+प्रतीक
+जाएगा
+अतः
+पालन
+खंड
+विष्णु
+भौतिक
+जिनका
+अकादमी
+होगा।
+गुण
+वित्तीय
+क्षेत्रफल
+कर्नूलु
+करें।
+भाव
+तापमान
+०७
+अनुमान
+डे
+अमरीका
+रासायनिक
+च
+ग
+अभिनय
+पत्थर
+खाता
+किस
+गणराज्य
+टेस्ट
+चोर
+इत्यादि
+शुद्ध
+होगी
+भिकियासैण
+संघर्ष
+अंतरराष्ट्रीय
+लगातार
+माँ
+उल्लेखनीय
+रखते
+लक्षण
+जेम्स
+ग्रह
+प्राय
+वही
+औद्योगिक
+संक्षिप्त
+२००६
+विमान
+टिप्पणी
+नागरिक
+ध्वनि
+याद
+संचार
+बराबर
+प्रधान
+अमेरिकन
+पारंपरिक
+युक्त
+अत
+पुरी
+प्रतिक्रिया
+शाह
+चक्र
+अवसर
+हमेशा
+शारीरिक
+हंडिया
+आबादी
+तट
+लाइन
+विकल्प
+अंग
+लोकसभा
+खाद्य
+पर्यावरण
+संसार
+विवाद
+बनने
+करीब
+व्यक्तियों
+०
+वैदिक
+बिक्री
+ब
+निम्नलिखित
+कोशिका
+पार
+परमाणु
+भवन
+समझ
+नष्ट
+स्वर
+दुर्ग
+जितना
+प्रकट
+फॉर
+विमानक्षेत्र
+रख
+रुप
+शहरों
+तकनीकी
+लखनऊ
+मुद्रा
+हिस्से
+झील
+आयोजन
+इकाई
+मील
+समस्त
+संरक्षण
+अंदर
+संस्था
+परंपरा
+सतह
+कार्यों
+विद्यालय
+संसद
+अभियान
+सिद्ध
+मुख्यालय
+प्रस्ताव
+सीधे
+सर्वोच्च
+डालकर
+वाहन
+गुजरात
+उपयुक्त
+राशि
+बोली
+सक्षम
+अधिकतर
+नेशनल
+प्राथमिक
+मौत
+इसने
+गणित
+अली
+व्यवसाय
+हवा
+मिट्टी
+अगले
+फिल्मों
+चले
+डेविड
+मिलते
+बनाई
+महल
+आक्रमण
+रे
+राजनीति
+मंत्री
+गंभीर
+शाखा
+अम्ल
+हटा
+तटस्थ
+भविष्य
+ईश्वर
+आए
+वि
+दावा
+प्रसारण
+जीवित
+कड़ी
+रखें।
+लिमिटेड
+अन्दर
+क्रांति
+लिखे
+मैदान
+धातु
+एफ
+सम्बन्ध
+विलियम
+हृदय
+संभावना
+वातावरण
+न्यायालय
+लगाने
+सैन्य
+परिवहन
+परिषद
+चारों
+पवित्र
+योगदानकर्ताओ
+गुणवत्ता
+खगड़िया
+शेष
+करे
+ला
+युवा
+नियमित
+ऑन
+सर
+पसंद
+दबाव
+ईरान
+लागत
+०९
+०८
+२९
+अधिकारी
+उनसे
+कहना
+बोर्ड
+ग्रहण
+अशोक
+स्टार
+जान
+दिखाया
+ग्राम
+स्पेन
+नीतियाँ
+सभ्य
+०००
+समारोह
+संविधान
+इटली
+आठ
+संग्रहालय
+तर्क
+दूतावास
+पाने
+लिया।
+पाँच
+थलीसैंण
+लगी
+जन
+ताप
+परिणामस्वरूप
+लॉग
+लिखी
+रॉक
+कार्ड
+प्रेरित
+आगंतुकों
+फूल
+तेलगू
+लेता
+मिले
+रोगी
+आक्षेप
+जरूरत
+गठन
+व्यक्त
+भुगतान
+मौसम
+मीडियाविकि
+अन्तर्राष्ट्रीय
+पदार्थों
+पूर्वाग्रह
+रहे।
+शादी
+पुरा
+विषयों
+बिलियन
+ढंग
+आदेश
+लंबे
+काउंटी
+धन्यवाद
+मुस्लिम
+विरोधी
+वेल्स
+लिखें।
+पुरानी
+कांडा
+रानी
+विभाजित
+मिलकर
+तारा
+वैसे
+ईसाई
+पू
+शिकार
+ज्ञानसंदूक
+नेता
+शास्त्र
+कौन
+राजवंश
+ब्लैक
+अस्तित्व
+धारी
+प्र
+०३
+तेजी
+रायपुर
+संवाद
+किनारे
+टाइम्स
+भार
+सिर
+उत्तरप्रदेश
+छह
+आलोचना
+दिये
+गुप्त
+गेम
+नियंत्रित
+पुराण
+उद्यान
+डालें।
+हिंदू
+डीवीडी
+परीक्षा
+वालों
+घरेलू
+वस्तुओं
+व्याख्या
+पौराणिक
+अर्थात
+फूलपुर
+करोड़
+दिवस
+लघु
+जिसमे
+पिथौरागढ
+विज्ञापन
+पेश
+चर्च
+घोषित
+कंपनियों
+पशु
+पाएँ
+दर्द
+चलते
+समाधान
+माइकल
+सामना
+पूछें
+लड़ाई
+जोड़ें।
+संपादित
+जनरल
+विविध
+मिश्र
+आग
+भावना
+टिल्ड
+कैलंडर
+हत्या
+ग्रेगोरी
+प्रशासन
+रिलीज़
+खास
+मध्यम
+ज्यादातर
+अरबी
+रानीखेत
+देखते
+पाई
+आसानी
+अंश
+कश्मीर
+नवागंतुकों
+प्रभावी
+लिख
+किताब
+जीन
+इंडियाना
+चूंकि
+सत्य
+गंगोलीहाट
+नामांकित
+कोशिकाओं
+कार्यालय
+छात्र
+मस्तिष्क
+डेटा
+अनुनाद
+मंडल
+चुकी
+नारायण
+कर्म
+संपूर्ण
+प्रतिनिधित्व
+पहुंचती
+तेज
+अपेक्षा
+जाएगा।
+व्यंजन
+आत्मा
+वैश्विक
+मांग
+सेट
+इन्होंने
+सम्पूर्ण
+बदलें
+लग
+एशियाई
+रोड
+ऑनलाइन
+इस्लाम
+दास
+संत
+पक्षी
+बीबीसी
+व्यावसायिक
+सीज़न
+फुट
+जानते
+संक्रमण
+विचारों
+चाहता
+मतलब
+विरुद्ध
+रसायन
+निवेश
+वर्षा
+प्रमंडल
+संस्कार
+केन्द्रीय
+अंतरिक्ष
+ध्वज
+विशेषता
+बाकी
+थीं।
+यूनिवर्सिटी
+शंकर
+दैनिक
+आचार्य
+सं
+अनुरोध
+गायक
+मानसिक
+जमा
+हाउस
+मंत्रालय
+पहुंच
+जॉर्ज
+उपस्थित
+मार
+प्रधानमंत्री
+अंततः
+घनत्व
+थराली
+दूध
+सेवाओं
+वर्णित
+नियमों
+यूनाइटेड
+साथी
+विभाजन
+आपकी
+चौबटाखाल
+सम्मिलित
+प्रवाह
+गोल
+हुए।
+बिलासपुर
+कह
+जलवायु
+ब्राह्मण
+समर्पित
+निवास
+फोन
+प्रमाण
+पैमाने
+बिजली
+रोहित
+शांति
+अति
+उत्पत्ति
+तीसरे
+आनंद
+हमारी
+एकमात्र
+नुकसान
+मिलने
+पे
+सौ
+घटनाओं
+मां
+प्रायः
+भौतिकी
+कठिन
+माने
+घाटी
+अधीन
+स्थिर
+लेना
+उपयोगी
+रखना
+छूटती
+द्वार
+वेद
+चैम्पियनशिप
+बिंदु
+जुड़ा
+कल्पना
+आये
+संपादन
+तारे
+दें।
+परिभाषित
+उ
+सिद्धार्थ
+जापानी
+ऊंचाई
+भौगोलिक
+समुद्री
+आदमी
+उपकरणों
+स्त्री
+वाक्य
+निर्देश
+मशीन
+०२
+सत्र
+फुटबॉल
+घाट
+उपग्रह
+पंथ
+बहुधा
+हाइड्रोजन
+लंबी
+श
+सुंदर
+दौर
+रखता
+फ़ाइल
+मोहन
+देकर
+काला
+नंबर
+उपस्थिति
+दवा
+जीवनी
+आंतरिक
+परिवर्तित
+ज्ञानकोष
+वहीं
+आय
+समझा
+निगम
+वृक्ष
+पॉल
+बुद्ध
+बाज़ार
+मराठी
+रूसी
+जय
+ग्रैंड
+संचालन
+तत्वों
+व्यक्तित्व
+कीया
+३१
+कारणों
+बनाना
+अपराध
+फिल्में
+चक
+व्यास
+चाहे
+छोड़कर
+नमस्कार
+टेलीविजन
+डा
+वितरण
+एक्स
+पुराना
+रामायण
+बेरीनाग
+ग्रामीण
+सेंटर
+लाइसेंस
+मित्र
+छात्रों
+अध्याय
+शेयर
+अभाव
+मानना
+विद्वानों
+जनजातियां
+वैकल्पिक
+तुर्की
+जैव
+पश्चात
+नहीं।
+डिजिटल
+तारीख़
+समीक्षा
+हजार
+प्रिय
+इतनी
+अर्जुन
+शराब
+स्मृति
+जीता
+उच्चारण
+श्रीलंका
+बीजापुर
+निकल
+स्वीडन
+सत्ता
+संपत्ति
+गर्म
+बीमारी
+अर्थात्
+५०
+सम्राट
+व्रत
+मिश्रण
+वार्षिक
+प्रत्यक्ष
+अंकित
+रॉबर्ट
+समूहों
+आपूर्ति
+इंजीनियरिंग
+कैलिफोर्निया
+उनको
+गेंद
+इच्छा
+रन
+ऋषि
+समस्याओं
+आन्दोलन
+अपेक्षाकृत
+रोम
+चाहिये
+चलने
+गतिविधियों
+गाने
+विम्बलडन
+हैरी
+एण्ड
+इंच
+सेवाएं
+वेस्ट
+वें
+जाये
+पहुँच
+हूं
+श्रेष्ठ
+रहा।
+हार
+अस्पताल
+निरंतर
+नियुक्त
+तारों
+ख
+केंद्रीय
+वर्तनी
+धारण
+दान
+वाराणसी
+स्टूडियो
+रोगियों
+कुकर्म
+साधन
+जटिल
+अक्षर
+देंगे
+स्कोर
+उत्पादों
+प्रोटीन
+अनिवार्य
+२००१
+कायमगंज
+सौर
+सरगुजा
+साबित
+ऊँचाई
+लीला
+सैनिक
+स्टेडियम
+रायगढ
+पर्व
+जयपुर
+व्याकरण
+रावत
+इसलिये
+करेगा
+तीव्र
+प्रकाशक
+कृतियाँ
+प्रसार
+नोबेल
+सभ्यता
+परिसर
+अफ़्रीका
+राजनैतिक
+इलाज
+साहित्यिक
+सतपुली
+लिखित
+फ्रेंच
+देखे
+ऋण
+अकबर
+सोवियत
+हमला
+प्रोग्राम
+मिस्र
+डाला
+छत्तीसगढ
+आयोग
+पुरुषों
+रस
+सुनिश्चित
+पेरिस
+साहित्यकार
+परिभाषा
+डाटा
+अर्थव्यवस्था
+महाराज
+ओम
+सह
+पेज
+जिनकी
+वर्ण
+दर्ज
+भारती
+तभी
+तय
+एसोसिएशन
+अनुपात
+झारखंड
+जोड़ा
+पुन
+छत्तीसगढ़ी
+यानि
+लकड़ी
+त्वचा
+अधिकतम
+कोरबा
+देखकर
+डाल
+पुरालेख
+कोइल
+बढ़ती
+सफेद
+प्रतीत
+कानूनी
+चयन
+बनता
+हाथों
+जल्दी
+चार्ल्स
+ग्रन्थ
+रोक
+कारक
+खाने
+अभ्यास
+कैरियर
+वर्गीकरण
+सर्वेक्षण
+नारायणपुर
+मिश्रित
+ें
+तमिलनाडु
+प्राप्ति
+आकर्षित
+भेजा
+बनाकर
+संग्राम
+किले
+अड्डा
+कहलाता
+महसूस
+मार्क
+माल
+वजन
+फ़्रेंच
+ठोस
+उपयोगकर्ता
+चम्पा
+सलाह
+भेद
+काफ़ी
+लोगो
+खाते
+निर्देशन
+स्वर्ण
+बनाते
+नोकिया
+मूर्ति
+हद
+रोकने
+समाप्ति
+अकाउंट
+कार्यक्रमों
+ग्रीक
+संधि
+लंबाई
+निवासी
+दौरे
+चाहें
+क्षेत्रीय
+स्थायी
+किंग
+न्याय
+मोटर
+संभवतः
+बनाता
+पेड़
+तल
+पति
+वां
+कराया
+शुरूआत
+प्रारूप
+काले
+कांकेर
+रखे
+पौधों
+खेलों
+००
+काशी
+मस्जिद
+हरा
+आकर्षण
+नयी
+रखी
+मजबूत
+कडप
+आजकल
+टंकण
+साक्षात्कार
+तीसरी
+खेती
+महासागर
+लाया
+जोड़
+सामान्यतः
+सम्बंधित
+सुन्दर
+रचित
+जांजगीर
+पृष्ठों
+दीवार
+उन्होने
+विद्या
+लाने
+पड़ती
+संयोजन
+तीसरा
+पड़
+रोगों
+संसाधन
+भाषाएँ
+मानचित्र
+जमीन
+देहरादून
+मुगल
+कोर्ट
+कवर्धा
+धमतरी
+जशपुर
+पौधे
+कदम
+आकर
+बढ़ा
+अधिकारियों
+आरोप
+मिलाकर
+बढ़ाने
+प्रशासनिक
+हमले
+टाइम
+प्रेरणा
+उड़ान
+शक्तिशाली
+पीपी
+महासमुन्द
+विधानसभा
+फीट
+प्रगति
+स्नातक
+सूक्ष्म
+जवाब
+कम्प्यूटर
+अप
+छवि
+फ़िल्मों
+भ
+शुल्क
+विभूतियाँ
+कलाकारों
+संकट
+संभावित
+दिशानिर्देश
+जोर
+विधान
+आहार
+गोठ
+उपाधि
+राजनांदगांव
+जम्मू
+सतनाम
+कर्णप्रयाग
+थोड़ा
+बाबा
+साइट
+तथापि
+दन्तेवाड़ा
+यानी
+अमर
+मार्टिन
+तुरंत
+जिले।
+लाइव
+पुनःप्राप्त
+निर्धारण
+तत्कालीन
+कक्षा
+सारी
+प्रजातियों
+गये।
+करो
+मूल्यांकन
+द्वाराहाट
+राजशाही
+घई
+होगी।
+गैरसैण
+हॉल
+बिल
+ऐ
+रूपों
+मंगल
+जानी
+चित्रण
+नीतियां
+शिक्षण
+अवधारणा
+चेक
+किला
+तीनों
+मारे
+इमारत
+आवासीय
+किंगडम
+राजीवमास
+चुना
+आँकड़े
+फलस्वरूप
+करेंगे
+ज्योतिष
+यंत्र
+ग्राहक
+चित्रों
+नौ
+सल्ट
+उम्मीदवार
+कोश्याँकुटोली
+बीज
+उत्कृष्ट
+०१
+कम्पनी
+महात्मा
+खर्च
+केंद्रित
+सिन्हा
+हाई
+प्रबंधकों
+मुश्किल
+नर
+गाँधी
+बनाएं
+करनी
+हूँ।
+स्टेट
+प्
+दार्शनिक
+निकाल
+मनोरंजन
+पुस्तकालय
+सोचते
+जेल
+हिमालय
+पा
+जहाज
+तरल
+यूनिकोड
+सैन
+हास्य
+पैर
+दि
+दी।
+खराब
+ख़ुदा
+कृति
+पुष्टि
+हल्द्वानी
+असम
+अर्थशास्त्र
+सेवन
+ग्रंथों
+कड़ियां
+बदले
+पुस्तकों
+हेनरी
+रिचर्ड
+परम
+सके।
+पृ
+रहना
+हल
+सर्वप्रथम
+सामान
+काली
+चेतावनी
+मनोविज्ञान
+बॉक्स
+छोड़ने
+संगठनों
+तारामंडल
+हैदराबाद
+छिबरामऊ
+मुख्यतः
+टैग
+४०
+यहूदी
+विद्रोह
+दर्शकों
+ग्रुप
+जोशी
+डीडीहाट
+सेन
+गरुङ
+कीमत
+पीटर
+कृत्रिम
+विपणन
+प्राण
+आस
+बुनियादी
+वीर
+जल्द
+ऊपरी
+टिप्पणियाँ
+नज़र
+पहुंचा
+लेखकों
+ईंधन
+गुणों
+२००४
+स्ट्रीट
+बचपन
+लैटिन
+मलयालम
+हिमाचल
+सरस्वती
+स्वामित्व
+जंगल
+भनोली
+भक्ति
+श्रीकृष्ण
+नवीन
+मैन
+पीढ़ी
+शहरी
+लव
+अररिया
+अनुबंध
+विश्वभर
+स्मारक
+पुर्णीमा
+देवताओं
+पढ़ें
+प्रसारित
+परिस्थितियों
+रास्ते
+टाटा
+वा
+तरीका
+विषाणु
+अनुप्रयोग
+ईरानी
+यात्री
+संशोधन
+क्रमांक
+पंडित
+ते
+माह
+मुक्ति
+गहराई
+सुबह
+यहीं
+नाथ
+संबद्ध
+उत्तम
+प्रजाति
+मापन
+गद्य
+टीका
+वित्त
+विख्यात
+अवतार
+उपनिषद
+दीया
+मुहम्मद
+राजाओं
+फैसला
+परंपरागत
+जर्नल
+व्यापारिक
+होंगे
+एयर
+चौखुटिया
+मथुरा
+लगते
+उसको
+तनाव
+सिंगापुर
+उत्सव
+पुणे
+अभिव्यक्ति
+बढ़ावा
+इसको
+बच्चन
+द्रव
+अनुरूप
+एट
+मेट्रो
+उत्सर्जन
+एलबम
+हरियाणा
+चलती
+वाणिज्यिक
+डॉक्टर
+चली
+मानी
+लगा।
+लॉस
+सैनिकों
+सवाल
+२००५
+आरंभिक
+निदान
+अतरौली
+कराने
+मालिक
+देर
+तीर्थ
+विदेश
+यथा
+प्रबंध
+संपादक
+जैविक
+दोस्त
+मि
+अनुकूल
+संस्थापक
+इंटरनेशनल
+स्लैम
+सकारात्मक
+टाइप
+पुस्तकें
+रा
+मियामी
+लगे।
+ड
+घटक
+निदेशक
+इतने
+प्रतिनिधि
+मितुल
+अंग्रेजों
+दोनो
+बांग्लादेश
+वनस्पति
+बढ़ने
+बंदरगाह
+आसान
+सटीक
+मनाया
+भू
+समकालीन
+पाठक
+दोष
+औपचारिक
+डिस्क
+बेटी
+संदर्भित
+निभाई
+राव
+सूरज
+मगर
+चलचित्र
+मछली
+देखी
+जगत
+ज़्यादा
+सर्वर
+लम्बाई
+ग्रेट
+कर्मचारियों
+पंजाबी
+अगला
+शाही
+दर्जा
+चिकित्सक
+विकार
+फैला
+शुक्ल
+प्रजनन
+हां
+सदा
+अग्रणी
+नायक
+गृह
+धन्यवाद।
+जालस्थल
+आवाज
+बनाम
+कपकोट
+संघीय
+बिग
+गलती
+विविधता
+नो
+लगती
+पेट
+रिलीज
+विद्वान
+अन्तिम
+कॉपीराइट
+नमक
+अधिकारों
+प्रणालियों
+युकेश
+आर्ट
+रॉयल
+बालक
+पश्चात्
+हटाया
+पर्यटक
+आर्य
+प्रीमियर
+शब्दावली
+परत
+सिद्धांतों
+हमारा
+अकार्बनिक
+चोट
+कौशल
+प्रारम्भ
+विकेट
+गुना
+ब्रह्म
+आयरलैंड
+पेशेवर
+इस्पात
+ठाकुर
+अग्नि
+कोश
+रुचि
+उपनाम
+दत्त
+उम्मीद
+पशुओं
+श्रेय
+मुम्बई
+निकाला
+सिख
+पदक
+कवियों
+इसीलिए
+मार्शल
+बॉलीवुड
+खन्ना
+प्रवृत्ति
+यौन
+रचनाओं
+उड़ीसा
+तेलुगू
+आश्रम
+अस्पष्ट
+माइक्रोसॉफ्ट
+महत्त्वपूर्ण
+चयनित
+शास्त्रीय
+कर्मचारी
+जैक
+खो
+विशेषकर
+शब्दकोष
+स्क्रीन
+प्रतिमा
+बर्फ
+फारसी
+महाराजा
+ब्लू
+शून्य
+जरूरी
+आनेवालों
+दौरा
+प्रतिभा
+सच
+मौजूदा
+क्षति
+स्थलों
+खून
+फ़िल्में
+प्रशंसा
+होटल
+सेल
+सालों
+थ
+दुर्गा
+हाँ
+स्मिथ
+बुक
+नोट
+रचयिता
+शिखर
+नेहरू
+ब्रांड
+सुख
+समझने
+मुंह
+महाविद्यालय
+ईस्ट
+शृंखला
+बचाने
+आध्यात्मिक
+पुल
+त्याग
+आविष्कार
+हजारों
+कहता
+जाय
+प्रक्रियाओं
+विलय
+दूसरों
+जाए।
+२०००
+वापसी
+आकाश
+थॉमस
+इलेक्ट्रॉनिक
+कडियाँ
+संगीतकार
+परस्पर
+मुख्यमंत्री
+उपभोक्ता
+प्राणी
+होनी
+आउट
+स्व
+उपनिषदों
+वक्त
+कक्ष
+यांत्रिक
+आंशिक
+बांग्ला
+संकोच
+शनि
+ट
+हिन्द
+पट्टी
+लंबा
+कन्या
+जीवों
+नैतिक
+किशोर
+फ्रांसीसी
+वस्त्र
+शिकागो
+नदियों
+संस्थाओं
+ो
+गतिविधि
+कठोर
+सोने
+कंपनियां
+बेटे
+प्रतिरोध
+दवाओं
+न्यूनतम
+खैर
+गरीब
+मेला
+निकटतम
+स्थानांतरित
+लौट
+विटामिन
+जोड़ने
+ब्रायन
+यादव
+सहारा
+अफ्रीकी
+सिनेमा
+रचनात्मक
+नामों
+यज्ञ
+स्थितियों
+तृतीय
+हुये
+रिंग
+पोषण
+कहने
+उपाय
+विशेषज्ञ
+चार्ट
+क्लासिक
+मानवीय
+कार्रवाई
+एक्सप्रेस
+निर्देशित
+सम्बन्धित
+ग्राहकों
+चलाने
+अड्डे
+चेतना
+देखभाल
+रंगों
+विकी
+कल
+संबंधों
+सम्पर्क
+निष्कर्ष
+तंत्रिका
+वैज्ञानिकों
+टॉम
+प्रयत्न
+२००३
+पाठ्यक्रम
+चिंता
+३५
+श्रम
+बहन
+काल्पनिक
+डब्ल्यू
+कपड़े
+डबल्यू
+जातियों
+खाड़ी
+गीता
+हाथी
+डिज़ाइन
+एकीकृत
+कन्नड़
+खतरा
+प्रस्तावित
+खरीद
+अन्त
+कार्यरत
+ग्रीन
+विकिरण
+असफल
+हानि
+लोहाघाट
+कानपुर
+खिलाड़ियों
+छ
+सूचित
+अयोध्या
+स्टॉक
+चन्द्र
+गवर्नर
+लिंक्स
+फ़ारसी
+खनिज
+मंदिरों
+गिरावट
+पोखरी
+सारा
+आवाज़
+वायरस
+विलियम्स
+राधा
+सेंट्रल
+सहमत
+बातें
+रामनगर
+लिंग
+श्वेत
+लक्षणों
+दर्शनीय
+बाराकोट
+ऐंड
+सन्
+रास्ता
+वसा
+शती
+बदला
+उन्नत
+हिन्दुस्तान
+३६
+पृष्ठभूमि
+हार्ट
+सहज
+गिटार
+इतालवी
+पर्यटकों
+हरे
+खुले
+वर
+व्युत्पन्न
+जाँच
+धारणा
+मुख
+होली
+खड़े
+प्रतिष्ठित
+पड़ा।
+बचने
+निवासियों
+बरो
+लेती
+पीठ
+पाकिस्तानी
+रामचरितमानस
+आपस
+समझौते
+महीनों
+कर्ण
+हिस्ट्री
+सो
+पोस्ट
+पंक्ति
+बहु
+संशोधित
+कोलंबिया
+बचाव
+रिकॉर्डिंग
+थोड़ी
+चुने
+चौधरी
+अंकों
+शाम
+बातचीत
+ओलम्पिक
+गर्मी
+फ्लोरिडा
+गोली
+लाइफ
+लम्बी
+बम
+चावल
+बातों
+वर्गों
+आवास
+मिशन
+सफ़ेद
+४५
+दशा
+अपलोड
+मेडिकल
+जानने
+कार्यकारी
+सकतें
+समीप
+संयंत्र
+नि
+आवेदन
+मांस
+गहरा
+तरीकों
+छः
+कल्याण
+लगने
+हुसैन
+औ
+संजय
+जंगली
+केन
+सुपर
+सबूत
+साफ
+क्रमश
+लॉर्ड
+समझौता
+नाडु
+अदालत
+आगमन
+प्रथा
+डालने
+औषधि
+करवाया
+जिम्मेदार
+यान
+पन्नों
+महावीर
+सकें
+परम्परा
+मेक्सिको
+गोल्डन
+गईं
+टन
+एकदिवसीय
+आदि।
+ऑल
+१००
+प्रदूषण
+अणु
+चोपड़ा
+भा
+संरक्षित
+प्रभावशाली
+पुचः
+जुड़ी
+प्रोत्साहित
+तल्ला
+साधना
+न्यूटन
+लोकप्रियता
+भरा
+प्रार्थना
+बंगाली
+द्रव्यमान
+व्यावहारिक
+ट्रैक
+सावधान
+बैठक
+तुम्हारे
+पॉटर
+रथ
+प्रोग्रामिंग
+कही
+कमल
+मशहूर
+नजर
+धरती
+स्वाभाविक
+चेहरे
+सकता।
+शिशु
+कोण
+पॉप
+मन्त्र
+५१
+निवेदन
+अकेले
+आवृत्ति
+३२
+उठा
+कवर
+गरम
+शैक्षिक
+वास्तुकला
+पाते
+खूबसूरत
+एसिड
+होता।
+जायेगा
+पड़े
+सीजन
+नीला
+योग्यता
+वैध
+ग्लोबल
+पथ
+बीमा
+हिस्सों
+माप
+मैने
+बारह
+उल्लंघन
+जानवरों
+प्रवासी
+साहब
+एजेंसी
+हिट
+सुविधाओं
+सोच
+रवि
+गीतों
+पेन
+गुजराती
+अगली
+दर्शाया
+पतन
+चित्रित
+आकृति
+मैसूर
+बुद्धि
+मंत्र
+मनुष्यों
+पत्रकार
+पेय
+विद्यमान
+मादा
+बोलने
+मना
+बेस
+सहयोगी
+हराया
+समीकरण
+लिखते
+फसल
+संहिता
+लें
+तिलक
+प्रोफेसर
+सीधा
+आकर्षक
+संज्ञा
+मोटे
+वार
+खगोलीय
+क्रमशः
+समर्थक
+स्नान
+नकारात्मक
+नक्षत्र
+पहुंचने
+चित्रकार
+दुर्लभ
+सिद्धान्त
+भाँति
+छाया
+पूंजी
+आलोचक
+अपनाया
+बेहद
+खड़ा
+सका
+उदय
+भूल
+यमुना
+क्रेडिट
+साउथ
+नैदानिक
+हिल
+में।
+फ
+नील
+प्रयोगशाला
+५२
+शासकों
+मा
+हिसाब
+इन्हीं
+रॉय
+गाय
+घायल
+ऋतु
+तार
+लम्बे
+३८
+संपन्न
+क्रिस
+कृत
+उतना
+नामकरण
+स्वाद
+मनोवैज्ञानिक
+भय
+नौसेना
+हावड़ा
+४८
+श्याम
+कार्यवाही
+हस्तक्षेप
+दंड
+दुबई
+किस्म
+अभियांत्रिकी
+फ़िल्मफ़ेयर
+मोहम्मद
+उर्जा
+पारित
+गोरखपुर
+अस्थायी
+स्तंभ
+मुसलमानों
+असामान्य
+कैथोलिक
+वर्गीकृत
+पाप
+मनीष
+श्रेणियों
+भरे
+४६
+पढ़ने
+बिल्कुल
+खुला
+उद्यम
+मूलतः
+जोड़ी
+युनाइटेड
+दरबार
+मद्रास
+निकालने
+विरासत
+संगम
+निहित
+गिर
+कथन
+दाब
+आवश्यकताओं
+कहानियों
+ऑक्सफोर्ड
+आफ
+उन्हीं
+आधा
+मर
+सोसाइटी
+ब्लॉग
+मल्ला
+कालाढूगी
+आकलन
+अत्यन्त
+पकड़
+चाहिये।
+भरी
+भाषण
+आधे
+रत्न
+टूर
+नाना
+संस्थानों
+कालेज
+शल्य
+।।
+नौकरी
+जुड़ने
+गा
+मास्टर
+किरदार
+कुशल
+पक्षियों
+अधिग्रहण
+मजबूर
+खड़ी
+बताते
+अनिल
+महाद्वीप
+हथियार
+कलकत्ता
+प्लास्टिक
+पायलट
+स्वस्थ
+जिनसे
+रचनाएँ
+शिवाजी
+परिक्रमा
+२००२
+भोपाल
+पटकथा
+खत्म
+ड्राइव
+रूपांतरण
+भक्त
+४२
+अन्यथा
+उच्चतम
+बढ़ता
+असर
+रेड
+घरों
+व्हाइट
+आना
+खाली
+जॉनी
+राहुल
+कमजोर
+ब्राज़ील
+श्रीमती
+चाय
+रखकर
+ॐ
+एपिसोड
+मुसलमान
+जाया
+एडवर्ड
+पारी
+बांध
+विस्फोट
+उर्फ
+गुरू
+डच
+प्रमाणित
+समग्र
+मतदान
+कण
+पाटी
+प्रोटोकॉल
+विकिपीडीया
+हिंसा
+आजादी
+तस्वीर
+४७
+चुनौती
+क्रांतिकारी
+शेर
+न्यूजीलैंड
+ऑक्सीजन
+बनते
+निगरानी
+व्यवस्थित
+सर्विस
+आखिरी
+चिन्ह
+समृद्ध
+प्रयासों
+रेस
+पाता
+खतरे
+उन्हे
+पटेल
+बादशाह
+गर्भ
+हमने
+चरम
+मुखर्जी
+चलकर
+पाउंड
+जातक
+टिप्पणीसूची
+न्यायाधीश
+५५
+अनुच्छेद
+शास्त्री
+हि
+५३
+पेशकश
+बिट
+गणेश
+जीवाणु
+संकलन
+पीड़ित
+ख़ास
+बेस्ट
+निकलने
+लोहे
+ऑव
+स्वर्ग
+सोसायटी
+बेल
+भट्ट
+बढ़ते
+दुर्घटना
+त्यौहार
+संगणक
+विनोद
+हालाँकि
+न्यूज़
+गहरी
+पब्लिक
+४३
+तीव्रता
+पेटेंट
+तिब्बत
+पीने
+इस्लामी
+भीड़
+बहादुर
+ड्रामा
+सुल्तान
+हटाए
+अन्तरविकि
+साक्षरता
+विक्टोरिया
+सिनसिनाटी
+मठ
+प्रतिदिन
+सम्बन्धी
+निबंध
+बनाती
+नव
+विषय।
+तेलुगु
+वीकीपीडीया
+ऊतक
+असली
+संसाधनों
+जानवर
+डाक
+बाग
+डर
+स्रोतों
+प्रतिबंध
+सोमेश्वर
+कब्जा
+रहित
+अवशेष
+वरिष्ठ
+बेल्जियम
+देशी
+जीतने
+रणनीति
+हें
+ताल
+द्रव्य
+खेला
+राजस्व
+रीति
+गयी।
+सजा
+उपयोगकर्ताओं
+बोस
+आलोक
+आत्म
+फ़्रांस
+किसान
+गणितीय
+ज्वालामुखी
+अंगों
+ों
+बनती
+४९
+कायम
+खिताब
+तुलसी
+लक्ष्मी
+समानता
+वयस्क
+शिष्य
+संतुलन
+अचानक
+नदियाँ
+नीतियों
+नागरिकों
+जाल
+नामित
+नेताओं
+पात्रों
+सिविल
+कप्तान
+दुश्मन
+चमक
+अर्जित
+मौखिक
+स्वभाव
+आनुवंशिक
+कितने
+भागीदारी
+चोरी
+रोशन
+आलोचकों
+बोल
+गहरे
+गेट
+स्तरीय
+बता
+बहस
+जावा
+खासकर
+पड़ने
+दौड़
+३७
+निर्माताओं
+विशेषताओं
+माई
+काट
+५६
+सृष्टि
+फाउंडेशन
+संप्रदाय
+उपर
+प्रखंड
+एटा
+प्रकरण
+अक्षय
+स्कॉटलैंड
+राजकुमार
+इंग्लिश
+आइपी
+ध्रुव
+मैक
+अनुमानित
+मधुमेह
+गौतम
+चरणों
+कहे
+ि
+महादेवी
+निम्नांकित
+कथित
+परिणामों
+लिखना
+गाड़ी
+कॉम
+लड़की
+उद्धृत
+ब्लॉक
+३९
+टेलीविज़न
+एकता
+खेलने
+कारों
+सांसद
+चौथे
+सहमति
+बचा
+गाइड
+भले
+हा
+कां
+रिसर्च
+ज़मीन
+आयुर्वेद
+बॉब
+मुद्दों
+सोडियम
+तरंग
+चालक
+बाघ
+साइंस
+ग्लोब
+सकल
+मिलान
+बताता
+जिलों
+जिम
+पत्रिकाओं
+लगाना
+वाशिंगटन
+बैंकिंग
+प्राणियों
+ै
+ईमेल
+३३
+निर्दिष्ट
+पोर्ट
+पुर्तगाली
+चीज़
+बाबू
+अखिल
+उदयपुर
+चोटी
+शक्तियों
+मापदंड
+ण
+घातक
+माध्यमिक
+मारा
+जरिए
+इकाइयों
+५४
+लेजर
+विधियों
+खण्ड
+देखना
+कान
+प्रस्तुति
+३४
+अक्षांश
+कइ
+मानकों
+गुफा
+रखती
+सुरक्षीत
+होम
+करियर
+कारकों
+पत्रकारिता
+पृष्ठ।
+प्रचलन
+अनुक्रम
+इगलास
+जूनियर
+विनिमय
+अनुवादक
+विद्यार्थी
+निर्यात
+शब्दार्थ
+केन्द्रित
+सम्पादन
+बोध
+ब्रह्मा
+फ़ोन
+चाल
+ध
+अंडे
+हनुमान
+ज़
+बास्केटबॉल
+समापन
+राग
+छोर
+साहिब
+शांत
+यॉर्क
+अद्भुत
+राष्ट्रों
+सदन
+प्रसंग
+मोशन
+तकनीकों
+परामर्श
+पैसे
+एवम
+पं
+पृथक
+सरदार
+माया
+मारने
+लेबल
+टु
+निचले
+अतिथि
+महादेव
+परियोजनाओं
+दर्शक
+विकिपीडियन
+जगदीश
+विकिपरियोजना
+मुख्यत
+सीमाओं
+मुकाबले
+प्रताप
+यौगिकों
+बजट
+५९
+अहमद
+चलाया
+अहमदाबाद
+अनुपम
+पूर्ति
+पिक्चर
+स्कूलों
+अंग्रेज
+स्वीकृति
+बसा
+धरोहर
+आंकड़े
+बैटरी
+फूलों
+बेटा
+गर्मियों
+प्रबन्धक
+जोड़े
+महाकाव्य
+जन्मे
+गानों
+वनों
+लेन
+बाह
+एकत्रित
+नेपाली
+अमीर
+नीदरलैंड
+कहानियाँ
+मेयर
+ऑपरेशन
+एक्शन
+श्रेणियाँ
+४१
+चुंबकीय
+मृत
+मुद्दे
+हित
+तोड़
+करे।
+बर्मा
+कहलगाँव
+कहाँ
+बैंकों
+मेले
+ग्रहों
+परे
+ब्रज
+ऑस्टिन
+सूचीबद्ध
+जरिये
+दूरभाष
+कितना
+प्रभावों
+वध
+वर्णमाला
+कितनी
+सचिव
+पवन
+मैक्स
+पिछला
+सौंदर्य
+लो
+खबर
+वाह्य
+प्रचालन
+री
+प्रभाकर
+पहल
+प्रभाग
+अनुसरण
+पहलू
+धूम्रपान
+रिकार्ड
+प्रशांत
+अक्षरों
+कथानक
+पारिवारिक
+लाहौर
+भाषाओँ
+यात्रियों
+घास
+जनपद
+विचारधारा
+बिलकुल
+सीता
+प्रतिष्ठा
+निशान
+टॉप
+अवैध
+दूरसंचार
+लौह
+अतीत
+छत
+इंक
+पूर्णिया
+कोर
+एलन
+उद्योगों
+निष्क्रिय
+क्यूबा
+वेग
+स्टील
+टाउन
+यूनान
+साफ़
+अलंकार
+विफल
+कुत्ते
+सम
+करना।
+मलेशिया
+तैयारी
+भव्य
+ार
+पुत्री
+इमामगंज
+वकील
+४४
+संकेतों
+मूल्यों
+बाई
+भ्रम
+पाल
+ब्याज
+गहन
+अंतराल
+चौथी
+प्रतिस्पर्धा
+निश्चय
+कारोबार
+बच
+कोटि
+साझा
+खुल
+लन्दन
+सार
+राज्यपाल
+पराजित
+स्नातकोत्तर
+रात्रि
+शानदार
+हॉलीवुड
+नाटकों
+पीला
+ब्राजील
+ऊंची
+पाये
+जोशीमठ
+सदस्यता
+पैरों
+हॉट
+आँख
+शिक्षक
+घिरा
+फ़ाइलों
+कथाओं
+बिगाड़
+रुपये
+तू
+संदेह
+लेखा
+क्रिसमस
+भूकंप
+बुरी
+हवेली
+बीकानेर
+जोधपुर
+कहलाते
+करनेवाले
+दशकों
+प्रदेशों
+कमरे
+वुल्फ़
+जितनी
+खतरनाक
+गुगल
+मामला
+रक्तचाप
+डा०
+रविवार
+लीये
+स्थापत्य
+वाहनों
+छूट
+हों।
+प्रो
+जातीय
+फंड
+चौक
+सिक्किम
+मिस्टर
+टूर्नामेंट
+रहमान
+जड़
+बनवाया
+इलाके
+गठबंधन
+किरण
+गोपाल
+कागज
+शुभ
+मिस
+एयरलाइंस
+लाखों
+तत्काल
+अवार्ड्स
+मौका
+गोल्ड
+व्यापारी
+हरी
+सलाहकार
+मनु
+फ़र्रूख़ाबाद
+अपवाद
+मूवी
+जोन्स
+फ्रॉम
+शिकारी
+ऑडियो
+महेश
+गौरव
+ऊँचा
+कब
+सतत
+पहाड़
+अनिरुद्ध
+अध्ययनों
+इंदिरा
+उपर्युक्त
+एकत्र
+महर्षि
+भर्ती
+सोचा
+गुरुआ
+शुरुआती
+अभियान्त्रिकी
+जनवादी
+पड़ी
+आंख
+फ़्राँस
+गोवा
+जैंती
+ट्रस्ट
+सर्जरी
+संयोग
+गिरफ्तार
+रामपुर
+समाजवादी
+सृजन
+बपतिस्मा
+कोष
+आराम
+मैचों
+बसे
+पैदल
+तलाश
+थियेटर
+शुष्क
+विश्वयुद्ध
+प्रतिद्वंदी
+परिवर्तनों
+एकदम
+भ्रूण
+मासिक
+द्वीपसमूह
+माला
+फैल
+नरेन्द्र
+स्टोन
+उठाया
+सारणी
+प्रारम्भिक
+बेतालघाट
+बीस
+त्रुटि
+संगठित
+क्लास
+एड
+आयरिश
+हू
+ललिता
+आग्रह
+संतान
+प्रबल
+नहर
+डॉन
+प्रवाहित
+स्पेनिश
+बनावट
+भाषाएं
+करा
+प्रोत्साहन
+भ्रष्टाचार
+उष्णकटिबंधीय
+गाना
+उपरांत
+पोलैंड
+बनायी
+आएगा।
+पादरी
+फैशन
+बजाए
+टूट
+सोनी
+गले
+मलेरिया
+बंगलौर
+पढ़ाई
+क्रिस्टल
+चौड़ाई
+जोकि
+व्यय
+मिला।
+विवेक
+अब्दुल
+परिवारों
+बाधा
+भूत
+रंगीन
+राजेश
+नींव
+हाइड्रोकार्बन
+पीले
+राकेश
+बुलाया
+इंस्पेक्टर
+परिचित
+वेतन
+इलेक्ट्रिक
+तरी
+खोला
+पदों
+मेन
+स्तरों
+रोजगार
+डोमेन
+मानता
+सेकंड
+६०
+ईसवी
+सिरे
+नाइट
+गभाना
+यथार्थ
+लि
+कीट
+भावनाओं
+नरेश
+करार
+जानता
+कार्यकाल
+सिडनी
+रमेश
+परिमाण
+भरत
+कार्ल
+खोल
+म्यूज़िक
+पठार
+शाखाओं
+गुप्ता
+कार्लो
+तिरवा
+वर्षीय
+चक्रवर्ती
+दिव्य
+चंद्र
+पावर
+विथ
+पूरक
+मुफ्त
+ग्रस्त
+रोज़
+समुदायों
+शैक्षणिक
+नीले
+भिन्नता
+फ़
+देन
+जाएँ
+अनेकों
+काउंसिल
+प्रतिद्वंद्वी
+माइक
+चालू
+सम्भव
+क्रियाओं
+शहीद
+विश्वविद्यालयों
+चौथा
+सदैव
+सुधीर
+नागपुर
+दु
+नवाब
+स्पर्श
+कोट
+दलों
+लगाए
+इतिहासकार
+ओवर
+फ़तेहाबाद
+ऑस्ट्रिया
+हार्ड
+मुकदमा
+स्टीव
+चीज
+पायी
+बादल
+आकाशगंगा
+आवरण
+भेजने
+सुनील
+कुश्ती
+ईसापूर्व
+२००
+मुनि
+स्
+बृहस्पति
+प्रयोगों
+बयान
+खाँ
+शब्दकोश
+स्वचालित
+सिम्बल
+पसंदीदा
+उत्तराधिकारी
+संसदीय
+गायन
+क्षमा
+आतंकवाद
+पत्रों
+हरिद्वार
+लगाकर
+अतएव
+गार्डन
+बैठे
+मदन
+चौहान
+चन्द्रमा
+उठाने
+जायें
+अर्ध
+तारीख
+डाउनलोड
+अनु
+ओलंपिक
+श्रंखला
+दिखाने
+अमिताभ
+मौर्य
+मुताबिक
+प्रपात
+फोटो
+लक्ष्मण
+मालूम
+देगा
+अपील
+लेंस
+स्पेस
+बिन्दु
+द्वीपों
+स्विट्ज़रलैंड
+अर्जेंटीना
+पूछा
+वोट
+अकाल
+शत्रु
+कबीर
+आचरण
+सफलतापूर्वक
+एक्सचेंज
+उत्तराखंड
+शिकायत
+शंकराचार्य
+धारावाहिक
+दृश्यों
+१९९०
+तूफान
+सड़कों
+अपेक्षित
+बाढ़
+प्रोजेक्ट
+पहुँचने
+हूं।
+ग्रांड
+उन्नति
+कच्चे
+स्वीकृत
+बहती
+व्यायाम
+प्रयोजन
+एरिक
+ऑटो
+इंटरसिटी
+सरलता
+उपनगरीय
+अनाज
+धातुओं
+संकल्प
+तेरे
+धूप
+वंशज
+परिपथ
+घोड़े
+मोक्ष
+तालाब
+असमर्थ
+श्रद्धा
+विनाश
+सापेक्ष
+अद्वितीय
+सराय
+सुरेश
+जनजाति
+ट्यूब
+रहकर
+कैम्ब्रिज
+श्वसन
+सुविधाएं
+सूत्रों
+बंध
+जंगलों
+नेत्र
+डीएनए
+बिलबोर्ड
+आदिवासी
+दिखने
+गाया
+आर्थर
+नैशनल
+सिक्के
+वायुयान
+समक्ष
+समतल
+पिछली
+छोड़े।
+विधा
+सीखने
+कालीन
+बौद्धिक
+विधेयक
+सक्सेना
+खा
+यूनियन
+परमात्मा
+संस्करणों
+योद्धा
+पैटर्न
+स्त्रियों
+कर्तव्य
+जातियाँ
+वंशावली
+कमाई
+पैसा
+वसंत
+कहलाती
+एंजिल्स
+अपोलो
+सिंहासन
+इनपुट
+बस्ती
+दीवारों
+प्राधिकरण
+संभवत
+भालू
+केबल
+पुष्प
+सिंचाई
+मानने
+कॉल
+क्रॉस
+अभिगम
+उपलब्धि
+राजनीतिज्ञ
+नोट्स
+बे
+मेजर
+ग्वालियर
+प्रजातियां
+लॉ
+प्रसन्न
+यूएस
+रहेगा
+बुरा
+रोल
+नली
+उक्त
+राजकीय
+हल्के
+हंगरी
+पैलेस
+बनकर
+फेर
+पुरे
+घड़ी
+कविताओं
+स्वरुप
+सेनानी
+अवयव
+अनुप्रयोगों
+कृतियों
+ध्रुवीय
+विल
+इंडोनेशिया
+बहुमत
+टिकट
+कठिनाई
+शासनकाल
+कार्यान्वयन
+दायित्व
+जर्सी
+वितरित
+मूर
+टर्मिनस
+सुन
+जाएगी
+फोर्ड
+दीपक
+चित्रकला
+गरीबी
+सेमी
+तात्पर्य
+संलग्न
+आश्चर्य
+मेहरा
+१९९८
+भंडार
+परिषद्
+लाइब्रेरी
+बंधन
+इण्डिया
+कोयला
+महमूद
+सुना
+नंदीग्राम
+संतोष
+यूके
+जागरण
+बदलकर
+नींद
+बचे
+किसानों
+खुशी
+स्पोर्ट्स
+बलों
+भंग
+कहानियां
+सफाई
+रहस्य
+कणों
+किशन
+वृत्त
+अरुण
+मानस
+प्रेमी
+हमलों
+जीते
+नमूने
+त्वरित
+नम्बर
+शरण
+आतंकवादी
+रंगमंच
+टुकड़े
+निकलता
+ठंडा
+खेत
+गेम्स
+राजेन्द्र
+तालिका
+तटीय
+दिनेश
+भंडारण
+निकला
+मध्यकालीन
+५००
+पान
+चक्कर
+ब्राउन
+वाणी
+असाधारण
+यकृत
+बोलते
+रोटी
+झूठ
+पौधा
+वेदों
+संक्रमित
+जितने
+खूब
+नाभिकीय
+ज्यामिति
+रेटिंग
+जिम्मेदारी
+प्रेमचंद
+एजेंट
+निरीक्षण
+लुईस
+नित्य
+मेमोरी
+उतनी
+उसपर
+पड़ोसी
+तुम्हें
+वचन
+लोकतंत्र
+पार्श्व
+संवेदनशील
+उत्पादित
+सीरीज
+कॉर्पोरेट
+सूचकांक
+चैनलों
+अनंत
+नीतिया
+रिकॉर्ड्स
+ज़रूरत
+भावी
+होल
+विवादास्पद
+पिनकोड
+सरकारों
+पहलुओं
+जादू
+तपस्या
+विहार
+मोटी
+रुपए
+अपितु
+व्यंग्य
+सीधी
+सिर्फ़
+गुवाहाटी
+बेच
+नाटकीय
+शोर
+पुराणों
+मरीज
+वाजपेयी
+तिवारी
+रही।
+ब्रेक
+फैले
+विन्यास
+भाप
+थोड़े
+सर्वोत्तम
+शशि
+पार्वती
+रचनाकाल
+अदा
+गयीं
+पुर्णिया
+बॉन्ड
+बिन
+मोंटे
+नाक
+दीक्षित
+जिनमे
+अवलोकन
+नस्ल
+डेनमार्क
+वरुण
+विभक्त
+सैकड़ों
+अनुभूति
+पंजीकृत
+मतभेद
+कॉमेडी
+कलात्मक
+निकाय
+तरफ़
+आणि
+साथियों
+गुलाब
+झिल्ली
+सोना
+संश्लेषण
+इलाकों
+पण्डित
+आया।
+रेसिंग
+खपत
+टेलीफोन
+पड़ते
+दिलीप
+ई०
+एकादशी
+प्रतिबंधित
+फलों
+साइड
+उपासना
+खोटे
+प्रिक्स
+एचआईवी
+आमंत्रित
+फार्म
+इसपर
+रेंज
+१९९९
+प्रयाग
+मंगोल
+शासित
+रद्द
+अजय
+भाजपा
+आईएसबीएन
+सुमित
+एवम्
+रजिस्टर
+विकीस्रोत
+इंदौर
+बोइंग
+अमृतसर
+मकान
+पारिस्थितिकी
+मैड्रिड
+समन्वय
+अन्ना
+लोहा
+कम्युनिस्ट
+गण
+अवसरों
+ब्यूरो
+चूँकि
+खुली
+तन्त्र
+राजपूत
+समझते
+बिहारी
+वैष्णव
+चैंपियनशिप
+प्रतिकूल
+सिंड्रोम
+बंबई
+अमृतपुर
+ख्याति
+पुर्तगाल
+क्यूँ
+घ
+नारी
+अनुभाग
+मैरी
+गर्भाशय
+सर्व
+पूर्ववर्ती
+चतुर्थ
+इमारतों
+रेजिस्ट्रेशन
+प्रभु
+अस्वीकार
+साक्ष्य
+वॉ
+बढ़कर
+इनकार
+सांस
+प्रतिवर्ष
+भाषी
+बढा
+मूत्र
+अरारिया
+निकलती
+क्रिटिक्स
+धारक
+उपयोगिता
+त्योहार
+समेत
+प्रतिरक्षा
+बटन
+समर्थ
+दा
+नगरी
+तेज़
+भूतपूर्व
+देखता
+दमन
+अनुचित
+श्रीवास्तव
+हट
+प्रशंसकों
+भंडा
+तथ्यों
+दस्तावेज
+ऑपरेटिंग
+कोशिकाएं
+वाणिज्य
+पोषक
+धीमी
+वियतनाम
+स्कॉट
+रहीं
+घाव
+प्रावधान
+१९९२
+बैक
+श्रीराम
+मुकाबला
+स्टेट्स
+पादप
+गणतंत्र
+योजनाओं
+रोजर
+हार्मोन
+उत्पादक
+टेक्सास
+बेहतरीन
+फ़्रांसिसी
+राजस्थानी
+लगाते
+बीटा
+मान्य
+उद्धरण
+एज
+उद्घाटन
+पूर्वोत्तर
+हार्डी
+यहा
+शैलियों
+ऋग्वेद
+तमाम
+बेन
+सुभाष
+प्रशिक्षित
+दुबारा
+भीतरी
+प्रिंस
+हड्डी
+मल्ली
+बेचने
+महत्त्व
+आक्रामक
+कार्यकर्ता
+कटौती
+सोमवार
+गिर्द
+शुरूआती
+तिहाई
+खरीदने
+इट
+बिजनेस
+असंभव
+डिज़्नी
+जानकी
+ली।
+तें
+बने।
+खेले
+दादा
+पृथ्वीराज
+सांख्यिकी
+हुईं
+केविन
+बनारस
+रोशनी
+आरती
+पीछा
+स्थानांतरण
+रिश्ते
+बर्तन
+परिस्थिति
+बोले
+राष्ट्रीयता
+बलि
+इंजीनियर
+प्रमेय
+बुक्स
+उनपर
+छंद
+गुंजन
+टॉवर
+शाब्दिक
+स्वप्न
+सुधारने
+यूरो
+अवध
+तत्त्व
+निधि
+ललित
+भांति
+विमानों
+जलप्रपात
+चाहती
+आंकड़ों
+तेज़ी
+मैनेजमेंट
+मैट्रिक्स
+राजभाषा
+आयाम
+गुड
+पाली
+सनहौला
+पारस्परिक
+जंग
+पिक्चर्स
+इनको
+आस्था
+गुलाबी
+आजाद
+टेक
+ऊंचा
+एतमादपुर
+ब्लोक
+प्रतिनिधियों
+स्टेशनों
+हालत
+१९९१
+अटलांटिक
+ऊँचे
+वेबसाईट
+पत्ते
+आलू
+इन्द्र
+परिकल्पना
+सुनने
+गुलशन
+हज़ार
+कम्प्यूटिंग
+नियुक्ति
+पहुँचा
+विशेषताएं
+आयात
+खुदरा
+लैंड
+मग
+महा
+फ़िर
+अनुयायी
+काफलीगैर
+डाउन
+ओबामा
+कैद
+सूजन
+उपदेश
+विवेचन
+मोटा
+नारंगी
+धर्मों
+कुमारी
+बंदी
+ख़त्म
+अल्प
+कोटा
+चीजों
+पहाड़ियों
+८०
+सर्किट
+स्रोतहीन
+दुकान
+हंस
+सैद्धांतिक
+किरन
+देखें।
+तलवार
+सबके
+ब्रदर्स
+दोषी
+टेलर
+बॉल
+कटाई
+वाद
+पक्षों
+फ्रैंक
+नगरों
+वाहक
+विश्वसनीय
+समस्याएं
+पत्थरों
+कार्टून
+जि
+बीसवीं
+तिब्बती
+गो
+भेंट
+जगहों
+निष्पादन
+विक्रेता
+खगोल
+रोज
+कसम
+स्मरण
+क्रोध
+कॉमिक्स
+सूर्यवंशी
+पोप
+भेजे
+्य
+किरौली
+सख्त
+ग्रीष्मकालीन
+विल्सन
+सुदूर
+ढांचे
+जगन्नाथ
+ड्राइवर
+गांवों
+कश्मीरी
+स्वीडिश
+वशिष्ठ
+पीड़ा
+कहकर
+नैतिकता
+वस्तुत
+औषधीय
+मैट
+ज्योति
+नगला
+महापौर
+गठित
+प्रदाता
+श्
+आर्ट्स
+हटाना
+ऊष्मा
+सकने
+मरने
+ग्रीस
+मिश्रा
+हमसे
+आपसे
+क्वीन
+गिनती
+शिल्प
+मनोनीत
+एकड़
+रोकथाम
+हितों
+आशू
+अधिकृत
+इर्द
+सांता
+खुदाई
+स्टीफन
+विश्वकोश
+लायक
+विश्वनाथ
+गीतकार
+मुमताज़
+रूचि
+इराक
+लम्बा
+ग़ैर
+वॉशिंगटन
+आपसी
+भूमिगत
+भरपूर
+रावण
+वन्य
+सौरभ
+जुड़
+विद्युत्
+अद्यतन
+जीएसएम
+मैकमोहन
+सेतु
+दूरदर्शन
+संवैधानिक
+जीवाश्म
+डबल
+हानिकारक
+दर्पण
+पूजन
+विलयन
+िया
+लता
+उपहार
+क़ानून
+थिएटर
+परिचालन
+एकीकरण
+प्लेट
+हार्डवेयर
+समावेश
+संचिका
+अपशिष्ट
+मनमोहन
+फाइबर
+भारतीयों
+दुसरे
+आंखों
+संस्कृतियों
+यंग
+सदियों
+मत्स्य
+युक्ति
+फ्रांसिस्को
+बर्लिन
+लौटने
+मेहता
+क्षण
+पाश्चात्य
+गामा
+कैमरा
+ताजमहल
+सर्च
+बना।
+तल्ली
+साधनों
+पहचाना
+राजा।
+मेरठ
+जिसको
+मधु
+रिश्ता
+धूल
+गायब
+मोर
+सीरीज़
+इति
+सें
+सामुदायिक
+अनुदान
+ड्रम
+बडा
+कालिदास
+ब्रूस
+क्षय
+मातृवंश
+ट्रिपल
+प्रगतिशील
+गोस्वामी
+शनिवार
+हल्का
+हिन्दुओं
+फैली
+विष
+गर्भावस्था
+विस्तारित
+मिमी
+बा
+डेल्टा
+आँखों
+दीर्घ
+गंतव्य
+गणितज्ञ
+बिली
+बल्लेबाज
+क्लोराइड
+बालों
+मैनचेस्टर
+यु
+निर्णायक
+इंगित
+मयुर
+साप्ताहिक
+वैशाली
+पूर्णतया
+बच्चा
+अक्ष
+भविष्यवाणी
+भ्रमण
+हांगकांग
+ब्लेक
+रेस्तरां
+कृपा
+परेशान
+विकासशील
+मांसपेशियों
+गोविन्द
+प्राकृत
+कथाएँ
+गुलाम
+व्यस्त
+मार्गदर्शन
+कोंच
+कट
+प्रतिस्थापित
+वैभव
+पहने
+पाठकों
+बातकरें
+डॉग
+विकिमीडिया
+बेदी
+पोशाक
+चंद्रमा
+छिद्र
+इमारतें
+माउंट
+सिफारिश
+होगन
+उज्जैन
+समर्थित
+ब्रह्माण्ड
+रसूल
+श्लोक
+राहत
+आखिर
+एम्
+दाल
+पकड़ने
+मुँह
+उत्साह
+गर्दन
+तुलनात्मक
+काटने
+पाक
+महारानी
+ग्रंथि
+जरुर
+यूरोपियन
+आत्महत्या
+शर्त
+चुम्बकीय
+सम्प्रदाय
+नवीनतम
+हीरो
+मशीनों
+जयंती
+मिथुन
+उद्देश्यों
+सामयिक
+अकेला
+परिवेश
+मोड
+लवण
+चिली
+रखरखाव
+बोलचाल
+अभिलेख
+चाँद
+लें।
+सेनाओं
+अखबार
+दिखा
+रूपरेखा
+भास्कर
+समाधि
+विंडोज
+बनाया।
+भयंकर
+अमृत
+अरुणा
+ऊंचे
+खेर
+दोबारा
+बाध्य
+लगी।
+नागर
+उपन्यासों
+हीन्दी
+नाट्य
+जनक
+नमूना
+टीमों
+आउटपुट
+जोस
+कोरियाई
+मरम्मत
+डाक्टर
+सूरा
+कष्ट
+परीक्षणों
+बाएं
+भरने
+वेन
+केस
+महिलाएं
+लुप्त
+फ्रेम
+द्विवेदी
+असरानी
+शोषण
+नियमितता
+इंसान
+पद्य
+वायुमंडल
+पोल
+विलुप्त
+अपूर्ण
+बेचा
+लिनक्स
+कडी
+सतीश
+बहरहाल
+आयी
+हिन्दु
+मल
+बताने
+श्रीनगर
+लड़ने
+टोक्यो
+ऊँची
+पर्ल
+पितृवंश
+नी
+दीर्घा
+धार
+मंदी
+फ्री
+घंटा
+दोपहर
+इंस्टिट्यूट
+गुर्दे
+एचटीएमएल
+रजत
+अवकाश
+सीबीएस
+पाना
+होती।
+फेसबुक
+भगवानपुर
+पतली
+सीट
+मोड़
+मक्का
+स्पेक्ट्रम
+संरचनाओं
+इसमे
+बुध
+ब्लूज़
+अवसाद
+अफगानिस्तान
+पंजीकरण
+जरुरत
+अवरोध
+ब्राउज़र
+टाइगर
+विनिर्माण
+जालघर
+विज्ञापनों
+बॉट
+ग्यारह
+मुजफ्फरपुर
+गिनी
+परी
+मिलेगा
+कस्बे
+भाषाई
+बारी
+माँग
+गैलरी
+मिलन
+शुक्र
+आर्मेनिया
+इंस्टीट्यूट
+आत्मकथा
+सदस्योंको
+प्रतिपादन
+टर्मिनल
+रहेगा।
+पेड़ों
+मिली।
+कमीशन
+योनि
+फसलों
+गतिशील
+भी।
+संचरण
+प्रभुत्व
+उपक्रम
+समुचित
+दक्षता
+द्रविड़
+बन्द
+दिखता
+मध्यप्रदेश
+सारांश
+भीम
+अस्तित्वहीन
+हथियारों
+खुराक
+प्रकारों
+तेरा
+ताकत
+भगवान्
+लेक
+समकक्ष
+देशांतर
+ै।
+जोसेफ
+आज़ाद
+सामान्यत
+उपभोग
+भीष्म
+ऊतकों
+खिलाफ़
+लोकमान्य
+अन
+राजू
+अस्थि
+दरवाजे
+राजनेता
+आघात
+उपमहाद्वीप
+प्रख्यात
+टोनी
+टुल्सका
+विफलता
+स्टोरी
+बैठ
+बनना
+स्वतः
+भाषाविज्ञान
+दृढ़
+अर्थात्
+शी
+पचास
+प्रसिद्धि
+अपराधी
+डाली
+हरि
+डकोटा
+कोहली
+प्लेयर
+आश्रय
+नाग
+बिस्मिल
+छात्रवृति
+मिनेसोटा
+लाए
+सकें।
+चुनावों
+ब्रिज
+चिंतन
+बिगाड
+विमर्श
+पहुंचे
+होंगे।
+वैसा
+भूख
+दिखें
+नॉर्थ
+अवस्थित
+घेरे
+स्ट्रोक
+सर्बिया
+असल
+हिन्दुस्तानी
+घन
+वीज़ा
+महोत्सव
+घटकों
+बढ़ी
+करवा
+सुनकर
+रावल
+घट
+प्रायद्वीप
+स्वाधीनता
+विशेषज्ञों
+प्रबंधकोने
+कैलिन्डर
+धनरूआ
+डेली
+किलो
+जाट
+अधिकारिक
+माहौल
+सीटें
+पुरातत्व
+पीपल
+लीटर
+अनुकूलन
+गेंदबाज़ी
+शीह
+वायुसेना
+सूर्यगढा
+उन्होनें
+सिंध
+इधर
+टैंक
+पंच
+भूमध्य
+अफ़्रीकी
+डांस
+बलिया
+एड्स
+जनन
+जंतु
+समझना
+ग्रन्थों
+सैम
+गुरुत्वाकर्षण
+कोमल
+जायेंगे
+थाईलैंड
+टेलिविज़न
+दायर
+ज़िले
+त्रिपाठी
+प्राचीनतम
+विदेशों
+करी
+पढ़ा
+पर्वतीय
+नाइट्रोजन
+परशुराम
+स्वतन्त्रता
+चार्ज
+मेहनत
+फिलिप
+पेट्रोलियम
+नदियां
+पिंड
+उत्तरार्ध
+लेनदेन
+दीर्घकालिक
+आयतन
+मूलभूत
+टनकपुर
+डाटाबेस
+औरत
+नकल
+डि
+चैंपियन
+मोती
+होनेवाले
+दिमाग
+टेक्स्ट
+जीवनचरित
+मणिपुर
+फील्ड
+प्रक्षेपण
+निकले
+खड़गपुर
+करन
+९१
+प्रदर्शनी
+अनुष्ठान
+वक्र
+संबोधित
+शिविर
+वास्तविकता
+गोआ
+मेटल
+भगत
+सवार
+मजदूर
+शतक
+मानवता
+वॉन
+बढ़ाया
+दानव
+सदृश
+१९८९
+विभागों
+कमाल
+बचत
+मिर्च
+कॉफी
+बडे
+कीं
+फर्स्ट
+स्तन
+कोने
+संसारके
+१९७२
+डुमरिया
+क्
+आवागमन
+१९८०
+होम्स
+संकलित
+पत्तियों
+सूखे
+मुलाकात
+लास
+सनातन
+सामग्रियों
+कुत्तों
+रोबोट
+खैरागढ़
+कर्नल
+राखी
+आधारभूत
+पालीगंज
+स्पेशल
+संजीव
+अग्रवाल
+आस्ट्रेलिया
+आधी
+सूरत
+संक्रामक
+मुझसे
+मुग़ल
+वोल्टेज
+अणुओं
+ज़रा
+सील
+खनन
+समानांतर
+बोला
+ग्रे
+ष
+भागवत
+रंजीत
+मीनार
+पूर्णागिरी
+बीरबल
+गायत्री
+जबलपुर
+उजागर
+सशस्त्र
+कोच
+प्रश्नों
+बुंदेलखंड
+बडी
+बदलते
+पुर
+जीवविज्ञान
+राह
+प्रशंसक
+पर्यावरणीय
+लड़कियों
+स्टोर
+संगत
+प्रोफ़ेसर
+एलिस
+हिंद
+पूल
+भि
+९०
+भावनात्मक
+प्राथमिकता
+वाष्प
+ओल्ड
+आज्ञा
+औजार
+गैसों
+व्हिस्की
+रोका
+कहती
+जहाजों
+सशक्त
+दिवसीय
+उतार
+शान्ति
+वृक्षों
+प्रचुर
+प्रसव
+७०
+संरचनात्मक
+फीचर
+फॉक्स
+देरी
+पुरूष
+कीबोर्ड
+लाइट
+शिलालेख
+सपना
+व्युत्पत्ति
+कद
+सजीव
+लोकतांत्रिक
+स्राव
+विन्डोज़
+शॉट
+चिह्नित
+उधार
+जेट
+चे
+युधिष्ठिर
+माधव
+आसन
+संख्याओं
+शेख
+घूमने
+आक्सीजन
+राइट
+नियत
+इतिहासकारों
+एनरॉन
+रु
+पारम्परिक
+व्
+सर्वथा
+वाद्य
+आपदा
+दरभंगा
+जात
+१९७१
+लाभदायक
+म्यूजिक
+दावे
+वोल्डेमॉर्ट
+भारतवर्ष
+जोकर
+राणा
+कादर
+गढ़
+कनालीछीना
+मुकेश
+जाएं
+क्लार्क
+बॉबी
+सम्पन्न
+भूरे
+शोधकर्ताओं
+पूर्ववत
+अहिंसा
+बीमार
+जूते
+फाइल
+नारियल
+अमरीश
+अवतरण
+छेद
+शर्करा
+सेनापति
+एक्सेस
+वस्तुएं
+वादक
+दांत
+योगी
+चोल
+परिष्कृत
+श्रमिक
+नामांकरण
+सबको
+जिसपर
+इलेक्ट्रॉन
+महिमा
+क्षैतिज
+उत्तरदायी
+शूटिंग
+कारखाने
+आरक्षण
+आरेख
+किए।
+रो
+यों
+घटनाएं
+बाइबिल
+दम
+वार्ड
+ज़रूरी
+औचित्य
+एव
+१९७०
+तीस
+यूनिट
+खेलते
+डेटाबेस
+मामूली
+सफर
+अध्यक्षता
+आदर
+कॉर्पोरेशन
+चैतन्य
+िक
+निरपेक्ष
+निकोलस
+आसमान
+विश्राम
+वर्जीनिया
+अभिनीत
+आन
+संरक्षक
+दाता
+तेरी
+जॉनसन
+अल्कोहल
+दिस
+दर्शाते
+अन्वेषण
+लगाई
+जीने
+टीबी
+३००
+उदाहरणार्थ
+करण
+चंडीगढ़
+शरद
+कास्त्रो
+सहकारी
+छुट्टी
+स्थिरता
+जोड़ता
+कैल्शियम
+वुड्स
+ित
+सपने
+इत्यादि।
+प्रजा
+सेक्स
+शुक्रवार
+सर्दियों
+चीजें
+नाव
+फर्म
+हॉकी
+कहां
+विमानक्षेत्रों
+१९४७
+चढ़ाई
+परवर्ती
+क्षत्रिय
+ब्राह्मणों
+कराता
+नौबतपुर
+आयन
+आइ
+प्रवर्तन
+लिटिल
+स्वत
+नासा
+तंग
+रक्षक
+ग्रोवर
+शिवपुरी
+सीडी
+गौर
+बतौर
+कल्प
+साधु
+इकाइयाँ
+पढ़
+दीक्षा
+घंटों
+करेगी
+उदहारण
+लीवर
+सती
+बियर
+हार्वर्ड
+सहारे
+दक्ष
+१९९६
+अभिषेक
+तुम्हारी
+रेगिस्तान
+अभयारण्य
+चाचा
+प्रशासकीय
+टावर
+अनुकरण
+जें
+ऊन
+फायर
+जैसलमेर
+कविताएँ
+विक्रमादित्य
+लड़के
+न्यायिक
+आपराधिक
+निंदा
+सेठ
+गत
+दुर्योधन
+गगनचुम्बी
+हीरा
+१९९५
+वैन
+मिशेल
+मालुम
+जिमी
+रिपब्लिकन
+चटर्जी
+पेपर
+बोस्टन
+व्यापारियों
+शान
+सुप्रसिद्ध
+सचिन
+हु
+राजकुमारी
+निवारण
+विकृत
+त्रिपुरा
+लेबनान
+परेशानी
+१९९७
+देवलथल
+प्रत्यय
+मरीजों
+स्थान
+फतेहपुर
+ह्रदय
+अध्यापन
+लीड्स
+औरंगजेब
+वस्तुएँ
+निवेशकों
+सरोवर
+एंडी
+दिनांक
+कंट्री
+लीप
+गंध
+श्रेणियां
+आरक्षित
+मारुति
+प्रशासक
+ज़िन्दगी
+जन्मस्थान
+वॉल
+भाइयों
+सहकुंड
+शेयरों
+कवरेज
+धाम
+कर्ता
+वाल्मीकि
+संग
+सेल्सियस
+सलीम
+सूक्ष्मदर्शी
+यांत्रिकी
+इलाका
+रियल
+पंकज
+विशेषताएँ
+मकबरा
+प्रहार
+अजमेर
+अभिगमन
+केशव
+मयूर
+धनी
+ऑक्साइड
+अरुणाचल
+उपलब्धता
+नजदीकी
+इंजीनियरी
+डीन
+उपनिषद्
+जरूर
+प्रखण्ड।
+ब्रह्मांड
+शीत
+पहाड़ों
+एक्ट
+विण्डोज़
+छठी
+कश्यप
+वार्नर
+उ०व०
+बुश
+१९६०
+सन्त
+पारसी
+खोजने
+कुंजी
+रोमानिया
+इकट्ठा
+लय
+शस्त्र
+फलन
+तुलसीदास
+आदित्य
+जगदीशपुर
+नीम
+इयर
+सामान्यतया
+चार्ली
+जानेवाले
+एजेंसियों
+पाटिल
+सिगरेट
+बरकरार
+पाठ्य
+साहनी
+जोड़कर
+शैल
+पाचन
+लेट
+से।
+अनावश्यक
+गतिविधियाँ
+विषयक
+शर्तों
+असंख्य
+याहू
+विक्रय
+राष्ट्रमंडल
+ऑस्ट्रेलियन
+बलिदान
+उपेक्षा
+पाती
+गौरी
+संचित
+मार्केट
+सिकंदर
+सीरिया
+अभिक्रिया
+टक्कर
+दहन
+हैमिल्टन
+घोष
+समाजशास्त्र
+भाग्य
+चट्टानों
+साझेदारी
+पठन
+उत्तेजित
+अवशोषण
+चिकित्सकीय
+अपमान
+ओजोन
+स्तूप
+वयस्कों
+ट्यूमर
+रॉ
+इंटरफेस
+टेबल
+संज्ञानात्मक
+सच्चे
+कपड़ा
+वक़्त
+ऐल्बम
+मित्रों
+बीहता
+उदाहरणों
+ऑस्कर
+पृथक्
+घी
+अं
+सुई
+झलक
+विराम
+फोर्ट
+पुरस्कारों
+इज़
+एनबीसी
+रखा।
+सत्येन्द्र
+वर्णक्रम
+चांदी
+वेगास
+नें
+वषीश्ठ
+श्र
+बगैर
+पुनर्निर्माण
+आदान
+हिटलर
+क्षतिग्रस्त
+ज्यों
+प्रसंस्करण
+सुरंग
+शाकाहारी
+धनुष
+वैचारिक
+मधुर
+गायिका
+प्रोफाइल
+प्रतिरोधी
+उपज
+संवर्धन
+चेहरा
+बाँध
+कोर्स
+स्पेनी
+परिप्रेक्ष्य
+प्रतापगढ़
+महानगर
+सुनाई
+गद्दी
+वास्तु
+निर्देशांक
+आँखें
+व्यतीत
+उन्नीसवीं
+गिरने
+भावों
+सांख्यिकीय
+आशय
+भगवती
+साधारणतया
+भोज
+मुराद
+रवी
+प्लेस
+परंपराओं
+हिप
+डार्क
+चुन
+साजन
+परिदृश्य
+रज़ा
+ताइवान
+सवारी
+देखिये
+त्रिकोण
+कपड़ों
+पद्धतियों
+अपनाने
+स्त्रोत
+खिज़िरसराय
+समर
+जड़ी
+वेदव्यास
+१९६५
+चलन
+जिव्
+सौंप
+औपनिवेशिक
+चिकित्सीय
+ट्रेड
+स्वच्छ
+बुरे
+डैनियल
+मंगलवार
+पूर्वज
+उष्मा
+चिकित्सकों
+रूपांतरित
+जंतुओं
+नारद
+पैकेज
+नागरी
+पल
+बहुविकल्पी
+तथाकथित
+कार्यक्षेत्र
+पंख
+अवॉर्ड
+मसौढी
+तम्बाकू
+लहर
+बीमारियों
+निरूपण
+साइकिल
+थीम
+क्रान्तिकारी
+इंग्लैण्ड
+सर्वत्र
+जॉर्जिया
+शेट्टी
+छाप
+मलिक
+हैमबर्ग
+स्वदेशी
+सूचक
+१९६२
+धारचुला
+चर्चिल
+रिलायंस
+ईस
+ती
+संकर
+विजुअल
+उदार
+उद्गम
+पंचमी
+मंजूरी
+अनन्त
+प्रायोजित
+नेट
+मालवा
+लाई
+बगल
+धर्मेन्द्र
+नाश
+फीफा
+नगरपालिका
+टेप
+खुर्द
+मार्गों
+धमकी
+शिवलिंग
+प्रासंगिक
+धरहरा
+मारिया
+विवादित
+मेक्सिकन
+१९८६
+उपायों
+दरअसल
+सम्पादक
+वृत्तचित्र
+सिंगल
+लुई
+विद्यार्थियों
+मुद्दा
+फैसले
+आए।
+अलगाव
+मिशिगन
+धान
+भयानक
+पिट
+दिखाए
+ान
+चाप
+पहनने
+विशेषज्ञता
+पैट्रिक
+इनमे
+चर
+कुत्ता
+निर्वाण
+दण्ड
+नागरिकता
+दुकानों
+वर्चुअल
+लंका
+शॉन
+ब्लड
+जैक्सन
+जलीय
+अमास
+कड़ियों
+अनुसूचित
+रेत
+गारंटी
+दिशाओं
+स्टैनफोर्ड
+मूलत
+डेनियल
+परि
+सेवक
+अमृता
+शताब्दियों
+जायेगी
+दिलचस्पी
+नाईट
+मॉडलों
+हान
+स्वायत्त
+ज्वर
+जवाहरलाल
+आगामी
+कूद
+बुधवार
+राक्षस
+आयेगा।
+इंटर
+वांछित
+धमनी
+सुलभ
+बाण
+वाई
+पुरातात्विक
+गौड़
+सामवेद
+नाभिक
+अध्यापक
+समाजवाद
+उद्भव
+डैनी
+चक्रवात
+फैलाव
+एंटीबायोटिक
+चर्चित
+जितेन्द्र
+उपनिवेश
+लास्ट
+१९७५
+डाई
+गुणा
+सूट
+इलेक्ट्रॉनिक्स
+स्क्वायर
+डाले
+दुःख
+कुंड
+सांचे
+चंपारण
+प्रवास
+दुख
+अधिवेशन
+भरोसा
+तप
+महामारी
+सेब
+जेरी
+हसन
+ऑर्डर
+घोड़ा
+पासवर्ड
+खारिज
+ख़ुद
+इन्होने
+डेविस
+सरन
+प्लाज्मा
+खुलासा
+स्कॉटिश
+टोरंटो
+बेकर
+प्रतीक्षा
+कराते
+क्षमताओं
+पांडे
+हॉप
+कांच
+मणि
+ऐतरेय
+णी
+न्यूज
+संतुलित
+सीला
+विरूद्ध
+द्वितीयक
+ट्रक
+भेदभाव
+निराला
+नजदीक
+भाष्य
+आयेगा
+सहन
+उस्ताद
+नॉर्वे
+बैठा
+संस्कारों
+घने
+गोपनीयता
+स्तम्भ
+वैमानिक
+पंत
+भक्तों
+सम्भावना
+श्वास
+ओवेन
+जगत्
+फायदा
+तस्वीरें
+रुक
+निषेध
+नेटवर्किंग
+आयरन
+मॉडलिंग
+१९८४
+चंद
+शिमला
+कोल
+मनोज
+बैल
+झा
+केन्द्रों
+केप
+एकाधिक
+कुरुक्षेत्र
+डिएगो
+कराना
+फिल्मी
+ठहराया
+जिल्ला
+अमीरात
+ज़िला
+प्रतिस्थापन
+मूर्तियों
+कूट
+साहस
+बेबी
+हाइब्रिड
+पेशी
+तिरुपति
+सोलह
+इयान
+डिक्शनरी
+ताज
+बहुमूल्य
+सुगंधित
+पैनल
+वाटर
+नकली
+टैक्सी
+अस्त्र
+बुखार
+जानना
+उत्परिवर्तन
+निमित्त
+द्वारका
+फिलिप्स
+कांगो
+आइलैंड
+दाढ़ीकेश
+आक्साइड
+मिल्वौकी
+पर्वतों
+१९८५
+ढाल
+ईस्टर
+वर्षो
+उधर
+बिल्डिंग
+ज़ोर
+निर्भरता
+सिन्धु
+अनौपचारिक
+यम
+योर
+नवजात
+नियंत्रक
+अनुभवों
+विज्ञानी
+लगाये
+वर्णों
+स्वतन्त्र
+अलौकिक
+हीं
+बदलता
+डालते
+चौड़ी
+आशीर्वाद
+गोद
+उपाध्याय
+जिनको
+स्टर्लिंग
+क्यू
+सिपाही
+मासने
+अनुभवी
+अपभ्रंश
+सलमान
+दर्जे
+आईसीसी
+मेँ
+किलोग्राम
+इंजनों
+खुश
+किंग्स
+व्यर्थ
+प्राप्तकर्ता
+सल्तनत
+उत
+सीख
+१०००
+अवयवों
+जिक्र
+दीप
+ज्ञानपीठ
+कोयले
+्र
+संदिग्ध
+नम
+परमाणुओं
+मछलियों
+मार्टिना
+स्कैन
+मादक
+अधिवर्ष
+महान्
+लेखांकन
+आजीवन
+बेला
+बाली
+दाहिने
+उठ
+भूरा
+कोस्ट
+यंत्रों
+दलित
+पर्याय
+प्रस्थान
+रेखाओं
+ईस्वी
+पालतू
+गिरा
+बरौनी
+१९९४
+प्लग
+दोहरी
+एडम्स
+अजीत
+सावधानी
+थ्री
+आशंका
+सिल्वर
+न्यूयार्क
+रोमांस
+डॉट
+कॉपी
+बाप
+ईंट
+गर्भवती
+लाला
+घूर्णन
+जया
+यशवंतपुर
+पागल
+जागरूकता
+कंठ
+आईटी
+पत्तों
+समर्थकों
+टूल
+राउंड
+अन्य
+ग्रिड
+दंत
+हिंसक
+तार्किक
+विशुद्ध
+बैठने
+मुद्रण
+सकती।
+पहुंचाने
+कंधे
+परिश्रम
+खोलने
+वृत्तांत
+सिस्टम्स
+धरातल
+सांचा
+संवेदनशीलता
+जिंदगी
+पूर्णतः
+पुरस्कृत
+सराहना
+अन्न
+मीठा
+संतों
+डीसी
+एंड्रयू
+़
+बृहदारण्यक
+टुकड़ों
+रिजर्व
+खंडन
+उपभोक्ताओं
+टिम
+नागार्जुन
+श्रवण
+प्रविष्टियों
+कीटों
+रेसलिंग
+मैदानों
+अभिनव
+एनिमेटेड
+दीन
+बारिश
+मॉल
+डेथ
+क्रान्ति
+छोड़ा
+पुण्य
+प्रतियोगिताओं
+देह
+माइक्रोफोन
+मनाने
+किम
+हेल्थ
+अभिव्यक्त
+दस्तावेजों
+बेरी
+अपहरण
+टोपी
+बाजारों
+संग्रहित
+देखो
+बहने
+भली
+चतुर्वेदी
+विघटन
+रियासत
+भवनों
+जायेगा।
+छठे
+अपर्याप्त
+वस्तुतः
+कार्बोहाइड्रेट
+इंजेक्शन
+नायर
+विद्रोही
+बैटमैन
+गोल्फ
+प्रतिज्ञा
+जरा
+पीस
+बदलती
+खरीदा
+इंटरनैशनल
+झुकाव
+लाना
+उत्थान
+सुसज्जित
+अर्चना
+ओं
+लोड
+कमांडर
+१९८२
+विद्यालयों
+व्याप्त
+आतंक
+अनियमित
+विंग
+चंद्रशेखर
+जाहिर
+त्र
+काटकर
+गिल
+इवान
+एंटी
+जाता।
+प्रदीप
+वकालत
+परजीवी
+प्रणालियां
+अहम
+केले
+चन्द्रगुप्त
+इक्विटी
+दोस्तों
+विद्यापीठ
+समर्पण
+जिल
+तोड़ने
+फिलाडेल्फिया
+पंचायत
+चिड़ियाघर
+नर्मदा
+विनियमन
+परम्परागत
+लॉजिक
+बधाई
+टेक्नोलॉजी
+थाई
+मापने
+सोशल
+७५
+फॉण्ट
+चित्रकूट
+प्राइवेट
+मराठा
+तुम्हारा
+जमशेदपुर
+१९६१
+सावली
+भूमिकाओं
+चयापचय
+अभिन्न
+किन
+खंडों
+एलिजाबेथ
+ग्रहणाधिकार
+ताजा
+निक
+उदा
+प्रयोजनों
+पश्चात्
+लेखो
+गन
+नमस्ते
+जोनाथन
+गोविंद
+ऑटोमोबाइल
+गोलाकार
+गंभीरता
+फिनलैंड
+प्रबन्धन
+पूर्णविराम
+एलेक्स
+मनोहर
+सौदा
+स्टाइल
+२०१२
+पीट
+सामरिक
+रेड्डी
+दया
+प्रा
+वॉल्ट
+वादा
+दरों
+उपन्यासकार
+तरंगों
+स्पैनिश
+बरेली
+दोस्ती
+विकारों
+पंक्तियों
+दिखायी
+ड्रैगन
+चाँदी
+यश
+विकृति
+बेसिक
+कामयाब
+हल्की
+अंडा
+वास
+आर्मी
+कार्तिक
+श्रे
+ब्रह्मचारी
+अर्द्ध
+ग्रेड
+फिल्मांकन
+पूर्वानुमान
+साइटों
+मैत्री
+इज
+कलाओं
+मुद्रित
+मिलर
+सुंदरता
+युवाओं
+विंबलडन
+मीले
+पाणिनि
+सहारनपुर
+पिशाच
+केंडीबार
+मृ
+डिवीजन
+निकलकर
+निभाया
+मनी
+वक्ता
+सिग्नल
+कैलाश
+वाक्यांश
+तुर्क
+विशेषण
+निशाना
+अग्रसर
+रैंक
+१९५०
+खाद
+ङ
+सीटों
+कनेक्शन
+पेट्रोल
+तु
+ग्राफ
+रण
+कंट्रोल
+रत
+जुड़वां
+पूर्वक
+बर्बरता
+पेरू
+एहसास
+व्याख्यान
+गिल्ड
+न्यूज़ीलैंड
+कमान
+पुत्रों
+फ्रांसिस
+पुजारी
+भरतपुर
+कुवैत
+मापा
+खाई
+थकान
+रिक्त
+अनुमोदन
+लेडी
+बाएँ
+शोथ
+अभिप्राय
+युवक
+स्टेम
+नीलम
+पीरपैंती
+प्रतियां
+बहाव
+बहार
+उत्
+अरविन्द
+आराधना
+मंगोलिया
+ध्वन्यात्मक
+फ़ेडरर
+एयरपोर्ट
+बाबर
+टेरियर
+क्रमिक
+विषम
+१९९३
+चालित
+स्थाई
+शीतल
+सज़ा
+अनुपस्थिति
+बफ़ेलो
+होस्ट
+क्लान
+जाएंगे
+ऊर्ध्वाधर
+द्रौपदी
+सूप
+रुपया
+१९४८
+मीना
+शेक्सपियर
+बेकार
+टैगोर
+किताबें
+प्रविष्ट
+सौंपा
+चा
+हिंदुओं
+ऑब्जेक्ट
+अवशोषित
+सातवीं
+पिन
+अयस्क
+हाइकु
+संस्थाएं
+निकासी
+भीषण
+सल्फेट
+बीघा
+निपटने
+नाते
+बाला
+रिक
+समलैंगिक
+आपातकालीन
+उष्ण
+ईस्टवुड
+रचनाएं
+बरसात
+अमित
+यजुर्वेद
+प्रशा
+संपदा
+व्यंजनों
+रॉकेट
+चट्टान
+जार्ज
+यहूदियों
+विजयनगर
+अल्फा
+उत्तेजना
+प्रायोगिक
+अर्थों
+गेज
+दस्तावेज़
+मानकीकरण
+१९७७
+पैक
+टेरी
+उल्लिखित
+काच
+परास्त
+स्वीकार्य
+रचनाकार
+अलंकृत
+शपथ
+अंगूर
+अग्रिम
+वंचित
+कपास
+पाण्डवों
+दानापुर
+घोर
+कामना
+बह
+धोखा
+नं
+प्रतियोगी
+१९६७
+ज़्यादातर
+जला
+अनुशासन
+मसाला
+अंडरटेकर
+दूरस्थ
+सेठी
+उसमे
+दिलाने
+मुक्केबाजी
+संस्कृतनिष्ठ
+ग्रा
+कोकेन
+जेरिको
+ठंडे
+प्रोडक्शन
+गर्ल
+विराट
+गेंदबाजी
+पैन
+जज
+कराची
+महानगरीय
+स्टाफ
+मजदूरों
+एनीमेशन
+शाखाएँ
+वाइन
+१९५६
+एंव
+वीर्य
+सकते।
+तलाई
+परिपक्व
+डेल
+अवस्थाओं
+सर्प
+उन्मुख
+भूभाग
+युद्धों
+रूढ़िवादी
+नाथनगर
+नामके
+लॉस्ट
+कॉट
+नियामक
+वहन
+कलम
+सम्राट्
+परिपूर्ण
+इश्क
+ड्रीम
+कब्र
+मोम
+अल्बर्ट
+दूरबीन
+उदर
+कानूनों
+जवान
+इन्हे
+सौदे
+गान
+दामोदर
+बेलारूस
+श्रेण
+दिख
+दही
+विजयी
+घोल
+चालीस
+मध्ययुगीन
+पेंगुइन
+समायोजित
+मिनी
+पीसी
+फ़्रांसीसी
+सीईओ
+भजन
+आदत
+लिखकर
+१९६८
+परमेश्वर
+एरिया
+कमर
+रेशम
+मिसाइल
+जेन
+मोटर्स
+उग्र
+शैव
+डालता
+यूनिवर्सल
+पिनांग
+फ्लैश
+विजेताओं
+१९८८
+स्वरों
+बैंगनी
+स्विच
+फेफड़ों
+सच्चाई
+चरित
+निकटवर्ती
+इंद्र
+निवेशक
+सिकंदराबाद
+पूंछ
+समाहित
+चित्त
+फिट
+खुसरो
+सार्वभौमिक
+खाया
+स्थानिक
+चिट्ठा
+लग्गा
+समझे
+उपसर्ग
+भोग
+साइन
+क्रीम
+पाकर
+बोलियों
+सका।
+१९७३
+सिद्धि
+गुलज़ार
+आलोचनात्मक
+मिलाया
+शोभा
+ऐनी
+दायरे
+गईं।
+जाएगी।
+वाल्व
+वैली
+रामचंद्र
+संध्या
+क्रय
+सम्बद्ध
+जमाने
+सहस्रनामन
+ध्वस्त
+किरणों
+कै
+आएगा
+एस्टन
+सोचना
+अनुयायियों
+जवाहर
+मॅट
+निभाने
+का।
+क्रोएशिया
+कीर्ति
+कल्चर
+चालु
+ईथेन
+इरादा
+न्यास
+वृंदावन
+हिम
+गेट्स
+ज़ी
+वृद्धी
+परीचय
+डेबिट
+कार्निवल
+सकी
+नालंदा
+यो
+परेश
+कालांतर
+मुखिया
+डेड
+डब्लू
+सांख्य
+फ्रैंकफर्ट
+अजीब
+वृत्ति
+एफ़
+अबतक
+रूट
+हिस्सेदारी
+आवेश
+रू
+अंतरण
+वॉकर
+भवानी
+पत्ती
+धवन
+लाभकारी
+मैगज़ीन
+ओपेरा
+निकलते
+परिधि
+विलक्षण
+बताती
+शिक्षित
+१९५४
+विद
+लेफ्टिनेंट
+उल्लेखनीयता
+जोली
+रतन
+डालर
+उड़िया
+अनुपालन
+क्रिस्टोफर
+केदारनाथ
+डायोड
+तराई
+गुरारू
+प्रतिपादित
+धुरी
+प्रतिबिंबित
+अंग्रेज़
+स्टेज
+खलनायक
+सुप्रीम
+राष्ट्रवादी
+स्विस
+कैथरीन
+अपोल्लोन
+हिल्स
+प्रवर्तक
+रबर
+जोड़ों
+बॉम्बे
+विवादों
+वेस्टर्न
+मध्यवर्ती
+मालिश
+दीवाना
+गुरुवार
+दर्शाती
+गतिविधियां
+मुख्यधारा
+ऋषियों
+खिलाडी
+औसतन
+फ्रेडरिक
+पंचम
+सूखी
+चौड़ा
+विधियाँ
+१९८७
+बेंजामिन
+गली
+हफ्ते
+डीप
+नलिका
+पिंक
+आईपी
+साउंडट्रैक
+दिनकर
+एमटीवी
+अंकन
+क्रूज़
+कैफीन
+बल्लेबाजी
+देसाई
+ऑप्टिकल
+विद्वान्
+हेड
+लेंगे।
+शिवा
+बॉण्ड
+कुशलता
+क्वांटम
+अनिश्चित
+कन्नड
+विचित्र
+रग्बी
+रिव्यू
+प्रपत्र
+निष्पक्षता
+आर्कटिक
+समस्याएँ
+प्रयोगात्मक
+जुडना
+वाल
+ज़िम्बाब्वे
+तलाक
+व्योम
+बिक्रम
+अमीनो
+प्रतिस्पर्धी
+श्रीश
+विश्वव्यापी
+ग्राउंड
+पॉवर
+्ड
+बहुतायत
+मौसमी
+उतर
+तैनात
+चित्रकारी
+इंटरफ़ेस
+खगोलशास्त्र
+गुहा
+अपराधों
+पाउडर
+नॉन
+टिप्पणियां
+डू
+राजन
+मेघालय
+समृद्धि
+सीमेंट
+कथाकार
+गौराडीह
+कतिपय
+डगलस
+असमिया
+आदिम
+हज़ारों
+मीर
+हड़ताल
+ज्ञानसे
+पोर्टलैंड
+्रेणी
+संकाय
+दर्शाने
+अल्लाह
+बिल्ली
+श्रमिकों
+अल्पसंख्यक
+मेजबानी
+चाइना
+ह्रास
+फ़ाइलें
+गल्फ
+राख
+औषधियों
+१८५७
+आश्चर्यजनक
+हाउ
+खेतों
+विनंत्ती
+बढ़े
+ग्रीवा
+ऋषिकेश
+पुनपुन
+जटिलता
+राज्य
+लक्ष्यों
+डमी
+किताबों
+जोश
+लड़कों
+कॉमिक
+कैमरून
+पूर
+हमे
+१९८१
+स्पर्धा
+दिखाता
+कार्यकर्ताओं
+वरदान
+कराई
+अनुकूलित
+आचार
+गार्ड
+सुर
+मोर्चा
+१९७४
+प्रदत्त
+प्रेत
+डेवलपमेंट
+कार्यात्मक
+बालू
+पहचानने
+आश्रित
+रॉबिन
+आकस्मिक
+कस्बा
+मालिकों
+उपाध्यक्ष
+सिलिकॉन
+करेगा।
+दूत
+संग्रहण
+ड्रग
+गिरजाघर
+मोहब्बत
+घूम
+चैन
+आर्यों
+महासचिव
+फिलहाल
+मेजबान
+बसने
+१९८३
+पोत
+एप्पल
+रेणी
+मल्होत्रा
+चैप्लिन
+जीवाणुओं
+१९७६
+छाती
+ट्विटर
+सिकन्दर
+बोझ
+बैठकर
+ऐसें
+विस्फोटक
+अद्वैत
+जीवनकाल
+विचलन
+कैपिटल
+नाटककार
+उपवास
+बसें
+बांटा
+मदर
+डेस्कटॉप
+उन्मूलन
+देनी
+इच्छुक
+नेटस्केप
+बैरी
+ढाका
+ति
+तह
+एचटीएम
+खुफिया
+कामों
+आतंरिक
+सोनिया
+स्वम्
+ईमान
+सार्थक
+मेडिसिन
+काण्ड
+कॉमन्स
+अफ़ग़ानिस्तान
+शिशुओं
+शतरंज
+१२४
+गाजियाबाद
+सर्दी
+स्क्रिप्ट
+बैकअप
+छद्म
+केली
+मकर
+साधक
+मूर्तियां
+शिया
+सूरी
+छाल
+अब्राहम
+फूड
+ञ
+पालि
+मीमांसा
+मीरा
+मान्यताओं
+कैसा
+विनय
+जाय।
+लेम्बोर्गिनी
+इज़रायल
+जीनोम
+मैक्सिको
+एलिज़ाबेथ
+नॉट
+कंक्रीट
+बाधित
+यूनिक्स
+पाण्डव
+स्तनधारी
+सिवाय
+शारदा
+सत्याग्रह
+पूर्णत
+कठ
+बताई
+लीड
+उत्सर्जित
+सुधारों
+एंडरसन
+उत्कर्षराज
+कमला
+मैनेजर
+डीजल
+डेक
+शेखर
+साईट
+संयम
+बढ़ाकर
+तैत्तिरीय
+चमत्कार
+कवच
+तिल
+सप्रू
+४००
+सिंधु
+सब्जी
+पाइप
+मैथ्यू
+लेग
+वादी
+काय
+नेचर
+कागज़
+मंजिल
+बेल्ट
+प्रोफ़ाइल
+गाथा
+सीमांत
+कीमतों
+अंतर्निहित
+मुद्राओं
+जग
+ममता
+स्टीवन
+शास्त्रों
+फोरम
+लिए।
+विचारक
+प्रबंधकोंने
+हिंदुस्तान
+सिखों
+महत्ता
+गोदावरी
+खुदाबंदपुर
+दुबे
+सबका
+फिक्शन
+व्यवसायिक
+मरे
+चमड़े
+कालोनी
+सितारों
+दुरउपयोग
+आयुक्त
+नसीरुद्दीन
+दाँत
+सुलतानगंज
+राष्ट्रिय
+फतुहा
+संग्रामपुर
+सोर्स
+करेंगे।
+सहयोगियों
+क्लैप्टन
+बीजगणित
+प्रांतों
+आभासी
+दीवान
+मानो
+गौण
+लगाता
+डेनिस
+सुदृढ़
+एडम
+आभास
+सदस्योंके
+उठता
+ल्योन
+बंगला
+टुन
+लिट्टे
+नक्काशी
+बिंदुओं
+हेपेटाइटिस
+वामन
+जिलाधिकारी
+्व
+आठवीं
+फी
+जिन्ना
+क्वार्टर
+अनवर
+विंडोज़
+देखरेख
+ऑयल
+समजकर
+साहित्यकारों
+बालकाण्ड
+कौटिल्य
+जामनगर
+अंचल
+बिकने
+ज्ञानकोषकी
+अंगूठी
+खींच
+एफबीआई
+पेस्ट
+विडियो
+मिलना
+लाइनों
+भूटान
+ट्रेडमार्क
+तने
+बापकी
+अत्याचार
+मॉरिसन
+मलय
+उतने
+एंटीबॉडी
+मिठाई
+१९७९
+कोलेस्ट्रॉल
+ेणी
+संतुष्ट
+बेगम
+समझता
+पोलिश
+फ़ुटबॉल
+मीटाकर
+तारापुर
+धनबाद
+एयरलाइन
+लाकर
+अप्रत्यक्ष
+इंकार
+लौटे
+मानसून
+रॉबर्ट्स
+फोर्स
+चलाते
+प्रिंट
+ठ
+यूनेस्को
+धुन
+स्टॉप
+हर्ष
+ऊ
+सावित्री
+सलाम
+फेडरल
+जनित
+कु
+अन्तरिक्ष
+विक्टर
+इथियोपिया
+दुरुपयोग
+भारद्वाज
+नमः
+दांते
+शव
+सचमुच
+मुनिता
+चौथाई
+सालाना
+कब्जे
+ओड़िशा
+अंतत
+संगमरमर
+पारिस्थितिक
+आरम्भिक
+राघव
+मैसाचुसेट्स
+वीकीपीडीयांके
+पुनर्जागरण
+मिलक्त
+बमबारी
+अस्थिर
+प्रतीकों
+उच्चतर
+पतले
+अधिकांशतः
+चरित्रों
+सौन्दर्य
+पुरातन
+डिज्नी
+ड्यूक
+कार्यालयों
+कमज़ोर
+मेट
+शेफ़ील्ड
+आरएनए
+उत्प्रेरक
+सेक्शन
+संभोग
+बास
+वापिस
+राष्ट्रभाषा
+सस्ते
+मैदानी
+लग्न
+भोजपुर
+कुण्ड
+सघन
+फ़ॉर
+१९६४
+संस्मरण
+फॉर्म
+वैद्युत
+पाम
+परदे
+अचल
+ग़लती
+मंद
+बरियारपुर
+शुद्धता
+परवेज़
+बॉय
+जीभ
+रोलिंग
+बदलना
+स्टब
+भुवनेश्वर
+कोइ
+हस्तांतरण
+मुकदमे
+फैलने
+पैरिस
+प्रत्यारोपण
+अफ़्ग़ानिस्तान
+दयाल
+कवक
+मेमोरियल
+एयरबस
+इंटेल
+फिल्मफेयर
+बरोबर
+पहुँचे
+सावरकर
+कुरान
+माली
+दिखाते
+किनारों
+निचली
+कराती
+किस्मों
+रहेंगे
+रीढ़
+खजुराहो
+शियर्र
+घात
+स्वयंसेवक
+मेगावाट
+झरने
+बाढ
+ग्रीष्म
+हराकर
+ठंडी
+गेहूं
+ओबेरॉय
+फ्रेंकलिन
+केंद्रों
+शुक्राणु
+रूपये
+इकाइयां
+हटाकर
+प्रचारक
+रैंकिंग
+नीली
+क्लाउड
+निजामुद्दीन
+फर्क
+ग्लास
+उपजाऊ
+गैरी
+घुटने
+सत्यजित
+न्यून
+कमजोरी
+जोएल
+हरीश
+जन्मदिन
+क्योकि
+शिवराज
+ख़़ुदा
+सिक्कों
+पंचांग
+मिथिला
+१९३०
+पेशे
+राष्ट्रीय
+पहना
+कॅरियर
+प्रतिष्ठान
+मालदीव
+कलाम
+गेहूँ
+हुयी
+दुष्ट
+रांची
+टुकड़ा
+डाकू
+प्रक्रियाएं
+सहाय
+फ्रंट
+निकास
+लहसुन
+हेलन
+डाइऑक्साइड
+श्रद्धांजलि
+चिप
+रोमांटिक
+बॉडी
+शोक
+सितारा
+लेनी
+आयुर्विज्ञान
+फेम
+हरित
+हीमोग्लोबिन
+ब्रायंट
+गोला
+मानद
+कब्ज़ा
+व्यू
+प्रदर्शनों
+डेमोक्रेटिक
+फेंक
+आंत
+समुच्चय
+मातृभाषा
+महाराणा
+रिटर्न
+१९५७
+छपाई
+उपग्रहों
+गोले
+जीवंत
+रियो
+ैं
+दृढ़ता
+धीमा
+गज
+यादृच्छिक
+विपक्ष
+विमानन
+कथाएं
+चेष्टा
+गतिशीलता
+लालकुआँ
+१५०
+दिलचस्प
+बैक्टीरिया
+पवार
+ढांचा
+पंप
+नूतन
+आमन्त्रित
+पुस्तिका
+चौदह
+फोर
+सऊदी
+सरसों
+कैलिफ़ोर्निया
+नेल्सन
+रकम
+६५
+कहा।
+नायिका
+आभार
+अनजाने
+एस्टर
+एलेन
+प्रेरक
+जरुरी
+वाइल्ड
+विशेषाधिकार
+नरसिंह
+ब्रदर
+अधिकता
+बर्मी
+धाराओं
+सिंघल
+समीक्षकों
+राजदूत
+समारोहों
+ढेर
+सूखा
+अर्जेन्टीना
+प्लेटो
+१९६३
+१९६६
+स्थलाकृति
+इरादे
+कर्मों
+जानेवाली
+क्षीण
+मरुस्थल
+प्रांतीय
+स्काई
+ऍ
+विशिष्टता
+एमी
+अरबों
+इंसुलिन
+युवावस्था
+कैमरे
+नमूनों
+जावेद
+नक्शे
+सु
+१९६९
+संकुचन
+किय
+समीक्षाएं
+स्पिन
+हवाला
+कारावास
+शिक्षकों
+नाहीं
+सर्जन
+दाने
+उठाते
+वरन्
+६००
+उठाना
+भट्टाचार्य
+्ता
+डोनाल्ड
+संतृप्त
+हड्डियों
+मिलाने
+करनेवाला
+निकोबार
+दे।
+सॉसेज
+चेतन
+त्रिवेंद्रम
+ऐन
+करीबी
+मासको
+पहेली
+देशभर
+इमेज
+मोटाई
+सिगार
+ऑक्सीकरण
+मैनुअल
+सूअर
+चलना
+पड़े।
+पर।
+पराजय
+मंगेशकर
+नर्तकी
+यज्ञोपवीत
+देखिए
+द्योतक
+आतां
+मीठे
+भागने
+रूपी
+परिणत
+श्रृंगार
+शक्तिपीठ
+कुरु
+बीजिंग
+मुगलों
+घटा
+सच्चा
+वान
+पैकेट
+चौथान
+मॉर्गन
+सिवा
+इन्टरनेट
+वैधानिक
+मास्को
+भेड़
+रोहिणी
+मैरीलैंड
+भेजी
+मिर्ज़ा
+परिशिष्ट
+निर्माणाधीन
+असे
+रॉन
+डायरी
+द्
+संदूक
+नक्शा
+विराजमान
+विकल्पों
+प्रधानता
+लिपियों
+काउण्टी
+याचिका
+वरीयता
+विजू
+त्रुटियों
+निर्देशिका
+चूर्ण
+समूचे
+प्लस
+टाइपिंग
+लिखें
+दोहरे
+प्रथाओं
+निर्मल
+रस्सी
+बेखम
+ण्ड
+बजाया
+मुलायम
+हमीरपुर
+बंधक
+प्रतिरक्षी
+आपरेशन
+निसान
+नरम
+वॉल्यूम
+ख्याल
+क्रैमलिन
+इट्स
+थ्योरी
+शेयरधारकों
+सुमीत
+अंदरूनी
+लवी
+माधुरी
+खातों
+गाड़ियों
+सजावट
+निपटान
+खोलकर
+जन्मा
+पीएच
+अभिनेताओं
+चावला
+प्रेमिका
+स्विट्जरलैंड
+ब्राउजर
+मोदी
+शेरशाह
+नमी
+चालुक्य
+सूफी
+उचाई
+कोलम्बिया
+सू
+उठाकर
+ग़ज़ल
+क्षरण
+ग़लत
+खरीदारी
+दुल्हन
+शम्मी
+निष्ठा
+प्रविष्टि
+साम्यवादी
+रहेगी
+अनोखा
+स्तुति
+उपलब्धियों
+परियोजनाएं
+गद्यकार
+स्विफ्ट
+इंडीज
+लौकिक
+कोशों
+प्रिया
+शिष्यों
+निकली
+बाँटने
+टकराव
+मौजूदगी
+निरन्तर
+आकाशवाणी
+उल
+चीफ
+सुविधाजनक
+यादगार
+समाचारपत्र
+म्युज़िक
+सूचनाओं
+जमालपुर
+रोकता
+लक्षित
+दौलत
+स्पेंसर
+लालू
+पिच
+आसवन
+ज्वार
+पाषाण
+संयोजित
+अरे
+ईथरनेट
+मय
+आखिरकार
+एथेंस
+लड़का
+धूम
+निर्देशों
+आहे
+प्रयोगकर्ता
+झीलों
+ज्वाला
+नागालैंड
+आपत्ति
+कांस्य
+ख़राब
+करनेवाली
+विगत
+ार्ता
+फेडरेशन
+वैसी
+युनुस
+वस्त्रों
+श्रद्धालु
+अदृश्य
+सामर्थ्य
+६३
+हार्दिक
+मानदंड
+बौना
+सुनवाई
+शॉपिंग
+बराबरी
+सि
+पलायन
+लाइसेंसिंग
+अञ्चल
+जगदीप
+गोत्र
+देहांत
+कार्टर
+प्रतिबन्ध
+शैतान
+फांसी
+रीड
+बोतल
+गोविन्दा
+सामंजस्य
+फर्श
+फिल
+यूएसए
+गाते
+उपक्षेत्र
+एंग्लो
+तुमने
+बुगु
+निर्वाह
+बताए
+दूरदर्शी
+धोखाधड़ी
+संचालक
+तकरीबन
+आमिर
+स्टारबक्स
+जड़ें
+रूम
+टेल
+घोड़ों
+नरसंहार
+प्रीति
+अश्लील
+कलश
+कैलगरी
+८५
+घूमते
+प्रवक्ता
+वूल्वरिन
+अप्रत्याशित
+आंकड़ा
+ग्रीनहाउस
+फेस्टिवल
+अनूदित
+सर्वे
+चेन
+छवियों
+अधिकाधिक
+मिटा
+पिरामिड
+अग्र
+चाणक्य
+प्रक्षेपास्त्र
+१९७८
+विक
+टंडन
+मैनहटन
+कैच
+मौन
+टमाटर
+सांद्रता
+इस्तीफा
+करवाने
+समीक्षक
+फारस
+वज़न
+प्रवृत्तियों
+लुइस
+उत्तीर्ण
+राँची
+वनस्पतियों
+अल्फ़ा
+रीडर
+गेंदबाज
+नकद
+क्रिश्चियन
+राजेंद्र
+ऐल्कोहॉल
+कच्चा
+असोसिएशन
+लैंग्वेज
+मसाले
+ज़रूर
+मंडी
+सुमन
+सनी
+कर्मियों
+साइबेरिया
+कंपन
+आवर्त
+रुधिर
+गढ़ी
+चिकन
+स्नेह
+दत्ता
+धर्मग्रन्थ
+जौनपुर
+मुरादाबाद
+पर्वतमाला
+लौटा
+लाये
+गोपी
+दाएं
+पुनर्जीवित
+आगम
+प्रतिक्रियाओं
+हीरे
+तीर
+भ्रष्ट
+गर्भाधान
+परेड
+टेलीग्राफ
+ऐक्शन
+वीरता
+आर्क
+इफ़्तेख़ार
+टार्ज़न
+प्रतिलिपि
+डेढ़
+सम्पत्ति
+गर्व
+मदुगु
+माघ
+मूर्तियाँ
+छन्द
+कठिनाइयों
+अभियानों
+तया
+चांद
+कौषीतकि
+वास्तुकार
+पडता
+मज़बूत
+कार्यान्वित
+क्लाइंट
+पूरब
+साइमन
+क्षतिपूर्ति
+माध्यमों
+स्केल
+उत्तरदायित्व
+पतला
+पीटर्सबर्ग
+नौका
+पटल
+समझाने
+मिसौरी
+आण्विक
+एस्पिरिन
+म०ब०
+जोन
+कुक
+बाईं
+ध्येय
+ब्लेड
+कृत्य
+गार्सिया
+तीर्थंकर
+सम्मुख
+चाहीये
+मार्केटिंग
+रोमांचक
+सहानुभूति
+वायरलेस
+घृणा
+महाद्वीपीय
+उर्मिला
+बसंत
+दवाएं
+पकाने
+नन्दा
+अलवर
+निराशा
+छिपा
+तपेदिक
+आदिवासियों
+अनुवादित
+सातवें
+सिक्का
+संवत्
+सावन
+कार्पोरेशन
+उर्वरक
+राही
+ओलिवर
+पांचवें
+झीलें
+डेविल
+खां
+अन्तरराष्ट्रीय
+ब्राह्मी
+कांड
+जू
+गाँवों
+भैरव
+वीकली
+टुडे
+बेसिन
+बाघों
+निरूपित
+शाप
+मन्त्री
+कुंडली
+अथ
+राष्ट्रगान
+आणविक
+दांतों
+वैश्वीकरण
+कहें
+शैवाल
+सिलसिला
+कैरी
+१९५५
+काबुल
+मोटरसाइकिल
+विवश
+फ़ूड
+अरोड़ा
+गिरोह
+पते
+झरना
+अनुमोदित
+मांडूक्य
+कडियां
+मजाक
+जरी
+विकीपीडिया
+होत
+जमैका
+स्पष्टीकरण
+पाद
+जरूरतों
+एम्पायर
+हस्त
+संहिताओं
+लड्डू
+मध्यकाल
+वीकी
+देवगन
+चित्रआकार
+विदिशा
+कॉफ़ी
+सेंचुरी
+होते।
+मित्रता
+कठोरता
+वज़ीर
+रूपक
+अश्वेत
+राज्यसभा
+आभूषण
+चैम्पियन
+उपरान्त
+लार्ड
+नोबल
+प्रविष्टियां
+बस्तियों
+िए
+नानक
+बर्ड
+पड़ेगा
+लिंकन
+बहाल
+९६
+बंदूक
+रेट
+अयोध्याकाण्ड
+महाप्रभु
+ग्राहम
+नल
+डार्विन
+ग्रेटर
+कारखानों
+वाट
+सोचने
+हिम्मत
+बढाने
+लेबर
+गिना
+पूर्वजों
+बेचे
+हरिवंश
+श्वेताश्वतर
+माइक्रो
+सीनेट
+पु
+दिए।
+नकदी
+ब्रॉडबैंड
+फ्रेमवर्क
+दाग
+ँ
+ग्लूकोज
+आश्वासन
+दरगाह
+बीवी
+किस्में
+अभिकल्पना
+इन्दिरा
+रामकृष्ण
+शेन
+वार्
+पॉइंट
+झांसी
+चेल्सी
+वाइस
+महानतम
+विश्वसनीयता
+चूना
+डिस्प्ले
+प्रकोप
+सदाबहार
+लोहिया
+मीनाक्षी
+र्ता
+हावर्ड
+इस्लामिक
+कौशिक
+भुजा
+पहलवान
+जादुई
+अर्थशास्त्री
+मनमौजी
+शायर
+डिजाइनर
+समयावधि
+सपनों
+मर्यादा
+रेकी
+दरवाजा
+उत्त
+बारूद
+हे।
+कुर्सी
+जन्मजात
+लूट
+नियोजित
+नियोजन
+तेरह
+हिंगू
+मैडोना
+्म
+सोमनाथ
+पीपुल्स
+मुद्रास्फीति
+बजाने
+काँच
+तैराकी
+साबुन
+अभ्यारण्य
+बढ़ाते
+तन
+उ०प०
+महासभा
+अहंकार
+मांसपेशी
+निर्वात
+खतरों
+जाओ
+हैपलोग्रुप
+हैवीवेट
+आरोपों
+सितारे
+विनियमित
+सब्जियों
+शीतकालीन
+पार्टियों
+शिला
+रसवात्सल्य
+पश्च
+चॅक
+लड़ाकू
+तुझे
+रॉस
+क्लोरीन
+विषाक्तता
+मानों
+वाक्यों
+प्रतियों
+उल्टी
+हैरिस
+निकालना
+अक्षम
+सिंधी
+विशेषत
+आस्ट्रिया
+अवगत
+साधारणत
+मार्क्स
+चीता
+व्यवसायों
+डालना
+क्षितिज
+पालिका
+उल्टा
+कारखाना
+सैयद
+कमेटी
+भला
+फेयर
+फ्लू
+रामभद्राचार्य
+स्प्रिंगस्टीन
+पिस्टन
+संदर्भों
+जनसँख्या
+आनुवांशिक
+उषा
+ज़रिए
+सीमाएं
+घर्षण
+प्रौद्योगिकियों
+दिखती
+मतों
+लत
+बैले
+एक्यूपंक्चर
+फोटोग्राफर
+क्रिकेटर
+अनीता
+इण्डिक
+आधिपत्य
+सतही
+गुफाओं
+प्रतीकात्मक
+नशीली
+शुक्ला
+शेंगेन
+फास्ट
+बुल्गारिया
+महंगे
+सनम
+नज़रिया
+हेलो
+माथुर
+सेवाएँ
+रिपब्लिक
+सेंसर
+सर्कल
+बिज़नेस
+सेकेंड
+असत्यापित
+कैनेडी
+दुर्भाग्य
+विनायक
+कारगर
+प्रस्तावना
+अरस्तू
+बताये
+गृहयुद्ध
+तर
+शीट
+गिरफ्तारी
+वार्मिंग
+इसीलिये
+महासागरीय
+खनिजों
+पेरी
+जटिलताओं
+जीती
+लॉरेंस
+पूर्
+साठ
+सूडान
+एबीसी
+संस्थाएँ
+सिएटल
+आख्यान
+बोल्ट
+खानों
+यीशु
+परिलक्षित
+अभिमन्यु
+दैत्य
+पॉलिन
+निकाली
+राष्ट्रवाद
+खोजा
+साक्षी
+पारदर्शी
+७२
+जाएँगे।
+फुलवारीशरीफ़
+वैवाहिक
+जुलती
+सेंटीमीटर
+ईश
+नाभि
+रेशे
+संकीर्ण
+नेताजी
+टीके
+एड्रेस
+विश्व
+चार्टर
+बीना
+मधुबनी
+पियानो
+हेक्टेयर
+मंगलौर
+फलत
+सीने
+संभाल
+अलास्का
+स्पाइवेयर
+सुलोचना
+नीलगिरी
+तैसें
+उभरा
+राजकोट
+मिलीग्राम
+फाइलें
+हिब्रू
+बैग
+आटा
+होतीं
+शंख
+मजबूती
+सीना
+उनमे
+आज़मी
+अभिलेखों
+रोचेस्टर
+पुष्ट
+दाहिनी
+क़रीब
+कार्लोस
+जादूगर
+मैनें
+अवरुद्ध
+झ
+सस्ता
+लैंस
+टैक्स
+बैड
+इशारा
+पढ़ना
+विलायक
+ज्यामितीय
+एनी
+पत्तियाँ
+बहामास
+पढ़े
+कारें
+प्ले
+चश्मे
+प्रतिकृति
+झंडा
+उभरते
+स्टेनली
+डेव
+बेनोइट
+वीवरण
+निकालकर
+तदनुसार
+बुल
+अवशेषों
+कच्छ
+बताना
+एंटरटेनमेंट
+राज्यमंत्री
+मायने
+परख
+बराक
+मिले।
+ढाई
+प्रतिफल
+क्रियाएँ
+स्थूल
+बसु
+आकलनकर्ता
+गुट
+अथर्ववेद
+संस
+केट
+टीमें
+सैंडविच
+लेखिका
+कैबिनेट
+जुर्माना
+मारी
+मिटाने
+परवरदिगार
+अंदाज़
+मूल्यवान
+लिखता
+संचय
+साउंड
+युवराज
+विकिक्वेट
+स्कूली
+नशे
+प्रयोक्ताओं
+पापों
+पित्त
+बहल
+विकलांग
+डूब
+किंगफिशर
+कार्यक्षमता
+टेड
+वगैरह
+डाउनटाउन
+अपूर्व
+कलन
+थाली
+साढ़े
+पीली
+कृष्णन
+९९
+प्रोसेसर
+एमआईटी
+तंतु
+राजेन्द्रनाथ
+छीन
+स्टैंड
+मुरलीधरन
+कंप्यूटिंग
+सॉफ़्टवेयर
+चुप
+एसी
+प्रोटोटाइप
+चुनने
+राजी
+अंडर
+सुविधाएँ
+शरत
+हरेक
+मु
+विमानसेवा
+पड़ी।
+मूर्तिकला
+जुडी
+संविदा
+बाय
+बढ़ाता
+रुख
+लोकगीत
+समायोजन
+अमेरिकियों
+कैन
+जीप
+नक़ल
+तेथ
+श्रृंखलाओं
+ज़माने
+मशीनी
+एक्सरे
+आह्वान
+अलाउद्दीन
+प्रत्याशी
+बिन्दू
+रहस्यमय
+रेखाएँ
+पिया
+पत्रकारों
+प्रतिभूति
+उमर
+स्वच्छता
+घनश्याम
+विषाक्त
+दबाने
+अध
+जोड़ते
+वायुमंडलीय
+ठंड
+बर्फ़
+फीसदी
+लेआउट
+दरिया
+क्लबों
+छत्रपति
+असुरक्षित
+नागरकोविल
+कार्यो
+सौभाग्य
+परवाह
+महंगा
+युगांडा
+नवाचार
+रामचन्द्र
+जुलता
+निष्कासन
+गर्भगृह
+वेदांत
+निराश
+शोधकर्ता
+पड़ोस
+मौके
+असफलता
+गय
+जयसिंह
+हैदर
+संगीतकारों
+दीपावली
+मूसा
+समाजों
+मानवाधिकार
+जोड़ना
+ट्रम्प
+एंजाइम
+गांधीजी
+चुनी
+१९३१
+डिवाइस
+समझाया
+हजरत
+प्रमोद
+कुशीनगर
+बर्मन
+गोलार्ध
+मोह
+पढ़ते
+गवाह
+मर्सिडीज
+आमन्त्रण
+कतर
+एकाधिकार
+टायसन
+ऑपरेटर
+बलराम
+होंगी
+आये।
+नानी
+अलीगंज
+जहा
+विद्युतीय
+जड़ों
+अपराधियों
+द्वि
+जौ
+बंदर
+बढ़िया
+रेसलमेनिया
+इलेक्ट्रान
+फिलीपींस
+प्राप्त
+क्यूंकि
+विकलांगता
+जिल्हा
+सींग
+बछवारा
+हावी
+गाए
+एकेडमी
+वाइरस
+सवालों
+फोटोग्राफी
+हाइड्रोकार्बनों
+कोबेन
+स्वर्गीय
+यार
+कोशिकीय
+बखरी
+उतरने
+गैलापागोस
+विलास
+हंगल
+आज़ादी
+अंशों
+सिलेंडर
+केन्या
+अप्रयुक्त
+धर्मनिरपेक्ष
+प्रबंधको
+ताजिकिस्तान
+पुनर्गठन
+स्टडी
+समा
+ीर्षक
+दोषों
+आईएसओ
+कोला
+रेलमार्ग
+जहाज़
+बहाने
+थोक
+जानबूझकर
+बेकेट
+कमाने
+खाल
+छावनी
+डबल्स
+पहनते
+आल
+मनोरंजक
+फ्रैंकलिन
+भ्रमित
+सुज़ुकी
+वॉर्स
+वर्जित
+अनशन
+वुड
+अपवाह
+श्राफ
+एवेन्यू
+नाप
+पर्पल
+हुक्म
+भूगोलवेत्ता
+दबा
+उभर
+शंघाई
+पैकेजिंग
+नॉटिंघम
+वर्
+भूमिकाएं
+जनमत
+सीखा
+हलसी
+ग्रैमी
+सकेगा
+वार्त
+१९४०
+डैन
+कलंकीत
+कारन
+नहरें
+पडा
+२५०
+दर्रा
+ओड़िया
+कांफ्रेंस
+तिमाही
+फिल्टर
+ग्राफिक्स
+लाइक
+रोज़ेज़
+केक
+आंदोलनों
+ऑ
+७६
+गाँठ
+सेन्ट्रल
+करों
+पोजीशन
+ट्रांस
+अस्पतालों
+प्रचारित
+सपोर्ट
+समितियों
+एस्टेट
+संकुचित
+दिखते
+जलन
+उत्तराधिकार
+प्राध्यापक
+सूक्ष्मजैविकी
+मिर्जापुर
+रैखिक
+नैनोट्यूब
+वीजा
+गुजरती
+मालाबार
+निगमों
+पोरबंदर
+ट्वेंटी
+नवरातिलोवा
+्त
+७७
+जासूस
+अभूतपूर्व
+नवागन्तुकों
+वर्मनने
+मिसाल
+गरीबों
+फूट
+फ्रेंड्स
+फोकस
+शत
+तैसा
+गे
+एनिमेशन
+मेवाड़
+स्ट्रीम
+१९५८
+प्रमुखता
+पेशियों
+ऋ
+जलाशय
+चलाता
+क्ष
+हेमामालिनी
+बैंगलोर
+सुनते
+लैंगिक
+सुदर्शन
+रमन
+नाइट्राइट
+टिहरी
+कैदी
+कस्टम
+खरा
+चिप्स
+अनगिनत
+महाकवि
+आवश्यकताएं
+कमिश्नर
+रचा
+श्रेणीबद्ध
+रवाना
+बूटी
+वाँ
+खिलौना
+गर्ल्स
+कमांड
+चलाना
+संसद्
+तस्वीरों
+प्रतियोगिताएं
+शाखाएं
+निरूपा
+पावन
+रसायनों
+औषध
+वीणा
+साजिश
+बुजुर्ग
+एनालॉग
+मकबरे
+परीक्षित
+धोनी
+नबम्बर
+प्रबंधित
+सैल्मन
+आकारों
+सवाई
+माईस्पेस
+किण्वन
+आईबीएम
+प्लांट
+गुजर
+शर्ट
+ल०व०
+विकिसम्मेलन
+पंद्रहवीं
+मातृ
+ीय
+भिक्षु
+फ़ोटो
+अपडेट
+दोहरा
+क्रेन
+बाइबल
+पहुँचाने
+दाएँ
+निःशुल्क
+नाइट्रेट
+एरनाकुलम
+पहुंची
+सक्रियता
+लियोन
+मंडली
+लोकपाल
+निकायों
+आधुनिकता
+वसूली
+नारा
+राना
+गॉर्डन
+दांव
+चन्द्रशेखर
+हार्बर
+सलाद
+मंत्रिमंडल
+रसेल
+तब्दील
+आशिक
+विधायक
+बची
+१९४९
+जैकी
+पनीर
+वेशभूषा
+वेल्श
+पसन्द
+चुपके
+चि
+अतरी
+परतों
+मधुबाला
+सांप
+पहुंचता
+रोकना
+पकड़े
+१९२०
+पीतल
+नास्तिक
+नासिर
+किस्मत
+लाइनें
+प्रतिबिंब
+माफी
+मार्क्सवादी
+एथिलीन
+कोशीश
+जगद्गुरु
+जीना
+वाह
+प्रेसीडेंसी
+सीनियर
+पूर्णता
+फिजी
+अत्र
+होनेवाली
+बिड़ला
+रिवाज
+उपनगर
+ईथर
+बद्रीनाथ
+शीर
+ु
+रेखाचित्र
+महेन्द्र
+त्तराखण्ड
+सूत
+सीढ़ी
+भट्ठी
+भण्डार
+व्यवसायी
+सेवानिवृत्त
+गुणांक
+जामा
+शेखावत
+८००
+क्रूर
+घिरे
+फलक
+अम्बेडकर
+लगन
+बिन्दुओं
+मुकुट
+वेस्टमिंस्टर
+इमाम
+बर्नार्ड
+मृदा
+बायें
+शासकीय
+ख़िताब
+षड्यंत्र
+रेखीय
+स्पीयर्स
+जीमेल
+डिस्ट्रिक्ट
+अल्बानिया
+राशियों
+लीन
+गवाही
+जस्टिस
+स्पेलिंग
+बाँटा
+कुश
+मकसद
+अटल
+मेटा
+सर्पिल
+रास
+पंखों
+संवेदना
+हलचल
+संकल्पना
+३०००
+मक्खन
+जॉर्डन
+मिथ्या
+समीकरणों
+फेफड़े
+पैतृक
+प्लैटिनम
+एंथोनी
+वीनस
+बदली
+७००
+पीढ़ियों
+सूरीनाम
+स्ट्रॉस
+क्रियाशील
+विक्रेताओं
+मोल
+लड़ते
+रहो
+वक्तव्य
+उत्पादकता
+मॉनिटर
+पुरोहित
+मालवीय
+समझी
+रूपांतर
+पनामा
+प्रतिरोधक
+समस्तीपुर
+वेधशाला
+पीड़ितों
+देवदास
+अवधारणाओं
+फर्ग्यूसन
+ग्लेन
+चौड़े
+फाँसी
+आंत्र
+त्रि
+फेरारी
+पदार्थो
+शंकु
+दादी
+पुनरावर्तन
+विवरणों
+हलके
+दरार
+मीन
+गिरीश
+चुनें
+निभाता
+१९४५
+स्पीड
+यथार्थवादी
+तोप
+किट
+चिन
+पुकार
+मॉडर्न
+कड़े
+कावेरी
+आई।
+तूफ़ान
+द्योल
+पिकनिक
+बायर
+गिटारवादक
+एकांकी
+लगाव
+सस्ती
+खुदा
+बढ़ाना
+संयंत्रों
+निष्पक्ष
+अरविंद
+पकड़ा
+गिने
+शहद
+मिथक
+मून
+दीया।
+डेविडसन
+ग्राफिक
+प्रियस
+अनिष्पक्ष
+कराटे
+सुनहरा
+सचिवालय
+फ़ॉर्मैटिंग
+वाल्टर
+स्तंभों
+आटे
+स्मार्ट
+मेक
+घाटियों
+मेसन
+अनोखी
+सदाशिव
+प्रतिजन
+रुझान
+प्रवीण
+कपिल
+विधवा
+रुकावट
+टर्नर
+त्रिभुज
+मंत्रियों
+तत्पश्चात
+चूहे
+म्हणे
+कॉलेजों
+उत्कीर्ण
+र्षक
+घेर
+नेपोलियन
+सुलझाने
+विभिन्न
+आइस
+भित्ति
+गला
+वैधता
+लुकास
+उड़
+स्टैंडर्ड
+खिलौने
+युगों
+लिवरपूल
+लिप्यन्तरण
+खड़ीबोली
+पर्दे
+शत्रुघन
+अग्निहोत्री
+वर्चस्व
+बहिष्कार
+एडवेंचर
+यूटोपिया
+ऐसीटिलीन
+विचरण
+कल्पित
+मुख्य
+अपनाई
+गंधक
+ेश
+किशोरावस्था
+लेज़र
+कैम्प
+टाई
+तुरन्त
+अर्धचालक
+मॉरीशस
+साँस
+संगठनात्मक
+बहुवचन
+तले
+कभार
+पुकारा
+चाँदनी
+१९५९
+जिनपर
+नागराज
+मोनिका
+्तराखण्ड
+६४
+सुखद
+आवारा
+पानदारक
+एशियन
+चैत्र
+कैश
+हथेली
+नैनो
+झूठा
+विस्थापन
+प्रमाणीकरण
+इसराइल
+आठवें
+सागरीय
+प्रजापति
+किसने
+सभ्यताओं
+अर्ल
+स्वराज
+१९३६
+चन्द
+बसाया
+महानदी
+वर्ड
+रिसाव
+चम्मच
+प्रशिक्षक
+रघुनाथ
+एमिनेम
+सुधा
+पंद्रह
+काटा
+चादर
+जैम
+निकटता
+उमा
+भयभीत
+फ़ॉर्मूला
+शाहजहाँ
+इंजीनियरों
+वर्दी
+ूर्व
+आनुवंशिकी
+घेरा
+हाथियों
+रैली
+संलयन
+आवर्ती
+क्रियान्वित
+दशहरा
+वृद्ध
+विरोधियों
+बोवी
+भूविज्ञान
+पो
+होय
+ऋणात्मक
+लाते
+अण्डा
+सम्बंध
+बोट
+इटावा
+साहसिक
+आपातकाल
+टायर
+साइप्रस
+चूहों
+विधियां
+षक
+जोड़ती
+त्रिज्या
+मनाते
+बांड
+प्रतिबद्धता
+आइसलैंड
+उत्तेजक
+पैमाना
+बांद्रा
+गर्भपात
+पब्लिशिंग
+अन्यत्र
+बम्बई
+महीन
+पूंजीवाद
+क्रियान्वयन
+संगीतमय
+दैट
+दाखिला
+आवश्यकतानुसार
+मेनन
+स्प्रिंग
+ख़िलाफ़
+शक्तियां
+अंतरजाल
+यूक्रेन
+अस
+वर्जिन
+मानती
+सद्भावना
+आंद्रे
+वल्लभ
+इजरायल
+अध्यायों
+मजदूरी
+उत्तरोत्तर
+प्रभात
+श्रोताओं
+हलन्त
+हीरोज़
+कुँवर
+अलेक्जेंडर
+कराया।
+वोल्टता
+एवार्ड
+गोल्डेन
+पनडुब्बी
+स्टेरॉयड
+सचदेव
+ट्रू
+सिरों
+मारकर
+माउंटबेटन
+बार्नस्टार
+कोका
+मन्दिरों
+फ़िल्मी
+धाराएं
+सांप्रदायिक
+आत्मसमर्पण
+समांतर
+प्रीमियम
+विनोबा
+बहुराष्ट्रीय
+डैविल
+धागे
+दसवीं
+बार्कलेज
+बिरला
+प्रतिमान
+कक्षाओं
+हैना
+अमूर्त
+मंज़िल
+निरंतरता
+निपुण
+ढोल
+१९४२
+मनोरोग
+डेप
+यूनीवर्स
+डाला।
+क्षार
+शूट
+बेसबॉल
+बीएमडब्लू
+शौकिया
+प्रागैतिहासिक
+ारत
+मुझ
+गुफाएं
+वर्क
+अनन्य
+सुरुचि
+छा
+बग
+कर्क
+उठे
+हक
+प्रशस्ति
+कलाई
+जयप्रकाश
+महीना
+चिंतित
+दूषित
+नियोक्ता
+स्वदेश
+यत्र
+पूछताछ
+विस्थापित
+खोजों
+लाभान्वित
+कांट
+पहचाने
+बॉर्न
+प्रवृति
+रेजिमेंट
+थिंक
+ऐश
+स्थगित
+सीटी
+विशेषतः
+बुराई
+रुद्रप्रयाग
+सुषमा
+८४
+बनी।
+जनजातियों
+रेख
+अन्याय
+संवाददाता
+कच्ची
+बोलियाँ
+एडी
+पेंटिंग
+जिन्हे
+रति
+स्टार्च
+अबू
+पहुंचते
+अम्लीय
+सैर
+बीबी
+इंटरटेनमेंट
+वानस्पतिक
+बेशक
+श्लोकों
+आपात
+नन्द
+मेज
+तृतीयक
+टॉड
+प्रसिद्द
+रांगेय
+कैप्टन
+बीन
+चाह
+बनीं
+पोटेंशिअल
+असित
+सीरम
+कैदियों
+चुनरी
+ज्येष्ठ
+अगासी
+जस्ता
+थेरेपी
+मैथुन
+लोकल
+सूर
+यात्राओं
+गेंदों
+चढ़
+गाजीपुर
+भागीदार
+राहु
+सजाया
+उत्पीड़न
+ओमान
+बायीं
+तुर्कमेनिस्तान
+फेस
+धड़
+वन्यजीव
+चीज़ों
+अनमोल
+निभाते
+जैसें
+मुंशी
+सुपरमैन
+बहारी
+विकिस्रोत
+दुग्ध
+लगीं
+गुड्डी
+माउस
+आग़ा
+गोरखा
+कसौटी
+अल्फ्रेड
+पूज्य
+वोक्सवैगन
+ख़
+तना
+ट्रैफिक
+खंडित
+मो
+्षक
+नायडू
+शबाना
+आतंकवादियों
+जाली
+लिविंग
+पुनरावृत्ति
+एक्सप्लोरर
+फ़ोर्स
+श्रोता
+राजनयिक
+तुल्य
+डेज़
+फ्रेड
+परोसा
+ची
+फोर्ब्स
+कण्ठ
+बर
+कीन
+प्रतिभागियों
+सुरेन्द्र
+फाइलों
+निद्रा
+बंगलोर
+संभावनाओं
+बॉस्टन
+हार्ले
+प्रोसेसिंग
+नासिक
+वाइड
+एनर्जी
+पकवान
+दारा
+कम्पनियों
+थोडा
+नवादा
+सप्त
+शाहरुख़
+तांबे
+नग्न
+अंजाम
+तुग़लक़
+बचाया
+बैनर्जी
+बादलों
+संप्रेषण
+लैरी
+९८
+डायमंड
+शुभारंभ
+अपार
+देगा।
+खिड़की
+जश्न
+मैनपुरी
+विधाओं
+६६
+भ्रामक
+तंत्रों
+सीरिज़
+लहरों
+पुस्तकालयों
+विनाशकारी
+जैज़
+खतना
+बस्तियां
+उत्कर्ष
+कोशिकाएँ
+नेहरु
+मेड
+लिखा।
+धनात्मक
+चॉकलेट
+मनोरमा
+१९५२
+बार्सिलोना
+लावा
+फैजाबाद
+वाटर्स
+प्रात
+बढ
+विद्युत्
+मसलन
+मसूरी
+अचार
+सटीकता
+कीर्तिमान
+ब्रिगेड
+प्रकाशीय
+कं
+उत्साहित
+नौकर
+वारिस
+नामदेव
+हेमंत
+ईंटों
+इंटेलिजेंस
+सपाट
+गोबर
+पर्सनल
+कार्यप्रणाली
+असीम
+कॉलम
+झाँसी
+प्रबन्ध
+करिश्मा
+मिसिसिपी
+ब्रेकिंग
+निभा
+खाती
+दावों
+वोल्ट
+आप्रवासी
+धड़कन
+बिताया
+प्रशस्त
+बीटल
+महलों
+निलंबित
+एबरडीन
+लूथर
+बारबरा
+खण्डों
+यूज़र
+बर्बाद
+उन्नयन
+वेल्लोर
+राजबब्बर
+समन्वित
+लोप
+हल्दी
+बुद्धिमान
+किराए
+८८
+अनुसन्धान
+जेड
+बादाम
+पासपोर्ट
+खुलता
+माकपा
+प्रमाणन
+वृन्दावन
+सड़कें
+बम्बोर
+पोषित
+सिन्दूर
+अमोनिया
+श्रुति
+उठाए
+तकनीकें
+पदवी
+ऑर
+गड़बड़ी
+आमाशय
+नरक
+मुहैया
+गुजरने
+संग्रहीत
+जेसन
+सीक्रेट
+असिमोव
+कन्याकुमारी
+र्व
+झारखण्ड
+उत्तराख
+परिपक्वता
+८१
+कौरव
+ज्ञानकोश
+रंगोली
+गान्धी
+ध्वनियों
+कनाडाई
+छिपे
+म्हणोनि
+प्रणालियाँ
+विखंडन
+गुम्बद
+किक
+बख़्तियारपुर
+वश
+नैस्टर
+शा
+बर्गर
+फ़ल
+हुवा
+बिक
+अटलांटा
+रोधी
+बचना
+घा
+लुटेरे
+मेगाडेथ
+बीजों
+वियना
+चिन्तन
+अय्यर
+सोम
+चिन्हित
+रेफरी
+सहिष्णुता
+छोड़ना
+मसले
+उद्यमी
+जुलते
+स्लोवाकिया
+साख
+गोकुल
+दरबारी
+बढ़ाई
+देखा।
+खूबसूरती
+पैसेंजर
+फ्लाइट
+हवाओं
+पीढी
+नौगांव
+आगंतुक
+लिली
+उत्तरकाशी
+गुरुत्व
+सिखाया
+पियरे
+शीर्
+सिक्स
+डब्ल्यूडब्ल्यूएफ
+प्री
+दशमलव
+तेतिहा
+क़ानूनी
+धृतराष्ट्र
+हाजीपुर
+आर्यभट्ट
+प्रायोजक
+सन्दूक
+सांसारिक
+फलित
+नामका
+भट्टी
+पांव
+त्
+सम्पादित
+शोधन
+विश्वविद्यालय
+कंस
+पम्प
+चलाई
+करतीं
+ईपू
+मिज़ोरम
+हीन्दीवीकीपीडीयाके
+दायें
+अयोग्य
+मृग
+आनेवाले
+लीबिया
+लेसनर
+तुमको
+मेहमान
+मेलबोर्न
+स्थापना
+थर्ड
+इमेजिंग
+सम्मेलनों
+अमज़द
+लगेगा
+बेड़े
+इब्राहिम
+पक्का
+पलट
+मानदंडों
+त्रिनिदाद
+साम्राज्यवाद
+परीक्षक
+पड़ाव
+पहाडी
+जुड़ना
+विलोपन
+सिलसिले
+खींचने
+चलाए
+जानकर
+बेली
+विचारकों
+पितामह
+नॉर्मन
+डिपार्टमेंट
+स्वादिष्ट
+सुगंध
+पेस
+समता
+गोंडा
+लेस
+फैलाने
+सैनी
+पिज़्ज़ा
+रामधारी
+तांत्रिक
+साध्य
+जन्मभूमि
+संभालने
+आकृतियों
+अख्तर
+हेल
+तवी
+पांडवों
+मीलकर
+उत्खनन
+स्वैच्छिक
+दिल्ली
+श्रीलंकाई
+दोहराया
+मुखर
+टोयोटा
+रिपोर्टिंग
+निषिद्ध
+गंगोत्री
+डिक
+परमार
+बार्न
+फ़ैल
+इण्डोनेशिया
+अकादमिक
+ड्राफ्ट
+भूकम्प
+दिखलाई
+धर्मशास्त्र
+किये।
+क्राई
+बकरी
+पाया।
+न्यूर्क
+जौहर
+कामयाबी
+फौज
+सुव्यवस्थित
+डॉक्टरों
+बढ़त
+क्योटो
+दर्जन
+जुटाने
+कलर
+हिन
+ग्
+प्रेरण
+एथलेटिक्स
+कपाल
+जस्टिन
+पश्तो
+कुंभ
+थाइलैंड
+बांस
+ँव
+कनेक्टिकट
+जोरदार
+बेरोजगारी
+सुल्तानपुर
+बिस्तर
+खींचा
+प्रौढ़
+एल्बमों
+कड़ा
+मानकीकृत
+सामंत
+वृहत
+परबत्ता
+दुल्हिनबाजार
+सोल
+चना
+भोसले
+सप्ताहांत
+विशालकाय
+धोने
+भस्म
+रहनेवाले
+टेघरा
+अमीन
+फ़्रान्सीसी
+शल्यक्रिया
+ग्रांट
+१९२१
+सांकेतिक
+फार
+मदिरा
+पोर्शे
+परिधान
+यूरेनियम
+जिन्होने
+बलात्कार
+परीक्षाओं
+उत्तराखण
+ट्रेक
+जन्में
+पि
+पवित्रता
+इंतजार
+लाता
+वादन
+महत्वपूर्ण
+ब्
+अल्जीरिया
+सीखना
+नगण्य
+खत्री
+चतुर्भुज
+बाक़ी
+१९००
+टेन
+करोड़ों
+स्क्रीनिंग
+टूटने
+प्रजातियाँ
+आन्तरिक
+कहो
+अपघटन
+देशो
+ब्रेट
+पहुँचे।
+परिस्थितियां
+म्
+पुनर्निर्देशित
+नतीजा
+साइबर
+पैदावार
+स्याही
+नंदा
+सैटेलाइट
+न्यूट्रॉन
+रोनाल्ड
+देवेन
+चमकदार
+जिगर
+योजनाएं
+प्लेग
+अध्यात्म
+विदेशियों
+सच्ची
+चट्टोपाध्याय
+दार्शनिकों
+परिसंपत्ति
+ओक
+जाये।
+इलाक़े
+तुमसे
+बिखरे
+व्यवहारिक
+तराखण्ड
+मऊ
+प्लूटो
+दुखी
+ताम्र
+इल्म
+फैलता
+समतुल्य
+किरणें
+पेव्ड
+हुमायूँ
+सईद
+भाभी
+अंडमान
+चूक
+रणधीर
+इब्न
+बो
+बॉस
+उपराष्ट्रपति
+वू
+स्पीकर
+च्वाइस
+स्टुअर्ट
+प्रदाताओं
+कार्गो
+डेन्जोंगपा
+महज
+सीतापुर
+लगान
+पेंटल
+अनुसूची
+हस्तियों
+बहू
+कुलीन
+किनारा
+कुलकर्णी
+धनराशि
+छुटकारा
+बगीचे
+शिरा
+देखती
+हीन
+मद
+बीट
+वर्धित
+संभाला
+नीच
+बेंज
+जम
+जप
+गियर
+एफएम
+आरोपित
+सोन
+ठाकरे
+स्टीवर्ट
+पाण्डेय
+आयकर
+स्वार्थ
+जन्मतिथि
+विज्ञप्ति
+न्
+रीज़न
+म्हणौनि
+वत
+रणनीतिक
+शु
+अत्याधिक
+खालसा
+प्रान्तों
+कैलोरी
+१२०
+विनिर्देश
+अमावस्या
+गोलियों
+जिन्दगी
+अशुद्ध
+स्मिता
+वार्तालाप
+दाखिल
+काउबॉय
+एक्टर्स
+टेनेसी
+पराबैंगनी
+घूमती
+खुलने
+हिरण
+संचारित
+लैला
+लाभप्रद
+प्वाइंट
+नर्तक
+जासूसी
+मानवों
+शाहपुर
+गुड़िया
+अनुग्रह
+९५
+विश्लेषक
+जहांगीर
+ही।
+त्रिशूल
+मनीश
+स्पैरो
+कोंकणी
+सेक्टर
+रिवर
+यथासंभव
+साम्यवाद
+हडसन
+सेव
+चैंपियंस
+बसों
+किपलिंग
+लड़
+विकिपिडिया
+घनिष्ठ
+दीवारें
+टॉक
+क्रमपरिवर्तन
+म्यूजियम
+प्लान
+केसरी
+फैमिली
+लातिन
+आर्द्रता
+घाना
+अस्मिता
+बट
+छड़ी
+कात्यायन
+पुनर्जन्म
+ग्लूकोज़
+अज्ञेय
+फिटनेस
+प्रतिभाशाली
+कलाकृतियों
+हीलियम
+दोहा
+अंधेरे
+तापीय
+मल्टी
+टीकू
+आर्किटेक्चर
+किन्हीं
+सत्यापन
+बलूचिस्तान
+लारा
+फिशर
+रिहा
+देवा
+गॉड
+सुनाया
+वेश
+सबौर
+प्रशान्त
+चिंताओं
+तंजानिया
+जाएँ।
+संयोजी
+साँचों
+पूछ
+श्राद्ध
+मात
+टैंगो
+अमरनाथ
+जानकार
+कृषक
+पेले
+गुणसूत्र
+पहियों
+जिज्ञासा
+टिप्पणियों
+कहलाने
+मोनोक्रोम
+हीरालाल
+बारीक
+देंगे।
+चित
+छोड़ते
+क़ुरान
+यमन
+आदर्शों
+अपन
+संघटन
+विषयवस्तु
+आमदनी
+स्क्वैश
+दर्शनों
+सूरदास
+मातृभूमि
+फेंकने
+१९५३
+दोस्ताना
+लैण्ड
+योजन
+लॉर्ड्स
+अभि
+यूएफओ
+विध्वंस
+भूपति
+नदाल
+प्रतिभूतियों
+ट्री
+टॉमी
+संप्रदायों
+६२
+वैयक्तिक
+भेजता
+मल्टीमीडिया
+आयामी
+गुड़
+ट्रॉफी
+आविष्कारक
+हुईं।
+लॉयड
+चिह्नों
+बिशप
+साँप
+हेवी
+पर्यवेक्षण
+ाद
+चिन्ता
+आलम
+चौबीस
+तलसानिया
+ताड़
+दायित्वों
+गलतियाँ
+रिएक्टर
+चंद्रगुप्त
+सप्तम
+नाइजीरिया
+स्थ
+गुदा
+त्यों
+मिटटी
+कर्ज़
+बॉन
+६७
+तात्कालिक
+गार्डनर
+अनूठा
+ओड़िआ
+रीटा
+विश्लेषणात्मक
+देवरिया
+नेवर
+्दी
+चिकनी
+डेटिंग
+पोर्टेबल
+उगाया
+बालकों
+स्पोर्ट
+१९५१
+द्रोण
+आवंटित
+गांगुली
+नार्वे
+यन्त्र
+देशपांडे
+८२
+प्याज
+एसएमएस
+तूं
+संहार
+अलौली
+शकीरा
+छू
+देवकी
+गोल्डबर्ग
+मशीनें
+कर्ज
+चढ़ने
+हिमानी
+बतलाया
+बंगलुरु
+पढाई
+नेम
+फ़ैसला
+प्रीतम
+हिरासत
+मुबारक
+खा०प०
+डिप्लोमा
+कॉनकॉर्ड
+समझकर
+संदर्म
+एलर्जी
+नितांत
+उठने
+मेरिल
+गोपनीय
+सुगम
+क़ी
+ाखण्ड
+युग्म
+बढ़ना
+अबाउट
+वहा
+चला।
+वतन
+बाधाओं
+हुबली
+हीट
+फुल
+अनुपस्थित
+येल
+भावुक
+पित्ताशय
+टिन
+लड़ा
+रॉकी
+नोल्स
+वमन
+मारना
+ब्लाक
+बहोत
+कूपर
+करो।
+प्रमाणपत्र
+यूट्यूब
+सम्मलेन
+रनवे
+पूँजी
+मंडप
+पोटेशियम
+उत्तरांचल
+ठेठ
+ओडिशा
+पल्लव
+इन्दौर
+तर्ज़
+ः
+अनूप
+आओ
+कुख्यात
+बांसुरी
+अनुपयुक्त
+मगरमच्छ
+स्पा
+सेबी
+चाहा
+धमनियों
+बारें
+अश्व
+हस्तिनापुर
+ईसाइयों
+आइपॉड
+१०१
+इराकी
+रयान
+ाल
+हिमनद
+अमरावती
+गिरी
+पूछने
+प्रेषित
+घटाने
+डिस्कवरी
+पथरी
+रायबरेली
+नायनमार
+बढती
+मिलेगी
+किशोरों
+साड़ी
+शिवजी
+पुनर्वास
+सहरसा
+कैरोलिना
+आरण्यक
+असुर
+लौंग
+समाविष्ट
+ज़ोन
+फकीर
+बियोवुल्फ़
+राइस
+थेफ्ट
+लू
+ल०
+अज़ाब
+वेबदुनिया
+ल्यूकेमिया
+मार्गरेट
+संन्यास
+रनों
+सुनहरे
+सबने
+विरल
+पॉलिसी
+रश
+कैमरों
+एंजेल्स
+प्राणायाम
+सेलिब्रिटी
+कण्डारस्यूं
+शाश्वत
+जुलूस
+विश
+जेफ
+मतानुसार
+उत्पात
+मामा
+७३
+रहीं।
+क्लिंटन
+विकिया
+आइवी
+लिस्ट
+आबू
+गोमती
+पुरुषोत्तम
+उत्तराखण्
+हेराल्ड
+दांता
+पद्मश्री
+शर्तें
+कटिहार
+स्विंग
+उत्तरार्द्ध
+सिंगल्स
+केदार
+रघु
+वासना
+पहुँचकर
+न्यूकैसल
+मांगी
+अमल
+सल्फर
+छोड
+अंजना
+कंप्यूटरों
+ढ
+विलिस
+सीकर
+जुड़ता
+प्रसन्नता
+प्लेटफॉर्म
+गिरि
+उछाल
+करीना
+जहर
+मासके
+सम्पदा
+चौदहवीं
+ढाईज्यूली
+साओ
+कोचीन
+श्रावण
+अर्पित
+मासूम
+टीन
+स्पार्क
+कट्टर
+चढ़ा
+ट्रिब्यून
+होंडा
+कीये
+एंटोनियो
+लैस
+किससे
+एकजुट
+पतंग
+१९२७
+टीकाकरण
+मूक
+असरगंज
+सतहों
+नाल
+आयताकार
+चढ़ाव
+कार्यशील
+दक्षिणपूर्व
+माथे
+मर्फी
+गुजरता
+सफ़र
+स्लोवेनिया
+रिले
+कॉमन
+जमाव
+कुलभूषण
+्स
+क्रोम
+उजाला
+मूत्राशय
+इस्राइल
+नाड़ी
+ंवत
+परगना
+लैंडिंग
+रेलगाड़ी
+कलाँ
+उद्धार
+ज़रिये
+शॉर्ट
+टिक
+डिज़नी
+फिल्माया
+मरते
+निष्कर्षों
+उलट
+भीमसेन
+चक्रों
+मात्राओं
+प्रणाम
+सिम्बियन
+संस्थागत
+बिताने
+आंग्ल
+बिजनौर
+फायदे
+खेड़ा
+कार्यभार
diff --git a/src/Makefile.am b/src/Makefile.am
index 225444e..31399a6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -47,6 +47,9 @@
HBDEPS += $(GLIB_DEPS)
HBSOURCES += $(HB_GLIB_sources)
HBHEADERS += $(HB_GLIB_headers)
+HB_HAS_GLIB_DEF = define HB_HAS_GLIB 1
+else
+HB_HAS_GLIB_DEF = undef HB_HAS_GLIB
endif
if HAVE_FREETYPE
@@ -55,6 +58,9 @@
HBDEPS += $(FREETYPE_DEPS)
HBSOURCES += $(HB_FT_sources)
HBHEADERS += $(HB_FT_headers)
+HB_HAS_FREETYPE_DEF = define HB_HAS_FREETYPE 1
+else
+HB_HAS_FREETYPE_DEF = undef HB_HAS_FREETYPE
endif
if HAVE_GRAPHITE2
@@ -63,6 +69,9 @@
HBDEPS += $(GRAPHITE2_DEPS)
HBSOURCES += $(HB_GRAPHITE2_sources)
HBHEADERS += $(HB_GRAPHITE2_headers)
+HB_HAS_GRAPHITE_DEF = define HB_HAS_GRAPHITE 1
+else
+HB_HAS_GRAPHITE_DEF = undef HB_HAS_GRAPHITE
endif
if HAVE_UNISCRIBE
@@ -70,6 +79,9 @@
HBNONPCLIBS += $(UNISCRIBE_LIBS)
HBSOURCES += $(HB_UNISCRIBE_sources)
HBHEADERS += $(HB_UNISCRIBE_headers)
+HB_HAS_UNISCRIBE_DEF = define HB_HAS_UNISCRIBE 1
+else
+HB_HAS_UNISCRIBE_DEF = undef HB_HAS_UNISCRIBE
endif
if HAVE_DIRECTWRITE
@@ -77,6 +89,9 @@
HBNONPCLIBS += $(DIRECTWRITE_LIBS)
HBSOURCES += $(HB_DIRECTWRITE_sources)
HBHEADERS += $(HB_DIRECTWRITE_headers)
+HB_HAS_DIRECTWRITE_DEF = define HB_HAS_DIRECTWRITE 1
+else
+HB_HAS_DIRECTWRITE_DEF = undef HB_HAS_DIRECTWRITE
endif
if HAVE_GDI
@@ -84,6 +99,9 @@
HBNONPCLIBS += $(GDI_LIBS)
HBSOURCES += $(HB_GDI_sources)
HBHEADERS += $(HB_GDI_headers)
+HB_HAS_GDI_DEF = define HB_HAS_GDI 1
+else
+HB_HAS_GDI_DEF = undef HB_HAS_GDI
endif
if HAVE_CORETEXT
@@ -91,6 +109,9 @@
HBNONPCLIBS += $(CORETEXT_LIBS)
HBSOURCES += $(HB_CORETEXT_sources)
HBHEADERS += $(HB_CORETEXT_headers)
+HB_HAS_CORETEXT_DEF = define HB_HAS_CORETEXT 1
+else
+HB_HAS_CORETEXT_DEF = undef HB_HAS_CORETEXT
endif
@@ -147,7 +168,7 @@
pkgconfig_DATA = harfbuzz.pc
cmakedir = $(libdir)/cmake/harfbuzz
cmake_DATA = harfbuzz-config.cmake
-EXTRA_DIST += hb-version.h.in harfbuzz.pc.in harfbuzz-config.cmake.in
+EXTRA_DIST += hb-version.h.in hb-features.h.in harfbuzz.pc.in harfbuzz-config.cmake.in
lib_LTLIBRARIES += libharfbuzz-subset.la
libharfbuzz_subset_la_LINK = $(chosen_linker) $(libharfbuzz_subset_la_LDFLAGS)
@@ -178,6 +199,7 @@
HBLIBS += $(ICU_LIBS)
HBSOURCES += $(HB_ICU_sources)
HBHEADERS += $(HB_ICU_headers)
+HB_HAS_ICU_DEF = define HB_HAS_ICU 1
else
lib_LTLIBRARIES += libharfbuzz-icu.la
libharfbuzz_icu_la_SOURCES = $(HB_ICU_sources)
@@ -187,6 +209,7 @@
EXTRA_libharfbuzz_icu_la_DEPENDENCIES = $(harfbuzz_icu_def_dependency)
pkginclude_HEADERS += $(HB_ICU_headers)
pkgconfig_DATA += harfbuzz-icu.pc
+HB_HAS_ICU_DEF = undef HB_HAS_ICU
endif
endif
EXTRA_DIST += harfbuzz-icu.pc.in
@@ -226,6 +249,25 @@
$(NULL)
+BUILT_SOURCES += \
+ hb-features.h
+DISTCLEANFILES += \
+ hb-features.h
+
+hb-features.h: hb-features.h.in $(top_builddir)/config.status
+ $(AM_V_GEN) $(SED) \
+ -e 's/mesondefine HB_HAS_FREETYPE/$(HB_HAS_FREETYPE_DEF)/' \
+ -e 's/mesondefine HB_HAS_GDI/$(HB_HAS_GDI_DEF)/' \
+ -e 's/mesondefine HB_HAS_GDI/$(HB_HAS_GDI_DEF)/' \
+ -e 's/mesondefine HB_HAS_GRAPHITE/$(HB_HAS_GRAPHITE_DEF)/' \
+ -e 's/mesondefine HB_HAS_GLIB/$(HB_HAS_GLIB_DEF)/' \
+ -e 's/mesondefine HB_HAS_UNISCRIBE/$(HB_HAS_UNISCRIBE_DEF)/' \
+ -e 's/mesondefine HB_HAS_DIRECTWRITE/$(HB_HAS_DIRECTWRITE_DEF)/' \
+ -e 's/mesondefine HB_HAS_CORETEXT/$(HB_HAS_CORETEXT_DEF)/' \
+ -e 's/mesondefine HB_HAS_ICU/$(HB_HAS_ICU_DEF)/' \
+ "$<" > "$@" || ($(RM) "$@"; false)
+
+
%.pc: %.pc.in $(top_builddir)/config.status
$(AM_V_GEN) \
$(SED) -e 's@%prefix%@$(prefix)@g' \
@@ -368,6 +410,7 @@
test-iter \
test-machinery \
test-map \
+ test-multimap \
test-number \
test-ot-tag \
test-priority-queue \
@@ -407,6 +450,10 @@
test_map_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
test_map_LDADD = $(COMPILED_TESTS_LDADD)
+test_multimap_SOURCES = test-multimap.cc hb-static.cc
+test_multimap_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_multimap_LDADD = $(COMPILED_TESTS_LDADD)
+
test_number_SOURCES = test-number.cc hb-number.cc
test_number_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
test_number_LDADD = $(COMPILED_TESTS_LDADD)
diff --git a/src/Makefile.sources b/src/Makefile.sources
index 6c891ea..6c4fc5d 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -52,6 +52,7 @@
hb-map.hh \
hb-meta.hh \
hb-ms-feature-ranges.hh \
+ hb-multimap.hh \
hb-mutex.hh \
hb-null.hh \
hb-number.cc \
@@ -95,7 +96,10 @@
OT/glyf/Glyph.hh \
OT/glyf/GlyphHeader.hh \
OT/glyf/SimpleGlyph.hh \
+ OT/glyf/coord-setter.hh \
+ OT/glyf/composite-iter.hh \
OT/glyf/CompositeGlyph.hh \
+ OT/glyf/VarCompositeGlyph.hh \
OT/glyf/SubsetGlyph.hh \
OT/Layout/types.hh \
OT/Layout/Common/Coverage.hh \
diff --git a/src/OT/Layout/Common/Coverage.hh b/src/OT/Layout/Common/Coverage.hh
index eef89a2..fbd7c64 100644
--- a/src/OT/Layout/Common/Coverage.hh
+++ b/src/OT/Layout/Common/Coverage.hh
@@ -49,7 +49,7 @@
HBUINT16 format; /* Format identifier */
CoverageFormat1_3<SmallTypes> format1;
CoverageFormat2_4<SmallTypes> format2;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
CoverageFormat1_3<MediumTypes>format3;
CoverageFormat2_4<MediumTypes>format4;
#endif
@@ -65,7 +65,7 @@
{
case 1: return_trace (u.format1.sanitize (c));
case 2: return_trace (u.format2.sanitize (c));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return_trace (u.format3.sanitize (c));
case 4: return_trace (u.format4.sanitize (c));
#endif
@@ -74,10 +74,8 @@
}
/* Has interface. */
- static constexpr unsigned SENTINEL = NOT_COVERED;
- typedef unsigned int value_t;
- value_t operator [] (hb_codepoint_t k) const { return get (k); }
- bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+ unsigned operator [] (hb_codepoint_t k) const { return get (k); }
+ bool has (hb_codepoint_t k) const { return (*this)[k] != NOT_COVERED; }
/* Predicate. */
bool operator () (hb_codepoint_t k) const { return has (k); }
@@ -87,7 +85,7 @@
switch (u.format) {
case 1: return u.format1.get_coverage (glyph_id);
case 2: return u.format2.get_coverage (glyph_id);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return u.format3.get_coverage (glyph_id);
case 4: return u.format4.get_coverage (glyph_id);
#endif
@@ -100,7 +98,7 @@
switch (u.format) {
case 1: return u.format1.get_population ();
case 2: return u.format2.get_population ();
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return u.format3.get_population ();
case 4: return u.format4.get_population ();
#endif
@@ -127,7 +125,7 @@
}
u.format = count <= num_ranges * 3 ? 1 : 2;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
if (count && last > 0xFFFFu)
u.format += 2;
#endif
@@ -136,7 +134,7 @@
{
case 1: return_trace (u.format1.serialize (c, glyphs));
case 2: return_trace (u.format2.serialize (c, glyphs));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return_trace (u.format3.serialize (c, glyphs));
case 4: return_trace (u.format4.serialize (c, glyphs));
#endif
@@ -166,7 +164,7 @@
{
case 1: return u.format1.intersects (glyphs);
case 2: return u.format2.intersects (glyphs);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return u.format3.intersects (glyphs);
case 4: return u.format4.intersects (glyphs);
#endif
@@ -179,7 +177,7 @@
{
case 1: return u.format1.intersects_coverage (glyphs, index);
case 2: return u.format2.intersects_coverage (glyphs, index);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return u.format3.intersects_coverage (glyphs, index);
case 4: return u.format4.intersects_coverage (glyphs, index);
#endif
@@ -196,7 +194,7 @@
{
case 1: return u.format1.collect_coverage (glyphs);
case 2: return u.format2.collect_coverage (glyphs);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return u.format3.collect_coverage (glyphs);
case 4: return u.format4.collect_coverage (glyphs);
#endif
@@ -212,7 +210,7 @@
{
case 1: return u.format1.intersect_set (glyphs, intersect_glyphs);
case 2: return u.format2.intersect_set (glyphs, intersect_glyphs);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return u.format3.intersect_set (glyphs, intersect_glyphs);
case 4: return u.format4.intersect_set (glyphs, intersect_glyphs);
#endif
@@ -225,13 +223,13 @@
static constexpr bool is_sorted_iterator = true;
iter_t (const Coverage &c_ = Null (Coverage))
{
- memset (this, 0, sizeof (*this));
+ hb_memset (this, 0, sizeof (*this));
format = c_.u.format;
switch (format)
{
case 1: u.format1.init (c_.u.format1); return;
case 2: u.format2.init (c_.u.format2); return;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: u.format3.init (c_.u.format3); return;
case 4: u.format4.init (c_.u.format4); return;
#endif
@@ -244,7 +242,7 @@
{
case 1: return u.format1.__more__ ();
case 2: return u.format2.__more__ ();
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return u.format3.__more__ ();
case 4: return u.format4.__more__ ();
#endif
@@ -257,7 +255,7 @@
{
case 1: u.format1.__next__ (); break;
case 2: u.format2.__next__ (); break;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: u.format3.__next__ (); break;
case 4: u.format4.__next__ (); break;
#endif
@@ -273,7 +271,7 @@
{
case 1: return u.format1.get_glyph ();
case 2: return u.format2.get_glyph ();
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return u.format3.get_glyph ();
case 4: return u.format4.get_glyph ();
#endif
@@ -287,7 +285,7 @@
{
case 1: return u.format1 != o.u.format1;
case 2: return u.format2 != o.u.format2;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return u.format3 != o.u.format3;
case 4: return u.format4 != o.u.format4;
#endif
@@ -302,7 +300,7 @@
{
case 1: it.u.format1 = u.format1.__end__ (); break;
case 2: it.u.format2 = u.format2.__end__ (); break;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: it.u.format3 = u.format3.__end__ (); break;
case 4: it.u.format4 = u.format4.__end__ (); break;
#endif
@@ -314,7 +312,7 @@
private:
unsigned int format;
union {
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
CoverageFormat2_4<MediumTypes>::iter_t format4; /* Put this one first since it's larger; helps shut up compiler. */
CoverageFormat1_3<MediumTypes>::iter_t format3;
#endif
diff --git a/src/OT/Layout/Common/CoverageFormat1.hh b/src/OT/Layout/Common/CoverageFormat1.hh
index 82fd48d..5d68e3d 100644
--- a/src/OT/Layout/Common/CoverageFormat1.hh
+++ b/src/OT/Layout/Common/CoverageFormat1.hh
@@ -77,7 +77,14 @@
bool intersects (const hb_set_t *glyphs) const
{
- /* TODO Speed up, using hb_set_next() and bsearch()? */
+ if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2)
+ {
+ for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+ if (get_coverage (g) != NOT_COVERED)
+ return true;
+ return false;
+ }
+
for (const auto& g : glyphArray.as_array ())
if (glyphs->has (g))
return true;
diff --git a/src/OT/Layout/Common/CoverageFormat2.hh b/src/OT/Layout/Common/CoverageFormat2.hh
index 974d094..d7fcc35 100644
--- a/src/OT/Layout/Common/CoverageFormat2.hh
+++ b/src/OT/Layout/Common/CoverageFormat2.hh
@@ -80,8 +80,6 @@
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (this))) return_trace (false);
- /* TODO(iter) Write more efficiently? */
-
unsigned num_ranges = 0;
hb_codepoint_t last = (hb_codepoint_t) -2;
for (auto g: glyphs)
@@ -115,26 +113,22 @@
bool intersects (const hb_set_t *glyphs) const
{
+ if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
+ {
+ for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+ if (get_coverage (g) != NOT_COVERED)
+ return true;
+ return false;
+ }
+
return hb_any (+ hb_iter (rangeRecord)
| hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs); }));
}
bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
{
- auto cmp = [] (const void *pk, const void *pr) -> int
- {
- unsigned index = * (const unsigned *) pk;
- const RangeRecord<Types> &range = * (const RangeRecord<Types> *) pr;
- if (index < range.value) return -1;
- if (index > (unsigned int) range.value + (range.last - range.first)) return +1;
- return 0;
- };
-
- auto arr = rangeRecord.as_array ();
- unsigned idx;
- if (hb_bsearch_impl (&idx, index,
- arr.arrayZ, arr.length, sizeof (arr[0]),
- (int (*)(const void *_key, const void *_item)) cmp))
- return arr.arrayZ[idx].intersects (*glyphs);
+ auto *range = rangeRecord.as_array ().bsearch (index);
+ if (range)
+ return range->intersects (*glyphs);
return false;
}
@@ -142,9 +136,14 @@
hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const
{
+ /* Break out of loop for overlapping, broken, tables,
+ * to avoid fuzzer timouts. */
+ hb_codepoint_t last = 0;
for (const auto& range : rangeRecord)
{
- hb_codepoint_t last = range.last;
+ if (unlikely (range.first < last))
+ break;
+ last = range.last;
for (hb_codepoint_t g = range.first - 1;
glyphs.next (&g) && g <= last;)
intersect_glyphs << g;
diff --git a/src/OT/Layout/GPOS/MarkBasePos.hh b/src/OT/Layout/GPOS/MarkBasePos.hh
index c99b6b2..edf7099 100644
--- a/src/OT/Layout/GPOS/MarkBasePos.hh
+++ b/src/OT/Layout/GPOS/MarkBasePos.hh
@@ -13,7 +13,7 @@
union {
HBUINT16 format; /* Format identifier */
MarkBasePosFormat1_2<SmallTypes> format1;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
MarkBasePosFormat1_2<MediumTypes> format2;
#endif
} u;
@@ -26,7 +26,7 @@
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
#endif
default:return_trace (c->default_return_value ());
diff --git a/src/OT/Layout/GPOS/MarkLigPos.hh b/src/OT/Layout/GPOS/MarkLigPos.hh
index 8a4de9f..09152fd 100644
--- a/src/OT/Layout/GPOS/MarkLigPos.hh
+++ b/src/OT/Layout/GPOS/MarkLigPos.hh
@@ -13,7 +13,7 @@
union {
HBUINT16 format; /* Format identifier */
MarkLigPosFormat1_2<SmallTypes> format1;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
MarkLigPosFormat1_2<MediumTypes> format2;
#endif
} u;
@@ -26,7 +26,7 @@
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
#endif
default:return_trace (c->default_return_value ());
diff --git a/src/OT/Layout/GPOS/MarkMarkPos.hh b/src/OT/Layout/GPOS/MarkMarkPos.hh
index 74b5105..4118fc3 100644
--- a/src/OT/Layout/GPOS/MarkMarkPos.hh
+++ b/src/OT/Layout/GPOS/MarkMarkPos.hh
@@ -13,7 +13,7 @@
union {
HBUINT16 format; /* Format identifier */
MarkMarkPosFormat1_2<SmallTypes> format1;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
MarkMarkPosFormat1_2<MediumTypes> format2;
#endif
} u;
@@ -26,7 +26,7 @@
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
#endif
default:return_trace (c->default_return_value ());
diff --git a/src/OT/Layout/GPOS/PairPos.hh b/src/OT/Layout/GPOS/PairPos.hh
index 72bfc43..9823768 100644
--- a/src/OT/Layout/GPOS/PairPos.hh
+++ b/src/OT/Layout/GPOS/PairPos.hh
@@ -15,7 +15,7 @@
HBUINT16 format; /* Format identifier */
PairPosFormat1_3<SmallTypes> format1;
PairPosFormat2_4<SmallTypes> format2;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
PairPosFormat1_3<MediumTypes> format3;
PairPosFormat2_4<MediumTypes> format4;
#endif
@@ -30,7 +30,7 @@
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
#endif
diff --git a/src/OT/Layout/GPOS/PairPosFormat1.hh b/src/OT/Layout/GPOS/PairPosFormat1.hh
index ddf7313..9c9b268 100644
--- a/src/OT/Layout/GPOS/PairPosFormat1.hh
+++ b/src/OT/Layout/GPOS/PairPosFormat1.hh
@@ -51,8 +51,21 @@
bool intersects (const hb_set_t *glyphs) const
{
+ auto &cov = this+coverage;
+
+ if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4)
+ {
+ for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+ {
+ unsigned i = cov.get_coverage (g);
+ if ((this+pairSet[i]).intersects (glyphs, valueFormat))
+ return true;
+ }
+ return false;
+ }
+
return
- + hb_zip (this+coverage, pairSet)
+ + hb_zip (cov, pairSet)
| hb_filter (*glyphs, hb_first)
| hb_map (hb_second)
| hb_map ([glyphs, this] (const typename Types::template OffsetTo<PairSet> &_)
@@ -171,12 +184,16 @@
unsigned format1 = 0;
unsigned format2 = 0;
for (const auto & _ :
- + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second))
+ + hb_zip (this+coverage, pairSet)
+ | hb_filter (glyphset, hb_first)
+ | hb_map (hb_second)
+ )
{
const PairSet& set = (this + _);
const PairValueRecord *record = &set.firstPairValueRecord;
- for (unsigned i = 0; i < set.len; i++)
+ unsigned count = set.len;
+ for (unsigned i = 0; i < count; i++)
{
if (record->intersects (glyphset))
{
@@ -185,6 +202,9 @@
}
record = &StructAtOffset<const PairValueRecord> (record, record_size);
}
+
+ if (format1 == valueFormat[0] && format2 == valueFormat[1])
+ break;
}
return hb_pair (format1, format2);
diff --git a/src/OT/Layout/GPOS/PairPosFormat2.hh b/src/OT/Layout/GPOS/PairPosFormat2.hh
index 83b093b..9c87ac2 100644
--- a/src/OT/Layout/GPOS/PairPosFormat2.hh
+++ b/src/OT/Layout/GPOS/PairPosFormat2.hh
@@ -220,17 +220,25 @@
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
{
c->buffer->message (c->font,
- "kerning glyphs at %d,%d",
+ "try kerning glyphs at %d,%d",
c->buffer->idx, skippy_iter.idx);
}
applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
+ if (applied_first || applied_second)
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "kerned glyphs at %d,%d",
+ c->buffer->idx, skippy_iter.idx);
+ }
+
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
{
c->buffer->message (c->font,
- "kerned glyphs at %d,%d",
+ "tried kerning glyphs at %d,%d",
c->buffer->idx, skippy_iter.idx);
}
@@ -241,10 +249,15 @@
boring:
buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
+ if (len2)
+ {
+ skippy_iter.idx++;
+ // https://github.com/harfbuzz/harfbuzz/issues/3824
+ // https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116
+ buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
+ }
buffer->idx = skippy_iter.idx;
- if (len2)
- buffer->idx++;
return_trace (true);
}
@@ -309,6 +322,7 @@
{
unsigned len1 = valueFormat1.get_len ();
unsigned len2 = valueFormat2.get_len ();
+ unsigned record_size = len1 + len2;
unsigned format1 = 0;
unsigned format2 = 0;
@@ -317,10 +331,13 @@
{
for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
{
- unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
+ unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_size;
format1 = format1 | valueFormat1.get_effective_format (&values[idx]);
format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1]);
}
+
+ if (format1 == valueFormat1 && format2 == valueFormat2)
+ break;
}
return hb_pair (format1, format2);
diff --git a/src/OT/Layout/GPOS/PairSet.hh b/src/OT/Layout/GPOS/PairSet.hh
index aa48d93..a318f39 100644
--- a/src/OT/Layout/GPOS/PairSet.hh
+++ b/src/OT/Layout/GPOS/PairSet.hh
@@ -112,24 +112,38 @@
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
{
c->buffer->message (c->font,
- "kerning glyphs at %d,%d",
+ "try kerning glyphs at %d,%d",
c->buffer->idx, pos);
}
bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
+ if (applied_first || applied_second)
+ if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+ {
+ c->buffer->message (c->font,
+ "kerned glyphs at %d,%d",
+ c->buffer->idx, pos);
+ }
+
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
{
c->buffer->message (c->font,
- "kerned glyphs at %d,%d",
+ "tried kerning glyphs at %d,%d",
c->buffer->idx, pos);
}
if (applied_first || applied_second)
buffer->unsafe_to_break (buffer->idx, pos + 1);
+
if (len2)
- pos++;
+ {
+ pos++;
+ // https://github.com/harfbuzz/harfbuzz/issues/3824
+ // https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116
+ buffer->unsafe_to_break (buffer->idx, pos + 1);
+ }
buffer->idx = pos;
return_trace (true);
diff --git a/src/OT/Layout/GSUB/AlternateSet.hh b/src/OT/Layout/GSUB/AlternateSet.hh
index 4a9e967..6c50c97 100644
--- a/src/OT/Layout/GSUB/AlternateSet.hh
+++ b/src/OT/Layout/GSUB/AlternateSet.hh
@@ -84,7 +84,7 @@
{
if (alternates.len && alternate_count)
{
- + alternates.sub_array (start_offset, alternate_count)
+ + alternates.as_array ().sub_array (start_offset, alternate_count)
| hb_sink (hb_array (alternate_glyphs, *alternate_count))
;
}
diff --git a/src/OT/Layout/GSUB/AlternateSubst.hh b/src/OT/Layout/GSUB/AlternateSubst.hh
index 3740617..9d7cd6f 100644
--- a/src/OT/Layout/GSUB/AlternateSubst.hh
+++ b/src/OT/Layout/GSUB/AlternateSubst.hh
@@ -14,7 +14,7 @@
union {
HBUINT16 format; /* Format identifier */
AlternateSubstFormat1_2<SmallTypes> format1;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
AlternateSubstFormat1_2<MediumTypes> format2;
#endif
} u;
@@ -27,7 +27,7 @@
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
#endif
default:return_trace (c->default_return_value ());
diff --git a/src/OT/Layout/GSUB/Ligature.hh b/src/OT/Layout/GSUB/Ligature.hh
index 6caa80e..cdb35f5 100644
--- a/src/OT/Layout/GSUB/Ligature.hh
+++ b/src/OT/Layout/GSUB/Ligature.hh
@@ -118,7 +118,7 @@
match_positions[i] += delta;
if (i)
*p++ = ',';
- snprintf (p, sizeof(buf), "%u", match_positions[i]);
+ snprintf (p, sizeof(buf) - (p - buf), "%u", match_positions[i]);
p += strlen(p);
}
diff --git a/src/OT/Layout/GSUB/LigatureSubst.hh b/src/OT/Layout/GSUB/LigatureSubst.hh
index 6370797..7ba19e8 100644
--- a/src/OT/Layout/GSUB/LigatureSubst.hh
+++ b/src/OT/Layout/GSUB/LigatureSubst.hh
@@ -14,7 +14,7 @@
union {
HBUINT16 format; /* Format identifier */
LigatureSubstFormat1_2<SmallTypes> format1;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
LigatureSubstFormat1_2<MediumTypes> format2;
#endif
} u;
@@ -27,7 +27,7 @@
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
#endif
default:return_trace (c->default_return_value ());
diff --git a/src/OT/Layout/GSUB/MultipleSubst.hh b/src/OT/Layout/GSUB/MultipleSubst.hh
index 852ca3e..95710ed 100644
--- a/src/OT/Layout/GSUB/MultipleSubst.hh
+++ b/src/OT/Layout/GSUB/MultipleSubst.hh
@@ -14,7 +14,7 @@
union {
HBUINT16 format; /* Format identifier */
MultipleSubstFormat1_2<SmallTypes> format1;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
MultipleSubstFormat1_2<MediumTypes> format2;
#endif
} u;
@@ -28,7 +28,7 @@
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
#endif
default:return_trace (c->default_return_value ());
diff --git a/src/OT/Layout/GSUB/Sequence.hh b/src/OT/Layout/GSUB/Sequence.hh
index abf1c64..e219007 100644
--- a/src/OT/Layout/GSUB/Sequence.hh
+++ b/src/OT/Layout/GSUB/Sequence.hh
@@ -117,7 +117,7 @@
{
if (buf < p)
*p++ = ',';
- snprintf (p, sizeof(buf), "%u", i);
+ snprintf (p, sizeof(buf) - (p - buf), "%u", i);
p += strlen(p);
}
diff --git a/src/OT/Layout/GSUB/SingleSubst.hh b/src/OT/Layout/GSUB/SingleSubst.hh
index 6942e69..7da8103 100644
--- a/src/OT/Layout/GSUB/SingleSubst.hh
+++ b/src/OT/Layout/GSUB/SingleSubst.hh
@@ -16,7 +16,7 @@
HBUINT16 format; /* Format identifier */
SingleSubstFormat1_3<SmallTypes> format1;
SingleSubstFormat2_4<SmallTypes> format2;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
SingleSubstFormat1_3<MediumTypes> format3;
SingleSubstFormat2_4<MediumTypes> format4;
#endif
@@ -32,7 +32,7 @@
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
#endif
@@ -55,7 +55,7 @@
format = 1;
hb_codepoint_t mask = 0xFFFFu;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
if (+ glyphs
| hb_map_retains_sorting (hb_first)
| hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; }))
@@ -78,7 +78,7 @@
| hb_map_retains_sorting (hb_first),
delta));
case 2: return_trace (u.format2.serialize (c, glyphs));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: return_trace (u.format3.serialize (c,
+ glyphs
| hb_map_retains_sorting (hb_first),
diff --git a/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/src/OT/Layout/GSUB/SingleSubstFormat1.hh
index 13665d7..1be21b9 100644
--- a/src/OT/Layout/GSUB/SingleSubstFormat1.hh
+++ b/src/OT/Layout/GSUB/SingleSubstFormat1.hh
@@ -57,7 +57,7 @@
hb_codepoint_t max_before = intersection.get_max ();
hb_codepoint_t min_after = (min_before + d) & mask;
hb_codepoint_t max_after = (max_before + d) & mask;
- if (pop >= max_before - min_before &&
+ if (intersection.get_population () == max_before - min_before + 1 &&
((min_before <= min_after && min_after <= max_before) ||
(min_before <= max_after && max_after <= max_before)))
return;
diff --git a/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/src/OT/Layout/GSUB/SingleSubstFormat2.hh
index 5416299..01df714 100644
--- a/src/OT/Layout/GSUB/SingleSubstFormat2.hh
+++ b/src/OT/Layout/GSUB/SingleSubstFormat2.hh
@@ -36,8 +36,24 @@
void closure (hb_closure_context_t *c) const
{
- + hb_zip (this+coverage, substitute)
- | hb_filter (c->parent_active_glyphs (), hb_first)
+ auto &cov = this+coverage;
+ auto &glyph_set = c->parent_active_glyphs ();
+
+ if (substitute.len > glyph_set.get_population () * 4)
+ {
+ for (auto g : glyph_set)
+ {
+ unsigned i = cov.get_coverage (g);
+ if (i == NOT_COVERED || i >= substitute.len)
+ continue;
+ c->output->add (substitute.arrayZ[i]);
+ }
+
+ return;
+ }
+
+ + hb_zip (cov, substitute)
+ | hb_filter (glyph_set, hb_first)
| hb_map (hb_second)
| hb_sink (c->output)
;
diff --git a/src/OT/glyf/CompositeGlyph.hh b/src/OT/glyf/CompositeGlyph.hh
index fc8e309..edf8cd8 100644
--- a/src/OT/glyf/CompositeGlyph.hh
+++ b/src/OT/glyf/CompositeGlyph.hh
@@ -3,6 +3,7 @@
#include "../../hb-open-type.hh"
+#include "composite-iter.hh"
namespace OT {
@@ -121,7 +122,7 @@
if (flags & ARG_1_AND_2_ARE_WORDS)
{
// no overflow, copy and update value with deltas
- memcpy (out, this, len);
+ hb_memcpy (out, this, len);
const HBINT16 *px = reinterpret_cast<const HBINT16 *> (p);
HBINT16 *o = reinterpret_cast<HBINT16 *> (out + len_before_val);
@@ -135,7 +136,7 @@
if (new_x <= 127 && new_x >= -128 &&
new_y <= 127 && new_y >= -128)
{
- memcpy (out, this, len);
+ hb_memcpy (out, this, len);
HBINT8 *o = reinterpret_cast<HBINT8 *> (out + len_before_val);
o[0] = new_x;
o[1] = new_y;
@@ -143,7 +144,7 @@
else
{
// int8 overflows after deltas applied
- memcpy (out, this, len_before_val);
+ hb_memcpy (out, this, len_before_val);
//update flags
CompositeGlyphRecord *o = reinterpret_cast<CompositeGlyphRecord *> (out);
@@ -152,14 +153,14 @@
HBINT16 new_value;
new_value = new_x;
- memcpy (out, &new_value, HBINT16::static_size);
+ hb_memcpy (out, &new_value, HBINT16::static_size);
out += HBINT16::static_size;
new_value = new_y;
- memcpy (out, &new_value, HBINT16::static_size);
+ hb_memcpy (out, &new_value, HBINT16::static_size);
out += HBINT16::static_size;
- memcpy (out, p+2, len - len_before_val - 2);
+ hb_memcpy (out, p+2, len - len_before_val - 2);
len += 2;
}
}
@@ -252,55 +253,7 @@
DEFINE_SIZE_MIN (4);
};
-struct composite_iter_t : hb_iter_with_fallback_t<composite_iter_t, const CompositeGlyphRecord &>
-{
- typedef const CompositeGlyphRecord *__item_t__;
- composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) :
- glyph (glyph_), current (nullptr), current_size (0)
- {
- set_current (current_);
- }
-
- composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {}
-
- item_t __item__ () const { return *current; }
- bool __more__ () const { return current; }
- void __next__ ()
- {
- if (!current->has_more ()) { current = nullptr; return; }
-
- set_current (&StructAtOffset<CompositeGlyphRecord> (current, current_size));
- }
- composite_iter_t __end__ () const { return composite_iter_t (); }
- bool operator != (const composite_iter_t& o) const
- { return current != o.current; }
-
-
- void set_current (__item_t__ current_)
- {
- if (!glyph.check_range (current_, CompositeGlyphRecord::min_size))
- {
- current = nullptr;
- current_size = 0;
- return;
- }
- unsigned size = current_->get_size ();
- if (!glyph.check_range (current_, size))
- {
- current = nullptr;
- current_size = 0;
- return;
- }
-
- current = current_;
- current_size = size;
- }
-
- private:
- hb_bytes_t glyph;
- __item_t__ current;
- unsigned current_size;
-};
+using composite_iter_t = composite_iter_tmpl<CompositeGlyphRecord>;
struct CompositeGlyph
{
@@ -382,7 +335,7 @@
unsigned comp_len = component.get_size ();
if (component.is_anchored ())
{
- memcpy (p, &component, comp_len);
+ hb_memcpy (p, &component, comp_len);
p += comp_len;
}
else
@@ -398,7 +351,7 @@
if (source_len > source_comp_len)
{
unsigned instr_len = source_len - source_comp_len;
- memcpy (p, (const char *)c + source_comp_len, instr_len);
+ hb_memcpy (p, (const char *)c + source_comp_len, instr_len);
p += instr_len;
}
diff --git a/src/OT/glyf/Glyph.hh b/src/OT/glyf/Glyph.hh
index 0b25659..b7215b0 100644
--- a/src/OT/glyf/Glyph.hh
+++ b/src/OT/glyf/Glyph.hh
@@ -7,6 +7,8 @@
#include "GlyphHeader.hh"
#include "SimpleGlyph.hh"
#include "CompositeGlyph.hh"
+#include "VarCompositeGlyph.hh"
+#include "coord-setter.hh"
namespace OT {
@@ -16,6 +18,11 @@
namespace glyf_impl {
+#ifndef HB_GLYF_MAX_POINTS
+#define HB_GLYF_MAX_POINTS 10000
+#endif
+
+
enum phantom_point_index_t
{
PHANTOM_LEFT = 0,
@@ -27,7 +34,7 @@
struct Glyph
{
- enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE };
+ enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE, VAR_COMPOSITE };
public:
composite_iter_t get_composite_iterator () const
@@ -35,6 +42,11 @@
if (type != COMPOSITE) return composite_iter_t ();
return CompositeGlyph (*header, bytes).iter ();
}
+ var_composite_iter_t get_var_composite_iterator () const
+ {
+ if (type != VAR_COMPOSITE) return var_composite_iter_t ();
+ return VarCompositeGlyph (*header, bytes).iter ();
+ }
const hb_bytes_t trim_padding () const
{
@@ -108,25 +120,25 @@
if (unlikely (!glyph_header)) return false;
}
- int xMin = 0, xMax = 0;
- int yMin = 0, yMax = 0;
+ float xMin = 0, xMax = 0;
+ float yMin = 0, yMax = 0;
if (all_points.length > 4)
{
- xMin = xMax = roundf (all_points[0].x);
- yMin = yMax = roundf (all_points[0].y);
+ xMin = xMax = all_points[0].x;
+ yMin = yMax = all_points[0].y;
}
for (unsigned i = 1; i < all_points.length - 4; i++)
{
- float rounded_x = roundf (all_points[i].x);
- float rounded_y = roundf (all_points[i].y);
- xMin = hb_min (xMin, rounded_x);
- xMax = hb_max (xMax, rounded_x);
- yMin = hb_min (yMin, rounded_y);
- yMax = hb_max (yMax, rounded_y);
+ float x = all_points[i].x;
+ float y = all_points[i].y;
+ xMin = hb_min (xMin, x);
+ xMax = hb_max (xMax, x);
+ yMin = hb_min (yMin, y);
+ yMax = hb_max (yMax, y);
}
- update_mtx (plan, xMin, yMax, all_points);
+ update_mtx (plan, roundf (xMin), roundf (yMax), all_points);
/*for empty glyphs: all_points only include phantom points.
*just update metrics and then return */
@@ -134,10 +146,10 @@
return true;
glyph_header->numberOfContours = header->numberOfContours;
- glyph_header->xMin = xMin;
- glyph_header->yMin = yMin;
- glyph_header->xMax = xMax;
- glyph_header->yMax = yMax;
+ glyph_header->xMin = roundf (xMin);
+ glyph_header->yMin = roundf (yMin);
+ glyph_header->xMax = roundf (xMax);
+ glyph_header->yMax = roundf (yMax);
dest_bytes = hb_bytes_t ((const char *)glyph_header, GlyphHeader::static_size);
return true;
@@ -199,15 +211,24 @@
bool shift_points_hori = true,
bool use_my_metrics = true,
bool phantom_only = false,
+ hb_array_t<int> coords = hb_array_t<int> (),
unsigned int depth = 0) const
{
if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false;
+
+ if (!coords)
+ coords = hb_array (font->coords, font->num_coords);
+
contour_point_vector_t stack_points;
bool inplace = type == SIMPLE && all_points.length == 0;
/* Load into all_points if it's empty, as an optimization. */
contour_point_vector_t &points = inplace ? all_points : stack_points;
switch (type) {
+ case SIMPLE:
+ if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
+ return false;
+ break;
case COMPOSITE:
{
/* pseudo component points for each component in composite glyph */
@@ -215,20 +236,25 @@
if (unlikely (!points.resize (num_points))) return false;
break;
}
- case SIMPLE:
- if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
- return false;
+#ifndef HB_NO_VAR_COMPOSITES
+ case VAR_COMPOSITE:
+ {
+ for (auto &item : get_var_composite_iterator ())
+ if (unlikely (!item.get_points (points))) return false;
+ }
+#endif
+ default:
break;
}
/* Init phantom points */
if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
- hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
+ hb_array_t<contour_point_t> phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
{
int lsb = 0;
int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ?
(int) header->xMin - lsb : 0;
- int tsb = 0;
+ HB_UNUSED int tsb = 0;
int v_orig = (int) header->yMax +
#ifndef HB_NO_VERTICAL
((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb)
@@ -257,7 +283,9 @@
}
#ifndef HB_NO_VAR
- glyf_accelerator.gvar->apply_deltas_to_points (gid, font, points.as_array ());
+ glyf_accelerator.gvar->apply_deltas_to_points (gid,
+ coords,
+ points.as_array ());
#endif
// mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
@@ -283,11 +311,24 @@
for (auto &item : get_composite_iterator ())
{
comp_points.reset ();
+
if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
- .get_points (font, glyf_accelerator, comp_points,
- deltas, shift_points_hori, use_my_metrics, phantom_only, depth + 1)))
+ .get_points (font,
+ glyf_accelerator,
+ comp_points,
+ deltas,
+ shift_points_hori,
+ use_my_metrics,
+ phantom_only,
+ coords,
+ depth + 1)))
return false;
+ /* Copy phantom points from component if USE_MY_METRICS flag set */
+ if (use_my_metrics && item.is_use_my_metrics ())
+ for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
+ phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
+
/* Apply component transformation & translation */
item.transform_points (comp_points);
@@ -308,20 +349,63 @@
}
}
- /* Copy phantom points from component if USE_MY_METRICS flag set */
- if (use_my_metrics && item.is_use_my_metrics ())
- for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
- phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
+ all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT));
- all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT));
+ if (all_points.length > HB_GLYF_MAX_POINTS)
+ return false;
comp_index++;
}
all_points.extend (phantoms);
} break;
+#ifndef HB_NO_VAR_COMPOSITES
+ case VAR_COMPOSITE:
+ {
+ contour_point_vector_t comp_points;
+ hb_array_t<contour_point_t> points_left = points.as_array ();
+ for (auto &item : get_var_composite_iterator ())
+ {
+ hb_array_t<contour_point_t> record_points = points_left.sub_array (0, item.get_num_points ());
+
+ comp_points.reset ();
+
+ coord_setter_t coord_setter (coords);
+ item.set_variations (coord_setter, record_points);
+
+ if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
+ .get_points (font,
+ glyf_accelerator,
+ comp_points,
+ deltas,
+ shift_points_hori,
+ use_my_metrics,
+ phantom_only,
+ coord_setter.get_coords (),
+ depth + 1)))
+ return false;
+
+ /* Apply component transformation */
+ item.transform_points (record_points, comp_points);
+
+ /* Copy phantom points from component if USE_MY_METRICS flag set */
+ if (use_my_metrics && item.is_use_my_metrics ())
+ for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
+ phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
+
+ all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT));
+
+ if (all_points.length > HB_GLYF_MAX_POINTS)
+ return false;
+
+ points_left += item.get_num_points ();
+ }
+ all_points.extend (phantoms);
+ } break;
+#endif
default:
all_points.extend (phantoms);
+ break;
}
if (depth == 0 && shift_points_hori) /* Apply at top level */
@@ -360,6 +444,7 @@
int num_contours = header->numberOfContours;
if (unlikely (num_contours == 0)) type = EMPTY;
else if (num_contours > 0) type = SIMPLE;
+ else if (num_contours == -2) type = VAR_COMPOSITE;
else type = COMPOSITE; /* negative numbers */
}
diff --git a/src/OT/glyf/SimpleGlyph.hh b/src/OT/glyf/SimpleGlyph.hh
index d45f4eb..2b4aa99 100644
--- a/src/OT/glyf/SimpleGlyph.hh
+++ b/src/OT/glyf/SimpleGlyph.hh
@@ -132,8 +132,8 @@
if (unlikely (p + 1 > end)) return false;
unsigned int repeat_count = *p++;
unsigned stop = hb_min (i + repeat_count, count);
- for (; i < stop;)
- points_.arrayZ[i++].flag = flag;
+ for (; i < stop; i++)
+ points_.arrayZ[i].flag = flag;
}
}
return true;
@@ -223,33 +223,34 @@
if (value > 0) flag |= same_flag;
else value = -value;
- coords.push ((uint8_t)value);
+ coords.arrayZ[coords.length++] = (uint8_t) value;
}
else
{
int16_t val = value;
- coords.push (val >> 8);
- coords.push (val & 0xff);
+ coords.arrayZ[coords.length++] = val >> 8;
+ coords.arrayZ[coords.length++] = val & 0xff;
}
}
static void encode_flag (uint8_t &flag,
uint8_t &repeat,
- uint8_t &lastflag,
+ uint8_t lastflag,
hb_vector_t<uint8_t> &flags /* OUT */)
{
if (flag == lastflag && repeat != 255)
{
- repeat = repeat + 1;
+ repeat++;
if (repeat == 1)
{
- flags.push(flag);
+ /* We know there's room. */
+ flags.arrayZ[flags.length++] = flag;
}
else
{
unsigned len = flags.length;
- flags[len-2] = flag | FLAG_REPEAT;
- flags[len-1] = repeat;
+ flags.arrayZ[len-2] = flag | FLAG_REPEAT;
+ flags.arrayZ[len-1] = repeat;
}
}
else
@@ -257,7 +258,6 @@
repeat = 0;
flags.push (flag);
}
- lastflag = flag;
}
bool compile_bytes_with_deltas (const contour_point_vector_t &all_points,
@@ -269,7 +269,6 @@
dest_bytes = hb_bytes_t ();
return true;
}
- //convert absolute values to relative values
unsigned num_points = all_points.length - 4;
hb_vector_t<uint8_t> flags, x_coords, y_coords;
@@ -277,23 +276,23 @@
if (unlikely (!x_coords.alloc (2*num_points))) return false;
if (unlikely (!y_coords.alloc (2*num_points))) return false;
- uint8_t lastflag = 0, repeat = 0;
- int prev_x = 0.f, prev_y = 0.f;
-
+ uint8_t lastflag = 255, repeat = 0;
+ int prev_x = 0, prev_y = 0;
+
for (unsigned i = 0; i < num_points; i++)
{
- uint8_t flag = all_points[i].flag;
+ uint8_t flag = all_points.arrayZ[i].flag;
flag &= FLAG_ON_CURVE + FLAG_OVERLAP_SIMPLE;
- float cur_x = roundf (all_points[i].x);
- float cur_y = roundf (all_points[i].y);
+ int cur_x = roundf (all_points.arrayZ[i].x);
+ int cur_y = roundf (all_points.arrayZ[i].y);
encode_coord (cur_x - prev_x, flag, FLAG_X_SHORT, FLAG_X_SAME, x_coords);
encode_coord (cur_y - prev_y, flag, FLAG_Y_SHORT, FLAG_Y_SAME, y_coords);
- if (i == 0) lastflag = flag + 1; //make lastflag != flag for the first point
encode_flag (flag, repeat, lastflag, flags);
prev_x = cur_x;
prev_y = cur_y;
+ lastflag = flag;
}
unsigned len_before_instrs = 2 * header.numberOfContours + 2;
@@ -303,29 +302,29 @@
if (!no_hinting)
total_len += len_instrs;
- char *p = (char *) hb_calloc (total_len, sizeof (char));
+ char *p = (char *) hb_malloc (total_len);
if (unlikely (!p)) return false;
const char *src = bytes.arrayZ + GlyphHeader::static_size;
char *cur = p;
- memcpy (p, src, len_before_instrs);
+ hb_memcpy (p, src, len_before_instrs);
cur += len_before_instrs;
src += len_before_instrs;
if (!no_hinting)
{
- memcpy (cur, src, len_instrs);
+ hb_memcpy (cur, src, len_instrs);
cur += len_instrs;
}
- memcpy (cur, flags.arrayZ, flags.length);
+ hb_memcpy (cur, flags.arrayZ, flags.length);
cur += flags.length;
- memcpy (cur, x_coords.arrayZ, x_coords.length);
+ hb_memcpy (cur, x_coords.arrayZ, x_coords.length);
cur += x_coords.length;
- memcpy (cur, y_coords.arrayZ, y_coords.length);
+ hb_memcpy (cur, y_coords.arrayZ, y_coords.length);
dest_bytes = hb_bytes_t (p, total_len);
return true;
diff --git a/src/OT/glyf/SubsetGlyph.hh b/src/OT/glyf/SubsetGlyph.hh
index 88fc93c..1a0370c 100644
--- a/src/OT/glyf/SubsetGlyph.hh
+++ b/src/OT/glyf/SubsetGlyph.hh
@@ -21,10 +21,18 @@
bool serialize (hb_serialize_context_t *c,
bool use_short_loca,
- const hb_subset_plan_t *plan) const
+ const hb_subset_plan_t *plan,
+ hb_font_t *font)
{
TRACE_SERIALIZE (this);
+ if (font)
+ {
+ const OT::glyf_accelerator_t &glyf = *font->face->table.glyf;
+ if (!this->compile_bytes_with_deltas (plan, font, glyf))
+ return_trace (false);
+ }
+
hb_bytes_t dest_glyph = dest_start.copy (c);
dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
unsigned int pad_length = use_short_loca ? padding () : 0;
diff --git a/src/OT/glyf/VarCompositeGlyph.hh b/src/OT/glyf/VarCompositeGlyph.hh
new file mode 100644
index 0000000..0f4c71c
--- /dev/null
+++ b/src/OT/glyf/VarCompositeGlyph.hh
@@ -0,0 +1,353 @@
+#ifndef OT_GLYF_VARCOMPOSITEGLYPH_HH
+#define OT_GLYF_VARCOMPOSITEGLYPH_HH
+
+
+#include "../../hb-open-type.hh"
+#include "coord-setter.hh"
+
+
+namespace OT {
+namespace glyf_impl {
+
+
+struct VarCompositeGlyphRecord
+{
+ protected:
+ enum var_composite_glyph_flag_t
+ {
+ USE_MY_METRICS = 0x0001,
+ AXIS_INDICES_ARE_SHORT = 0x0002,
+ UNIFORM_SCALE = 0x0004,
+ HAVE_TRANSLATE_X = 0x0008,
+ HAVE_TRANSLATE_Y = 0x0010,
+ HAVE_ROTATION = 0x0020,
+ HAVE_SCALE_X = 0x0040,
+ HAVE_SCALE_Y = 0x0080,
+ HAVE_SKEW_X = 0x0100,
+ HAVE_SKEW_Y = 0x0200,
+ HAVE_TCENTER_X = 0x0400,
+ HAVE_TCENTER_Y = 0x0800,
+ GID_IS_24 = 0x1000,
+ AXES_HAVE_VARIATION = 0x2000,
+ };
+
+ public:
+
+ unsigned int get_size () const
+ {
+ unsigned int size = min_size;
+
+ unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 4 : 3;
+ size += numAxes * axis_width;
+
+ // gid
+ size += 2;
+ if (flags & GID_IS_24) size += 1;
+
+ if (flags & HAVE_TRANSLATE_X) size += 2;
+ if (flags & HAVE_TRANSLATE_Y) size += 2;
+ if (flags & HAVE_ROTATION) size += 2;
+ if (flags & HAVE_SCALE_X) size += 2;
+ if (flags & HAVE_SCALE_Y) size += 2;
+ if (flags & HAVE_SKEW_X) size += 2;
+ if (flags & HAVE_SKEW_Y) size += 2;
+ if (flags & HAVE_TCENTER_X) size += 2;
+ if (flags & HAVE_TCENTER_Y) size += 2;
+
+ return size;
+ }
+
+ bool has_more () const { return true; }
+
+ bool is_use_my_metrics () const { return flags & USE_MY_METRICS; }
+
+ hb_codepoint_t get_gid () const
+ {
+ if (flags & GID_IS_24)
+ return StructAfter<const HBGlyphID24> (numAxes);
+ else
+ return StructAfter<const HBGlyphID16> (numAxes);
+ }
+
+ unsigned get_numAxes () const
+ {
+ return numAxes;
+ }
+
+ unsigned get_num_points () const
+ {
+ unsigned num = 0;
+ if (flags & AXES_HAVE_VARIATION) num += numAxes;
+ if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) num++;
+ if (flags & HAVE_ROTATION) num++;
+ if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y)) num++;
+ if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y)) num++;
+ if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) num++;
+ return num;
+ }
+
+ void transform_points (hb_array_t<contour_point_t> record_points,
+ contour_point_vector_t &points) const
+ {
+ float matrix[4];
+ contour_point_t trans;
+
+ get_transformation_from_points (record_points, matrix, trans);
+
+ points.transform (matrix);
+ points.translate (trans);
+ }
+
+ static inline void transform (float (&matrix)[4], contour_point_t &trans,
+ float (other)[6])
+ {
+ // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L268
+ float xx1 = other[0];
+ float xy1 = other[1];
+ float yx1 = other[2];
+ float yy1 = other[3];
+ float dx1 = other[4];
+ float dy1 = other[5];
+ float xx2 = matrix[0];
+ float xy2 = matrix[1];
+ float yx2 = matrix[2];
+ float yy2 = matrix[3];
+ float dx2 = trans.x;
+ float dy2 = trans.y;
+
+ matrix[0] = xx1*xx2 + xy1*yx2;
+ matrix[1] = xx1*xy2 + xy1*yy2;
+ matrix[2] = yx1*xx2 + yy1*yx2;
+ matrix[3] = yx1*xy2 + yy1*yy2;
+ trans.x = xx2*dx1 + yx2*dy1 + dx2;
+ trans.y = xy2*dx1 + yy2*dy1 + dy2;
+ }
+
+ static void translate (float (&matrix)[4], contour_point_t &trans,
+ float translateX, float translateY)
+ {
+ // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L213
+ float other[6] = {1.f, 0.f, 0.f, 1.f, translateX, translateY};
+ transform (matrix, trans, other);
+ }
+
+ static void scale (float (&matrix)[4], contour_point_t &trans,
+ float scaleX, float scaleY)
+ {
+ // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L224
+ float other[6] = {scaleX, 0.f, 0.f, scaleY, 0.f, 0.f};
+ transform (matrix, trans, other);
+ }
+
+ static void rotate (float (&matrix)[4], contour_point_t &trans,
+ float rotation)
+ {
+ // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240
+ rotation = rotation * float (M_PI);
+ float c = cosf (rotation);
+ float s = sinf (rotation);
+ float other[6] = {c, s, -s, c, 0.f, 0.f};
+ transform (matrix, trans, other);
+ }
+
+ static void skew (float (&matrix)[4], contour_point_t &trans,
+ float skewX, float skewY)
+ {
+ // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255
+ skewX = skewX * float (M_PI);
+ skewY = skewY * float (M_PI);
+ float other[6] = {1.f, tanf (skewY), tanf (skewX), 1.f, 0.f, 0.f};
+ transform (matrix, trans, other);
+ }
+
+ bool get_points (contour_point_vector_t &points) const
+ {
+ float translateX = 0.f;
+ float translateY = 0.f;
+ float rotation = 0.f;
+ float scaleX = 1.f * (1 << 12);
+ float scaleY = 1.f * (1 << 12);
+ float skewX = 0.f;
+ float skewY = 0.f;
+ float tCenterX = 0.f;
+ float tCenterY = 0.f;
+
+ if (unlikely (!points.resize (points.length + get_num_points ()))) return false;
+
+ unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
+ unsigned axes_size = numAxes * axis_width;
+
+ const F2DOT14 *q = (const F2DOT14 *) (axes_size +
+ (flags & GID_IS_24 ? 3 : 2) +
+ &StructAfter<const HBUINT8> (numAxes));
+
+ hb_array_t<contour_point_t> rec_points = points.as_array ().sub_array (points.length - get_num_points ());
+
+ unsigned count = numAxes;
+ if (flags & AXES_HAVE_VARIATION)
+ {
+ for (unsigned i = 0; i < count; i++)
+ rec_points[i].x = *q++;
+ rec_points += count;
+ }
+ else
+ q += count;
+
+ const HBUINT16 *p = (const HBUINT16 *) q;
+
+ if (flags & HAVE_TRANSLATE_X) translateX = * (const FWORD *) p++;
+ if (flags & HAVE_TRANSLATE_Y) translateY = * (const FWORD *) p++;
+ if (flags & HAVE_ROTATION) rotation = * (const F2DOT14 *) p++;
+ if (flags & HAVE_SCALE_X) scaleX = * (const F4DOT12 *) p++;
+ if (flags & HAVE_SCALE_Y) scaleY = * (const F4DOT12 *) p++;
+ if (flags & HAVE_SKEW_X) skewX = * (const F2DOT14 *) p++;
+ if (flags & HAVE_SKEW_Y) skewY = * (const F2DOT14 *) p++;
+ if (flags & HAVE_TCENTER_X) tCenterX = * (const FWORD *) p++;
+ if (flags & HAVE_TCENTER_Y) tCenterY = * (const FWORD *) p++;
+
+ if ((flags & UNIFORM_SCALE) && !(flags & HAVE_SCALE_Y))
+ scaleY = scaleX;
+
+ if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
+ {
+ rec_points[0].x = translateX;
+ rec_points[0].y = translateY;
+ rec_points++;
+ }
+ if (flags & HAVE_ROTATION)
+ {
+ rec_points[0].x = rotation;
+ rec_points++;
+ }
+ if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
+ {
+ rec_points[0].x = scaleX;
+ rec_points[0].y = scaleY;
+ rec_points++;
+ }
+ if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
+ {
+ rec_points[0].x = skewX;
+ rec_points[0].y = skewY;
+ rec_points++;
+ }
+ if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
+ {
+ rec_points[0].x = tCenterX;
+ rec_points[0].y = tCenterY;
+ rec_points++;
+ }
+ assert (!rec_points);
+
+ return true;
+ }
+
+ void get_transformation_from_points (hb_array_t<contour_point_t> rec_points,
+ float (&matrix)[4], contour_point_t &trans) const
+ {
+ if (flags & AXES_HAVE_VARIATION)
+ rec_points += numAxes;
+
+ matrix[0] = matrix[3] = 1.f;
+ matrix[1] = matrix[2] = 0.f;
+ trans.init (0.f, 0.f);
+
+ float translateX = 0.f;
+ float translateY = 0.f;
+ float rotation = 0.f;
+ float scaleX = 1.f;
+ float scaleY = 1.f;
+ float skewX = 0.f;
+ float skewY = 0.f;
+ float tCenterX = 0.f;
+ float tCenterY = 0.f;
+
+ if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
+ {
+ translateX = rec_points[0].x;
+ translateY = rec_points[0].y;
+ rec_points++;
+ }
+ if (flags & HAVE_ROTATION)
+ {
+ rotation = rec_points[0].x / (1 << 14);
+ rec_points++;
+ }
+ if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
+ {
+ scaleX = rec_points[0].x / (1 << 12);
+ scaleY = rec_points[0].y / (1 << 12);
+ rec_points++;
+ }
+ if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
+ {
+ skewX = rec_points[0].x / (1 << 14);
+ skewY = rec_points[0].y / (1 << 14);
+ rec_points++;
+ }
+ if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
+ {
+ tCenterX = rec_points[0].x;
+ tCenterY = rec_points[0].y;
+ rec_points++;
+ }
+ assert (!rec_points);
+
+ translate (matrix, trans, translateX + tCenterX, translateY + tCenterY);
+ rotate (matrix, trans, rotation);
+ scale (matrix, trans, scaleX, scaleY);
+ skew (matrix, trans, -skewX, skewY);
+ translate (matrix, trans, -tCenterX, -tCenterY);
+ }
+
+ void set_variations (coord_setter_t &setter,
+ hb_array_t<contour_point_t> rec_points) const
+ {
+ bool have_variations = flags & AXES_HAVE_VARIATION;
+ unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
+
+ const HBUINT8 *p = (const HBUINT8 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2));
+ const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2));
+
+ const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + numAxes) : (HBUINT8 *) (q + numAxes)));
+
+ unsigned count = numAxes;
+ for (unsigned i = 0; i < count; i++)
+ {
+ unsigned axis_index = axis_width == 1 ? (unsigned) *p++ : (unsigned) *q++;
+
+ signed v = have_variations ? rec_points[i].x : *a++;
+
+ v += setter[axis_index];
+ v = hb_clamp (v, -(1<<14), (1<<14));
+ setter[axis_index] = v;
+ }
+ }
+
+ protected:
+ HBUINT16 flags;
+ HBUINT8 numAxes;
+ public:
+ DEFINE_SIZE_MIN (3);
+};
+
+using var_composite_iter_t = composite_iter_tmpl<VarCompositeGlyphRecord>;
+
+struct VarCompositeGlyph
+{
+ const GlyphHeader &header;
+ hb_bytes_t bytes;
+ VarCompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
+ header (header_), bytes (bytes_) {}
+
+ var_composite_iter_t iter () const
+ { return var_composite_iter_t (bytes, &StructAfter<VarCompositeGlyphRecord, GlyphHeader> (header)); }
+
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+
+#endif /* OT_GLYF_VARCOMPOSITEGLYPH_HH */
diff --git a/src/OT/glyf/composite-iter.hh b/src/OT/glyf/composite-iter.hh
new file mode 100644
index 0000000..d05701f
--- /dev/null
+++ b/src/OT/glyf/composite-iter.hh
@@ -0,0 +1,68 @@
+#ifndef OT_GLYF_COMPOSITE_ITER_HH
+#define OT_GLYF_COMPOSITE_ITER_HH
+
+
+#include "../../hb.hh"
+
+
+namespace OT {
+namespace glyf_impl {
+
+
+template <typename CompositeGlyphRecord>
+struct composite_iter_tmpl : hb_iter_with_fallback_t<composite_iter_tmpl<CompositeGlyphRecord>,
+ const CompositeGlyphRecord &>
+{
+ typedef const CompositeGlyphRecord *__item_t__;
+ composite_iter_tmpl (hb_bytes_t glyph_, __item_t__ current_) :
+ glyph (glyph_), current (nullptr), current_size (0)
+ {
+ set_current (current_);
+ }
+
+ composite_iter_tmpl () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {}
+
+ const CompositeGlyphRecord & __item__ () const { return *current; }
+ bool __more__ () const { return current; }
+ void __next__ ()
+ {
+ if (!current->has_more ()) { current = nullptr; return; }
+
+ set_current (&StructAtOffset<CompositeGlyphRecord> (current, current_size));
+ }
+ composite_iter_tmpl __end__ () const { return composite_iter_tmpl (); }
+ bool operator != (const composite_iter_tmpl& o) const
+ { return current != o.current; }
+
+
+ void set_current (__item_t__ current_)
+ {
+ if (!glyph.check_range (current_, CompositeGlyphRecord::min_size))
+ {
+ current = nullptr;
+ current_size = 0;
+ return;
+ }
+ unsigned size = current_->get_size ();
+ if (!glyph.check_range (current_, size))
+ {
+ current = nullptr;
+ current_size = 0;
+ return;
+ }
+
+ current = current_;
+ current_size = size;
+ }
+
+ private:
+ hb_bytes_t glyph;
+ __item_t__ current;
+ unsigned current_size;
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+#endif /* OT_GLYF_COMPOSITE_ITER_HH */
diff --git a/src/OT/glyf/coord-setter.hh b/src/OT/glyf/coord-setter.hh
new file mode 100644
index 0000000..df64ed5
--- /dev/null
+++ b/src/OT/glyf/coord-setter.hh
@@ -0,0 +1,34 @@
+#ifndef OT_GLYF_COORD_SETTER_HH
+#define OT_GLYF_COORD_SETTER_HH
+
+
+#include "../../hb.hh"
+
+
+namespace OT {
+namespace glyf_impl {
+
+
+struct coord_setter_t
+{
+ coord_setter_t (hb_array_t<int> coords) :
+ coords (coords) {}
+
+ int& operator [] (unsigned idx)
+ {
+ if (coords.length < idx + 1)
+ coords.resize (idx + 1);
+ return coords[idx];
+ }
+
+ hb_array_t<int> get_coords ()
+ { return coords.as_array (); }
+
+ hb_vector_t<int> coords;
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+#endif /* OT_GLYF_COORD_SETTER_HH */
diff --git a/src/OT/glyf/glyf.hh b/src/OT/glyf/glyf.hh
index 5fb32f6..e6e985c 100644
--- a/src/OT/glyf/glyf.hh
+++ b/src/OT/glyf/glyf.hh
@@ -42,11 +42,15 @@
bool serialize (hb_serialize_context_t *c,
Iterator it,
bool use_short_loca,
- const hb_subset_plan_t *plan)
+ const hb_subset_plan_t *plan,
+ hb_font_t *font)
{
TRACE_SERIALIZE (this);
+
unsigned init_len = c->length ();
- for (const auto &_ : it) _.serialize (c, use_short_loca, plan);
+ for (auto &_ : it)
+ if (unlikely (!_.serialize (c, use_short_loca, plan, font)))
+ return false;
/* As a special case when all glyph in the font are empty, add a zero byte
* to the table, so that OTS doesn’t reject it, and to make the table work
@@ -74,10 +78,11 @@
hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
_populate_subset_glyphs (c->plan, glyphs);
+ hb_font_t *font = nullptr;
if (!c->plan->pinned_at_default)
{
- if (!_compile_subset_glyphs_with_deltas (c->plan, &glyphs))
- return_trace (false);
+ font = _create_font_for_instancing (c->plan);
+ if (unlikely (!font)) return false;
}
auto padded_offsets =
@@ -85,11 +90,14 @@
| hb_map (&glyf_impl::SubsetGlyph::padded_size)
;
- unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0);
- bool use_short_loca = max_offset < 0x1FFFF;
+ bool use_short_loca = false;
+ if (likely (!c->plan->force_long_loca))
+ {
+ unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0);
+ use_short_loca = max_offset < 0x1FFFF;
+ }
-
- glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan);
+ glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan, font);
if (!use_short_loca) {
padded_offsets =
+ hb_iter (glyphs)
@@ -97,9 +105,12 @@
;
}
-
- if (!c->plan->pinned_at_default)
+ if (font)
+ {
_free_compiled_subset_glyphs (&glyphs);
+ hb_font_destroy (font);
+ }
+
if (unlikely (c->serializer->in_error ())) return_trace (false);
return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan,
padded_offsets,
@@ -110,9 +121,8 @@
_populate_subset_glyphs (const hb_subset_plan_t *plan,
hb_vector_t<glyf_impl::SubsetGlyph> &glyphs /* OUT */) const;
- bool
- _compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
- hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const;
+ hb_font_t *
+ _create_font_for_instancing (const hb_subset_plan_t *plan) const;
void _free_compiled_subset_glyphs (hb_vector_t<glyf_impl::SubsetGlyph> *glyphs) const
{
@@ -394,7 +404,11 @@
plan->pinned_at_default)
subset_glyph.source_glyph = glyf_impl::Glyph ();
else
- subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
+ {
+ /* If plan has an accelerator, the preprocessing step already trimmed glyphs.
+ * Don't trim them again! */
+ subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, !plan->accelerator);
+ }
if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
subset_glyph.drop_hints_bytes ();
@@ -403,17 +417,15 @@
}
}
-inline bool
-glyf::_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
- hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const
+inline hb_font_t *
+glyf::_create_font_for_instancing (const hb_subset_plan_t *plan) const
{
- OT::glyf_accelerator_t glyf (plan->source);
hb_font_t *font = hb_font_create (plan->source);
- if (unlikely (!font)) return false;
+ if (unlikely (font == hb_font_get_empty ())) return nullptr;
hb_vector_t<hb_variation_t> vars;
if (unlikely (!vars.alloc (plan->user_axes_location->get_population ())))
- return false;
+ return nullptr;
for (auto _ : *plan->user_axes_location)
{
@@ -423,18 +435,10 @@
vars.push (var);
}
+#ifndef HB_NO_VAR
hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ());
- for (auto& subset_glyph : *glyphs)
- {
- if (!const_cast<glyf_impl::SubsetGlyph &> (subset_glyph).compile_bytes_with_deltas (plan, font, glyf))
- {
- hb_font_destroy (font);
- return false;
- }
- }
-
- hb_font_destroy (font);
- return true;
+#endif
+ return font;
}
diff --git a/src/check-symbols.py b/src/check-symbols.py
index 11ca28d..d0b8bd3 100755
--- a/src/check-symbols.py
+++ b/src/check-symbols.py
@@ -31,7 +31,7 @@
symprefix = '_' if suffix == 'dylib' else ''
EXPORTED_SYMBOLS = [s.split ()[2]
- for s in re.findall (r'^.+ [BCDGIRST] .+$', subprocess.check_output (nm.split() + [so]).decode ('utf-8'), re.MULTILINE)
+ for s in re.findall (r'^.+ [BCDGIRSTu] .+$', subprocess.check_output (nm.split() + [so]).decode ('utf-8'), re.MULTILINE)
if not re.match (r'.* %s(%s)\b' % (symprefix, IGNORED_SYMBOLS), s)]
# run again c++filt also if is available
diff --git a/src/gen-def.py b/src/gen-def.py
index e751f52..9b4efd4 100755
--- a/src/gen-def.py
+++ b/src/gen-def.py
@@ -20,9 +20,7 @@
# Move these to harfbuzz-sections.txt when got stable
experimental_symbols = \
"""hb_subset_repack_or_fail
-hb_subset_input_pin_axis_location
-hb_subset_input_pin_axis_to_default
-hb_subset_preprocess
+hb_subset_input_override_name_table
""".splitlines ()
symbols = [x for x in symbols if x not in experimental_symbols]
symbols = "\n".join (symbols)
diff --git a/src/gen-indic-table.py b/src/gen-indic-table.py
index 0ff3ef4..4ef9702 100755
--- a/src/gen-indic-table.py
+++ b/src/gen-indic-table.py
@@ -95,6 +95,7 @@
'PLACEHOLDER',
'DOTTEDCIRCLE',
'RS',
+ 'MPst',
'Repha',
'Ra',
'CM',
@@ -168,8 +169,6 @@
'Vowel' : 'V',
'Vowel_Dependent' : 'M',
'Vowel_Independent' : 'V',
- 'Dotted_Circle' : 'DOTTEDCIRCLE', # Ours, not Unicode's
- 'Ra' : 'Ra', # Ours, not Unicode's
}
position_map = {
'Not_Applicable' : 'END',
@@ -240,6 +239,9 @@
0x0953: 'SM',
0x0954: 'SM',
+ # U+0A40 GURMUKHI VOWEL SIGN II may be preceded by U+0A02 GURMUKHI SIGN BINDI.
+ 0x0A40: 'MPst',
+
# The following act like consonants.
0x0A72: 'C',
0x0A73: 'C',
@@ -440,7 +442,7 @@
indic_data[k] = (new_cat, pos, unicode_data[2][k])
# We only expect position for certain types
-positioned_categories = ('CM', 'SM', 'RS', 'H', 'M')
+positioned_categories = ('CM', 'SM', 'RS', 'H', 'M', 'MPst')
for k, (cat, pos, block) in indic_data.items():
if cat not in positioned_categories:
pos = 'END'
@@ -450,11 +452,12 @@
# Keep in sync with CONSONANT_FLAGS in the shaper
consonant_categories = ('C', 'CS', 'Ra','CM', 'V', 'PLACEHOLDER', 'DOTTEDCIRCLE')
+matra_categories = ('M', 'MPst')
smvd_categories = ('SM', 'VD', 'A', 'Symbol')
for k, (cat, pos, block) in indic_data.items():
if cat in consonant_categories:
pos = 'BASE_C'
- elif cat == 'M':
+ elif cat in matra_categories:
if block.startswith('Khmer') or block.startswith('Myanmar'):
cat = position_to_category(pos)
else:
@@ -634,7 +637,7 @@
end = (end-1)//8*8 + 7
if start != last + 1:
- if start - last <= 1+16*3:
+ if start - last <= 1+16*2:
print_block (None, last+1, start-1, indic_data)
else:
if last >= 0:
@@ -691,6 +694,6 @@
print ()
print ("/* == End of generated table == */")
-# Maintain at least 30% occupancy in the table */
-if occupancy < 30:
+# Maintain at least 50% occupancy in the table */
+if occupancy < 50:
raise Exception ("Table too sparse, please investigate: ", occupancy)
diff --git a/src/gen-ucd-table.py b/src/gen-ucd-table.py
index f4c099f..d85ae4f 100755
--- a/src/gen-ucd-table.py
+++ b/src/gen-ucd-table.py
@@ -25,14 +25,28 @@
logging.info('Preparing data tables...')
+
+# This is how the data is encoded:
+#
+# General_Category (gc), Canonical_Combining_Class (ccc),
+# and Script (sc) are encoded as integers.
+#
+# Mirroring character (bmg) is encoded as difference from
+# the original character.
+#
+# Composition & Decomposition (dm) are encoded elaborately,
+# as discussed below.
+
gc = [u['gc'] for u in ucd]
ccc = [int(u['ccc']) for u in ucd]
bmg = [int(v, 16) - int(u) if v else 0 for u,v in enumerate(u['bmg'] for u in ucd)]
-#gc_ccc_non0 = set((cat,klass) for cat,klass in zip(gc,ccc) if klass)
-#gc_bmg_non0 = set((cat,mirr) for cat,mirr in zip(gc, bmg) if mirr)
-
sc = [u['sc'] for u in ucd]
+
+# Prepare Compose / Decompose data
+#
+# This code is very dense. See hb_ucd_compose() / hb_ucd_decompose() for the logic.
+
dm = {i:tuple(int(v, 16) for v in u['dm'].split()) for i,u in enumerate(ucd)
if u['dm'] != '#' and u['dt'] == 'can' and not (0xAC00 <= i < 0xAC00+11172)}
ce = {i for i,u in enumerate(ucd) if u['Comp_Ex'] == 'Y'}
@@ -63,6 +77,9 @@
dm_order.update(dm1_order)
dm_order.update(dm2_order)
+
+# Prepare General_Category / Script mapping arrays
+
gc_order = dict()
for i,v in enumerate(('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu',
'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf',
@@ -83,10 +100,18 @@
sc_order[i] = tag
sc_array.append(name)
-DEFAULT = 3
-COMPACT = 5
-SLOPPY = 9
+# Write out main data
+
+DEFAULT = 'DEFAULT'
+COMPACT = 'COMPACT'
+SLOPPY = 'SLOPPY'
+
+compression_level = {
+ DEFAULT: 5,
+ COMPACT: 9,
+ SLOPPY: 9,
+}
logging.info('Generating output...')
print("/* == Start of generated table == */")
@@ -104,6 +129,9 @@
print('#include "hb.hh"')
print()
+
+# Write mapping data
+
code = packTab.Code('_hb_ucd')
sc_array, _ = code.addArray('hb_script_t', 'sc_map', sc_array)
dm1_p0_array, _ = code.addArray('uint16_t', 'dm1_p0_map', dm1_p0_array)
@@ -120,18 +148,24 @@
('dm', dm, None, dm_order),
]
-for compression in (DEFAULT, COMPACT, SLOPPY):
+
+# Write main data
+
+for step in (DEFAULT, COMPACT, SLOPPY):
+ compression = compression_level[step]
logging.info(' Compression=%d:' % compression)
print()
- if compression == DEFAULT:
+ if step == DEFAULT:
print('#ifndef HB_OPTIMIZE_SIZE')
- elif compression == COMPACT:
+ elif step == COMPACT:
print('#elif !defined(HB_NO_UCD_UNASSIGNED)')
- else:
+ elif step == SLOPPY:
print('#else')
+ else:
+ assert False
print()
- if compression == SLOPPY:
+ if step == SLOPPY:
for i in range(len(gc)):
if (i % 128) and gc[i] == 'Cn':
gc[i] = gc[i - 1]
@@ -157,6 +191,7 @@
print()
+
print('#endif')
print()
diff --git a/src/gen-use-table.py b/src/gen-use-table.py
index 0600a33..e8b76df 100755
--- a/src/gen-use-table.py
+++ b/src/gen-use-table.py
@@ -1,6 +1,9 @@
#!/usr/bin/env python3
# flake8: noqa: F821
+import logging
+logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
+
"""usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt
Input files:
@@ -465,10 +468,29 @@
import packTab
data = {u:v[0] for u,v in use_data.items()}
-code = packTab.Code('hb_use')
-sol = packTab.pack_table(data, compression=5, default='O')
-sol.genCode(code, f'get_category')
-code.print_c(linkage='static inline')
+
+DEFAULT = 5
+COMPACT = 9
+for compression in (DEFAULT, COMPACT):
+
+ logging.info(' Compression=%d:' % compression)
+ print()
+ if compression == DEFAULT:
+ print('#ifndef HB_OPTIMIZE_SIZE')
+ elif compression == COMPACT:
+ print('#else')
+ else:
+ assert False
+ print()
+
+ code = packTab.Code('hb_use')
+ sol = packTab.pack_table(data, compression=compression, default='O')
+ logging.info(' FullCost=%d' % (sol.fullCost))
+ sol.genCode(code, f'get_category')
+ code.print_c(linkage='static inline')
+ print ()
+
+print('#endif')
print ()
for k in sorted(use_mapping.keys()):
diff --git a/src/graph/classdef-graph.hh b/src/graph/classdef-graph.hh
index 0bda76a..c2e24a7 100644
--- a/src/graph/classdef-graph.hh
+++ b/src/graph/classdef-graph.hh
@@ -112,7 +112,7 @@
{
case 1: return ((ClassDefFormat1*)this)->sanitize (vertex);
case 2: return ((ClassDefFormat2*)this)->sanitize (vertex);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
// Not currently supported
case 3:
case 4:
diff --git a/src/graph/coverage-graph.hh b/src/graph/coverage-graph.hh
index 3c1022f..49d0936 100644
--- a/src/graph/coverage-graph.hh
+++ b/src/graph/coverage-graph.hh
@@ -136,7 +136,7 @@
{
case 1: return ((CoverageFormat1*)this)->sanitize (vertex);
case 2: return ((CoverageFormat2*)this)->sanitize (vertex);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
// Not currently supported
case 3:
case 4:
diff --git a/src/graph/graph.hh b/src/graph/graph.hh
index 79c7e69..dc5b6a3 100644
--- a/src/graph/graph.hh
+++ b/src/graph/graph.hh
@@ -49,6 +49,50 @@
unsigned end = 0;
unsigned priority = 0;
+
+ bool link_positions_valid (unsigned num_objects, bool removed_nil)
+ {
+ hb_set_t assigned_bytes;
+ for (const auto& l : obj.real_links)
+ {
+ if (l.objidx >= num_objects
+ || (removed_nil && !l.objidx))
+ {
+ DEBUG_MSG (SUBSET_REPACK, nullptr,
+ "Invalid graph. Invalid object index.");
+ return false;
+ }
+
+ unsigned start = l.position;
+ unsigned end = start + l.width - 1;
+
+ if (unlikely (l.width < 2 || l.width > 4))
+ {
+ DEBUG_MSG (SUBSET_REPACK, nullptr,
+ "Invalid graph. Invalid link width.");
+ return false;
+ }
+
+ if (unlikely (end >= table_size ()))
+ {
+ DEBUG_MSG (SUBSET_REPACK, nullptr,
+ "Invalid graph. Link position is out of bounds.");
+ return false;
+ }
+
+ if (unlikely (assigned_bytes.intersects (start, end)))
+ {
+ DEBUG_MSG (SUBSET_REPACK, nullptr,
+ "Invalid graph. Found offsets whose positions overlap.");
+ return false;
+ }
+
+ assigned_bytes.add_range (start, end);
+ }
+
+ return !assigned_bytes.in_error ();
+ }
+
void normalize ()
{
obj.real_links.qsort ();
@@ -132,7 +176,7 @@
for (unsigned i = 0; i < parents.length; i++)
{
if (parents[i] != parent_index) continue;
- parents.remove (i);
+ parents.remove_unordered (i);
break;
}
}
@@ -148,7 +192,7 @@
if ((obj.head + link.position) != offset)
continue;
- obj.real_links.remove (i);
+ obj.real_links.remove_unordered (i);
return;
}
}
@@ -286,8 +330,6 @@
vertices_scratch_.alloc (objects.length);
for (unsigned i = 0; i < objects.length; i++)
{
- // TODO(grieger): check all links point to valid objects.
-
// If this graph came from a serialization buffer object 0 is the
// nil object. We don't need it for our purposes here so drop it.
if (i == 0 && !objects[i])
@@ -299,6 +341,9 @@
vertex_t* v = vertices_.push ();
if (check_success (!vertices_.in_error ()))
v->obj = *objects[i];
+
+ check_success (v->link_positions_valid (objects.length, removed_nil));
+
if (!removed_nil) continue;
// Fix indices to account for removed nil object.
for (auto& l : v->obj.all_links_writer ()) {
@@ -418,6 +463,13 @@
hb_swap (sorted_graph[new_id], vertices_[next_id]);
const vertex_t& next = sorted_graph[new_id];
+ if (unlikely (!check_success(new_id >= 0))) {
+ // We are out of ids. Which means we've visited a node more than once.
+ // This graph contains a cycle which is not allowed.
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Invalid graph. Contains cycle.");
+ return;
+ }
+
id_map[next_id] = new_id--;
for (const auto& link : next.obj.all_links ()) {
@@ -580,7 +632,7 @@
while (roots)
{
- unsigned next = HB_SET_VALUE_INVALID;
+ uint32_t next = HB_SET_VALUE_INVALID;
if (unlikely (!check_success (!roots.in_error ()))) break;
if (!roots.next (&next)) break;
@@ -661,8 +713,8 @@
auto new_subgraph =
+ subgraph.keys ()
- | hb_map([&] (unsigned node_idx) {
- const unsigned *v;
+ | hb_map([&] (uint32_t node_idx) {
+ const uint32_t *v;
if (index_map.has (node_idx, &v)) return *v;
return node_idx;
})
@@ -672,10 +724,10 @@
remap_obj_indices (index_map, parents.iter (), true);
// Update roots set with new indices as needed.
- unsigned next = HB_SET_VALUE_INVALID;
+ uint32_t next = HB_SET_VALUE_INVALID;
while (roots.next (&next))
{
- const unsigned *v;
+ const uint32_t *v;
if (index_map.has (next, &v))
{
roots.del (next);
@@ -690,7 +742,7 @@
{
for (const auto& link : vertices_[node_idx].obj.all_links ())
{
- const unsigned *v;
+ const uint32_t *v;
if (subgraph.has (link.objidx, &v))
{
subgraph.set (link.objidx, *v + 1);
@@ -941,6 +993,72 @@
return made_change;
}
+ bool is_fully_connected ()
+ {
+ update_parents();
+
+ if (root().parents)
+ // Root cannot have parents.
+ return false;
+
+ for (unsigned i = 0; i < root_idx (); i++)
+ {
+ if (!vertices_[i].parents)
+ return false;
+ }
+ return true;
+ }
+
+#if 0
+ /*
+ * Saves the current graph to a packed binary format which the repacker fuzzer takes
+ * as a seed.
+ */
+ void save_fuzzer_seed (hb_tag_t tag) const
+ {
+ FILE* f = fopen ("./repacker_fuzzer_seed", "w");
+ fwrite ((void*) &tag, sizeof (tag), 1, f);
+
+ uint16_t num_objects = vertices_.length;
+ fwrite ((void*) &num_objects, sizeof (num_objects), 1, f);
+
+ for (const auto& v : vertices_)
+ {
+ uint16_t blob_size = v.table_size ();
+ fwrite ((void*) &blob_size, sizeof (blob_size), 1, f);
+ fwrite ((const void*) v.obj.head, blob_size, 1, f);
+ }
+
+ uint16_t link_count = 0;
+ for (const auto& v : vertices_)
+ link_count += v.obj.real_links.length;
+
+ fwrite ((void*) &link_count, sizeof (link_count), 1, f);
+
+ typedef struct
+ {
+ uint16_t parent;
+ uint16_t child;
+ uint16_t position;
+ uint8_t width;
+ } link_t;
+
+ for (unsigned i = 0; i < vertices_.length; i++)
+ {
+ for (const auto& l : vertices_[i].obj.real_links)
+ {
+ link_t link {
+ (uint16_t) i, (uint16_t) l.objidx,
+ (uint16_t) l.position, (uint8_t) l.width
+ };
+ fwrite ((void*) &link, sizeof (link), 1, f);
+ }
+ }
+
+ fclose (f);
+ }
+#endif
+
void print_orphaned_nodes ()
{
if (!DEBUG_ENABLED(SUBSET_REPACK)) return;
@@ -949,6 +1067,10 @@
parents_invalid = true;
update_parents();
+ if (root().parents) {
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Root node has incoming edges.");
+ }
+
for (unsigned i = 0; i < root_idx (); i++)
{
const auto& v = vertices_[i];
@@ -1065,6 +1187,11 @@
}
}
+ for (unsigned i = 0; i < vertices_.length; i++)
+ // parents arrays must be accurate or downstream operations like cycle detection
+ // and sorting won't work correctly.
+ check_success (!vertices_[i].parents.in_error ());
+
parents_invalid = false;
}
@@ -1183,7 +1310,7 @@
{
for (auto& link : vertices_[i].obj.all_links_writer ())
{
- const unsigned *v;
+ const uint32_t *v;
if (!id_map.has (link.objidx, &v)) continue;
if (only_wide && !(link.width == 4 && !link.is_signed)) continue;
diff --git a/src/graph/gsubgpos-graph.hh b/src/graph/gsubgpos-graph.hh
index e8d5bef..c170638 100644
--- a/src/graph/gsubgpos-graph.hh
+++ b/src/graph/gsubgpos-graph.hh
@@ -201,7 +201,7 @@
+ new_subtable_count * OT::Offset16::static_size;
char* buffer = (char*) hb_calloc (1, new_size);
c.add_buffer (buffer);
- memcpy (buffer, v.obj.head, v.table_size());
+ hb_memcpy (buffer, v.obj.head, v.table_size());
v.obj.head = buffer;
v.obj.tail = buffer + new_size;
@@ -355,7 +355,7 @@
{
switch (u.version.major) {
case 1: return u.version1.get_lookup_list_offset ();
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 2: return u.version2.get_lookup_list_offset ();
#endif
default: return 0;
@@ -374,7 +374,7 @@
{
switch (u.version.major) {
case 1: find_lookups<SmallTypes> (graph, lookups); break;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 2: find_lookups<MediumTypes> (graph, lookups); break;
#endif
}
diff --git a/src/graph/markbasepos-graph.hh b/src/graph/markbasepos-graph.hh
index e42a604..84ef5f7 100644
--- a/src/graph/markbasepos-graph.hh
+++ b/src/graph/markbasepos-graph.hh
@@ -112,7 +112,7 @@
auto& child = c.graph.vertices_[child_idx];
child.remove_parent (this_index);
- o.real_links.remove (i);
+ o.real_links.remove_unordered (i);
num_links--;
i--;
}
@@ -372,7 +372,7 @@
if (!mark_coverage) return false;
hb_set_t marks = sc.marks_for (0, count);
auto new_coverage =
- + hb_zip (hb_range (), mark_coverage.table->iter ())
+ + hb_enumerate (mark_coverage.table->iter ())
| hb_filter (marks, hb_first)
| hb_map_retains_sorting (hb_second)
;
@@ -431,7 +431,7 @@
if (!mark_coverage) return false;
hb_set_t marks = sc.marks_for (start, end);
auto new_coverage =
- + hb_zip (hb_range (), mark_coverage.table->iter ())
+ + hb_enumerate (mark_coverage.table->iter ())
| hb_filter (marks, hb_first)
| hb_map_retains_sorting (hb_second)
;
@@ -477,7 +477,7 @@
switch (u.format) {
case 1:
return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 2: HB_FALLTHROUGH;
// Don't split 24bit PairPos's.
#endif
@@ -494,7 +494,7 @@
switch (u.format) {
case 1:
return ((MarkBasePosFormat1*)(&u.format1))->sanitize (vertex);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 2: HB_FALLTHROUGH;
#endif
default:
diff --git a/src/graph/pairpos-graph.hh b/src/graph/pairpos-graph.hh
index 8040778..1c13eb2 100644
--- a/src/graph/pairpos-graph.hh
+++ b/src/graph/pairpos-graph.hh
@@ -434,7 +434,7 @@
char* start_addr = ((char*)&values[0]) + start * split_context.class1_record_size;
unsigned num_records = end - start;
- memcpy (&pair_pos_prime->values[0],
+ hb_memcpy (&pair_pos_prime->values[0],
start_addr,
num_records * split_context.class1_record_size);
@@ -611,7 +611,7 @@
return ((PairPosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
case 2:
return ((PairPosFormat2*)(&u.format2))->split_subtables (c, parent_index, this_index);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: HB_FALLTHROUGH;
case 4: HB_FALLTHROUGH;
// Don't split 24bit PairPos's.
@@ -631,7 +631,7 @@
return ((PairPosFormat1*)(&u.format1))->sanitize (vertex);
case 2:
return ((PairPosFormat2*)(&u.format2))->sanitize (vertex);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
case 3: HB_FALLTHROUGH;
case 4: HB_FALLTHROUGH;
#endif
diff --git a/src/graph/serialize.hh b/src/graph/serialize.hh
index ecc6cc5..d03a61b 100644
--- a/src/graph/serialize.hh
+++ b/src/graph/serialize.hh
@@ -33,6 +33,23 @@
{
unsigned parent;
unsigned child;
+
+ bool operator != (const overflow_record_t o) const
+ { return !(*this == o); }
+
+ inline bool operator == (const overflow_record_t& o) const
+ {
+ return parent == o.parent &&
+ child == o.child;
+ }
+
+ inline uint32_t hash () const
+ {
+ uint32_t current = 0;
+ current = current * 31 + hb_hash (parent);
+ current = current * 31 + hb_hash (child);
+ return current;
+ }
};
inline
@@ -94,6 +111,7 @@
if (overflows) overflows->resize (0);
graph.update_positions ();
+ hb_hashmap_t<overflow_record_t*, bool> record_set;
const auto& vertices = graph.vertices_;
for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--)
{
@@ -109,7 +127,10 @@
overflow_record_t r;
r.parent = parent_idx;
r.child = link.objidx;
+ if (record_set.has(&r)) continue; // don't keep duplicate overflows.
+
overflows->push (r);
+ record_set.set(&r, true);
}
}
@@ -223,7 +244,7 @@
return nullptr;
}
- memcpy (start, vertices[i].obj.head, size);
+ hb_memcpy (start, vertices[i].obj.head, size);
// Only real links needs to be serialized.
for (const auto& link : vertices[i].obj.real_links)
diff --git a/src/harfbuzz-config.cmake.in b/src/harfbuzz-config.cmake.in
index 304410d..0de082c 100644
--- a/src/harfbuzz-config.cmake.in
+++ b/src/harfbuzz-config.cmake.in
@@ -1,29 +1,5 @@
-# Set these variables so that the `${prefix}/lib` expands to something we can
-# remove.
-set(_harfbuzz_remove_string "REMOVE_ME")
-set(exec_prefix "${_harfbuzz_remove_string}")
-set(prefix "${_harfbuzz_remove_string}")
-
-# Compute the installation prefix by stripping components from our current
-# location.
-get_filename_component(_harfbuzz_prefix "${CMAKE_CURRENT_LIST_DIR}" DIRECTORY)
-get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY)
set(_harfbuzz_libdir "@libdir@")
-string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_libdir "${_harfbuzz_libdir}")
-set(_harfbuzz_libdir_iter "${_harfbuzz_libdir}")
-while (_harfbuzz_libdir_iter)
- set(_harfbuzz_libdir_prev_iter "${_harfbuzz_libdir_iter}")
- get_filename_component(_harfbuzz_libdir_iter "${_harfbuzz_libdir_iter}" DIRECTORY)
- if (_harfbuzz_libdir_prev_iter STREQUAL _harfbuzz_libdir_iter)
- break()
- endif ()
- get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY)
-endwhile ()
-unset(_harfbuzz_libdir_iter)
-
-# Get the include subdir.
set(_harfbuzz_includedir "@includedir@")
-string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_includedir "${_harfbuzz_includedir}")
# Extract version information from libtool.
set(_harfbuzz_version_info "@HB_LIBTOOL_VERSION_INFO@")
@@ -48,29 +24,29 @@
# Add the libraries.
add_library(harfbuzz::harfbuzz SHARED IMPORTED)
set_target_properties(harfbuzz::harfbuzz PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz"
- IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz${_harfbuzz_lib_suffix}")
+ INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_includedir}/harfbuzz"
+ IMPORTED_LOCATION "${_harfbuzz_libdir}/libharfbuzz${_harfbuzz_lib_suffix}")
add_library(harfbuzz::icu SHARED IMPORTED)
set_target_properties(harfbuzz::icu PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz"
+ INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_includedir}/harfbuzz"
INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz"
- IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-icu${_harfbuzz_lib_suffix}")
+ IMPORTED_LOCATION "${_harfbuzz_libdir}/libharfbuzz-icu${_harfbuzz_lib_suffix}")
add_library(harfbuzz::subset SHARED IMPORTED)
set_target_properties(harfbuzz::subset PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz"
+ INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_includedir}/harfbuzz"
INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz"
- IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-subset${_harfbuzz_lib_suffix}")
+ IMPORTED_LOCATION "${_harfbuzz_libdir}/libharfbuzz-subset${_harfbuzz_lib_suffix}")
# Only add the gobject library if it was built.
set(_harfbuzz_have_gobject "@have_gobject@")
if (_harfbuzz_have_gobject)
add_library(harfbuzz::gobject SHARED IMPORTED)
set_target_properties(harfbuzz::gobject PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz"
+ INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_includedir}/harfbuzz"
INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz"
- IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-gobject${_harfbuzz_lib_suffix}")
+ IMPORTED_LOCATION "${_harfbuzz_libdir}/libharfbuzz-gobject${_harfbuzz_lib_suffix}")
endif ()
# Clean out variables we used in our scope.
@@ -80,7 +56,3 @@
unset(_harfbuzz_age)
unset(_harfbuzz_includedir)
unset(_harfbuzz_libdir)
-unset(_harfbuzz_prefix)
-unset(exec_prefix)
-unset(prefix)
-unset(_harfbuzz_remove_string)
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index aa4ad4c..8b9190d 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -131,14 +131,14 @@
hb_glyph_info_t *info = buffer->info;
hb_glyph_info_t buf[4];
- memcpy (buf, info + start, l * sizeof (buf[0]));
- memcpy (buf + 2, info + end - r, r * sizeof (buf[0]));
+ hb_memcpy (buf, info + start, l * sizeof (buf[0]));
+ hb_memcpy (buf + 2, info + end - r, r * sizeof (buf[0]));
if (l != r)
memmove (info + start + r, info + start + l, (end - start - l - r) * sizeof (buf[0]));
- memcpy (info + start, buf + 2, r * sizeof (buf[0]));
- memcpy (info + end - l, buf, l * sizeof (buf[0]));
+ hb_memcpy (info + start, buf + 2, r * sizeof (buf[0]));
+ hb_memcpy (info + end - l, buf, l * sizeof (buf[0]));
if (reverse_l)
{
buf[0] = info[end - 1];
diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc
index d60126f..78427b0 100644
--- a/src/hb-aat-layout.cc
+++ b/src/hb-aat-layout.cc
@@ -289,7 +289,7 @@
void
hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
{
- hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph);
+ buffer->delete_glyphs_inplace (is_deleted_glyph);
}
/**
diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh
index c914f58..d0ee7d6 100644
--- a/src/hb-aat-map.hh
+++ b/src/hb-aat-map.hh
@@ -38,7 +38,7 @@
void init ()
{
- memset (this, 0, sizeof (*this));
+ hb_memset (this, 0, sizeof (*this));
chain_flags.init ();
}
void fini () { chain_flags.fini (); }
diff --git a/src/hb-algs.hh b/src/hb-algs.hh
index cc37c07..d85a4af 100644
--- a/src/hb-algs.hh
+++ b/src/hb-algs.hh
@@ -236,17 +236,6 @@
template <typename T> constexpr auto
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
- template <typename T> constexpr uint32_t
- impl (const hb::shared_ptr<T>& v, hb_priority<1>) const
- {
- return v.get () ? v.get ()->hash () : 0;
- }
- template <typename T> constexpr uint32_t
- impl (const hb::unique_ptr<T>& v, hb_priority<1>) const
- {
- return v.get () ? v.get ()->hash () : 0;
- }
-
template <typename T> constexpr auto
impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v)))
@@ -495,6 +484,17 @@
}
HB_FUNCOBJ (hb_equal);
+struct
+{
+ template <typename T> void
+ operator () (T& a, T& b) const
+ {
+ using std::swap; // allow ADL
+ swap (a, b);
+ }
+}
+HB_FUNCOBJ (hb_swap);
+
template <typename T1, typename T2>
struct hb_pair_t
@@ -507,7 +507,7 @@
hb_enable_if (std::is_default_constructible<U1>::value &&
std::is_default_constructible<U2>::value)>
hb_pair_t () : first (), second () {}
- hb_pair_t (T1 a, T2 b) : first (a), second (b) {}
+ hb_pair_t (T1 a, T2 b) : first (std::forward<T1> (a)), second (std::forward<T2> (b)) {}
template <typename Q1, typename Q2,
hb_enable_if (hb_is_convertible (T1, Q1) &&
@@ -524,6 +524,25 @@
bool operator > (const pair_t& o) const { return first > o.first || (first == o.first && second > o.second); }
bool operator <= (const pair_t& o) const { return !(*this > o); }
+ static int cmp (const void *pa, const void *pb)
+ {
+ pair_t *a = (pair_t *) pa;
+ pair_t *b = (pair_t *) pb;
+
+ if (a->first < b->first) return -1;
+ if (a->first > b->first) return +1;
+ if (a->second < b->second) return -1;
+ if (a->second > b->second) return +1;
+ return 0;
+ }
+
+ friend void swap (hb_pair_t& a, hb_pair_t& b)
+ {
+ hb_swap (a.first, b.first);
+ hb_swap (a.second, b.second);
+ }
+
+
T1 first;
T2 second;
};
@@ -570,17 +589,6 @@
}
HB_FUNCOBJ (hb_clamp);
-struct
-{
- template <typename T> void
- operator () (T& a, T& b) const
- {
- using std::swap; // allow ADL
- swap (a, b);
- }
-}
-HB_FUNCOBJ (hb_swap);
-
/*
* Bithacks.
*/
@@ -849,19 +857,14 @@
return (T)(u - lo) <= (T)(hi - lo);
}
template <typename T> static inline bool
-hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
+hb_in_ranges (T u, T lo1, T hi1)
{
- return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
+ return hb_in_range (u, lo1, hi1);
}
-template <typename T> static inline bool
-hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
+template <typename T, typename ...Ts> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, Ts... ds)
{
- return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
-}
-template <typename T> static inline bool
-hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3, T lo4, T hi4)
-{
- return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3) || hb_in_range (u, lo4, hi4);
+ return hb_in_range<T> (u, lo1, hi1) || hb_in_ranges<T> (u, ds...);
}
@@ -869,10 +872,18 @@
* Overflow checking.
*/
-/* Consider __builtin_mul_overflow use here also */
static inline bool
-hb_unsigned_mul_overflows (unsigned int count, unsigned int size)
+hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *result = nullptr)
{
+#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
+ unsigned stack_result;
+ if (!result)
+ result = &stack_result;
+ return __builtin_mul_overflow (count, size, result);
+#endif
+
+ if (result)
+ *result = count * size;
return (size > 0) && (count >= ((unsigned int) -1) / size);
}
@@ -1164,9 +1175,12 @@
}
-template <typename T, typename T2, typename T3> static inline void
-hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2)
+template <typename T, typename T2, typename T3 = int> static inline void
+hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2 = nullptr)
{
+ static_assert (hb_is_trivially_copy_assignable (T), "");
+ static_assert (hb_is_trivially_copy_assignable (T3), "");
+
for (unsigned int i = 1; i < len; i++)
{
unsigned int j = i;
@@ -1189,12 +1203,6 @@
}
}
-template <typename T> static inline void
-hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
-{
- hb_stable_sort (array, len, compar, (int *) nullptr);
-}
-
static inline hb_bool_t
hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
{
@@ -1322,47 +1330,4 @@
HB_FUNCOBJ (hb_dec);
-/* Compiler-assisted vectorization. */
-
-/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))),
- * basically a fixed-size bitset. */
-template <typename elt_t, unsigned int byte_size>
-struct hb_vector_size_t
-{
- elt_t& operator [] (unsigned int i) { return v[i]; }
- const elt_t& operator [] (unsigned int i) const { return v[i]; }
-
- void clear (unsigned char v = 0) { memset (this, v, sizeof (*this)); }
-
- template <typename Op>
- hb_vector_size_t process (const Op& op) const
- {
- hb_vector_size_t r;
- for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
- r.v[i] = op (v[i]);
- return r;
- }
- template <typename Op>
- hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const
- {
- hb_vector_size_t r;
- for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
- r.v[i] = op (v[i], o.v[i]);
- return r;
- }
- hb_vector_size_t operator | (const hb_vector_size_t &o) const
- { return process (hb_bitwise_or, o); }
- hb_vector_size_t operator & (const hb_vector_size_t &o) const
- { return process (hb_bitwise_and, o); }
- hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
- { return process (hb_bitwise_xor, o); }
- hb_vector_size_t operator ~ () const
- { return process (hb_bitwise_neg); }
-
- private:
- static_assert (0 == byte_size % sizeof (elt_t), "");
- elt_t v[byte_size / sizeof (elt_t)];
-};
-
-
#endif /* HB_ALGS_HH */
diff --git a/src/hb-array.hh b/src/hb-array.hh
index 5884007..17562bc 100644
--- a/src/hb-array.hh
+++ b/src/hb-array.hh
@@ -100,10 +100,18 @@
/* Ouch. The operator== compares the contents of the array. For range-based for loops,
* it's best if we can just compare arrayZ, though comparing contents is still fast,
* but also would require that Type has operator==. As such, we optimize this operator
- * for range-based for loop and just compare arrayZ and length. */
+ * for range-based for loop and just compare arrayZ and length.
+ *
+ * The above comment is outdated now because we implemented separate begin/end to
+ * objects that were using hb_array_t for range-based loop before. */
bool operator != (const hb_array_t& o) const
{ return this->arrayZ != o.arrayZ || this->length != o.length; }
+ /* Faster range-based for loop without bounds-check. */
+ Type *begin () const { return arrayZ; }
+ Type *end () const { return arrayZ + length; }
+
+
/* Extra operators.
*/
Type * operator & () const { return arrayZ; }
@@ -112,11 +120,11 @@
HB_INTERNAL bool operator == (const hb_array_t &o) const;
- uint32_t hash () const {
+ uint32_t hash () const
+ {
uint32_t current = 0;
- for (unsigned int i = 0; i < this->length; i++) {
- current = current * 31 + hb_hash (this->arrayZ[i]);
- }
+ for (auto &v : *this)
+ current = current * 31 + hb_hash (v);
return current;
}
@@ -184,23 +192,18 @@
hb_sorted_array_t<Type> qsort (int (*cmp_)(const void*, const void*))
{
+ //static_assert (hb_enable_if (hb_is_trivially_copy_assignable(Type)), "");
if (likely (length))
hb_qsort (arrayZ, length, this->get_item_size (), cmp_);
return hb_sorted_array_t<Type> (*this);
}
hb_sorted_array_t<Type> qsort ()
{
+ //static_assert (hb_enable_if (hb_is_trivially_copy_assignable(Type)), "");
if (likely (length))
hb_qsort (arrayZ, length, this->get_item_size (), Type::cmp);
return hb_sorted_array_t<Type> (*this);
}
- void qsort (unsigned int start, unsigned int end)
- {
- end = hb_min (end, length);
- assert (start <= end);
- if (likely (start < end))
- hb_qsort (arrayZ + start, end - start, this->get_item_size (), Type::cmp);
- }
/*
* Other methods.
@@ -262,17 +265,31 @@
void fini ()
{ hb_free ((void *) arrayZ); arrayZ = nullptr; length = 0; }
- template <typename hb_serialize_context_t>
+ template <typename hb_serialize_context_t,
+ typename U = Type,
+ hb_enable_if (!(sizeof (U) < sizeof (long long) && hb_is_trivially_copy_assignable(hb_decay<Type>)))>
hb_array_t copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
auto* out = c->start_embed (arrayZ);
- if (unlikely (!c->extend_size (out, get_size ()))) return_trace (hb_array_t ());
+ if (unlikely (!c->extend_size (out, get_size (), false))) return_trace (hb_array_t ());
for (unsigned i = 0; i < length; i++)
out[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */
return_trace (hb_array_t (out, length));
}
+ template <typename hb_serialize_context_t,
+ typename U = Type,
+ hb_enable_if (sizeof (U) < sizeof (long long) && hb_is_trivially_copy_assignable(hb_decay<Type>))>
+ hb_array_t copy (hb_serialize_context_t *c) const
+ {
+ TRACE_SERIALIZE (this);
+ auto* out = c->start_embed (arrayZ);
+ if (unlikely (!c->extend_size (out, get_size (), false))) return_trace (hb_array_t ());
+ hb_memcpy (out, arrayZ, get_size ());
+ return_trace (hb_array_t (out, length));
+ }
+
template <typename hb_sanitize_context_t>
bool sanitize (hb_sanitize_context_t *c) const
{ return c->check_array (arrayZ, length); }
@@ -295,8 +312,8 @@
template <typename Type>
struct hb_sorted_array_t :
- hb_iter_t<hb_sorted_array_t<Type>, Type&>,
- hb_array_t<Type>
+ hb_array_t<Type>,
+ hb_iter_t<hb_sorted_array_t<Type>, Type&>
{
typedef hb_iter_t<hb_sorted_array_t, Type&> iter_base_t;
HB_ITER_USING (iter_base_t);
@@ -316,8 +333,8 @@
template <typename U,
hb_enable_if (hb_is_cr_convertible(U, Type))>
constexpr hb_sorted_array_t (const hb_array_t<U> &o) :
- hb_iter_t<hb_sorted_array_t, Type&> (),
- hb_array_t<Type> (o) {}
+ hb_array_t<Type> (o),
+ hb_iter_t<hb_sorted_array_t, Type&> () {}
template <typename U,
hb_enable_if (hb_is_cr_convertible(U, Type))>
hb_sorted_array_t& operator = (const hb_array_t<U> &o)
@@ -329,6 +346,11 @@
bool operator != (const hb_sorted_array_t& o) const
{ return this->arrayZ != o.arrayZ || this->length != o.length; }
+ /* Faster range-based for loop without bounds-check. */
+ Type *begin () const { return this->arrayZ; }
+ Type *end () const { return this->arrayZ + this->length; }
+
+
hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const
{ return hb_sorted_array_t (((const hb_array_t<Type> *) (this))->sub_array (start_offset, seg_count)); }
hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const
@@ -421,18 +443,42 @@
return 0 == hb_memcmp (arrayZ, o.arrayZ, length);
}
+
+/* Specialize hash() for byte arrays. */
+
template <>
-inline uint32_t hb_array_t<const char>::hash () const {
+inline uint32_t hb_array_t<const char>::hash () const
+{
uint32_t current = 0;
- for (unsigned int i = 0; i < this->length; i++)
- current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u);
+ unsigned i = 0;
+
+#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
+ ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__))
+ struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
+ for (; i + 4 <= this->length; i += 4)
+ current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v);
+#endif
+
+ for (; i < this->length; i++)
+ current = current * 31 + hb_hash (this->arrayZ[i]);
return current;
}
+
template <>
-inline uint32_t hb_array_t<const unsigned char>::hash () const {
+inline uint32_t hb_array_t<const unsigned char>::hash () const
+{
uint32_t current = 0;
- for (unsigned int i = 0; i < this->length; i++)
- current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u);
+ unsigned i = 0;
+
+#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
+ ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__))
+ struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
+ for (; i + 4 <= this->length; i += 4)
+ current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v);
+#endif
+
+ for (; i < this->length; i++)
+ current = current * 31 + hb_hash (this->arrayZ[i]);
return current;
}
diff --git a/src/hb-bit-page.hh b/src/hb-bit-page.hh
index 95ae1b7..1198705 100644
--- a/src/hb-bit-page.hh
+++ b/src/hb-bit-page.hh
@@ -30,6 +30,53 @@
#include "hb.hh"
+
+/* Compiler-assisted vectorization. */
+
+/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))),
+ * basically a fixed-size bitset. */
+template <typename elt_t, unsigned int byte_size>
+struct hb_vector_size_t
+{
+ elt_t& operator [] (unsigned int i) { return v[i]; }
+ const elt_t& operator [] (unsigned int i) const { return v[i]; }
+
+ void clear (unsigned char v = 0) { hb_memset (this, v, sizeof (*this)); }
+
+ template <typename Op>
+ hb_vector_size_t process (const Op& op) const
+ {
+ hb_vector_size_t r;
+ for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
+ r.v[i] = op (v[i]);
+ return r;
+ }
+ template <typename Op>
+ hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const
+ {
+ hb_vector_size_t r;
+ for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
+ r.v[i] = op (v[i], o.v[i]);
+ return r;
+ }
+ hb_vector_size_t operator | (const hb_vector_size_t &o) const
+ { return process (hb_bitwise_or, o); }
+ hb_vector_size_t operator & (const hb_vector_size_t &o) const
+ { return process (hb_bitwise_and, o); }
+ hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
+ { return process (hb_bitwise_xor, o); }
+ hb_vector_size_t operator ~ () const
+ { return process (hb_bitwise_neg); }
+
+ hb_array_t<const elt_t> iter () const
+ { return hb_array (v); }
+
+ private:
+ static_assert (0 == byte_size % sizeof (elt_t), "");
+ elt_t v[byte_size / sizeof (elt_t)];
+};
+
+
struct hb_bit_page_t
{
void init0 () { v.clear (); }
@@ -40,17 +87,17 @@
bool is_empty () const
{
- for (unsigned i = 0; i < len (); i++)
- if (v[i])
- return false;
- return true;
+ return
+ + hb_iter (v)
+ | hb_none
+ ;
}
uint32_t hash () const
{
- uint32_t h = 0;
- for (unsigned i = 0; i < len (); i++)
- h = h * 31 + hb_hash (v[i]);
- return h;
+ return
+ + hb_iter (v)
+ | hb_reduce ([] (uint32_t h, const elt_t &_) { return h * 31 + hb_hash (_); }, (uint32_t) 0u)
+ ;
}
void add (hb_codepoint_t g) { elt (g) |= mask (g); }
@@ -69,7 +116,7 @@
*la |= ~(mask (a) - 1);
la++;
- memset (la, 0xff, (char *) lb - (char *) la);
+ hb_memset (la, 0xff, (char *) lb - (char *) la);
*lb |= ((mask (b) << 1) - 1);
}
@@ -85,7 +132,7 @@
*la &= mask (a) - 1;
la++;
- memset (la, 0, (char *) lb - (char *) la);
+ hb_memset (la, 0, (char *) lb - (char *) la);
*lb &= ~((mask (b) << 1) - 1);
}
@@ -101,13 +148,13 @@
hb_codepoint_t *p,
unsigned int size) const
{
- unsigned int start_v = start_value >> ELT_BITS_LOG_2;
+ unsigned int start_v = start_value / ELT_BITS;
unsigned int start_bit = start_value & ELT_MASK;
unsigned int count = 0;
for (unsigned i = start_v; i < len () && count < size; i++)
{
elt_t bits = v[i];
- uint32_t v_base = base | (i << ELT_BITS_LOG_2);
+ uint32_t v_base = base | (i * ELT_BITS);
for (unsigned int j = start_bit; j < ELT_BITS && count < size; j++)
{
if ((elt_t(1) << j) & bits) {
@@ -132,13 +179,13 @@
unsigned int size,
hb_codepoint_t *next_value) const
{
- unsigned int start_v = start_value >> ELT_BITS_LOG_2;
+ unsigned int start_v = start_value / ELT_BITS;
unsigned int start_bit = start_value & ELT_MASK;
unsigned int count = 0;
for (unsigned i = start_v; i < len () && count < size; i++)
{
elt_t bits = v[i];
- uint32_t v_offset = i << ELT_BITS_LOG_2;
+ uint32_t v_offset = i * ELT_BITS;
for (unsigned int j = start_bit; j < ELT_BITS && count < size; j++)
{
if ((elt_t(1) << j) & bits)
@@ -161,7 +208,10 @@
bool is_equal (const hb_bit_page_t &other) const
{
- return 0 == hb_memcmp (&v, &other.v, sizeof (v));
+ for (unsigned i = 0; i < len (); i++)
+ if (v[i] != other.v[i])
+ return false;
+ return true;
}
bool is_subset (const hb_bit_page_t &larger_page) const
{
@@ -173,10 +223,10 @@
unsigned int get_population () const
{
- unsigned int pop = 0;
- for (unsigned int i = 0; i < len (); i++)
- pop += hb_popcount (v[i]);
- return pop;
+ return
+ + hb_iter (v)
+ | hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u)
+ ;
}
bool next (hb_codepoint_t *codepoint) const
@@ -262,8 +312,6 @@
typedef hb_vector_size_t<elt_t, PAGE_BITS / 8> vector_t;
static constexpr unsigned ELT_BITS = sizeof (elt_t) * 8;
- static constexpr unsigned ELT_BITS_LOG_2 = 6;
- static_assert (1 << ELT_BITS_LOG_2 == ELT_BITS, "");
static constexpr unsigned ELT_MASK = ELT_BITS - 1;
static constexpr unsigned BITS = sizeof (vector_t) * 8;
diff --git a/src/hb-bit-set-invertible.hh b/src/hb-bit-set-invertible.hh
index 27fb073..ff8aecc 100644
--- a/src/hb-bit-set-invertible.hh
+++ b/src/hb-bit-set-invertible.hh
@@ -123,10 +123,8 @@
bool get (hb_codepoint_t g) const { return s.get (g) ^ inverted; }
/* Has interface. */
- static constexpr bool SENTINEL = false;
- typedef bool value_t;
- value_t operator [] (hb_codepoint_t k) const { return get (k); }
- bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+ bool operator [] (hb_codepoint_t k) const { return get (k); }
+ bool has (hb_codepoint_t k) const { return (*this)[k]; }
/* Predicate. */
bool operator () (hb_codepoint_t k) const { return has (k); }
diff --git a/src/hb-bit-set.hh b/src/hb-bit-set.hh
index a63887e..8de6e03 100644
--- a/src/hb-bit-set.hh
+++ b/src/hb-bit-set.hh
@@ -85,10 +85,10 @@
void err () { if (successful) successful = false; } /* TODO Remove */
bool in_error () const { return !successful; }
- bool resize (unsigned int count)
+ bool resize (unsigned int count, bool clear = true)
{
if (unlikely (!successful)) return false;
- if (unlikely (!pages.resize (count) || !page_map.resize (count)))
+ if (unlikely (!pages.resize (count, clear) || !page_map.resize (count, clear)))
{
pages.resize (page_map.length);
successful = false;
@@ -330,10 +330,8 @@
}
/* Has interface. */
- static constexpr bool SENTINEL = false;
- typedef bool value_t;
- value_t operator [] (hb_codepoint_t k) const { return get (k); }
- bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+ bool operator [] (hb_codepoint_t k) const { return get (k); }
+ bool has (hb_codepoint_t k) const { return (*this)[k]; }
/* Predicate. */
bool operator () (hb_codepoint_t k) const { return has (k); }
@@ -352,7 +350,7 @@
{
if (unlikely (!successful)) return;
unsigned int count = other.pages.length;
- if (unlikely (!resize (count)))
+ if (unlikely (!resize (count, false)))
return;
population = other.population;
@@ -391,7 +389,7 @@
bool is_subset (const hb_bit_set_t &larger_set) const
{
if (has_population () && larger_set.has_population () &&
- population != larger_set.population)
+ population > larger_set.population)
return false;
uint32_t spi = 0;
@@ -540,21 +538,21 @@
b = nb;
for (; a && b; )
{
- if (page_map[a - 1].major == other.page_map[b - 1].major)
+ if (page_map.arrayZ[a - 1].major == other.page_map.arrayZ[b - 1].major)
{
a--;
b--;
count--;
- page_map[count] = page_map[a];
+ page_map.arrayZ[count] = page_map.arrayZ[a];
page_at (count).v = op (page_at (a).v, other.page_at (b).v);
}
- else if (page_map[a - 1].major > other.page_map[b - 1].major)
+ else if (page_map.arrayZ[a - 1].major > other.page_map.arrayZ[b - 1].major)
{
a--;
if (passthru_left)
{
count--;
- page_map[count] = page_map[a];
+ page_map.arrayZ[count] = page_map.arrayZ[a];
}
}
else
@@ -563,8 +561,8 @@
if (passthru_right)
{
count--;
- page_map[count].major = other.page_map[b].major;
- page_map[count].index = next_page++;
+ page_map.arrayZ[count].major = other.page_map.arrayZ[b].major;
+ page_map.arrayZ[count].index = next_page++;
page_at (count).v = other.page_at (b).v;
}
}
@@ -574,15 +572,15 @@
{
a--;
count--;
- page_map[count] = page_map [a];
+ page_map.arrayZ[count] = page_map.arrayZ[a];
}
if (passthru_right)
while (b)
{
b--;
count--;
- page_map[count].major = other.page_map[b].major;
- page_map[count].index = next_page++;
+ page_map.arrayZ[count].major = other.page_map.arrayZ[b].major;
+ page_map.arrayZ[count].index = next_page++;
page_at (count).v = other.page_at (b).v;
}
assert (!count);
@@ -605,8 +603,6 @@
bool next (hb_codepoint_t *codepoint) const
{
- // TODO: this should be merged with prev() as both implementations
- // are very similar.
if (unlikely (*codepoint == INVALID)) {
*codepoint = get_min ();
return *codepoint != INVALID;
@@ -640,7 +636,7 @@
for (; i < page_map.length; i++)
{
- const page_map_t ¤t = page_map.arrayZ[i];
+ const page_map_t ¤t = page_map_array[i];
hb_codepoint_t m = pages_array[current.index].get_min ();
if (m != INVALID)
{
@@ -663,21 +659,21 @@
page_map_t map = {get_major (*codepoint), 0};
unsigned int i;
page_map.bfind (map, &i, HB_NOT_FOUND_STORE_CLOSEST);
- if (i < page_map.length && page_map[i].major == map.major)
+ if (i < page_map.length && page_map.arrayZ[i].major == map.major)
{
- if (pages[page_map[i].index].previous (codepoint))
+ if (pages[page_map.arrayZ[i].index].previous (codepoint))
{
- *codepoint += page_map[i].major * page_t::PAGE_BITS;
+ *codepoint += page_map.arrayZ[i].major * page_t::PAGE_BITS;
return true;
}
}
i--;
for (; (int) i >= 0; i--)
{
- hb_codepoint_t m = pages[page_map[i].index].get_max ();
+ hb_codepoint_t m = pages.arrayZ[page_map.arrayZ[i].index].get_max ();
if (m != INVALID)
{
- *codepoint = page_map[i].major * page_t::PAGE_BITS + m;
+ *codepoint = page_map.arrayZ[i].major * page_t::PAGE_BITS + m;
return true;
}
}
@@ -905,7 +901,7 @@
{
auto &cached_page = page_map.arrayZ[i];
if (cached_page.major == major)
- return &pages[cached_page.index];
+ return &pages.arrayZ[cached_page.index];
}
page_map_t map = {major, pages.length};
@@ -917,15 +913,15 @@
if (unlikely (!resize (pages.length + 1)))
return nullptr;
- pages[map.index].init0 ();
- memmove (page_map + i + 1,
- page_map + i,
+ pages.arrayZ[map.index].init0 ();
+ memmove (page_map.arrayZ + i + 1,
+ page_map.arrayZ + i,
(page_map.length - 1 - i) * page_map.item_size);
page_map[i] = map;
}
last_page_lookup = i;
- return &pages[page_map[i].index];
+ return &pages.arrayZ[page_map.arrayZ[i].index];
}
const page_t *page_for (hb_codepoint_t g) const
{
@@ -939,7 +935,7 @@
{
auto &cached_page = page_map.arrayZ[i];
if (cached_page.major == major)
- return &pages[cached_page.index];
+ return &pages.arrayZ[cached_page.index];
}
page_map_t key = {major};
@@ -947,10 +943,18 @@
return nullptr;
last_page_lookup = i;
- return &pages[page_map[i].index];
+ return &pages.arrayZ[page_map[i].index];
}
- page_t &page_at (unsigned int i) { return pages[page_map[i].index]; }
- const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; }
+ page_t &page_at (unsigned int i)
+ {
+ assert (i < page_map.length);
+ return pages.arrayZ[page_map.arrayZ[i].index];
+ }
+ const page_t &page_at (unsigned int i) const
+ {
+ assert (i < page_map.length);
+ return pages.arrayZ[page_map.arrayZ[i].index];
+ }
unsigned int get_major (hb_codepoint_t g) const { return g >> page_t::PAGE_BITS_LOG_2; }
unsigned int page_remainder (hb_codepoint_t g) const { return g & page_t::PAGE_BITMASK; }
hb_codepoint_t major_start (unsigned int major) const { return major << page_t::PAGE_BITS_LOG_2; }
diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index 9bc12ea..f0fda1f 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -495,7 +495,7 @@
DEBUG_MSG_FUNC (BLOB, this, "dupped successfully -> %p\n", this->data);
- memcpy (new_data, this->data, this->length);
+ hb_memcpy (new_data, this->data, this->length);
this->destroy_user_data ();
this->mode = HB_MEMORY_MODE_WRITABLE;
this->data = new_data;
diff --git a/src/hb-buffer-deserialize-json.hh b/src/hb-buffer-deserialize-json.hh
index 8709585..993bb1f 100644
--- a/src/hb-buffer-deserialize-json.hh
+++ b/src/hb-buffer-deserialize-json.hh
@@ -32,7 +32,7 @@
#include "hb.hh"
-#line 36 "hb-buffer-deserialize-json.hh"
+#line 33 "hb-buffer-deserialize-json.hh"
static const unsigned char _deserialize_json_trans_keys[] = {
0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u,
@@ -557,12 +557,12 @@
hb_glyph_info_t info = {0};
hb_glyph_position_t pos = {0};
-#line 561 "hb-buffer-deserialize-json.hh"
+#line 554 "hb-buffer-deserialize-json.hh"
{
cs = deserialize_json_start;
}
-#line 566 "hb-buffer-deserialize-json.hh"
+#line 557 "hb-buffer-deserialize-json.hh"
{
int _slen;
int _trans;
@@ -590,8 +590,8 @@
case 1:
#line 38 "hb-buffer-deserialize-json.rl"
{
- memset (&info, 0, sizeof (info));
- memset (&pos , 0, sizeof (pos ));
+ hb_memset (&info, 0, sizeof (info));
+ hb_memset (&pos , 0, sizeof (pos ));
}
break;
case 5:
@@ -774,7 +774,7 @@
*end_ptr = p;
}
break;
-#line 778 "hb-buffer-deserialize-json.hh"
+#line 735 "hb-buffer-deserialize-json.hh"
}
_again:
diff --git a/src/hb-buffer-deserialize-json.rl b/src/hb-buffer-deserialize-json.rl
index d5e3c13..d6fbfe8 100644
--- a/src/hb-buffer-deserialize-json.rl
+++ b/src/hb-buffer-deserialize-json.rl
@@ -36,8 +36,8 @@
write data;
action clear_item {
- memset (&info, 0, sizeof (info));
- memset (&pos , 0, sizeof (pos ));
+ hb_memset (&info, 0, sizeof (info));
+ hb_memset (&pos , 0, sizeof (pos ));
}
action add_item {
diff --git a/src/hb-buffer-deserialize-text.hh b/src/hb-buffer-deserialize-text.hh
index 9062610..6b9b428 100644
--- a/src/hb-buffer-deserialize-text.hh
+++ b/src/hb-buffer-deserialize-text.hh
@@ -32,32 +32,30 @@
#include "hb.hh"
-#line 36 "hb-buffer-deserialize-text.hh"
+#line 33 "hb-buffer-deserialize-text.hh"
static const unsigned char _deserialize_text_trans_keys[] = {
- 0u, 0u, 9u, 91u, 85u, 85u, 43u, 43u, 48u, 102u, 9u, 85u, 48u, 57u, 45u, 57u,
- 48u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u,
- 44u, 57u, 43u, 124u, 45u, 57u, 48u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u,
+ 0u, 0u, 9u, 91u, 85u, 85u, 43u, 43u, 48u, 102u, 9u, 85u, 48u, 57u, 48u, 57u,
+ 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u,
+ 45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u,
9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u,
9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u,
- 9u, 124u, 9u, 124u, 9u, 124u, 0
+ 0
};
static const char _deserialize_text_key_spans[] = {
- 0, 83, 1, 1, 55, 77, 10, 13,
- 10, 10, 10, 13, 10, 1, 13, 10,
- 14, 82, 13, 10, 116, 116, 0, 77,
+ 0, 83, 1, 1, 55, 77, 10, 10,
+ 13, 10, 13, 10, 10, 13, 10, 1,
+ 13, 10, 14, 82, 116, 116, 0, 77,
116, 116, 116, 116, 116, 116, 116, 116,
- 116, 116, 116, 116, 116, 116, 116, 116,
- 116, 116, 116
+ 116, 116, 116, 116, 116, 116, 116, 116
};
static const short _deserialize_text_index_offsets[] = {
0, 0, 84, 86, 88, 144, 222, 233,
- 247, 258, 269, 280, 294, 305, 307, 321,
- 332, 347, 430, 444, 455, 572, 689, 690,
+ 244, 258, 269, 283, 294, 305, 319, 330,
+ 332, 346, 357, 372, 455, 572, 689, 690,
768, 885, 1002, 1119, 1236, 1353, 1470, 1587,
- 1704, 1821, 1938, 2055, 2172, 2289, 2406, 2523,
- 2640, 2757, 2874
+ 1704, 1821, 1938, 2055, 2172, 2289, 2406, 2523
};
static const char _deserialize_text_indicies[] = {
@@ -90,34 +88,34 @@
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 4, 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,
+ 9, 1, 10, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 1, 12, 1, 1,
13, 14, 14, 14, 14, 14, 14, 14,
14, 14, 1, 15, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 1, 17, 18,
- 18, 18, 18, 18, 18, 18, 18, 18,
- 1, 19, 1, 1, 20, 21, 21, 21,
+ 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,
23, 23, 23, 23, 23, 23, 23, 23,
- 23, 1, 24, 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, 24, 1, 1,
- 1, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 1, 30, 30, 1, 1,
+ 23, 1, 24, 1, 1, 25, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 1,
+ 27, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 1, 29, 1, 30, 1, 1,
+ 31, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 1, 33, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 1, 29, 1,
+ 1, 1, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 1, 35, 35, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 30, 1,
- 1, 30, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 35,
+ 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, 30, 30, 1,
+ 1, 1, 1, 1, 1, 1, 35, 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, 30, 1, 31,
- 1, 1, 32, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 1, 34, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 1,
+ 1, 1, 1, 1, 1, 1, 35, 1,
36, 36, 36, 36, 36, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 36,
@@ -201,53 +199,24 @@
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 56, 48,
- 57, 57, 57, 57, 57, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 57,
- 30, 30, 58, 30, 30, 30, 30, 30,
- 30, 30, 59, 1, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 60, 30, 30, 61,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 62, 63, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 64, 30, 57, 57, 57,
- 57, 57, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 57, 30, 30, 58,
- 30, 30, 30, 30, 30, 30, 30, 59,
- 1, 30, 30, 30, 65, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 30, 30,
- 30, 60, 30, 30, 61, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 62, 63, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 64, 30, 67, 67, 67, 67, 67, 1,
+ 57, 57, 57, 57, 57, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 57,
+ 35, 35, 58, 35, 35, 35, 35, 35,
+ 35, 35, 59, 1, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 60, 35, 35, 61,
+ 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 62, 63, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 64, 35, 65, 65, 65,
+ 65, 65, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 67, 1, 1, 68, 1, 1, 1,
- 1, 1, 1, 1, 1, 69, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 70, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 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, 65, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
@@ -255,228 +224,210 @@
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 42, 1, 1, 1, 1,
+ 1, 66, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 73, 1, 74, 74, 74, 74,
- 74, 48, 48, 48, 48, 48, 48, 48,
+ 67, 1, 68, 68, 68, 68, 68, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 68, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 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, 69, 1, 70,
+ 70, 70, 70, 70, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 74, 48, 48, 50, 48,
- 48, 48, 48, 48, 48, 48, 51, 1,
+ 48, 48, 48, 48, 48, 48, 70, 48,
+ 48, 50, 48, 48, 48, 48, 48, 48,
+ 48, 51, 1, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 52, 48, 48, 53, 48,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
- 52, 48, 48, 53, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 54, 55, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 54,
- 55, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 56,
- 48, 75, 75, 75, 75, 75, 1, 1,
+ 48, 48, 56, 48, 71, 71, 71, 71,
+ 71, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 75, 1, 1, 76, 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,
- 78, 1, 1, 1, 1, 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, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 79, 1, 80, 80,
- 80, 80, 80, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 80, 1, 1,
+ 1, 1, 1, 71, 1, 1, 72, 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,
+ 74, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 75,
+ 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, 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, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 78, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 79, 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,
+ 77, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 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, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 79, 1, 71, 71, 71, 71, 71,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 71, 1, 1, 72, 1, 1,
+ 1, 1, 1, 1, 1, 1, 73, 1,
+ 1, 1, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 75, 1,
+ 80, 80, 80, 80, 80, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 80,
1, 1, 81, 1, 1, 1, 1, 1,
+ 1, 1, 82, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 83,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 82, 1, 80, 80, 80, 80, 80,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 80, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 1, 1, 1, 1,
+ 1, 1, 1, 1, 45, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 81,
+ 1, 1, 1, 84, 1, 85, 85, 85,
+ 85, 85, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 82, 1,
- 84, 84, 84, 84, 84, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 84,
- 1, 1, 85, 1, 1, 1, 1, 1,
- 1, 1, 86, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 85, 1, 1, 86,
+ 1, 1, 1, 1, 1, 1, 1, 87,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 88, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 89, 1, 85, 85, 85, 85, 85, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 85, 1, 1, 86, 1, 1, 1,
1, 1, 1, 1, 87, 1, 1, 1,
+ 1, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 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, 88, 1, 84, 84, 84,
- 84, 84, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 88, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 84, 1, 1, 85,
- 1, 1, 1, 1, 1, 1, 1, 86,
- 1, 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, 89, 1, 80,
+ 80, 80, 80, 80, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 80, 1,
+ 1, 81, 1, 1, 1, 1, 1, 1,
+ 1, 82, 1, 1, 1, 1, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 1, 1, 1, 1, 1, 1, 83, 1,
+ 1, 1, 1, 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, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 84, 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, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 87, 1, 1, 1, 1, 1, 1,
+ 66, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 88, 1, 75, 75, 75, 75, 75, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 75, 1, 1, 76, 1, 1, 1,
- 1, 1, 1, 1, 77, 1, 1, 1,
- 1, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 1, 1, 1, 1, 1,
- 1, 78, 1, 1, 1, 1, 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,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 79, 1, 90,
- 90, 90, 90, 90, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 90, 1,
- 1, 91, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 92, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 93, 1, 90, 90, 90, 90,
- 90, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 90, 1, 1, 91, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 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, 1, 1, 1, 1, 1,
- 92, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 93,
- 1, 67, 67, 67, 67, 67, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 67, 1, 1, 68, 1, 1, 1, 1,
- 1, 1, 1, 1, 69, 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, 70, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 71, 1, 94, 94,
- 94, 94, 94, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 94, 30, 30,
- 58, 30, 30, 30, 30, 30, 30, 30,
- 59, 1, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 60, 30, 30, 61, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 62, 95, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 96, 30, 94, 94, 94, 94, 94,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 94, 30, 30, 58, 30, 30,
- 30, 30, 30, 30, 30, 59, 1, 30,
- 30, 30, 97, 97, 97, 97, 97, 97,
- 97, 97, 97, 97, 30, 30, 30, 60,
- 30, 30, 61, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 62, 95,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 96, 30,
- 0
+ 1, 1, 1, 1, 1, 1, 1, 67,
+ 1, 0
};
static const char _deserialize_text_trans_targs[] = {
1, 0, 2, 26, 3, 4, 20, 5,
- 24, 25, 8, 29, 40, 29, 40, 32,
- 37, 33, 34, 12, 13, 16, 13, 16,
- 14, 15, 35, 36, 35, 36, 27, 19,
- 38, 39, 38, 39, 21, 20, 6, 22,
+ 24, 25, 28, 39, 9, 31, 34, 31,
+ 34, 11, 32, 33, 32, 33, 35, 38,
+ 14, 15, 18, 15, 18, 16, 17, 36,
+ 37, 36, 37, 27, 21, 20, 6, 22,
23, 21, 22, 23, 21, 22, 23, 25,
- 27, 27, 28, 7, 9, 11, 17, 22,
- 31, 27, 28, 7, 9, 11, 17, 22,
- 31, 41, 42, 30, 10, 18, 22, 31,
- 30, 31, 31, 30, 10, 7, 11, 31,
- 30, 22, 31, 34, 30, 10, 7, 22,
- 31, 37, 30, 10, 22, 31, 27, 22,
- 31, 42
+ 27, 27, 7, 8, 12, 13, 19, 22,
+ 30, 27, 7, 8, 12, 13, 19, 22,
+ 30, 29, 22, 30, 29, 30, 30, 29,
+ 7, 10, 22, 30, 29, 7, 22, 30,
+ 29, 7, 8, 13, 30, 29, 7, 8,
+ 22, 30, 38, 39
};
static const char _deserialize_text_trans_actions[] = {
0, 0, 0, 0, 1, 0, 2, 0,
- 2, 2, 3, 4, 4, 5, 5, 4,
- 4, 4, 4, 3, 3, 3, 0, 0,
- 6, 3, 4, 4, 5, 5, 5, 3,
- 4, 4, 5, 5, 7, 8, 9, 7,
+ 2, 2, 3, 3, 4, 3, 3, 5,
+ 5, 4, 3, 3, 5, 5, 3, 3,
+ 4, 4, 4, 0, 0, 6, 4, 3,
+ 3, 5, 5, 5, 7, 8, 9, 7,
7, 0, 0, 0, 10, 10, 10, 8,
- 12, 13, 14, 15, 15, 15, 16, 11,
- 11, 18, 19, 20, 20, 20, 0, 17,
- 17, 4, 4, 21, 22, 22, 21, 21,
- 0, 0, 13, 10, 23, 23, 23, 10,
- 24, 24, 24, 5, 25, 26, 26, 25,
- 25, 5, 27, 28, 27, 27, 30, 29,
- 29, 5
+ 12, 13, 14, 14, 14, 14, 15, 11,
+ 11, 17, 18, 18, 18, 18, 0, 16,
+ 16, 19, 19, 19, 0, 0, 13, 20,
+ 21, 21, 20, 20, 22, 23, 22, 22,
+ 10, 24, 24, 24, 10, 25, 26, 26,
+ 25, 25, 5, 5
};
static const char _deserialize_text_eof_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 7, 0, 0, 0,
- 10, 10, 11, 17, 17, 21, 0, 11,
- 10, 24, 24, 25, 25, 10, 27, 27,
- 21, 29, 29
+ 10, 10, 11, 16, 19, 0, 11, 20,
+ 22, 22, 20, 10, 25, 25, 10, 19
};
static const int deserialize_text_start = 1;
@@ -509,12 +460,12 @@
hb_glyph_info_t info = {0};
hb_glyph_position_t pos = {0};
-#line 513 "hb-buffer-deserialize-text.hh"
+#line 457 "hb-buffer-deserialize-text.hh"
{
cs = deserialize_text_start;
}
-#line 518 "hb-buffer-deserialize-text.hh"
+#line 460 "hb-buffer-deserialize-text.hh"
{
int _slen;
int _trans;
@@ -542,11 +493,11 @@
case 1:
#line 38 "hb-buffer-deserialize-text.rl"
{
- memset (&info, 0, sizeof (info));
- memset (&pos , 0, sizeof (pos ));
+ hb_memset (&info, 0, sizeof (info));
+ hb_memset (&pos , 0, sizeof (pos ));
}
break;
- case 3:
+ case 4:
#line 51 "hb-buffer-deserialize-text.rl"
{
tok = p;
@@ -560,7 +511,7 @@
#line 56 "hb-buffer-deserialize-text.rl"
{ if (unlikely (!buffer->ensure_unicode ())) return false; }
break;
- case 20:
+ case 18:
#line 58 "hb-buffer-deserialize-text.rl"
{
/* TODO Unescape delimiters. */
@@ -574,7 +525,7 @@
#line 66 "hb-buffer-deserialize-text.rl"
{if (!parse_hex (tok, p, &info.codepoint )) return false; }
break;
- case 23:
+ case 24:
#line 68 "hb-buffer-deserialize-text.rl"
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
break;
@@ -586,26 +537,26 @@
#line 70 "hb-buffer-deserialize-text.rl"
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
break;
- case 22:
+ case 21:
#line 71 "hb-buffer-deserialize-text.rl"
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
break;
- case 28:
+ case 23:
#line 72 "hb-buffer-deserialize-text.rl"
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
break;
- case 16:
+ case 15:
#line 38 "hb-buffer-deserialize-text.rl"
{
- memset (&info, 0, sizeof (info));
- memset (&pos , 0, sizeof (pos ));
+ hb_memset (&info, 0, sizeof (info));
+ hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text.rl"
{
tok = p;
}
break;
- case 4:
+ case 3:
#line 51 "hb-buffer-deserialize-text.rl"
{
tok = p;
@@ -621,7 +572,7 @@
#line 56 "hb-buffer-deserialize-text.rl"
{ if (unlikely (!buffer->ensure_unicode ())) return false; }
break;
- case 17:
+ case 16:
#line 58 "hb-buffer-deserialize-text.rl"
{
/* TODO Unescape delimiters. */
@@ -639,18 +590,6 @@
*end_ptr = p;
}
break;
- case 19:
-#line 58 "hb-buffer-deserialize-text.rl"
- {
- /* TODO Unescape delimiters. */
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
-#line 55 "hb-buffer-deserialize-text.rl"
- { if (unlikely (!buffer->ensure_glyphs ())) return false; }
- break;
case 7:
#line 66 "hb-buffer-deserialize-text.rl"
{if (!parse_hex (tok, p, &info.codepoint )) return false; }
@@ -687,7 +626,7 @@
*end_ptr = p;
}
break;
- case 21:
+ case 20:
#line 71 "hb-buffer-deserialize-text.rl"
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
#line 43 "hb-buffer-deserialize-text.rl"
@@ -699,7 +638,7 @@
*end_ptr = p;
}
break;
- case 27:
+ case 22:
#line 72 "hb-buffer-deserialize-text.rl"
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
#line 43 "hb-buffer-deserialize-text.rl"
@@ -711,7 +650,7 @@
*end_ptr = p;
}
break;
- case 24:
+ case 19:
#line 73 "hb-buffer-deserialize-text.rl"
{ if (!parse_uint (tok, p, &info.mask )) return false; }
#line 43 "hb-buffer-deserialize-text.rl"
@@ -726,8 +665,8 @@
case 12:
#line 38 "hb-buffer-deserialize-text.rl"
{
- memset (&info, 0, sizeof (info));
- memset (&pos , 0, sizeof (pos ));
+ hb_memset (&info, 0, sizeof (info));
+ hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text.rl"
{
@@ -736,11 +675,11 @@
#line 55 "hb-buffer-deserialize-text.rl"
{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
break;
- case 15:
+ case 14:
#line 38 "hb-buffer-deserialize-text.rl"
{
- memset (&info, 0, sizeof (info));
- memset (&pos , 0, sizeof (pos ));
+ hb_memset (&info, 0, sizeof (info));
+ hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text.rl"
{
@@ -755,7 +694,7 @@
return false;
}
break;
- case 18:
+ case 17:
#line 58 "hb-buffer-deserialize-text.rl"
{
/* TODO Unescape delimiters. */
@@ -775,31 +714,11 @@
*end_ptr = p;
}
break;
- case 29:
-#line 58 "hb-buffer-deserialize-text.rl"
- {
- /* TODO Unescape delimiters. */
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
-#line 73 "hb-buffer-deserialize-text.rl"
- { if (!parse_uint (tok, p, &info.mask )) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
case 11:
#line 38 "hb-buffer-deserialize-text.rl"
{
- memset (&info, 0, sizeof (info));
- memset (&pos , 0, sizeof (pos ));
+ hb_memset (&info, 0, sizeof (info));
+ hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text.rl"
{
@@ -822,54 +741,11 @@
*end_ptr = p;
}
break;
- case 14:
-#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;
-}
-#line 58 "hb-buffer-deserialize-text.rl"
- {
- /* TODO Unescape delimiters. */
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
-#line 55 "hb-buffer-deserialize-text.rl"
- { if (unlikely (!buffer->ensure_glyphs ())) return false; }
- break;
- case 30:
-#line 58 "hb-buffer-deserialize-text.rl"
- {
- /* TODO Unescape delimiters. */
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
-#line 73 "hb-buffer-deserialize-text.rl"
- { if (!parse_uint (tok, p, &info.mask )) return false; }
-#line 55 "hb-buffer-deserialize-text.rl"
- { if (unlikely (!buffer->ensure_glyphs ())) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
case 13:
#line 38 "hb-buffer-deserialize-text.rl"
{
- memset (&info, 0, sizeof (info));
- memset (&pos , 0, sizeof (pos ));
+ hb_memset (&info, 0, sizeof (info));
+ hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text.rl"
{
@@ -894,7 +770,7 @@
*end_ptr = p;
}
break;
-#line 898 "hb-buffer-deserialize-text.hh"
+#line 715 "hb-buffer-deserialize-text.hh"
}
_again:
@@ -906,7 +782,7 @@
if ( p == eof )
{
switch ( _deserialize_text_eof_actions[cs] ) {
- case 17:
+ case 16:
#line 58 "hb-buffer-deserialize-text.rl"
{
/* TODO Unescape delimiters. */
@@ -960,7 +836,7 @@
*end_ptr = p;
}
break;
- case 21:
+ case 20:
#line 71 "hb-buffer-deserialize-text.rl"
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
#line 43 "hb-buffer-deserialize-text.rl"
@@ -972,7 +848,7 @@
*end_ptr = p;
}
break;
- case 27:
+ case 22:
#line 72 "hb-buffer-deserialize-text.rl"
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
#line 43 "hb-buffer-deserialize-text.rl"
@@ -984,27 +860,7 @@
*end_ptr = p;
}
break;
- case 24:
-#line 73 "hb-buffer-deserialize-text.rl"
- { if (!parse_uint (tok, p, &info.mask )) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 29:
-#line 58 "hb-buffer-deserialize-text.rl"
- {
- /* TODO Unescape delimiters. */
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
+ case 19:
#line 73 "hb-buffer-deserialize-text.rl"
{ if (!parse_uint (tok, p, &info.mask )) return false; }
#line 43 "hb-buffer-deserialize-text.rl"
@@ -1019,8 +875,8 @@
case 11:
#line 38 "hb-buffer-deserialize-text.rl"
{
- memset (&info, 0, sizeof (info));
- memset (&pos , 0, sizeof (pos ));
+ hb_memset (&info, 0, sizeof (info));
+ hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text.rl"
{
@@ -1043,7 +899,7 @@
*end_ptr = p;
}
break;
-#line 1047 "hb-buffer-deserialize-text.hh"
+#line 825 "hb-buffer-deserialize-text.hh"
}
}
diff --git a/src/hb-buffer-deserialize-text.rl b/src/hb-buffer-deserialize-text.rl
index 0f33eb8..f82d5ab 100644
--- a/src/hb-buffer-deserialize-text.rl
+++ b/src/hb-buffer-deserialize-text.rl
@@ -36,8 +36,8 @@
write data;
action clear_item {
- memset (&info, 0, sizeof (info));
- memset (&pos , 0, sizeof (pos ));
+ hb_memset (&info, 0, sizeof (info));
+ hb_memset (&pos , 0, sizeof (pos ));
}
action add_item {
@@ -76,7 +76,7 @@
num = '-'? unum;
glyph_id = unum;
-glyph_name = ([^\\\]=@+,|] | '\\' [\\\]=@+,|]) *;
+glyph_name = ([^\\\]=@+,#|] | '\\' [\\\]=@+,|]) *;
glyph = (glyph_id | glyph_name) >tok %parse_glyph;
cluster = '=' (unum >tok %parse_cluster);
diff --git a/src/hb-buffer-serialize.cc b/src/hb-buffer-serialize.cc
index d1e1775..a458f23 100644
--- a/src/hb-buffer-serialize.cc
+++ b/src/hb-buffer-serialize.cc
@@ -183,7 +183,7 @@
unsigned int l = p - b;
if (buf_size > l)
{
- memcpy (buf, b, l);
+ hb_memcpy (buf, b, l);
buf += l;
buf_size -= l;
*buf_consumed += l;
@@ -241,7 +241,7 @@
unsigned int l = p - b;
if (buf_size > l)
{
- memcpy (buf, b, l);
+ hb_memcpy (buf, b, l);
buf += l;
buf_size -= l;
*buf_consumed += l;
@@ -329,7 +329,7 @@
unsigned int l = p - b;
if (buf_size > l)
{
- memcpy (buf, b, l);
+ hb_memcpy (buf, b, l);
buf += l;
buf_size -= l;
*buf_consumed += l;
@@ -381,7 +381,7 @@
unsigned int l = p - b;
if (buf_size > l)
{
- memcpy (buf, b, l);
+ hb_memcpy (buf, b, l);
buf += l;
buf_size -= l;
*buf_consumed += l;
diff --git a/src/hb-buffer-verify.cc b/src/hb-buffer-verify.cc
index 5453e1c..1cd52b3 100644
--- a/src/hb-buffer-verify.cc
+++ b/src/hb-buffer-verify.cc
@@ -186,7 +186,7 @@
bool ret = true;
hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
- if (diff)
+ if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
{
buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-break test failed.");
ret = false;
@@ -313,7 +313,6 @@
bool ret = true;
hb_buffer_diff_flags_t diff;
-
/*
* Shape the two fragment streams.
*/
@@ -382,7 +381,7 @@
* Diff results.
*/
diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
- if (diff)
+ if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
{
buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-concat test failed.");
ret = false;
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 57a5ae0..4b6c2d9 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -172,12 +172,13 @@
while (size >= new_allocated)
new_allocated += (new_allocated >> 1) + 32;
- static_assert ((sizeof (info[0]) == sizeof (pos[0])), "");
- if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0]))))
+ unsigned new_bytes;
+ if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0]), &new_bytes)))
goto done;
- new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_allocated * sizeof (pos[0]));
- new_info = (hb_glyph_info_t *) hb_realloc (info, new_allocated * sizeof (info[0]));
+ static_assert (sizeof (info[0]) == sizeof (pos[0]), "");
+ new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_bytes);
+ new_info = (hb_glyph_info_t *) hb_realloc (info, new_bytes);
done:
if (unlikely (!new_pos || !new_info))
@@ -208,7 +209,7 @@
assert (have_output);
out_info = (hb_glyph_info_t *) pos;
- memcpy (out_info, info, out_len * sizeof (out_info[0]));
+ hb_memcpy (out_info, info, out_len * sizeof (out_info[0]));
}
return true;
@@ -229,7 +230,7 @@
* Ideally, we should at least set Default_Ignorable bits on
* these, as well as consistent cluster values. But the former
* is layering violation... */
- memset (info + len, 0, (idx + count - len) * sizeof (info[0]));
+ hb_memset (info + len, 0, (idx + count - len) * sizeof (info[0]));
}
len += count;
idx += count;
@@ -298,8 +299,8 @@
out_len = 0;
out_info = info;
- memset (context, 0, sizeof context);
- memset (context_len, 0, sizeof context_len);
+ hb_memset (context, 0, sizeof context);
+ hb_memset (context_len, 0, sizeof context_len);
deallocate_var_all ();
serial = 0;
@@ -313,15 +314,14 @@
serial = 0;
shaping_failed = false;
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
- if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR)))
+ unsigned mul;
+ if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR, &mul)))
{
- max_len = hb_max (len * HB_BUFFER_MAX_LEN_FACTOR,
- (unsigned) HB_BUFFER_MAX_LEN_MIN);
+ max_len = hb_max (mul, (unsigned) HB_BUFFER_MAX_LEN_MIN);
}
- if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR)))
+ if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR, &mul)))
{
- max_ops = hb_max (len * HB_BUFFER_MAX_OPS_FACTOR,
- (unsigned) HB_BUFFER_MAX_OPS_MIN);
+ max_ops = hb_max (mul, (unsigned) HB_BUFFER_MAX_OPS_MIN);
}
}
void
@@ -345,7 +345,7 @@
glyph = &info[len];
- memset (glyph, 0, sizeof (*glyph));
+ hb_memset (glyph, 0, sizeof (*glyph));
glyph->codepoint = codepoint;
glyph->mask = 0;
glyph->cluster = cluster;
@@ -606,6 +606,53 @@
}
void
+hb_buffer_t::delete_glyphs_inplace (bool (*filter) (const hb_glyph_info_t *info))
+{
+ /* Merge clusters and delete filtered glyphs.
+ * NOTE! We can't use out-buffer as we have positioning data. */
+ unsigned int j = 0;
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (filter (&info[i]))
+ {
+ /* Merge clusters.
+ * Same logic as delete_glyph(), but for in-place removal. */
+
+ unsigned int cluster = info[i].cluster;
+ if (i + 1 < count && cluster == info[i + 1].cluster)
+ continue; /* Cluster survives; do nothing. */
+
+ if (j)
+ {
+ /* Merge cluster backward. */
+ if (cluster < info[j - 1].cluster)
+ {
+ unsigned int mask = info[i].mask;
+ unsigned int old_cluster = info[j - 1].cluster;
+ for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--)
+ set_cluster (info[k - 1], cluster, mask);
+ }
+ continue;
+ }
+
+ if (i + 1 < count)
+ merge_clusters (i, i + 2); /* Merge cluster forward. */
+
+ continue;
+ }
+
+ if (j != i)
+ {
+ info[j] = info[i];
+ pos[j] = pos[i];
+ }
+ j++;
+ }
+ len = j;
+}
+
+void
hb_buffer_t::guess_segment_properties ()
{
assert_unicode ();
@@ -933,7 +980,6 @@
void
hb_buffer_set_direction (hb_buffer_t *buffer,
hb_direction_t direction)
-
{
if (unlikely (hb_object_is_immutable (buffer)))
return;
@@ -1385,9 +1431,9 @@
/* Wipe the new space */
if (length > buffer->len) {
- memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
+ hb_memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
if (buffer->have_positions)
- memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
+ hb_memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
}
buffer->len = length;
@@ -1795,7 +1841,9 @@
* marks at stat of run.
*
* This function does not check the validity of @text, it is up to the caller
- * to ensure it contains a valid Unicode code points.
+ * to ensure it contains a valid Unicode scalar values. In contrast,
+ * hb_buffer_add_utf32() can be used that takes similar input but performs
+ * sanity-check on the input.
*
* Since: 0.9.31
**/
@@ -1858,9 +1906,9 @@
hb_segment_properties_overlay (&buffer->props, &source->props);
- memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
+ hb_memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
if (buffer->have_positions)
- memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
+ hb_memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
if (source->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE)
{
@@ -2048,7 +2096,7 @@
result |= HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH;
if (buf_info->cluster != ref_info->cluster)
result |= HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH;
- if ((buf_info->mask & ~ref_info->mask & HB_GLYPH_FLAG_DEFINED))
+ if ((buf_info->mask ^ ref_info->mask) & HB_GLYPH_FLAG_DEFINED)
result |= HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH;
if (contains && ref_info->codepoint == dottedcircle_glyph)
result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
@@ -2103,6 +2151,13 @@
hb_buffer_message_func_t func,
void *user_data, hb_destroy_func_t destroy)
{
+ if (unlikely (hb_object_is_immutable (buffer)))
+ {
+ if (destroy)
+ destroy (user_data);
+ return;
+ }
+
if (buffer->message_destroy)
buffer->message_destroy (buffer->message_data);
diff --git a/src/hb-buffer.hh b/src/hb-buffer.hh
index 26c3f0f..bb1efe9 100644
--- a/src/hb-buffer.hh
+++ b/src/hb-buffer.hh
@@ -32,6 +32,7 @@
#include "hb.hh"
#include "hb-unicode.hh"
+#include "hb-set-digest.hh"
#ifndef HB_BUFFER_MAX_LEN_FACTOR
@@ -207,6 +208,14 @@
hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; }
hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; }
+ hb_set_digest_t digest () const
+ {
+ hb_set_digest_t d;
+ d.init ();
+ d.add_array (&info[0].codepoint, len, sizeof (info[0]));
+ return d;
+ }
+
HB_INTERNAL void similar (const hb_buffer_t &src);
HB_INTERNAL void reset ();
HB_INTERNAL void clear ();
@@ -402,6 +411,8 @@
HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end);
/* Merge clusters for deleting current glyph, and skip it. */
HB_INTERNAL void delete_glyph ();
+ HB_INTERNAL void delete_glyphs_inplace (bool (*filter) (const hb_glyph_info_t *info));
+
/* Adds glyph flags in mask to infos with clusters between start and end.
diff --git a/src/hb-cache.hh b/src/hb-cache.hh
index 897f313..f8c8108 100644
--- a/src/hb-cache.hh
+++ b/src/hb-cache.hh
@@ -46,7 +46,7 @@
>::type;
static_assert ((key_bits >= cache_bits), "");
- static_assert ((key_bits + value_bits - cache_bits <= 8 * sizeof (item_t)), "");
+ static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), "");
void init () { clear (); }
void fini () {}
diff --git a/src/hb-cff-interp-common.hh b/src/hb-cff-interp-common.hh
index 5c2cb06..49805a8 100644
--- a/src/hb-cff-interp-common.hh
+++ b/src/hb-cff-interp-common.hh
@@ -284,65 +284,56 @@
/* A byte string associated with the current offset and an error condition */
struct byte_str_ref_t
{
- byte_str_ref_t () { init (); }
-
- void init ()
- {
- str = hb_ubytes_t ();
- offset = 0;
- error = false;
- }
-
- void fini () {}
+ byte_str_ref_t ()
+ : str () {}
byte_str_ref_t (const hb_ubytes_t &str_, unsigned int offset_ = 0)
- : str (str_), offset (offset_), error (false) {}
+ : str (str_) { set_offset (offset_); }
void reset (const hb_ubytes_t &str_, unsigned int offset_ = 0)
{
str = str_;
- offset = offset_;
- error = false;
+ set_offset (offset_);
}
const unsigned char& operator [] (int i) {
- if (unlikely ((unsigned int) (offset + i) >= str.length))
+ if (unlikely ((unsigned int) (get_offset () + i) >= str.length))
{
set_error ();
return Null (unsigned char);
}
- return str[offset + i];
+ return str.arrayZ[get_offset () + i];
}
+ unsigned char head_unchecked () const { return str.arrayZ[get_offset ()]; }
+
/* Conversion to hb_ubytes_t */
- operator hb_ubytes_t () const { return str.sub_array (offset, str.length - offset); }
+ operator hb_ubytes_t () const { return str.sub_array (get_offset ()); }
hb_ubytes_t sub_array (unsigned int offset_, unsigned int len_) const
{ return str.sub_array (offset_, len_); }
bool avail (unsigned int count=1) const
- { return (!in_error () && offset + count <= str.length); }
+ { return get_offset () + count <= str.length; }
void inc (unsigned int count=1)
{
- if (likely (!in_error () && (offset <= str.length) && (offset + count <= str.length)))
- {
- offset += count;
- }
- else
- {
- offset = str.length;
- set_error ();
- }
+ /* Automatically puts us in error if count is out-of-range. */
+ set_offset (get_offset () + count);
}
- void set_error () { error = true; }
- bool in_error () const { return error; }
+ /* We (ab)use ubytes backwards_length as a cursor (called offset),
+ * as well as to store error condition. */
- hb_ubytes_t str;
- unsigned int offset; /* beginning of the sub-string within str */
+ unsigned get_offset () const { return str.backwards_length; }
+ void set_offset (unsigned offset) { str.backwards_length = offset; }
+
+ void set_error () { str.backwards_length = str.length + 1; }
+ bool in_error () const { return str.backwards_length > str.length; }
+
+ unsigned total_size () const { return str.length; }
protected:
- bool error;
+ hb_ubytes_t str;
};
using byte_str_array_t = hb_vector_t<hb_ubytes_t>;
@@ -491,8 +482,15 @@
/* an operator prefixed by its operands in a byte string */
struct op_str_t
{
- hb_ubytes_t str;
+ /* This used to have a hb_ubytes_t. Using a pointer and length
+ * in a particular order, saves 8 bytes in this struct and more
+ * in our parsed_cs_op_t subclass. */
+
+ const unsigned char *ptr = nullptr;
+
op_code_t op;
+
+ uint8_t length = 0;
};
/* base of OP_SERIALIZER */
@@ -503,9 +501,11 @@
{
TRACE_SERIALIZE (this);
- HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length);
+ unsigned char *d = c->allocate_size<unsigned char> (opstr.length);
if (unlikely (!d)) return_trace (false);
- memcpy (d, &opstr.str[0], opstr.str.length);
+ /* Faster than hb_memcpy for small strings. */
+ for (unsigned i = 0; i < opstr.length; i++)
+ d[i] = opstr.ptr[i];
return_trace (true);
}
};
@@ -529,16 +529,20 @@
{
VAL *val = values.push ();
val->op = op;
- val->str = str_ref.str.sub_array (opStart, str_ref.offset - opStart);
- opStart = str_ref.offset;
+ auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart);
+ val->ptr = arr.arrayZ;
+ val->length = arr.length;
+ opStart = str_ref.get_offset ();
}
void add_op (op_code_t op, const byte_str_ref_t& str_ref, const VAL &v)
{
VAL *val = values.push (v);
val->op = op;
- val->str = str_ref.sub_array ( opStart, str_ref.offset - opStart);
- opStart = str_ref.offset;
+ auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart);
+ val->ptr = arr.arrayZ;
+ val->length = arr.length;
+ opStart = str_ref.get_offset ();
}
bool has_op (op_code_t op) const
@@ -549,8 +553,7 @@
}
unsigned get_count () const { return values.length; }
- const VAL &get_value (unsigned int i) const { return values[i]; }
- const VAL &operator [] (unsigned int i) const { return get_value (i); }
+ const VAL &operator [] (unsigned int i) const { return values[i]; }
unsigned int opStart;
hb_vector_t<VAL> values;
@@ -565,23 +568,23 @@
str_ref.reset (str_);
}
bool in_error () const
- { return error || str_ref.in_error () || argStack.in_error (); }
+ { return str_ref.in_error () || argStack.in_error (); }
- void set_error () { error = true; }
+ void set_error () { str_ref.set_error (); }
op_code_t fetch_op ()
{
op_code_t op = OpCode_Invalid;
if (unlikely (!str_ref.avail ()))
return OpCode_Invalid;
- op = (op_code_t)(unsigned char)str_ref[0];
+ op = (op_code_t) str_ref.head_unchecked ();
+ str_ref.inc ();
if (op == OpCode_escape) {
if (unlikely (!str_ref.avail ()))
return OpCode_Invalid;
- op = Make_OpCode_ESC(str_ref[1]);
+ op = Make_OpCode_ESC (str_ref.head_unchecked ());
str_ref.inc ();
}
- str_ref.inc ();
return op;
}
@@ -596,8 +599,6 @@
str_ref;
arg_stack_t<ARG>
argStack;
- protected:
- bool error = false;
};
using num_interp_env_t = interp_env_t<>;
diff --git a/src/hb-cff2-interp-cs.hh b/src/hb-cff2-interp-cs.hh
index d0b9e7b..00c2580 100644
--- a/src/hb-cff2-interp-cs.hh
+++ b/src/hb-cff2-interp-cs.hh
@@ -40,13 +40,15 @@
void set_real (double v) { reset_blends (); number_t::set_real (v); }
void set_blends (unsigned int numValues_, unsigned int valueIndex_,
- unsigned int numBlends, hb_array_t<const blend_arg_t> blends_)
+ hb_array_t<const blend_arg_t> blends_)
{
numValues = numValues_;
valueIndex = valueIndex_;
- deltas.resize (numBlends);
+ unsigned numBlends = blends_.length;
+ if (unlikely (!deltas.resize (numBlends)))
+ return;
for (unsigned int i = 0; i < numBlends; i++)
- deltas[i] = blends_[i];
+ deltas.arrayZ[i] = blends_.arrayZ[i];
}
bool blending () const { return deltas.length > 0; }
@@ -61,7 +63,6 @@
hb_vector_t<number_t> deltas;
};
-typedef interp_env_t<blend_arg_t> BlendInterpEnv;
typedef biased_subrs_t<CFF2Subrs> cff2_biased_subrs_t;
template <typename ELEM>
@@ -154,8 +155,9 @@
{
if (likely (scalars.length == deltas.length))
{
- for (unsigned int i = 0; i < scalars.length; i++)
- v += (double) scalars[i] * deltas[i].to_real ();
+ unsigned count = scalars.length;
+ for (unsigned i = 0; i < count; i++)
+ v += (double) scalars.arrayZ[i] * deltas.arrayZ[i].to_real ();
}
}
return v;
@@ -220,7 +222,7 @@
const hb_array_t<const ELEM> blends,
unsigned n, unsigned i)
{
- arg.set_blends (n, i, blends.length, blends);
+ arg.set_blends (n, i, blends);
}
template <typename T = ELEM,
hb_enable_if (!hb_is_same (T, blend_arg_t))>
diff --git a/src/hb-common.cc b/src/hb-common.cc
index bbb6cd5..e9f9cfe 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -285,7 +285,7 @@
lang = (hb_language_t) hb_malloc(len);
if (likely (lang))
{
- memcpy((unsigned char *) lang, s, len);
+ hb_memcpy((unsigned char *) lang, s, len);
for (unsigned char *p = (unsigned char *) lang; *p; p++)
*p = canon_map[*p];
}
@@ -379,7 +379,7 @@
/* NUL-terminate it. */
char strbuf[64];
len = hb_min (len, (int) sizeof (strbuf) - 1);
- memcpy (strbuf, str, len);
+ hb_memcpy (strbuf, str, len);
strbuf[len] = '\0';
item = lang_find_or_insert (strbuf);
}
@@ -976,7 +976,7 @@
}
if (feature)
- memset (feature, 0, sizeof (*feature));
+ hb_memset (feature, 0, sizeof (*feature));
return false;
}
@@ -1025,7 +1025,7 @@
}
assert (len < ARRAY_LENGTH (s));
len = hb_min (len, size - 1);
- memcpy (buf, s, len);
+ hb_memcpy (buf, s, len);
buf[len] = '\0';
}
@@ -1088,7 +1088,7 @@
}
if (variation)
- memset (variation, 0, sizeof (*variation));
+ hb_memset (variation, 0, sizeof (*variation));
return false;
}
@@ -1136,7 +1136,7 @@
/**
* hb_variation_to_string:
* @variation: an #hb_variation_t to convert
- * @buf: (array length=size) (out): output string
+ * @buf: (array length=size) (out caller-allocates): output string
* @size: the allocated size of @buf
*
* Converts an #hb_variation_t into a `NULL`-terminated string in the format
@@ -1166,7 +1166,7 @@
assert (len < ARRAY_LENGTH (s));
len = hb_min (len, size - 1);
- memcpy (buf, s, len);
+ hb_memcpy (buf, s, len);
buf[len] = '\0';
}
diff --git a/src/hb-config.hh b/src/hb-config.hh
index d56617f..98b1e9d 100644
--- a/src/hb-config.hh
+++ b/src/hb-config.hh
@@ -35,8 +35,9 @@
#include "config.h"
#endif
-#ifndef HB_BORING_EXPANSION
-#define HB_NO_BORING_EXPANSION
+#ifndef HB_EXPERIMENTAL_API
+#define HB_NO_BEYOND_64K
+#define HB_NO_VAR_COMPOSITES
#endif
#ifdef HB_TINY
@@ -84,6 +85,7 @@
#define HB_NO_OT_SHAPE_FRACTIONS
#define HB_NO_STYLE
#define HB_NO_SUBSET_LAYOUT
+#define HB_NO_VERTICAL
#define HB_NO_VAR
#endif
@@ -104,7 +106,7 @@
#ifdef HB_NO_BORING_EXPANSION
#define HB_NO_BEYOND_64K
-#define HB_NO_VARIATIONS2
+#define HB_NO_AVAR2
#endif
#ifdef HB_DISABLE_DEPRECATED
@@ -113,6 +115,11 @@
#define HB_IF_NOT_DEPRECATED(x) x
#endif
+#ifdef HB_NO_SHAPER
+#define HB_NO_OT_SHAPE
+#define HB_NO_AAT_SHAPE
+#endif
+
#ifdef HB_NO_AAT
#define HB_NO_OT_NAME_LANGUAGE_AAT
#define HB_NO_AAT_SHAPE
@@ -159,6 +166,7 @@
#define HB_NO_OT_SHAPER_HEBREW_FALLBACK
#define HB_NO_OT_SHAPER_THAI_FALLBACK
#define HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS
+#define HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
#endif
#ifdef NDEBUG
diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc
index 99b33c0..4267e0e 100644
--- a/src/hb-coretext.cc
+++ b/src/hb-coretext.cc
@@ -347,10 +347,13 @@
hb_ot_var_axis_info_t info;
unsigned int c = 1;
hb_ot_var_get_axis_infos (font->face, i, &c, &info);
- CFDictionarySetValue (variations,
- CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag),
- CFNumberCreate (kCFAllocatorDefault, kCFNumberFloatType, &font->design_coords[i])
- );
+ float v = hb_clamp (font->design_coords[i], info.min_value, info.max_value);
+
+ CFNumberRef tag_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag);
+ CFNumberRef value_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberFloatType, &v);
+ CFDictionarySetValue (variations, tag_number, value_number);
+ CFRelease (tag_number);
+ CFRelease (value_number);
}
CFDictionaryRef attributes =
@@ -648,7 +651,7 @@
} else {
active_feature_t *feature = active_features.lsearch (event->feature);
if (feature)
- active_features.remove (feature - active_features.arrayZ);
+ active_features.remove_ordered (feature - active_features.arrayZ);
}
}
}
diff --git a/src/hb-draw.cc b/src/hb-draw.cc
index 46797e6..72c203f 100644
--- a/src/hb-draw.cc
+++ b/src/hb-draw.cc
@@ -80,6 +80,56 @@
void *user_data HB_UNUSED) {}
+static bool
+_hb_draw_funcs_set_preamble (hb_draw_funcs_t *dfuncs,
+ bool func_is_null,
+ void **user_data,
+ hb_destroy_func_t *destroy)
+{
+ if (hb_object_is_immutable (dfuncs))
+ {
+ if (*destroy)
+ (*destroy) (*user_data);
+ return false;
+ }
+
+ if (func_is_null)
+ {
+ if (*destroy)
+ (*destroy) (*user_data);
+ *destroy = nullptr;
+ *user_data = nullptr;
+ }
+
+ return true;
+}
+
+static bool
+_hb_draw_funcs_set_middle (hb_draw_funcs_t *dfuncs,
+ void *user_data,
+ hb_destroy_func_t destroy)
+{
+ if (user_data && !dfuncs->user_data)
+ {
+ dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data));
+ if (unlikely (!dfuncs->user_data))
+ goto fail;
+ }
+ if (destroy && !dfuncs->destroy)
+ {
+ dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy));
+ if (unlikely (!dfuncs->destroy))
+ goto fail;
+ }
+
+ return true;
+
+fail:
+ if (destroy)
+ (destroy) (user_data);
+ return false;
+}
+
#define HB_DRAW_FUNC_IMPLEMENT(name) \
\
void \
@@ -88,43 +138,24 @@
void *user_data, \
hb_destroy_func_t destroy) \
{ \
- if (hb_object_is_immutable (dfuncs)) \
- return; \
+ if (!_hb_draw_funcs_set_preamble (dfuncs, !func, &user_data, &destroy))\
+ return; \
\
if (dfuncs->destroy && dfuncs->destroy->name) \
dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name); \
\
- if (user_data && !dfuncs->user_data) \
- { \
- dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data)); \
- if (unlikely (!dfuncs->user_data)) \
- goto fail; \
- } \
- if (destroy && !dfuncs->destroy) \
- { \
- dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy)); \
- if (unlikely (!dfuncs->destroy)) \
- goto fail; \
- } \
+ if (!_hb_draw_funcs_set_middle (dfuncs, user_data, destroy)) \
+ return; \
\
- if (func) { \
+ if (func) \
dfuncs->func.name = func; \
- if (dfuncs->user_data) \
- dfuncs->user_data->name = user_data; \
- if (dfuncs->destroy) \
- dfuncs->destroy->name = destroy; \
- } else { \
+ else \
dfuncs->func.name = hb_draw_##name##_nil; \
- if (dfuncs->user_data) \
- dfuncs->user_data->name = nullptr; \
- if (dfuncs->destroy) \
- dfuncs->destroy->name = nullptr; \
- } \
- return; \
- \
-fail: \
- if (destroy) \
- destroy (user_data); \
+ \
+ if (dfuncs->user_data) \
+ dfuncs->user_data->name = user_data; \
+ if (dfuncs->destroy) \
+ dfuncs->destroy->name = destroy; \
}
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
diff --git a/src/hb-face.cc b/src/hb-face.cc
index e7deb31..8b4b635 100644
--- a/src/hb-face.cc
+++ b/src/hb-face.cc
@@ -288,6 +288,7 @@
{
if (!hb_object_destroy (face)) return;
+#ifndef HB_NO_SHAPER
for (hb_face_t::plan_node_t *node = face->shape_plans; node; )
{
hb_face_t::plan_node_t *next = node->next;
@@ -295,6 +296,7 @@
hb_free (node);
node = next;
}
+#endif
face->data.fini ();
face->table.fini ();
@@ -636,7 +638,7 @@
struct face_table_info_t
{
hb_blob_t* data;
- unsigned order;
+ signed order;
};
struct hb_face_builder_data_t
@@ -784,16 +786,16 @@
hb_bool_t
hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
{
- if (tag == HB_MAP_VALUE_INVALID)
+ if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy))
return false;
- if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy))
+ if (tag == HB_MAP_VALUE_INVALID)
return false;
hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
hb_blob_t* previous = data->tables.get (tag).data;
- if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), 0}))
+ if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), -1}))
{
hb_blob_destroy (blob);
return false;
@@ -819,13 +821,16 @@
hb_face_builder_sort_tables (hb_face_t *face,
const hb_tag_t *tags)
{
+ if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy))
+ return;
+
hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
// Sort all unspecified tables after any specified tables.
for (auto& info : data->tables.values_ref())
- info.order = -1;
+ info.order = (unsigned) -1;
- unsigned order = 0;
+ signed order = 0;
for (const hb_tag_t* tag = tags;
*tag;
tag++)
diff --git a/src/hb-face.hh b/src/hb-face.hh
index 12e10d0..1bf0606 100644
--- a/src/hb-face.hh
+++ b/src/hb-face.hh
@@ -65,7 +65,9 @@
hb_shape_plan_t *shape_plan;
plan_node_t *next;
};
+#ifndef HB_NO_SHAPER
hb_atomic_ptr_t<plan_node_t> shape_plans;
+#endif
hb_blob_t *reference_table (hb_tag_t tag) const
{
diff --git a/src/hb-fallback-shape.cc b/src/hb-fallback-shape.cc
index f8524ec..c54ad87 100644
--- a/src/hb-fallback-shape.cc
+++ b/src/hb-fallback-shape.cc
@@ -75,16 +75,6 @@
const hb_feature_t *features HB_UNUSED,
unsigned int num_features HB_UNUSED)
{
- /* TODO
- *
- * - Apply fallback kern.
- * - Handle Variation Selectors?
- * - Apply normalization?
- *
- * This will make the fallback shaper into a dumb "TrueType"
- * shaper which many people unfortunately still request.
- */
-
hb_codepoint_t space;
bool has_space = (bool) font->get_nominal_glyph (' ', &space);
diff --git a/src/hb-features.h.in b/src/hb-features.h.in
new file mode 100644
index 0000000..30ebf65
--- /dev/null
+++ b/src/hb-features.h.in
@@ -0,0 +1,96 @@
+/*
+ * Copyright © 2022 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.
+ */
+
+#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_FEATURES_H
+#define HB_FEATURES_H
+
+#include "hb-common.h"
+
+HB_BEGIN_DECLS
+
+
+/**
+ * HB_HAS_FREETYPE:
+ *
+ * Defined if Harfbuzz has been built with Freetype support.
+ */
+#mesondefine HB_HAS_FREETYPE
+
+/**
+ * HB_HAS_GDI:
+ *
+ * Defined if Harfbuzz has been built with GDI support.
+ */
+#mesondefine HB_HAS_GDI
+
+/**
+ * HB_HAS_GRAPHITE:
+ *
+ * Defined if Harfbuzz has been built with Graphite support.
+ */
+#mesondefine HB_HAS_GRAPHITE
+
+/**
+ * HB_HAS_GLIB:
+ *
+ * Defined if Harfbuzz has been built with GLib support.
+ */
+#mesondefine HB_HAS_GLIB
+
+/**
+ * HB_HAS_UNISCRIBE:
+ *
+ * Defined if Harfbuzz has been built with Uniscribe support.
+ */
+#mesondefine HB_HAS_UNISCRIBE
+
+/**
+ * HB_HAS_DIRECTWRITE:
+ *
+ * Defined if Harfbuzz has been built with DirectWrite support.
+ */
+#mesondefine HB_HAS_DIRECTWRITE
+
+/**
+ * HB_HAS_CORETEXT:
+ *
+ * Defined if Harfbuzz has been built with CoreText support.
+ */
+#mesondefine HB_HAS_CORETEXT
+
+/**
+ * HB_HAS_ICU:
+ *
+ * Defined if Harfbuzz has been built with ICU support.
+ */
+#mesondefine HB_HAS_ICU
+
+
+HB_END_DECLS
+
+#endif /* HB_FEATURES_H */
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 856bbdd..0ce3e26 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -71,7 +71,7 @@
hb_font_extents_t *extents,
void *user_data HB_UNUSED)
{
- memset (extents, 0, sizeof (*extents));
+ hb_memset (extents, 0, sizeof (*extents));
return false;
}
@@ -96,7 +96,7 @@
hb_font_extents_t *extents,
void *user_data HB_UNUSED)
{
- memset (extents, 0, sizeof (*extents));
+ hb_memset (extents, 0, sizeof (*extents));
return false;
}
@@ -409,7 +409,7 @@
hb_glyph_extents_t *extents,
void *user_data HB_UNUSED)
{
- memset (extents, 0, sizeof (*extents));
+ hb_memset (extents, 0, sizeof (*extents));
return false;
}
@@ -518,6 +518,7 @@
void *draw_data;
float x_scale;
float y_scale;
+ float slant;
} hb_font_get_glyph_shape_default_adaptor_t;
static void
@@ -530,9 +531,10 @@
hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
float x_scale = adaptor->x_scale;
float y_scale = adaptor->y_scale;
+ float slant = adaptor->slant;
adaptor->draw_funcs->emit_move_to (adaptor->draw_data, *st,
- x_scale * to_x, y_scale * to_y);
+ x_scale * to_x + slant * to_y, y_scale * to_y);
}
static void
@@ -544,12 +546,13 @@
hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
float x_scale = adaptor->x_scale;
float y_scale = adaptor->y_scale;
+ float slant = adaptor->slant;
- st->current_x *= x_scale;
- st->current_y *= y_scale;
+ st->current_x = st->current_x * x_scale + st->current_y * slant;
+ st->current_y = st->current_y * y_scale;
adaptor->draw_funcs->emit_line_to (adaptor->draw_data, *st,
- x_scale * to_x, y_scale * to_y);
+ x_scale * to_x + slant * to_y, y_scale * to_y);
}
static void
@@ -562,13 +565,14 @@
hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
float x_scale = adaptor->x_scale;
float y_scale = adaptor->y_scale;
+ float slant = adaptor->slant;
- st->current_x *= x_scale;
- st->current_y *= y_scale;
+ st->current_x = st->current_x * x_scale + st->current_y * slant;
+ st->current_y = st->current_y * y_scale;
adaptor->draw_funcs->emit_quadratic_to (adaptor->draw_data, *st,
- x_scale * control_x, y_scale * control_y,
- x_scale * to_x, y_scale * to_y);
+ x_scale * control_x + slant * control_y, y_scale * control_y,
+ x_scale * to_x + slant * to_y, y_scale * to_y);
}
static void
@@ -582,14 +586,15 @@
hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
float x_scale = adaptor->x_scale;
float y_scale = adaptor->y_scale;
+ float slant = adaptor->slant;
- st->current_x *= x_scale;
- st->current_y *= y_scale;
+ st->current_x = st->current_x * x_scale + st->current_y * slant;
+ st->current_y = st->current_y * y_scale;
adaptor->draw_funcs->emit_cubic_to (adaptor->draw_data, *st,
- x_scale * control1_x, y_scale * control1_y,
- x_scale * control2_x, y_scale * control2_y,
- x_scale * to_x, y_scale * to_y);
+ x_scale * control1_x + slant * control1_y, y_scale * control1_y,
+ x_scale * control2_x + slant * control2_y, y_scale * control2_y,
+ x_scale * to_x + slant * to_y, y_scale * to_y);
}
static void
@@ -623,8 +628,10 @@
hb_font_get_glyph_shape_default_adaptor_t adaptor = {
draw_funcs,
draw_data,
- (float) font->x_scale / (float) font->parent->x_scale,
- (float) font->y_scale / (float) font->parent->y_scale
+ font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f,
+ font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f,
+ font->parent->y_scale ? (font->slant - font->parent->slant) *
+ (float) font->x_scale / (float) font->parent->y_scale : 0.f
};
font->parent->get_glyph_shape (glyph,
@@ -822,6 +829,56 @@
}
+static bool
+_hb_font_funcs_set_preamble (hb_font_funcs_t *ffuncs,
+ bool func_is_null,
+ void **user_data,
+ hb_destroy_func_t *destroy)
+{
+ if (hb_object_is_immutable (ffuncs))
+ {
+ if (*destroy)
+ (*destroy) (*user_data);
+ return false;
+ }
+
+ if (func_is_null)
+ {
+ if (*destroy)
+ (*destroy) (*user_data);
+ *destroy = nullptr;
+ *user_data = nullptr;
+ }
+
+ return true;
+}
+
+static bool
+_hb_font_funcs_set_middle (hb_font_funcs_t *ffuncs,
+ void *user_data,
+ hb_destroy_func_t destroy)
+{
+ if (user_data && !ffuncs->user_data)
+ {
+ ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data));
+ if (unlikely (!ffuncs->user_data))
+ goto fail;
+ }
+ if (destroy && !ffuncs->destroy)
+ {
+ ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy));
+ if (unlikely (!ffuncs->destroy))
+ goto fail;
+ }
+
+ return true;
+
+fail:
+ if (destroy)
+ (destroy) (user_data);
+ return false;
+}
+
#define HB_FONT_FUNC_IMPLEMENT(name) \
\
void \
@@ -830,51 +887,24 @@
void *user_data, \
hb_destroy_func_t destroy) \
{ \
- if (hb_object_is_immutable (ffuncs)) \
- goto fail; \
- \
- if (!func) \
- { \
- if (destroy) \
- destroy (user_data); \
- destroy = nullptr; \
- user_data = nullptr; \
- } \
+ if (!_hb_font_funcs_set_preamble (ffuncs, !func, &user_data, &destroy))\
+ return; \
\
if (ffuncs->destroy && ffuncs->destroy->name) \
ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); \
\
- if (user_data && !ffuncs->user_data) \
- { \
- ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data)); \
- if (unlikely (!ffuncs->user_data)) \
- goto fail; \
- } \
- if (destroy && !ffuncs->destroy) \
- { \
- ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy)); \
- if (unlikely (!ffuncs->destroy)) \
- goto fail; \
- } \
+ if (!_hb_font_funcs_set_middle (ffuncs, user_data, destroy)) \
+ return; \
\
- if (func) { \
+ if (func) \
ffuncs->get.f.name = func; \
- if (ffuncs->user_data) \
- ffuncs->user_data->name = user_data; \
- if (ffuncs->destroy) \
- ffuncs->destroy->name = destroy; \
- } else { \
+ else \
ffuncs->get.f.name = hb_font_get_##name##_default; \
- if (ffuncs->user_data) \
- ffuncs->user_data->name = nullptr; \
- if (ffuncs->destroy) \
- ffuncs->destroy->name = nullptr; \
- } \
- return; \
- \
-fail: \
- if (destroy) \
- destroy (user_data); \
+ \
+ if (ffuncs->user_data) \
+ ffuncs->user_data->name = user_data; \
+ if (ffuncs->destroy) \
+ ffuncs->destroy->name = destroy; \
}
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
@@ -1323,7 +1353,7 @@
* @draw_data: User data to pass to draw callbacks
*
* Fetches the glyph shape that corresponds to a glyph in the specified @font.
- * The shape is returned by way of calls to the callsbacks of the @dfuncs
+ * The shape is returned by way of calls to the callbacks of the @dfuncs
* objects, with @draw_data passed to them.
*
* Since: 4.0.0
@@ -1780,8 +1810,8 @@
float *design_coords = (float *) hb_calloc (num_coords, sizeof (parent->design_coords[0]));
if (likely (coords && design_coords))
{
- memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0]));
- memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0]));
+ hb_memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0]));
+ hb_memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0]));
_hb_font_adopt_var_coords (font, coords, design_coords, num_coords);
}
else
@@ -2443,7 +2473,7 @@
}
if (coords_length)
- memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0]));
+ hb_memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0]));
hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
_hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
@@ -2519,8 +2549,8 @@
if (coords_length)
{
- memcpy (copy, coords, coords_length * sizeof (coords[0]));
- memcpy (unmapped, coords, coords_length * sizeof (coords[0]));
+ hb_memcpy (copy, coords, coords_length * sizeof (coords[0]));
+ hb_memcpy (unmapped, coords, coords_length * sizeof (coords[0]));
}
/* Best effort design coords simulation */
diff --git a/src/hb-font.hh b/src/hb-font.hh
index bb402e2..6942d99 100644
--- a/src/hb-font.hh
+++ b/src/hb-font.hh
@@ -206,14 +206,14 @@
hb_bool_t get_font_h_extents (hb_font_extents_t *extents)
{
- memset (extents, 0, sizeof (*extents));
+ hb_memset (extents, 0, sizeof (*extents));
return klass->get.f.font_h_extents (this, user_data,
extents,
!klass->user_data ? nullptr : klass->user_data->font_h_extents);
}
hb_bool_t get_font_v_extents (hb_font_extents_t *extents)
{
- memset (extents, 0, sizeof (*extents));
+ hb_memset (extents, 0, sizeof (*extents));
return klass->get.f.font_v_extents (this, user_data,
extents,
!klass->user_data ? nullptr : klass->user_data->font_v_extents);
@@ -342,7 +342,7 @@
hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
hb_glyph_extents_t *extents)
{
- memset (extents, 0, sizeof (*extents));
+ hb_memset (extents, 0, sizeof (*extents));
return klass->get.f.glyph_extents (this, user_data,
glyph,
extents,
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index bcc1dd0..3892ded 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -89,7 +89,7 @@
bool unref; /* Whether to destroy ft_face when done. */
bool transform; /* Whether to apply FT_Face's transform. */
- mutable hb_mutex_t lock;
+ mutable hb_mutex_t lock; /* Protects members below. */
FT_Face ft_face;
mutable unsigned cached_serial;
mutable hb_ft_advance_cache_t advance_cache;
@@ -732,16 +732,18 @@
static int
_hb_ft_move_to (const FT_Vector *to,
- hb_draw_session_t *drawing)
+ void *arg)
{
+ hb_draw_session_t *drawing = (hb_draw_session_t *) arg;
drawing->move_to (to->x, to->y);
return FT_Err_Ok;
}
static int
_hb_ft_line_to (const FT_Vector *to,
- hb_draw_session_t *drawing)
+ void *arg)
{
+ hb_draw_session_t *drawing = (hb_draw_session_t *) arg;
drawing->line_to (to->x, to->y);
return FT_Err_Ok;
}
@@ -749,8 +751,9 @@
static int
_hb_ft_conic_to (const FT_Vector *control,
const FT_Vector *to,
- hb_draw_session_t *drawing)
+ void *arg)
{
+ hb_draw_session_t *drawing = (hb_draw_session_t *) arg;
drawing->quadratic_to (control->x, control->y,
to->x, to->y);
return FT_Err_Ok;
@@ -760,8 +763,9 @@
_hb_ft_cubic_to (const FT_Vector *control1,
const FT_Vector *control2,
const FT_Vector *to,
- hb_draw_session_t *drawing)
+ void *arg)
{
+ hb_draw_session_t *drawing = (hb_draw_session_t *) arg;
drawing->cubic_to (control1->x, control1->y,
control2->x, control2->y,
to->x, to->y);
@@ -787,10 +791,10 @@
return;
const FT_Outline_Funcs outline_funcs = {
- (FT_Outline_MoveToFunc) _hb_ft_move_to,
- (FT_Outline_LineToFunc) _hb_ft_line_to,
- (FT_Outline_ConicToFunc) _hb_ft_conic_to,
- (FT_Outline_CubicToFunc) _hb_ft_cubic_to,
+ _hb_ft_move_to,
+ _hb_ft_line_to,
+ _hb_ft_conic_to,
+ _hb_ft_cubic_to,
0, /* shift */
0, /* delta */
};
@@ -975,8 +979,9 @@
}
static void
-hb_ft_face_finalize (FT_Face ft_face)
+hb_ft_face_finalize (void *arg)
{
+ FT_Face ft_face = (FT_Face) arg;
hb_face_destroy ((hb_face_t *) ft_face->generic.data);
}
@@ -1008,7 +1013,7 @@
ft_face->generic.finalizer (ft_face);
ft_face->generic.data = hb_ft_face_create (ft_face, nullptr);
- ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize;
+ ft_face->generic.finalizer = hb_ft_face_finalize;
}
return hb_face_reference ((hb_face_t *) ft_face->generic.data);
@@ -1217,8 +1222,9 @@
}
static void
-_release_blob (FT_Face ft_face)
+_release_blob (void *arg)
{
+ FT_Face ft_face = (FT_Face) arg;
hb_blob_destroy ((hb_blob_t *) ft_face->generic.data);
}
@@ -1271,7 +1277,7 @@
ft_face->generic.data = blob;
- ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;
+ ft_face->generic.finalizer = _release_blob;
_hb_ft_font_set_funcs (font, ft_face, true);
hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING);
diff --git a/src/hb-glib.cc b/src/hb-glib.cc
index 8ddc7eb..1da8169 100644
--- a/src/hb-glib.cc
+++ b/src/hb-glib.cc
@@ -129,32 +129,9 @@
{
#if GLIB_CHECK_VERSION(2,29,12)
return g_unichar_compose (a, b, ab);
+#else
+ return false;
#endif
-
- /* We don't ifdef-out the fallback code such that compiler always
- * sees it and makes sure it's compilable. */
-
- gchar utf8[12];
- gchar *normalized;
- int len;
- hb_bool_t ret;
-
- len = g_unichar_to_utf8 (a, utf8);
- len += g_unichar_to_utf8 (b, utf8 + len);
- normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFC);
- len = g_utf8_strlen (normalized, -1);
- if (unlikely (!len))
- return false;
-
- if (len == 1) {
- *ab = g_utf8_get_char (normalized);
- ret = true;
- } else {
- ret = false;
- }
-
- g_free (normalized);
- return ret;
}
static hb_bool_t
@@ -166,55 +143,9 @@
{
#if GLIB_CHECK_VERSION(2,29,12)
return g_unichar_decompose (ab, a, b);
+#else
+ return false;
#endif
-
- /* We don't ifdef-out the fallback code such that compiler always
- * sees it and makes sure it's compilable. */
-
- gchar utf8[6];
- gchar *normalized;
- int len;
- hb_bool_t ret;
-
- len = g_unichar_to_utf8 (ab, utf8);
- normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFD);
- len = g_utf8_strlen (normalized, -1);
- if (unlikely (!len))
- return false;
-
- if (len == 1) {
- *a = g_utf8_get_char (normalized);
- *b = 0;
- ret = *a != ab;
- } else if (len == 2) {
- *a = g_utf8_get_char (normalized);
- *b = g_utf8_get_char (g_utf8_next_char (normalized));
- /* Here's the ugly part: if ab decomposes to a single character and
- * that character decomposes again, we have to detect that and undo
- * the second part :-(. */
- gchar *recomposed = g_utf8_normalize (normalized, -1, G_NORMALIZE_NFC);
- hb_codepoint_t c = g_utf8_get_char (recomposed);
- if (c != ab && c != *a) {
- *a = c;
- *b = 0;
- }
- g_free (recomposed);
- ret = true;
- } else {
- /* If decomposed to more than two characters, take the last one,
- * and recompose the rest to get the first component. */
- gchar *end = g_utf8_offset_to_pointer (normalized, len - 1);
- gchar *recomposed;
- *b = g_utf8_get_char (end);
- recomposed = g_utf8_normalize (normalized, end - normalized, G_NORMALIZE_NFC);
- /* We expect that recomposed has exactly one character now. */
- *a = g_utf8_get_char (recomposed);
- g_free (recomposed);
- ret = true;
- }
-
- g_free (normalized);
- return ret;
}
diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc
index 4d0e687..9e068f8 100644
--- a/src/hb-graphite2.cc
+++ b/src/hb-graphite2.cc
@@ -318,7 +318,7 @@
#undef ALLOCATE_ARRAY
- memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
+ hb_memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
hb_codepoint_t *pg = gids;
clusters[0].cluster = buffer->info[0].cluster;
diff --git a/src/hb-iter.hh b/src/hb-iter.hh
index 1a3ab43..b57f37b 100644
--- a/src/hb-iter.hh
+++ b/src/hb-iter.hh
@@ -73,8 +73,10 @@
/* Operators. */
iter_t iter () const { return *thiz(); }
iter_t operator + () const { return *thiz(); }
- iter_t begin () const { return *thiz(); }
- iter_t end () const { return thiz()->__end__ (); }
+ iter_t _begin () const { return *thiz(); }
+ iter_t begin () const { return _begin (); }
+ iter_t _end () const { return thiz()->__end__ (); }
+ iter_t end () const { return _end (); }
explicit operator bool () const { return thiz()->__more__ (); }
unsigned len () const { return thiz()->__len__ (); }
/* The following can only be enabled if item_t is reference type. Otherwise
@@ -118,7 +120,9 @@
#define HB_ITER_USING(Name) \
using item_t = typename Name::item_t; \
+ using Name::_begin; \
using Name::begin; \
+ using Name::_end; \
using Name::end; \
using Name::get_item_size; \
using Name::is_iterator; \
@@ -377,7 +381,7 @@
void __forward__ (unsigned n) { it += n; }
void __prev__ () { --it; }
void __rewind__ (unsigned n) { it -= n; }
- hb_map_iter_t __end__ () const { return hb_map_iter_t (it.end (), f); }
+ hb_map_iter_t __end__ () const { return hb_map_iter_t (it._end (), f); }
bool operator != (const hb_map_iter_t& o) const
{ return it != o.it; }
@@ -440,7 +444,7 @@
bool __more__ () const { return bool (it); }
void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
void __prev__ () { do --it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
- hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it.end (), p, f); }
+ hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it._end (), p, f); }
bool operator != (const hb_filter_iter_t& o) const
{ return it != o.it; }
@@ -553,7 +557,7 @@
void __forward__ (unsigned n) { a += n; b += n; }
void __prev__ () { --a; --b; }
void __rewind__ (unsigned n) { a -= n; b -= n; }
- hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a.end (), b.end ()); }
+ hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a._end (), b._end ()); }
/* Note, we should stop if ANY of the iters reaches end. As such two compare
* unequal if both items are unequal, NOT if either is unequal. */
bool operator != (const hb_zip_iter_t& o) const
@@ -637,7 +641,7 @@
}
}
- hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a.end (), b.end ()); }
+ hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a._end (), b._end ()); }
bool operator != (const hb_concat_iter_t& o) const
{
return a != o.a
diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh
index 2571f22..b555739 100644
--- a/src/hb-machinery.hh
+++ b/src/hb-machinery.hh
@@ -136,6 +136,13 @@
/*
* Lazy loaders.
+ *
+ * The lazy-loaders are thread-safe pointer-like objects that create their
+ * instead on-demand. They also support access to a "data" object that is
+ * necessary for creating their instance. The data object, if specified,
+ * is accessed via pointer math, located at a location before the position
+ * of the loader itself. This avoids having to store a pointer to data
+ * for every lazy-loader. Multiple lazy-loaders can access the same data.
*/
template <typename Data, unsigned int WheresData>
@@ -228,7 +235,8 @@
bool cmpexch (Stored *current, Stored *value) const
{
- /* This *must* be called when there are no other threads accessing. */
+ /* This function can only be safely called directly if no
+ * other thread is accessing. */
return this->instance.cmpexch (current, value);
}
@@ -261,7 +269,7 @@
hb_free (p);
}
-// private:
+ private:
/* Must only have one pointer. */
hb_atomic_ptr_t<Stored *> instance;
};
@@ -283,7 +291,7 @@
{
auto c = hb_sanitize_context_t ();
if (core)
- c.set_num_glyphs (0); // So we don't recurse ad infinitum...
+ c.set_num_glyphs (0); // So we don't recurse ad infinitum, or doesn't need num_glyphs
return c.reference_table<T> (face);
}
static void destroy (hb_blob_t *p) { hb_blob_destroy (p); }
diff --git a/src/hb-map.hh b/src/hb-map.hh
index 8302e3f..bfb1b3f 100644
--- a/src/hb-map.hh
+++ b/src/hb-map.hh
@@ -43,9 +43,9 @@
hb_hashmap_t () { init (); }
~hb_hashmap_t () { fini (); }
- hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (population); hb_copy (o, *this); }
+ hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (o.population); hb_copy (o, *this); }
hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); }
- hb_hashmap_t& operator= (const hb_hashmap_t& o) { resize (population); hb_copy (o, *this); return *this; }
+ hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); resize (o.population); hb_copy (o, *this); return *this; }
hb_hashmap_t& operator= (hb_hashmap_t&& o) { hb_swap (*this, o); return *this; }
hb_hashmap_t (std::initializer_list<hb_pair_t<K, V>> lst) : hb_hashmap_t ()
@@ -71,6 +71,11 @@
uint32_t is_tombstone_ : 1;
V value;
+ item_t () : key (),
+ hash (0),
+ is_used_ (false), is_tombstone_ (false),
+ value () {}
+
bool is_used () const { return is_used_; }
void set_used (bool is_used) { is_used_ = is_used; }
bool is_tombstone () const { return is_tombstone_; }
@@ -88,17 +93,8 @@
return minus_1;
};
- void clear ()
- {
- new (std::addressof (key)) K ();
- new (std::addressof (value)) V ();
- hash = 0;
- is_used_ = false;
- is_tombstone_ = false;
- }
-
- bool operator == (const K &o) { return hb_deref (key) == hb_deref (o); }
- bool operator == (const item_t &o) { return *this == o.key; }
+ bool operator == (const K &o) const { return hb_deref (key) == hb_deref (o); }
+ bool operator == (const item_t &o) const { return *this == o.key; }
hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); }
hb_pair_t<const K &, const V &> get_pair_ref() const { return hb_pair_t<const K &, const V &> (key, value); }
@@ -107,8 +103,8 @@
};
hb_object_header_t header;
- bool successful; /* Allocations successful */
- unsigned int population; /* Not including tombstones. */
+ unsigned int successful : 1; /* Allocations successful */
+ unsigned int population : 31; /* Not including tombstones. */
unsigned int occupancy; /* Including tombstones. */
unsigned int mask;
unsigned int prime;
@@ -118,7 +114,10 @@
{
if (unlikely (!a.successful || !b.successful))
return;
- hb_swap (a.population, b.population);
+ unsigned tmp = a.population;
+ a.population = b.population;
+ b.population = tmp;
+ //hb_swap (a.population, b.population);
hb_swap (a.occupancy, b.occupancy);
hb_swap (a.mask, b.mask);
hb_swap (a.prime, b.prime);
@@ -160,7 +159,9 @@
{
if (unlikely (!successful)) return false;
- unsigned int power = hb_bit_storage (hb_max (population, new_population) * 2 + 8);
+ if (new_population != 0 && (new_population + new_population / 2) < mask) return true;
+
+ unsigned int power = hb_bit_storage (hb_max ((unsigned) population, new_population) * 2 + 8);
unsigned int new_size = 1u << power;
item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t));
if (unlikely (!new_items))
@@ -169,9 +170,9 @@
return false;
}
for (auto &_ : hb_iter (new_items, new_size))
- _.clear ();
+ new (&_) item_t ();
- unsigned int old_size = mask + 1;
+ unsigned int old_size = size ();
item_t *old_items = items;
/* Switch to new, empty, array. */
@@ -181,47 +182,82 @@
items = new_items;
/* Insert back old items. */
- if (old_items)
- for (unsigned int i = 0; i < old_size; i++)
+ for (unsigned int i = 0; i < old_size; i++)
+ {
+ if (old_items[i].is_real ())
{
- if (old_items[i].is_real ())
- {
- set_with_hash (old_items[i].key,
- old_items[i].hash,
- std::move (old_items[i].value));
- }
- old_items[i].~item_t ();
+ set_with_hash (std::move (old_items[i].key),
+ old_items[i].hash,
+ std::move (old_items[i].value));
}
+ old_items[i].~item_t ();
+ }
hb_free (old_items);
return true;
}
- template <typename VV>
- bool set (K key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); }
-
- const V& get (K key) const
+ template <typename KK, typename VV>
+ bool set_with_hash (KK&& key, uint32_t hash, VV&& value, bool is_delete=false)
{
- if (unlikely (!items)) return item_t::default_value ();
- unsigned int i = bucket_for (key);
- return items[i].is_real () && items[i] == key ? items[i].value : item_t::default_value ();
+ if (unlikely (!successful)) return false;
+ if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
+ item_t &item = item_for_hash (key, hash);
+
+ if (is_delete && !(item == key))
+ return true; /* Trying to delete non-existent key. */
+
+ if (item.is_used ())
+ {
+ occupancy--;
+ if (!item.is_tombstone ())
+ population--;
+ }
+
+ item.key = std::forward<KK> (key);
+ item.value = std::forward<VV> (value);
+ item.hash = hash;
+ item.set_used (true);
+ item.set_tombstone (is_delete);
+
+ occupancy++;
+ if (!is_delete)
+ population++;
+
+ return true;
}
- void del (K key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); }
+ template <typename VV>
+ bool set (const K &key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); }
+ template <typename VV>
+ bool set (K &&key, VV&& value) { return set_with_hash (std::move (key), hb_hash (key), std::forward<VV> (value)); }
+
+ const V& get_with_hash (const K &key, uint32_t hash) const
+ {
+ if (unlikely (!items)) return item_t::default_value ();
+ auto &item = item_for_hash (key, hash);
+ return item.is_real () && item == key ? item.value : item_t::default_value ();
+ }
+ const V& get (const K &key) const
+ {
+ if (unlikely (!items)) return item_t::default_value ();
+ return get_with_hash (key, hb_hash (key));
+ }
+
+ void del (const K &key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); }
/* Has interface. */
- typedef const V& value_t;
- value_t operator [] (K k) const { return get (k); }
+ const V& operator [] (K k) const { return get (k); }
template <typename VV=V>
bool has (K key, VV **vp = nullptr) const
{
if (unlikely (!items))
return false;
- unsigned int i = bucket_for (key);
- if (items[i].is_real () && items[i] == key)
+ auto &item = item_for_hash (key, hb_hash (key));
+ if (item.is_real () && item == key)
{
- if (vp) *vp = &items[i].value;
+ if (vp) *vp = std::addressof (item.value);
return true;
}
else
@@ -230,13 +266,18 @@
/* Projection. */
V operator () (K k) const { return get (k); }
+ unsigned size () const { return mask ? mask + 1 : 0; }
+
void clear ()
{
if (unlikely (!successful)) return;
- if (items)
- for (auto &_ : hb_iter (items, mask + 1))
- _.clear ();
+ for (auto &_ : hb_iter (items, size ()))
+ {
+ /* Reconstruct items. */
+ _.~item_t ();
+ new (&_) item_t ();
+ }
population = occupancy = 0;
}
@@ -246,11 +287,10 @@
uint32_t hash () const
{
- uint32_t h = 0;
- for (const auto &item : + hb_array (items, mask ? mask + 1 : 0)
- | hb_filter (&item_t::is_real))
- h ^= item.total_hash ();
- return h;
+ return
+ + iter_items ()
+ | hb_reduce ([] (uint32_t h, const item_t &_) { return h ^ _.total_hash (); }, (uint32_t) 0u)
+ ;
}
bool is_equal (const hb_hashmap_t &other) const
@@ -258,7 +298,7 @@
if (population != other.population) return false;
for (auto pair : iter ())
- if (get (pair.first) != pair.second)
+ if (other.get (pair.first) != pair.second)
return false;
return true;
@@ -271,87 +311,54 @@
/*
* Iterator
*/
- auto iter () const HB_AUTO_RETURN
+
+ auto iter_items () const HB_AUTO_RETURN
(
- + hb_array (items, mask ? mask + 1 : 0)
+ + hb_iter (items, size ())
| hb_filter (&item_t::is_real)
- | hb_map (&item_t::get_pair)
)
auto iter_ref () const HB_AUTO_RETURN
(
- + hb_array (items, mask ? mask + 1 : 0)
- | hb_filter (&item_t::is_real)
+ + iter_items ()
| hb_map (&item_t::get_pair_ref)
)
- auto keys () const HB_AUTO_RETURN
+ auto iter () const HB_AUTO_RETURN
(
- + hb_array (items, mask ? mask + 1 : 0)
- | hb_filter (&item_t::is_real)
- | hb_map (&item_t::key)
- | hb_map (hb_ridentity)
+ + iter_items ()
+ | hb_map (&item_t::get_pair)
)
auto keys_ref () const HB_AUTO_RETURN
(
- + hb_array (items, mask ? mask + 1 : 0)
- | hb_filter (&item_t::is_real)
+ + iter_items ()
| hb_map (&item_t::key)
)
- auto values () const HB_AUTO_RETURN
+ auto keys () const HB_AUTO_RETURN
(
- + hb_array (items, mask ? mask + 1 : 0)
- | hb_filter (&item_t::is_real)
- | hb_map (&item_t::value)
+ + keys_ref ()
| hb_map (hb_ridentity)
)
auto values_ref () const HB_AUTO_RETURN
(
- + hb_array (items, mask ? mask + 1 : 0)
- | hb_filter (&item_t::is_real)
+ + iter_items ()
| hb_map (&item_t::value)
)
+ auto values () const HB_AUTO_RETURN
+ (
+ + values_ref ()
+ | hb_map (hb_ridentity)
+ )
/* Sink interface. */
hb_hashmap_t& operator << (const hb_pair_t<K, V>& v)
{ set (v.first, v.second); return *this; }
+ hb_hashmap_t& operator << (const hb_pair_t<K, V&&>& v)
+ { set (v.first, std::move (v.second)); return *this; }
+ hb_hashmap_t& operator << (const hb_pair_t<K&&, V>& v)
+ { set (std::move (v.first), v.second); return *this; }
+ hb_hashmap_t& operator << (const hb_pair_t<K&&, V&&>& v)
+ { set (std::move (v.first), std::move (v.second)); return *this; }
- protected:
-
- template <typename VV>
- bool set_with_hash (K key, uint32_t hash, VV&& value, bool is_delete=false)
- {
- if (unlikely (!successful)) return false;
- if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
- unsigned int i = bucket_for_hash (key, hash);
-
- if (is_delete && items[i].key != key)
- return true; /* Trying to delete non-existent key. */
-
- if (items[i].is_used ())
- {
- occupancy--;
- if (!items[i].is_tombstone ())
- population--;
- }
-
- items[i].key = key;
- items[i].value = std::forward<VV> (value);
- items[i].hash = hash;
- items[i].set_used (true);
- items[i].set_tombstone (is_delete);
-
- occupancy++;
- if (!is_delete)
- population++;
-
- return true;
- }
-
- unsigned int bucket_for (const K &key) const
- {
- return bucket_for_hash (key, hb_hash (key));
- }
-
- unsigned int bucket_for_hash (const K &key, uint32_t hash) const
+ item_t& item_for_hash (const K &key, uint32_t hash) const
{
hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
unsigned int i = hash % prime;
@@ -360,12 +367,12 @@
while (items[i].is_used ())
{
if (items[i].hash == hash && items[i] == key)
- return i;
+ return items[i];
if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
tombstone = i;
i = (i + ++step) & mask;
}
- return tombstone == (unsigned) -1 ? i : tombstone;
+ return items[tombstone == (unsigned) -1 ? i : tombstone];
}
static unsigned int prime_for (unsigned int shift)
diff --git a/src/hb-meta.hh b/src/hb-meta.hh
index 52a6791..31aa7fa 100644
--- a/src/hb-meta.hh
+++ b/src/hb-meta.hh
@@ -112,8 +112,7 @@
template <typename T> using hb_add_pointer = decltype (_hb_try_add_pointer<T> (hb_prioritize));
-/* TODO Add feature-parity to std::decay. */
-template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>;
+template <typename T> using hb_decay = typename std::decay<T>::type;
#define hb_is_convertible(From,To) std::is_convertible<From, To>::value
diff --git a/src/hb-ms-feature-ranges.hh b/src/hb-ms-feature-ranges.hh
index d40fdea..46a20c9 100644
--- a/src/hb-ms-feature-ranges.hh
+++ b/src/hb-ms-feature-ranges.hh
@@ -166,7 +166,7 @@
{
auto *feature = active_features.lsearch (event->feature);
if (feature)
- active_features.remove (feature - active_features.arrayZ);
+ active_features.remove_ordered (feature - active_features.arrayZ);
}
}
diff --git a/src/hb-multimap.hh b/src/hb-multimap.hh
new file mode 100644
index 0000000..f0f9591
--- /dev/null
+++ b/src/hb-multimap.hh
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2022 Behdad Esfahbod
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_MULTIMAP_HH
+#define HB_MULTIMAP_HH
+
+#include "hb.hh"
+#include "hb-map.hh"
+#include "hb-vector.hh"
+
+
+/*
+ * hb_multimap_t
+ */
+
+struct hb_multimap_t
+{
+ void add (hb_codepoint_t k, hb_codepoint_t v)
+ {
+ hb_codepoint_t *i;
+ if (multiples_indices.has (k, &i))
+ {
+ multiples_values[*i].push (v);
+ return;
+ }
+
+ hb_codepoint_t *old_v;
+ if (singulars.has (k, &old_v))
+ {
+ hb_codepoint_t old = *old_v;
+ singulars.del (k);
+
+ multiples_indices.set (k, multiples_values.length);
+ auto *vec = multiples_values.push ();
+
+ vec->push (old);
+ vec->push (v);
+
+ return;
+ }
+
+ singulars.set (k, v);
+ }
+
+ hb_array_t<const hb_codepoint_t> get (hb_codepoint_t k) const
+ {
+ hb_codepoint_t *v;
+ if (singulars.has (k, &v))
+ return hb_array (v, 1);
+
+ hb_codepoint_t *i;
+ if (multiples_indices.has (k, &i))
+ return multiples_values[*i].as_array ();
+
+ return hb_array_t<hb_codepoint_t> ();
+ }
+
+ bool in_error () const
+ {
+ return singulars.in_error () || multiples_indices.in_error () || multiples_values.in_error ();
+ }
+
+ protected:
+ hb_map_t singulars;
+ hb_map_t multiples_indices;
+ hb_vector_t<hb_vector_t<hb_codepoint_t>> multiples_values;
+};
+
+
+
+#endif /* HB_MULTIMAP_HH */
diff --git a/src/hb-mutex.hh b/src/hb-mutex.hh
index 6914b22..053f9dd 100644
--- a/src/hb-mutex.hh
+++ b/src/hb-mutex.hh
@@ -108,10 +108,11 @@
struct hb_lock_t
{
- hb_lock_t (hb_mutex_t &mutex_) : mutex (mutex_) { mutex.lock (); }
- ~hb_lock_t () { mutex.unlock (); }
+ hb_lock_t (hb_mutex_t &mutex_) : mutex (&mutex_) { mutex->lock (); }
+ hb_lock_t (hb_mutex_t *mutex_) : mutex (mutex_) { if (mutex) mutex->lock (); }
+ ~hb_lock_t () { if (mutex) mutex->unlock (); }
private:
- hb_mutex_t &mutex;
+ hb_mutex_t *mutex;
};
diff --git a/src/hb-number-parser.hh b/src/hb-number-parser.hh
index 1a9dbba..ec68c3a 100644
--- a/src/hb-number-parser.hh
+++ b/src/hb-number-parser.hh
@@ -31,7 +31,7 @@
#include "hb.hh"
-#line 35 "hb-number-parser.hh"
+#line 32 "hb-number-parser.hh"
static const unsigned char _double_parser_trans_keys[] = {
0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u,
46u, 101u, 0
@@ -135,12 +135,12 @@
int cs;
-#line 139 "hb-number-parser.hh"
+#line 132 "hb-number-parser.hh"
{
cs = double_parser_start;
}
-#line 144 "hb-number-parser.hh"
+#line 135 "hb-number-parser.hh"
{
int _slen;
int _trans;
@@ -198,7 +198,7 @@
exp_overflow = true;
}
break;
-#line 202 "hb-number-parser.hh"
+#line 187 "hb-number-parser.hh"
}
_again:
diff --git a/src/hb-object.hh b/src/hb-object.hh
index 9876c29..a23c25f 100644
--- a/src/hb-object.hh
+++ b/src/hb-object.hh
@@ -80,7 +80,7 @@
if (item)
{
item_t old = *item;
- *item = items[items.length - 1];
+ *item = std::move (items.tail ());
items.pop ();
l.unlock ();
old.fini ();
@@ -123,7 +123,7 @@
l.lock ();
while (items.length)
{
- item_t old = items[items.length - 1];
+ item_t old = items.tail ();
items.pop ();
l.unlock ();
old.fini ();
diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh
index 6eee582..13570a4 100644
--- a/src/hb-open-file.hh
+++ b/src/hb-open-file.hh
@@ -90,7 +90,7 @@
{
if (table_count)
{
- + tables.sub_array (start_offset, table_count)
+ + tables.as_array ().sub_array (start_offset, table_count)
| hb_map (&TableRecord::tag)
| hb_sink (hb_array (table_tags, *table_count))
;
@@ -158,7 +158,7 @@
return_trace (false);
if (likely (len))
- memcpy (start, blob->data, len);
+ hb_memcpy (start, blob->data, len);
/* 4-byte alignment. */
c->align (4);
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index e66f451..2907991 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -148,7 +148,7 @@
static_assert (Type::static_size * 8 > fraction_bits, "");
HBFixed& operator = (typename Type::type i ) { Type::operator= (i); return *this; }
- float to_float () const { return ((int32_t) Type::v) / shift; }
+ float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) / shift; }
void set_float (float f) { Type::v = roundf (f * shift); }
public:
DEFINE_SIZE_STATIC (Type::static_size);
@@ -157,6 +157,9 @@
/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
using F2DOT14 = HBFixed<HBINT16, 14>;
+/* 16-bit signed fixed number with the low 12 bits of fraction (4.12). */
+using F4DOT12 = HBFixed<HBINT16, 12>;
+
/* 32-bit signed fixed-point number (16.16). */
using F16DOT16 = HBFixed<HBINT32, 16>;
@@ -209,6 +212,12 @@
struct VarIdx : HBUINT32 {
static constexpr unsigned NO_VARIATION = 0xFFFFFFFFu;
+ static_assert (NO_VARIATION == HB_OT_LAYOUT_NO_VARIATIONS_INDEX, "");
+ static uint32_t add (uint32_t i, unsigned short v)
+ {
+ if (i == NO_VARIATION) return i;
+ return i + v;
+ }
VarIdx& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; }
};
DECLARE_NULL_NAMESPACE_BYTES (OT, VarIdx);
@@ -493,10 +502,10 @@
void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1)
{ as_array (len).qsort (start, end); }
- bool serialize (hb_serialize_context_t *c, unsigned int items_len)
+ bool serialize (hb_serialize_context_t *c, unsigned int items_len, bool clear = true)
{
TRACE_SERIALIZE (this);
- if (unlikely (!c->extend (this, items_len))) return_trace (false);
+ if (unlikely (!c->extend_size (this, get_size (items_len), clear))) return_trace (false);
return_trace (true);
}
template <typename Iterator,
@@ -504,8 +513,8 @@
bool serialize (hb_serialize_context_t *c, Iterator items)
{
TRACE_SERIALIZE (this);
- unsigned count = items.len ();
- if (unlikely (!serialize (c, count))) return_trace (false);
+ unsigned count = hb_len (items);
+ if (unlikely (!serialize (c, count, false))) return_trace (false);
/* TODO Umm. Just exhaust the iterator instead? Being extra
* cautious right now.. */
for (unsigned i = 0; i < count; i++, ++items)
@@ -646,14 +655,9 @@
operator iter_t () const { return iter (); }
operator writer_t () { return writer (); }
- hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
- { return as_array ().sub_array (start_offset, count); }
- hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
- { return as_array ().sub_array (start_offset, count); }
- hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
- { return as_array ().sub_array (start_offset, count); }
- hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
- { return as_array ().sub_array (start_offset, count); }
+ /* Faster range-based for loop. */
+ const Type *begin () const { return arrayZ; }
+ const Type *end () const { return arrayZ + len; }
template <typename T>
Type &lsearch (const T &x, Type ¬_found = Crap (Type))
@@ -667,15 +671,15 @@
unsigned int to_store = (unsigned int) -1) const
{ return as_array ().lfind (x, i, not_found, to_store); }
- void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1)
- { as_array ().qsort (start, end); }
+ void qsort ()
+ { as_array ().qsort (); }
- HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len)
+ HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len, bool clear = true)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (this))) return_trace (false);
c->check_assign (len, items_len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW);
- if (unlikely (!c->extend (this))) return_trace (false);
+ if (unlikely (!c->extend_size (this, get_size (), clear))) return_trace (false);
return_trace (true);
}
template <typename Iterator,
@@ -683,8 +687,8 @@
HB_NODISCARD bool serialize (hb_serialize_context_t *c, Iterator items)
{
TRACE_SERIALIZE (this);
- unsigned count = items.len ();
- if (unlikely (!serialize (c, count))) return_trace (false);
+ unsigned count = hb_len (items);
+ if (unlikely (!serialize (c, count, false))) return_trace (false);
/* TODO Umm. Just exhaust the iterator instead? Being extra
* cautious right now.. */
for (unsigned i = 0; i < count; i++, ++items)
@@ -828,21 +832,25 @@
operator iter_t () const { return iter (); }
operator writer_t () { return writer (); }
- bool serialize (hb_serialize_context_t *c, unsigned int items_len)
+ /* Faster range-based for loop. */
+ const Type *begin () const { return arrayZ; }
+ const Type *end () const { return arrayZ + get_length (); }
+
+ HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned int items_len, bool clear = true)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (this))) return_trace (false);
c->check_assign (lenP1, items_len + 1, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW);
- if (unlikely (!c->extend (this))) return_trace (false);
+ if (unlikely (!c->extend_size (this, get_size (), clear))) return_trace (false);
return_trace (true);
}
template <typename Iterator,
hb_requires (hb_is_source_of (Iterator, Type))>
- bool serialize (hb_serialize_context_t *c, Iterator items)
+ HB_NODISCARD bool serialize (hb_serialize_context_t *c, Iterator items)
{
TRACE_SERIALIZE (this);
- unsigned count = items.len ();
- if (unlikely (!serialize (c, count))) return_trace (false);
+ unsigned count = hb_len (items);
+ if (unlikely (!serialize (c, count, false))) return_trace (false);
/* TODO Umm. Just exhaust the iterator instead? Being extra
* cautious right now.. */
for (unsigned i = 0; i < count; i++, ++items)
@@ -944,14 +952,9 @@
operator iter_t () const { return iter (); }
operator writer_t () { return writer (); }
- hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
- { return as_array ().sub_array (start_offset, count); }
- hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
- { return as_array ().sub_array (start_offset, count); }
- hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
- { return as_array ().sub_array (start_offset, count); }
- hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
- { return as_array ().sub_array (start_offset, count); }
+ /* Faster range-based for loop. */
+ const Type *begin () const { return this->arrayZ; }
+ const Type *end () const { return this->arrayZ + this->len; }
bool serialize (hb_serialize_context_t *c, unsigned int items_len)
{
diff --git a/src/hb-ot-cff-common.hh b/src/hb-ot-cff-common.hh
index ae3b83a..f22824f 100644
--- a/src/hb-ot-cff-common.hh
+++ b/src/hb-ot-cff-common.hh
@@ -66,95 +66,25 @@
{
TRACE_SERIALIZE (this);
unsigned int size = get_size ();
- CFFIndex *out = c->allocate_size<CFFIndex> (size);
+ CFFIndex *out = c->allocate_size<CFFIndex> (size, false);
if (likely (out))
- memcpy (out, this, size);
+ hb_memcpy (out, this, size);
return_trace (out);
}
+ template <typename Iterable,
+ hb_requires (hb_is_iterable (Iterable))>
bool serialize (hb_serialize_context_t *c,
- unsigned int offSize_,
- const byte_str_array_t &byteArray)
+ const Iterable &iterable)
{
TRACE_SERIALIZE (this);
-
- if (byteArray.length == 0)
- {
- COUNT *dest = c->allocate_min<COUNT> ();
- if (unlikely (!dest)) return_trace (false);
- *dest = 0;
- return_trace (true);
- }
-
- /* serialize CFFIndex header */
- if (unlikely (!c->extend_min (this))) return_trace (false);
- this->count = byteArray.length;
- this->offSize = offSize_;
- if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (byteArray.length + 1))))
- return_trace (false);
-
- /* serialize indices */
- unsigned int offset = 1;
- unsigned int i = 0;
- for (; i < byteArray.length; i++)
- {
- set_offset_at (i, offset);
- offset += byteArray[i].get_size ();
- }
- set_offset_at (i, offset);
-
- /* serialize data */
- for (unsigned int i = 0; i < byteArray.length; i++)
- {
- const hb_ubytes_t &bs = byteArray[i];
- unsigned char *dest = c->allocate_size<unsigned char> (bs.length);
- if (unlikely (!dest)) return_trace (false);
- memcpy (dest, &bs[0], bs.length);
- }
-
- return_trace (true);
- }
-
- bool serialize (hb_serialize_context_t *c,
- unsigned int offSize_,
- const str_buff_vec_t &buffArray)
- {
- byte_str_array_t byteArray;
- byteArray.init ();
- byteArray.resize (buffArray.length);
- for (unsigned int i = 0; i < byteArray.length; i++)
- byteArray[i] = hb_ubytes_t (buffArray[i].arrayZ, buffArray[i].length);
- bool result = this->serialize (c, offSize_, byteArray);
- byteArray.fini ();
- return result;
- }
-
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool serialize (hb_serialize_context_t *c,
- Iterator it)
- {
- TRACE_SERIALIZE (this);
- serialize_header(c, + it | hb_map ([] (const hb_ubytes_t &_) { return _.length; }));
+ auto it = hb_iter (iterable);
+ serialize_header(c, + it | hb_map (hb_iter) | hb_map (hb_len));
for (const auto &_ : +it)
- _.copy (c);
+ hb_iter (_).copy (c);
return_trace (true);
}
- bool serialize (hb_serialize_context_t *c,
- const byte_str_array_t &byteArray)
- { return serialize (c, + hb_iter (byteArray)); }
-
- bool serialize (hb_serialize_context_t *c,
- const str_buff_vec_t &buffArray)
- {
- auto it =
- + hb_iter (buffArray)
- | hb_map ([] (const str_buff_t &_) { return hb_ubytes_t (_.arrayZ, _.length); })
- ;
- return serialize (c, it);
- }
-
template <typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
bool serialize_header (hb_serialize_context_t *c,
@@ -171,7 +101,7 @@
if (!this->count) return_trace (true);
if (unlikely (!c->extend (this->offSize))) return_trace (false);
this->offSize = off_size;
- if (unlikely (!c->allocate_size<HBUINT8> (off_size * (this->count + 1))))
+ if (unlikely (!c->allocate_size<HBUINT8> (off_size * (this->count + 1), false)))
return_trace (false);
/* serialize indices */
@@ -179,14 +109,27 @@
unsigned int i = 0;
for (unsigned _ : +it)
{
- CFFIndex<COUNT>::set_offset_at (i++, offset);
+ set_offset_at (i++, offset);
offset += _;
}
- CFFIndex<COUNT>::set_offset_at (i, offset);
+ set_offset_at (i, offset);
return_trace (true);
}
+ template <typename Iterable,
+ hb_requires (hb_is_iterable (Iterable))>
+ static unsigned total_size (const Iterable &iterable)
+ {
+ auto it = + hb_iter (iterable) | hb_map (hb_iter) | hb_map (hb_len);
+ if (!it) return 0;
+
+ unsigned total = + it | hb_reduce (hb_add, 0);
+ unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8;
+
+ return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total;
+ }
+
void set_offset_at (unsigned int index, unsigned int offset)
{
assert (index <= count);
@@ -207,10 +150,14 @@
unsigned int size = offSize;
const HBUINT8 *p = offsets + size * index;
- unsigned int offset = 0;
- for (; size; size--)
- offset = (offset << 8) + *p++;
- return offset;
+ switch (size)
+ {
+ case 1: return * (HBUINT8 *) p;
+ case 2: return * (HBUINT16 *) p;
+ case 3: return * (HBUINT24 *) p;
+ case 4: return * (HBUINT32 *) p;
+ default: return 0;
+ }
}
unsigned int length_at (unsigned int index) const
@@ -229,6 +176,7 @@
hb_ubytes_t operator [] (unsigned int index) const
{
if (unlikely (index >= count)) return hb_ubytes_t ();
+ _hb_compiler_memory_r_barrier ();
unsigned length = length_at (index);
if (unlikely (!length)) return hb_ubytes_t ();
return hb_ubytes_t (data_base () + offset_at (index) - 1, length);
@@ -280,7 +228,7 @@
if (unlikely (!c->extend_min (this))) return_trace (false);
this->count = dataArrayLen;
this->offSize = offSize_;
- if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1))))
+ if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1), false)))
return_trace (false);
/* serialize indices */
@@ -288,10 +236,10 @@
unsigned int i = 0;
for (; i < dataArrayLen; i++)
{
- CFFIndex<COUNT>::set_offset_at (i, offset);
+ this->set_offset_at (i, offset);
offset += dataSizeArray[i];
}
- CFFIndex<COUNT>::set_offset_at (i, offset);
+ this->set_offset_at (i, offset);
/* serialize data */
for (unsigned int i = 0; i < dataArrayLen; i++)
@@ -324,13 +272,12 @@
template <typename T, typename V>
static bool serialize_int_op (hb_serialize_context_t *c, op_code_t op, V value, op_code_t intOp)
{
- // XXX: not sure why but LLVM fails to compile the following 'unlikely' macro invocation
- if (/*unlikely*/ (!serialize_int<T, V> (c, intOp, value)))
+ if (unlikely ((!serialize_int<T, V> (c, intOp, value))))
return false;
TRACE_SERIALIZE (this);
/* serialize the opcode */
- HBUINT8 *p = c->allocate_size<HBUINT8> (OpCode_Size (op));
+ HBUINT8 *p = c->allocate_size<HBUINT8> (OpCode_Size (op), false);
if (unlikely (!p)) return_trace (false);
if (Is_OpCode_ESC (op))
{
@@ -415,9 +362,8 @@
TRACE_SANITIZE (this);
if (unlikely (!(c->check_struct (this))))
return_trace (false);
- for (unsigned int i = 0; i < c->get_num_glyphs (); i++)
- if (unlikely (!fds[i].sanitize (c)))
- return_trace (false);
+ if (unlikely (!c->check_array (fds, c->get_num_glyphs ())))
+ return_trace (false);
return_trace (true);
}
@@ -471,14 +417,20 @@
return_trace (true);
}
+ static int _cmp_range (const void *_key, const void *_item)
+ {
+ hb_codepoint_t glyph = * (hb_codepoint_t *) _key;
+ FDSelect3_4_Range<GID_TYPE, FD_TYPE> *range = (FDSelect3_4_Range<GID_TYPE, FD_TYPE> *) _item;
+
+ if (glyph < range[0].first) return -1;
+ if (glyph < range[1].first) return 0;
+ return +1;
+ }
+
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
{
- unsigned int i;
- for (i = 1; i < nRanges (); i++)
- if (glyph < ranges[i].first)
- break;
-
- return (hb_codepoint_t) ranges[i - 1].fd;
+ auto *range = hb_bsearch (glyph, &ranges[0], nRanges () - 1, sizeof (ranges[0]), _cmp_range);
+ return range ? range->fd : ranges[nRanges () - 1].fd;
}
GID_TYPE &nRanges () { return ranges.len; }
@@ -501,9 +453,9 @@
{
TRACE_SERIALIZE (this);
unsigned int size = src.get_size (num_glyphs);
- FDSelect *dest = c->allocate_size<FDSelect> (size);
+ FDSelect *dest = c->allocate_size<FDSelect> (size, false);
if (unlikely (!dest)) return_trace (false);
- memcpy (dest, &src, size);
+ hb_memcpy (dest, &src, size);
return_trace (true);
}
diff --git a/src/hb-ot-cff1-table.hh b/src/hb-ot-cff1-table.hh
index 17b0296..bb856c9 100644
--- a/src/hb-ot-cff1-table.hh
+++ b/src/hb-ot-cff1-table.hh
@@ -175,7 +175,7 @@
unsigned int size = src.get_size ();
Encoding *dest = c->allocate_size<Encoding> (size);
if (unlikely (!dest)) return_trace (false);
- memcpy (dest, &src, size);
+ hb_memcpy (dest, &src, size);
return_trace (true);
}
@@ -471,7 +471,7 @@
unsigned int size = src.get_size (num_glyphs);
Charset *dest = c->allocate_size<Charset> (size);
if (unlikely (!dest)) return_trace (false);
- memcpy (dest, &src, size);
+ hb_memcpy (dest, &src, size);
return_trace (true);
}
@@ -617,7 +617,6 @@
}
byte_str_array_t bytesArray;
- bytesArray.init ();
if (!bytesArray.resize (sidmap.get_population ()))
return_trace (false);
for (unsigned int i = 0; i < strings.count; i++)
@@ -628,7 +627,6 @@
}
bool result = CFF1Index::serialize (c, bytesArray);
- bytesArray.fini ();
return_trace (result);
}
};
@@ -813,7 +811,7 @@
break;
default:
- env.last_offset = env.str_ref.offset;
+ env.last_offset = env.str_ref.get_offset ();
top_dict_opset_t<cff1_top_dict_val_t>::process_op (op, env, dictval);
/* Record this operand below if stack is empty, otherwise done */
if (!env.argStack.is_empty ()) return;
@@ -1295,10 +1293,10 @@
}
protected:
- hb_blob_t *blob = nullptr;
hb_sanitize_context_t sc;
public:
+ hb_blob_t *blob = nullptr;
const Encoding *encoding = nullptr;
const Charset *charset = nullptr;
const CFF1NameIndex *nameIndex = nullptr;
diff --git a/src/hb-ot-cff2-table.hh b/src/hb-ot-cff2-table.hh
index 746160d..9081930 100644
--- a/src/hb-ot-cff2-table.hh
+++ b/src/hb-ot-cff2-table.hh
@@ -56,7 +56,7 @@
unsigned int size = src.get_size (num_glyphs);
CFF2FDSelect *dest = c->allocate_size<CFF2FDSelect> (size);
if (unlikely (!dest)) return_trace (false);
- memcpy (dest, &src, size);
+ hb_memcpy (dest, &src, size);
return_trace (true);
}
@@ -124,7 +124,7 @@
unsigned int size_ = varStore->get_size ();
CFF2VariationStore *dest = c->allocate_size<CFF2VariationStore> (size_);
if (unlikely (!dest)) return_trace (false);
- memcpy (dest, varStore, size_);
+ hb_memcpy (dest, varStore, size_);
return_trace (true);
}
@@ -483,13 +483,18 @@
blob = nullptr;
}
+ hb_map_t *create_glyph_to_sid_map () const
+ {
+ return nullptr;
+ }
+
bool is_valid () const { return blob; }
protected:
- hb_blob_t *blob = nullptr;
hb_sanitize_context_t sc;
public:
+ hb_blob_t *blob = nullptr;
cff2_top_dict_values_t topDict;
const CFF2Subrs *globalSubrs = nullptr;
const CFF2VariationStore *varStore = nullptr;
diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh
index 09c9fe9..523196f 100644
--- a/src/hb-ot-cmap-table.hh
+++ b/src/hb-ot-cmap-table.hh
@@ -909,7 +909,7 @@
hb_codepoint_t first = arrayZ[i].startUnicodeValue;
hb_codepoint_t last = hb_min ((hb_codepoint_t) (first + arrayZ[i].additionalCount),
(hb_codepoint_t) HB_UNICODE_MAX);
- out->add_range (first, hb_min (last, 0x10FFFFu));
+ out->add_range (first, last);
}
}
@@ -925,37 +925,75 @@
if (unlikely (!c->copy<HBUINT32> (len))) return nullptr;
unsigned init_len = c->length ();
- hb_codepoint_t lastCode = HB_MAP_VALUE_INVALID;
- int count = -1;
-
- for (const UnicodeValueRange& _ : as_array ())
+ if (this->len > unicodes->get_population () * hb_bit_storage ((unsigned) this->len))
{
- for (const unsigned addcnt : hb_range ((unsigned) _.additionalCount + 1))
- {
- unsigned curEntry = (unsigned) _.startUnicodeValue + addcnt;
- if (!unicodes->has (curEntry)) continue;
- count += 1;
- if (lastCode == HB_MAP_VALUE_INVALID)
- lastCode = curEntry;
- else if (lastCode + count != curEntry)
- {
- UnicodeValueRange rec;
- rec.startUnicodeValue = lastCode;
- rec.additionalCount = count - 1;
- c->copy<UnicodeValueRange> (rec);
+ hb_codepoint_t start = HB_SET_VALUE_INVALID;
+ hb_codepoint_t end = HB_SET_VALUE_INVALID;
- lastCode = curEntry;
- count = 0;
+ for (hb_codepoint_t u = HB_SET_VALUE_INVALID;
+ unicodes->next (&u);)
+ {
+ if (!as_array ().bsearch (u))
+ continue;
+ if (start == HB_SET_VALUE_INVALID)
+ {
+ start = u;
+ end = start - 1;
+ }
+ if (end + 1 != u || end - start == 255)
+ {
+ UnicodeValueRange rec;
+ rec.startUnicodeValue = start;
+ rec.additionalCount = end - start;
+ c->copy<UnicodeValueRange> (rec);
+ start = u;
+ }
+ end = u;
+ }
+ if (start != HB_SET_VALUE_INVALID)
+ {
+ UnicodeValueRange rec;
+ rec.startUnicodeValue = start;
+ rec.additionalCount = end - start;
+ c->copy<UnicodeValueRange> (rec);
+ }
+
+ }
+ else
+ {
+ hb_codepoint_t lastCode = HB_SET_VALUE_INVALID;
+ int count = -1;
+
+ for (const UnicodeValueRange& _ : *this)
+ {
+ hb_codepoint_t curEntry = (hb_codepoint_t) (_.startUnicodeValue - 1);
+ hb_codepoint_t end = curEntry + _.additionalCount + 2;
+
+ for (; unicodes->next (&curEntry) && curEntry < end;)
+ {
+ count += 1;
+ if (lastCode == HB_SET_VALUE_INVALID)
+ lastCode = curEntry;
+ else if (lastCode + count != curEntry)
+ {
+ UnicodeValueRange rec;
+ rec.startUnicodeValue = lastCode;
+ rec.additionalCount = count - 1;
+ c->copy<UnicodeValueRange> (rec);
+
+ lastCode = curEntry;
+ count = 0;
+ }
}
}
- }
- if (lastCode != HB_MAP_VALUE_INVALID)
- {
- UnicodeValueRange rec;
- rec.startUnicodeValue = lastCode;
- rec.additionalCount = count;
- c->copy<UnicodeValueRange> (rec);
+ if (lastCode != HB_MAP_VALUE_INVALID)
+ {
+ UnicodeValueRange rec;
+ rec.startUnicodeValue = lastCode;
+ rec.additionalCount = count;
+ c->copy<UnicodeValueRange> (rec);
+ }
}
if (c->length () - init_len == 0)
@@ -1474,32 +1512,80 @@
DEFINE_SIZE_STATIC (8);
};
+struct cmap;
+
struct SubtableUnicodesCache {
private:
- const void* base;
- hb_hashmap_t<intptr_t, hb::unique_ptr<hb_set_t>> cached_unicodes;
+ hb_blob_ptr_t<cmap> base_blob;
+ const char* base;
+ hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> cached_unicodes;
public:
- SubtableUnicodesCache(const void* cmap_base)
- : base(cmap_base), cached_unicodes() {}
- hb_set_t* set_for (const EncodingRecord* record)
+ static SubtableUnicodesCache* create (hb_blob_ptr_t<cmap> source_table)
{
- if (!cached_unicodes.has ((intptr_t) record))
+ SubtableUnicodesCache* cache =
+ (SubtableUnicodesCache*) hb_malloc (sizeof(SubtableUnicodesCache));
+ new (cache) SubtableUnicodesCache (source_table);
+ return cache;
+ }
+
+ static void destroy (void* value) {
+ if (!value) return;
+
+ SubtableUnicodesCache* cache = (SubtableUnicodesCache*) value;
+ cache->~SubtableUnicodesCache ();
+ hb_free (cache);
+ }
+
+ SubtableUnicodesCache(const void* cmap_base)
+ : base_blob(),
+ base ((const char*) cmap_base),
+ cached_unicodes ()
+ {}
+
+ SubtableUnicodesCache(hb_blob_ptr_t<cmap> base_blob_)
+ : base_blob(base_blob_),
+ base ((const char *) base_blob.get()),
+ cached_unicodes ()
+ {}
+
+ ~SubtableUnicodesCache()
+ {
+ base_blob.destroy ();
+ }
+
+ bool same_base(const void* other) const
+ {
+ return other == (const void*) base;
+ }
+
+ const hb_set_t* set_for (const EncodingRecord* record,
+ SubtableUnicodesCache& mutable_cache) const
+ {
+ if (cached_unicodes.has ((unsigned) ((const char *) record - base)))
+ return cached_unicodes.get ((unsigned) ((const char *) record - base));
+
+ return mutable_cache.set_for (record);
+ }
+
+ const hb_set_t* set_for (const EncodingRecord* record)
+ {
+ if (!cached_unicodes.has ((unsigned) ((const char *) record - base)))
{
hb_set_t *s = hb_set_create ();
if (unlikely (s->in_error ()))
return hb_set_get_empty ();
-
+
(base+record->subtable).collect_unicodes (s);
- if (unlikely (!cached_unicodes.set ((intptr_t) record, hb::unique_ptr<hb_set_t> {s})))
+ if (unlikely (!cached_unicodes.set ((unsigned) ((const char *) record - base), hb::unique_ptr<hb_set_t> {s})))
return hb_set_get_empty ();
return s;
}
- return cached_unicodes.get ((intptr_t) record);
+ return cached_unicodes.get ((unsigned) ((const char *) record - base));
}
};
@@ -1523,13 +1609,30 @@
{
static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap;
+
+ static SubtableUnicodesCache* create_filled_cache(hb_blob_ptr_t<cmap> source_table) {
+ const cmap* cmap = source_table.get();
+ auto it =
+ + hb_iter (cmap->encodingRecord)
+ | hb_filter ([&](const EncodingRecord& _) {
+ return cmap::filter_encoding_records_for_subset (cmap, _);
+ })
+ ;
+
+ SubtableUnicodesCache* cache = SubtableUnicodesCache::create(source_table);
+ for (const EncodingRecord& _ : it)
+ cache->set_for(&_); // populate the cache for this encoding record.
+
+ return cache;
+ }
+
template<typename Iterator, typename EncodingRecIter,
hb_requires (hb_is_iterator (EncodingRecIter))>
bool serialize (hb_serialize_context_t *c,
Iterator it,
EncodingRecIter encodingrec_iter,
const void *base,
- const hb_subset_plan_t *plan,
+ hb_subset_plan_t *plan,
bool drop_format_4 = false)
{
if (unlikely (!c->extend_min ((*this)))) return false;
@@ -1538,7 +1641,14 @@
unsigned format4objidx = 0, format12objidx = 0, format14objidx = 0;
auto snap = c->snapshot ();
- SubtableUnicodesCache unicodes_cache (base);
+ SubtableUnicodesCache local_unicodes_cache (base);
+ const SubtableUnicodesCache* unicodes_cache = &local_unicodes_cache;
+
+ if (plan->accelerator &&
+ plan->accelerator->cmap_cache &&
+ plan->accelerator->cmap_cache->same_base (base))
+ unicodes_cache = plan->accelerator->cmap_cache;
+
for (const EncodingRecord& _ : encodingrec_iter)
{
if (c->in_error ())
@@ -1547,7 +1657,7 @@
unsigned format = (base+_.subtable).u.format;
if (format != 4 && format != 12 && format != 14) continue;
- hb_set_t* unicodes_set = unicodes_cache.set_for (&_);
+ const hb_set_t* unicodes_set = unicodes_cache->set_for (&_, local_unicodes_cache);
if (!drop_format_4 && format == 4)
{
@@ -1566,7 +1676,13 @@
else if (format == 12)
{
- if (_can_drop (_, *unicodes_set, base, unicodes_cache, + it | hb_map (hb_first), encodingrec_iter)) continue;
+ if (_can_drop (_,
+ *unicodes_set,
+ base,
+ *unicodes_cache,
+ local_unicodes_cache,
+ + it | hb_map (hb_first), encodingrec_iter))
+ continue;
c->copy (_, + it | hb_filter (*unicodes_set, hb_first), 12u, base, plan, &format12objidx);
}
else if (format == 14) c->copy (_, it, 14u, base, plan, &format14objidx);
@@ -1585,7 +1701,8 @@
bool _can_drop (const EncodingRecord& cmap12,
const hb_set_t& cmap12_unicodes,
const void* base,
- SubtableUnicodesCache& unicodes_cache,
+ const SubtableUnicodesCache& unicodes_cache,
+ SubtableUnicodesCache& local_unicodes_cache,
Iterator subset_unicodes,
EncodingRecordIterator encoding_records)
{
@@ -1616,7 +1733,7 @@
|| (base+_.subtable).get_language() != target_language)
continue;
- hb_set_t* sibling_unicodes = unicodes_cache.set_for (&_);
+ const hb_set_t* sibling_unicodes = unicodes_cache.set_for (&_, local_unicodes_cache);
auto cmap12 = + subset_unicodes | hb_filter (cmap12_unicodes);
auto sibling = + subset_unicodes | hb_filter (*sibling_unicodes);
@@ -1653,17 +1770,9 @@
auto encodingrec_iter =
+ hb_iter (encodingRecord)
- | hb_filter ([&] (const EncodingRecord& _)
- {
- if ((_.platformID == 0 && _.encodingID == 3) ||
- (_.platformID == 0 && _.encodingID == 4) ||
- (_.platformID == 3 && _.encodingID == 1) ||
- (_.platformID == 3 && _.encodingID == 10) ||
- (this + _.subtable).u.format == 14)
- return true;
-
- return false;
- })
+ | hb_filter ([&](const EncodingRecord& _) {
+ return cmap::filter_encoding_records_for_subset (this, _);
+ })
;
if (unlikely (!encodingrec_iter.len ())) return_trace (false);
@@ -1692,7 +1801,11 @@
{ return (_.second != HB_MAP_VALUE_INVALID); })
;
- return_trace (cmap_prime->serialize (c->serializer, it, encodingrec_iter, this, c->plan));
+ return_trace (cmap_prime->serialize (c->serializer,
+ it,
+ encodingrec_iter,
+ this,
+ c->plan));
}
const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const
@@ -1928,6 +2041,19 @@
encodingRecord.sanitize (c, this));
}
+ private:
+
+ static bool filter_encoding_records_for_subset(const cmap* cmap,
+ const EncodingRecord& _)
+ {
+ return
+ (_.platformID == 0 && _.encodingID == 3) ||
+ (_.platformID == 0 && _.encodingID == 4) ||
+ (_.platformID == 3 && _.encodingID == 1) ||
+ (_.platformID == 3 && _.encodingID == 10) ||
+ (cmap + _.subtable).u.format == 14;
+ }
+
protected:
HBUINT16 version; /* Table version number (0). */
SortedArray16Of<EncodingRecord>
diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh
index 23fa56c..3246894 100644
--- a/src/hb-ot-color-cbdt-table.hh
+++ b/src/hb-ot-color-cbdt-table.hh
@@ -67,7 +67,7 @@
{
unsigned int new_len = cbdt_prime->length + length;
if (unlikely (!cbdt_prime->alloc (new_len))) return false;
- memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length);
+ hb_memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length);
cbdt_prime->length = new_len;
return true;
}
@@ -468,13 +468,13 @@
if (unlikely (!c->serializer->check_success (records->resize (records->length + 1))))
return_trace (false);
- (*records)[records->length - 1].firstGlyphIndex = 1;
- (*records)[records->length - 1].lastGlyphIndex = 0;
+ records->tail ().firstGlyphIndex = 1;
+ records->tail ().lastGlyphIndex = 0;
bitmap_size_context->size += IndexSubtableRecord::min_size;
c->serializer->push ();
- if (unlikely (!add_new_subtable (c, bitmap_size_context, &((*records)[records->length - 1]), lookup, base, start)))
+ if (unlikely (!add_new_subtable (c, bitmap_size_context, &(records->tail ()), lookup, base, start)))
{
c->serializer->pop_discard ();
c->serializer->revert (snap);
diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh
index 908bf55..1af9d30 100644
--- a/src/hb-ot-color-colr-table.hh
+++ b/src/hb-ot-color-colr-table.hh
@@ -39,11 +39,7 @@
#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
#ifndef HB_COLRV1_MAX_NESTING_LEVEL
-#define HB_COLRV1_MAX_NESTING_LEVEL 100
-#endif
-
-#ifndef COLRV1_ENABLE_SUBSETTING
-#define COLRV1_ENABLE_SUBSETTING 1
+#define HB_COLRV1_MAX_NESTING_LEVEL 16
#endif
namespace OT {
@@ -188,6 +184,7 @@
protected:
T value;
+ public:
VarIdx varIdxBase;
public:
DEFINE_SIZE_STATIC (4 + T::static_size);
@@ -196,6 +193,8 @@
template <typename T>
struct NoVariable
{
+ static constexpr uint32_t varIdxBase = VarIdx::NO_VARIATION;
+
NoVariable<T>* copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
@@ -888,6 +887,11 @@
DEFINE_SIZE_STATIC (8);
};
+struct ClipBoxData
+{
+ int xMin, yMin, xMax, yMax;
+};
+
struct ClipBoxFormat1
{
bool sanitize (hb_sanitize_context_t *c) const
@@ -896,6 +900,14 @@
return_trace (c->check_struct (this));
}
+ void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer HB_UNUSED) const
+ {
+ clip_box.xMin = xMin;
+ clip_box.yMin = yMin;
+ clip_box.xMax = xMax;
+ clip_box.yMax = yMax;
+ }
+
public:
HBUINT8 format; /* format = 1(noVar) or 2(Var)*/
FWORD xMin;
@@ -906,7 +918,20 @@
DEFINE_SIZE_STATIC (1 + 4 * FWORD::static_size);
};
-struct ClipBoxFormat2 : Variable<ClipBoxFormat1> {};
+struct ClipBoxFormat2 : Variable<ClipBoxFormat1>
+{
+ void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer) const
+ {
+ value.get_clip_box(clip_box, instancer);
+ if (instancer)
+ {
+ clip_box.xMin += _hb_roundf (instancer (varIdxBase, 0));
+ clip_box.yMin += _hb_roundf (instancer (varIdxBase, 1));
+ clip_box.xMax += _hb_roundf (instancer (varIdxBase, 2));
+ clip_box.yMax += _hb_roundf (instancer (varIdxBase, 3));
+ }
+ }
+};
struct ClipBox
{
@@ -932,6 +957,28 @@
}
}
+ bool get_extents (hb_glyph_extents_t *extents,
+ const VarStoreInstancer &instancer) const
+ {
+ ClipBoxData clip_box;
+ switch (u.format) {
+ case 1:
+ u.format1.get_clip_box (clip_box, instancer);
+ break;
+ case 2:
+ u.format2.get_clip_box (clip_box, instancer);
+ break;
+ default:
+ return false;
+ }
+
+ extents->x_bearing = clip_box.xMin;
+ extents->y_bearing = clip_box.yMax;
+ extents->width = clip_box.xMax - clip_box.xMin;
+ extents->height = clip_box.yMin - clip_box.yMax;
+ return true;
+ }
+
protected:
union {
HBUINT8 format; /* Format identifier */
@@ -942,6 +989,9 @@
struct ClipRecord
{
+ int cmp (hb_codepoint_t g) const
+ { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; }
+
ClipRecord* copy (hb_serialize_context_t *c, const void *base) const
{
TRACE_SERIALIZE (this);
@@ -957,6 +1007,13 @@
return_trace (c->check_struct (this) && clipBox.sanitize (c, base));
}
+ bool get_extents (hb_glyph_extents_t *extents,
+ const void *base,
+ const VarStoreInstancer &instancer) const
+ {
+ return (base+clipBox).get_extents (extents, instancer);
+ }
+
public:
HBUINT16 startGlyphID; // first gid clip applies to
HBUINT16 endGlyphID; // last gid clip applies to, inclusive
@@ -964,6 +1021,7 @@
public:
DEFINE_SIZE_STATIC (7);
};
+DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord);
struct ClipList
{
@@ -1052,11 +1110,26 @@
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
+ // TODO Make a formatted struct!
return_trace (c->check_struct (this) && clips.sanitize (c, this));
}
+ bool
+ get_extents (hb_codepoint_t gid,
+ hb_glyph_extents_t *extents,
+ const VarStoreInstancer &instancer) const
+ {
+ auto *rec = clips.as_array ().bsearch (gid);
+ if (rec)
+ {
+ rec->get_extents (extents, this, instancer);
+ return true;
+ }
+ return false;
+ }
+
HBUINT8 format; // Set to 1.
- Array32Of<ClipRecord> clips; // Clip records, sorted by startGlyphID
+ SortedArray32Of<ClipRecord> clips; // Clip records, sorted by startGlyphID
public:
DEFINE_SIZE_ARRAY_SIZED (5, clips);
};
@@ -1359,7 +1432,7 @@
(this+baseGlyphsZ).sanitize (c, numBaseGlyphs) &&
(this+layersZ).sanitize (c, numLayers) &&
(version == 0 ||
- (COLRV1_ENABLE_SUBSETTING && version == 1 &&
+ (version == 1 &&
baseGlyphList.sanitize (c, this) &&
layerList.sanitize (c, this) &&
clipList.sanitize (c, this) &&
@@ -1516,6 +1589,30 @@
return_trace (true);
}
+ bool
+ get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
+ {
+ if (version != 1)
+ return false;
+
+ VarStoreInstancer instancer (this+varStore,
+ this+varIdxMap,
+ hb_array (font->coords, font->num_coords));
+
+ if ((this+clipList).get_extents (glyph,
+ extents,
+ instancer))
+ {
+ extents->x_bearing = font->em_scale_x (extents->x_bearing);
+ extents->y_bearing = font->em_scale_x (extents->y_bearing);
+ extents->width = font->em_scale_x (extents->width);
+ extents->height = font->em_scale_x (extents->height);
+ return true;
+ }
+
+ return false;
+ }
+
protected:
HBUINT16 version; /* Table version number (starts at 0). */
HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */
diff --git a/src/hb-ot-face-table-list.hh b/src/hb-ot-face-table-list.hh
index c05034b..c9da36c 100644
--- a/src/hb-ot-face-table-list.hh
+++ b/src/hb-ot-face-table-list.hh
@@ -56,9 +56,9 @@
#if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT)
HB_OT_ACCELERATOR (OT, cmap)
#endif
-HB_OT_TABLE (OT, hhea)
+HB_OT_CORE_TABLE (OT, hhea)
HB_OT_ACCELERATOR (OT, hmtx)
-HB_OT_TABLE (OT, OS2)
+HB_OT_CORE_TABLE (OT, OS2)
#if !defined(HB_NO_OT_FONT_GLYPH_NAMES) || !defined(HB_NO_METRICS) || !defined(HB_NO_STYLE)
HB_OT_ACCELERATOR (OT, post)
#endif
@@ -66,7 +66,7 @@
HB_OT_ACCELERATOR (OT, name)
#endif
#ifndef HB_NO_STYLE
-HB_OT_TABLE (OT, STAT)
+HB_OT_CORE_TABLE (OT, STAT)
#endif
#ifndef HB_NO_META
HB_OT_ACCELERATOR (OT, meta)
@@ -74,9 +74,9 @@
/* Vertical layout. */
#ifndef HB_NO_VERTICAL
-HB_OT_TABLE (OT, vhea)
+HB_OT_CORE_TABLE (OT, vhea)
HB_OT_ACCELERATOR (OT, vmtx)
-HB_OT_TABLE (OT, VORG)
+HB_OT_CORE_TABLE (OT, VORG)
#endif
/* TrueType outlines. */
@@ -91,15 +91,15 @@
/* OpenType variations. */
#ifndef HB_NO_VAR
-HB_OT_TABLE (OT, fvar)
-HB_OT_TABLE (OT, avar)
+HB_OT_CORE_TABLE (OT, fvar)
+HB_OT_CORE_TABLE (OT, avar)
HB_OT_ACCELERATOR (OT, gvar)
-HB_OT_TABLE (OT, MVAR)
+HB_OT_CORE_TABLE (OT, MVAR)
#endif
/* Legacy kern. */
#ifndef HB_NO_OT_KERN
-HB_OT_TABLE (OT, kern)
+HB_OT_CORE_TABLE (OT, kern)
#endif
/* OpenType shaping. */
@@ -107,12 +107,12 @@
HB_OT_ACCELERATOR (OT, GDEF)
HB_OT_ACCELERATOR (OT, GSUB)
HB_OT_ACCELERATOR (OT, GPOS)
-//HB_OT_TABLE (OT, JSTF)
+//HB_OT_CORE_TABLE (OT, JSTF)
#endif
/* OpenType baseline. */
#ifndef HB_NO_BASE
-HB_OT_TABLE (OT, BASE)
+HB_OT_CORE_TABLE (OT, BASE)
#endif
/* AAT shaping. */
@@ -129,8 +129,8 @@
/* OpenType color fonts. */
#ifndef HB_NO_COLOR
-HB_OT_TABLE (OT, COLR)
-HB_OT_TABLE (OT, CPAL)
+HB_OT_CORE_TABLE (OT, COLR)
+HB_OT_CORE_TABLE (OT, CPAL)
HB_OT_ACCELERATOR (OT, CBDT)
HB_OT_ACCELERATOR (OT, sbix)
HB_OT_ACCELERATOR (OT, SVG)
@@ -138,7 +138,7 @@
/* OpenType math. */
#ifndef HB_NO_MATH
-HB_OT_TABLE (OT, MATH)
+HB_OT_CORE_TABLE (OT, MATH)
#endif
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 825b308..8405103 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -45,6 +45,7 @@
#include "hb-ot-vorg-table.hh"
#include "hb-ot-color-cbdt-table.hh"
#include "hb-ot-color-sbix-table.hh"
+#include "hb-ot-color-colr-table.hh"
/**
@@ -350,13 +351,15 @@
if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
if (ot_face->CBDT->get_extents (font, glyph, extents)) return true;
#endif
+#if !defined(HB_NO_COLOR)
+ if (ot_face->COLR->get_extents (font, glyph, extents)) return true;
+#endif
if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
#ifndef HB_NO_OT_FONT_CFF
if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
if (ot_face->cff2->get_extents (font, glyph, extents)) return true;
#endif
- // TODO Hook up side-bearings variations.
return false;
}
diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh
index 579abf0..0f424f5 100644
--- a/src/hb-ot-layout-common.hh
+++ b/src/hb-ot-layout-common.hh
@@ -478,7 +478,7 @@
{
if (_count)
{
- + this->sub_array (start_offset, _count)
+ + this->as_array ().sub_array (start_offset, _count)
| hb_sink (hb_array (_indexes, *_count))
;
}
@@ -658,7 +658,7 @@
{
if (char_count)
{
- + characters.sub_array (start_offset, char_count)
+ + characters.as_array ().sub_array (start_offset, char_count)
| hb_sink (hb_array (chars, *char_count))
;
}
@@ -932,7 +932,7 @@
{
if (record_count)
{
- + this->sub_array (start_offset, record_count)
+ + this->as_array ().sub_array (start_offset, record_count)
| hb_map (&Record<Type>::tag)
| hb_sink (hb_array (record_tags, *record_count))
;
@@ -980,18 +980,16 @@
auto *out = c->serializer->start_embed (*this);
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
- unsigned count = this->len;
-
- + hb_zip (*this, hb_range (count))
- | hb_filter (l->feature_index_map, hb_second)
- | hb_apply ([l, out, this] (const hb_pair_t<const Record<Feature>&, unsigned>& _)
+ + hb_enumerate (*this)
+ | hb_filter (l->feature_index_map, hb_first)
+ | hb_apply ([l, out, this] (const hb_pair_t<unsigned, const Record<Feature>&>& _)
{
const Feature *f_sub = nullptr;
const Feature **f = nullptr;
- if (l->feature_substitutes_map->has (_.second, &f))
+ if (l->feature_substitutes_map->has (_.first, &f))
f_sub = *f;
- subset_record_array (l, out, this, f_sub) (_.first);
+ subset_record_array (l, out, this, f_sub) (_.second);
})
;
@@ -1079,7 +1077,7 @@
auto *out = c->serializer->start_embed (*this);
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
- const unsigned *v;
+ const uint32_t *v;
out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu;
if (!l->visitFeatureIndex (featureIndex.len))
@@ -1147,7 +1145,6 @@
return;
}
- unsigned langsys_count = get_lang_sys_count ();
if (has_default_lang_sys ())
{
//only collect features from non-redundant langsys
@@ -1156,24 +1153,24 @@
d.collect_features (c);
}
- for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
+ for (auto _ : + hb_enumerate (langSys))
{
- const LangSys& l = this+_.first.offset;
+ const LangSys& l = this+_.second.offset;
if (!c->visitLangsys (l.get_feature_count ())) continue;
if (l.compare (d, c->duplicate_feature_map)) continue;
l.collect_features (c);
- c->script_langsys_map->get (script_index)->add (_.second);
+ c->script_langsys_map->get (script_index)->add (_.first);
}
}
else
{
- for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
+ for (auto _ : + hb_enumerate (langSys))
{
- const LangSys& l = this+_.first.offset;
+ const LangSys& l = this+_.second.offset;
if (!c->visitLangsys (l.get_feature_count ())) continue;
l.collect_features (c);
- c->script_langsys_map->get (script_index)->add (_.second);
+ c->script_langsys_map->get (script_index)->add (_.first);
}
}
}
@@ -1211,10 +1208,9 @@
const hb_set_t *active_langsys = l->script_langsys_map->get (l->cur_script_index);
if (active_langsys)
{
- unsigned count = langSys.len;
- + hb_zip (langSys, hb_range (count))
- | hb_filter (active_langsys, hb_second)
- | hb_map (hb_first)
+ + hb_enumerate (langSys)
+ | hb_filter (active_langsys, hb_first)
+ | hb_map (hb_second)
| hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); })
| hb_apply (subset_record_array (l, &(out->langSys), this))
;
@@ -1250,12 +1246,11 @@
auto *out = c->serializer->start_embed (*this);
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
- unsigned count = this->len;
- for (auto _ : + hb_zip (*this, hb_range (count)))
+ for (auto _ : + hb_enumerate (*this))
{
auto snap = c->serializer->snapshot ();
- l->cur_script_index = _.second;
- bool ret = _.first.subset (l, this);
+ l->cur_script_index = _.first;
+ bool ret = _.second.subset (l, this);
if (!ret) c->serializer->revert (snap);
else out->len++;
}
@@ -1388,7 +1383,13 @@
outMarkFilteringSet = markFilteringSet;
}
- return_trace (out->subTable.len);
+ // Always keep the lookup even if it's empty. The rest of layout subsetting depends on lookup
+ // indices being consistent with those computed during planning. So if an empty lookup is
+ // discarded during the subset phase it will invalidate all subsequent lookup indices.
+ // Generally we shouldn't end up with an empty lookup as we pre-prune them during the planning
+ // phase, but it can happen in rare cases such as when during closure subtable is considered
+ // degenerate (see: https://github.com/harfbuzz/harfbuzz/issues/3853)
+ return true;
}
template <typename TSubTable>
@@ -1454,10 +1455,9 @@
auto *out = c->serializer->start_embed (this);
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
- unsigned count = this->len;
- + hb_zip (*this, hb_range (count))
- | hb_filter (l->lookup_index_map, hb_second)
- | hb_map (hb_first)
+ + hb_enumerate (*this)
+ | hb_filter (l->lookup_index_map, hb_first)
+ | hb_map (hb_second)
| hb_apply (subset_offset_array (c, *out, this))
;
return_trace (true);
@@ -1491,7 +1491,7 @@
klass_map->set (0, 0);
unsigned idx = klass_map->has (0) ? 1 : 0;
- for (const unsigned k: klasses.iter ())
+ for (const unsigned k: klasses)
{
if (klass_map->has (k)) continue;
klass_map->set (k, idx);
@@ -1524,6 +1524,11 @@
return classValue[(unsigned int) (glyph_id - startGlyph)];
}
+ unsigned get_population () const
+ {
+ return classValue.len;
+ }
+
template<typename Iterator,
hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
bool serialize (hb_serialize_context_t *c,
@@ -1548,7 +1553,7 @@
startGlyph = glyph_min;
if (unlikely (!classValue.serialize (c, glyph_count))) return_trace (false);
- for (const hb_pair_t<hb_codepoint_t, unsigned> gid_klass_pair : + it)
+ for (const hb_pair_t<hb_codepoint_t, uint32_t> gid_klass_pair : + it)
{
unsigned idx = gid_klass_pair.first - glyph_min;
classValue[idx] = gid_klass_pair.second;
@@ -1639,11 +1644,10 @@
bool intersects (const hb_set_t *glyphs) const
{
- /* TODO Speed up, using hb_set_next()? */
hb_codepoint_t start = startGlyph;
hb_codepoint_t end = startGlyph + classValue.len;
for (hb_codepoint_t iter = startGlyph - 1;
- hb_set_next (glyphs, &iter) && iter < end;)
+ glyphs->next (&iter) && iter < end;)
if (classValue[iter - start]) return true;
return false;
}
@@ -1654,10 +1658,10 @@
{
/* Match if there's any glyph that is not listed! */
hb_codepoint_t g = HB_SET_VALUE_INVALID;
- if (!hb_set_next (glyphs, &g)) return false;
+ if (!glyphs->next (&g)) return false;
if (g < startGlyph) return true;
g = startGlyph + count - 1;
- if (hb_set_next (glyphs, &g)) return true;
+ if (glyphs->next (&g)) return true;
/* Fall through. */
}
/* TODO Speed up, using set overlap first? */
@@ -1675,12 +1679,12 @@
if (klass == 0)
{
unsigned start_glyph = startGlyph;
- for (unsigned g = HB_SET_VALUE_INVALID;
- hb_set_next (glyphs, &g) && g < start_glyph;)
+ for (uint32_t g = HB_SET_VALUE_INVALID;
+ glyphs->next (&g) && g < start_glyph;)
intersect_glyphs->add (g);
- for (unsigned g = startGlyph + count - 1;
- hb_set_next (glyphs, &g);)
+ for (uint32_t g = startGlyph + count - 1;
+ glyphs-> next (&g);)
intersect_glyphs->add (g);
return;
@@ -1696,7 +1700,7 @@
unsigned start_glyph = startGlyph;
unsigned end_glyph = start_glyph + count;
for (unsigned g = startGlyph - 1;
- hb_set_next (glyphs, &g) && g < end_glyph;)
+ glyphs->next (&g) && g < end_glyph;)
if (classValue.arrayZ[g - start_glyph] == klass)
intersect_glyphs->add (g);
#endif
@@ -1739,6 +1743,14 @@
return rangeRecord.bsearch (glyph_id).value;
}
+ unsigned get_population () const
+ {
+ typename Types::large_int ret = 0;
+ for (const auto &r : rangeRecord)
+ ret += r.get_population ();
+ return ret > UINT_MAX ? UINT_MAX : (unsigned) ret;
+ }
+
template<typename Iterator,
hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
bool serialize (hb_serialize_context_t *c,
@@ -1802,28 +1814,45 @@
{
TRACE_SUBSET (this);
const hb_map_t &glyph_map = *c->plan->glyph_map_gsub;
+ const hb_set_t &glyph_set = *c->plan->glyphset_gsub ();
hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass;
hb_set_t orig_klasses;
- unsigned num_source_glyphs = c->plan->source->get_num_glyphs ();
- unsigned count = rangeRecord.len;
- for (unsigned i = 0; i < count; i++)
+ if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2
+ < get_population ())
{
- unsigned klass = rangeRecord[i].value;
- if (!klass) continue;
- hb_codepoint_t start = rangeRecord[i].first;
- hb_codepoint_t end = hb_min (rangeRecord[i].last + 1, num_source_glyphs);
- for (hb_codepoint_t g = start; g < end; g++)
+ for (hb_codepoint_t g : glyph_set)
{
- hb_codepoint_t new_gid = glyph_map[g];
+ unsigned klass = get_class (g);
+ if (!klass) continue;
+ hb_codepoint_t new_gid = glyph_map[g];
if (new_gid == HB_MAP_VALUE_INVALID) continue;
- if (glyph_filter && !glyph_filter->has (g)) continue;
-
+ if (glyph_filter && !glyph_filter->has (g)) continue;
glyph_and_klass.push (hb_pair (new_gid, klass));
orig_klasses.add (klass);
}
}
+ else
+ {
+ unsigned num_source_glyphs = c->plan->source->get_num_glyphs ();
+ for (auto &range : rangeRecord)
+ {
+ unsigned klass = range.value;
+ if (!klass) continue;
+ hb_codepoint_t start = range.first;
+ hb_codepoint_t end = hb_min (range.last + 1, num_source_glyphs);
+ for (hb_codepoint_t g = start; g < end; g++)
+ {
+ hb_codepoint_t new_gid = glyph_map[g];
+ if (new_gid == HB_MAP_VALUE_INVALID) continue;
+ if (glyph_filter && !glyph_filter->has (g)) continue;
+
+ glyph_and_klass.push (hb_pair (new_gid, klass));
+ orig_klasses.add (klass);
+ }
+ }
+ }
const hb_set_t& glyphset = *c->plan->glyphset_gsub ();
unsigned glyph_count = glyph_filter
@@ -1850,10 +1879,9 @@
template <typename set_t>
bool collect_coverage (set_t *glyphs) const
{
- unsigned int count = rangeRecord.len;
- for (unsigned int i = 0; i < count; i++)
- if (rangeRecord[i].value)
- if (unlikely (!rangeRecord[i].collect_coverage (glyphs)))
+ for (auto &range : rangeRecord)
+ if (range.value)
+ if (unlikely (!range.collect_coverage (glyphs)))
return false;
return true;
}
@@ -1861,11 +1889,10 @@
template <typename set_t>
bool collect_class (set_t *glyphs, unsigned int klass) const
{
- unsigned int count = rangeRecord.len;
- for (unsigned int i = 0; i < count; i++)
+ for (auto &range : rangeRecord)
{
- if (rangeRecord[i].value == klass)
- if (unlikely (!rangeRecord[i].collect_coverage (glyphs)))
+ if (range.value == klass)
+ if (unlikely (!range.collect_coverage (glyphs)))
return false;
}
return true;
@@ -1873,32 +1900,32 @@
bool intersects (const hb_set_t *glyphs) const
{
- /* TODO Speed up, using hb_set_next() and bsearch()? */
- unsigned int count = rangeRecord.len;
- for (unsigned int i = 0; i < count; i++)
+ if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
{
- const auto& range = rangeRecord[i];
- if (range.intersects (*glyphs) && range.value)
- return true;
+ for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+ if (get_class (g))
+ return true;
+ return false;
}
- return false;
+
+ return hb_any (+ hb_iter (rangeRecord)
+ | hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs) && range.value; }));
}
bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const
{
- unsigned int count = rangeRecord.len;
if (klass == 0)
{
/* Match if there's any glyph that is not listed! */
hb_codepoint_t g = HB_SET_VALUE_INVALID;
- for (unsigned int i = 0; i < count; i++)
+ for (auto &range : rangeRecord)
{
- if (!hb_set_next (glyphs, &g))
+ if (!glyphs->next (&g))
break;
- if (g < rangeRecord[i].first)
+ if (g < range.first)
return true;
- g = rangeRecord[i].last;
+ g = range.last;
}
- if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
+ if (g != HB_SET_VALUE_INVALID && glyphs->next (&g))
return true;
/* Fall through. */
}
@@ -1910,49 +1937,49 @@
void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const
{
- unsigned count = rangeRecord.len;
if (klass == 0)
{
hb_codepoint_t g = HB_SET_VALUE_INVALID;
- for (unsigned int i = 0; i < count; i++)
+ for (auto &range : rangeRecord)
{
- if (!hb_set_next (glyphs, &g))
+ if (!glyphs->next (&g))
goto done;
- while (g < rangeRecord[i].first)
+ while (g < range.first)
{
intersect_glyphs->add (g);
- if (!hb_set_next (glyphs, &g))
+ if (!glyphs->next (&g))
goto done;
}
- g = rangeRecord[i].last;
+ g = range.last;
}
- while (hb_set_next (glyphs, &g))
+ while (glyphs->next (&g))
intersect_glyphs->add (g);
done:
return;
}
-#if 0
- /* The following implementation is faster asymptotically, but slower
- * in practice. */
- if ((count >> 3) > glyphs->get_population ())
+ unsigned count = rangeRecord.len;
+ if (count > glyphs->get_population () * hb_bit_storage (count) * 8)
{
for (hb_codepoint_t g = HB_SET_VALUE_INVALID;
- hb_set_next (glyphs, &g);)
- if (rangeRecord.as_array ().bfind (g))
+ glyphs->next (&g);)
+ {
+ unsigned i;
+ if (rangeRecord.as_array ().bfind (g, &i) &&
+ rangeRecord.arrayZ[i].value == klass)
intersect_glyphs->add (g);
+ }
return;
}
-#endif
- for (unsigned int i = 0; i < count; i++)
+ for (auto &range : rangeRecord)
{
- if (rangeRecord[i].value != klass) continue;
+ if (range.value != klass) continue;
- unsigned end = rangeRecord[i].last + 1;
- for (hb_codepoint_t g = rangeRecord[i].first - 1;
- hb_set_next (glyphs, &g) && g < end;)
+ unsigned end = range.last + 1;
+ for (hb_codepoint_t g = range.first - 1;
+ glyphs->next (&g) && g < end;)
intersect_glyphs->add (g);
}
}
@@ -1961,25 +1988,24 @@
{
if (glyphs->is_empty ()) return;
- unsigned count = rangeRecord.len;
hb_codepoint_t g = HB_SET_VALUE_INVALID;
- for (unsigned int i = 0; i < count; i++)
+ for (auto &range : rangeRecord)
{
- if (!hb_set_next (glyphs, &g))
+ if (!glyphs->next (&g))
break;
- if (g < rangeRecord[i].first)
+ if (g < range.first)
{
intersect_classes->add (0);
break;
}
- g = rangeRecord[i].last;
+ g = range.last;
}
- if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
+ if (g != HB_SET_VALUE_INVALID && glyphs->next (&g))
intersect_classes->add (0);
- for (const auto& record : rangeRecord.iter ())
- if (record.intersects (*glyphs))
- intersect_classes->add (record.value);
+ for (const auto& range : rangeRecord)
+ if (range.intersects (*glyphs))
+ intersect_classes->add (range.value);
}
protected:
@@ -1994,10 +2020,8 @@
struct ClassDef
{
/* Has interface. */
- static constexpr unsigned SENTINEL = 0;
- typedef unsigned int value_t;
- value_t operator [] (hb_codepoint_t k) const { return get (k); }
- bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+ unsigned operator [] (hb_codepoint_t k) const { return get (k); }
+ bool has (hb_codepoint_t k) const { return (*this)[k]; }
/* Projection. */
hb_codepoint_t operator () (hb_codepoint_t k) const { return get (k); }
@@ -2015,6 +2039,19 @@
}
}
+ unsigned get_population () const
+ {
+ switch (u.format) {
+ case 1: return u.format1.get_population ();
+ case 2: return u.format2.get_population ();
+#ifndef HB_NO_BEYOND_64K
+ case 3: return u.format3.get_population ();
+ case 4: return u.format4.get_population ();
+#endif
+ default:return NOT_COVERED;
+ }
+ }
+
template<typename Iterator,
hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
bool serialize (hb_serialize_context_t *c, Iterator it_with_class_zero)
@@ -2332,7 +2369,7 @@
{
unsigned int backward = region_map.backward (r);
if (backward >= region_count) return_trace (false);
- memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * backward], VarRegionAxis::static_size * axisCount);
+ hb_memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * backward], VarRegionAxis::static_size * axisCount);
}
return_trace (true);
@@ -2442,21 +2479,26 @@
unsigned ri_count = src->regionIndices.len;
enum delta_size_t { kZero=0, kNonWord, kWord };
hb_vector_t<delta_size_t> delta_sz;
- hb_vector_t<unsigned int> ri_map; /* maps old index to new index */
+ hb_vector_t<unsigned int> ri_map; /* maps new index to old index */
delta_sz.resize (ri_count);
ri_map.resize (ri_count);
unsigned int new_word_count = 0;
unsigned int r;
+ const HBUINT8 *src_delta_bytes = src->get_delta_bytes ();
+ unsigned src_row_size = src->get_row_size ();
+ unsigned src_word_count = src->wordCount ();
+ bool src_long_words = src->longWords ();
+
bool has_long = false;
- if (src->longWords ())
+ if (src_long_words)
{
- for (r = 0; r < ri_count; r++)
+ for (r = 0; r < src_word_count; r++)
{
for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
{
unsigned int old = inner_map.backward (i);
- int32_t delta = src->get_item_delta (old, r);
+ int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size);
if (delta < -65536 || 65535 < delta)
{
has_long = true;
@@ -2470,11 +2512,13 @@
signed max_threshold = has_long ? +65535 : +127;
for (r = 0; r < ri_count; r++)
{
+ bool short_circuit = src_long_words == has_long && src_word_count <= r;
+
delta_sz[r] = kZero;
for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
{
unsigned int old = inner_map.backward (i);
- int32_t delta = src->get_item_delta (old, r);
+ int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size);
if (delta < min_threshold || max_threshold < delta)
{
delta_sz[r] = kWord;
@@ -2482,7 +2526,11 @@
break;
}
else if (delta != 0)
+ {
delta_sz[r] = kNonWord;
+ if (short_circuit)
+ break;
+ }
}
}
@@ -2492,7 +2540,8 @@
for (r = 0; r < ri_count; r++)
if (delta_sz[r])
{
- ri_map[r] = (delta_sz[r] == kWord)? word_index++ : non_word_index++;
+ unsigned new_r = (delta_sz[r] == kWord)? word_index++ : non_word_index++;
+ ri_map[new_r] = r;
new_ri_count++;
}
@@ -2502,14 +2551,20 @@
if (unlikely (!c->extend (this))) return_trace (false);
- for (r = 0; r < ri_count; r++)
- if (delta_sz[r]) regionIndices[ri_map[r]] = region_map[src->regionIndices[r]];
+ for (r = 0; r < new_ri_count; r++)
+ regionIndices[r] = region_map[src->regionIndices[ri_map[r]]];
- for (unsigned int i = 0; i < itemCount; i++)
+ HBUINT8 *delta_bytes = get_delta_bytes ();
+ unsigned row_size = get_row_size ();
+ unsigned count = itemCount;
+ for (unsigned int i = 0; i < count; i++)
{
- unsigned int old = inner_map.backward (i);
- for (unsigned int r = 0; r < ri_count; r++)
- if (delta_sz[r]) set_item_delta (i, ri_map[r], src->get_item_delta (old, r));
+ unsigned int old = inner_map.backward (i);
+ for (unsigned int r = 0; r < new_ri_count; r++)
+ set_item_delta_fast (i, r,
+ src->get_item_delta_fast (old, ri_map[r],
+ src_delta_bytes, src_row_size),
+ delta_bytes, row_size);
}
return_trace (true);
@@ -2517,12 +2572,15 @@
void collect_region_refs (hb_set_t ®ion_indices, const hb_inc_bimap_t &inner_map) const
{
+ const HBUINT8 *delta_bytes = get_delta_bytes ();
+ unsigned row_size = get_row_size ();
+
for (unsigned int r = 0; r < regionIndices.len; r++)
{
- unsigned int region = regionIndices[r];
+ unsigned int region = regionIndices.arrayZ[r];
if (region_indices.has (region)) continue;
for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
- if (get_item_delta (inner_map.backward (i), r) != 0)
+ if (get_item_delta_fast (inner_map.backward (i), r, delta_bytes, row_size) != 0)
{
region_indices.add (region);
break;
@@ -2537,10 +2595,12 @@
HBUINT8 *get_delta_bytes ()
{ return &StructAfter<HBUINT8> (regionIndices); }
- int32_t get_item_delta (unsigned int item, unsigned int region) const
+ int32_t get_item_delta_fast (unsigned int item, unsigned int region,
+ const HBUINT8 *delta_bytes, unsigned row_size) const
{
- if ( item >= itemCount || unlikely (region >= regionIndices.len)) return 0;
- const HBINT8 *p = (const HBINT8 *) get_delta_bytes () + item * get_row_size ();
+ if (unlikely (item >= itemCount || region >= regionIndices.len)) return 0;
+
+ const HBINT8 *p = (const HBINT8 *) delta_bytes + item * row_size;
unsigned word_count = wordCount ();
bool is_long = longWords ();
if (is_long)
@@ -2558,10 +2618,17 @@
return (p + HBINT16::static_size * word_count)[region - word_count];
}
}
-
- void set_item_delta (unsigned int item, unsigned int region, int32_t delta)
+ int32_t get_item_delta (unsigned int item, unsigned int region) const
{
- HBINT8 *p = (HBINT8 *)get_delta_bytes () + item * get_row_size ();
+ return get_item_delta_fast (item, region,
+ get_delta_bytes (),
+ get_row_size ());
+ }
+
+ void set_item_delta_fast (unsigned int item, unsigned int region, int32_t delta,
+ HBUINT8 *delta_bytes, unsigned row_size)
+ {
+ HBINT8 *p = (HBINT8 *) delta_bytes + item * row_size;
unsigned word_count = wordCount ();
bool is_long = longWords ();
if (is_long)
@@ -2579,6 +2646,12 @@
(p + HBINT16::static_size * word_count)[region - word_count] = delta;
}
}
+ void set_item_delta (unsigned int item, unsigned int region, int32_t delta)
+ {
+ set_item_delta_fast (item, region, delta,
+ get_delta_bytes (),
+ get_row_size ());
+ }
bool longWords () const { return wordSizeCount & 0x8000u /* LONG_WORDS */; }
unsigned wordCount () const { return wordSizeCount & 0x7FFFu /* WORD_DELTA_COUNT_MASK */; }
@@ -2642,6 +2715,14 @@
unsigned int inner = index & 0xFFFF;
return get_delta (outer, inner, coords, coord_count, cache);
}
+ float get_delta (unsigned int index,
+ hb_array_t<int> coords,
+ VarRegionList::cache_t *cache = nullptr) const
+ {
+ return get_delta (index,
+ coords.arrayZ, coords.length,
+ cache);
+ }
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -2948,7 +3029,7 @@
// all conditions met
if (num_kept_cond == 0) return DROP_COND_WITH_VAR;
-
+
//check if condition_set is unique with variations
if (c->conditionset_map->has (p))
//duplicate found, drop the entire record
@@ -3420,17 +3501,16 @@
{
TRACE_SERIALIZE (this);
if (!layout_variation_idx_delta_map) return_trace (nullptr);
- auto snap = c->snapshot ();
+
+ hb_pair_t<unsigned, int> *v;
+ if (!layout_variation_idx_delta_map->has (varIdx, &v))
+ return_trace (nullptr);
+
+ c->start_zerocopy (this->static_size);
auto *out = c->embed (this);
if (unlikely (!out)) return_trace (nullptr);
- /* TODO Just get() and bail if NO_VARIATION. Needs to setup the map to return that. */
- if (!layout_variation_idx_delta_map->has (varIdx))
- {
- c->revert (snap);
- return_trace (nullptr);
- }
- unsigned new_idx = hb_first (layout_variation_idx_delta_map->get (varIdx));
+ unsigned new_idx = hb_first (*v);
out->varIdx = new_idx;
return_trace (out);
}
diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh
index 22925fd..a84edef 100644
--- a/src/hb-ot-layout-gdef-table.hh
+++ b/src/hb-ot-layout-gdef-table.hh
@@ -73,7 +73,7 @@
if (point_count)
{
- + points.sub_array (start_offset, point_count)
+ + points.as_array ().sub_array (start_offset, point_count)
| hb_sink (hb_array (point_array, *point_count))
;
}
@@ -322,7 +322,7 @@
{
if (caret_count)
{
- + carets.sub_array (start_offset, caret_count)
+ + carets.as_array ().sub_array (start_offset, caret_count)
| hb_map (hb_add (this))
| hb_map ([&] (const CaretValue &value) { return value.get_caret_value (font, direction, glyph_id, var_store); })
| hb_sink (hb_array (caret_array, *caret_count))
diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh
index d1d9425..04ccefd 100644
--- a/src/hb-ot-layout-gsubgpos.hh
+++ b/src/hb-ot-layout-gsubgpos.hh
@@ -100,8 +100,8 @@
bool is_lookup_done (unsigned int lookup_index)
{
- if (done_lookups_glyph_count->in_error () ||
- done_lookups_glyph_set->in_error ())
+ if (unlikely (done_lookups_glyph_count->in_error () ||
+ done_lookups_glyph_set->in_error ()))
return true;
/* Have we visited this lookup with the current set of glyphs? */
@@ -535,7 +535,12 @@
bool next (unsigned *unsafe_to = nullptr)
{
assert (num_items > 0);
- while (idx + num_items < end)
+ /* The alternate condition below is faster at string boundaries,
+ * but produces subpar "unsafe-to-concat" values. */
+ signed stop = (signed) end - (signed) num_items;
+ if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
+ stop = (signed) end - 1;
+ while ((signed) idx < stop)
{
idx++;
hb_glyph_info_t &info = c->buffer->info[idx];
@@ -568,7 +573,12 @@
bool prev (unsigned *unsafe_from = nullptr)
{
assert (num_items > 0);
- while (idx > num_items - 1)
+ /* The alternate condition below is faster at string boundaries,
+ * but produces subpar "unsafe-to-concat" values. */
+ unsigned stop = num_items - 1;
+ if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
+ stop = 1 - 1;
+ while (idx > stop)
{
idx--;
hb_glyph_info_t &info = c->buffer->out_info[idx];
@@ -672,6 +682,7 @@
const GDEF &gdef;
const VariationStore &var_store;
VariationStore::cache_t *var_store_cache;
+ hb_set_digest_t digest;
hb_direction_t direction;
hb_mask_t lookup_mask = 1;
@@ -707,6 +718,7 @@
nullptr
#endif
),
+ digest (buffer_->digest ()),
direction (buffer_->props.direction),
has_glyph_classes (gdef.has_glyph_classes ())
{ init_iters (); }
@@ -781,8 +793,10 @@
void _set_glyph_class (hb_codepoint_t glyph_index,
unsigned int class_guess = 0,
bool ligature = false,
- bool component = false) const
+ bool component = false)
{
+ digest.add (glyph_index);
+
if (new_syllables != (unsigned) -1)
buffer->cur().syllable() = new_syllables;
@@ -815,24 +829,24 @@
_hb_glyph_info_set_glyph_props (&buffer->cur(), props);
}
- void replace_glyph (hb_codepoint_t glyph_index) const
+ void replace_glyph (hb_codepoint_t glyph_index)
{
_set_glyph_class (glyph_index);
(void) buffer->replace_glyph (glyph_index);
}
- void replace_glyph_inplace (hb_codepoint_t glyph_index) const
+ void replace_glyph_inplace (hb_codepoint_t glyph_index)
{
_set_glyph_class (glyph_index);
buffer->cur().codepoint = glyph_index;
}
void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
- unsigned int class_guess) const
+ unsigned int class_guess)
{
_set_glyph_class (glyph_index, class_guess, true);
(void) buffer->replace_glyph (glyph_index);
}
void output_glyph_for_component (hb_codepoint_t glyph_index,
- unsigned int class_guess) const
+ unsigned int class_guess)
{
_set_glyph_class (glyph_index, class_guess, false, true);
(void) buffer->output_glyph (glyph_index);
@@ -844,7 +858,7 @@
hb_dispatch_context_t<hb_accelerate_subtables_context_t>
{
template <typename Type>
- static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
+ static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c)
{
const Type *typed_obj = (const Type *) obj;
return typed_obj->apply (c);
@@ -852,30 +866,30 @@
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
template <typename T>
- static inline auto apply_cached_ (const T *obj, OT::hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply (c, true) )
+ static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply (c, true) )
template <typename T>
- static inline auto apply_cached_ (const T *obj, OT::hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
+ static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
template <typename Type>
- static inline bool apply_cached_to (const void *obj, OT::hb_ot_apply_context_t *c)
+ static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c)
{
const Type *typed_obj = (const Type *) obj;
return apply_cached_ (typed_obj, c, hb_prioritize);
}
template <typename T>
- static inline auto cache_func_ (const T *obj, OT::hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) )
+ static inline auto cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) )
template <typename T>
- static inline bool cache_func_ (const T *obj, OT::hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; }
+ static inline bool cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; }
template <typename Type>
- static inline bool cache_func_to (const void *obj, OT::hb_ot_apply_context_t *c, bool enter)
+ static inline bool cache_func_to (const void *obj, hb_ot_apply_context_t *c, bool enter)
{
const Type *typed_obj = (const Type *) obj;
return cache_func_ (typed_obj, c, enter, hb_prioritize);
}
#endif
- typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c);
- typedef bool (*hb_cache_func_t) (const void *obj, OT::hb_ot_apply_context_t *c, bool enter);
+ typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c);
+ typedef bool (*hb_cache_func_t) (const void *obj, hb_ot_apply_context_t *c, bool enter);
struct hb_applicable_t
{
@@ -901,20 +915,20 @@
obj_.get_coverage ().collect_coverage (&digest);
}
- bool apply (OT::hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c) const
{
return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c);
}
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- bool apply_cached (OT::hb_ot_apply_context_t *c) const
+ bool apply_cached (hb_ot_apply_context_t *c) const
{
return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c);
}
- bool cache_enter (OT::hb_ot_apply_context_t *c) const
+ bool cache_enter (hb_ot_apply_context_t *c) const
{
return cache_func (obj, c, true);
}
- void cache_leave (OT::hb_ot_apply_context_t *c) const
+ void cache_leave (hb_ot_apply_context_t *c) const
{
cache_func (obj, c, false);
}
@@ -988,8 +1002,8 @@
};
-typedef bool (*intersects_func_t) (const hb_set_t *glyphs, unsigned value, const void *data);
-typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs);
+typedef bool (*intersects_func_t) (const hb_set_t *glyphs, unsigned value, const void *data, void *cache);
+typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, void *cache);
typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, unsigned value, const void *data);
typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data);
@@ -1012,16 +1026,25 @@
};
-static inline bool intersects_glyph (const hb_set_t *glyphs, unsigned value, const void *data HB_UNUSED)
+static inline bool intersects_glyph (const hb_set_t *glyphs, unsigned value, const void *data HB_UNUSED, void *cache HB_UNUSED)
{
return glyphs->has (value);
}
-static inline bool intersects_class (const hb_set_t *glyphs, unsigned value, const void *data)
+static inline bool intersects_class (const hb_set_t *glyphs, unsigned value, const void *data, void *cache)
{
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
- return class_def.intersects_class (glyphs, value);
+ hb_map_t *map = (hb_map_t *) cache;
+
+ hb_codepoint_t *cached_v;
+ if (map->has (value, &cached_v))
+ return *cached_v;
+
+ bool v = class_def.intersects_class (glyphs, value);
+ map->set (value, v);
+
+ return v;
}
-static inline bool intersects_coverage (const hb_set_t *glyphs, unsigned value, const void *data)
+static inline bool intersects_coverage (const hb_set_t *glyphs, unsigned value, const void *data, void *cache HB_UNUSED)
{
Offset16To<Coverage> coverage;
coverage = value;
@@ -1029,17 +1052,36 @@
}
-static inline void intersected_glyph (const hb_set_t *glyphs HB_UNUSED, const void *data, unsigned value, hb_set_t *intersected_glyphs)
+static inline void intersected_glyph (const hb_set_t *glyphs HB_UNUSED, const void *data, unsigned value, hb_set_t *intersected_glyphs, HB_UNUSED void *cache)
{
unsigned g = reinterpret_cast<const HBUINT16 *>(data)[value];
intersected_glyphs->add (g);
}
-static inline void intersected_class_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs)
+
+using intersected_class_cache_t = hb_hashmap_t<unsigned, hb_set_t>;
+
+static inline void intersected_class_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, void *cache)
{
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
- class_def.intersected_class_glyphs (glyphs, value, intersected_glyphs);
+
+ intersected_class_cache_t *map = (intersected_class_cache_t *) cache;
+
+ hb_set_t *cached_v;
+ if (map->has (value, &cached_v))
+ {
+ intersected_glyphs->union_ (*cached_v);
+ return;
+ }
+
+ hb_set_t v;
+ class_def.intersected_class_glyphs (glyphs, value, &v);
+
+ intersected_glyphs->union_ (v);
+
+ map->set (value, std::move (v));
}
-static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs)
+
+static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, HB_UNUSED void *cache)
{
Offset16To<Coverage> coverage;
coverage = value;
@@ -1052,10 +1094,11 @@
unsigned int count,
const HBUINT values[],
intersects_func_t intersects_func,
- const void *intersects_data)
+ const void *intersects_data,
+ void *cache)
{
for (const auto &_ : + hb_iter (values, count))
- if (!intersects_func (glyphs, _, intersects_data)) return false;
+ if (!intersects_func (glyphs, _, intersects_data, cache)) return false;
return true;
}
@@ -1492,7 +1535,8 @@
unsigned value,
ContextFormat context_format,
const void *data,
- intersected_glyphs_func_t intersected_glyphs_func)
+ intersected_glyphs_func_t intersected_glyphs_func,
+ void *cache)
{
hb_set_t *covered_seq_indicies = hb_set_create ();
for (unsigned int i = 0; i < lookupCount; i++)
@@ -1513,7 +1557,7 @@
pos_glyphs.add (value);
break;
case ContextFormat::ClassBasedContext:
- intersected_glyphs_func (&c->parent_active_glyphs (), data, value, &pos_glyphs);
+ intersected_glyphs_func (&c->parent_active_glyphs (), data, value, &pos_glyphs, cache);
break;
case ContextFormat::CoverageBasedContext:
pos_glyphs.set (c->parent_active_glyphs ());
@@ -1530,7 +1574,7 @@
input_value = input[seqIndex - 1];
}
- intersected_glyphs_func (c->glyphs, input_data, input_value, &pos_glyphs);
+ intersected_glyphs_func (c->glyphs, input_data, input_value, &pos_glyphs, cache);
}
}
@@ -1710,6 +1754,8 @@
ContextClosureFuncs funcs;
ContextFormat context_format;
const void *intersects_data;
+ void *intersects_cache;
+ void *intersected_glyphs_cache;
};
struct ContextCollectGlyphsLookupContext
@@ -1732,7 +1778,9 @@
{
return array_is_subset_of (glyphs,
inputCount ? inputCount - 1 : 0, input,
- lookup_context.funcs.intersects, lookup_context.intersects_data);
+ lookup_context.funcs.intersects,
+ lookup_context.intersects_data,
+ lookup_context.intersects_cache);
}
template <typename HBUINT>
@@ -1753,7 +1801,8 @@
value,
lookup_context.context_format,
lookup_context.intersects_data,
- lookup_context.funcs.intersected_glyphs);
+ lookup_context.funcs.intersected_glyphs,
+ lookup_context.intersected_glyphs_cache);
}
template <typename HBUINT>
@@ -1777,7 +1826,7 @@
const HBUINT input[], /* Array of input values--start with second glyph */
unsigned int lookupCount HB_UNUSED,
const LookupRecord lookupRecord[] HB_UNUSED,
- ContextApplyLookupContext &lookup_context)
+ const ContextApplyLookupContext &lookup_context)
{
return would_match_input (c,
inputCount, input,
@@ -1790,7 +1839,7 @@
const HBUINT input[], /* Array of input values--start with second glyph */
unsigned int lookupCount,
const LookupRecord lookupRecord[],
- ContextApplyLookupContext &lookup_context)
+ const ContextApplyLookupContext &lookup_context)
{
unsigned match_end = 0;
unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
@@ -1858,7 +1907,7 @@
}
bool would_apply (hb_would_apply_context_t *c,
- ContextApplyLookupContext &lookup_context) const
+ const ContextApplyLookupContext &lookup_context) const
{
const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
(inputZ.as_array (inputCount ? inputCount - 1 : 0));
@@ -1869,7 +1918,7 @@
}
bool apply (hb_ot_apply_context_t *c,
- ContextApplyLookupContext &lookup_context) const
+ const ContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY (this);
const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
@@ -1989,7 +2038,7 @@
}
bool would_apply (hb_would_apply_context_t *c,
- ContextApplyLookupContext &lookup_context) const
+ const ContextApplyLookupContext &lookup_context) const
{
return
+ hb_iter (rule)
@@ -2000,7 +2049,7 @@
}
bool apply (hb_ot_apply_context_t *c,
- ContextApplyLookupContext &lookup_context) const
+ const ContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY (this);
return_trace (
@@ -2108,7 +2157,7 @@
void closure_lookups (hb_closure_lookups_context_t *c) const
{
struct ContextClosureLookupContext lookup_context = {
- {intersects_glyph, intersected_glyph},
+ {intersects_glyph, nullptr},
ContextFormat::SimpleContext,
nullptr
};
@@ -2220,10 +2269,12 @@
const ClassDef &class_def = this+classDef;
+ hb_map_t cache;
struct ContextClosureLookupContext lookup_context = {
- {intersects_class, intersected_class_glyphs},
+ {intersects_class, nullptr},
ContextFormat::ClassBasedContext,
- &class_def
+ &class_def,
+ &cache
};
hb_set_t retained_coverage_glyphs;
@@ -2259,10 +2310,14 @@
const ClassDef &class_def = this+classDef;
+ hb_map_t cache;
+ intersected_class_cache_t intersected_cache;
struct ContextClosureLookupContext lookup_context = {
{intersects_class, intersected_class_glyphs},
ContextFormat::ClassBasedContext,
- &class_def
+ &class_def,
+ &cache,
+ &intersected_cache
};
+ hb_enumerate (ruleSet)
@@ -2286,10 +2341,12 @@
const ClassDef &class_def = this+classDef;
+ hb_map_t cache;
struct ContextClosureLookupContext lookup_context = {
- {intersects_class, intersected_class_glyphs},
+ {intersects_class, nullptr},
ContextFormat::ClassBasedContext,
- &class_def
+ &class_def,
+ &cache
};
+ hb_iter (ruleSet)
@@ -2407,6 +2464,7 @@
const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
bool ret = true;
int non_zero_index = -1, index = 0;
+ auto snapshot = c->serializer->snapshot();
for (const auto& _ : + hb_enumerate (ruleSet)
| hb_filter (klass_map, hb_first))
{
@@ -2418,8 +2476,10 @@
}
if (coverage_glyph_classes.has (_.first) &&
- o->serialize_subset (c, _.second, this, lookup_map, &klass_map))
+ o->serialize_subset (c, _.second, this, lookup_map, &klass_map)) {
non_zero_index = index;
+ snapshot = c->serializer->snapshot();
+ }
index++;
}
@@ -2433,6 +2493,7 @@
out->ruleSet.pop ();
index--;
}
+ c->serializer->revert (snapshot);
return_trace (bool (out->ruleSet));
}
@@ -2469,7 +2530,7 @@
return false;
struct ContextClosureLookupContext lookup_context = {
- {intersects_coverage, intersected_coverage_glyphs},
+ {intersects_coverage, nullptr},
ContextFormat::CoverageBasedContext,
this
};
@@ -2655,6 +2716,8 @@
ContextClosureFuncs funcs;
ContextFormat context_format;
const void *intersects_data[3];
+ void *intersects_cache[3];
+ void *intersected_glyphs_cache;
};
struct ChainContextCollectGlyphsLookupContext
@@ -2681,13 +2744,19 @@
{
return array_is_subset_of (glyphs,
backtrackCount, backtrack,
- lookup_context.funcs.intersects, lookup_context.intersects_data[0])
+ lookup_context.funcs.intersects,
+ lookup_context.intersects_data[0],
+ lookup_context.intersects_cache[0])
&& array_is_subset_of (glyphs,
inputCount ? inputCount - 1 : 0, input,
- lookup_context.funcs.intersects, lookup_context.intersects_data[1])
+ lookup_context.funcs.intersects,
+ lookup_context.intersects_data[1],
+ lookup_context.intersects_cache[1])
&& array_is_subset_of (glyphs,
lookaheadCount, lookahead,
- lookup_context.funcs.intersects, lookup_context.intersects_data[2]);
+ lookup_context.funcs.intersects,
+ lookup_context.intersects_data[2],
+ lookup_context.intersects_cache[2]);
}
template <typename HBUINT>
@@ -2714,7 +2783,8 @@
value,
lookup_context.context_format,
lookup_context.intersects_data[1],
- lookup_context.funcs.intersected_glyphs);
+ lookup_context.funcs.intersected_glyphs,
+ lookup_context.intersected_glyphs_cache);
}
template <typename HBUINT>
@@ -2752,7 +2822,7 @@
const HBUINT lookahead[] HB_UNUSED,
unsigned int lookupCount HB_UNUSED,
const LookupRecord lookupRecord[] HB_UNUSED,
- ChainContextApplyLookupContext &lookup_context)
+ const ChainContextApplyLookupContext &lookup_context)
{
return (c->zero_context ? !backtrackCount && !lookaheadCount : true)
&& would_match_input (c,
@@ -2770,7 +2840,7 @@
const HBUINT lookahead[],
unsigned int lookupCount,
const LookupRecord lookupRecord[],
- ChainContextApplyLookupContext &lookup_context)
+ const ChainContextApplyLookupContext &lookup_context)
{
unsigned end_index = c->buffer->idx;
unsigned match_end = 0;
@@ -2864,7 +2934,7 @@
}
bool would_apply (hb_would_apply_context_t *c,
- ChainContextApplyLookupContext &lookup_context) const
+ const ChainContextApplyLookupContext &lookup_context) const
{
const auto &input = StructAfter<decltype (inputX)> (backtrack);
const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
@@ -2876,7 +2946,8 @@
lookup.arrayZ, lookup_context);
}
- bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+ bool apply (hb_ot_apply_context_t *c,
+ const ChainContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY (this);
const auto &input = StructAfter<decltype (inputX)> (backtrack);
@@ -3042,7 +3113,8 @@
;
}
- bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+ bool would_apply (hb_would_apply_context_t *c,
+ const ChainContextApplyLookupContext &lookup_context) const
{
return
+ hb_iter (rule)
@@ -3052,7 +3124,8 @@
;
}
- bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+ bool apply (hb_ot_apply_context_t *c,
+ const ChainContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY (this);
return_trace (
@@ -3166,7 +3239,7 @@
void closure_lookups (hb_closure_lookups_context_t *c) const
{
struct ChainContextClosureLookupContext lookup_context = {
- {intersects_glyph, intersected_glyph},
+ {intersects_glyph, nullptr},
ContextFormat::SimpleContext,
{nullptr, nullptr, nullptr}
};
@@ -3278,12 +3351,14 @@
const ClassDef &input_class_def = this+inputClassDef;
const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+ hb_map_t caches[3] = {};
struct ChainContextClosureLookupContext lookup_context = {
- {intersects_class, intersected_class_glyphs},
+ {intersects_class, nullptr},
ContextFormat::ClassBasedContext,
{&backtrack_class_def,
&input_class_def,
- &lookahead_class_def}
+ &lookahead_class_def},
+ {&caches[0], &caches[1], &caches[2]}
};
hb_set_t retained_coverage_glyphs;
@@ -3321,12 +3396,16 @@
const ClassDef &input_class_def = this+inputClassDef;
const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+ hb_map_t caches[3] = {};
+ intersected_class_cache_t intersected_cache;
struct ChainContextClosureLookupContext lookup_context = {
{intersects_class, intersected_class_glyphs},
ContextFormat::ClassBasedContext,
{&backtrack_class_def,
&input_class_def,
- &lookahead_class_def}
+ &lookahead_class_def},
+ {&caches[0], &caches[1], &caches[2]},
+ &intersected_cache
};
+ hb_enumerate (ruleSet)
@@ -3352,12 +3431,14 @@
const ClassDef &input_class_def = this+inputClassDef;
const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+ hb_map_t caches[3] = {};
struct ChainContextClosureLookupContext lookup_context = {
- {intersects_class, intersected_class_glyphs},
+ {intersects_class, nullptr},
ContextFormat::ClassBasedContext,
{&backtrack_class_def,
&input_class_def,
- &lookahead_class_def}
+ &lookahead_class_def},
+ {&caches[0], &caches[1], &caches[2]}
};
+ hb_iter (ruleSet)
@@ -3587,7 +3668,7 @@
const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
struct ChainContextClosureLookupContext lookup_context = {
- {intersects_coverage, intersected_coverage_glyphs},
+ {intersects_coverage, nullptr},
ContextFormat::CoverageBasedContext,
{this, this, this}
};
@@ -3938,13 +4019,14 @@
template <typename TLookup>
void init (const TLookup &lookup)
{
- digest.init ();
- lookup.collect_coverage (&digest);
-
subtables.init ();
- OT::hb_accelerate_subtables_context_t c_accelerate_subtables (subtables);
+ hb_accelerate_subtables_context_t c_accelerate_subtables (subtables);
lookup.dispatch (&c_accelerate_subtables);
+ digest.init ();
+ for (auto& subtable : hb_iter (subtables))
+ digest.add (subtable.digest);
+
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
cache_user_idx = c_accelerate_subtables.cache_user_idx;
for (unsigned i = 0; i < subtables.length; i++)
@@ -3962,21 +4044,25 @@
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
if (use_cache)
{
- for (unsigned int i = 0; i < subtables.length; i++)
- if (subtables[i].apply_cached (c))
- return true;
+ return
+ + hb_iter (subtables)
+ | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply_cached (c); })
+ | hb_any
+ ;
}
else
#endif
{
- for (unsigned int i = 0; i < subtables.length; i++)
- if (subtables[i].apply (c))
- return true;
+ return
+ + hb_iter (subtables)
+ | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply (c); })
+ | hb_any
+ ;
}
return false;
}
- bool cache_enter (OT::hb_ot_apply_context_t *c) const
+ bool cache_enter (hb_ot_apply_context_t *c) const
{
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
return cache_user_idx != (unsigned) -1 &&
@@ -3985,7 +4071,7 @@
return false;
#endif
}
- void cache_leave (OT::hb_ot_apply_context_t *c) const
+ void cache_leave (hb_ot_apply_context_t *c) const
{
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
subtables[cache_user_idx].cache_leave (c);
@@ -3993,8 +4079,8 @@
}
- private:
hb_set_digest_t digest;
+ private:
hb_accelerate_subtables_context_t::array_t subtables;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
unsigned cache_user_idx = (unsigned) -1;
@@ -4255,11 +4341,11 @@
hb_set_t *lookup_indexes /* IN/OUT */) const
{
hb_set_t visited_lookups, inactive_lookups;
- OT::hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups);
+ hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups);
c.set_recurse_func (TLookup::template dispatch_recurse_func<hb_closure_lookups_context_t>);
- for (unsigned lookup_index : + hb_iter (lookup_indexes))
+ for (unsigned lookup_index : *lookup_indexes)
reinterpret_cast<const TLookup &> (get_lookup (lookup_index)).closure_lookups (&c, lookup_index);
hb_set_union (lookup_indexes, &visited_lookups);
@@ -4301,7 +4387,7 @@
}
#endif
- for (unsigned i : feature_indices->iter())
+ for (unsigned i : hb_iter (feature_indices))
{
hb_tag_t tag = get_feature_tag (i);
if (tag == HB_TAG ('p', 'r', 'e', 'f'))
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index dbb3007..e8091ec 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -1465,56 +1465,6 @@
_hb_ot_layout_set_glyph_props (font, buffer);
}
-void
-hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer,
- bool (*filter) (const hb_glyph_info_t *info))
-{
- /* Merge clusters and delete filtered glyphs.
- * NOTE! We can't use out-buffer as we have positioning data. */
- unsigned int j = 0;
- unsigned int count = buffer->len;
- hb_glyph_info_t *info = buffer->info;
- hb_glyph_position_t *pos = buffer->pos;
- for (unsigned int i = 0; i < count; i++)
- {
- if (filter (&info[i]))
- {
- /* Merge clusters.
- * Same logic as buffer->delete_glyph(), but for in-place removal. */
-
- unsigned int cluster = info[i].cluster;
- if (i + 1 < count && cluster == info[i + 1].cluster)
- continue; /* Cluster survives; do nothing. */
-
- if (j)
- {
- /* Merge cluster backward. */
- if (cluster < info[j - 1].cluster)
- {
- unsigned int mask = info[i].mask;
- unsigned int old_cluster = info[j - 1].cluster;
- for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--)
- buffer->set_cluster (info[k - 1], cluster, mask);
- }
- continue;
- }
-
- if (i + 1 < count)
- buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */
-
- continue;
- }
-
- if (j != i)
- {
- info[j] = info[i];
- pos[j] = pos[i];
- }
- j++;
- }
- buffer->len = j;
-}
-
/**
* hb_ot_layout_lookup_substitute_closure:
* @face: #hb_face_t to work upon
@@ -1867,7 +1817,7 @@
while (buffer->idx < buffer->len && buffer->successful)
{
bool applied = false;
- if (accel.may_have (buffer->cur().codepoint) &&
+ if (accel.digest.may_have (buffer->cur().codepoint) &&
(buffer->cur().mask & c->lookup_mask) &&
c->check_glyph_property (&buffer->cur(), c->lookup_props))
{
@@ -1894,7 +1844,7 @@
hb_buffer_t *buffer = c->buffer;
do
{
- if (accel.may_have (buffer->cur().codepoint) &&
+ if (accel.digest.may_have (buffer->cur().codepoint) &&
(buffer->cur().mask & c->lookup_mask) &&
c->check_glyph_property (&buffer->cur(), c->lookup_props))
ret |= accel.apply (c, false);
@@ -1908,15 +1858,16 @@
}
template <typename Proxy>
-static inline void
+static inline bool
apply_string (OT::hb_ot_apply_context_t *c,
const typename Proxy::Lookup &lookup,
const OT::hb_ot_layout_lookup_accelerator_t &accel)
{
+ bool ret = false;
hb_buffer_t *buffer = c->buffer;
if (unlikely (!buffer->len || !c->lookup_mask))
- return;
+ return ret;
c->set_lookup_props (lookup.get_props ());
@@ -1927,7 +1878,7 @@
buffer->clear_output ();
buffer->idx = 0;
- apply_forward (c, accel);
+ ret = apply_forward (c, accel);
if (!Proxy::always_inplace)
buffer->sync ();
@@ -1937,8 +1888,10 @@
/* in-place backward substitution/positioning */
assert (!buffer->have_output);
buffer->idx = buffer->len - 1;
- apply_backward (c, accel);
+ ret = apply_backward (c, accel);
}
+
+ return ret;
}
template <typename Proxy>
@@ -1957,23 +1910,42 @@
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;
- if (!buffer->message (font, "start lookup %d", lookup_index)) continue;
- c.set_lookup_index (lookup_index);
- c.set_lookup_mask (lookups[table_index][i].mask);
- c.set_auto_zwj (lookups[table_index][i].auto_zwj);
- c.set_auto_zwnj (lookups[table_index][i].auto_zwnj);
- c.set_random (lookups[table_index][i].random);
- c.set_per_syllable (lookups[table_index][i].per_syllable);
+ auto &lookup = lookups[table_index][i];
- apply_string<Proxy> (&c,
- proxy.table.get_lookup (lookup_index),
- proxy.accels[lookup_index]);
- (void) buffer->message (font, "end lookup %d", lookup_index);
+ unsigned int lookup_index = lookup.index;
+ if (!buffer->message (font, "start lookup %d feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag))) continue;
+
+ /* c.digest is a digest of all the current glyphs in the buffer
+ * (plus some past glyphs).
+ *
+ * Only try applying the lookup if there is any overlap. */
+ if (proxy.accels[lookup_index].digest.may_have (c.digest))
+ {
+ c.set_lookup_index (lookup_index);
+ c.set_lookup_mask (lookup.mask);
+ c.set_auto_zwj (lookup.auto_zwj);
+ c.set_auto_zwnj (lookup.auto_zwnj);
+ c.set_random (lookup.random);
+ c.set_per_syllable (lookup.per_syllable);
+
+ apply_string<Proxy> (&c,
+ proxy.table.get_lookup (lookup_index),
+ proxy.accels[lookup_index]);
+ }
+ else
+ (void) buffer->message (font, "skipped lookup %d feature '%c%c%c%c' because no glyph matches", lookup_index, HB_UNTAG (lookup.feature_tag));
+
+ (void) buffer->message (font, "end lookup %d feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag));
}
if (stage->pause_func)
- stage->pause_func (plan, font, buffer);
+ {
+ if (stage->pause_func (plan, font, buffer))
+ {
+ /* Refresh working buffer digest since buffer changed. */
+ c.digest = buffer->digest ();
+ }
+ }
}
}
diff --git a/src/hb-ot-layout.hh b/src/hb-ot-layout.hh
index de06610..9505d5f 100644
--- a/src/hb-ot-layout.hh
+++ b/src/hb-ot-layout.hh
@@ -102,10 +102,6 @@
hb_ot_layout_substitute_start (hb_font_t *font,
hb_buffer_t *buffer);
-HB_INTERNAL void
-hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer,
- bool (*filter) (const hb_glyph_info_t *info));
-
namespace OT {
struct hb_ot_apply_context_t;
struct hb_ot_layout_lookup_accelerator_t;
@@ -552,7 +548,7 @@
info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
}
-static inline void
+static inline bool
_hb_clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
@@ -561,6 +557,7 @@
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
_hb_glyph_info_clear_substituted (&info[i]);
+ return false;
}
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 39215b3..8882dba 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -45,7 +45,7 @@
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));
+ hb_memset (this, 0, sizeof (*this));
feature_infos.init ();
for (unsigned int table_index = 0; table_index < 2; table_index++)
@@ -133,7 +133,8 @@
bool auto_zwnj,
bool auto_zwj,
bool random,
- bool per_syllable)
+ bool per_syllable,
+ hb_tag_t feature_tag)
{
unsigned int lookup_indices[32];
unsigned int offset, len;
@@ -162,6 +163,7 @@
lookup->auto_zwj = auto_zwj;
lookup->random = random;
lookup->per_syllable = per_syllable;
+ lookup->feature_tag = feature_tag;
}
offset += len;
@@ -212,24 +214,26 @@
if (feature_infos.length)
{
feature_infos.qsort ();
+ auto *f = feature_infos.arrayZ;
unsigned int j = 0;
- for (unsigned int i = 1; i < feature_infos.length; i++)
- if (feature_infos[i].tag != feature_infos[j].tag)
- feature_infos[++j] = feature_infos[i];
+ unsigned count = feature_infos.length;
+ for (unsigned int i = 1; i < count; i++)
+ if (f[i].tag != f[j].tag)
+ f[++j] = f[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;
+ if (f[i].flags & F_GLOBAL) {
+ f[j].flags |= F_GLOBAL;
+ f[j].max_value = f[i].max_value;
+ f[j].default_value = f[i].default_value;
} else {
- if (feature_infos[j].flags & F_GLOBAL)
- feature_infos[j].flags ^= F_GLOBAL;
- feature_infos[j].max_value = hb_max (feature_infos[j].max_value, feature_infos[i].max_value);
+ if (f[j].flags & F_GLOBAL)
+ f[j].flags ^= F_GLOBAL;
+ f[j].max_value = hb_max (f[j].max_value, f[i].max_value);
/* Inherit default_value from j */
}
- feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK);
- feature_infos[j].stage[0] = hb_min (feature_infos[j].stage[0], feature_infos[i].stage[0]);
- feature_infos[j].stage[1] = hb_min (feature_infos[j].stage[1], feature_infos[i].stage[1]);
+ f[j].flags |= (f[i].flags & F_HAS_FALLBACK);
+ f[j].stage[0] = hb_min (f[j].stage[0], f[i].stage[0]);
+ f[j].stage[1] = hb_min (f[j].stage[1], f[i].stage[1]);
}
feature_infos.shrink (j + 1);
}
@@ -239,7 +243,8 @@
static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
unsigned int next_bit = hb_popcount (HB_GLYPH_FLAG_DEFINED) + 1;
- for (unsigned int i = 0; i < feature_infos.length; i++)
+ unsigned count = feature_infos.length;
+ for (unsigned int i = 0; i < count; i++)
{
const feature_info_t *info = &feature_infos[i];
@@ -308,7 +313,7 @@
map->_1_mask = (1u << map->shift) & map->mask;
map->needs_fallback = !found;
}
- feature_infos.shrink (0); /* Done with these */
+ //feature_infos.shrink (0); /* Done with these */
add_gsub_pause (nullptr);
@@ -317,6 +322,7 @@
for (unsigned int table_index = 0; table_index < 2; table_index++)
{
/* Collect lookup indices for features */
+ auto &lookups = m.lookups[table_index];
unsigned int stage_index = 0;
unsigned int last_num_lookups = 0;
@@ -329,36 +335,39 @@
key.variations_index[table_index],
global_bit_mask);
- for (unsigned i = 0; i < m.features.length; i++)
- if (m.features[i].stage[table_index] == stage)
- add_lookups (m, table_index,
- m.features[i].index[table_index],
- key.variations_index[table_index],
- m.features[i].mask,
- m.features[i].auto_zwnj,
- m.features[i].auto_zwj,
- m.features[i].random,
- m.features[i].per_syllable);
-
- /* Sort lookups and merge duplicates */
- if (last_num_lookups < m.lookups[table_index].length)
+ for (auto &feature : m.features)
{
- m.lookups[table_index].qsort (last_num_lookups, m.lookups[table_index].length);
-
- unsigned int j = last_num_lookups;
- for (unsigned int i = j + 1; i < m.lookups[table_index].length; 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_zwnj &= m.lookups[table_index][i].auto_zwnj;
- m.lookups[table_index][j].auto_zwj &= m.lookups[table_index][i].auto_zwj;
- }
- m.lookups[table_index].shrink (j + 1);
+ if (feature.stage[table_index] == stage)
+ add_lookups (m, table_index,
+ feature.index[table_index],
+ key.variations_index[table_index],
+ feature.mask,
+ feature.auto_zwnj,
+ feature.auto_zwj,
+ feature.random,
+ feature.per_syllable,
+ feature.tag);
}
- last_num_lookups = m.lookups[table_index].length;
+ /* Sort lookups and merge duplicates */
+ if (last_num_lookups < lookups.length)
+ {
+ lookups.as_array ().sub_array (last_num_lookups, lookups.length - last_num_lookups).qsort ();
+
+ unsigned int j = last_num_lookups;
+ for (unsigned int i = j + 1; i < lookups.length; i++)
+ if (lookups.arrayZ[i].index != lookups.arrayZ[j].index)
+ lookups.arrayZ[++j] = lookups.arrayZ[i];
+ else
+ {
+ lookups.arrayZ[j].mask |= lookups.arrayZ[i].mask;
+ lookups.arrayZ[j].auto_zwnj &= lookups.arrayZ[i].auto_zwnj;
+ lookups.arrayZ[j].auto_zwj &= lookups.arrayZ[i].auto_zwj;
+ }
+ lookups.shrink (j + 1);
+ }
+
+ last_num_lookups = lookups.length;
if (stage_index < stages[table_index].length && stages[table_index][stage_index].index == stage) {
hb_ot_map_t::stage_map_t *stage_map = m.stages[table_index].push ();
diff --git a/src/hb-ot-map.hh b/src/hb-ot-map.hh
index a7b5eec..efc8cae 100644
--- a/src/hb-ot-map.hh
+++ b/src/hb-ot-map.hh
@@ -69,6 +69,7 @@
unsigned short random : 1;
unsigned short per_syllable : 1;
hb_mask_t mask;
+ hb_tag_t feature_tag;
HB_INTERNAL static int cmp (const void *pa, const void *pb)
{
@@ -78,7 +79,9 @@
}
};
- typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
+ /* Pause functions return true if new glyph indices might have been
+ * added to the buffer. This is used to update buffer digest. */
+ typedef bool (*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 */
@@ -87,13 +90,13 @@
void init ()
{
- memset (this, 0, sizeof (*this));
+ hb_memset (this, 0, sizeof (*this));
- features.init ();
+ features.init0 ();
for (unsigned int table_index = 0; table_index < 2; table_index++)
{
- lookups[table_index].init ();
- stages[table_index].init ();
+ lookups[table_index].init0 ();
+ stages[table_index].init0 ();
}
}
void fini ()
@@ -239,7 +242,8 @@
bool auto_zwnj = true,
bool auto_zwj = true,
bool random = false,
- bool per_syllable = false);
+ bool per_syllable = false,
+ hb_tag_t feature_tag = HB_TAG(' ',' ',' ',' '));
struct feature_info_t {
hb_tag_t tag;
diff --git a/src/hb-ot-math-table.hh b/src/hb-ot-math-table.hh
index d834d94..9395337 100644
--- a/src/hb-ot-math-table.hh
+++ b/src/hb-ot-math-table.hh
@@ -77,11 +77,11 @@
HBINT16 *p = c->allocate_size<HBINT16> (HBINT16::static_size * 2);
if (unlikely (!p)) return_trace (nullptr);
- memcpy (p, percentScaleDown, HBINT16::static_size * 2);
+ hb_memcpy (p, percentScaleDown, HBINT16::static_size * 2);
HBUINT16 *m = c->allocate_size<HBUINT16> (HBUINT16::static_size * 2);
if (unlikely (!m)) return_trace (nullptr);
- memcpy (m, minHeight, HBUINT16::static_size * 2);
+ hb_memcpy (m, minHeight, HBUINT16::static_size * 2);
unsigned count = ARRAY_LENGTH (mathValueRecords);
for (unsigned i = 0; i < count; i++)
@@ -786,7 +786,7 @@
if (parts_count)
{
int64_t mult = font->dir_mult (direction);
- for (auto _ : hb_zip (partRecords.sub_array (start_offset, parts_count),
+ for (auto _ : hb_zip (partRecords.as_array ().sub_array (start_offset, parts_count),
hb_array (parts, *parts_count)))
_.first.extract (_.second, mult, font);
}
@@ -855,7 +855,7 @@
if (variants_count)
{
int64_t mult = font->dir_mult (direction);
- for (auto _ : hb_zip (mathGlyphVariantRecord.sub_array (start_offset, variants_count),
+ for (auto _ : hb_zip (mathGlyphVariantRecord.as_array ().sub_array (start_offset, variants_count),
hb_array (variants, *variants_count)))
_.second = {_.first.variantGlyph, font->em_mult (_.first.advanceMeasurement, mult)};
}
diff --git a/src/hb-ot-meta-table.hh b/src/hb-ot-meta-table.hh
index 93e64c5..e1b68bc 100644
--- a/src/hb-ot-meta-table.hh
+++ b/src/hb-ot-meta-table.hh
@@ -84,7 +84,7 @@
{
if (count)
{
- + table->dataMaps.sub_array (start_offset, count)
+ + table->dataMaps.as_array ().sub_array (start_offset, count)
| hb_map (&DataMap::get_tag)
| hb_map ([](hb_tag_t tag) { return (hb_ot_meta_tag_t) tag; })
| hb_sink (hb_array (entries, *count))
diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh
index 1f2131f..6f4461c 100644
--- a/src/hb-ot-name-table.hh
+++ b/src/hb-ot-name-table.hh
@@ -30,10 +30,55 @@
#include "hb-open-type.hh"
#include "hb-ot-name-language.hh"
#include "hb-aat-layout.hh"
+#include "hb-utf.hh"
namespace OT {
+template <typename in_utf_t, typename out_utf_t>
+inline unsigned int
+hb_ot_name_convert_utf (hb_bytes_t bytes,
+ unsigned int *text_size /* IN/OUT */,
+ typename out_utf_t::codepoint_t *text /* OUT */)
+{
+ unsigned int src_len = bytes.length / sizeof (typename in_utf_t::codepoint_t);
+ const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes.arrayZ;
+ const typename in_utf_t::codepoint_t *src_end = src + src_len;
+
+ typename out_utf_t::codepoint_t *dst = text;
+
+ hb_codepoint_t unicode;
+ const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
+
+ if (text_size && *text_size)
+ {
+ (*text_size)--; /* Save room for NUL-termination. */
+ const typename out_utf_t::codepoint_t *dst_end = text + *text_size;
+
+ while (src < src_end && dst < dst_end)
+ {
+ const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement);
+ typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode);
+ if (dst_next == dst)
+ break; /* Out-of-room. */
+
+ dst = dst_next;
+ src = src_next;
+ }
+
+ *text_size = dst - text;
+ *dst = 0; /* NUL-terminate. */
+ }
+
+ /* Accumulate length of rest. */
+ unsigned int dst_len = dst - text;
+ while (src < src_end)
+ {
+ src = in_utf_t::next (src, src_end, &unicode, replacement);
+ dst_len += out_utf_t::encode_len (unicode);
+ }
+ return dst_len;
+}
#define entry_score var.u16[0]
#define entry_index var.u16[1]
@@ -97,12 +142,68 @@
return UNSUPPORTED;
}
- NameRecord* copy (hb_serialize_context_t *c, const void *base) const
+ NameRecord* copy (hb_serialize_context_t *c, const void *base
+#ifdef HB_EXPERIMENTAL_API
+ , const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides
+#endif
+ ) const
{
TRACE_SERIALIZE (this);
+ HB_UNUSED auto snap = c->snapshot ();
auto *out = c->embed (this);
if (unlikely (!out)) return_trace (nullptr);
- out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length);
+#ifdef HB_EXPERIMENTAL_API
+ hb_ot_name_record_ids_t record_ids (platformID, encodingID, languageID, nameID);
+ hb_bytes_t* name_bytes;
+
+ if (name_table_overrides->has (record_ids, &name_bytes)) {
+ hb_bytes_t encoded_bytes = *name_bytes;
+ char *name_str_utf16_be = nullptr;
+
+ if (platformID != 1)
+ {
+ unsigned text_size = hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, nullptr, nullptr);
+
+ text_size++; // needs to consider NULL terminator for use in hb_ot_name_convert_utf()
+ unsigned byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
+ name_str_utf16_be = (char *) hb_calloc (byte_len, 1);
+ if (!name_str_utf16_be)
+ {
+ c->revert (snap);
+ return_trace (nullptr);
+ }
+ hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, &text_size,
+ (hb_utf16_be_t::codepoint_t *) name_str_utf16_be);
+
+ unsigned encoded_byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
+ if (!encoded_byte_len || !c->check_assign (out->length, encoded_byte_len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
+ c->revert (snap);
+ hb_free (name_str_utf16_be);
+ return_trace (nullptr);
+ }
+
+ encoded_bytes = hb_bytes_t (name_str_utf16_be, encoded_byte_len);
+ }
+ else
+ {
+ // mac platform, copy the UTF-8 string(all ascii characters) as is
+ if (!c->check_assign (out->length, encoded_bytes.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
+ c->revert (snap);
+ return_trace (nullptr);
+ }
+ }
+
+ out->offset = 0;
+ c->push ();
+ encoded_bytes.copy (c);
+ c->add_link (out->offset, c->pop_pack (), hb_serialize_context_t::Tail, 0);
+ hb_free (name_str_utf16_be);
+ }
+ else
+#endif
+ {
+ out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length);
+ }
return_trace (out);
}
@@ -216,29 +317,61 @@
hb_requires (hb_is_source_of (Iterator, const NameRecord &))>
bool serialize (hb_serialize_context_t *c,
Iterator it,
- const void *src_string_pool)
+ const void *src_string_pool
+#ifdef HB_EXPERIMENTAL_API
+ , const hb_vector_t<hb_ot_name_record_ids_t>& insert_name_records
+ , const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides
+#endif
+ )
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min ((*this)))) return_trace (false);
+ unsigned total_count = it.len ()
+#ifdef HB_EXPERIMENTAL_API
+ + insert_name_records.length
+#endif
+ ;
this->format = 0;
- this->count = it.len ();
+ if (!c->check_assign (this->count, total_count, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+ return false;
- NameRecord *name_records = (NameRecord *) hb_calloc (it.len (), NameRecord::static_size);
+ NameRecord *name_records = (NameRecord *) hb_calloc (total_count, NameRecord::static_size);
if (unlikely (!name_records)) return_trace (false);
- hb_array_t<NameRecord> records (name_records, it.len ());
+ hb_array_t<NameRecord> records (name_records, total_count);
for (const NameRecord& record : it)
{
- memcpy (name_records, &record, NameRecord::static_size);
+ hb_memcpy (name_records, &record, NameRecord::static_size);
name_records++;
}
+#ifdef HB_EXPERIMENTAL_API
+ for (unsigned i = 0; i < insert_name_records.length; i++)
+ {
+ const hb_ot_name_record_ids_t& ids = insert_name_records[i];
+ NameRecord record;
+ record.platformID = ids.platform_id;
+ record.encodingID = ids.encoding_id;
+ record.languageID = ids.language_id;
+ record.nameID = ids.name_id;
+ record.length = 0; // handled in NameRecord copy()
+ record.offset = 0;
+ memcpy (name_records, &record, NameRecord::static_size);
+ name_records++;
+ }
+#endif
+
records.qsort ();
- c->copy_all (records, src_string_pool);
+ c->copy_all (records,
+ src_string_pool
+#ifdef HB_EXPERIMENTAL_API
+ , name_table_overrides
+#endif
+ );
hb_free (records.arrayZ);
@@ -256,6 +389,11 @@
name *name_prime = c->serializer->start_embed<name> ();
if (unlikely (!name_prime)) return_trace (false);
+#ifdef HB_EXPERIMENTAL_API
+ const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides =
+ c->plan->name_table_overrides;
+#endif
+
auto it =
+ nameRecordZ.as_array (count)
| hb_filter (c->plan->name_ids, &NameRecord::nameID)
@@ -265,10 +403,48 @@
(c->plan->flags & HB_SUBSET_FLAGS_NAME_LEGACY)
|| namerecord.isUnicode ();
})
+#ifdef HB_EXPERIMENTAL_API
+ | hb_filter ([&] (const NameRecord& namerecord) {
+ if (name_table_overrides->is_empty ())
+ return true;
+ hb_ot_name_record_ids_t rec_ids (namerecord.platformID,
+ namerecord.encodingID,
+ namerecord.languageID,
+ namerecord.nameID);
+
+ hb_bytes_t *p;
+ if (name_table_overrides->has (rec_ids, &p) &&
+ (*p).length == 0)
+ return false;
+ return true;
+ })
+#endif
;
- name_prime->serialize (c->serializer, it, std::addressof (this + stringOffset));
- return_trace (name_prime->count);
+#ifdef HB_EXPERIMENTAL_API
+ hb_vector_t<hb_ot_name_record_ids_t> insert_name_records;
+ if (!name_table_overrides->is_empty ())
+ {
+ if (unlikely (!insert_name_records.alloc (name_table_overrides->get_population ())))
+ return_trace (false);
+ for (const auto& record_ids : name_table_overrides->keys ())
+ {
+ if (name_table_overrides->get (record_ids).length == 0)
+ continue;
+ if (has_name_record_with_ids (record_ids))
+ continue;
+ insert_name_records.push (record_ids);
+ }
+ }
+#endif
+
+ return (name_prime->serialize (c->serializer, it,
+ std::addressof (this + stringOffset)
+#ifdef HB_EXPERIMENTAL_API
+ , insert_name_records
+ , name_table_overrides
+#endif
+ ));
}
bool sanitize_records (hb_sanitize_context_t *c) const
@@ -378,6 +554,23 @@
hb_vector_t<hb_ot_name_entry_t> names;
};
+ private:
+ // sometimes NameRecords are not sorted in the font file, so use linear search
+ // here
+ bool has_name_record_with_ids (const hb_ot_name_record_ids_t& record_ids) const
+ {
+ for (const auto& record : nameRecordZ.as_array (count))
+ {
+ if (record.platformID == record_ids.platform_id &&
+ record.encodingID == record_ids.encoding_id &&
+ record.languageID == record_ids.language_id &&
+ record.nameID == record_ids.name_id)
+ return true;
+ }
+ return false;
+ }
+
+ public:
/* We only implement format 0 for now. */
HBUINT16 format; /* Format selector (=0/1). */
HBUINT16 count; /* Number of name records. */
diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc
index c35ac5b..6adf1e8 100644
--- a/src/hb-ot-name.cc
+++ b/src/hb-ot-name.cc
@@ -64,52 +64,6 @@
return (const hb_ot_name_entry_t *) name.names;
}
-
-template <typename in_utf_t, typename out_utf_t>
-static inline unsigned int
-hb_ot_name_convert_utf (hb_bytes_t bytes,
- unsigned int *text_size /* IN/OUT */,
- typename out_utf_t::codepoint_t *text /* OUT */)
-{
- unsigned int src_len = bytes.length / sizeof (typename in_utf_t::codepoint_t);
- const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes.arrayZ;
- const typename in_utf_t::codepoint_t *src_end = src + src_len;
-
- typename out_utf_t::codepoint_t *dst = text;
-
- hb_codepoint_t unicode;
- const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
-
- if (text_size && *text_size)
- {
- (*text_size)--; /* Same room for NUL-termination. */
- const typename out_utf_t::codepoint_t *dst_end = text + *text_size;
-
- while (src < src_end && dst < dst_end)
- {
- const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement);
- typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode);
- if (dst_next == dst)
- break; /* Out-of-room. */
-
- dst = dst_next;
- src = src_next;
- }
-
- *text_size = dst - text;
- *dst = 0; /* NUL-terminate. */
- }
-
- /* Accumulate length of rest. */
- unsigned int dst_len = dst - text;
- while (src < src_end)
- {
- src = in_utf_t::next (src, src_end, &unicode, replacement);
- dst_len += out_utf_t::encode_len (unicode);
- }
- return dst_len;
-}
-
template <typename utf_t>
static inline unsigned int
hb_ot_name_get_utf (hb_face_t *face,
@@ -130,10 +84,10 @@
hb_bytes_t bytes = name.get_name (idx);
if (width == 2) /* UTF16-BE */
- return hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (bytes, text_size, text);
+ return OT::hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (bytes, text_size, text);
if (width == 1) /* ASCII */
- return hb_ot_name_convert_utf<hb_ascii_t, utf_t> (bytes, text_size, text);
+ return OT::hb_ot_name_convert_utf<hb_ascii_t, utf_t> (bytes, text_size, text);
}
if (text_size)
@@ -227,5 +181,4 @@
return hb_ot_name_get_utf<hb_utf32_t> (face, name_id, language, text_size, text);
}
-
#endif
diff --git a/src/hb-ot-os2-table.hh b/src/hb-ot-os2-table.hh
index c6e8fad..5b017d5 100644
--- a/src/hb-ot-os2-table.hh
+++ b/src/hb-ot-os2-table.hh
@@ -212,17 +212,6 @@
TRACE_SUBSET (this);
OS2 *os2_prime = c->serializer->embed (this);
if (unlikely (!os2_prime)) return_trace (false);
- if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES)
- return_trace (true);
-
- /* when --gids option is not used, no need to do collect_mapping that is
- * iterating all codepoints in each subtable, which is not efficient */
- uint16_t min_cp, max_cp;
- find_min_and_max_codepoint (c->plan->unicodes, &min_cp, &max_cp);
- os2_prime->usFirstCharIndex = min_cp;
- os2_prime->usLastCharIndex = max_cp;
-
- _update_unicode_ranges (c->plan->unicodes, os2_prime->ulUnicodeRange);
if (c->plan->user_axes_location->has (HB_TAG ('w','g','h','t')) &&
!c->plan->pinned_at_default)
@@ -244,6 +233,18 @@
return_trace (false);
}
+ if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES)
+ return_trace (true);
+
+ /* when --gids option is not used, no need to do collect_mapping that is
+ * iterating all codepoints in each subtable, which is not efficient */
+ uint16_t min_cp, max_cp;
+ find_min_and_max_codepoint (c->plan->unicodes, &min_cp, &max_cp);
+ os2_prime->usFirstCharIndex = min_cp;
+ os2_prime->usLastCharIndex = max_cp;
+
+ _update_unicode_ranges (c->plan->unicodes, os2_prime->ulUnicodeRange);
+
return_trace (true);
}
diff --git a/src/hb-ot-post-table-v2subset.hh b/src/hb-ot-post-table-v2subset.hh
index 4d427e5..951e639 100644
--- a/src/hb-ot-post-table-v2subset.hh
+++ b/src/hb-ot-post-table-v2subset.hh
@@ -78,14 +78,14 @@
post::accelerator_t _post (c->plan->source);
- hb_hashmap_t<hb_bytes_t, unsigned, true> glyph_name_to_new_index;
+ hb_hashmap_t<hb_bytes_t, uint32_t, true> glyph_name_to_new_index;
for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
{
hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
unsigned old_index = glyphNameIndex[old_gid];
unsigned new_index;
- const unsigned *new_index2;
+ const uint32_t *new_index2;
if (old_index <= 257) new_index = old_index;
else if (old_new_index_map.has (old_index, &new_index2))
{
diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh
index 59c1de3..a04b803 100644
--- a/src/hb-ot-post-table.hh
+++ b/src/hb-ot-post-table.hh
@@ -84,7 +84,7 @@
post *post_prime = c->allocate_min<post> ();
if (unlikely (!post_prime)) return_trace (false);
- memcpy (post_prime, this, post::min_size);
+ hb_memcpy (post_prime, this, post::min_size);
if (!glyph_names)
return_trace (c->check_assign (post_prime->version.major, 3,
HB_SERIALIZE_ERROR_INT_OVERFLOW)); // Version 3 does not have any glyph names.
diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc
index 7db0b25..897377a 100644
--- a/src/hb-ot-shape-normalize.cc
+++ b/src/hb-ot-shape-normalize.cc
@@ -341,7 +341,7 @@
{
unsigned int end;
for (end = buffer->idx + 1; end < count; end++)
- if (unlikely (_hb_glyph_info_is_unicode_mark (&buffer->info[end])))
+ if (_hb_glyph_info_is_unicode_mark (&buffer->info[end]))
break;
if (end < count)
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 249b5a8..bbdfc21 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -91,9 +91,11 @@
script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE;
script_fallback_mark_positioning = shaper->fallback_position;
+#ifndef HB_NO_AAT_SHAPE
/* https://github.com/harfbuzz/harfbuzz/issues/1528 */
if (apply_morx && shaper != &_hb_ot_shaper_default)
shaper = &_hb_ot_shaper_dumber;
+#endif
}
void
@@ -864,7 +866,7 @@
}
}
else
- hb_ot_layout_delete_glyphs_inplace (buffer, _hb_glyph_info_is_default_ignorable);
+ buffer->delete_glyphs_inplace (_hb_glyph_info_is_default_ignorable);
}
diff --git a/src/hb-ot-shape.hh b/src/hb-ot-shape.hh
index cd6f15c..ace2860 100644
--- a/src/hb-ot-shape.hh
+++ b/src/hb-ot-shape.hh
@@ -51,7 +51,7 @@
bool equal (const hb_ot_shape_plan_key_t *other)
{
- return 0 == memcmp (this, other, sizeof (*this));
+ return 0 == hb_memcmp (this, other, sizeof (*this));
}
};
diff --git a/src/hb-ot-shaper-arabic.cc b/src/hb-ot-shaper-arabic.cc
index ed2748b..2332ae3 100644
--- a/src/hb-ot-shaper-arabic.cc
+++ b/src/hb-ot-shaper-arabic.cc
@@ -161,22 +161,23 @@
};
-static void
+static bool
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
-static void
+static bool
record_stch (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
-static void
+static bool
deallocate_buffer_var (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
+ return false;
}
static void
@@ -412,19 +413,19 @@
setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script);
}
-static void
+static bool
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#ifdef HB_NO_OT_SHAPER_ARABIC_FALLBACK
- return;
+ return false;
#endif
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
if (!arabic_plan->do_fallback)
- return;
+ return false;
retry:
arabic_fallback_plan_t *fallback_plan = arabic_plan->fallback_plan;
@@ -440,6 +441,7 @@
}
arabic_fallback_plan_shape (fallback_plan, font, buffer);
+ return true;
}
/*
@@ -450,14 +452,14 @@
* marks can use it as well.
*/
-static void
+static bool
record_stch (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
if (!arabic_plan->has_stch)
- return;
+ return false;
/* 'stch' feature was just applied. Look for anything that multiplied,
* and record it for stch treatment later. Note that rtlm, frac, etc
@@ -473,6 +475,7 @@
info[i].arabic_shaping_action() = comp % 2 ? STCH_REPEATING : STCH_FIXED;
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH;
}
+ return false;
}
static void
diff --git a/src/hb-ot-shaper-default.cc b/src/hb-ot-shaper-default.cc
index 2f6f499..f0404a4 100644
--- a/src/hb-ot-shaper-default.cc
+++ b/src/hb-ot-shaper-default.cc
@@ -49,6 +49,7 @@
true, /* fallback_position */
};
+#ifndef HB_NO_AAT_SHAPE
/* Same as default but no mark advance zeroing / fallback positioning.
* Dumbest shaper ever, basically. */
const hb_ot_shaper_t _hb_ot_shaper_dumber =
@@ -68,6 +69,7 @@
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};
+#endif
#endif
diff --git a/src/hb-ot-shaper-indic-machine.hh b/src/hb-ot-shaper-indic-machine.hh
index d52b13f..d6c67b8 100644
--- a/src/hb-ot-shaper-indic-machine.hh
+++ b/src/hb-ot-shaper-indic-machine.hh
@@ -53,7 +53,7 @@
};
-#line 57 "hb-ot-shaper-indic-machine.hh"
+#line 54 "hb-ot-shaper-indic-machine.hh"
#define indic_syllable_machine_ex_A 9u
#define indic_syllable_machine_ex_C 1u
#define indic_syllable_machine_ex_CM 16u
@@ -61,6 +61,7 @@
#define indic_syllable_machine_ex_DOTTEDCIRCLE 11u
#define indic_syllable_machine_ex_H 4u
#define indic_syllable_machine_ex_M 7u
+#define indic_syllable_machine_ex_MPst 13u
#define indic_syllable_machine_ex_N 3u
#define indic_syllable_machine_ex_PLACEHOLDER 10u
#define indic_syllable_machine_ex_RS 12u
@@ -75,268 +76,302 @@
#define indic_syllable_machine_ex_ZWNJ 5u
-#line 79 "hb-ot-shaper-indic-machine.hh"
+#line 75 "hb-ot-shaper-indic-machine.hh"
static const unsigned char _indic_syllable_machine_trans_keys[] = {
- 8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 8u, 8u, 8u,
- 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 12u, 4u, 12u, 8u, 8u, 5u, 7u,
- 5u, 8u, 4u, 8u, 4u, 8u, 4u, 12u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u,
- 4u, 8u, 5u, 8u, 8u, 8u, 1u, 18u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u,
- 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, 1u, 15u, 1u, 15u, 3u, 9u,
- 4u, 9u, 5u, 9u, 4u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u,
- 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u,
- 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u,
- 4u, 9u, 5u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 4u, 8u,
- 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u,
- 5u, 9u, 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u, 3u, 16u, 4u, 9u,
- 5u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 4u, 12u, 4u, 8u, 3u, 16u,
- 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u,
- 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u, 3u, 16u, 4u, 9u, 5u, 9u,
- 5u, 9u, 3u, 9u, 5u, 9u, 1u, 16u, 3u, 16u, 1u, 16u, 4u, 12u, 5u, 9u,
- 9u, 9u, 5u, 9u, 1u, 15u, 3u, 9u, 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u,
- 1u, 15u, 0
+ 8u, 8u, 4u, 13u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u,
+ 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 4u, 13u,
+ 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u,
+ 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 5u, 13u, 8u, 8u, 1u, 18u,
+ 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u,
+ 1u, 15u, 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u,
+ 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 3u, 16u, 3u, 16u, 4u, 16u,
+ 1u, 15u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u,
+ 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u, 5u, 9u,
+ 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 4u, 13u, 3u, 16u, 3u, 16u,
+ 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u,
+ 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u,
+ 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 4u, 13u, 4u, 13u, 3u, 16u, 3u, 16u,
+ 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u,
+ 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u,
+ 5u, 9u, 3u, 9u, 5u, 9u, 1u, 16u, 3u, 16u, 1u, 16u, 4u, 13u, 5u, 13u,
+ 5u, 13u, 9u, 9u, 5u, 9u, 1u, 15u, 3u, 9u, 5u, 9u, 5u, 9u, 9u, 9u,
+ 5u, 9u, 1u, 15u, 0
};
static const char _indic_syllable_machine_key_spans[] = {
- 1, 5, 3, 4, 5, 9, 5, 1,
- 3, 4, 5, 9, 9, 9, 1, 3,
- 4, 5, 5, 9, 1, 3, 4, 5,
- 5, 4, 1, 18, 14, 14, 13, 15,
- 5, 5, 1, 5, 15, 15, 15, 7,
- 6, 5, 6, 5, 7, 5, 14, 14,
- 14, 14, 13, 15, 14, 14, 13, 15,
- 5, 1, 5, 15, 15, 7, 6, 5,
- 6, 5, 5, 7, 5, 14, 14, 5,
- 14, 14, 13, 15, 14, 15, 5, 1,
- 5, 15, 15, 7, 6, 5, 14, 6,
- 5, 5, 7, 5, 14, 9, 5, 14,
- 14, 13, 15, 14, 15, 5, 1, 5,
- 15, 15, 7, 6, 5, 14, 6, 5,
- 5, 7, 5, 16, 14, 16, 9, 5,
- 1, 5, 15, 7, 5, 5, 1, 5,
- 15
+ 1, 10, 9, 9, 1, 10, 10, 10,
+ 1, 9, 9, 1, 10, 10, 10, 10,
+ 1, 9, 9, 1, 10, 10, 10, 1,
+ 9, 9, 1, 10, 10, 9, 1, 18,
+ 14, 14, 13, 15, 5, 5, 1, 5,
+ 15, 15, 15, 11, 10, 9, 9, 10,
+ 5, 7, 5, 14, 14, 14, 14, 13,
+ 15, 14, 14, 13, 15, 5, 1, 5,
+ 15, 15, 11, 10, 9, 9, 10, 5,
+ 5, 7, 5, 14, 14, 10, 14, 14,
+ 13, 15, 14, 15, 5, 1, 5, 15,
+ 15, 11, 10, 9, 9, 14, 10, 5,
+ 5, 7, 5, 14, 10, 10, 14, 14,
+ 13, 15, 14, 15, 5, 1, 5, 15,
+ 15, 11, 10, 9, 9, 14, 10, 5,
+ 5, 7, 5, 16, 14, 16, 10, 9,
+ 9, 1, 5, 15, 7, 5, 5, 1,
+ 5, 15
};
static const short _indic_syllable_machine_index_offsets[] = {
- 0, 2, 8, 12, 17, 23, 33, 39,
- 41, 45, 50, 56, 66, 76, 86, 88,
- 92, 97, 103, 109, 119, 121, 125, 130,
- 136, 142, 147, 149, 168, 183, 198, 212,
- 228, 234, 240, 242, 248, 264, 280, 296,
- 304, 311, 317, 324, 330, 338, 344, 359,
- 374, 389, 404, 418, 434, 449, 464, 478,
- 494, 500, 502, 508, 524, 540, 548, 555,
- 561, 568, 574, 580, 588, 594, 609, 624,
- 630, 645, 660, 674, 690, 705, 721, 727,
- 729, 735, 751, 767, 775, 782, 788, 803,
- 810, 816, 822, 830, 836, 851, 861, 867,
- 882, 897, 911, 927, 942, 958, 964, 966,
- 972, 988, 1004, 1012, 1019, 1025, 1040, 1047,
- 1053, 1059, 1067, 1073, 1090, 1105, 1122, 1132,
- 1138, 1140, 1146, 1162, 1170, 1176, 1182, 1184,
- 1190
+ 0, 2, 13, 23, 33, 35, 46, 57,
+ 68, 70, 80, 90, 92, 103, 114, 125,
+ 136, 138, 148, 158, 160, 171, 182, 193,
+ 195, 205, 215, 217, 228, 239, 249, 251,
+ 270, 285, 300, 314, 330, 336, 342, 344,
+ 350, 366, 382, 398, 410, 421, 431, 441,
+ 452, 458, 466, 472, 487, 502, 517, 532,
+ 546, 562, 577, 592, 606, 622, 628, 630,
+ 636, 652, 668, 680, 691, 701, 711, 722,
+ 728, 734, 742, 748, 763, 778, 789, 804,
+ 819, 833, 849, 864, 880, 886, 888, 894,
+ 910, 926, 938, 949, 959, 969, 984, 995,
+ 1001, 1007, 1015, 1021, 1036, 1047, 1058, 1073,
+ 1088, 1102, 1118, 1133, 1149, 1155, 1157, 1163,
+ 1179, 1195, 1207, 1218, 1228, 1238, 1253, 1264,
+ 1270, 1276, 1284, 1290, 1307, 1322, 1339, 1350,
+ 1360, 1370, 1372, 1378, 1394, 1402, 1408, 1414,
+ 1416, 1422
};
static const unsigned char _indic_syllable_machine_indicies[] = {
- 1, 0, 2, 3, 3, 4, 1, 0,
- 3, 3, 4, 0, 3, 3, 4, 1,
- 0, 5, 3, 3, 4, 1, 0, 2,
- 3, 3, 4, 1, 0, 0, 0, 6,
- 0, 8, 9, 9, 10, 11, 7, 11,
- 7, 9, 9, 10, 7, 9, 9, 10,
- 11, 7, 12, 9, 9, 10, 11, 7,
- 8, 9, 9, 10, 11, 7, 7, 7,
- 13, 7, 8, 9, 9, 10, 11, 7,
- 7, 7, 14, 7, 16, 17, 17, 18,
- 19, 15, 15, 15, 20, 15, 19, 15,
- 17, 17, 18, 21, 17, 17, 18, 19,
- 15, 16, 17, 17, 18, 19, 15, 22,
- 17, 17, 18, 19, 15, 24, 25, 25,
- 26, 27, 23, 23, 23, 28, 23, 27,
- 23, 25, 25, 26, 23, 25, 25, 26,
- 27, 23, 24, 25, 25, 26, 27, 23,
- 29, 25, 25, 26, 27, 23, 17, 17,
- 18, 1, 0, 31, 30, 33, 34, 35,
- 36, 37, 38, 18, 19, 39, 40, 40,
- 20, 32, 41, 42, 43, 44, 45, 32,
- 47, 48, 49, 50, 4, 1, 51, 46,
- 46, 6, 46, 46, 46, 52, 46, 53,
- 48, 54, 54, 4, 1, 51, 46, 46,
- 46, 46, 46, 46, 52, 46, 48, 54,
- 54, 4, 1, 51, 46, 46, 46, 46,
- 46, 46, 52, 46, 33, 46, 46, 46,
- 55, 56, 46, 1, 51, 46, 46, 46,
- 46, 46, 33, 46, 57, 57, 46, 1,
- 51, 46, 51, 46, 46, 58, 51, 46,
- 51, 46, 51, 46, 46, 46, 51, 46,
- 33, 46, 59, 46, 57, 57, 46, 1,
- 51, 46, 46, 46, 46, 46, 33, 46,
- 33, 46, 46, 46, 57, 57, 46, 1,
- 51, 46, 46, 46, 46, 46, 33, 46,
- 33, 46, 46, 46, 57, 56, 46, 1,
- 51, 46, 46, 46, 46, 46, 33, 46,
- 60, 61, 62, 62, 4, 1, 51, 46,
- 61, 62, 62, 4, 1, 51, 46, 62,
- 62, 4, 1, 51, 46, 63, 64, 64,
- 4, 1, 51, 46, 55, 65, 46, 1,
- 51, 46, 55, 46, 57, 57, 46, 1,
- 51, 46, 57, 65, 46, 1, 51, 46,
- 47, 48, 54, 54, 4, 1, 51, 46,
- 46, 46, 46, 46, 46, 52, 46, 47,
- 48, 49, 54, 4, 1, 51, 46, 46,
- 6, 46, 46, 46, 52, 46, 67, 68,
- 69, 70, 10, 11, 71, 66, 66, 14,
- 66, 66, 66, 72, 66, 73, 68, 74,
- 70, 10, 11, 71, 66, 66, 66, 66,
- 66, 66, 72, 66, 68, 74, 70, 10,
- 11, 71, 66, 66, 66, 66, 66, 66,
- 72, 66, 75, 66, 66, 66, 76, 77,
- 66, 11, 71, 66, 66, 66, 66, 66,
- 75, 66, 78, 68, 79, 80, 10, 11,
- 71, 66, 66, 13, 66, 66, 66, 72,
- 66, 81, 68, 74, 74, 10, 11, 71,
- 66, 66, 66, 66, 66, 66, 72, 66,
- 68, 74, 74, 10, 11, 71, 66, 66,
- 66, 66, 66, 66, 72, 66, 75, 66,
- 66, 66, 82, 77, 66, 11, 71, 66,
- 66, 66, 66, 66, 75, 66, 71, 66,
- 66, 83, 71, 66, 71, 66, 71, 66,
- 66, 66, 71, 66, 75, 66, 84, 66,
- 82, 82, 66, 11, 71, 66, 66, 66,
- 66, 66, 75, 66, 75, 66, 66, 66,
- 82, 82, 66, 11, 71, 66, 66, 66,
- 66, 66, 75, 66, 85, 86, 87, 87,
- 10, 11, 71, 66, 86, 87, 87, 10,
- 11, 71, 66, 87, 87, 10, 11, 71,
- 66, 88, 89, 89, 10, 11, 71, 66,
- 76, 90, 66, 11, 71, 66, 82, 82,
- 66, 11, 71, 66, 76, 66, 82, 82,
- 66, 11, 71, 66, 82, 90, 66, 11,
- 71, 66, 78, 68, 74, 74, 10, 11,
- 71, 66, 66, 66, 66, 66, 66, 72,
- 66, 78, 68, 79, 74, 10, 11, 71,
- 66, 66, 13, 66, 66, 66, 72, 66,
- 8, 9, 9, 10, 11, 66, 67, 68,
- 74, 70, 10, 11, 71, 66, 66, 66,
- 66, 66, 66, 72, 66, 92, 36, 93,
- 93, 18, 19, 39, 91, 91, 91, 91,
- 91, 91, 43, 91, 36, 93, 93, 18,
- 19, 39, 91, 91, 91, 91, 91, 91,
- 43, 91, 94, 91, 91, 91, 95, 96,
- 91, 19, 39, 91, 91, 91, 91, 91,
- 94, 91, 35, 36, 97, 98, 18, 19,
- 39, 91, 91, 20, 91, 91, 91, 43,
- 91, 94, 91, 91, 91, 99, 96, 91,
- 19, 39, 91, 91, 91, 91, 91, 94,
- 91, 39, 91, 91, 100, 39, 91, 39,
- 91, 39, 91, 91, 91, 39, 91, 94,
- 91, 101, 91, 99, 99, 91, 19, 39,
- 91, 91, 91, 91, 91, 94, 91, 94,
- 91, 91, 91, 99, 99, 91, 19, 39,
- 91, 91, 91, 91, 91, 94, 91, 102,
- 103, 104, 104, 18, 19, 39, 91, 103,
- 104, 104, 18, 19, 39, 91, 104, 104,
- 18, 19, 39, 91, 35, 36, 93, 93,
- 18, 19, 39, 91, 91, 91, 91, 91,
- 91, 43, 91, 105, 106, 106, 18, 19,
- 39, 91, 95, 107, 91, 19, 39, 91,
- 99, 99, 91, 19, 39, 91, 95, 91,
- 99, 99, 91, 19, 39, 91, 99, 107,
- 91, 19, 39, 91, 35, 36, 97, 93,
- 18, 19, 39, 91, 91, 20, 91, 91,
- 91, 43, 91, 16, 17, 17, 18, 19,
- 108, 108, 108, 20, 108, 16, 17, 17,
- 18, 19, 108, 110, 111, 112, 113, 26,
- 27, 114, 109, 109, 28, 109, 109, 109,
- 115, 109, 116, 111, 113, 113, 26, 27,
- 114, 109, 109, 109, 109, 109, 109, 115,
- 109, 111, 113, 113, 26, 27, 114, 109,
- 109, 109, 109, 109, 109, 115, 109, 117,
- 109, 109, 109, 118, 119, 109, 27, 114,
- 109, 109, 109, 109, 109, 117, 109, 110,
- 111, 112, 40, 26, 27, 114, 109, 109,
- 28, 109, 109, 109, 115, 109, 117, 109,
- 109, 109, 120, 119, 109, 27, 114, 109,
- 109, 109, 109, 109, 117, 109, 114, 109,
- 109, 121, 114, 109, 114, 109, 114, 109,
- 109, 109, 114, 109, 117, 109, 122, 109,
- 120, 120, 109, 27, 114, 109, 109, 109,
- 109, 109, 117, 109, 117, 109, 109, 109,
- 120, 120, 109, 27, 114, 109, 109, 109,
- 109, 109, 117, 109, 123, 124, 125, 125,
- 26, 27, 114, 109, 124, 125, 125, 26,
- 27, 114, 109, 125, 125, 26, 27, 114,
- 109, 110, 111, 113, 113, 26, 27, 114,
- 109, 109, 109, 109, 109, 109, 115, 109,
- 126, 127, 127, 26, 27, 114, 109, 118,
- 128, 109, 27, 114, 109, 120, 120, 109,
- 27, 114, 109, 118, 109, 120, 120, 109,
- 27, 114, 109, 120, 128, 109, 27, 114,
- 109, 33, 34, 35, 36, 97, 93, 18,
- 19, 39, 40, 40, 20, 91, 91, 33,
- 43, 91, 47, 129, 49, 50, 4, 1,
- 51, 46, 46, 6, 46, 46, 46, 52,
- 46, 33, 34, 35, 36, 130, 131, 18,
- 132, 133, 46, 40, 20, 46, 46, 33,
- 43, 46, 16, 134, 134, 18, 132, 51,
- 46, 46, 20, 46, 133, 46, 46, 135,
- 133, 46, 133, 46, 133, 46, 46, 46,
- 133, 46, 33, 46, 59, 16, 134, 134,
- 18, 132, 51, 46, 46, 46, 46, 46,
- 33, 46, 137, 136, 138, 138, 136, 31,
- 139, 136, 138, 138, 136, 31, 139, 136,
- 139, 136, 136, 140, 139, 136, 139, 136,
- 139, 136, 136, 136, 139, 136, 33, 108,
- 108, 108, 108, 108, 108, 108, 108, 40,
- 108, 108, 108, 108, 33, 108, 0
+ 1, 0, 2, 3, 3, 4, 5, 0,
+ 0, 0, 0, 4, 0, 3, 3, 4,
+ 6, 0, 0, 0, 0, 4, 0, 3,
+ 3, 4, 5, 0, 0, 0, 0, 4,
+ 0, 4, 0, 7, 3, 3, 4, 5,
+ 0, 0, 0, 0, 4, 0, 2, 3,
+ 3, 4, 5, 0, 0, 0, 8, 4,
+ 0, 10, 11, 11, 12, 13, 9, 9,
+ 9, 9, 12, 9, 14, 9, 11, 11,
+ 12, 15, 9, 9, 9, 9, 12, 9,
+ 11, 11, 12, 13, 9, 9, 9, 9,
+ 12, 9, 12, 9, 16, 11, 11, 12,
+ 13, 9, 9, 9, 9, 12, 9, 10,
+ 11, 11, 12, 13, 9, 9, 9, 17,
+ 12, 9, 10, 11, 11, 12, 13, 9,
+ 9, 9, 18, 12, 9, 20, 21, 21,
+ 22, 23, 19, 19, 19, 24, 22, 19,
+ 25, 19, 21, 21, 22, 27, 26, 26,
+ 26, 26, 22, 26, 21, 21, 22, 23,
+ 19, 19, 19, 19, 22, 19, 22, 26,
+ 20, 21, 21, 22, 23, 19, 19, 19,
+ 19, 22, 19, 28, 21, 21, 22, 23,
+ 19, 19, 19, 19, 22, 19, 30, 31,
+ 31, 32, 33, 29, 29, 29, 34, 32,
+ 29, 35, 29, 31, 31, 32, 36, 29,
+ 29, 29, 29, 32, 29, 31, 31, 32,
+ 33, 29, 29, 29, 29, 32, 29, 32,
+ 29, 30, 31, 31, 32, 33, 29, 29,
+ 29, 29, 32, 29, 37, 31, 31, 32,
+ 33, 29, 29, 29, 29, 32, 29, 21,
+ 21, 22, 38, 0, 0, 0, 0, 22,
+ 0, 40, 39, 42, 43, 44, 45, 46,
+ 47, 22, 23, 48, 49, 49, 24, 22,
+ 50, 51, 52, 53, 54, 41, 56, 57,
+ 58, 59, 4, 5, 60, 55, 55, 8,
+ 4, 55, 55, 61, 55, 62, 57, 63,
+ 63, 4, 5, 60, 55, 55, 55, 4,
+ 55, 55, 61, 55, 57, 63, 63, 4,
+ 5, 60, 55, 55, 55, 4, 55, 55,
+ 61, 55, 42, 55, 55, 55, 64, 65,
+ 55, 1, 60, 55, 55, 55, 55, 55,
+ 42, 55, 66, 66, 55, 1, 60, 55,
+ 60, 55, 55, 67, 60, 55, 60, 55,
+ 60, 55, 55, 55, 60, 55, 42, 55,
+ 68, 55, 66, 66, 55, 1, 60, 55,
+ 55, 55, 55, 55, 42, 55, 42, 55,
+ 55, 55, 66, 66, 55, 1, 60, 55,
+ 55, 55, 55, 55, 42, 55, 42, 55,
+ 55, 55, 66, 65, 55, 1, 60, 55,
+ 55, 55, 55, 55, 42, 55, 69, 70,
+ 71, 71, 4, 5, 60, 55, 55, 55,
+ 4, 55, 70, 71, 71, 4, 5, 60,
+ 55, 55, 55, 4, 55, 71, 71, 4,
+ 5, 60, 55, 55, 55, 4, 55, 60,
+ 55, 55, 67, 60, 55, 55, 55, 4,
+ 55, 72, 73, 73, 4, 5, 60, 55,
+ 55, 55, 4, 55, 64, 74, 55, 1,
+ 60, 55, 64, 55, 66, 66, 55, 1,
+ 60, 55, 66, 74, 55, 1, 60, 55,
+ 56, 57, 63, 63, 4, 5, 60, 55,
+ 55, 55, 4, 55, 55, 61, 55, 56,
+ 57, 58, 63, 4, 5, 60, 55, 55,
+ 8, 4, 55, 55, 61, 55, 76, 77,
+ 78, 79, 12, 13, 80, 75, 75, 18,
+ 12, 75, 75, 81, 75, 82, 77, 83,
+ 79, 12, 13, 80, 75, 75, 75, 12,
+ 75, 75, 81, 75, 77, 83, 79, 12,
+ 13, 80, 75, 75, 75, 12, 75, 75,
+ 81, 75, 84, 75, 75, 75, 85, 86,
+ 75, 14, 80, 75, 75, 75, 75, 75,
+ 84, 75, 87, 77, 88, 89, 12, 13,
+ 80, 75, 75, 17, 12, 75, 75, 81,
+ 75, 90, 77, 83, 83, 12, 13, 80,
+ 75, 75, 75, 12, 75, 75, 81, 75,
+ 77, 83, 83, 12, 13, 80, 75, 75,
+ 75, 12, 75, 75, 81, 75, 84, 75,
+ 75, 75, 91, 86, 75, 14, 80, 75,
+ 75, 75, 75, 75, 84, 75, 80, 75,
+ 75, 92, 80, 75, 80, 75, 80, 75,
+ 75, 75, 80, 75, 84, 75, 93, 75,
+ 91, 91, 75, 14, 80, 75, 75, 75,
+ 75, 75, 84, 75, 84, 75, 75, 75,
+ 91, 91, 75, 14, 80, 75, 75, 75,
+ 75, 75, 84, 75, 94, 95, 96, 96,
+ 12, 13, 80, 75, 75, 75, 12, 75,
+ 95, 96, 96, 12, 13, 80, 75, 75,
+ 75, 12, 75, 96, 96, 12, 13, 80,
+ 75, 75, 75, 12, 75, 80, 75, 75,
+ 92, 80, 75, 75, 75, 12, 75, 97,
+ 98, 98, 12, 13, 80, 75, 75, 75,
+ 12, 75, 85, 99, 75, 14, 80, 75,
+ 91, 91, 75, 14, 80, 75, 85, 75,
+ 91, 91, 75, 14, 80, 75, 91, 99,
+ 75, 14, 80, 75, 87, 77, 83, 83,
+ 12, 13, 80, 75, 75, 75, 12, 75,
+ 75, 81, 75, 87, 77, 88, 83, 12,
+ 13, 80, 75, 75, 17, 12, 75, 75,
+ 81, 75, 10, 11, 11, 12, 13, 75,
+ 75, 75, 75, 12, 75, 76, 77, 83,
+ 79, 12, 13, 80, 75, 75, 75, 12,
+ 75, 75, 81, 75, 101, 45, 102, 102,
+ 22, 23, 48, 100, 100, 100, 22, 100,
+ 100, 52, 100, 45, 102, 102, 22, 23,
+ 48, 100, 100, 100, 22, 100, 100, 52,
+ 100, 103, 100, 100, 100, 104, 105, 100,
+ 25, 48, 100, 100, 100, 100, 100, 103,
+ 100, 44, 45, 106, 107, 22, 23, 48,
+ 100, 100, 24, 22, 100, 100, 52, 100,
+ 103, 100, 100, 100, 108, 105, 100, 25,
+ 48, 100, 100, 100, 100, 100, 103, 100,
+ 48, 100, 100, 109, 48, 100, 48, 100,
+ 48, 100, 100, 100, 48, 100, 103, 100,
+ 110, 100, 108, 108, 100, 25, 48, 100,
+ 100, 100, 100, 100, 103, 100, 103, 100,
+ 100, 100, 108, 108, 100, 25, 48, 100,
+ 100, 100, 100, 100, 103, 100, 111, 112,
+ 113, 113, 22, 23, 48, 100, 100, 100,
+ 22, 100, 112, 113, 113, 22, 23, 48,
+ 100, 100, 100, 22, 100, 113, 113, 22,
+ 23, 48, 100, 100, 100, 22, 100, 48,
+ 100, 100, 109, 48, 100, 100, 100, 22,
+ 100, 44, 45, 102, 102, 22, 23, 48,
+ 100, 100, 100, 22, 100, 100, 52, 100,
+ 114, 115, 115, 22, 23, 48, 100, 100,
+ 100, 22, 100, 104, 116, 100, 25, 48,
+ 100, 108, 108, 100, 25, 48, 100, 104,
+ 100, 108, 108, 100, 25, 48, 100, 108,
+ 116, 100, 25, 48, 100, 44, 45, 106,
+ 102, 22, 23, 48, 100, 100, 24, 22,
+ 100, 100, 52, 100, 20, 21, 21, 22,
+ 23, 117, 117, 117, 24, 22, 117, 20,
+ 21, 21, 22, 23, 117, 117, 117, 117,
+ 22, 117, 119, 120, 121, 122, 32, 33,
+ 123, 118, 118, 34, 32, 118, 118, 124,
+ 118, 125, 120, 122, 122, 32, 33, 123,
+ 118, 118, 118, 32, 118, 118, 124, 118,
+ 120, 122, 122, 32, 33, 123, 118, 118,
+ 118, 32, 118, 118, 124, 118, 126, 118,
+ 118, 118, 127, 128, 118, 35, 123, 118,
+ 118, 118, 118, 118, 126, 118, 119, 120,
+ 121, 49, 32, 33, 123, 118, 118, 34,
+ 32, 118, 118, 124, 118, 126, 118, 118,
+ 118, 129, 128, 118, 35, 123, 118, 118,
+ 118, 118, 118, 126, 118, 123, 118, 118,
+ 130, 123, 118, 123, 118, 123, 118, 118,
+ 118, 123, 118, 126, 118, 131, 118, 129,
+ 129, 118, 35, 123, 118, 118, 118, 118,
+ 118, 126, 118, 126, 118, 118, 118, 129,
+ 129, 118, 35, 123, 118, 118, 118, 118,
+ 118, 126, 118, 132, 133, 134, 134, 32,
+ 33, 123, 118, 118, 118, 32, 118, 133,
+ 134, 134, 32, 33, 123, 118, 118, 118,
+ 32, 118, 134, 134, 32, 33, 123, 118,
+ 118, 118, 32, 118, 123, 118, 118, 130,
+ 123, 118, 118, 118, 32, 118, 119, 120,
+ 122, 122, 32, 33, 123, 118, 118, 118,
+ 32, 118, 118, 124, 118, 135, 136, 136,
+ 32, 33, 123, 118, 118, 118, 32, 118,
+ 127, 137, 118, 35, 123, 118, 129, 129,
+ 118, 35, 123, 118, 127, 118, 129, 129,
+ 118, 35, 123, 118, 129, 137, 118, 35,
+ 123, 118, 42, 43, 44, 45, 106, 102,
+ 22, 23, 48, 49, 49, 24, 22, 100,
+ 42, 52, 100, 56, 138, 58, 59, 4,
+ 5, 60, 55, 55, 8, 4, 55, 55,
+ 61, 55, 42, 43, 44, 45, 139, 140,
+ 22, 141, 142, 55, 49, 24, 22, 55,
+ 42, 52, 55, 20, 143, 143, 22, 141,
+ 60, 55, 55, 24, 22, 55, 60, 55,
+ 55, 67, 60, 55, 55, 55, 22, 55,
+ 142, 55, 55, 144, 142, 55, 55, 55,
+ 22, 55, 142, 55, 142, 55, 55, 55,
+ 142, 55, 42, 55, 68, 20, 143, 143,
+ 22, 141, 60, 55, 55, 55, 22, 55,
+ 42, 55, 146, 145, 147, 147, 145, 40,
+ 148, 145, 147, 147, 145, 40, 148, 145,
+ 148, 145, 145, 149, 148, 145, 148, 145,
+ 148, 145, 145, 145, 148, 145, 42, 117,
+ 117, 117, 117, 117, 117, 117, 117, 49,
+ 117, 117, 117, 117, 42, 117, 0
};
static const unsigned char _indic_syllable_machine_trans_targs[] = {
- 27, 33, 38, 2, 39, 45, 46, 27,
- 55, 8, 61, 56, 68, 69, 72, 27,
- 77, 15, 83, 78, 86, 27, 91, 27,
- 100, 21, 106, 101, 109, 114, 27, 125,
- 27, 28, 48, 73, 75, 93, 94, 79,
- 95, 115, 116, 87, 123, 128, 27, 29,
- 31, 5, 47, 34, 42, 30, 1, 32,
- 36, 0, 35, 37, 40, 41, 3, 43,
- 4, 44, 27, 49, 51, 12, 71, 57,
- 64, 50, 6, 52, 66, 59, 53, 11,
- 70, 54, 7, 58, 60, 62, 63, 9,
- 65, 10, 67, 27, 74, 17, 76, 89,
- 81, 13, 92, 14, 80, 82, 84, 85,
- 16, 88, 18, 90, 27, 27, 96, 98,
- 19, 23, 102, 110, 97, 99, 112, 104,
- 20, 103, 105, 107, 108, 22, 111, 24,
- 113, 117, 118, 122, 119, 120, 25, 121,
- 27, 124, 26, 126, 127
+ 31, 37, 42, 2, 43, 46, 4, 50,
+ 51, 31, 60, 9, 66, 69, 61, 11,
+ 74, 75, 78, 31, 83, 17, 89, 92,
+ 93, 84, 31, 19, 98, 31, 107, 24,
+ 113, 116, 117, 108, 26, 122, 127, 31,
+ 134, 31, 32, 53, 79, 81, 100, 101,
+ 85, 102, 123, 124, 94, 132, 137, 31,
+ 33, 35, 6, 52, 38, 47, 34, 1,
+ 36, 40, 0, 39, 41, 44, 45, 3,
+ 48, 5, 49, 31, 54, 56, 14, 77,
+ 62, 70, 55, 7, 57, 72, 64, 58,
+ 13, 76, 59, 8, 63, 65, 67, 68,
+ 10, 71, 12, 73, 31, 80, 20, 82,
+ 96, 87, 15, 99, 16, 86, 88, 90,
+ 91, 18, 95, 21, 97, 31, 31, 103,
+ 105, 22, 27, 109, 118, 104, 106, 120,
+ 111, 23, 110, 112, 114, 115, 25, 119,
+ 28, 121, 125, 126, 131, 128, 129, 29,
+ 130, 31, 133, 30, 135, 136
};
static const char _indic_syllable_machine_trans_actions[] = {
- 1, 0, 2, 0, 2, 2, 2, 3,
- 2, 0, 2, 0, 2, 2, 2, 4,
- 2, 0, 5, 0, 5, 6, 2, 7,
- 2, 0, 2, 0, 2, 2, 8, 0,
- 11, 2, 2, 5, 0, 12, 12, 0,
- 2, 5, 2, 5, 2, 0, 13, 2,
- 0, 0, 2, 0, 2, 2, 0, 2,
- 2, 0, 0, 2, 2, 2, 0, 0,
- 0, 2, 14, 2, 0, 0, 2, 0,
- 2, 2, 0, 2, 2, 2, 2, 0,
+ 1, 0, 2, 0, 2, 0, 0, 2,
+ 2, 3, 2, 0, 2, 0, 0, 0,
+ 2, 2, 2, 4, 2, 0, 5, 0,
+ 5, 0, 6, 0, 2, 7, 2, 0,
+ 2, 0, 2, 0, 0, 2, 0, 8,
+ 0, 11, 2, 2, 5, 0, 12, 12,
+ 0, 2, 5, 2, 5, 2, 0, 13,
+ 2, 0, 0, 2, 0, 2, 2, 0,
2, 2, 0, 0, 2, 2, 2, 0,
- 0, 0, 2, 15, 5, 0, 5, 2,
- 2, 0, 5, 0, 0, 2, 5, 5,
- 0, 0, 0, 2, 16, 17, 2, 0,
- 0, 0, 0, 2, 2, 2, 2, 2,
- 0, 0, 2, 2, 2, 0, 0, 0,
- 2, 0, 18, 18, 0, 0, 0, 0,
- 19, 2, 0, 0, 0
+ 0, 0, 2, 14, 2, 0, 0, 2,
+ 0, 2, 2, 0, 2, 2, 2, 2,
+ 0, 2, 2, 0, 0, 2, 2, 2,
+ 0, 0, 0, 2, 15, 5, 0, 5,
+ 2, 2, 0, 5, 0, 0, 2, 5,
+ 5, 0, 0, 0, 2, 16, 17, 2,
+ 0, 0, 0, 0, 2, 2, 2, 2,
+ 2, 0, 0, 2, 2, 2, 0, 0,
+ 0, 2, 0, 18, 18, 0, 0, 0,
+ 0, 19, 2, 0, 0, 0
};
static const char _indic_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 9, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 9,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -349,14 +384,15 @@
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 _indic_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 10, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 10,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -369,41 +405,43 @@
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 _indic_syllable_machine_eof_trans[] = {
- 1, 1, 1, 1, 1, 1, 8, 8,
- 8, 8, 8, 8, 8, 16, 16, 22,
- 16, 16, 16, 24, 24, 24, 24, 24,
- 24, 1, 31, 0, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 67, 67, 67, 67, 67, 67, 67, 67,
- 67, 67, 67, 67, 67, 67, 67, 67,
- 67, 67, 67, 67, 67, 67, 67, 67,
- 67, 92, 92, 92, 92, 92, 92, 92,
- 92, 92, 92, 92, 92, 92, 92, 92,
- 92, 92, 92, 92, 92, 109, 109, 110,
- 110, 110, 110, 110, 110, 110, 110, 110,
- 110, 110, 110, 110, 110, 110, 110, 110,
- 110, 110, 110, 92, 47, 47, 47, 47,
- 47, 47, 47, 137, 137, 137, 137, 137,
- 109
+ 1, 1, 1, 1, 1, 1, 1, 10,
+ 10, 10, 10, 10, 10, 10, 10, 20,
+ 20, 27, 20, 27, 20, 20, 30, 30,
+ 30, 30, 30, 30, 30, 1, 40, 0,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 101,
+ 101, 101, 101, 101, 101, 101, 101, 101,
+ 101, 101, 101, 101, 101, 101, 101, 101,
+ 101, 101, 101, 101, 118, 118, 119, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119,
+ 119, 119, 119, 101, 56, 56, 56, 56,
+ 56, 56, 56, 56, 146, 146, 146, 146,
+ 146, 118
};
-static const int indic_syllable_machine_start = 27;
-static const int indic_syllable_machine_first_final = 27;
+static const int indic_syllable_machine_start = 31;
+static const int indic_syllable_machine_first_final = 31;
static const int indic_syllable_machine_error = -1;
-static const int indic_syllable_machine_en_main = 27;
+static const int indic_syllable_machine_en_main = 31;
#line 58 "hb-ot-shaper-indic-machine.rl"
-#line 117 "hb-ot-shaper-indic-machine.rl"
+#line 118 "hb-ot-shaper-indic-machine.rl"
#define found_syllable(syllable_type) \
@@ -412,7 +450,7 @@
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
- if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ if (syllable_serial == 16) syllable_serial = 1; \
} HB_STMT_END
inline void
@@ -422,7 +460,7 @@
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 426 "hb-ot-shaper-indic-machine.hh"
+#line 453 "hb-ot-shaper-indic-machine.hh"
{
cs = indic_syllable_machine_start;
ts = 0;
@@ -430,7 +468,7 @@
act = 0;
}
-#line 137 "hb-ot-shaper-indic-machine.rl"
+#line 138 "hb-ot-shaper-indic-machine.rl"
p = 0;
@@ -438,7 +476,7 @@
unsigned int syllable_serial = 1;
-#line 442 "hb-ot-shaper-indic-machine.hh"
+#line 465 "hb-ot-shaper-indic-machine.hh"
{
int _slen;
int _trans;
@@ -452,7 +490,7 @@
#line 1 "NONE"
{ts = p;}
break;
-#line 456 "hb-ot-shaper-indic-machine.hh"
+#line 477 "hb-ot-shaper-indic-machine.hh"
}
_keys = _indic_syllable_machine_trans_keys + (cs<<1);
@@ -475,51 +513,51 @@
{te = p+1;}
break;
case 11:
-#line 113 "hb-ot-shaper-indic-machine.rl"
+#line 114 "hb-ot-shaper-indic-machine.rl"
{te = p+1;{ found_syllable (indic_non_indic_cluster); }}
break;
case 13:
-#line 108 "hb-ot-shaper-indic-machine.rl"
+#line 109 "hb-ot-shaper-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_consonant_syllable); }}
break;
case 14:
-#line 109 "hb-ot-shaper-indic-machine.rl"
+#line 110 "hb-ot-shaper-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_vowel_syllable); }}
break;
case 17:
-#line 110 "hb-ot-shaper-indic-machine.rl"
+#line 111 "hb-ot-shaper-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_standalone_cluster); }}
break;
case 19:
-#line 111 "hb-ot-shaper-indic-machine.rl"
+#line 112 "hb-ot-shaper-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_symbol_cluster); }}
break;
case 15:
-#line 112 "hb-ot-shaper-indic-machine.rl"
+#line 113 "hb-ot-shaper-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
break;
case 16:
-#line 113 "hb-ot-shaper-indic-machine.rl"
+#line 114 "hb-ot-shaper-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_non_indic_cluster); }}
break;
case 1:
-#line 108 "hb-ot-shaper-indic-machine.rl"
+#line 109 "hb-ot-shaper-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }}
break;
case 3:
-#line 109 "hb-ot-shaper-indic-machine.rl"
+#line 110 "hb-ot-shaper-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }}
break;
case 7:
-#line 110 "hb-ot-shaper-indic-machine.rl"
+#line 111 "hb-ot-shaper-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }}
break;
case 8:
-#line 111 "hb-ot-shaper-indic-machine.rl"
+#line 112 "hb-ot-shaper-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }}
break;
case 4:
-#line 112 "hb-ot-shaper-indic-machine.rl"
+#line 113 "hb-ot-shaper-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
break;
case 6:
@@ -540,19 +578,19 @@
case 18:
#line 1 "NONE"
{te = p+1;}
-#line 108 "hb-ot-shaper-indic-machine.rl"
+#line 109 "hb-ot-shaper-indic-machine.rl"
{act = 1;}
break;
case 5:
#line 1 "NONE"
{te = p+1;}
-#line 112 "hb-ot-shaper-indic-machine.rl"
+#line 113 "hb-ot-shaper-indic-machine.rl"
{act = 5;}
break;
case 12:
#line 1 "NONE"
{te = p+1;}
-#line 113 "hb-ot-shaper-indic-machine.rl"
+#line 114 "hb-ot-shaper-indic-machine.rl"
{act = 6;}
break;
#line 559 "hb-ot-shaper-indic-machine.hh"
@@ -564,7 +602,7 @@
#line 1 "NONE"
{ts = 0;}
break;
-#line 568 "hb-ot-shaper-indic-machine.hh"
+#line 566 "hb-ot-shaper-indic-machine.hh"
}
if ( ++p != pe )
@@ -580,7 +618,7 @@
}
-#line 145 "hb-ot-shaper-indic-machine.rl"
+#line 146 "hb-ot-shaper-indic-machine.rl"
}
diff --git a/src/hb-ot-shaper-indic-machine.rl b/src/hb-ot-shaper-indic-machine.rl
index 3274a77..4684188 100644
--- a/src/hb-ot-shaper-indic-machine.rl
+++ b/src/hb-ot-shaper-indic-machine.rl
@@ -74,6 +74,7 @@
export PLACEHOLDER = 10;
export DOTTEDCIRCLE = 11;
export RS = 12;
+export MPst = 13;
export Repha = 14;
export Ra = 15;
export CM = 16;
@@ -88,7 +89,7 @@
cn = c.ZWJ?.n?;
symbol = Symbol.N?;
-matra_group = z*.M.N?.H?;
+matra_group = z*.(M | SM? MPst).N?.H?;
syllable_tail = (z?.SM.SM?.ZWNJ?)? (A | VD)*;
halant_group = (z?.H.(ZWJ.N?)?);
final_halant_group = halant_group | H.ZWNJ;
@@ -122,7 +123,7 @@
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
- if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ if (syllable_serial == 16) syllable_serial = 1; \
} HB_STMT_END
inline void
diff --git a/src/hb-ot-shaper-indic-table.cc b/src/hb-ot-shaper-indic-table.cc
index bf6a275..d9fb051 100644
--- a/src/hb-ot-shaper-indic-table.cc
+++ b/src/hb-ot-shaper-indic-table.cc
@@ -42,6 +42,7 @@
#define OT_PLACEHOLDER I_Cat(PLACEHOLDER)
#define OT_DOTTEDCIRCLE I_Cat(DOTTEDCIRCLE)
#define OT_RS I_Cat(RS)
+#define OT_MPst I_Cat(MPst)
#define OT_Repha I_Cat(Repha)
#define OT_Ra I_Cat(Ra)
#define OT_CM I_Cat(CM)
@@ -80,9 +81,10 @@
#define _OT_CS OT_CS /* 2 chars; CS */
#define _OT_DC OT_DOTTEDCIRCLE /* 1 chars; DOTTEDCIRCLE */
#define _OT_H OT_H /* 11 chars; H */
-#define _OT_M OT_M /* 143 chars; M */
+#define _OT_M OT_M /* 142 chars; M */
#define _OT_MH OT_MH /* 1 chars; MH */
#define _OT_ML OT_ML /* 1 chars; ML */
+#define _OT_MP OT_MPst /* 1 chars; MPst */
#define _OT_MR OT_MR /* 1 chars; MR */
#define _OT_MW OT_MW /* 2 chars; MW */
#define _OT_MY OT_MY /* 3 chars; MY */
@@ -200,7 +202,7 @@
/* 0A28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
/* 0A30 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(X,X),
/* 0A38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(X,X), _(M,AP), _(M,LM),
- /* 0A40 */ _(M,AP), _(M,AP), _(M,AP), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP),
+ /* 0A40 */_(MP,AP), _(M,AP), _(M,AP), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP),
/* 0A48 */ _(M,AP), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X),
/* 0A50 */ _(X,X), _(M,B), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
/* 0A58 */ _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(X,X), _(C,C), _(X,X),
@@ -451,15 +453,12 @@
/* Grantha */
/* 11300 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 11308 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 11310 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 11318 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 11320 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 11328 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 11330 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
+
+#define indic_offset_0x11338u 1720
+
/* 11338 */ _(X,X), _(X,X), _(X,X), _(N,X), _(N,X), _(X,X), _(X,X), _(X,X),
-}; /* Table items: 1776; occupancy: 69% */
+}; /* Table items: 1728; occupancy: 71% */
uint16_t
hb_indic_get_categories (hb_codepoint_t u)
@@ -497,7 +496,8 @@
break;
case 0x11u:
- if (hb_in_range<hb_codepoint_t> (u, 0x11300u, 0x1133Fu)) return indic_table[u - 0x11300u + indic_offset_0x11300u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x11300u, 0x11307u)) return indic_table[u - 0x11300u + indic_offset_0x11300u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x11338u, 0x1133Fu)) return indic_table[u - 0x11338u + indic_offset_0x11338u];
break;
default:
@@ -519,6 +519,7 @@
#undef _OT_M
#undef _OT_MH
#undef _OT_ML
+#undef _OT_MP
#undef _OT_MR
#undef _OT_MW
#undef _OT_MY
diff --git a/src/hb-ot-shaper-indic.cc b/src/hb-ot-shaper-indic.cc
index 55509c1..7652210 100644
--- a/src/hb-ot-shaper-indic.cc
+++ b/src/hb-ot-shaper-indic.cc
@@ -223,15 +223,15 @@
INDIC_BASIC_FEATURES = INDIC_INIT, /* Don't forget to update this! */
};
-static void
+static bool
setup_syllables_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
-static void
+static bool
initial_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
-static void
+static bool
final_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
@@ -413,7 +413,7 @@
set_indic_properties (info[i]);
}
-static void
+static bool
setup_syllables_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
@@ -422,6 +422,7 @@
find_syllables_indic (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
+ return false;
}
static int
@@ -714,6 +715,9 @@
}
}
} else if (info[i].indic_position() != POS_SMVD) {
+ if (info[i].indic_category() == I_Cat(MPst) &&
+ i > start && info[i - 1].indic_category() == I_Cat(SM))
+ info[i - 1].indic_position() = info[i].indic_position();
last_pos = (indic_position_t) info[i].indic_position();
}
}
@@ -729,7 +733,7 @@
if (info[j].indic_position() < POS_SMVD)
info[j].indic_position() = info[i].indic_position();
last = i;
- } else if (info[i].indic_category() == I_Cat(M))
+ } else if (FLAG_UNSAFE (info[i].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst))))
last = i;
}
@@ -742,14 +746,40 @@
/* Sit tight, rock 'n roll! */
hb_stable_sort (info + start, end - start, compare_indic_order);
- /* Find base again */
+
+ /* Find base again; also flip left-matra sequence. */
+ unsigned first_left_matra = end;
+ unsigned last_left_matra = end;
base = end;
for (unsigned int i = start; i < end; i++)
+ {
if (info[i].indic_position() == POS_BASE_C)
{
base = i;
break;
}
+ else if (info[i].indic_position() == POS_PRE_M)
+ {
+ if (first_left_matra == end)
+ first_left_matra = i;
+ last_left_matra = i;
+ }
+ }
+ /* https://github.com/harfbuzz/harfbuzz/issues/3863 */
+ if (first_left_matra < last_left_matra)
+ {
+ /* No need to merge clusters, handled later. */
+ buffer->reverse_range (first_left_matra, last_left_matra + 1);
+ /* Reverse back nuktas, etc. */
+ unsigned i = first_left_matra;
+ for (unsigned j = i; j <= last_left_matra; j++)
+ if (FLAG_UNSAFE (info[j].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst))))
+ {
+ buffer->reverse_range (i, j + 1);
+ i = j + 1;
+ }
+ }
+
/* Things are out-of-control for post base positions, they may shuffle
* around like crazy. In old-spec mode, we move halants around, so in
* that case merge all clusters after base. Otherwise, check the sort
@@ -955,25 +985,29 @@
}
}
-static void
+static bool
initial_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
+ bool ret = false;
if (!buffer->message (font, "start reordering indic initial"))
- return;
+ return ret;
update_consonant_positions_indic (plan, font, buffer);
- hb_syllabic_insert_dotted_circles (font, buffer,
- indic_broken_cluster,
- I_Cat(DOTTEDCIRCLE),
- I_Cat(Repha),
- POS_END);
+ if (hb_syllabic_insert_dotted_circles (font, buffer,
+ indic_broken_cluster,
+ I_Cat(DOTTEDCIRCLE),
+ I_Cat(Repha),
+ POS_END))
+ ret = true;
foreach_syllable (buffer, start, end)
initial_reordering_syllable_indic (plan, font->face, buffer, start, end);
(void) buffer->message (font, "end reordering indic initial");
+
+ return ret;
}
static void
@@ -1116,7 +1150,7 @@
{
search:
while (new_pos > start &&
- !(is_one_of (info[new_pos], (FLAG (I_Cat(M)) | FLAG (I_Cat(H))))))
+ !(is_one_of (info[new_pos], (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)) | FLAG (I_Cat(H))))))
new_pos--;
/* If we found no Halant we are done.
@@ -1316,7 +1350,8 @@
unlikely (is_halant (info[new_reph_pos])))
{
for (unsigned int i = base + 1; i < new_reph_pos; i++)
- if (info[i].indic_category() == I_Cat(M)) {
+ if (FLAG_UNSAFE (info[i].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst))))
+ {
/* Ok, got it. */
new_reph_pos--;
}
@@ -1376,7 +1411,7 @@
if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
{
while (new_pos > start &&
- !(is_one_of (info[new_pos - 1], FLAG(I_Cat(M)) | FLAG (I_Cat(H)))))
+ !(is_one_of (info[new_pos - 1], FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)) | FLAG (I_Cat(H)))))
new_pos--;
}
@@ -1439,13 +1474,13 @@
}
-static void
+static bool
final_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
- if (unlikely (!count)) return;
+ if (unlikely (!count)) return false;
if (buffer->message (font, "start reordering indic final")) {
foreach_syllable (buffer, start, end)
@@ -1455,6 +1490,8 @@
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
+
+ return false;
}
diff --git a/src/hb-ot-shaper-khmer-machine.hh b/src/hb-ot-shaper-khmer-machine.hh
index e18bd75..fd91ee0 100644
--- a/src/hb-ot-shaper-khmer-machine.hh
+++ b/src/hb-ot-shaper-khmer-machine.hh
@@ -48,7 +48,7 @@
};
-#line 52 "hb-ot-shaper-khmer-machine.hh"
+#line 49 "hb-ot-shaper-khmer-machine.hh"
#define khmer_syllable_machine_ex_C 1u
#define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u
#define khmer_syllable_machine_ex_H 4u
@@ -66,7 +66,7 @@
#define khmer_syllable_machine_ex_ZWNJ 5u
-#line 70 "hb-ot-shaper-khmer-machine.hh"
+#line 65 "hb-ot-shaper-khmer-machine.hh"
static const unsigned char _khmer_syllable_machine_trans_keys[] = {
5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u,
5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u,
@@ -284,7 +284,7 @@
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
- if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ if (syllable_serial == 16) syllable_serial = 1; \
} HB_STMT_END
inline void
@@ -294,7 +294,7 @@
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 298 "hb-ot-shaper-khmer-machine.hh"
+#line 287 "hb-ot-shaper-khmer-machine.hh"
{
cs = khmer_syllable_machine_start;
ts = 0;
@@ -310,7 +310,7 @@
unsigned int syllable_serial = 1;
-#line 314 "hb-ot-shaper-khmer-machine.hh"
+#line 299 "hb-ot-shaper-khmer-machine.hh"
{
int _slen;
int _trans;
@@ -324,7 +324,7 @@
#line 1 "NONE"
{ts = p;}
break;
-#line 328 "hb-ot-shaper-khmer-machine.hh"
+#line 311 "hb-ot-shaper-khmer-machine.hh"
}
_keys = _khmer_syllable_machine_trans_keys + (cs<<1);
@@ -394,7 +394,7 @@
#line 98 "hb-ot-shaper-khmer-machine.rl"
{act = 3;}
break;
-#line 398 "hb-ot-shaper-khmer-machine.hh"
+#line 368 "hb-ot-shaper-khmer-machine.hh"
}
_again:
@@ -403,7 +403,7 @@
#line 1 "NONE"
{ts = 0;}
break;
-#line 407 "hb-ot-shaper-khmer-machine.hh"
+#line 375 "hb-ot-shaper-khmer-machine.hh"
}
if ( ++p != pe )
diff --git a/src/hb-ot-shaper-khmer-machine.rl b/src/hb-ot-shaper-khmer-machine.rl
index f180471..d5d429d 100644
--- a/src/hb-ot-shaper-khmer-machine.rl
+++ b/src/hb-ot-shaper-khmer-machine.rl
@@ -107,7 +107,7 @@
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
- if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ if (syllable_serial == 16) syllable_serial = 1; \
} HB_STMT_END
inline void
diff --git a/src/hb-ot-shaper-khmer.cc b/src/hb-ot-shaper-khmer.cc
index d979558..019a285 100644
--- a/src/hb-ot-shaper-khmer.cc
+++ b/src/hb-ot-shaper-khmer.cc
@@ -89,11 +89,11 @@
info.khmer_category() = (khmer_category_t) (type & 0xFFu);
}
-static void
+static bool
setup_syllables_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
-static void
+static bool
reorder_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
@@ -192,7 +192,7 @@
set_khmer_properties (info[i]);
}
-static void
+static bool
setup_syllables_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
@@ -201,6 +201,7 @@
find_syllables_khmer (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
+ return false;
}
@@ -303,23 +304,27 @@
}
}
-static void
+static bool
reorder_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
+ bool ret = false;
if (buffer->message (font, "start reordering khmer"))
{
- hb_syllabic_insert_dotted_circles (font, buffer,
- khmer_broken_cluster,
- K_Cat(DOTTEDCIRCLE),
- (unsigned) -1);
+ if (hb_syllabic_insert_dotted_circles (font, buffer,
+ khmer_broken_cluster,
+ K_Cat(DOTTEDCIRCLE),
+ (unsigned) -1))
+ ret = true;
foreach_syllable (buffer, start, end)
reorder_syllable_khmer (plan, font->face, buffer, start, end);
(void) buffer->message (font, "end reordering khmer");
}
HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
+
+ return ret;
}
diff --git a/src/hb-ot-shaper-myanmar-machine.hh b/src/hb-ot-shaper-myanmar-machine.hh
index b109708..87cded4 100644
--- a/src/hb-ot-shaper-myanmar-machine.hh
+++ b/src/hb-ot-shaper-myanmar-machine.hh
@@ -50,7 +50,7 @@
};
-#line 54 "hb-ot-shaper-myanmar-machine.hh"
+#line 51 "hb-ot-shaper-myanmar-machine.hh"
#define myanmar_syllable_machine_ex_A 9u
#define myanmar_syllable_machine_ex_As 32u
#define myanmar_syllable_machine_ex_C 1u
@@ -77,7 +77,7 @@
#define myanmar_syllable_machine_ex_ZWNJ 5u
-#line 81 "hb-ot-shaper-myanmar-machine.hh"
+#line 76 "hb-ot-shaper-myanmar-machine.hh"
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
1u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u,
5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 39u, 3u, 39u,
@@ -433,7 +433,7 @@
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
- if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ if (syllable_serial == 16) syllable_serial = 1; \
} HB_STMT_END
inline void
@@ -443,7 +443,7 @@
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 447 "hb-ot-shaper-myanmar-machine.hh"
+#line 436 "hb-ot-shaper-myanmar-machine.hh"
{
cs = myanmar_syllable_machine_start;
ts = 0;
@@ -459,7 +459,7 @@
unsigned int syllable_serial = 1;
-#line 463 "hb-ot-shaper-myanmar-machine.hh"
+#line 448 "hb-ot-shaper-myanmar-machine.hh"
{
int _slen;
int _trans;
@@ -473,7 +473,7 @@
#line 1 "NONE"
{ts = p;}
break;
-#line 477 "hb-ot-shaper-myanmar-machine.hh"
+#line 460 "hb-ot-shaper-myanmar-machine.hh"
}
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@@ -519,7 +519,7 @@
#line 113 "hb-ot-shaper-myanmar-machine.rl"
{te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }}
break;
-#line 523 "hb-ot-shaper-myanmar-machine.hh"
+#line 498 "hb-ot-shaper-myanmar-machine.hh"
}
_again:
@@ -528,7 +528,7 @@
#line 1 "NONE"
{ts = 0;}
break;
-#line 532 "hb-ot-shaper-myanmar-machine.hh"
+#line 505 "hb-ot-shaper-myanmar-machine.hh"
}
if ( ++p != pe )
diff --git a/src/hb-ot-shaper-myanmar-machine.rl b/src/hb-ot-shaper-myanmar-machine.rl
index 2cb6e4e..db6a44c 100644
--- a/src/hb-ot-shaper-myanmar-machine.rl
+++ b/src/hb-ot-shaper-myanmar-machine.rl
@@ -122,7 +122,7 @@
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
- if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ if (syllable_serial == 16) syllable_serial = 1; \
} HB_STMT_END
inline void
diff --git a/src/hb-ot-shaper-myanmar.cc b/src/hb-ot-shaper-myanmar.cc
index 78bd8de..1b2a085 100644
--- a/src/hb-ot-shaper-myanmar.cc
+++ b/src/hb-ot-shaper-myanmar.cc
@@ -98,11 +98,11 @@
}
-static void
+static bool
setup_syllables_myanmar (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
-static void
+static bool
reorder_myanmar (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
@@ -150,7 +150,7 @@
set_myanmar_properties (info[i]);
}
-static void
+static bool
setup_syllables_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
@@ -159,6 +159,7 @@
find_syllables_myanmar (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
+ return false;
}
static int
@@ -270,6 +271,33 @@
/* Sit tight, rock 'n roll! */
buffer->sort (start, end, compare_myanmar_order);
+
+ /* Flip left-matra sequence. */
+ unsigned first_left_matra = end;
+ unsigned last_left_matra = end;
+ for (unsigned int i = start; i < end; i++)
+ {
+ if (info[i].myanmar_position() == POS_PRE_M)
+ {
+ if (first_left_matra == end)
+ first_left_matra = i;
+ last_left_matra = i;
+ }
+ }
+ /* https://github.com/harfbuzz/harfbuzz/issues/3863 */
+ if (first_left_matra < last_left_matra)
+ {
+ /* No need to merge clusters, done already? */
+ buffer->reverse_range (first_left_matra, last_left_matra + 1);
+ /* Reverse back VS, etc. */
+ unsigned i = first_left_matra;
+ for (unsigned j = i; j <= last_left_matra; j++)
+ if (info[j].myanmar_category() == M_Cat(VPre))
+ {
+ buffer->reverse_range (i, j + 1);
+ i = j + 1;
+ }
+ }
}
static void
@@ -291,16 +319,18 @@
}
}
-static void
+static bool
reorder_myanmar (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
+ bool ret = false;
if (buffer->message (font, "start reordering myanmar"))
{
- hb_syllabic_insert_dotted_circles (font, buffer,
- myanmar_broken_cluster,
- M_Cat(DOTTEDCIRCLE));
+ if (hb_syllabic_insert_dotted_circles (font, buffer,
+ myanmar_broken_cluster,
+ M_Cat(DOTTEDCIRCLE)))
+ ret = true;
foreach_syllable (buffer, start, end)
reorder_syllable_myanmar (plan, font->face, buffer, start, end);
@@ -309,6 +339,8 @@
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
+
+ return ret;
}
@@ -331,6 +363,7 @@
};
+#ifndef HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
/* Ugly Zawgyi encoding.
* Disable all auto processing.
* https://github.com/harfbuzz/harfbuzz/issues/1162 */
@@ -351,6 +384,7 @@
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};
+#endif
#endif
diff --git a/src/hb-ot-shaper-syllabic.cc b/src/hb-ot-shaper-syllabic.cc
index a8e0d8e..89226ae 100644
--- a/src/hb-ot-shaper-syllabic.cc
+++ b/src/hb-ot-shaper-syllabic.cc
@@ -29,7 +29,7 @@
#include "hb-ot-shaper-syllabic.hh"
-void
+bool
hb_syllabic_insert_dotted_circles (hb_font_t *font,
hb_buffer_t *buffer,
unsigned int broken_syllable_type,
@@ -38,13 +38,13 @@
int dottedcircle_position)
{
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
- return;
+ return false;
if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE)))
- return;
+ return false;
hb_codepoint_t dottedcircle_glyph;
if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph))
- return;
+ return false;
hb_glyph_info_t dottedcircle = {0};
dottedcircle.codepoint = 0x25CCu;
@@ -84,14 +84,16 @@
(void) buffer->next_glyph ();
}
buffer->sync ();
+ return true;
}
-HB_INTERNAL void
+HB_INTERNAL bool
hb_syllabic_clear_var (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
+ return false;
}
diff --git a/src/hb-ot-shaper-syllabic.hh b/src/hb-ot-shaper-syllabic.hh
index e8a15bb..f240ad1 100644
--- a/src/hb-ot-shaper-syllabic.hh
+++ b/src/hb-ot-shaper-syllabic.hh
@@ -30,7 +30,7 @@
#include "hb-ot-shaper.hh"
-HB_INTERNAL void
+HB_INTERNAL bool
hb_syllabic_insert_dotted_circles (hb_font_t *font,
hb_buffer_t *buffer,
unsigned int broken_syllable_type,
@@ -38,7 +38,7 @@
int repha_category = -1,
int dottedcircle_position = -1);
-HB_INTERNAL void
+HB_INTERNAL bool
hb_syllabic_clear_var (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
diff --git a/src/hb-ot-shaper-thai.cc b/src/hb-ot-shaper-thai.cc
index 15349b1..6cd67cd 100644
--- a/src/hb-ot-shaper-thai.cc
+++ b/src/hb-ot-shaper-thai.cc
@@ -98,9 +98,9 @@
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;
+ uint16_t u;
+ uint16_t win_pua;
+ uint16_t mac_pua;
} const *pua_mappings = nullptr;
static const thai_pua_mapping_t SD_mappings[] = {
{0x0E48u, 0xF70Au, 0xF88Bu}, /* MAI EK */
diff --git a/src/hb-ot-shaper-use-machine.hh b/src/hb-ot-shaper-use-machine.hh
index 41e8a34..f2fbdb7 100644
--- a/src/hb-ot-shaper-use-machine.hh
+++ b/src/hb-ot-shaper-use-machine.hh
@@ -53,7 +53,7 @@
};
-#line 57 "hb-ot-shaper-use-machine.hh"
+#line 54 "hb-ot-shaper-use-machine.hh"
#define use_syllable_machine_ex_B 1u
#define use_syllable_machine_ex_CGJ 6u
#define use_syllable_machine_ex_CMAbv 31u
@@ -97,7 +97,7 @@
#define use_syllable_machine_ex_ZWNJ 14u
-#line 101 "hb-ot-shaper-use-machine.hh"
+#line 96 "hb-ot-shaper-use-machine.hh"
static const unsigned char _use_syllable_machine_trans_keys[] = {
0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u,
14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u,
@@ -839,7 +839,7 @@
for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
- if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ if (syllable_serial == 16) syllable_serial = 1; \
} HB_STMT_END
@@ -929,7 +929,7 @@
unsigned int act HB_UNUSED;
int cs;
-#line 933 "hb-ot-shaper-use-machine.hh"
+#line 922 "hb-ot-shaper-use-machine.hh"
{
cs = use_syllable_machine_start;
ts = 0;
@@ -942,7 +942,7 @@
unsigned int syllable_serial = 1;
-#line 946 "hb-ot-shaper-use-machine.hh"
+#line 931 "hb-ot-shaper-use-machine.hh"
{
int _slen;
int _trans;
@@ -956,7 +956,7 @@
#line 1 "NONE"
{ts = p;}
break;
-#line 960 "hb-ot-shaper-use-machine.hh"
+#line 943 "hb-ot-shaper-use-machine.hh"
}
_keys = _use_syllable_machine_trans_keys + (cs<<1);
@@ -1046,7 +1046,7 @@
#line 178 "hb-ot-shaper-use-machine.rl"
{te = p;p--;{ found_syllable (use_non_cluster); }}
break;
-#line 1050 "hb-ot-shaper-use-machine.hh"
+#line 1014 "hb-ot-shaper-use-machine.hh"
}
_again:
@@ -1055,7 +1055,7 @@
#line 1 "NONE"
{ts = 0;}
break;
-#line 1059 "hb-ot-shaper-use-machine.hh"
+#line 1021 "hb-ot-shaper-use-machine.hh"
}
if ( ++p != pe )
diff --git a/src/hb-ot-shaper-use-machine.rl b/src/hb-ot-shaper-use-machine.rl
index 9f22057..8ace1f0 100644
--- a/src/hb-ot-shaper-use-machine.rl
+++ b/src/hb-ot-shaper-use-machine.rl
@@ -187,7 +187,7 @@
for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
- if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ if (syllable_serial == 16) syllable_serial = 1; \
} HB_STMT_END
diff --git a/src/hb-ot-shaper-use-table.hh b/src/hb-ot-shaper-use-table.hh
index 9833fb5..6b6b552 100644
--- a/src/hb-ot-shaper-use-table.hh
+++ b/src/hb-ot-shaper-use-table.hh
@@ -91,6 +91,9 @@
#define VMPre USE(VMPre)
#pragma GCC diagnostic pop
+
+#ifndef HB_OPTIMIZE_SIZE
+
static const uint8_t
hb_use_u8[3141] =
{
@@ -357,6 +360,273 @@
return u<921600u?hb_use_u8[2777+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
}
+
+#else
+
+static const uint8_t
+hb_use_u8[3413] =
+{
+ 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 14, 0, 1, 1, 2, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 1,
+ 11, 12, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 17, 18, 19, 1,
+ 1, 20, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 22, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 24, 25, 26, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27,
+ 28, 1, 1, 1, 1, 1, 29, 1, 1, 1, 1, 30, 31, 1, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 1, 46, 47, 48,
+ 49, 50, 50, 50, 50, 51, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 52, 53, 1, 1, 1,
+ 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 55, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 56, 1, 1,
+ 1, 1, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 58, 59, 1, 60, 1, 1, 1, 1, 61, 1, 1, 1, 1, 1,
+ 1, 62, 63, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 8, 0, 0, 0, 0,
+ 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 36, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 0, 55, 56, 57, 58, 59, 0, 0, 0, 60, 61, 62, 63, 55, 64, 65,
+ 66, 67, 55, 55, 68, 69, 70, 0, 0, 71, 72, 73, 74, 55, 75, 76,
+ 0, 77, 55, 78, 79, 80, 0, 0, 0, 81, 82, 83, 84, 85, 86, 55,
+ 87, 55, 88, 89, 0, 0, 0, 90, 91, 0, 0, 0, 0, 0, 0, 0,
+ 92, 93, 94, 0, 95, 96, 0, 0, 97, 0, 0, 0, 0, 0, 0, 98,
+ 0, 0, 99, 55, 100, 0, 0, 0, 0, 101, 102, 55, 103, 104, 105, 106,
+ 107, 55, 108, 109, 0, 110, 111, 112, 113, 55, 114, 115, 116, 55, 117, 118,
+ 119, 0, 0, 0, 0, 0, 0, 55, 120, 121, 0, 0, 0, 0, 0, 0,
+ 122, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 124, 125, 126, 0,
+ 0, 127, 128, 129, 0, 0, 0, 50, 130, 0, 0, 0, 0, 131, 132, 0,
+ 0, 55, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 134, 0,
+ 0, 0, 99, 135, 99, 136, 137, 138, 0, 139, 140, 141, 142, 143, 144, 145,
+ 0, 146, 147, 148, 149, 143, 150, 151, 152, 153, 154, 155, 0, 156, 157, 158,
+ 159, 160, 161, 162, 163, 0, 0, 0, 0, 55, 164, 165, 166, 167, 168, 169,
+ 0, 0, 0, 0, 0, 55, 170, 171, 0, 55, 172, 173, 0, 55, 174, 66,
+ 0, 175, 176, 177, 0, 0, 0, 0, 0, 55, 178, 0, 0, 0, 0, 0,
+ 0, 179, 180, 181, 0, 0, 182, 183, 184, 185, 186, 187, 55, 188, 0, 0,
+ 0, 189, 190, 191, 192, 193, 194, 0, 0, 195, 196, 197, 198, 199, 66, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 200, 201, 202, 203, 0, 0, 0, 0,
+ 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 204, 205, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 66, 0, 55, 206, 0, 0, 0, 0, 0,
+ 0, 55, 55, 207, 208, 209, 0, 0, 210, 55, 55, 55, 55, 55, 55, 211,
+ 0, 55, 55, 55, 212, 213, 0, 0, 0, 0, 0, 0, 214, 0, 0, 0,
+ 0, 55, 215, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 217, 55,
+ 218, 0, 0, 0, 0, 0, 0, 99, 219, 55, 55, 220, 0, 0, 0, 0,
+ 0, 221, 221, 221, 221, 221, 221, 221, 221, 222, 222, 222, 222, 222, 222, 222,
+ 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0, 2, 2, 2, 2, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4,
+ 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 8, 9, 9, 9, 9, 0, 0, 0, 7, 10,
+ 0, 2, 2, 2, 2, 11, 12, 0, 0, 9, 13, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 14, 15, 16, 17, 18, 19, 20, 14, 21, 22,
+ 23, 10, 24, 25, 18, 2, 2, 2, 2, 2, 18, 0, 2, 2, 2, 2,
+ 2, 0, 2, 2, 2, 2, 2, 2, 2, 26, 27, 28, 2, 2, 2, 7,
+ 28, 7, 28, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2,
+ 2, 7, 7, 0, 2, 2, 0, 15, 16, 17, 18, 29, 30, 31, 30, 32,
+ 0, 0, 0, 0, 33, 0, 0, 2, 28, 2, 0, 0, 0, 0, 0, 7,
+ 34, 10, 13, 28, 2, 2, 7, 0, 28, 7, 2, 28, 7, 2, 0, 35,
+ 16, 17, 29, 0, 25, 36, 25, 37, 0, 38, 0, 0, 0, 28, 2, 7,
+ 7, 0, 0, 0, 2, 2, 2, 2, 2, 39, 40, 41, 0, 0, 0, 0,
+ 0, 10, 13, 28, 2, 2, 2, 2, 28, 2, 28, 2, 2, 2, 2, 2,
+ 2, 7, 2, 28, 2, 2, 0, 15, 16, 17, 18, 19, 25, 20, 33, 22,
+ 0, 0, 0, 0, 0, 28, 39, 39, 42, 10, 27, 28, 2, 2, 2, 7,
+ 28, 7, 2, 28, 2, 2, 0, 15, 43, 0, 0, 25, 20, 0, 0, 2,
+ 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 44, 28, 2, 2, 7, 0,
+ 2, 7, 2, 2, 0, 28, 7, 7, 2, 0, 28, 7, 0, 2, 7, 0,
+ 2, 2, 2, 2, 2, 2, 0, 0, 21, 14, 45, 0, 46, 31, 46, 32,
+ 0, 0, 0, 0, 33, 0, 0, 0, 0, 13, 27, 47, 2, 2, 2, 7,
+ 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 15,
+ 20, 14, 21, 45, 20, 36, 20, 37, 0, 0, 0, 25, 29, 2, 7, 0,
+ 0, 8, 27, 28, 2, 2, 2, 7, 2, 2, 2, 28, 2, 2, 0, 15,
+ 43, 0, 0, 33, 45, 0, 0, 0, 7, 48, 49, 0, 0, 0, 0, 0,
+ 0, 9, 27, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 50, 51,
+ 21, 21, 17, 29, 46, 31, 46, 32, 52, 0, 0, 0, 33, 0, 0, 0,
+ 28, 10, 27, 28, 2, 2, 2, 2, 2, 2, 2, 2, 7, 0, 2, 2,
+ 2, 2, 28, 2, 2, 2, 2, 28, 0, 2, 2, 2, 7, 0, 53, 0,
+ 33, 21, 20, 29, 29, 16, 46, 46, 23, 0, 21, 0, 0, 0, 0, 0,
+ 0, 2, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0,
+ 0, 2, 2, 54, 54, 55, 0, 0, 16, 2, 2, 2, 2, 28, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 7, 0, 56, 19, 57, 20, 20, 18, 18,
+ 44, 19, 9, 29, 9, 2, 2, 58, 59, 59, 59, 59, 59, 60, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61,
+ 0, 0, 0, 0, 62, 0, 0, 0, 0, 2, 2, 2, 2, 2, 63, 43,
+ 57, 64, 20, 20, 65, 66, 67, 68, 69, 2, 2, 2, 2, 2, 1, 0,
+ 3, 2, 2, 2, 21, 18, 2, 2, 70, 69, 71, 72, 63, 71, 27, 27,
+ 2, 50, 20, 51, 2, 2, 2, 2, 2, 2, 73, 74, 75, 27, 27, 76,
+ 77, 2, 2, 2, 2, 2, 27, 43, 0, 2, 57, 78, 0, 0, 0, 0,
+ 28, 2, 57, 45, 0, 0, 0, 0, 0, 2, 57, 0, 0, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 2, 7, 2, 7, 57, 0, 0, 0, 0, 0,
+ 0, 2, 2, 79, 43, 20, 57, 18, 46, 46, 46, 46, 13, 80, 81, 82,
+ 83, 84, 85, 0, 0, 0, 0, 86, 0, 7, 0, 0, 28, 0, 87, 79,
+ 88, 2, 2, 2, 2, 7, 0, 0, 0, 40, 40, 89, 90, 2, 2, 2,
+ 2, 2, 2, 2, 2, 11, 7, 0, 0, 91, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 7, 20, 78, 43, 20, 92, 59, 0,
+ 0, 93, 94, 93, 93, 95, 96, 0, 0, 2, 2, 2, 2, 2, 2, 2,
+ 0, 2, 2, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0,
+ 0, 2, 2, 2, 2, 27, 0, 0, 0, 2, 2, 2, 2, 2, 7, 0,
+ 0, 2, 2, 2, 50, 97, 43, 0, 0, 2, 2, 98, 99, 100, 101, 59,
+ 61, 102, 14, 43, 20, 57, 19, 78, 46, 46, 74, 9, 9, 9, 103, 44,
+ 38, 9, 104, 72, 2, 2, 2, 2, 2, 2, 2, 105, 20, 18, 18, 20,
+ 46, 46, 20, 106, 2, 2, 2, 7, 0, 0, 0, 0, 0, 0, 107, 108,
+ 109, 109, 109, 0, 0, 0, 0, 0, 0, 104, 72, 2, 2, 2, 2, 2,
+ 2, 58, 59, 57, 23, 20, 110, 59, 2, 2, 2, 2, 105, 20, 21, 43,
+ 43, 100, 12, 0, 0, 0, 0, 0, 0, 2, 2, 59, 16, 46, 21, 111,
+ 100, 100, 100, 112, 113, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 28,
+ 2, 9, 44, 114, 114, 114, 9, 114, 114, 13, 114, 114, 114, 24, 0, 38,
+ 0, 0, 0, 115, 49, 9, 3, 0, 0, 0, 0, 0, 0, 0, 116, 0,
+ 0, 0, 0, 0, 0, 0, 4, 117, 118, 40, 40, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 118, 118, 119, 118, 118, 118, 118, 118, 118, 118,
+ 118, 0, 0, 120, 0, 0, 0, 0, 0, 0, 5, 120, 0, 0, 0, 0,
+ 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 0, 2, 2, 2, 2, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
+ 121, 2, 51, 2, 106, 2, 8, 2, 2, 2, 63, 17, 14, 0, 0, 29,
+ 0, 2, 2, 0, 0, 0, 0, 0, 0, 27, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 122, 21, 21, 21, 21, 21, 21, 21, 123, 0, 0, 0, 0,
+ 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 0,
+ 50, 2, 2, 2, 20, 20, 124, 114, 0, 2, 2, 2, 125, 18, 57, 18,
+ 111, 100, 126, 0, 0, 0, 0, 0, 0, 9, 127, 2, 2, 2, 2, 2,
+ 2, 2, 128, 21, 20, 18, 46, 129, 130, 131, 0, 0, 0, 0, 0, 0,
+ 0, 2, 2, 50, 28, 2, 2, 2, 2, 2, 2, 2, 2, 8, 20, 57,
+ 97, 74, 132, 133, 134, 0, 0, 0, 0, 2, 135, 2, 2, 2, 2, 136,
+ 0, 28, 2, 40, 3, 0, 77, 13, 2, 51, 20, 137, 50, 51, 2, 2,
+ 103, 8, 7, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 138, 19,
+ 23, 0, 0, 139, 140, 0, 0, 0, 0, 2, 63, 43, 21, 78, 45, 141,
+ 0, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 0, 0, 0, 0, 0,
+ 4, 118, 118, 118, 118, 119, 0, 0, 0, 2, 2, 2, 2, 2, 7, 2,
+ 2, 2, 7, 2, 28, 2, 2, 2, 2, 2, 28, 2, 2, 2, 28, 7,
+ 0, 125, 18, 25, 29, 0, 0, 142, 143, 2, 2, 28, 2, 28, 2, 2,
+ 2, 2, 2, 2, 0, 12, 35, 0, 144, 2, 2, 11, 35, 0, 28, 2,
+ 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 2, 2,
+ 7, 2, 2, 9, 39, 0, 0, 0, 0, 2, 2, 2, 2, 2, 25, 36,
+ 0, 2, 2, 2, 114, 114, 114, 114, 114, 145, 2, 7, 0, 0, 0, 0,
+ 0, 2, 12, 12, 0, 0, 0, 0, 0, 7, 2, 2, 7, 2, 2, 2,
+ 2, 28, 2, 7, 0, 28, 2, 0, 0, 146, 147, 148, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 20, 20, 18, 18, 18, 20, 20, 131, 0, 0, 0,
+ 0, 0, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 2, 2, 2, 2,
+ 2, 51, 50, 51, 0, 0, 0, 0, 150, 9, 72, 2, 2, 2, 2, 2,
+ 2, 16, 17, 19, 14, 22, 35, 0, 0, 0, 29, 0, 0, 0, 0, 0,
+ 0, 9, 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 18, 20, 151,
+ 20, 19, 152, 153, 2, 2, 2, 2, 2, 0, 0, 63, 154, 0, 0, 0,
+ 0, 2, 11, 0, 0, 0, 0, 0, 0, 2, 63, 23, 18, 18, 18, 20,
+ 20, 106, 155, 0, 0, 54, 156, 29, 157, 28, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 21, 17, 20, 20, 158, 42, 0, 0, 0,
+ 47, 125, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 7, 7, 2, 2,
+ 28, 2, 2, 2, 2, 2, 2, 2, 28, 2, 2, 2, 2, 2, 2, 2,
+ 8, 16, 17, 19, 20, 159, 29, 0, 0, 9, 9, 28, 2, 2, 2, 7,
+ 28, 7, 2, 28, 2, 2, 56, 15, 21, 14, 21, 45, 30, 31, 30, 32,
+ 0, 0, 0, 0, 33, 0, 0, 0, 2, 2, 21, 0, 9, 9, 9, 44,
+ 0, 9, 9, 44, 0, 0, 0, 0, 0, 2, 2, 63, 23, 18, 18, 18,
+ 20, 21, 123, 13, 15, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0,
+ 160, 161, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18, 18, 64, 97, 23,
+ 157, 9, 162, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2,
+ 63, 23, 18, 18, 0, 46, 46, 9, 163, 35, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2, 2, 18, 0, 21, 17, 18, 18, 19, 14, 80,
+ 163, 36, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 8, 164,
+ 23, 18, 20, 20, 162, 7, 0, 0, 0, 2, 2, 2, 2, 2, 7, 41,
+ 133, 21, 20, 18, 74, 19, 20, 0, 0, 2, 2, 2, 7, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 103, 163, 35, 0,
+ 0, 2, 2, 2, 7, 28, 0, 2, 2, 2, 2, 28, 7, 2, 2, 2,
+ 2, 21, 21, 16, 30, 31, 10, 165, 166, 167, 168, 0, 0, 0, 0, 0,
+ 0, 2, 2, 2, 2, 0, 2, 2, 2, 63, 23, 18, 18, 0, 20, 21,
+ 27, 106, 0, 31, 0, 0, 0, 0, 0, 50, 18, 20, 20, 20, 137, 2,
+ 2, 2, 169, 170, 9, 13, 171, 70, 172, 0, 0, 1, 144, 0, 0, 0,
+ 0, 50, 18, 20, 14, 17, 18, 2, 2, 2, 2, 155, 155, 155, 173, 173,
+ 173, 173, 173, 173, 13, 174, 0, 28, 0, 20, 18, 18, 29, 20, 20, 9,
+ 163, 0, 59, 59, 59, 59, 59, 59, 59, 64, 19, 80, 44, 0, 0, 0,
+ 0, 2, 2, 2, 7, 2, 28, 2, 2, 50, 20, 20, 29, 0, 36, 20,
+ 25, 9, 156, 175, 171, 0, 0, 0, 0, 2, 2, 2, 28, 7, 2, 2,
+ 2, 2, 2, 2, 2, 2, 21, 21, 45, 20, 33, 80, 66, 0, 0, 0,
+ 0, 2, 176, 64, 45, 0, 0, 0, 0, 9, 177, 2, 2, 2, 2, 2,
+ 2, 2, 2, 21, 20, 18, 29, 0, 46, 14, 140, 0, 0, 0, 0, 0,
+ 0, 178, 178, 178, 106, 179, 178, 0, 0, 145, 2, 2, 180, 114, 114, 114,
+ 114, 114, 114, 114, 0, 0, 0, 0, 0, 9, 9, 9, 44, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 7, 0, 56, 181, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0,
+ 38, 114, 24, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
+ 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 56,
+ 35, 0, 4, 118, 118, 118, 119, 0, 0, 9, 9, 9, 47, 2, 2, 2,
+ 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+ 44, 2, 2, 2, 2, 2, 2, 9, 9, 2, 2, 2, 2, 2, 2, 20,
+ 20, 2, 2, 42, 42, 42, 90, 0, 0, O, O, O, GB, B, B, GB,
+ O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,
+ CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw,
+ VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst,
+ VMPst, O, B, VBlw, O, O, VPre, VPre, O, VPre, H, O, VPst,FMAbv, O,CMBlw,
+ O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst,
+ VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, B, O, CS, CS,VMPst, B, VAbv, VAbv,
+ B, R, O, HVM, O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB,
+ SUB, O, SUB, SUB, O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv,
+ MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,
+ VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,
+ VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB,
+ B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw,
+ SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,
+ SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,
+ CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, O, H, MPst, VPst, H,
+ VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H,
+ O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,
+ VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst,
+ CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R,
+ R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, B, CS, CS, H,CMBlw,VMPst,
+ H,VMPst, VAbv,VMAbv, VPst, IS, R, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, R,
+ MBlw, MBlw, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, VAbv, R,VMPst, H, H, B,
+ H, B,VMBlw, O, VBlw,
+};
+static const uint16_t
+hb_use_u16[448] =
+{
+ 0, 0, 1, 2, 3, 4, 0, 5, 6, 0, 7, 0, 8, 9, 10, 11,
+ 9, 12, 13, 9, 9, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 17, 25, 26, 20, 21, 27, 28, 29, 30, 31, 32, 33, 21, 34, 35, 0,
+ 17, 36, 37, 20, 21, 38, 23, 39, 17, 40, 41, 42, 43, 44, 45, 46,
+ 30, 0, 47, 48, 21, 49, 50, 51, 17, 0, 52, 48, 21, 53, 50, 54,
+ 17, 55, 56, 48, 9, 57, 58, 59, 60, 61, 9, 62, 63, 64, 30, 65,
+ 66, 67, 9, 68, 69, 9, 70, 71, 72, 73, 74, 75, 76, 0, 9, 9,
+ 77, 78, 79, 80, 81, 82, 83, 84, 9, 85, 9, 86, 9, 87, 88, 89,
+ 9, 90, 91, 92, 2, 0, 93, 0, 9, 94, 95, 9, 96, 0, 97, 98,
+ 99,100, 30, 9,101,102,103, 9,104,105, 9,106, 9,107,108,109,
+ 2, 2,110, 9, 9,111,112, 2,113,114,115, 9,116, 9,117,118,
+ 119,120,121, 0, 0,122,123,124, 0,125,126,127,128, 0,129,130,
+ 131, 0, 0,132,133, 0, 0, 9,134,135,136, 9,137, 0, 9,138,
+ 139, 9, 9,140,141, 2,142,143,144, 9,145,146,147, 9, 9,148,
+ 149, 2,150, 98,151,152,153, 2, 9,154, 9,155,156, 0,157,158,
+ 159, 2,160, 0, 0,161, 0,162, 0,163,163,164, 33,165,166,167,
+ 9,168, 94, 0,169, 0, 9,170,171, 0,172, 2,173,170,174,175,
+ 176, 0, 0,177,178, 0,179, 9, 9,180,181,182,183,184,185, 9,
+ 9,186,187, 0,188, 9,189,190,191, 9, 9,192, 9,193,194,105,
+ 195,102, 9, 33,196,197,198, 0,199,200, 94, 9, 9,201,202, 2,
+ 203, 20, 21,204,205,206,207,208, 9,209,210,211,212, 0,195, 9,
+ 9,213,214, 2,215,216,217,218, 9,219,220, 2,221,222, 9,223,
+ 224,103,225, 0,226,227,228,229, 9,230,231, 2,232, 9, 9,233,
+ 234, 0,235, 9, 9,236,237,238,239,240, 21, 9,215,241, 7, 9,
+ 70, 18, 9,242, 73,243,244, 9, 9,245,246, 2,247, 9,248,249,
+ 9,250,251, 48, 9,252,253, 2, 9,254,255,256, 9,257,258,259,
+ 260,260,261,262,263, 0, 9,264,105, 70, 94,265, 0,266, 70,267,
+ 268, 0,269, 0,270, 2,271, 2,272, 2,129,129,160,160,160,129,
+};
+
+static inline unsigned
+hb_use_b4 (const uint8_t* a, unsigned i)
+{
+ return (a[i>>1]>>((i&1u)<<2))&15u;
+}
+static inline uint_fast8_t
+hb_use_get_category (unsigned u)
+{
+ return u<921600u?hb_use_u8[3049+(((hb_use_u8[865+(((hb_use_u16[((hb_use_u8[353+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
+}
+
+#endif
+
#undef B
#undef CGJ
#undef CS
diff --git a/src/hb-ot-shaper-use.cc b/src/hb-ot-shaper-use.cc
index c40ec52..342aba1 100644
--- a/src/hb-ot-shaper-use.cc
+++ b/src/hb-ot-shaper-use.cc
@@ -89,19 +89,19 @@
HB_TAG('p','s','t','s'),
};
-static void
+static bool
setup_syllables_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
-static void
+static bool
record_rphf_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
-static void
+static bool
record_pref_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
-static void
+static bool
reorder_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
@@ -293,7 +293,7 @@
}
}
-static void
+static bool
setup_syllables_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
@@ -304,9 +304,10 @@
buffer->unsafe_to_break (start, end);
setup_rphf_mask (plan, buffer);
setup_topographical_masks (plan, buffer);
+ return false;
}
-static void
+static bool
record_rphf_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
@@ -314,7 +315,7 @@
const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
hb_mask_t mask = use_plan->rphf_mask;
- if (!mask) return;
+ if (!mask) return false;
hb_glyph_info_t *info = buffer->info;
foreach_syllable (buffer, start, end)
@@ -327,9 +328,10 @@
break;
}
}
+ return false;
}
-static void
+static bool
record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
@@ -346,6 +348,7 @@
break;
}
}
+ return false;
}
static inline bool
@@ -438,17 +441,19 @@
}
}
-static void
+static bool
reorder_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
+ bool ret = false;
if (buffer->message (font, "start reordering USE"))
{
- hb_syllabic_insert_dotted_circles (font, buffer,
- use_broken_cluster,
- USE(B),
- USE(R));
+ if (hb_syllabic_insert_dotted_circles (font, buffer,
+ use_broken_cluster,
+ USE(B),
+ USE(R)))
+ ret = true;
foreach_syllable (buffer, start, end)
reorder_syllable_use (buffer, start, end);
@@ -457,6 +462,8 @@
}
HB_BUFFER_DEALLOCATE_VAR (buffer, use_category);
+
+ return ret;
}
diff --git a/src/hb-ot-shaper.hh b/src/hb-ot-shaper.hh
index b2d1acb..0207b2b 100644
--- a/src/hb-ot-shaper.hh
+++ b/src/hb-ot-shaper.hh
@@ -262,11 +262,13 @@
return &_hb_ot_shaper_myanmar;
+#ifndef HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g'))
case HB_SCRIPT_MYANMAR_ZAWGYI:
/* https://github.com/harfbuzz/harfbuzz/issues/1162 */
return &_hb_ot_shaper_myanmar_zawgyi;
+#endif
/* Unicode-2.0 additions */
diff --git a/src/hb-ot-stat-table.hh b/src/hb-ot-stat-table.hh
index af6d550..59bb2da 100644
--- a/src/hb-ot-stat-table.hh
+++ b/src/hb-ot-stat-table.hh
@@ -320,7 +320,7 @@
unsigned total_size = min_size + axisCount * AxisValueRecord::static_size;
auto *out = c->serializer->allocate_size<AxisValueFormat4> (total_size);
if (unlikely (!out)) return_trace (false);
- memcpy (out, this, total_size);
+ hb_memcpy (out, this, total_size);
return_trace (true);
}
diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc
index 1b18270..f6ba3b0 100644
--- a/src/hb-ot-tag.cc
+++ b/src/hb-ot-tag.cc
@@ -577,7 +577,7 @@
else
{
int shift;
- memcpy (buf, lang_str, len);
+ hb_memcpy (buf, lang_str, len);
if (lang_str[0] != 'x' || lang_str[1] != '-') {
buf[len++] = '-';
buf[len++] = 'x';
diff --git a/src/hb-ot-var-avar-table.hh b/src/hb-ot-var-avar-table.hh
index f60bc4a..cc5c5c0 100644
--- a/src/hb-ot-var-avar-table.hh
+++ b/src/hb-ot-var-avar-table.hh
@@ -143,7 +143,7 @@
TRACE_SANITIZE (this);
if (!(version.sanitize (c) &&
(version.major == 1
-#ifndef HB_NO_VARIATIONS2
+#ifndef HB_NO_AVAR2
|| version.major == 2
#endif
) &&
@@ -159,7 +159,7 @@
map = &StructAfter<SegmentMaps> (*map);
}
-#ifndef HB_NO_VARIATIONS2
+#ifndef HB_NO_AVAR2
if (version.major < 2)
return_trace (true);
@@ -182,7 +182,7 @@
map = &StructAfter<SegmentMaps> (*map);
}
-#ifndef HB_NO_VARIATIONS2
+#ifndef HB_NO_AVAR2
if (version.major < 2)
return;
diff --git a/src/hb-ot-var-common.hh b/src/hb-ot-var-common.hh
index 1d29e3e..4997c2e 100644
--- a/src/hb-ot-var-common.hh
+++ b/src/hb-ot-var-common.hh
@@ -47,7 +47,7 @@
HBUINT8 *p = c->allocate_size<HBUINT8> (total_size);
if (unlikely (!p)) return_trace (nullptr);
- memcpy (p, this, HBUINT8::static_size * total_size);
+ hb_memcpy (p, this, HBUINT8::static_size * total_size);
return_trace (out);
}
@@ -219,6 +219,25 @@
DEFINE_SIZE_UNION (1, format);
};
+
+struct VarStoreInstancer
+{
+ VarStoreInstancer (const VariationStore &varStore,
+ const DeltaSetIndexMap &varIdxMap,
+ hb_array_t<int> coords) :
+ varStore (varStore), varIdxMap (varIdxMap), coords (coords) {}
+
+ operator bool () const { return bool (coords); }
+
+ float operator() (uint32_t varIdx, unsigned short offset = 0) const
+ { return varStore.get_delta (varIdxMap.map (VarIdx::add (varIdx, offset)), coords); }
+
+ const VariationStore &varStore;
+ const DeltaSetIndexMap &varIdxMap;
+ hb_array_t<int> coords;
+};
+
+
} /* namespace OT */
diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh
index af23862..c1d57a0 100644
--- a/src/hb-ot-var-fvar-table.hh
+++ b/src/hb-ot-var-fvar-table.hh
@@ -59,7 +59,7 @@
const hb_hashmap_t<hb_tag_t, float> *axes_location = c->plan->user_axes_location;
for (unsigned i = 0 ; i < axis_count; i++)
{
- unsigned *axis_tag;
+ uint32_t *axis_tag;
// only keep instances whose coordinates == pinned axis location
if (!c->plan->axes_old_index_tag_map->has (i, &axis_tag)) continue;
@@ -337,13 +337,13 @@
{
const InstanceRecord *instance = get_instance (i);
- if (hb_any (+ hb_zip (instance->get_coordinates (axisCount), hb_range ((unsigned)axisCount))
- | hb_filter (pinned_axes, hb_second)
- | hb_map ([&] (const hb_pair_t<const F16DOT16&, unsigned>& _)
+ if (hb_any (+ hb_enumerate (instance->get_coordinates (axisCount))
+ | hb_filter (pinned_axes, hb_first)
+ | hb_map ([&] (const hb_pair_t<unsigned, const F16DOT16&>& _)
{
- hb_tag_t axis_tag = pinned_axes.get (_.second);
+ hb_tag_t axis_tag = pinned_axes.get (_.first);
float location = user_axes_location->get (axis_tag);
- if (fabs ((double)location - (double)_.first.to_float ()) > 0.001) return true;
+ if (fabs ((double)location - (double)_.second.to_float ()) > 0.001) return true;
return false;
})
))
diff --git a/src/hb-ot-var-gvar-table.hh b/src/hb-ot-var-gvar-table.hh
index bf1039d..e02063c 100644
--- a/src/hb-ot-var-gvar-table.hh
+++ b/src/hb-ot-var-gvar-table.hh
@@ -56,12 +56,11 @@
void extend (const hb_array_t<contour_point_t> &a)
{
unsigned int old_len = length;
- if (unlikely (!resize (old_len + a.length)))
+ if (unlikely (!resize (old_len + a.length, false)))
return;
auto arrayZ = this->arrayZ + old_len;
unsigned count = a.length;
- for (unsigned int i = 0; i < count; i++)
- arrayZ[i] = a.arrayZ[i];
+ hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0]));
}
void transform (const float (&matrix)[4])
@@ -231,8 +230,8 @@
{
return (index < var_data->tupleVarCount.get_count ()) &&
var_data_bytes.check_range (current_tuple, TupleVariationHeader::min_size) &&
- var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (), current_tuple->get_size (axis_count))) &&
- current_tuple->get_size (axis_count);
+ var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (),
+ current_tuple->get_size (axis_count)));
}
bool move_to_next ()
@@ -281,42 +280,42 @@
if (unlikely (p + 1 > end)) return false;
- uint16_t count = *p++;
+ unsigned count = *p++;
if (count & POINTS_ARE_WORDS)
{
if (unlikely (p + 1 > end)) return false;
count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++;
}
- if (unlikely (!points.resize (count))) return false;
+ if (unlikely (!points.resize (count, false))) return false;
- unsigned int n = 0;
- uint16_t i = 0;
+ unsigned n = 0;
+ unsigned i = 0;
while (i < count)
{
if (unlikely (p + 1 > end)) return false;
- uint16_t j;
- uint8_t control = *p++;
- uint16_t run_count = (control & POINT_RUN_COUNT_MASK) + 1;
+ unsigned control = *p++;
+ unsigned run_count = (control & POINT_RUN_COUNT_MASK) + 1;
+ if (unlikely (i + run_count > count)) return false;
+ unsigned j;
if (control & POINTS_ARE_WORDS)
{
- for (j = 0; j < run_count && i < count; j++, i++)
+ if (unlikely (p + run_count * HBUINT16::static_size > end)) return false;
+ for (j = 0; j < run_count; j++, i++)
{
- if (unlikely (p + HBUINT16::static_size > end)) return false;
n += *(const HBUINT16 *)p;
- points[i] = n;
+ points.arrayZ[i] = n;
p += HBUINT16::static_size;
}
}
else
{
- for (j = 0; j < run_count && i < count; j++, i++)
+ if (unlikely (p + run_count > end)) return false;
+ for (j = 0; j < run_count; j++, i++)
{
- if (unlikely (p + 1 > end)) return false;
n += *p++;
- points[i] = n;
+ points.arrayZ[i] = n;
}
}
- if (j < run_count) return false;
}
return true;
}
@@ -332,32 +331,37 @@
DELTA_RUN_COUNT_MASK = 0x3F
};
- unsigned int i = 0;
- unsigned int count = deltas.length;
+ unsigned i = 0;
+ unsigned count = deltas.length;
while (i < count)
{
if (unlikely (p + 1 > end)) return false;
- uint8_t control = *p++;
- unsigned int run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
- unsigned int j;
+ unsigned control = *p++;
+ unsigned run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
+ if (unlikely (i + run_count > count)) return false;
+ unsigned j;
if (control & DELTAS_ARE_ZERO)
- for (j = 0; j < run_count && i < count; j++, i++)
- deltas[i] = 0;
+ {
+ for (j = 0; j < run_count; j++, i++)
+ deltas.arrayZ[i] = 0;
+ }
else if (control & DELTAS_ARE_WORDS)
- for (j = 0; j < run_count && i < count; j++, i++)
+ {
+ if (unlikely (p + run_count * HBUINT16::static_size > end)) return false;
+ for (j = 0; j < run_count; j++, i++)
{
- if (unlikely (p + HBUINT16::static_size > end)) return false;
- deltas[i] = *(const HBINT16 *) p;
+ deltas.arrayZ[i] = * (const HBINT16 *) p;
p += HBUINT16::static_size;
}
+ }
else
- for (j = 0; j < run_count && i < count; j++, i++)
+ {
+ if (unlikely (p + run_count > end)) return false;
+ for (j = 0; j < run_count; j++, i++)
{
- if (unlikely (p + 1 > end)) return false;
- deltas[i] = *(const HBINT8 *) p++;
+ deltas.arrayZ[i] = * (const HBINT8 *) p++;
}
- if (j < run_count)
- return false;
+ }
}
return true;
}
@@ -450,7 +454,7 @@
F2DOT14 *tuples = c->serializer->allocate_size<F2DOT14> (shared_tuple_size);
if (!tuples) return_trace (false);
out->sharedTuples = (char *) tuples - (char *) out;
- memcpy (tuples, this+sharedTuples, shared_tuple_size);
+ hb_memcpy (tuples, this+sharedTuples, shared_tuple_size);
}
char *subset_data = c->serializer->allocate_size<char> (subset_data_size);
@@ -473,7 +477,7 @@
((HBUINT16 *) subset_offsets)[gid] = glyph_offset / 2;
if (var_data_bytes.length > 0)
- memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length);
+ hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length);
subset_data += var_data_bytes.length;
glyph_offset += var_data_bytes.length;
}
@@ -501,6 +505,7 @@
unsigned get_offset (unsigned i) const
{
if (unlikely (i > glyphCount)) return 0;
+ _hb_compiler_memory_r_barrier ();
return is_long_offset () ? get_long_offset_array ()[i] : get_short_offset_array ()[i] * 2;
}
@@ -521,11 +526,11 @@
unsigned int target, unsigned int prev, unsigned int next,
float contour_point_t::*m)
{
- float target_val = points[target].*m;
- float prev_val = points[prev].*m;
- float next_val = points[next].*m;
- float prev_delta = deltas[prev].*m;
- float next_delta = deltas[next].*m;
+ float target_val = points.arrayZ[target].*m;
+ float prev_val = points.arrayZ[prev].*m;
+ float next_val = points.arrayZ[next].*m;
+ float prev_delta = deltas.arrayZ[prev].*m;
+ float next_delta = deltas.arrayZ[next].*m;
if (prev_val == next_val)
return (prev_delta == next_delta) ? prev_delta : 0.f;
@@ -543,10 +548,11 @@
{ return (i >= end) ? start : (i + 1); }
public:
- bool apply_deltas_to_points (hb_codepoint_t glyph, hb_font_t *font,
+ bool apply_deltas_to_points (hb_codepoint_t glyph,
+ hb_array_t<int> coords,
const hb_array_t<contour_point_t> points) const
{
- if (!font->num_coords) return true;
+ if (!coords) return true;
if (unlikely (glyph >= table->glyphCount)) return true;
@@ -559,20 +565,20 @@
return true; /* so isn't applied at all */
/* Save original points for inferred delta calculation */
- contour_point_vector_t orig_points;
- if (unlikely (!orig_points.resize (points.length))) return false;
- for (unsigned int i = 0; i < orig_points.length; i++)
- orig_points.arrayZ[i] = points.arrayZ[i];
+ contour_point_vector_t orig_points_vec;
+ orig_points_vec.extend (points);
+ if (unlikely (orig_points_vec.in_error ())) return false;
+ auto orig_points = orig_points_vec.as_array ();
- contour_point_vector_t deltas; /* flag is used to indicate referenced point */
- if (unlikely (!deltas.resize (points.length))) return false;
+ contour_point_vector_t deltas_vec; /* flag is used to indicate referenced point */
+ if (unlikely (!deltas_vec.resize (points.length, false))) return false;
+ auto deltas = deltas_vec.as_array ();
hb_vector_t<unsigned> end_points;
for (unsigned i = 0; i < points.length; ++i)
- if (points[i].is_end_point)
+ if (points.arrayZ[i].is_end_point)
end_points.push (i);
- auto coords = hb_array (font->coords, font->num_coords);
unsigned num_coords = table->axisCount;
hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
@@ -598,70 +604,89 @@
bool apply_to_all = (indices.length == 0);
unsigned int num_deltas = apply_to_all ? points.length : indices.length;
- if (unlikely (!x_deltas.resize (num_deltas))) return false;
+ if (unlikely (!x_deltas.resize (num_deltas, false))) return false;
if (unlikely (!GlyphVariationData::unpack_deltas (p, x_deltas, end))) return false;
- if (unlikely (!y_deltas.resize (num_deltas))) return false;
+ if (unlikely (!y_deltas.resize (num_deltas, false))) return false;
if (unlikely (!GlyphVariationData::unpack_deltas (p, y_deltas, end))) return false;
- for (unsigned int i = 0; i < deltas.length; i++)
- deltas[i].init ();
- for (unsigned int i = 0; i < num_deltas; i++)
- {
- unsigned int pt_index = apply_to_all ? i : indices[i];
- if (unlikely (pt_index >= deltas.length)) continue;
- deltas.arrayZ[pt_index].flag = 1; /* this point is referenced, i.e., explicit deltas specified */
- deltas.arrayZ[pt_index].x += x_deltas.arrayZ[i] * scalar;
- deltas.arrayZ[pt_index].y += y_deltas.arrayZ[i] * scalar;
- }
+ hb_memset (deltas.arrayZ, 0, deltas.get_size ());
+
+ unsigned ref_points = 0;
+ if (scalar != 1.0f)
+ for (unsigned int i = 0; i < num_deltas; i++)
+ {
+ unsigned int pt_index = apply_to_all ? i : indices[i];
+ if (unlikely (pt_index >= deltas.length)) continue;
+ auto &delta = deltas.arrayZ[pt_index];
+ ref_points += !delta.flag;
+ delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */
+ delta.x += x_deltas.arrayZ[i] * scalar;
+ delta.y += y_deltas.arrayZ[i] * scalar;
+ }
+ else
+ for (unsigned int i = 0; i < num_deltas; i++)
+ {
+ unsigned int pt_index = apply_to_all ? i : indices[i];
+ if (unlikely (pt_index >= deltas.length)) continue;
+ auto &delta = deltas.arrayZ[pt_index];
+ ref_points += !delta.flag;
+ delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */
+ delta.x += x_deltas.arrayZ[i];
+ delta.y += y_deltas.arrayZ[i];
+ }
/* infer deltas for unreferenced points */
- unsigned start_point = 0;
- for (unsigned c = 0; c < end_points.length; c++)
+ if (ref_points && ref_points < orig_points.length)
{
- unsigned end_point = end_points[c];
-
- /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
- unsigned unref_count = 0;
- for (unsigned i = start_point; i <= end_point; i++)
- if (!deltas[i].flag) unref_count++;
-
- unsigned j = start_point;
- if (unref_count == 0 || unref_count > end_point - start_point)
- goto no_more_gaps;
-
- for (;;)
+ unsigned start_point = 0;
+ for (unsigned c = 0; c < end_points.length; c++)
{
- /* Locate the next gap of unreferenced points between two referenced points prev and next.
- * Note that a gap may wrap around at left (start_point) and/or at right (end_point).
- */
- unsigned int prev, next, i;
+ unsigned end_point = end_points.arrayZ[c];
+
+ /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
+ unsigned unref_count = 0;
+ for (unsigned i = start_point; i < end_point + 1; i++)
+ unref_count += deltas.arrayZ[i].flag;
+ unref_count = (end_point - start_point + 1) - unref_count;
+
+ unsigned j = start_point;
+ if (unref_count == 0 || unref_count > end_point - start_point)
+ goto no_more_gaps;
+
for (;;)
{
- i = j;
- j = next_index (i, start_point, end_point);
- if (deltas[i].flag && !deltas[j].flag) break;
+ /* Locate the next gap of unreferenced points between two referenced points prev and next.
+ * Note that a gap may wrap around at left (start_point) and/or at right (end_point).
+ */
+ unsigned int prev, next, i;
+ for (;;)
+ {
+ i = j;
+ j = next_index (i, start_point, end_point);
+ if (deltas.arrayZ[i].flag && !deltas.arrayZ[j].flag) break;
+ }
+ prev = j = i;
+ for (;;)
+ {
+ i = j;
+ j = next_index (i, start_point, end_point);
+ if (!deltas.arrayZ[i].flag && deltas.arrayZ[j].flag) break;
+ }
+ next = j;
+ /* Infer deltas for all unref points in the gap between prev and next */
+ i = prev;
+ for (;;)
+ {
+ i = next_index (i, start_point, end_point);
+ if (i == next) break;
+ deltas.arrayZ[i].x = infer_delta (orig_points, deltas, i, prev, next, &contour_point_t::x);
+ deltas.arrayZ[i].y = infer_delta (orig_points, deltas, i, prev, next, &contour_point_t::y);
+ if (--unref_count == 0) goto no_more_gaps;
+ }
}
- prev = j = i;
- for (;;)
- {
- i = j;
- j = next_index (i, start_point, end_point);
- if (!deltas[i].flag && deltas[j].flag) break;
- }
- next = j;
- /* Infer deltas for all unref points in the gap between prev and next */
- i = prev;
- for (;;)
- {
- i = next_index (i, start_point, end_point);
- if (i == next) break;
- deltas[i].x = infer_delta (orig_points.as_array (), deltas.as_array (), i, prev, next, &contour_point_t::x);
- deltas[i].y = infer_delta (orig_points.as_array (), deltas.as_array (), i, prev, next, &contour_point_t::y);
- if (--unref_count == 0) goto no_more_gaps;
- }
+ no_more_gaps:
+ start_point = end_point + 1;
}
- no_more_gaps:
- start_point = end_point + 1;
}
/* apply specified / inferred deltas to points */
diff --git a/src/hb-pool.hh b/src/hb-pool.hh
index dcf8f66..e4bb64f 100644
--- a/src/hb-pool.hh
+++ b/src/hb-pool.hh
@@ -35,15 +35,13 @@
struct hb_pool_t
{
hb_pool_t () : next (nullptr) {}
- ~hb_pool_t () { fini (); }
-
- void fini ()
+ ~hb_pool_t ()
{
next = nullptr;
- for (chunk_t *_ : chunks) hb_free (_);
-
- chunks.fini ();
+ + hb_iter (chunks)
+ | hb_apply (hb_free)
+ ;
}
T* alloc ()
@@ -60,7 +58,7 @@
T* obj = next;
next = * ((T**) next);
- memset (obj, 0, sizeof (T));
+ hb_memset (obj, 0, sizeof (T));
return obj;
}
diff --git a/src/hb-priority-queue.hh b/src/hb-priority-queue.hh
index ffb86e3..ac76b7d 100644
--- a/src/hb-priority-queue.hh
+++ b/src/hb-priority-queue.hh
@@ -63,7 +63,9 @@
heap.arrayZ[0] = heap.arrayZ[heap.length - 1];
heap.shrink (heap.length - 1);
- bubble_down (0);
+
+ if (!is_empty ())
+ bubble_down (0);
return result;
}
@@ -100,7 +102,7 @@
void bubble_down (unsigned index)
{
- assert (index <= heap.length);
+ assert (index < heap.length);
unsigned left = left_child (index);
unsigned right = right_child (index);
@@ -112,7 +114,7 @@
bool has_right = right < heap.length;
if (heap.arrayZ[index].first <= heap.arrayZ[left].first
- && (!has_right || heap[index].first <= heap.arrayZ[right].first))
+ && (!has_right || heap.arrayZ[index].first <= heap.arrayZ[right].first))
return;
if (!has_right || heap.arrayZ[left].first < heap.arrayZ[right].first)
@@ -128,7 +130,7 @@
void bubble_up (unsigned index)
{
- assert (index <= heap.length);
+ assert (index < heap.length);
if (index == 0) return;
@@ -142,8 +144,8 @@
void swap (unsigned a, unsigned b)
{
- assert (a <= heap.length);
- assert (b <= heap.length);
+ assert (a < heap.length);
+ assert (b < heap.length);
hb_swap (heap.arrayZ[a], heap.arrayZ[b]);
}
};
diff --git a/src/hb-repacker.hh b/src/hb-repacker.hh
index c97ce6c..7a3143c 100644
--- a/src/hb-repacker.hh
+++ b/src/hb-repacker.hh
@@ -209,7 +209,7 @@
// Only move at most half of the roots in a space at a time.
unsigned extra = roots_to_isolate.get_population () - maximum_to_move;
while (extra--) {
- unsigned root = HB_SET_VALUE_INVALID;
+ uint32_t root = HB_SET_VALUE_INVALID;
roots_to_isolate.previous (&root);
roots_to_isolate.del (root);
}
@@ -283,6 +283,11 @@
graph_t& sorted_graph /* IN/OUT */)
{
sorted_graph.sort_shortest_distance ();
+ if (sorted_graph.in_error ())
+ {
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Sorted graph in error state after initial sort.");
+ return false;
+ }
bool will_overflow = graph::will_overflow (sorted_graph);
if (!will_overflow)
@@ -376,6 +381,26 @@
unsigned max_rounds = 20,
bool recalculate_extensions = false) {
graph_t sorted_graph (packed);
+ if (sorted_graph.in_error ())
+ {
+ // Invalid graph definition.
+ return nullptr;
+ }
+
+ if (!sorted_graph.is_fully_connected ())
+ {
+ sorted_graph.print_orphaned_nodes ();
+ return nullptr;
+ }
+
+ if (sorted_graph.in_error ())
+ {
+ // Allocations failed somewhere
+ DEBUG_MSG (SUBSET_REPACK, nullptr,
+ "Graph is in error, likely due to a memory allocation error.");
+ return nullptr;
+ }
+
if (!hb_resolve_graph_overflows (table_tag, max_rounds, recalculate_extensions, sorted_graph))
return nullptr;
diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh
index 65c2772..bd3250e 100644
--- a/src/hb-sanitize.hh
+++ b/src/hb-sanitize.hh
@@ -198,10 +198,11 @@
void start_processing ()
{
reset_object ();
- if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR)))
+ unsigned m;
+ if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR, &m)))
this->max_ops = HB_SANITIZE_MAX_OPS_MAX;
else
- this->max_ops = hb_clamp ((unsigned) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
+ this->max_ops = hb_clamp (m,
(unsigned) HB_SANITIZE_MAX_OPS_MIN,
(unsigned) HB_SANITIZE_MAX_OPS_MAX);
this->edit_count = 0;
@@ -252,8 +253,9 @@
unsigned int a,
unsigned int b) const
{
- return !hb_unsigned_mul_overflows (a, b) &&
- this->check_range (base, a * b);
+ unsigned m;
+ return !hb_unsigned_mul_overflows (a, b, &m) &&
+ this->check_range (base, m);
}
template <typename T>
@@ -262,8 +264,9 @@
unsigned int b,
unsigned int c) const
{
- return !hb_unsigned_mul_overflows (a, b) &&
- this->check_range (base, a * b, c);
+ unsigned m;
+ return !hb_unsigned_mul_overflows (a, b, &m) &&
+ this->check_range (base, m, c);
}
template <typename T>
diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh
index f47cde5..d557328 100644
--- a/src/hb-serialize.hh
+++ b/src/hb-serialize.hh
@@ -194,7 +194,6 @@
current = current->next;
_->fini ();
}
- object_pool.fini ();
}
bool in_error () const { return bool (errors); }
@@ -224,6 +223,7 @@
this->errors = HB_SERIALIZE_ERROR_NONE;
this->head = this->start;
this->tail = this->end;
+ this->zerocopy = nullptr;
this->debug_depth = 0;
fini ();
@@ -326,7 +326,8 @@
if (unlikely (in_error() && !only_overflow ())) return;
current = current->next;
- revert (obj->head, obj->tail);
+ revert (zerocopy ? zerocopy : obj->head, obj->tail);
+ zerocopy = nullptr;
obj->fini ();
object_pool.release (obj);
}
@@ -344,8 +345,11 @@
current = current->next;
obj->tail = head;
obj->next = nullptr;
+ assert (obj->head <= obj->tail);
unsigned len = obj->tail - obj->head;
- head = obj->head; /* Rewind head. */
+ head = zerocopy ? zerocopy : obj->head; /* Rewind head. */
+ bool was_zerocopy = zerocopy;
+ zerocopy = nullptr;
if (!len)
{
@@ -355,9 +359,11 @@
}
objidx_t objidx;
+ uint32_t hash = 0;
if (share)
{
- objidx = packed_map.get (obj);
+ hash = hb_hash (obj);
+ objidx = packed_map.get_with_hash (obj, hash);
if (objidx)
{
merge_virtual_links (obj, objidx);
@@ -367,7 +373,10 @@
}
tail -= len;
- memmove (tail, obj->head, len);
+ if (was_zerocopy)
+ assert (tail == obj->head);
+ else
+ memmove (tail, obj->head, len);
obj->head = tail;
obj->tail = tail + len;
@@ -385,7 +394,7 @@
objidx = packed.length - 1;
- if (share) packed_map.set (obj, objidx);
+ if (share) packed_map.set_with_hash (obj, hash, objidx);
propagate_error (packed_map);
return objidx;
@@ -569,8 +578,26 @@
return !bool ((errors = (errors | err_type)));
}
+ bool start_zerocopy (size_t size)
+ {
+ if (unlikely (in_error ())) return false;
+
+ if (unlikely (size > INT_MAX || this->tail - this->head < ptrdiff_t (size)))
+ {
+ err (HB_SERIALIZE_ERROR_OUT_OF_ROOM);
+ return false;
+ }
+
+ assert (!this->zerocopy);
+ this->zerocopy = this->head;
+
+ assert (this->current->head == this->head);
+ this->current->head = this->current->tail = this->head = this->tail - size;
+ return true;
+ }
+
template <typename Type>
- Type *allocate_size (size_t size)
+ Type *allocate_size (size_t size, bool clear = true)
{
if (unlikely (in_error ())) return nullptr;
@@ -579,7 +606,8 @@
err (HB_SERIALIZE_ERROR_OUT_OF_ROOM);
return nullptr;
}
- hb_memset (this->head, 0, size);
+ if (clear)
+ hb_memset (this->head, 0, size);
char *ret = this->head;
this->head += size;
return reinterpret_cast<Type *> (ret);
@@ -593,9 +621,9 @@
Type *embed (const Type *obj)
{
unsigned int size = obj->get_size ();
- Type *ret = this->allocate_size<Type> (size);
+ Type *ret = this->allocate_size<Type> (size, false);
if (unlikely (!ret)) return nullptr;
- memcpy (ret, obj, size);
+ hb_memcpy (ret, obj, size);
return ret;
}
template <typename Type>
@@ -616,7 +644,7 @@
}
/* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data
- * instead of memcpy(). */
+ * instead of hb_memcpy(). */
template <typename Type, typename ...Ts>
Type *copy (const Type &src, Ts&&... ds)
{ return _copy (src, hb_prioritize, std::forward<Ts> (ds)...); }
@@ -634,7 +662,7 @@
hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; }
template <typename Type>
- Type *extend_size (Type *obj, size_t size)
+ Type *extend_size (Type *obj, size_t size, bool clear = true)
{
if (unlikely (in_error ())) return nullptr;
@@ -642,12 +670,12 @@
assert ((char *) obj <= this->head);
assert ((size_t) (this->head - (char *) obj) <= size);
if (unlikely (((char *) obj + size < (char *) obj) ||
- !this->allocate_size<Type> (((char *) obj) + size - this->head))) return nullptr;
+ !this->allocate_size<Type> (((char *) obj) + size - this->head, clear))) return nullptr;
return reinterpret_cast<Type *> (obj);
}
template <typename Type>
- Type *extend_size (Type &obj, size_t size)
- { return extend_size (std::addressof (obj), size); }
+ Type *extend_size (Type &obj, size_t size, bool clear = true)
+ { return extend_size (std::addressof (obj), size, clear); }
template <typename Type>
Type *extend_min (Type *obj) { return extend_size (obj, obj->min_size); }
@@ -676,8 +704,8 @@
char *p = (char *) hb_malloc (len);
if (unlikely (!p)) return hb_bytes_t ();
- memcpy (p, this->start, this->head - this->start);
- memcpy (p + (this->head - this->start), this->tail, this->end - this->tail);
+ hb_memcpy (p, this->start, this->head - this->start);
+ hb_memcpy (p + (this->head - this->start), this->tail, this->end - this->tail);
return hb_bytes_t (p, len);
}
template <typename Type>
@@ -704,7 +732,7 @@
}
public:
- char *start, *head, *tail, *end;
+ char *start, *head, *tail, *end, *zerocopy;
unsigned int debug_depth;
hb_serialize_error_t errors;
diff --git a/src/hb-set-digest.hh b/src/hb-set-digest.hh
index fab3621..e840911 100644
--- a/src/hb-set-digest.hh
+++ b/src/hb-set-digest.hh
@@ -28,6 +28,7 @@
#define HB_SET_DIGEST_HH
#include "hb.hh"
+#include "hb-machinery.hh"
/*
* The set-digests here implement various "filters" that support
@@ -75,6 +76,8 @@
void init () { mask = 0; }
+ void add (const hb_set_digest_bits_pattern_t &o) { mask |= o.mask; }
+
void add (hb_codepoint_t g) { mask |= mask_for (g); }
bool add_range (hb_codepoint_t a, hb_codepoint_t b)
@@ -95,7 +98,7 @@
for (unsigned int i = 0; i < count; i++)
{
add (*array);
- array = (const T *) (stride + (const char *) array);
+ array = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
}
}
template <typename T>
@@ -103,16 +106,15 @@
template <typename T>
bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
{
- for (unsigned int i = 0; i < count; i++)
- {
- add (*array);
- array = (const T *) (stride + (const char *) array);
- }
+ add_array (array, count, stride);
return true;
}
template <typename T>
bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
+ bool may_have (const hb_set_digest_bits_pattern_t &o) const
+ { return mask & o.mask; }
+
bool may_have (hb_codepoint_t g) const
{ return mask & mask_for (g); }
@@ -132,6 +134,12 @@
tail.init ();
}
+ void add (const hb_set_digest_combiner_t &o)
+ {
+ head.add (o.head);
+ tail.add (o.tail);
+ }
+
void add (hb_codepoint_t g)
{
head.add (g);
@@ -140,9 +148,8 @@
bool add_range (hb_codepoint_t a, hb_codepoint_t b)
{
- head.add_range (a, b);
- tail.add_range (a, b);
- return true;
+ return head.add_range (a, b) &&
+ tail.add_range (a, b);
}
template <typename T>
void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
@@ -155,13 +162,17 @@
template <typename T>
bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
{
- head.add_sorted_array (array, count, stride);
- tail.add_sorted_array (array, count, stride);
- return true;
+ return head.add_sorted_array (array, count, stride) &&
+ tail.add_sorted_array (array, count, stride);
}
template <typename T>
bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
+ bool may_have (const hb_set_digest_combiner_t &o) const
+ {
+ return head.may_have (o.head) && tail.may_have (o.tail);
+ }
+
bool may_have (hb_codepoint_t g) const
{
return head.may_have (g) && tail.may_have (g);
diff --git a/src/hb-set.hh b/src/hb-set.hh
index 5d5576c..f958a08 100644
--- a/src/hb-set.hh
+++ b/src/hb-set.hh
@@ -105,10 +105,8 @@
bool get (hb_codepoint_t g) const { return s.get (g); }
/* Has interface. */
- static constexpr bool SENTINEL = false;
- typedef bool value_t;
- value_t operator [] (hb_codepoint_t k) const { return get (k); }
- bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+ bool operator [] (hb_codepoint_t k) const { return get (k); }
+ bool has (hb_codepoint_t k) const { return (*this)[k]; }
/* Predicate. */
bool operator () (hb_codepoint_t k) const { return has (k); }
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index 9e513c0..cabcbd4 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -31,6 +31,8 @@
#include "hb-buffer.hh"
+#ifndef HB_NO_SHAPER
+
/**
* SECTION:hb-shape-plan
* @title: hb-shape-plan
@@ -74,7 +76,7 @@
this->user_features = copy ? features : user_features;
if (copy && num_user_features)
{
- memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
+ hb_memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
/* Make start/end uniform to easier catch bugs. */
for (unsigned int i = 0; i < num_user_features; i++)
{
@@ -574,3 +576,6 @@
return hb_shape_plan_reference (shape_plan);
}
+
+
+#endif
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 547d0af..7b5bf2c 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -35,6 +35,8 @@
#include "hb-machinery.hh"
+#ifndef HB_NO_SHAPER
+
/**
* SECTION:hb-shape
* @title: hb-shape
@@ -192,3 +194,6 @@
{
hb_shape_full (font, buffer, features, num_features, nullptr);
}
+
+
+#endif
diff --git a/src/hb-shaper.cc b/src/hb-shaper.cc
index a900ac6..c4885cd 100644
--- a/src/hb-shaper.cc
+++ b/src/hb-shaper.cc
@@ -53,7 +53,7 @@
if (unlikely (!shapers))
return nullptr;
- memcpy (shapers, _hb_all_shapers, sizeof (_hb_all_shapers));
+ hb_memcpy (shapers, _hb_all_shapers, sizeof (_hb_all_shapers));
/* Reorder shaper list to prefer requested shapers. */
unsigned int i = 0;
diff --git a/src/hb-static.cc b/src/hb-static.cc
index 5d4c7cd..eac5075 100644
--- a/src/hb-static.cc
+++ b/src/hb-static.cc
@@ -33,6 +33,7 @@
#include "hb-aat-layout-feat-table.hh"
#include "hb-ot-layout-common.hh"
#include "hb-ot-cmap-table.hh"
+#include "hb-ot-color-colr-table.hh"
#include "hb-ot-glyf-table.hh"
#include "hb-ot-head-table.hh"
#include "hb-ot-maxp-table.hh"
@@ -47,6 +48,7 @@
DEFINE_NULL_NAMESPACE_BYTES (OT, VarIdx) = {0xFF,0xFF,0xFF,0xFF};
DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00};
DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x01};
+DEFINE_NULL_NAMESPACE_BYTES (OT, ClipRecord) = {0x01};
DEFINE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup) = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00};
DEFINE_NULL_NAMESPACE_BYTES (AAT, SettingName) = {0xFF,0xFF, 0xFF,0xFF};
DEFINE_NULL_NAMESPACE_BYTES (AAT, Lookup) = {0xFF,0xFF};
diff --git a/src/hb-subset-accelerator.hh b/src/hb-subset-accelerator.hh
index 34bd053..63ae6d7 100644
--- a/src/hb-subset-accelerator.hh
+++ b/src/hb-subset-accelerator.hh
@@ -31,21 +31,34 @@
#include "hb.hh"
#include "hb-map.hh"
+#include "hb-multimap.hh"
#include "hb-set.hh"
+extern HB_INTERNAL hb_user_data_key_t _hb_subset_accelerator_user_data_key;
+
+namespace CFF {
+struct cff_subset_accelerator_t;
+}
+
+namespace OT {
+struct SubtableUnicodesCache;
+};
+
struct hb_subset_accelerator_t
{
static hb_user_data_key_t* user_data_key()
{
- static hb_user_data_key_t key;
- return &key;
+ return &_hb_subset_accelerator_user_data_key;
}
static hb_subset_accelerator_t* create(const hb_map_t& unicode_to_gid_,
- const hb_set_t& unicodes_) {
+ const hb_multimap_t gid_to_unicodes_,
+ const hb_set_t& unicodes_,
+ bool has_seac_) {
hb_subset_accelerator_t* accel =
(hb_subset_accelerator_t*) hb_malloc (sizeof(hb_subset_accelerator_t));
- new (accel) hb_subset_accelerator_t (unicode_to_gid_, unicodes_);
+ new (accel) hb_subset_accelerator_t (unicode_to_gid_, gid_to_unicodes_, unicodes_);
+ accel->has_seac = has_seac_;
return accel;
}
@@ -53,22 +66,54 @@
if (!value) return;
hb_subset_accelerator_t* accel = (hb_subset_accelerator_t*) value;
+
+ if (accel->cff_accelerator && accel->destroy_cff_accelerator)
+ accel->destroy_cff_accelerator ((void*) accel->cff_accelerator);
+
+ if (accel->cmap_cache && accel->destroy_cmap_cache)
+ accel->destroy_cmap_cache ((void*) accel->cmap_cache);
+
accel->~hb_subset_accelerator_t ();
hb_free (accel);
}
- hb_subset_accelerator_t(const hb_map_t& unicode_to_gid_,
+ hb_subset_accelerator_t (const hb_map_t& unicode_to_gid_,
+ const hb_multimap_t& gid_to_unicodes_,
const hb_set_t& unicodes_)
- : unicode_to_gid(unicode_to_gid_), unicodes(unicodes_) {}
+ : unicode_to_gid(unicode_to_gid_), gid_to_unicodes (gid_to_unicodes_), unicodes(unicodes_),
+ cmap_cache(nullptr), destroy_cmap_cache(nullptr),
+ has_seac(false), cff_accelerator(nullptr), destroy_cff_accelerator(nullptr)
+ { sanitized_table_cache_lock.init (); }
+
+ ~hb_subset_accelerator_t ()
+ { sanitized_table_cache_lock.fini (); }
+
+ // Generic
+
+ mutable hb_mutex_t sanitized_table_cache_lock;
+ mutable hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>> sanitized_table_cache;
const hb_map_t unicode_to_gid;
+ const hb_multimap_t gid_to_unicodes;
const hb_set_t unicodes;
+
+ // cmap
+ const OT::SubtableUnicodesCache* cmap_cache;
+ hb_destroy_func_t destroy_cmap_cache;
+
+ // CFF
+ bool has_seac;
+ const CFF::cff_subset_accelerator_t* cff_accelerator;
+ hb_destroy_func_t destroy_cff_accelerator;
+
// TODO(garretrieger): cumulative glyf checksum map
- // TODO(garretrieger): sanitized table cache.
bool in_error () const
{
- return unicode_to_gid.in_error() || unicodes.in_error ();
+ return unicode_to_gid.in_error () ||
+ gid_to_unicodes.in_error () ||
+ unicodes.in_error () ||
+ sanitized_table_cache.in_error ();
}
};
diff --git a/src/hb-subset-cff-common.cc b/src/hb-subset-cff-common.cc
index 711b223..6e1b6f7 100644
--- a/src/hb-subset-cff-common.cc
+++ b/src/hb-subset-cff-common.cc
@@ -66,8 +66,7 @@
{
/* use hb_set to determine the subset of font dicts */
- hb_set_t *set = hb_set_create ();
- if (unlikely (set == &Null (hb_set_t))) return false;
+ hb_set_t set;
hb_codepoint_t prev_fd = CFF_UNDEF_CODE;
for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++)
{
@@ -79,7 +78,7 @@
glyph = i;
}
fd = src.get_fd (glyph);
- set->add (fd);
+ set.add (fd);
if (fd != prev_fd)
{
@@ -90,12 +89,11 @@
}
}
- subset_fd_count = set->get_population ();
+ subset_fd_count = set.get_population ();
if (subset_fd_count == fdCount)
{
/* all font dicts belong to the subset. no need to subset FDSelect & FDArray */
fdmap.identity (fdCount);
- hb_set_destroy (set);
}
else
{
@@ -103,9 +101,8 @@
fdmap.reset ();
hb_codepoint_t fd = CFF_UNDEF_CODE;
- while (set->next (&fd))
+ while (set.next (&fd))
fdmap.add (fd);
- hb_set_destroy (set);
if (unlikely (fdmap.get_population () != subset_fd_count))
return false;
}
diff --git a/src/hb-subset-cff-common.hh b/src/hb-subset-cff-common.hh
index bb9f27e..8bbc017 100644
--- a/src/hb-subset-cff-common.hh
+++ b/src/hb-subset-cff-common.hh
@@ -38,15 +38,16 @@
struct str_encoder_t
{
str_encoder_t (str_buff_t &buff_)
- : buff (buff_), error (false) {}
+ : buff (buff_) {}
void reset () { buff.reset (); }
void encode_byte (unsigned char b)
{
- buff.push (b);
- if (unlikely (buff.in_error ()))
- set_error ();
+ if (likely ((signed) buff.length < buff.allocated))
+ buff.arrayZ[buff.length++] = b;
+ else
+ buff.push (b);
}
void encode_int (int v)
@@ -108,27 +109,18 @@
encode_byte (op);
}
- void copy_str (const hb_ubytes_t &str)
+ void copy_str (const unsigned char *str, unsigned length)
{
- unsigned int offset = buff.length;
- /* Manually resize buffer since faster. */
- if ((signed) (buff.length + str.length) <= buff.allocated)
- buff.length += str.length;
- else if (unlikely (!buff.resize (offset + str.length)))
- {
- set_error ();
- return;
- }
- memcpy (buff.arrayZ + offset, &str[0], str.length);
+ assert ((signed) (buff.length + length) <= buff.allocated);
+ hb_memcpy (buff.arrayZ + buff.length, str, length);
+ buff.length += length;
}
- bool is_error () const { return error; }
+ bool in_error () const { return buff.in_error (); }
protected:
- void set_error () { error = true; }
str_buff_t &buff;
- bool error;
};
struct cff_sub_table_info_t {
@@ -187,9 +179,12 @@
}
else
{
- HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length);
+ unsigned char *d = c->allocate_size<unsigned char> (opstr.length);
if (unlikely (!d)) return_trace (false);
- memcpy (d, &opstr.str[0], opstr.str.length);
+ /* Faster than hb_memcpy for small strings. */
+ for (unsigned i = 0; i < opstr.length; i++)
+ d[i] = opstr.ptr[i];
+ //hb_memcpy (d, opstr.ptr, opstr.length);
}
return_trace (true);
}
@@ -239,11 +234,10 @@
bool flatten (str_buff_vec_t &flat_charstrings)
{
- if (!flat_charstrings.resize (plan->num_output_glyphs ()))
+ unsigned count = plan->num_output_glyphs ();
+ if (!flat_charstrings.resize (count))
return false;
- for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
- flat_charstrings[i].init ();
- for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
+ for (unsigned int i = 0; i < count; i++)
{
hb_codepoint_t glyph;
if (!plan->old_gid_for_new_gid (i, &glyph))
@@ -259,7 +253,7 @@
ENV env (str, acc, fd);
cs_interpreter_t<ENV, OPSET, flatten_param_t> interp (env);
flatten_param_t param = {
- flat_charstrings[i],
+ flat_charstrings.arrayZ[i],
(bool) (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
};
if (unlikely (!interp.interpret (param)))
@@ -274,11 +268,9 @@
struct subr_closures_t
{
- subr_closures_t (unsigned int fd_count) : valid (false), global_closure (), local_closures ()
+ subr_closures_t (unsigned int fd_count) : global_closure (), local_closures ()
{
- valid = true;
- if (!local_closures.resize (fd_count))
- valid = false;
+ local_closures.resize (fd_count);
}
void reset ()
@@ -288,47 +280,38 @@
local_closures[i].clear();
}
- bool is_valid () const { return valid; }
- bool valid;
+ bool in_error () const { return local_closures.in_error (); }
hb_set_t global_closure;
hb_vector_t<hb_set_t> local_closures;
};
struct parsed_cs_op_t : op_str_t
{
- void init (unsigned int subr_num_ = 0)
- {
- subr_num = subr_num_;
- drop_flag = false;
- keep_flag = false;
- skip_flag = false;
- }
+ parsed_cs_op_t (unsigned int subr_num_ = 0) :
+ subr_num (subr_num_) {}
- bool for_drop () const { return drop_flag; }
- void set_drop () { if (!for_keep ()) drop_flag = true; }
+ bool is_hinting () const { return hinting_flag; }
+ void set_hinting () { hinting_flag = true; }
- bool for_keep () const { return keep_flag; }
- void set_keep () { keep_flag = true; }
-
- bool for_skip () const { return skip_flag; }
- void set_skip () { skip_flag = true; }
-
- unsigned int subr_num;
+ /* The layout of this struct is designed to fit within the
+ * padding of op_str_t! */
protected:
- bool drop_flag;
- bool keep_flag;
- bool skip_flag;
+ bool hinting_flag = false;
+
+ public:
+ uint16_t subr_num;
};
struct parsed_cs_str_t : parsed_values_t<parsed_cs_op_t>
{
- void init ()
+ parsed_cs_str_t () :
+ parsed (false),
+ hint_dropped (false),
+ has_prefix_ (false),
+ has_calls_ (false)
{
SUPER::init ();
- parsed = false;
- hint_dropped = false;
- has_prefix_ = false;
}
void add_op (op_code_t op, const byte_str_ref_t& str_ref)
@@ -341,13 +324,12 @@
{
if (!is_parsed ())
{
- unsigned int parsed_len = get_count ();
- if (likely (parsed_len > 0))
- values[parsed_len-1].set_skip ();
+ has_calls_ = true;
- parsed_cs_op_t val;
- val.init (subr_num);
- SUPER::add_op (op, str_ref, val);
+ /* Pop the subroutine number. */
+ values.pop ();
+
+ SUPER::add_op (op, str_ref, {subr_num});
}
}
@@ -377,11 +359,14 @@
op_code_t prefix_op () const { return prefix_op_; }
const number_t &prefix_num () const { return prefix_num_; }
+ bool has_calls () const { return has_calls_; }
+
protected:
- bool parsed;
- bool hint_dropped;
- bool vsindex_dropped;
- bool has_prefix_;
+ bool parsed : 1;
+ bool hint_dropped : 1;
+ bool vsindex_dropped : 1;
+ bool has_prefix_ : 1;
+ bool has_calls_ : 1;
op_code_t prefix_op_;
number_t prefix_num_;
@@ -395,6 +380,59 @@
typedef hb_vector_t<parsed_cs_str_t> SUPER;
};
+struct cff_subset_accelerator_t
+{
+ static cff_subset_accelerator_t* create (
+ hb_blob_t* original_blob,
+ const parsed_cs_str_vec_t& parsed_charstrings,
+ const parsed_cs_str_vec_t& parsed_global_subrs,
+ const hb_vector_t<parsed_cs_str_vec_t>& parsed_local_subrs) {
+ cff_subset_accelerator_t* accel =
+ (cff_subset_accelerator_t*) hb_malloc (sizeof(cff_subset_accelerator_t));
+ new (accel) cff_subset_accelerator_t (original_blob,
+ parsed_charstrings,
+ parsed_global_subrs,
+ parsed_local_subrs);
+ return accel;
+ }
+
+ static void destroy (void* value) {
+ if (!value) return;
+
+ cff_subset_accelerator_t* accel = (cff_subset_accelerator_t*) value;
+ accel->~cff_subset_accelerator_t ();
+ hb_free (accel);
+ }
+
+ cff_subset_accelerator_t(
+ hb_blob_t* original_blob_,
+ const parsed_cs_str_vec_t& parsed_charstrings_,
+ const parsed_cs_str_vec_t& parsed_global_subrs_,
+ const hb_vector_t<parsed_cs_str_vec_t>& parsed_local_subrs_)
+ {
+ parsed_charstrings = parsed_charstrings_;
+ parsed_global_subrs = parsed_global_subrs_;
+ parsed_local_subrs = parsed_local_subrs_;
+
+ // the parsed charstrings point to memory in the original CFF table so we must hold a reference
+ // to it to keep the memory valid.
+ original_blob = hb_blob_reference (original_blob_);
+ }
+
+ ~cff_subset_accelerator_t() {
+ hb_blob_destroy (original_blob);
+ hb_map_destroy (glyph_to_sid_map.get_relaxed ());
+ }
+
+ parsed_cs_str_vec_t parsed_charstrings;
+ parsed_cs_str_vec_t parsed_global_subrs;
+ hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs;
+ mutable hb_atomic_ptr_t<hb_map_t> glyph_to_sid_map = nullptr;
+
+ private:
+ hb_blob_t* original_blob;
+};
+
struct subr_subset_param_t
{
subr_subset_param_t (parsed_cs_str_t *parsed_charstring_,
@@ -446,7 +484,11 @@
if (unlikely (calling && !parsed_str->is_parsed () && (parsed_str->values.length > 0)))
env.set_error ();
else
+ {
+ if (!parsed_str->is_parsed ())
+ parsed_str->alloc (env.str_ref.total_size () / 2);
current_parsed_str = parsed_str;
+ }
}
parsed_cs_str_t *current_parsed_str;
@@ -506,7 +548,7 @@
{
global_remap.create (&closures.global_closure);
for (unsigned int i = 0; i < local_remaps.length; i++)
- local_remaps[i].create (&closures.local_closures[i]);
+ local_remaps.arrayZ[i].create (&closures.local_closures[i]);
}
subr_remap_t global_remap;
@@ -517,7 +559,8 @@
struct subr_subsetter_t
{
subr_subsetter_t (ACC &acc_, const hb_subset_plan_t *plan_)
- : acc (acc_), plan (plan_), closures(acc_.fdCount), remaps(acc_.fdCount)
+ : acc (acc_), plan (plan_), closures(acc_.fdCount),
+ remaps(acc_.fdCount)
{}
/* Subroutine subsetting with --no-desubroutinize runs in phases:
@@ -536,55 +579,96 @@
*/
bool subset (void)
{
- parsed_charstrings.resize (plan->num_output_glyphs ());
- parsed_global_subrs.resize (acc.globalSubrs->count);
+ unsigned fd_count = acc.fdCount;
+ const cff_subset_accelerator_t* cff_accelerator = nullptr;
+ if (plan->accelerator && plan->accelerator->cff_accelerator) {
+ cff_accelerator = plan->accelerator->cff_accelerator;
+ fd_count = cff_accelerator->parsed_local_subrs.length;
+ }
+
+ if (cff_accelerator) {
+ // If we are not dropping hinting then charstrings are not modified so we can
+ // just use a reference to the cached copies.
+ cached_charstrings.resize (plan->num_output_glyphs ());
+ parsed_global_subrs = &cff_accelerator->parsed_global_subrs;
+ parsed_local_subrs = &cff_accelerator->parsed_local_subrs;
+ } else {
+ parsed_charstrings.resize (plan->num_output_glyphs ());
+ parsed_global_subrs_storage.resize (acc.globalSubrs->count);
+
+ if (unlikely (!parsed_local_subrs_storage.resize (fd_count))) return false;
+
+ for (unsigned int i = 0; i < acc.fdCount; i++)
+ {
+ unsigned count = acc.privateDicts[i].localSubrs->count;
+ parsed_local_subrs_storage[i].resize (count);
+ if (unlikely (parsed_local_subrs_storage[i].in_error ())) return false;
+ }
+
+ parsed_global_subrs = &parsed_global_subrs_storage;
+ parsed_local_subrs = &parsed_local_subrs_storage;
+ }
if (unlikely (remaps.in_error()
+ || cached_charstrings.in_error ()
|| parsed_charstrings.in_error ()
- || parsed_global_subrs.in_error ())) {
+ || parsed_global_subrs->in_error ()
+ || closures.in_error ())) {
return false;
}
- if (unlikely (!parsed_local_subrs.resize (acc.fdCount))) return false;
-
- for (unsigned int i = 0; i < acc.fdCount; i++)
- {
- parsed_local_subrs[i].resize (acc.privateDicts[i].localSubrs->count);
- if (unlikely (parsed_local_subrs[i].in_error ())) return false;
- }
- if (unlikely (!closures.valid))
- return false;
-
/* phase 1 & 2 */
for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
{
hb_codepoint_t glyph;
if (!plan->old_gid_for_new_gid (i, &glyph))
- continue;
+ continue;
+
const hb_ubytes_t str = (*acc.charStrings)[glyph];
unsigned int fd = acc.fdSelect->get_fd (glyph);
if (unlikely (fd >= acc.fdCount))
- return false;
+ return false;
+
+ if (cff_accelerator)
+ {
+ // parsed string already exists in accelerator, copy it and move
+ // on.
+ if (cached_charstrings)
+ cached_charstrings[i] = &cff_accelerator->parsed_charstrings[glyph];
+ else
+ parsed_charstrings[i] = cff_accelerator->parsed_charstrings[glyph];
+
+ continue;
+ }
ENV env (str, acc, fd);
cs_interpreter_t<ENV, OPSET, subr_subset_param_t> interp (env);
- parsed_charstrings[i].alloc (str.length);
+ parsed_charstrings[i].alloc (str.length / 2);
subr_subset_param_t param (&parsed_charstrings[i],
- &parsed_global_subrs,
- &parsed_local_subrs[fd],
- &closures.global_closure,
- &closures.local_closures[fd],
- plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
+ &parsed_global_subrs_storage,
+ &parsed_local_subrs_storage[fd],
+ &closures.global_closure,
+ &closures.local_closures[fd],
+ plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
if (unlikely (!interp.interpret (param)))
- return false;
+ return false;
/* complete parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */
SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[i]);
}
- if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
+ // Since parsed strings were loaded from accelerator, we still need
+ // to compute the subroutine closures which would have normally happened during
+ // parsing.
+ if (cff_accelerator &&
+ !closure_subroutines(*parsed_global_subrs,
+ *parsed_local_subrs))
+ return false;
+
+ if ((plan->flags & HB_SUBSET_FLAGS_NO_HINTING && !cff_accelerator) ||
+ plan->inprogress_accelerator)
{
/* mark hint ops and arguments for drop */
for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
@@ -596,8 +680,8 @@
if (unlikely (fd >= acc.fdCount))
return false;
subr_subset_param_t param (&parsed_charstrings[i],
- &parsed_global_subrs,
- &parsed_local_subrs[fd],
+ &parsed_global_subrs_storage,
+ &parsed_local_subrs_storage[fd],
&closures.global_closure,
&closures.local_closures[fd],
plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
@@ -612,27 +696,14 @@
}
/* after dropping hints recreate closures of actually used subrs */
- closures.reset ();
- for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
- {
- hb_codepoint_t glyph;
- if (!plan->old_gid_for_new_gid (i, &glyph))
- continue;
- unsigned int fd = acc.fdSelect->get_fd (glyph);
- if (unlikely (fd >= acc.fdCount))
- return false;
- subr_subset_param_t param (&parsed_charstrings[i],
- &parsed_global_subrs,
- &parsed_local_subrs[fd],
- &closures.global_closure,
- &closures.local_closures[fd],
- plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
- collect_subr_refs_in_str (parsed_charstrings[i], param);
- }
+ if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING &&
+ !cff_accelerator &&
+ !closure_subroutines(*parsed_global_subrs, *parsed_local_subrs)) return false;
}
remaps.create (closures);
+ populate_subset_accelerator ();
return true;
}
@@ -646,13 +717,13 @@
if (!plan->old_gid_for_new_gid (i, &glyph))
{
/* add an endchar only charstring for a missing glyph if CFF1 */
- if (endchar_op != OpCode_Invalid) buffArray[i].push (endchar_op);
+ if (endchar_op != OpCode_Invalid) buffArray.arrayZ[i].push (endchar_op);
continue;
}
unsigned int fd = acc.fdSelect->get_fd (glyph);
if (unlikely (fd >= acc.fdCount))
return false;
- if (unlikely (!encode_str (parsed_charstrings[i], fd, buffArray[i])))
+ if (unlikely (!encode_str (get_parsed_charstring (i), fd, buffArray.arrayZ[i])))
return false;
}
return true;
@@ -664,26 +735,25 @@
if (unlikely (!buffArray.resize (count)))
return false;
- for (unsigned int old_num = 0; old_num < subrs.length; old_num++)
+ for (unsigned int new_num = 0; new_num < count; new_num++)
{
- hb_codepoint_t new_num = remap[old_num];
- if (new_num != CFF_UNDEF_CODE)
- {
- if (unlikely (!encode_str (subrs[old_num], fd, buffArray[new_num])))
- return false;
- }
+ hb_codepoint_t old_num = remap.backward (new_num);
+ assert (old_num != CFF_UNDEF_CODE);
+
+ if (unlikely (!encode_str (subrs[old_num], fd, buffArray[new_num])))
+ return false;
}
return true;
}
bool encode_globalsubrs (str_buff_vec_t &buffArray)
{
- return encode_subrs (parsed_global_subrs, remaps.global_remap, 0, buffArray);
+ return encode_subrs (*parsed_global_subrs, remaps.global_remap, 0, buffArray);
}
bool encode_localsubrs (unsigned int fd, str_buff_vec_t &buffArray) const
{
- return encode_subrs (parsed_local_subrs[fd], remaps.local_remaps[fd], fd, buffArray);
+ return encode_subrs ((*parsed_local_subrs)[fd], remaps.local_remaps[fd], fd, buffArray);
}
protected:
@@ -712,7 +782,7 @@
* then this entire subroutine must be a hint. drop its call. */
if (drop.ends_in_hint)
{
- str.values[pos].set_drop ();
+ str.values[pos].set_hinting ();
/* if this subr call is at the end of the parent subr, propagate the flag
* otherwise reset the flag */
if (!str.at_end (pos))
@@ -720,7 +790,7 @@
}
else if (drop.all_dropped)
{
- str.values[pos].set_drop ();
+ str.values[pos].set_hinting ();
}
return has_hint;
@@ -731,20 +801,22 @@
{
bool seen_hint = false;
- for (unsigned int pos = 0; pos < str.values.length; pos++)
+ unsigned count = str.values.length;
+ auto *values = str.values.arrayZ;
+ for (unsigned int pos = 0; pos < count; pos++)
{
bool has_hint = false;
- switch (str.values[pos].op)
+ switch (values[pos].op)
{
case OpCode_callsubr:
has_hint = drop_hints_in_subr (str, pos,
- *param.parsed_local_subrs, str.values[pos].subr_num,
+ *param.parsed_local_subrs, values[pos].subr_num,
param, drop);
break;
case OpCode_callgsubr:
has_hint = drop_hints_in_subr (str, pos,
- *param.parsed_global_subrs, str.values[pos].subr_num,
+ *param.parsed_global_subrs, values[pos].subr_num,
param, drop);
break;
@@ -758,7 +830,7 @@
case OpCode_cntrmask:
if (drop.seen_moveto)
{
- str.values[pos].set_drop ();
+ values[pos].set_hinting ();
break;
}
HB_FALLTHROUGH;
@@ -768,13 +840,13 @@
case OpCode_hstem:
case OpCode_vstem:
has_hint = true;
- str.values[pos].set_drop ();
+ values[pos].set_hinting ();
if (str.at_end (pos))
drop.ends_in_hint = true;
break;
case OpCode_dotsection:
- str.values[pos].set_drop ();
+ values[pos].set_hinting ();
break;
default:
@@ -785,10 +857,10 @@
{
for (int i = pos - 1; i >= 0; i--)
{
- parsed_cs_op_t &csop = str.values[(unsigned)i];
- if (csop.for_drop ())
+ parsed_cs_op_t &csop = values[(unsigned)i];
+ if (csop.is_hinting ())
break;
- csop.set_drop ();
+ csop.set_hinting ();
if (csop.op == OpCode_vsindexcs)
drop.vsindex_dropped = true;
}
@@ -801,12 +873,12 @@
* only (usually one) hintmask operator, then calls to this subr can be dropped.
*/
drop.all_dropped = true;
- for (unsigned int pos = 0; pos < str.values.length; pos++)
+ for (unsigned int pos = 0; pos < count; pos++)
{
- parsed_cs_op_t &csop = str.values[pos];
+ parsed_cs_op_t &csop = values[pos];
if (csop.op == OpCode_return)
break;
- if (!csop.for_drop ())
+ if (!csop.is_hinting ())
{
drop.all_dropped = false;
break;
@@ -816,32 +888,62 @@
return seen_hint;
}
- void collect_subr_refs_in_subr (parsed_cs_str_t &str, unsigned int pos,
- unsigned int subr_num, parsed_cs_str_vec_t &subrs,
+ bool closure_subroutines (const parsed_cs_str_vec_t& global_subrs,
+ const hb_vector_t<parsed_cs_str_vec_t>& local_subrs)
+ {
+ closures.reset ();
+ for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
+ {
+ hb_codepoint_t glyph;
+ if (!plan->old_gid_for_new_gid (i, &glyph))
+ continue;
+ unsigned int fd = acc.fdSelect->get_fd (glyph);
+ if (unlikely (fd >= acc.fdCount))
+ return false;
+
+ // Note: const cast is safe here because the collect_subr_refs_in_str only performs a
+ // closure and does not modify any of the charstrings.
+ subr_subset_param_t param (const_cast<parsed_cs_str_t*> (&get_parsed_charstring (i)),
+ const_cast<parsed_cs_str_vec_t*> (&global_subrs),
+ const_cast<parsed_cs_str_vec_t*> (&local_subrs[fd]),
+ &closures.global_closure,
+ &closures.local_closures[fd],
+ plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
+ collect_subr_refs_in_str (get_parsed_charstring (i), param);
+ }
+
+ return true;
+ }
+
+ void collect_subr_refs_in_subr (unsigned int subr_num, parsed_cs_str_vec_t &subrs,
hb_set_t *closure,
const subr_subset_param_t ¶m)
{
+ if (closure->has (subr_num))
+ return;
closure->add (subr_num);
collect_subr_refs_in_str (subrs[subr_num], param);
}
- void collect_subr_refs_in_str (parsed_cs_str_t &str, const subr_subset_param_t ¶m)
+ void collect_subr_refs_in_str (const parsed_cs_str_t &str,
+ const subr_subset_param_t ¶m)
{
- for (unsigned int pos = 0; pos < str.values.length; pos++)
+ if (!str.has_calls ())
+ return;
+
+ for (auto &opstr : str.values)
{
- if (!str.values[pos].for_drop ())
+ if (!param.drop_hints || !opstr.is_hinting ())
{
- switch (str.values[pos].op)
+ switch (opstr.op)
{
case OpCode_callsubr:
- collect_subr_refs_in_subr (str, pos,
- str.values[pos].subr_num, *param.parsed_local_subrs,
+ collect_subr_refs_in_subr (opstr.subr_num, *param.parsed_local_subrs,
param.local_closure, param);
break;
case OpCode_callgsubr:
- collect_subr_refs_in_subr (str, pos,
- str.values[pos].subr_num, *param.parsed_global_subrs,
+ collect_subr_refs_in_subr (opstr.subr_num, *param.parsed_global_subrs,
param.global_closure, param);
break;
@@ -853,42 +955,113 @@
bool encode_str (const parsed_cs_str_t &str, const unsigned int fd, str_buff_t &buff) const
{
- unsigned count = str.get_count ();
str_encoder_t encoder (buff);
encoder.reset ();
- buff.alloc (count * 3);
+ bool hinting = !(plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
/* if a prefix (CFF1 width or CFF2 vsindex) has been removed along with hints,
* re-insert it at the beginning of charstreing */
- if (str.has_prefix () && str.is_hint_dropped ())
+ if (str.has_prefix () && !hinting && str.is_hint_dropped ())
{
encoder.encode_num (str.prefix_num ());
if (str.prefix_op () != OpCode_Invalid)
encoder.encode_op (str.prefix_op ());
}
- for (unsigned int i = 0; i < count; i++)
+
+ unsigned size = 0;
+ for (auto &opstr : str.values)
{
- const parsed_cs_op_t &opstr = str.values[i];
- if (!opstr.for_drop () && !opstr.for_skip ())
+ size += opstr.length;
+ if (opstr.op == OpCode_callsubr || opstr.op == OpCode_callgsubr)
+ size += 3;
+ }
+ if (!buff.alloc (buff.length + size))
+ return false;
+
+ for (auto &opstr : str.values)
+ {
+ if (hinting || !opstr.is_hinting ())
{
switch (opstr.op)
{
case OpCode_callsubr:
encoder.encode_int (remaps.local_remaps[fd].biased_num (opstr.subr_num));
- encoder.encode_op (OpCode_callsubr);
+ encoder.copy_str (opstr.ptr, opstr.length);
break;
case OpCode_callgsubr:
encoder.encode_int (remaps.global_remap.biased_num (opstr.subr_num));
- encoder.encode_op (OpCode_callgsubr);
+ encoder.copy_str (opstr.ptr, opstr.length);
break;
default:
- encoder.copy_str (opstr.str);
+ encoder.copy_str (opstr.ptr, opstr.length);
break;
}
}
}
- return !encoder.is_error ();
+ return !encoder.in_error ();
+ }
+
+ void compact_parsed_strings () const
+ {
+ for (auto &cs : parsed_charstrings)
+ compact_string (cs);
+ for (auto &cs : parsed_global_subrs_storage)
+ compact_string (cs);
+ for (auto &vec : parsed_local_subrs_storage)
+ for (auto &cs : vec)
+ compact_string (cs);
+ }
+
+ static void compact_string (parsed_cs_str_t &str)
+ {
+ unsigned count = str.values.length;
+ if (unlikely (!count)) return;
+ auto &opstr = str.values.arrayZ;
+ unsigned j = 0;
+ for (unsigned i = 1; i < count; i++)
+ {
+ /* See if we can combine op j and op i. */
+ bool combine =
+ (opstr[j].op != OpCode_callsubr && opstr[j].op != OpCode_callgsubr) &&
+ (opstr[i].op != OpCode_callsubr && opstr[i].op != OpCode_callgsubr) &&
+ (opstr[j].is_hinting () == opstr[i].is_hinting ()) &&
+ (opstr[j].ptr + opstr[j].length == opstr[i].ptr) &&
+ (opstr[j].length + opstr[i].length <= 255);
+
+ if (combine)
+ {
+ opstr[j].length += opstr[i].length;
+ opstr[j].op = OpCode_Invalid;
+ }
+ else
+ {
+ opstr[++j] = opstr[i];
+ }
+ }
+ str.values.shrink (j + 1);
+ }
+
+ void populate_subset_accelerator () const
+ {
+ if (!plan->inprogress_accelerator) return;
+
+ compact_parsed_strings ();
+
+ plan->inprogress_accelerator->cff_accelerator =
+ cff_subset_accelerator_t::create(acc.blob,
+ parsed_charstrings,
+ parsed_global_subrs_storage,
+ parsed_local_subrs_storage);
+ plan->inprogress_accelerator->destroy_cff_accelerator =
+ cff_subset_accelerator_t::destroy;
+
+ }
+
+ const parsed_cs_str_t& get_parsed_charstring (unsigned i) const
+ {
+ if (cached_charstrings) return *(cached_charstrings[i]);
+ return parsed_charstrings[i];
}
protected:
@@ -897,13 +1070,17 @@
subr_closures_t closures;
- parsed_cs_str_vec_t parsed_charstrings;
- parsed_cs_str_vec_t parsed_global_subrs;
- hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs;
+ hb_vector_t<const parsed_cs_str_t*> cached_charstrings;
+ const parsed_cs_str_vec_t* parsed_global_subrs;
+ const hb_vector_t<parsed_cs_str_vec_t>* parsed_local_subrs;
subr_remaps_t remaps;
private:
+
+ parsed_cs_str_vec_t parsed_charstrings;
+ parsed_cs_str_vec_t parsed_global_subrs_storage;
+ hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs_storage;
typedef typename SUBRS::count_type subr_count_type;
};
diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc
index 52bb13d..538f28f 100644
--- a/src/hb-subset-cff1.cc
+++ b/src/hb-subset-cff1.cc
@@ -167,9 +167,10 @@
* for supplement, the original byte string is copied along with the op code */
op_str_t supp_op;
supp_op.op = op;
- if ( unlikely (!(opstr.str.length >= opstr.last_arg_offset + 3)))
+ if ( unlikely (!(opstr.length >= opstr.last_arg_offset + 3)))
return_trace (false);
- supp_op.str = hb_ubytes_t (&opstr.str + opstr.last_arg_offset, opstr.str.length - opstr.last_arg_offset);
+ supp_op.ptr = opstr.ptr + opstr.last_arg_offset;
+ supp_op.length = opstr.length - opstr.last_arg_offset;
return_trace (UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::registry]) &&
UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::ordering]) &&
copy_opstr (c, supp_op));
@@ -442,8 +443,17 @@
return;
}
- bool use_glyph_to_sid_map = plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.;
- hb_map_t *glyph_to_sid_map = use_glyph_to_sid_map ? acc.create_glyph_to_sid_map () : nullptr;
+ hb_map_t *glyph_to_sid_map = (plan->accelerator && plan->accelerator->cff_accelerator) ?
+ plan->accelerator->cff_accelerator->glyph_to_sid_map :
+ nullptr;
+ bool created_map = false;
+ if (!glyph_to_sid_map &&
+ ((plan->accelerator && plan->accelerator->cff_accelerator) ||
+ plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.))
+ {
+ created_map = true;
+ glyph_to_sid_map = acc.create_glyph_to_sid_map ();
+ }
unsigned int glyph;
for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++)
@@ -467,8 +477,12 @@
last_sid = sid;
}
- if (glyph_to_sid_map)
- hb_map_destroy (glyph_to_sid_map);
+ if (created_map)
+ {
+ if (!(plan->accelerator && plan->accelerator->cff_accelerator) ||
+ !plan->accelerator->cff_accelerator->glyph_to_sid_map.cmpexch (nullptr, glyph_to_sid_map))
+ hb_map_destroy (glyph_to_sid_map);
+ }
bool two_byte = subset_charset_ranges.complete (glyph);
@@ -728,11 +742,17 @@
/* CharStrings */
{
+ c->push<CFF1CharStrings> ();
+
+ unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings);
+ if (unlikely (!c->start_zerocopy (total_size)))
+ return false;
+
CFF1CharStrings *cs = c->start_embed<CFF1CharStrings> ();
if (unlikely (!cs)) return false;
- c->push ();
+
if (likely (cs->serialize (c, plan.subset_charstrings)))
- plan.info.char_strings_link = c->pop_pack ();
+ plan.info.char_strings_link = c->pop_pack (false);
else
{
c->pop_discard ();
@@ -815,7 +835,7 @@
CFF1Subrs *dest = c->start_embed <CFF1Subrs> ();
if (unlikely (!dest)) return false;
if (likely (dest->serialize (c, plan.subset_globalsubrs)))
- c->pop_pack ();
+ c->pop_pack (false);
else
{
c->pop_discard ();
diff --git a/src/hb-subset-cff2.cc b/src/hb-subset-cff2.cc
index 08e820e..60946b0 100644
--- a/src/hb-subset-cff2.cc
+++ b/src/hb-subset-cff2.cc
@@ -334,7 +334,7 @@
if (unlikely (!dest)) return false;
c->push ();
if (likely (dest->serialize (c, plan.subset_localsubrs[i])))
- subrs_link = c->pop_pack ();
+ subrs_link = c->pop_pack (false);
else
{
c->pop_discard ();
@@ -361,11 +361,17 @@
/* CharStrings */
{
+ c->push ();
+
+ unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings);
+ if (unlikely (!c->start_zerocopy (total_size)))
+ return false;
+
CFF2CharStrings *cs = c->start_embed<CFF2CharStrings> ();
if (unlikely (!cs)) return false;
- c->push ();
+
if (likely (cs->serialize (c, plan.subset_charstrings)))
- plan.info.char_strings_link = c->pop_pack ();
+ plan.info.char_strings_link = c->pop_pack (false);
else
{
c->pop_discard ();
@@ -377,9 +383,10 @@
if (acc.fdSelect != &Null (CFF2FDSelect))
{
c->push ();
- if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *(const FDSelect *)acc.fdSelect, plan.orig_fdcount,
- plan.subset_fdselect_format, plan.subset_fdselect_size,
- plan.subset_fdselect_ranges)))
+ if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *(const FDSelect *)acc.fdSelect,
+ plan.orig_fdcount,
+ plan.subset_fdselect_format, plan.subset_fdselect_size,
+ plan.subset_fdselect_ranges)))
plan.info.fd_select.link = c->pop_pack ();
else
{
@@ -401,7 +408,7 @@
hb_iter (private_dict_infos))
;
if (unlikely (!fda->serialize (c, it, fontSzr))) return false;
- plan.info.fd_array_link = c->pop_pack ();
+ plan.info.fd_array_link = c->pop_pack (false);
}
/* variation store */
@@ -410,7 +417,7 @@
c->push ();
CFF2VariationStore *dest = c->start_embed<CFF2VariationStore> ();
if (unlikely (!dest || !dest->serialize (c, acc.varStore))) return false;
- plan.info.var_store_link = c->pop_pack ();
+ plan.info.var_store_link = c->pop_pack (false);
}
OT::cff2 *cff2 = c->allocate_min<OT::cff2> ();
diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc
index fd25010..42434ae 100644
--- a/src/hb-subset-input.cc
+++ b/src/hb-subset-input.cc
@@ -26,7 +26,7 @@
#include "hb-subset.hh"
#include "hb-set.hh"
-
+#include "hb-utf.hh"
/**
* hb_subset_input_create_or_fail:
*
@@ -49,8 +49,15 @@
set = hb_set_create ();
input->axes_location = hb_hashmap_create<hb_tag_t, float> ();
+#ifdef HB_EXPERIMENTAL_API
+ input->name_table_overrides = hb_hashmap_create<hb_ot_name_record_ids_t, hb_bytes_t> ();
+#endif
- if (!input->axes_location || input->in_error ())
+ if (!input->axes_location ||
+#ifdef HB_EXPERIMENTAL_API
+ !input->name_table_overrides ||
+#endif
+ input->in_error ())
{
hb_subset_input_destroy (input);
return nullptr;
@@ -248,6 +255,15 @@
hb_hashmap_destroy (input->axes_location);
+#ifdef HB_EXPERIMENTAL_API
+ if (input->name_table_overrides)
+ {
+ for (auto _ : *input->name_table_overrides)
+ _.second.fini ();
+ }
+ hb_hashmap_destroy (input->name_table_overrides);
+#endif
+
hb_free (input);
}
@@ -379,7 +395,6 @@
return hb_object_get_user_data (input, key);
}
-#ifdef HB_EXPERIMENTAL_API
#ifndef HB_NO_VAR
/**
* hb_subset_input_pin_axis_to_default: (skip)
@@ -388,9 +403,12 @@
*
* Pin an axis to its default location in the given subset input object.
*
+ * Currently only works for fonts with 'glyf' tables. CFF and CFF2 is not
+ * yet supported. Additionally all axes in a font must be pinned.
+ *
* Return value: `true` if success, `false` otherwise
*
- * Since: EXPERIMENTAL
+ * Since: 6.0.0
**/
HB_EXTERN hb_bool_t
hb_subset_input_pin_axis_to_default (hb_subset_input_t *input,
@@ -412,9 +430,12 @@
*
* Pin an axis to a fixed location in the given subset input object.
*
+ * Currently only works for fonts with 'glyf' tables. CFF and CFF2 is not
+ * yet supported. Additionally all axes in a font must be pinned.
+ *
* Return value: `true` if success, `false` otherwise
*
- * Since: EXPERIMENTAL
+ * Since: 6.0.0
**/
HB_EXTERN hb_bool_t
hb_subset_input_pin_axis_location (hb_subset_input_t *input,
@@ -430,28 +451,41 @@
return input->axes_location->set (axis_tag, val);
}
#endif
-#endif
-#ifdef HB_EXPERIMENTAL_API
/**
- * hb_subset_preprocess
- * @input: a #hb_face_t object.
+ * hb_subset_preprocess:
+ * @source: a #hb_face_t object.
*
* Preprocesses the face and attaches data that will be needed by the
* subsetter. Future subsetting operations can then use the precomputed data
* to speed up the subsetting operation.
*
- * Since: EXPERIMENTAL
+ * See [subset-preprocessing](https://github.com/harfbuzz/harfbuzz/blob/main/docs/subset-preprocessing.md)
+ * for more information.
+ *
+ * Note: the preprocessed face may contain sub-blobs that reference the memory
+ * backing the source #hb_face_t. Therefore in the case that this memory is not
+ * owned by the source face you will need to ensure that memory lives
+ * as long as the returned #hb_face_t.
+ *
+ * Returns: a new #hb_face_t.
+ *
+ * Since: 6.0.0
**/
HB_EXTERN hb_face_t *
hb_subset_preprocess (hb_face_t *source)
{
hb_subset_input_t* input = hb_subset_input_create_or_fail ();
+ if (!input)
+ return source;
hb_set_clear (hb_subset_input_set(input, HB_SUBSET_SETS_UNICODE));
hb_set_invert (hb_subset_input_set(input, HB_SUBSET_SETS_UNICODE));
+ hb_set_clear (hb_subset_input_set(input, HB_SUBSET_SETS_GLYPH_INDEX));
+ hb_set_invert (hb_subset_input_set(input, HB_SUBSET_SETS_GLYPH_INDEX));
+
hb_set_clear (hb_subset_input_set(input,
HB_SUBSET_SETS_LAYOUT_FEATURE_TAG));
hb_set_invert (hb_subset_input_set(input,
@@ -467,15 +501,100 @@
hb_set_invert (hb_subset_input_set(input,
HB_SUBSET_SETS_NAME_ID));
+ hb_set_clear (hb_subset_input_set(input,
+ HB_SUBSET_SETS_NAME_LANG_ID));
+ hb_set_invert (hb_subset_input_set(input,
+ HB_SUBSET_SETS_NAME_LANG_ID));
+
hb_subset_input_set_flags(input,
HB_SUBSET_FLAGS_NOTDEF_OUTLINE |
HB_SUBSET_FLAGS_GLYPH_NAMES |
- HB_SUBSET_FLAGS_RETAIN_GIDS);
+ HB_SUBSET_FLAGS_RETAIN_GIDS |
+ HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES);
input->attach_accelerator_data = true;
+ // Always use long loca in the preprocessed version. This allows
+ // us to store the glyph bytes unpadded which allows the future subset
+ // operation to run faster by skipping the trim padding step.
+ input->force_long_loca = true;
+
hb_face_t* new_source = hb_subset_or_fail (source, input);
hb_subset_input_destroy (input);
+ if (!new_source) {
+ DEBUG_MSG (SUBSET, nullptr, "Preprocessing failed due to subset failure.");
+ return source;
+ }
+
return new_source;
}
+
+#ifdef HB_EXPERIMENTAL_API
+/**
+ * hb_subset_input_override_name_table:
+ * @input: a #hb_subset_input_t object.
+ * @name_id: name_id of a nameRecord
+ * @platform_id: platform ID of a nameRecord
+ * @encoding_id: encoding ID of a nameRecord
+ * @language_id: language ID of a nameRecord
+ * @name_str: pointer to name string new value or null to indicate should remove
+ * @str_len: the size of @name_str, or -1 if it is `NULL`-terminated
+ *
+ * Override the name string of the NameRecord identified by name_id,
+ * platform_id, encoding_id and language_id. If a record with that name_id
+ * doesn't exist, create it and insert to the name table.
+ *
+ * Note: for mac platform, we only support name_str with all ascii characters,
+ * name_str with non-ascii characters will be ignored.
+ *
+ * Since: EXPERIMENTAL
+ **/
+HB_EXTERN hb_bool_t
+hb_subset_input_override_name_table (hb_subset_input_t *input,
+ hb_ot_name_id_t name_id,
+ unsigned platform_id,
+ unsigned encoding_id,
+ unsigned language_id,
+ const char *name_str,
+ int str_len /* -1 means nul-terminated */)
+{
+ if (!name_str)
+ {
+ str_len = 0;
+ }
+ else if (str_len == -1)
+ {
+ str_len = strlen (name_str);
+ }
+
+ hb_bytes_t name_bytes (nullptr, 0);
+ if (str_len)
+ {
+ if (platform_id == 1)
+ {
+ const uint8_t *src = reinterpret_cast<const uint8_t*> (name_str);
+ const uint8_t *src_end = src + str_len;
+
+ hb_codepoint_t unicode;
+ const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
+ while (src < src_end)
+ {
+ src = hb_utf8_t::next (src, src_end, &unicode, replacement);
+ if (unicode >= 0x0080u)
+ {
+ printf ("Non-ascii character detected, ignored...This API supports acsii characters only for mac platform\n");
+ return false;
+ }
+ }
+ }
+ char *override_name = (char *) hb_malloc (str_len);
+ if (unlikely (!override_name)) return false;
+
+ hb_memcpy (override_name, name_str, str_len);
+ name_bytes = hb_bytes_t (override_name, str_len);
+ }
+ input->name_table_overrides->set (hb_ot_name_record_ids_t (platform_id, encoding_id, language_id, name_id), name_bytes);
+ return true;
+}
+
#endif
diff --git a/src/hb-subset-input.hh b/src/hb-subset-input.hh
index dabb491..ecd47b7 100644
--- a/src/hb-subset-input.hh
+++ b/src/hb-subset-input.hh
@@ -36,6 +36,48 @@
#include "hb-font.hh"
+struct hb_ot_name_record_ids_t
+{
+ hb_ot_name_record_ids_t () = default;
+ hb_ot_name_record_ids_t (unsigned platform_id_,
+ unsigned encoding_id_,
+ unsigned language_id_,
+ unsigned name_id_)
+ :platform_id (platform_id_),
+ encoding_id (encoding_id_),
+ language_id (language_id_),
+ name_id (name_id_) {}
+
+ bool operator != (const hb_ot_name_record_ids_t o) const
+ { return !(*this == o); }
+
+ inline bool operator == (const hb_ot_name_record_ids_t& o) const
+ {
+ return platform_id == o.platform_id &&
+ encoding_id == o.encoding_id &&
+ language_id == o.language_id &&
+ name_id == o.name_id;
+ }
+
+ inline uint32_t hash () const
+ {
+ uint32_t current = 0;
+ current = current * 31 + hb_hash (platform_id);
+ current = current * 31 + hb_hash (encoding_id);
+ current = current * 31 + hb_hash (language_id);
+ current = current * 31 + hb_hash (name_id);
+ return current;
+ }
+
+ unsigned platform_id;
+ unsigned encoding_id;
+ unsigned language_id;
+ unsigned name_id;
+};
+
+typedef struct hb_ot_name_record_ids_t hb_ot_name_record_ids_t;
+
+
HB_MARK_AS_FLAG_T (hb_subset_flags_t);
struct hb_subset_input_t
@@ -60,7 +102,14 @@
unsigned flags;
bool attach_accelerator_data = false;
+
+ // If set loca format will always be the long version.
+ bool force_long_loca = false;
+
hb_hashmap_t<hb_tag_t, float> *axes_location;
+#ifdef HB_EXPERIMENTAL_API
+ hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides;
+#endif
inline unsigned num_sets () const
{
@@ -80,7 +129,11 @@
return true;
}
- return axes_location->in_error ();
+ return axes_location->in_error ()
+#ifdef HB_EXPERIMENTAL_API
+ || name_table_overrides->in_error ()
+#endif
+ ;
}
};
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index 9cf7c9e..71bc908 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -27,6 +27,7 @@
#include "hb-subset-plan.hh"
#include "hb-subset-accelerator.hh"
#include "hb-map.hh"
+#include "hb-multimap.hh"
#include "hb-set.hh"
#include "hb-ot-cmap-table.hh"
@@ -47,7 +48,7 @@
typedef hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> script_langsys_map;
#ifndef HB_NO_SUBSET_CFF
-static inline void
+static inline bool
_add_cff_seac_components (const OT::cff1::accelerator_t &cff,
hb_codepoint_t gid,
hb_set_t *gids_to_retain)
@@ -57,7 +58,9 @@
{
gids_to_retain->add (base_gid);
gids_to_retain->add (accent_gid);
+ return true;
}
+ return false;
}
#endif
@@ -82,10 +85,8 @@
_remap_indexes (const hb_set_t *indexes,
hb_map_t *mapping /* OUT */)
{
- unsigned count = indexes->get_population ();
-
- for (auto _ : + hb_zip (indexes->iter (), hb_range (count)))
- mapping->set (_.first, _.second);
+ for (auto _ : + hb_enumerate (indexes->iter ()))
+ mapping->set (_.second, _.first);
}
@@ -344,7 +345,9 @@
vars.push (var);
}
+#ifndef HB_NO_VAR
hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ());
+#endif
return font;
}
@@ -521,14 +524,44 @@
cmap_unicodes = &plan->accelerator->unicodes;
}
- for (hb_codepoint_t cp : *cmap_unicodes)
+ if (plan->accelerator &&
+ unicodes->get_population () < cmap_unicodes->get_population () &&
+ glyphs->get_population () < cmap_unicodes->get_population ())
{
- hb_codepoint_t gid = (*unicode_glyphid_map)[cp];
- if (!unicodes->has (cp) && !glyphs->has (gid))
- continue;
+ auto &gid_to_unicodes = plan->accelerator->gid_to_unicodes;
+ for (hb_codepoint_t gid : *glyphs)
+ {
+ auto unicodes = gid_to_unicodes.get (gid);
- plan->codepoint_to_glyph->set (cp, gid);
- plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
+ for (hb_codepoint_t cp : unicodes)
+ {
+ plan->codepoint_to_glyph->set (cp, gid);
+ plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
+ }
+ }
+ for (hb_codepoint_t cp : *unicodes)
+ {
+ /* Don't double-add entry. */
+ if (plan->codepoint_to_glyph->has (cp))
+ continue;
+
+ hb_codepoint_t gid = (*unicode_glyphid_map)[cp];
+ plan->codepoint_to_glyph->set (cp, gid);
+ plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
+ }
+ plan->unicode_to_new_gid_list.qsort ();
+ }
+ else
+ {
+ for (hb_codepoint_t cp : *cmap_unicodes)
+ {
+ hb_codepoint_t gid = (*unicode_glyphid_map)[cp];
+ if (!unicodes->has (cp) && !glyphs->has (gid))
+ continue;
+
+ plan->codepoint_to_glyph->set (cp, gid);
+ plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
+ }
}
/* Add gids which where requested, but not mapped in cmap */
@@ -639,9 +672,15 @@
else
plan->_glyphset->union_ (cur_glyphset);
#ifndef HB_NO_SUBSET_CFF
- if (cff.is_valid ())
- for (hb_codepoint_t gid : cur_glyphset)
- _add_cff_seac_components (cff, gid, plan->_glyphset);
+ if (!plan->accelerator || plan->accelerator->has_seac)
+ {
+ bool has_seac = false;
+ if (cff.is_valid ())
+ for (hb_codepoint_t gid : cur_glyphset)
+ if (_add_cff_seac_components (cff, gid, plan->_glyphset))
+ has_seac = true;
+ plan->has_seac = has_seac;
+ }
#endif
_remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ());
@@ -848,9 +887,28 @@
plan->check_success (plan->vmtx_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ());
plan->check_success (plan->hmtx_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ());
+#ifdef HB_EXPERIMENTAL_API
+ plan->check_success (plan->name_table_overrides = hb_hashmap_create<hb_ot_name_record_ids_t, hb_bytes_t> ());
+ if (plan->name_table_overrides && input->name_table_overrides)
+ {
+ for (auto _ : *input->name_table_overrides)
+ {
+ hb_bytes_t name_bytes = _.second;
+ unsigned len = name_bytes.length;
+ char *name_str = (char *) hb_malloc (len);
+ if (unlikely (!plan->check_success (name_str)))
+ break;
+
+ hb_memcpy (name_str, name_bytes.arrayZ, len);
+ plan->name_table_overrides->set (_.first, hb_bytes_t (name_str, len));
+ }
+ }
+#endif
+
void* accel = hb_face_get_user_data(face, hb_subset_accelerator_t::user_data_key());
plan->attach_accelerator_data = input->attach_accelerator_data;
+ plan->force_long_loca = input->force_long_loca;
if (accel)
plan->accelerator = (hb_subset_accelerator_t*) accel;
@@ -893,6 +951,28 @@
hb_subset_plan_destroy (plan);
return nullptr;
}
+
+
+ if (plan->attach_accelerator_data)
+ {
+ hb_multimap_t gid_to_unicodes;
+
+ hb_map_t &unicode_to_gid = *plan->codepoint_to_glyph;
+
+ for (auto unicode : *plan->unicodes)
+ {
+ auto gid = unicode_to_gid[unicode];
+ gid_to_unicodes.add (gid, unicode);
+ }
+
+ plan->inprogress_accelerator =
+ hb_subset_accelerator_t::create (*plan->codepoint_to_glyph,
+ gid_to_unicodes,
+ *plan->unicodes,
+ plan->has_seac);
+ }
+
+
return plan;
}
diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh
index 15fabba..1b2aee7 100644
--- a/src/hb-subset-plan.hh
+++ b/src/hb-subset-plan.hh
@@ -87,6 +87,18 @@
hb_hashmap_destroy (vmtx_map);
hb_hashmap_destroy (layout_variation_idx_delta_map);
+#ifdef HB_EXPERIMENTAL_API
+ if (name_table_overrides)
+ {
+ for (auto _ : *name_table_overrides)
+ _.second.fini ();
+ }
+ hb_hashmap_destroy (name_table_overrides);
+#endif
+
+ if (inprogress_accelerator)
+ hb_subset_accelerator_t::destroy ((void*) inprogress_accelerator);
+
if (user_axes_location)
{
hb_object_destroy (user_axes_location);
@@ -99,10 +111,11 @@
bool successful;
unsigned flags;
bool attach_accelerator_data = false;
+ bool force_long_loca = false;
// For each cp that we'd like to retain maps to the corresponding gid.
hb_set_t *unicodes;
- hb_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> unicode_to_new_gid_list;
+ hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> unicode_to_new_gid_list;
// name_ids we would like to retain
hb_set_t *name_ids;
@@ -185,31 +198,41 @@
hb_map_t *axes_old_index_tag_map;
bool all_axes_pinned;
bool pinned_at_default;
+ bool has_seac;
//hmtx metrics map: new gid->(advance, lsb)
hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *hmtx_map;
//vmtx metrics map: new gid->(advance, lsb)
hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *vmtx_map;
+#ifdef HB_EXPERIMENTAL_API
+ // name table overrides map: hb_ot_name_record_ids_t-> name string new value or
+ // None to indicate should remove
+ hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides;
+#endif
+
const hb_subset_accelerator_t* accelerator;
+ hb_subset_accelerator_t* inprogress_accelerator;
public:
template<typename T>
hb_blob_ptr_t<T> source_table()
{
- if (sanitized_table_cache
- && !sanitized_table_cache->in_error ()
- && sanitized_table_cache->has (T::tableTag)) {
- return hb_blob_reference (sanitized_table_cache->get (T::tableTag).get ());
+ hb_lock_t (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr);
+
+ auto *cache = accelerator ? &accelerator->sanitized_table_cache : sanitized_table_cache;
+ if (cache
+ && !cache->in_error ()
+ && cache->has (+T::tableTag)) {
+ return hb_blob_reference (cache->get (+T::tableTag).get ());
}
hb::unique_ptr<hb_blob_t> table_blob {hb_sanitize_context_t ().reference_table<T> (source)};
hb_blob_t* ret = hb_blob_reference (table_blob.get ());
- if (likely (sanitized_table_cache))
- sanitized_table_cache->set (T::tableTag,
- std::move (table_blob));
+ if (likely (cache))
+ cache->set (+T::tableTag, std::move (table_blob));
return ret;
}
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index 6026aa6..186b12d 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -82,6 +82,10 @@
* retain glyph ids option and configure the subset to pass through the layout tables untouched.
*/
+
+hb_user_data_key_t _hb_subset_accelerator_user_data_key = {};
+
+
/*
* The list of tables in the open type spec. Used to check for tables that may need handling
* if we are unable to list the tables in a face.
@@ -409,20 +413,14 @@
static bool
_dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag,
- hb_set_t &visited_set, hb_set_t &revisit_set)
+ const hb_set_t &subsetted_tags,
+ const hb_set_t &pending_subset_tags)
{
switch (tag)
{
case HB_OT_TAG_hmtx:
case HB_OT_TAG_vmtx:
- if (!plan->pinned_at_default &&
- !visited_set.has (HB_OT_TAG_glyf))
- {
- revisit_set.add (tag);
- return false;
- }
- return true;
-
+ return plan->pinned_at_default || !pending_subset_tags.has (HB_OT_TAG_glyf);
default:
return true;
}
@@ -495,12 +493,14 @@
}
}
-static void _attach_accelerator_data (const hb_subset_plan_t* plan,
+static void _attach_accelerator_data (hb_subset_plan_t* plan,
hb_face_t* face /* IN/OUT */)
{
- hb_subset_accelerator_t* accel =
- hb_subset_accelerator_t::create (*plan->codepoint_to_glyph,
- *plan->unicodes);
+ if (!plan->inprogress_accelerator) return;
+
+ // Transfer the accelerator from the plan to us.
+ hb_subset_accelerator_t* accel = plan->inprogress_accelerator;
+ plan->inprogress_accelerator = nullptr;
if (accel->in_error ())
{
@@ -508,6 +508,11 @@
return;
}
+ // Populate caches that need access to the final tables.
+ hb_blob_ptr_t<OT::cmap> cmap_ptr (hb_sanitize_context_t ().reference_table<OT::cmap> (face));
+ accel->cmap_cache = OT::cmap::create_filled_cache (cmap_ptr);
+ accel->destroy_cmap_cache = OT::SubtableUnicodesCache::destroy;
+
if (!hb_face_set_user_data(face,
hb_subset_accelerator_t::user_data_key(),
accel,
@@ -561,41 +566,63 @@
return nullptr;
}
- hb_set_t tags_set, revisit_set;
- bool success = true;
hb_tag_t table_tags[32];
unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags);
- hb_vector_t<char> buf;
- buf.alloc (4096 - 16);
+ hb_set_t subsetted_tags, pending_subset_tags;
while (((void) _get_table_tags (plan, offset, &num_tables, table_tags), num_tables))
{
for (unsigned i = 0; i < num_tables; ++i)
{
hb_tag_t tag = table_tags[i];
- if (_should_drop_table (plan, tag) && !tags_set.has (tag)) continue;
- if (!_dependencies_satisfied (plan, tag, tags_set, revisit_set)) continue;
- tags_set.add (tag);
+ if (_should_drop_table (plan, tag)) continue;
+ pending_subset_tags.add (tag);
+ }
+
+ offset += num_tables;
+ }
+
+ hb_vector_t<char> buf;
+ buf.alloc (4096 - 16);
+
+
+ bool success = true;
+
+ while (!pending_subset_tags.is_empty ())
+ {
+ if (subsetted_tags.in_error ()
+ || pending_subset_tags.in_error ()) {
+ success = false;
+ goto end;
+ }
+
+ bool made_changes = false;
+ for (hb_tag_t tag : pending_subset_tags)
+ {
+ if (!_dependencies_satisfied (plan, tag,
+ subsetted_tags,
+ pending_subset_tags))
+ {
+ // delayed subsetting for some tables since they might have dependency on other tables
+ // in some cases: e.g: during instantiating glyf tables, hmetrics/vmetrics are updated
+ // and saved in subset plan, hmtx/vmtx subsetting need to use these updated metrics values
+ continue;
+ }
+
+ pending_subset_tags.del (tag);
+ subsetted_tags.add (tag);
+ made_changes = true;
+
success = _subset_table (plan, buf, tag);
if (unlikely (!success)) goto end;
}
- /*delayed subsetting for some tables since they might have dependency on other tables in some cases:
- e.g: during instantiating glyf tables, hmetrics/vmetrics are updated and saved in subset plan,
- hmtx/vmtx subsetting need to use these updated metrics values*/
- while (!revisit_set.is_empty ())
+ if (!made_changes)
{
- hb_set_t revisit_temp;
- for (hb_tag_t tag : revisit_set)
- {
- if (!_dependencies_satisfied (plan, tag, tags_set, revisit_temp)) continue;
- tags_set.add (tag);
- success = _subset_table (plan, buf, tag);
- if (unlikely (!success)) goto end;
- }
- revisit_set = revisit_temp;
+ DEBUG_MSG (SUBSET, nullptr, "Table dependencies unable to be satisfied. Subset failed.");
+ success = false;
+ goto end;
}
- offset += num_tables;
}
if (success && plan->attach_accelerator_data) {
diff --git a/src/hb-subset.h b/src/hb-subset.h
index 6a2c5f6..b83264e 100644
--- a/src/hb-subset.h
+++ b/src/hb-subset.h
@@ -28,6 +28,7 @@
#define HB_SUBSET_H
#include "hb.h"
+#include "hb-ot.h"
HB_BEGIN_DECLS
@@ -164,8 +165,6 @@
hb_subset_input_set_flags (hb_subset_input_t *input,
unsigned value);
-#ifdef HB_EXPERIMENTAL_API
-#ifndef HB_NO_VAR
HB_EXTERN hb_bool_t
hb_subset_input_pin_axis_to_default (hb_subset_input_t *input,
hb_face_t *face,
@@ -176,16 +175,22 @@
hb_face_t *face,
hb_tag_t axis_tag,
float axis_value);
-#endif
-#endif
#ifdef HB_EXPERIMENTAL_API
+HB_EXTERN hb_bool_t
+hb_subset_input_override_name_table (hb_subset_input_t *input,
+ hb_ot_name_id_t name_id,
+ unsigned platform_id,
+ unsigned encoding_id,
+ unsigned language_id,
+ const char *name_str,
+ int str_len);
+
+#endif
HB_EXTERN hb_face_t *
hb_subset_preprocess (hb_face_t *source);
-#endif
-
HB_EXTERN hb_face_t *
hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input);
diff --git a/src/hb-ucd-table.hh b/src/hb-ucd-table.hh
index a372a4a..f7d76ee 100644
--- a/src/hb-ucd-table.hh
+++ b/src/hb-ucd-table.hh
@@ -1069,1791 +1069,6 @@
#ifndef HB_OPTIMIZE_SIZE
static const uint8_t
-_hb_ucd_u8[18260] =
-{
- 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 11, 12, 13, 13, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 22, 22, 22, 22, 24, 7, 7,
- 25, 26, 22, 22, 22, 27, 28, 29, 22, 30, 31, 32, 33, 34, 35, 36,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 22, 42,
- 7, 7, 43, 7, 44, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 45, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 46,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 47,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 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, 64, 65, 66, 67, 68, 69, 70, 71, 69, 72, 73,
- 69, 69, 64, 74, 64, 64, 75, 76, 77, 78, 79, 80, 81, 82, 69, 83,
- 84, 85, 86, 87, 88, 89, 69, 69, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 90, 34, 34, 34, 34,
- 91, 34, 34, 34, 34, 34, 34, 34, 34, 92, 34, 34, 93, 94, 95, 96,
- 97, 98, 99,100,101,102,103,104, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,105,
- 106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
- 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
- 107,107, 34, 34,108,109,110,111, 34, 34,112,113,114,115,116,117,
- 118,119,120,121,122,123,124,125,126,127,128,129, 34, 34,130,131,
- 132,133,134,135,136,137,138,139,140,141,142,122,143,144,145,146,
- 147,148,149,150,151,152,153,122,154,155,122,156,157,158,159,122,
- 160,161,162,163,164,165,166,122,167,168,169,170,122,171,172,173,
- 34, 34, 34, 34, 34, 34, 34,174,175, 34,176,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,177,
- 34, 34, 34, 34, 34, 34, 34, 34,178,122,122,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
- 122,122,122,122,122,122,122,122, 34, 34, 34, 34,179,122,122,122,
- 34, 34, 34, 34,180,181,182,183,122,122,122,122,184,185,186,187,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,188,
- 34, 34, 34, 34, 34, 34, 34, 34, 34,189,190,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,191,
- 34, 34,192, 34, 34,193,122,122,122,122,122,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,194,195,122,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,122,122,122,122,122,122,196,197,
- 69,198,199,200,201,202,203,122,204,205,206,207,208,209,210,211,
- 69, 69, 69, 69,212,213,122,122,122,122,122,122,122,122,214,122,
- 215,216,217,122,122,218,122,122,122,219,122,122,122,122,122,220,
- 34,221,222,122,122,122,122,122,223,224,225,122,226,227,122,122,
- 228,229,230,231,232,122, 69,233, 69, 69, 69, 69, 69,234,235,236,
- 237,238, 69, 69,239,240, 69,241,122,122,122,122,122,122,122,122,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,242, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34,
- 244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34,
- 34, 34, 34, 34, 34, 34, 34,246,122,122,122,122,122,122,122,122,
- 34, 34, 34, 34,247,122,122,122,122,122,122,122,122,122,122,122,
- 34, 34, 34, 34, 34, 34,248, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34,249,122,122,122,122,122,122,122,122,
- 250,122,251,252,122,122,122,122,122,122,122,122,122,122,122,122,
- 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,253,
- 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2,
- 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25,
- 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32,
- 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11,
- 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11,
- 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34,
- 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32,
- 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32,
- 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41,
- 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41,
- 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10,
- 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11,
- 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34,
- 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11,
- 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16,
- 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2,
- 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62,
- 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67,
- 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43,
- 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36,
- 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79,
- 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36,
- 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44,
- 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43,
- 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43,
- 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64,
- 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44,
- 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 44, 43, 43, 43, 43,
- 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43,
- 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86,
- 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36,
- 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36,
- 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86,
- 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62,
- 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80,
- 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86,
- 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61,
- 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44,
- 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36,
- 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44,
- 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43,
- 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87,
- 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62,
- 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36,
- 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36,
- 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44,
- 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44,
- 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44,
- 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91,
- 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87,
- 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61,
- 62, 94, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36,
- 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77,
- 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36,
- 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36,
- 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89,
- 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44,
- 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96,
- 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36,
- 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44,
- 36, 36, 61, 81, 43, 43, 43, 80, 7, 7, 7, 7, 7, 44, 36, 36,
- 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67,
- 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86,
- 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44,
- 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43,
- 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67,
- 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44,
- 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71,
- 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43,
- 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36,
- 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67,
- 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16,
- 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44,
- 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36,
- 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43,
- 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44,
- 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44,
- 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72,
- 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44,
- 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44,
- 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44,
- 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36,
- 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86,
- 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44,
- 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44,
- 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36,
- 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44,
- 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7,
- 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44,
- 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67,
- 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80,
- 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57,
- 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109,
- 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36,
- 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 44,
- 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 64,
- 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36,
- 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2,
- 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2,
- 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2,
- 16, 16, 16, 16,110, 44, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11,
- 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43,
- 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44,
- 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16,
- 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40,
- 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11,
- 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48,
- 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112,
- 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41,
- 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41,
- 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65,
- 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124,
- 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2,
- 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65,
- 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104,
- 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20,
- 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51,
- 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44,
- 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67,
- 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11,
- 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27,
- 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44,
- 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144,
- 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67,
- 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67,
- 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8,
- 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8,
- 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44,
- 67, 67, 67, 67, 67, 92, 44, 44, 27, 27, 27, 27, 27, 27, 67, 67,
- 67, 67, 67, 67, 67, 27, 27, 27, 67, 67, 67, 26, 67, 67, 67, 67,
- 26, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8,
- 67, 67, 67, 67, 67, 67, 67, 26, 67, 67, 67, 67, 4, 4, 4, 4,
- 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67,
- 8, 8,129,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4,
- 8,129,148,148,148,148,148,148,148,148,148,148,147, 8, 8, 8,
- 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8,
- 8, 8,144, 26, 8, 8,144, 67, 67, 67, 44, 67, 67, 67, 67, 67,
- 67, 67, 67, 55, 67, 67, 67, 67, 32, 11, 32, 34, 34, 34, 34, 11,
- 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,140, 67, 67,138, 34,149,
- 43, 32, 44, 44, 93, 2, 99, 2, 16, 16, 16,150, 44, 44,150, 44,
- 36, 36, 36, 36, 44, 44, 44, 52, 64, 44, 44, 44, 44, 44, 44, 57,
- 36, 36, 36, 61, 44, 44, 44, 44, 36, 36, 36, 61, 36, 36, 36, 61,
- 2,121,121, 2,125,126,121, 2, 2, 2, 2, 6, 2,108,121, 2,
- 121, 4, 4, 4, 4, 2, 2, 88, 2, 2, 2, 2, 2,120, 2, 2,
- 108,151, 2, 2, 2, 2, 2, 2, 67, 2,152,148,148,148,153, 44,
- 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44,
- 67, 67, 67, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44,
- 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157,
- 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67,
- 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69,
- 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67,
- 67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67,
- 67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27,
- 36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164, 2,
- 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70,
- 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43,
- 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44,
- 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32,
- 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32,
- 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32,
- 32, 32, 11, 11, 34,110, 44, 44, 32,150,150, 32, 32, 44, 44, 44,
- 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36,
- 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44,
- 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2,
- 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2,
- 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93,
- 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52,
- 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36,
- 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85,
- 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44,
- 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36,
- 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86,
- 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61,
- 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40,
- 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44,
- 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36,
- 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171,
- 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71,
- 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61,
- 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41,
- 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67,
- 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148,
- 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130,
- 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2,
- 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36,
- 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40,
- 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44,
- 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44,
- 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62,
- 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67,
- 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92,
- 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44,
- 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36,
- 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44,
- 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36,
- 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16,
- 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44,
- 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93,
- 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16,
- 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44,
- 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44,
- 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62,
- 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27,
- 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27,
- 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93,
- 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27,
- 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36,
- 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44,
- 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30,
- 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36,
- 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44,
- 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27,
- 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44,
- 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44,
- 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44,
- 27, 27, 27, 27, 27, 27, 27,100, 36, 36, 36, 36, 36, 57,184, 44,
- 36, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 57, 43,
- 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44,
- 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44,
- 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43,
- 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7,
- 71, 70, 71, 44, 44, 44, 44, 57, 86, 87, 43, 85, 87, 60,185, 2,
- 2, 80, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 70, 43, 43, 87, 43, 43, 43, 80, 7, 7, 7, 7, 7,
- 2, 2, 94, 98, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44,
- 36, 94, 86, 43, 43, 43, 43, 85, 98, 36, 63, 2, 59, 43, 60, 87,
- 7, 7, 7, 7, 7, 63, 63, 2,179, 27, 27, 27, 27, 27, 27, 27,
- 27, 27,100, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 86, 87,
- 43, 86, 85, 43, 2, 2, 2, 71, 70, 44, 44, 44, 44, 44, 44, 44,
- 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62,
- 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70,
- 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62,
- 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44,
- 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44,
- 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 94, 86, 43, 43, 43, 43,
- 86, 43, 85, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 2, 93, 71,
- 86, 87, 43, 43, 85, 85, 86, 87, 85, 43, 36, 72, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 36, 36, 94, 86, 43, 43, 44, 86, 86, 43, 87,
- 60, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 44,
- 86, 87, 43, 43, 43, 85, 87, 87, 60, 2, 61, 44, 44, 44, 44, 44,
- 2, 2, 2, 2, 2, 2, 64, 44, 36, 36, 36, 36, 36, 70, 87, 86,
- 43, 43, 43, 87, 63, 44, 44, 44, 86, 43, 43, 87, 43, 43, 44, 44,
- 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44,
- 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36,
- 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71,
- 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36,
- 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44,
- 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60,
- 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36,
- 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2,
- 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44,
- 43, 43, 43, 80, 43, 43, 43, 87, 63, 2, 2, 44, 44, 44, 44, 44,
- 2, 36, 36, 36, 36, 36, 36, 36, 44, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 89, 43, 43, 43, 85, 43, 87, 80, 44, 44, 44, 44,
- 36, 36, 36, 61, 36, 62, 36, 36, 70, 43, 43, 80, 44, 80, 43, 57,
- 43, 43, 43, 70, 44, 44, 44, 44, 36, 36, 36, 62, 61, 36, 36, 36,
- 36, 36, 36, 36, 36, 86, 86, 90, 43, 89, 87, 87, 61, 44, 44, 44,
- 36, 70, 85,107, 64, 44, 44, 44, 43, 94, 36, 36, 36, 36, 36, 36,
- 36, 36, 86, 43, 43, 80, 44, 86, 85, 60, 2, 2, 2, 2, 2, 2,
- 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67,
- 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181,
- 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44,
- 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43,
- 43, 43, 43, 44, 44, 44, 44, 44, 43, 43, 60, 44, 44, 44, 44, 44,
- 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44,
- 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 44, 44, 62, 36, 27, 27, 27, 30, 2, 64, 44, 44,
- 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57,
- 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44,
- 86, 44, 44, 44, 44, 44, 44, 44, 40, 40, 52, 40, 40, 40, 52, 81,
- 36, 61, 44, 44, 44, 44, 44, 44, 44, 61, 44, 44, 44, 44, 44, 44,
- 36, 61, 62, 44, 44, 44, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 44, 50, 60, 65, 65, 44, 44, 44, 44, 44, 44,
- 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 80, 44, 44, 44, 44,
- 67, 67, 67, 92, 55, 67, 67, 67, 67, 67,186, 87, 43, 67,186, 86,
- 86,187, 65, 65, 65, 84, 43, 43, 43, 76, 50, 43, 43, 43, 67, 67,
- 67, 67, 67, 67, 67, 43, 43, 67, 67, 43, 76, 44, 44, 44, 44, 44,
- 27, 27, 44, 44, 44, 44, 44, 44, 11, 11, 11, 11, 11, 16, 16, 16,
- 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16,
- 16, 16,110, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 47, 11, 44, 47, 48, 47, 48, 11, 47, 11,
- 11, 11, 11, 16, 16,150,150, 16, 16, 16,150, 16, 16, 16, 16, 16,
- 16, 16, 11, 48, 11, 47, 48, 11, 11, 11, 47, 11, 11, 11, 47, 16,
- 16, 16, 16, 16, 11, 48, 11, 47, 11, 11, 47, 47, 44, 11, 11, 11,
- 47, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11,
- 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 44, 11, 11, 11, 11,
- 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16,
- 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16,
- 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16,
- 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 44, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 43, 43, 43, 76, 67, 50, 43, 43,
- 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67,
- 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43,
- 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110,
- 44, 44,150, 16, 16,110, 44, 44, 43, 43, 43, 80, 43, 43, 43, 43,
- 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44,
- 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 57,
- 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77,
- 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43,
- 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43,
- 36, 36, 36, 61, 36, 36, 62, 61, 36, 36, 61,179, 27, 27, 27, 27,
- 16, 16, 43, 43, 43, 74, 44, 44, 27, 27, 27, 27, 27, 27,163, 27,
- 188, 27,100, 44, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27,163,
- 27, 27, 27, 27, 27, 27, 27, 44, 36, 36, 62, 36, 36, 36, 36, 36,
- 62, 61, 61, 62, 62, 36, 36, 36, 36, 61, 36, 36, 62, 62, 44, 44,
- 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62,
- 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61,
- 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36,
- 8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67,
- 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44,
- 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44,
- 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44,
- 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67,
- 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44,
- 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 44, 44, 44, 44, 67,
- 67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44,
- 171,171,171,171,171,171,171, 44,171,171,171,171,171,171,171, 0,
- 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13,
- 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5,
- 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20,
- 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25,
- 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 7, 5,
- 6, 6, 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2,
- 2, 9, 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26,
- 26, 23, 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21,
- 21, 2, 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7,
- 21, 7, 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1,
- 12, 2, 6, 2, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12,
- 21, 6, 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7,
- 2, 23, 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22,
- 18, 2, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 2, 5, 6,
- 8, 8, 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1,
- 17, 17, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16,
- 16, 21, 25, 22, 18, 21, 21, 29, 1, 2, 15, 6, 18, 6, 23, 2,
- 12, 11, 9, 26, 26, 9, 26, 5, 5, 26, 14, 9, 5, 14, 14, 15,
- 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21,
- 21, 22, 18, 17, 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6,
- 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9,
- 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16,
- 25, 17, 25, 2, 25, 24, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15,
- 12, 17, 21, 1, 26, 10, 10, 1, 23, 15, 0, 1, 2, 3, 4, 5,
- 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0,
- 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19,
- 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, 20, 0, 21, 22, 23, 0, 0, 0, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 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, 35,
- 0, 36, 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, 37, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 38, 39, 0, 0, 0, 0, 0, 0, 40, 41, 42, 0, 43, 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, 0, 0, 0, 0,
- 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 0,
- 9, 0, 10, 11, 0, 0, 12, 13, 14, 15, 16, 0, 0, 0, 0, 17,
- 18, 19, 20, 0, 21, 0, 22, 23, 0, 24, 25, 0, 0, 24, 26, 27,
- 0, 24, 26, 0, 0, 24, 26, 0, 0, 24, 26, 0, 0, 0, 26, 0,
- 0, 24, 28, 0, 0, 24, 26, 0, 0, 29, 26, 0, 0, 0, 30, 0,
- 0, 31, 32, 0, 0, 33, 34, 0, 35, 36, 0, 37, 38, 0, 39, 0,
- 0, 40, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 0, 0, 45, 0,
- 0, 0, 0, 0, 0, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0,
- 48, 0, 0, 49, 0, 50, 51, 0, 0, 52, 53, 54, 0, 55, 0, 56,
- 0, 57, 0, 0, 0, 0, 58, 59, 0, 0, 0, 0, 0, 0, 60, 61,
- 0, 0, 0, 0, 0, 0, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66,
- 0, 67, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 69, 70, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0,
- 72, 73, 0, 0, 0, 0, 53, 74, 0, 75, 76, 0, 0, 77, 78, 0,
- 0, 0, 0, 0, 0, 79, 80, 81, 0, 0, 0, 0, 0, 0, 0, 26,
- 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0,
- 0, 83, 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, 84,
- 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, 0, 86, 0, 0, 0, 0,
- 87, 88, 0, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 91, 0, 92, 0, 0, 93, 0, 94, 0, 0, 0,
- 0, 0, 72, 95, 0, 96, 0, 0, 97, 98, 0, 77, 0, 0, 99, 0,
- 0,100, 0, 0, 0, 0, 0,101, 0,102, 26,103, 0, 0, 0, 0,
- 0, 0,104, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 65,106, 0,
- 0, 65, 0, 0, 0,107, 0, 0, 0,108, 0, 0, 0, 0, 0, 0,
- 0, 96, 0, 0, 0, 0, 0, 0, 0,109,110, 0, 0, 0, 0, 78,
- 0, 44,111, 0,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 65, 0, 0, 0, 0, 0, 0, 0, 0,113, 0,114, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,116, 0,117, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,
- 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,121,122, 0, 0,
- 0, 0,123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 124,125, 0, 0,126, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,127, 0,128, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,129, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,130, 0, 0, 0,131, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4,
- 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17,
- 18, 1, 1, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28,
- 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 31, 0,
- 0, 0, 32, 33, 34, 35, 1, 36, 0, 0, 0, 0, 37, 0, 0, 0,
- 0, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 0, 0, 0, 0,
- 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 43, 36, 44, 45,
- 21, 45, 46, 0, 0, 0, 0, 0, 0, 0, 19, 1, 21, 0, 0, 47,
- 0, 0, 0, 0, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 52, 1,
- 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1,
- 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0,
- 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59,
- 0, 0, 0, 56, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 61, 62,
- 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0,
- 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0,
- 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0,
- 0, 0, 0, 0, 0, 69, 70, 0, 0, 0, 0, 0, 71, 72, 73, 74,
- 75, 76, 0, 0, 0, 0, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 80, 0, 0,
- 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 63, 0, 0, 81,
- 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0,
- 0, 0, 0, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85,
- 0, 0, 0, 0, 1, 52, 15, 86, 36, 10, 21, 87, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 55, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0,
- 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0,
- 0, 89, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0,
- 0, 0, 0, 0, 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0,
- 21, 1, 21, 92, 93, 1, 1, 1, 1, 1, 1, 1, 1, 94, 95, 96,
- 0, 0, 0, 0, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, 0, 0,
- 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61,
- 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,101,102, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 19, 0, 1, 1, 50,
- 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 50, 0, 0, 0,
- 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0,
- 1, 1, 1, 1, 50, 0, 0, 0, 0, 0,104, 68, 0, 0, 0, 0,
- 0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0,
- 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,106, 58, 38,
- 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,107, 1, 14, 4, 12, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 47, 84, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,109, 61, 0,110, 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 19, 58, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 51, 0,111, 14, 52, 84, 0, 0, 0,
- 112, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 61,
- 0, 0, 0, 0, 0, 0,113, 0, 87, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 78, 55, 0, 38, 1, 58, 1, 58, 0, 0,
- 63, 89, 0, 0, 0, 0, 0, 59,115, 0, 0, 0, 0, 0, 0, 0,
- 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,115, 0, 0,
- 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79,
- 78, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 61, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 8, 91, 0, 0, 0, 0, 0, 0, 1, 87, 0, 0,
- 0, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117,
- 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, 0, 0,
- 0, 0, 38, 50, 0, 0, 0, 0, 38, 58, 0, 0, 0, 0, 0, 0,
- 1, 87, 1, 1, 1, 1, 39, 1, 48,105, 87, 0, 0, 0, 0, 0,
- 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,123, 0, 0, 0, 0,
- 0, 0, 0, 0, 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,230,230,230,230,230,232,220,220,220,220,232,216,
- 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220,
- 1, 1, 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220,
- 220,220,230,230,230,220,220, 0,230,230,230,220,220,220,220,230,
- 232,220,220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230,
- 0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220,
- 230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20,
- 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0,
- 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,
- 220,230,230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230,
- 230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230,
- 220,220,230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0,
- 230,230, 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220,
- 230,220,220,220,230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0,
- 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0,
- 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0,
- 103,103, 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122,
- 220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0,
- 132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230,
- 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0,
- 9, 9, 0, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220,
- 220, 0, 0, 0,230, 0, 0,220,230,220, 0,220,230,230,230, 0,
- 0, 0, 9, 9, 0, 0, 7, 0,230, 0, 1, 1, 1, 0, 0, 0,
- 230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230,
- 233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,
- 220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0,
- 0, 0, 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0,
- 0,220, 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220,
- 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7,
- 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0,
- 0,226,216,216,216,216,216, 0,220,220,220, 0,232,232,220,230,
- 230,230, 7, 0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19,
- 17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17,237, 0, 1, 2, 2, 0, 3, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 5, 0, 0, 0, 0, 6, 7, 8, 9, 0, 0, 0, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20,
- 0, 0, 21, 22, 0, 0, 0, 0, 23, 24, 25, 26, 0, 27, 0, 28,
- 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 33, 34, 35, 36, 0,
- 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39,
- 0, 0, 0, 0, 1, 2, 40, 41, 0, 1, 2, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0,
- 0, 0, 3, 4, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0,
- 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0,
- 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 11, 12,
- 0, 13, 0, 14, 15, 16, 0, 0, 0, 0, 0, 1, 17, 18, 0, 19,
- 7, 1, 0, 0, 0, 20, 20, 7, 20, 20, 20, 20, 20, 20, 20, 8,
- 21, 0, 22, 0, 7, 23, 24, 0, 20, 20, 25, 0, 0, 0, 26, 27,
- 1, 7, 20, 20, 20, 20, 20, 1, 28, 29, 30, 31, 0, 0, 20, 0,
- 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 20, 20,
- 20, 1, 0, 0, 8, 21, 32, 4, 0, 10, 0, 33, 7, 20, 20, 20,
- 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, 37, 0, 38, 1, 20, 20,
- 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, 20, 0, 0, 0, 1, 0,
- 0, 40, 1, 1, 0, 0, 8, 21, 0, 1, 0, 1, 0, 1, 0, 0,
- 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 7, 20, 41,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 0, 42, 43, 44, 0, 45,
- 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, 0, 46, 7, 1, 10, 1,
- 0, 0, 0, 1, 20, 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 26, 34, 9, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0,
- 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3,
- 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13,
- 13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 13, 42, 7, 7, 43, 7,
- 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45, 0, 0, 1,
- 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, 53, 54, 55, 56,
- 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61,
- 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109,
- 110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123,
- 124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138,
- 139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151,
- 152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164,
- 164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169,
- 169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173,
- 173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182,
- 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
- 182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182,
- 182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189,
- 190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197,
- 198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208,
- 208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212,
- 213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218,
- 219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226,
- 59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233,
- 59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70,
- 70, 70, 70, 70, 70,241, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
- 70, 70,242, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
- 70, 70, 70, 70,243, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70,244, 96, 96, 96, 96, 96, 96, 96, 96,245, 96,
- 246,247, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0,
- 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0,
- 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0,
- 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9,
- 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2,
- 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9,
- 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2,
- 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14,
- 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3,
- 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3,
- 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38,
- 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90,
- 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90,
- 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3,
- 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3,
- 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1,
- 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5,
- 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2,
- 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2,
- 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5,
- 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2,
- 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5,
- 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11,
- 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2,
- 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2,
- 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11,
- 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11,
- 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2,
- 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10,
- 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10,
- 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2,
- 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10,
- 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2,
- 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10,
- 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21,
- 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2,
- 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2,
- 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21,
- 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2,
- 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21,
- 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22,
- 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22,
- 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2,
- 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22,
- 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23,
- 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2,
- 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 23, 23,
- 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16,
- 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2,
- 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16,
- 16, 16, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2,
- 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, 36,
- 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36,
- 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, 2,
- 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2,
- 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 24,
- 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
- 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18,
- 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18,
- 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18,
- 18, 18, 18, 18, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25,
- 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25,
- 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33,
- 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8,
- 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30,
- 30, 30, 30, 30, 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30,
- 30, 30, 30, 2, 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28,
- 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31,
- 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 2,
- 2, 2, 2, 2, 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28,
- 28, 28, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2,
- 2, 2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58,
- 2, 2, 2, 2, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91,
- 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91,
- 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91,
- 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62,
- 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 2, 2, 62, 62,
- 62, 62, 62, 62, 62, 2, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93,
- 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2,
- 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 2, 2,
- 2, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73,
- 73, 73, 73, 73, 73, 73, 6, 2, 2, 2, 2, 2, 2, 2, 8, 8,
- 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0,
- 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 19, 19,
- 19, 19, 19, 19, 9, 9, 9, 9, 9, 6, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 9, 9, 9, 9,
- 9, 19, 19, 19, 19, 19, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, 9, 9, 2, 2, 2, 9,
- 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9,
- 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 2, 2,
- 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0,
- 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 19,
- 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0,
- 0, 0, 0, 0, 0, 2, 19, 19, 19, 19, 19, 2, 2, 2, 0, 2,
- 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0,
- 0, 0, 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 2, 2, 2, 2, 0, 0,
- 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0,
- 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56,
- 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55,
- 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2,
- 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0,
- 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13,
- 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0,
- 0, 0, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 1, 1, 1, 1, 12, 12, 13, 13, 13, 13, 0, 0, 0, 0, 2, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 2, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17,
- 17, 17, 17, 17, 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86,
- 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0,
- 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19,
- 19, 2, 2, 2, 2, 2, 19, 19, 2, 19, 2, 19, 19, 19, 19, 19,
- 2, 2, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 2, 2, 2, 0, 0,
- 2, 2, 2, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75,
- 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2,
- 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74,
- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84,
- 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68,
- 68, 68, 68, 68, 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92,
- 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2,
- 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
- 87, 87, 87, 87, 87, 2, 2, 30, 30, 30, 30, 30, 30, 2, 19, 19,
- 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19,
- 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87,
- 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2,
- 2, 12, 12, 12, 12, 12, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19,
- 19, 19, 19, 19, 19, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2,
- 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14,
- 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, 3,
- 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2,
- 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0,
- 0, 2, 0, 0, 0, 0, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3,
- 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 2, 2,
- 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 2, 2, 2, 2, 0,
- 0, 0, 0, 0, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49,
- 49, 2, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 2, 2, 49, 49,
- 49, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0,
- 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 2,
- 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67,
- 67, 67, 67, 67, 67, 67, 67, 2, 2, 2, 2, 2, 2, 2, 1, 0,
- 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 2, 2, 2, 2, 2, 2, 2, 2, 2, 42, 42, 42, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41, 41, 2, 2, 2, 2, 2,118,118,
- 118,118,118,118,118,118,118,118,118, 2, 2, 2, 2, 2, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, 59, 59,
- 59, 59, 59, 59, 2, 2, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51,
- 51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 2, 2, 50, 50, 2, 2, 2, 2, 2, 2,135,135,
- 135,135,135,135,135,135,135,135,135,135, 2, 2, 2, 2,106,106,
- 106,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104,
- 104,104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,104,161,161,
- 161,161,161,161,161,161,161,161,161, 2,161,161,161,161,161,161,
- 161, 2,161,161, 2,161,161,161, 2,161,161,161,161,161,161,161,
- 2,161,161, 2, 2, 2,110,110,110,110,110,110,110,110,110,110,
- 110,110,110,110,110, 2,110,110,110,110,110,110, 2, 2, 19, 19,
- 19, 19, 19, 19, 2, 19, 19, 2, 19, 19, 19, 19, 19, 19, 47, 47,
- 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2,
- 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 2, 81,120,120,120,120,120,120,120,120,116,116,
- 116,116,116,116,116,116,116,116,116,116,116,116,116, 2, 2, 2,
- 2, 2, 2, 2, 2,116,128,128,128,128,128,128,128,128,128,128,
- 128, 2,128,128, 2, 2, 2, 2, 2,128,128,128,128,128, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72,
- 72, 72, 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72, 98, 98,
- 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 2, 2,
- 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 57, 57,
- 57, 57, 2, 57, 57, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57,
- 57, 57, 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 57, 57,
- 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 2, 2, 2, 2, 88, 88,
- 88, 88, 88, 88, 88, 88,117,117,117,117,117,117,117,117,112,112,
- 112,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2,
- 2,112,112,112,112,112, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
- 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82,
- 82, 82, 82, 82, 82, 82, 82, 82, 82, 2, 2, 2, 2, 2,122,122,
- 122,122,122,122,122,122,122,122, 2, 2, 2, 2, 2, 2, 2,122,
- 122,122,122, 2, 2, 2, 2,122,122,122,122,122,122,122, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130,
- 130,130,130,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2,
- 130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144,
- 2, 2, 2, 2, 2, 2,156,156,156,156,156,156,156,156,156,156,
- 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 3, 3, 3,147,147,147,147,147,147,147,147,148,148,
- 148,148,148,148,148,148,148,148, 2, 2, 2, 2, 2, 2,158,158,
- 158,158,158,158,158,158,158,158, 2, 2, 2, 2, 2, 2,153,153,
- 153,153,153,153,153,153,153,153,153,153, 2, 2, 2, 2,149,149,
- 149,149,149,149,149,149,149,149,149,149,149,149,149, 2, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2,
- 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 2, 2, 2, 94, 85, 85,
- 85, 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 85, 2, 2,101,101,101,101,101,101,101,101,101, 2,
- 2, 2, 2, 2, 2, 2,101,101, 2, 2, 2, 2, 2, 2, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 2, 96, 96,111,111,
- 111,111,111,111,111,111,111,111,111,111,111,111,111, 2,100,100,
- 100,100,100,100,100,100, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 2, 2, 2,108,108,108,108,108,108,108,108,108,108,
- 2,108,108,108,108,108,108,108, 2, 2, 2, 2, 2, 2,129,129,
- 129,129,129,129,129, 2,129, 2,129,129,129,129, 2,129,129,129,
- 129,129,129,129,129,129,129,129,129,129,129,129, 2,129,129,129,
- 2, 2, 2, 2, 2, 2,109,109,109,109,109,109,109,109,109,109,
- 109, 2, 2, 2, 2, 2,109,109, 2, 2, 2, 2, 2, 2,107,107,
- 107,107, 2,107,107,107,107,107,107,107,107, 2, 2,107,107, 2,
- 2,107,107,107,107,107,107,107,107,107,107,107,107,107,107, 2,
- 107,107,107,107,107,107,107, 2,107,107, 2,107,107,107,107,107,
- 2, 1,107,107,107,107,107, 2, 2,107,107,107, 2, 2,107, 2,
- 2, 2, 2, 2, 2,107, 2, 2, 2, 2, 2,107,107,107,107,107,
- 107,107, 2, 2,107,107,107,107,107,107,107, 2, 2, 2,137,137,
- 137,137,137,137,137,137,137,137,137,137, 2,137,137,137,137,137,
- 2, 2, 2, 2, 2, 2,124,124,124,124,124,124,124,124,124,124,
- 2, 2, 2, 2, 2, 2,123,123,123,123,123,123,123,123,123,123,
- 123,123,123,123, 2, 2,114,114,114,114,114,114,114,114,114,114,
- 114,114,114, 2, 2, 2,114,114, 2, 2, 2, 2, 2, 2, 32, 32,
- 32, 32, 32, 2, 2, 2,102,102,102,102,102,102,102,102,102,102,
- 2, 2, 2, 2, 2, 2,126,126,126,126,126,126,126,126,126,126,
- 126, 2, 2,126,126,126,126,126,126,126, 2, 2, 2, 2,126,126,
- 126,126,126,126,126, 2,142,142,142,142,142,142,142,142,142,142,
- 142,142, 2, 2, 2, 2,125,125,125,125,125,125,125,125,125,125,
- 125, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,125,154,154,
- 154,154,154,154,154, 2, 2,154, 2, 2,154,154,154,154,154,154,
- 154,154, 2,154,154, 2,154,154,154,154,154,154,154,154,154,154,
- 154,154,154,154, 2,154,154, 2, 2,154,154,154,154,154,154,154,
- 2, 2, 2, 2, 2, 2,150,150,150,150,150,150,150,150, 2, 2,
- 150,150,150,150,150,150,150,150,150,150,150, 2, 2, 2,141,141,
- 141,141,141,141,141,141,140,140,140,140,140,140,140,140,140,140,
- 140, 2, 2, 2, 2, 2,121,121,121,121,121,121,121,121,121, 2,
- 2, 2, 2, 2, 2, 2, 7, 7, 2, 2, 2, 2, 2, 2,133,133,
- 133,133,133,133,133,133,133, 2,133,133,133,133,133,133,133,133,
- 133,133,133,133,133, 2,133,133,133,133,133,133, 2, 2,133,133,
- 133,133,133, 2, 2, 2,134,134,134,134,134,134,134,134, 2, 2,
- 134,134,134,134,134,134, 2,134,134,134,134,134,134,134,134,134,
- 134,134,134,134,134, 2,138,138,138,138,138,138,138, 2,138,138,
- 2,138,138,138,138,138,138,138,138,138,138,138,138,138, 2, 2,
- 138, 2,138,138, 2,138,138,138, 2, 2, 2, 2, 2, 2,143,143,
- 143,143,143,143, 2,143,143, 2,143,143,143,143,143,143,143,143,
- 143,143,143,143,143,143,143,143,143,143,143,143,143, 2,143,143,
- 2,143,143,143,143,143,143, 2, 2, 2, 2, 2, 2, 2,143,143,
- 2, 2, 2, 2, 2, 2,145,145,145,145,145,145,145,145,145, 2,
- 2, 2, 2, 2, 2, 2,163,163,163,163,163,163,163,163,163, 2,
- 163,163,163,163,163,163,163,163,163, 2, 2, 2,163,163,163,163,
- 2, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 22, 22,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, 63, 63,
- 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 63, 63,
- 63, 63, 2, 2, 2, 2,157,157,157,157,157,157,157,157,157,157,
- 157, 2, 2, 2, 2, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 2, 2,127,127,127,127,127,127,127,127,127,127,
- 127,127,127,127,127, 2, 79, 2, 2, 2, 2, 2, 2, 2,115,115,
- 115,115,115,115,115,115,115,115,115,115,115,115,115, 2,115,115,
- 2, 2, 2, 2,115,115,159,159,159,159,159,159,159,159,159,159,
- 159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,103,103,
- 103,103,103,103,103,103,103,103,103,103,103,103, 2, 2,119,119,
- 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2,119,119,
- 2,119,119,119,119,119, 2, 2, 2, 2, 2,119,119,119,146,146,
- 146,146,146,146,146,146,146,146,146, 2, 2, 2, 2, 2, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2,
- 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136,
- 136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155,
- 155,155,155,155, 2, 2,136, 2, 2, 2, 2, 2, 2, 2, 17, 17,
- 17, 17, 2, 17, 17, 17, 17, 17, 17, 17, 2, 17, 17, 2, 17, 15,
- 15, 15, 15, 15, 15, 15, 17, 17, 17, 2, 2, 2, 2, 2, 2, 2,
- 15, 2, 2, 2, 2, 2, 15, 15, 15, 2, 2, 17, 2, 2, 2, 2,
- 2, 2, 17, 17, 17, 17,139,139,139,139,139,139,139,139,139,139,
- 139,139, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105,
- 105, 2, 2, 2, 2, 2,105,105,105,105,105, 2, 2, 2,105, 2,
- 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 1, 1,
- 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 0, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0,
- 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0,
- 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0,
- 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2,
- 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,131,131,
- 131,131,131,131,131,131,131,131,131,131, 2, 2, 2, 2, 2, 2,
- 2,131,131,131,131,131, 2,131,131,131,131,131,131,131, 2, 2,
- 2, 2, 2, 19, 19, 19, 56, 56, 56, 56, 56, 56, 56, 2, 56, 2,
- 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, 2, 56, 56, 56, 56,
- 56, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 6,151,151,151,151,151,151,151,151,151,151,
- 151,151,151, 2, 2, 2,151,151,151,151,151,151, 2, 2,151,151,
- 2, 2, 2, 2,151,151,160,160,160,160,160,160,160,160,160,160,
- 160,160,160,160,160, 2,152,152,152,152,152,152,152,152,152,152,
- 2, 2, 2, 2, 2,152,164,164,164,164,164,164,164,164,164,164,
- 2, 2, 2, 2, 2, 2, 30, 30, 30, 30, 2, 30, 30, 2,113,113,
- 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113,
- 113,113,113,113,113, 2,132,132,132,132,132,132,132,132,132,132,
- 132,132, 2, 2, 2, 2,132,132, 2, 2, 2, 2,132,132, 3, 3,
- 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3,
- 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3,
- 2, 3, 2, 3, 3, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
- 3, 3, 3, 2, 3, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2,
- 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 13, 2,
- 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0,
- 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
- 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 16, 17, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 19,
- 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 22, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28,
- 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0,
- 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 41, 42, 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, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0,
- 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0,
- 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0,
- 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0,
- 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65,
- 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
- 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
- 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,
- 107, 0, 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0,
- 0, 0,115, 0, 0, 0,116, 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,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124,
- 125,126, 0,127, 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,128,129,130,131,132,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, 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162,163, 0,
- 0, 0, 0, 0, 0, 0,164, 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,165, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,168, 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,169,170, 0, 0, 0, 0,171,
- 172, 0, 0, 0,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,
- 201,202,203,204,205,206, 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,
-};
-static const uint16_t
-_hb_ucd_u16[9320] =
-{
- 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12,
- 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23,
- 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31,
- 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39,
- 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13,
- 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50,
- 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58,
- 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66,
- 48, 67, 68, 69, 48, 70, 71, 48, 72, 73, 48, 48, 74, 32, 75, 32,
- 76, 48, 48, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- 90, 83, 84, 91, 92, 93, 94, 95, 96, 97, 84, 98, 99, 100, 88, 101,
- 102, 83, 84, 103, 104, 105, 88, 106, 107, 108, 109, 110, 111, 112, 94, 113,
- 114, 115, 84, 116, 117, 118, 88, 119, 120, 115, 84, 121, 122, 123, 88, 124,
- 125, 115, 48, 126, 127, 128, 88, 129, 130, 131, 48, 132, 133, 134, 94, 135,
- 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140,
- 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140,
- 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167,
- 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48,
- 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175,
- 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183,
- 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193,
- 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199,
- 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209,
- 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140,
- 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225,
- 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235,
- 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13,
- 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250,
- 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265,
- 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278,
- 279, 279, 279, 279, 279, 279, 279, 279, 280, 209, 281, 209, 209, 209, 209, 282,
- 209, 283, 279, 284, 209, 285, 286, 209, 209, 209, 287, 140, 288, 140, 271, 271,
- 271, 289, 209, 209, 209, 209, 290, 271, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 291, 292, 209, 209, 293, 209, 209, 209, 209, 209, 209, 294, 209,
- 209, 209, 209, 209, 209, 209, 295, 296, 271, 297, 209, 209, 298, 279, 299, 279,
- 300, 301, 279, 279, 279, 302, 279, 303, 209, 209, 209, 279, 304, 209, 209, 305,
- 209, 306, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 307, 308,
- 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313,
- 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 321, 140, 140,
- 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 325,
- 326, 327, 328, 329, 136, 48, 48, 48, 48, 330, 178, 48, 48, 48, 48, 331,
- 332, 48, 48, 136, 48, 48, 48, 48, 200, 333, 48, 48, 209, 209, 323, 48,
- 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209,
- 48, 48, 48, 48, 209, 209, 209, 209, 48, 338, 48, 48, 48, 48, 48, 48,
- 151, 209, 209, 209, 287, 48, 48, 229, 339, 48, 340, 140, 13, 13, 341, 342,
- 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349,
- 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360,
- 361, 48, 48, 362, 363, 192, 32, 364, 64, 48, 365, 48, 366, 367, 48, 151,
- 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377,
- 48, 48, 48, 378, 379, 380, 381, 382, 383, 384, 315, 11, 11, 385, 386, 11,
- 11, 11, 11, 11, 48, 48, 387, 192, 48, 48, 388, 48, 389, 48, 48, 206,
- 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391,
- 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140,
- 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48,
- 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403,
- 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410,
- 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419,
- 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71,
- 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428,
- 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430,
- 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140,
- 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439,
- 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 140, 140, 140, 140,
- 48, 48, 48, 314, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140,
- 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453,
- 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271,
- 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467,
- 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140,
- 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474,
- 48, 48, 475, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 271, 476,
- 48, 48, 477, 478, 140, 140, 140, 479, 48, 464, 480, 48, 62, 481, 140, 48,
- 482, 140, 140, 48, 483, 140, 48, 314, 484, 48, 48, 485, 486, 457, 487, 488,
- 222, 48, 48, 489, 490, 48, 196, 192, 491, 48, 492, 493, 494, 48, 48, 495,
- 222, 48, 48, 496, 497, 498, 499, 500, 48, 97, 501, 502, 503, 140, 140, 140,
- 504, 505, 506, 48, 48, 507, 508, 192, 509, 83, 84, 510, 511, 512, 513, 514,
- 48, 48, 48, 515, 516, 517, 478, 140, 48, 48, 48, 518, 519, 192, 140, 140,
- 48, 48, 520, 521, 522, 523, 140, 140, 48, 48, 48, 524, 525, 192, 526, 140,
- 48, 48, 527, 528, 192, 140, 140, 140, 48, 173, 529, 530, 314, 140, 140, 140,
- 48, 48, 501, 531, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 532,
- 533, 534, 48, 535, 536, 192, 140, 140, 140, 140, 537, 48, 48, 538, 539, 140,
- 540, 48, 48, 541, 542, 543, 48, 48, 544, 545, 546, 48, 48, 48, 48, 196,
- 547, 140, 140, 140, 140, 140, 140, 140, 84, 48, 520, 548, 549, 148, 175, 550,
- 48, 551, 552, 553, 140, 140, 140, 140, 554, 48, 48, 555, 556, 192, 557, 48,
- 558, 559, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 560,
- 561, 115, 48, 562, 563, 192, 140, 140, 140, 140, 140, 100, 271, 564, 565, 566,
- 48, 207, 140, 140, 140, 140, 140, 140, 272, 272, 272, 272, 272, 272, 567, 568,
- 48, 48, 48, 48, 388, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 569,
- 48, 48, 48, 570, 571, 572, 140, 140, 48, 48, 48, 48, 314, 140, 140, 140,
- 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 573,
- 48, 48, 48, 574, 575, 576, 577, 578, 48, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 9, 9, 11, 11, 271, 579, 140, 140, 140, 140, 140, 140,
- 48, 48, 48, 48, 580, 581, 582, 582, 583, 584, 140, 140, 140, 140, 585, 586,
- 48, 48, 48, 48, 48, 48, 48, 440, 48, 48, 48, 48, 48, 199, 140, 140,
- 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 587,
- 48, 48, 588, 589, 140, 590, 591, 48, 48, 48, 48, 48, 48, 48, 48, 206,
- 48, 48, 48, 48, 48, 48, 71, 151, 196, 592, 593, 140, 140, 140, 140, 140,
- 32, 32, 594, 32, 595, 209, 209, 209, 209, 209, 209, 209, 323, 140, 140, 140,
- 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 596, 209, 209, 209, 597, 598,
- 599, 209, 600, 209, 209, 209, 288, 140, 209, 209, 209, 209, 601, 140, 140, 140,
- 140, 140, 140, 140, 271, 602, 271, 602, 209, 209, 209, 209, 209, 287, 271, 461,
- 9, 603, 11, 604, 605, 606, 241, 9, 607, 608, 609, 610, 611, 9, 603, 11,
- 612, 613, 11, 614, 615, 616, 617, 9, 618, 11, 9, 603, 11, 604, 605, 11,
- 241, 9, 607, 617, 9, 618, 11, 9, 603, 11, 619, 9, 620, 621, 622, 623,
- 11, 624, 9, 625, 626, 627, 628, 11, 629, 9, 630, 11, 631, 632, 632, 632,
- 32, 32, 32, 633, 32, 32, 634, 635, 636, 637, 45, 140, 140, 140, 140, 140,
- 638, 639, 640, 140, 140, 140, 140, 140, 641, 642, 643, 27, 27, 27, 644, 140,
- 645, 140, 140, 140, 140, 140, 140, 140, 48, 48, 151, 646, 647, 140, 140, 140,
- 140, 48, 648, 140, 48, 48, 649, 650, 140, 140, 140, 140, 140, 48, 651, 192,
- 140, 140, 140, 140, 140, 140, 652, 200, 48, 48, 48, 48, 653, 595, 140, 140,
- 9, 9, 607, 11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499,
- 271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140,
- 659, 48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668,
- 209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 669, 669, 669, 209, 324,
- 670, 209, 209, 209, 209, 209, 209, 209, 209, 209, 671, 140, 140, 140, 672, 209,
- 673, 209, 209, 325, 674, 675, 324, 140, 209, 209, 209, 209, 209, 209, 209, 676,
- 209, 209, 209, 209, 209, 677, 426, 426, 209, 209, 209, 209, 209, 209, 209, 678,
- 209, 209, 209, 209, 209, 176, 325, 427, 325, 209, 209, 209, 679, 176, 209, 209,
- 679, 209, 671, 675, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 671, 426,
- 674, 209, 209, 680, 681, 325, 674, 674, 209, 682, 209, 209, 288, 140, 140, 192,
- 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 207, 48, 48, 48, 48,
- 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 100, 140, 48, 204, 140, 140, 140, 140, 140, 140,
- 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140,
- 683, 140, 570, 570, 570, 570, 570, 570, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 140, 391, 391, 391, 391, 391, 391, 391, 684,
- 391, 391, 391, 391, 391, 391, 391, 685, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 2, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 4, 0, 4,
- 2, 2, 5, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,
- 0, 0, 0, 0, 7, 8, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14,
- 14, 14, 14, 14, 16, 17, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 19, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 21,
- 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25,
- 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31,
- 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 29, 31, 31, 31, 31, 37, 38, 37, 37, 37, 37, 37, 37,
- 37, 39, 31, 31, 31, 31, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26,
- 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46,
- 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 52, 31, 31, 31, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, 59, 60, 61, 62,
- 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, 71, 72, 73, 74,
- 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, 83, 84, 85, 86,
- 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98,
- 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, 107, 104, 108, 109,
- 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116,
- 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126,
- 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, 131, 131, 131, 131,
- 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141,
- 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, 147, 147, 147, 148,
- 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, 153, 152, 152, 154,
- 155, 156, 152, 157, 26, 26, 26, 26, 158, 158, 158, 158, 158, 158, 158, 158,
- 158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161,
- 158, 161, 162, 163, 26, 26, 26, 26, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165,
- 166, 167, 165, 165, 165, 165, 165, 168, 169, 169, 169, 169, 169, 169, 169, 169,
- 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170,
- 170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172,
- 171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170,
- 170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176,
- 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178,
- 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181,
- 181, 181, 181, 181, 181, 182, 181, 183, 184, 184, 185, 186, 187, 187, 188, 26,
- 189, 189, 190, 26, 191, 192, 193, 26, 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, 198, 198, 198, 198,
- 198, 198, 198, 198, 198, 198, 198, 200, 198, 198, 198, 198, 198, 201, 178, 178,
- 178, 178, 178, 178, 178, 178, 202, 26, 203, 203, 203, 204, 203, 205, 203, 205,
- 206, 203, 207, 207, 207, 208, 209, 26, 210, 210, 210, 210, 210, 211, 210, 210,
- 210, 212, 210, 213, 194, 194, 194, 194, 214, 214, 214, 215, 216, 216, 216, 216,
- 216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, 216, 220, 9, 9,
- 9, 221, 26, 26, 26, 26, 26, 26, 222, 222, 222, 222, 222, 222, 222, 222,
- 222, 223, 222, 222, 222, 222, 222, 224, 225, 225, 225, 225, 225, 225, 225, 225,
- 226, 226, 226, 226, 226, 226, 227, 228, 229, 229, 229, 229, 229, 229, 229, 230,
- 229, 231, 232, 232, 232, 232, 232, 232, 18, 233, 165, 165, 165, 165, 165, 234,
- 225, 26, 235, 9, 236, 237, 238, 239, 2, 2, 2, 2, 240, 241, 2, 2,
- 2, 2, 2, 242, 243, 244, 2, 245, 2, 2, 2, 2, 2, 2, 2, 246,
- 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 247, 247, 14, 14, 14, 14,
- 247, 247, 14, 248, 14, 14, 14, 247, 14, 14, 14, 14, 14, 14, 249, 14,
- 249, 14, 250, 251, 14, 14, 252, 253, 0, 254, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 255, 0, 256, 257, 0, 258, 2, 259, 0, 0, 0, 0,
- 260, 26, 9, 9, 9, 9, 261, 26, 0, 0, 0, 0, 262, 263, 4, 0,
- 0, 264, 0, 0, 2, 2, 2, 2, 2, 265, 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, 258, 26, 26, 26,
- 0, 266, 26, 26, 0, 0, 0, 0, 267, 267, 267, 267, 267, 267, 267, 267,
- 267, 267, 267, 267, 267, 267, 267, 267, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 269, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270,
- 270, 270, 270, 270, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273,
- 273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172, 26, 172, 172, 172, 172,
- 172, 172, 172, 172, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 276, 26, 26, 26, 26, 277, 277, 277, 278, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 280, 26, 26, 26, 0, 281, 282, 0, 0, 0, 283, 284, 0, 285,
- 286, 287, 287, 287, 287, 287, 287, 287, 287, 287, 288, 289, 290, 291, 291, 291,
- 291, 291, 291, 291, 291, 291, 291, 292, 293, 294, 294, 294, 294, 294, 295, 169,
- 169, 169, 169, 169, 169, 169, 169, 169, 169, 296, 0, 0, 294, 294, 294, 294,
- 0, 0, 0, 0, 281, 26, 291, 291, 169, 169, 169, 296, 0, 0, 0, 0,
- 0, 0, 0, 0, 169, 169, 169, 297, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 291, 291, 291, 291, 291, 298, 291, 291, 291, 291, 291, 291, 291, 291,
- 291, 291, 291, 0, 0, 0, 0, 0, 277, 277, 277, 277, 277, 277, 277, 277,
- 0, 0, 0, 0, 0, 0, 0, 0, 299, 299, 299, 299, 299, 299, 299, 299,
- 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299,
- 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303,
- 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 304, 26, 26,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 305, 305, 305, 305,
- 305, 305, 305, 305, 305, 305, 305, 26, 0, 0, 0, 0, 306, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 307, 2, 2, 2, 2, 2, 2,
- 2, 308, 309, 310, 26, 26, 311, 2, 312, 312, 312, 312, 312, 313, 0, 314,
- 315, 315, 315, 315, 315, 315, 315, 26, 316, 316, 316, 316, 316, 316, 316, 316,
- 317, 318, 316, 319, 53, 53, 53, 53, 320, 320, 320, 320, 320, 321, 322, 322,
- 322, 322, 323, 324, 169, 169, 169, 325, 326, 326, 326, 326, 326, 326, 326, 326,
- 326, 327, 326, 328, 164, 164, 164, 329, 330, 330, 330, 330, 330, 330, 331, 26,
- 330, 332, 330, 333, 164, 164, 164, 164, 334, 334, 334, 334, 334, 334, 334, 334,
- 335, 26, 26, 336, 337, 337, 338, 26, 339, 339, 339, 26, 172, 172, 2, 2,
- 2, 2, 2, 340, 341, 342, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
- 337, 337, 337, 337, 337, 343, 337, 344, 169, 169, 169, 169, 345, 26, 169, 169,
- 296, 346, 169, 169, 169, 169, 169, 345, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 347, 26, 26, 26, 26, 348, 26, 349, 350, 25, 25, 351, 352,
- 353, 25, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 354, 26, 355, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 356,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 357, 31, 31, 31, 31, 31,
- 31, 358, 26, 26, 26, 26, 31, 31, 9, 9, 0, 314, 9, 359, 0, 0,
- 0, 0, 360, 0, 258, 281, 361, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 362, 363, 0, 0, 0, 1, 2, 2, 3,
- 1, 2, 2, 3, 364, 291, 290, 291, 291, 291, 291, 365, 169, 169, 169, 296,
- 366, 366, 366, 367, 258, 258, 26, 368, 369, 370, 369, 369, 371, 369, 369, 372,
- 369, 373, 369, 373, 26, 26, 26, 26, 369, 369, 369, 369, 369, 369, 369, 369,
- 369, 369, 369, 369, 369, 369, 369, 374, 375, 0, 0, 0, 0, 0, 376, 0,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 253, 0, 377, 378, 26, 26, 26,
- 26, 26, 0, 0, 0, 0, 0, 379, 380, 380, 380, 381, 382, 382, 382, 382,
- 382, 382, 383, 26, 384, 0, 0, 281, 385, 385, 385, 385, 386, 387, 388, 388,
- 388, 389, 390, 390, 390, 390, 390, 391, 392, 392, 392, 393, 394, 394, 394, 394,
- 395, 394, 396, 26, 26, 26, 26, 26, 397, 397, 397, 397, 397, 397, 397, 397,
- 397, 397, 398, 398, 398, 398, 398, 398, 399, 399, 399, 400, 399, 401, 402, 402,
- 402, 402, 403, 402, 402, 402, 402, 403, 404, 404, 404, 404, 404, 26, 405, 405,
- 405, 405, 405, 405, 406, 407, 408, 409, 408, 409, 410, 408, 411, 408, 411, 412,
- 26, 26, 26, 26, 26, 26, 26, 26, 413, 413, 413, 413, 413, 413, 413, 413,
- 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 414, 26,
- 413, 413, 415, 26, 413, 26, 26, 26, 416, 2, 2, 2, 2, 2, 417, 308,
- 26, 26, 26, 26, 26, 26, 26, 26, 418, 419, 420, 420, 420, 420, 421, 422,
- 423, 423, 424, 423, 425, 425, 425, 425, 426, 426, 426, 427, 428, 426, 26, 26,
- 26, 26, 26, 26, 429, 429, 430, 431, 432, 432, 432, 433, 434, 434, 434, 435,
- 26, 26, 26, 26, 26, 26, 26, 26, 436, 436, 436, 436, 437, 437, 437, 438,
- 437, 437, 439, 437, 437, 437, 437, 437, 440, 441, 442, 443, 444, 444, 445, 446,
- 444, 447, 444, 447, 448, 448, 448, 448, 449, 449, 449, 449, 26, 26, 26, 26,
- 450, 450, 450, 450, 451, 452, 451, 26, 453, 453, 453, 453, 453, 453, 454, 455,
- 456, 456, 457, 456, 458, 458, 459, 458, 460, 460, 461, 462, 26, 463, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 464, 464, 464, 464, 464, 464, 464, 464,
- 464, 465, 26, 26, 26, 26, 26, 26, 466, 466, 466, 466, 466, 466, 467, 26,
- 466, 466, 466, 466, 466, 466, 467, 468, 469, 469, 469, 469, 469, 26, 469, 470,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 31, 31, 31, 50, 471, 471, 471, 471, 471, 472, 473, 26,
- 26, 26, 26, 26, 26, 26, 26, 474, 475, 475, 475, 475, 475, 26, 476, 476,
- 476, 476, 476, 477, 26, 26, 478, 478, 478, 479, 26, 26, 26, 26, 480, 480,
- 480, 481, 26, 26, 482, 482, 483, 26, 484, 484, 484, 484, 484, 484, 484, 484,
- 484, 485, 486, 484, 484, 484, 485, 487, 488, 488, 488, 488, 488, 488, 488, 488,
- 489, 490, 491, 491, 491, 492, 491, 493, 494, 494, 494, 494, 494, 494, 495, 494,
- 494, 26, 496, 496, 496, 496, 497, 26, 498, 498, 498, 498, 498, 498, 498, 498,
- 498, 498, 498, 498, 499, 137, 500, 26, 501, 501, 502, 501, 501, 501, 501, 501,
- 503, 26, 26, 26, 26, 26, 26, 26, 504, 505, 506, 507, 506, 508, 509, 509,
- 509, 509, 509, 509, 509, 510, 509, 511, 512, 513, 514, 515, 515, 516, 517, 518,
- 513, 519, 520, 521, 522, 523, 523, 26, 524, 524, 524, 524, 524, 524, 524, 524,
- 524, 524, 524, 525, 526, 26, 26, 26, 527, 527, 527, 527, 527, 527, 527, 527,
- 527, 26, 527, 528, 26, 26, 26, 26, 529, 529, 529, 529, 529, 529, 530, 529,
- 529, 529, 529, 530, 26, 26, 26, 26, 531, 531, 531, 531, 531, 531, 531, 531,
- 532, 26, 531, 533, 198, 534, 26, 26, 535, 535, 535, 535, 535, 535, 535, 536,
- 535, 536, 26, 26, 26, 26, 26, 26, 537, 537, 537, 538, 537, 539, 537, 537,
- 540, 26, 26, 26, 26, 26, 26, 26, 541, 541, 541, 541, 541, 541, 541, 542,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 543, 543, 543, 543,
- 543, 543, 543, 543, 543, 543, 544, 545, 546, 547, 548, 549, 549, 549, 550, 551,
- 546, 26, 549, 552, 26, 26, 26, 26, 26, 26, 26, 26, 553, 554, 553, 553,
- 553, 553, 553, 554, 555, 26, 26, 26, 556, 556, 556, 556, 556, 556, 556, 556,
- 556, 26, 557, 557, 557, 557, 557, 557, 557, 557, 557, 557, 558, 26, 178, 178,
- 559, 559, 559, 559, 559, 559, 559, 560, 53, 561, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 562, 563, 562, 562, 562, 562, 564, 562,
- 565, 26, 562, 562, 562, 566, 567, 567, 567, 567, 568, 567, 567, 569, 570, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 571, 572, 573, 573, 573, 573, 571, 574,
- 573, 26, 573, 575, 576, 577, 578, 578, 578, 579, 580, 581, 578, 582, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 583, 583, 583, 584, 585, 585, 586, 585, 585, 585, 585, 587,
- 585, 585, 585, 588, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 589, 26,
- 108, 108, 108, 108, 108, 108, 590, 591, 592, 592, 592, 592, 592, 592, 592, 592,
- 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 593, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 592, 592, 592, 592, 592, 592, 592, 592,
- 592, 592, 592, 592, 592, 594, 595, 26, 592, 592, 592, 592, 592, 592, 592, 592,
- 596, 26, 26, 26, 26, 26, 26, 26, 26, 26, 597, 597, 597, 597, 597, 597,
- 597, 597, 597, 597, 597, 597, 598, 26, 599, 599, 599, 599, 599, 599, 599, 599,
- 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599,
- 599, 599, 600, 26, 26, 26, 26, 26, 601, 601, 601, 601, 601, 601, 601, 601,
- 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601,
- 602, 26, 26, 26, 26, 26, 26, 26, 305, 305, 305, 305, 305, 305, 305, 305,
- 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 603,
- 604, 604, 604, 605, 604, 606, 607, 607, 607, 607, 607, 607, 607, 607, 607, 608,
- 607, 609, 610, 610, 610, 611, 611, 26, 612, 612, 612, 612, 612, 612, 612, 612,
- 613, 26, 612, 614, 614, 612, 612, 615, 612, 612, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 618, 618, 618, 618, 618, 618, 618, 618,
- 618, 619, 618, 618, 618, 618, 618, 618, 618, 620, 618, 618, 26, 26, 26, 26,
- 26, 26, 26, 26, 621, 26, 347, 26, 622, 622, 622, 622, 622, 622, 622, 622,
- 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622,
- 622, 622, 622, 622, 622, 622, 622, 26, 623, 623, 623, 623, 623, 623, 623, 623,
- 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
- 623, 623, 624, 26, 26, 26, 26, 26, 622, 625, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 626, 627, 628, 287, 287, 287, 287, 287, 287, 287,
- 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287,
- 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 629, 26, 630, 26,
- 26, 26, 631, 26, 632, 26, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633,
- 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633,
- 633, 633, 633, 633, 633, 633, 633, 634, 635, 635, 635, 635, 635, 635, 635, 635,
- 635, 635, 635, 635, 635, 636, 635, 637, 635, 638, 635, 639, 281, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 9, 9, 9, 9, 9, 640, 9, 9,
- 221, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 281, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 276, 26, 0, 0, 0, 0, 258, 363, 0, 0,
- 0, 0, 0, 0, 641, 642, 0, 643, 644, 645, 0, 0, 0, 646, 0, 0,
- 0, 0, 0, 0, 0, 266, 26, 26, 14, 14, 14, 14, 14, 14, 14, 14,
- 247, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 0, 0, 281, 26, 0, 0, 281, 26, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 258, 26, 0, 0, 0, 260, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 647, 648, 0, 649,
- 650, 0, 0, 0, 0, 0, 0, 0, 269, 651, 255, 255, 0, 0, 0, 652,
- 653, 654, 655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 268, 0, 0, 0, 0, 0, 0, 656, 656, 656, 656, 656, 656, 656, 656,
- 656, 656, 656, 656, 656, 656, 656, 656, 656, 657, 26, 658, 659, 656, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 348, 660, 308, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 661, 270, 270, 662, 663, 664, 18, 18,
- 18, 18, 18, 18, 18, 665, 26, 26, 26, 666, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 667, 667, 667, 667, 667, 668, 667, 669,
- 667, 670, 26, 26, 26, 26, 26, 26, 26, 26, 671, 671, 671, 672, 26, 26,
- 673, 673, 673, 673, 673, 673, 673, 674, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 675, 675, 675, 675, 675, 676, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 172, 677, 170, 172, 678, 678, 678, 678, 678, 678, 678, 678,
- 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678,
- 679, 678, 680, 26, 26, 26, 26, 26, 681, 681, 681, 681, 681, 681, 681, 681,
- 681, 682, 681, 683, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 363, 0, 0, 0, 0, 0, 0, 0, 377, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 363, 0, 0, 0, 0, 0, 0, 276,
- 26, 26, 26, 26, 26, 26, 26, 26, 684, 31, 31, 31, 685, 686, 687, 688,
- 689, 690, 685, 691, 685, 687, 687, 692, 31, 693, 31, 694, 695, 693, 31, 694,
- 26, 26, 26, 26, 26, 26, 51, 26, 0, 0, 0, 0, 0, 281, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 26, 0, 258, 363, 0,
- 363, 0, 363, 0, 0, 0, 276, 26, 0, 0, 0, 0, 0, 276, 26, 26,
- 26, 26, 26, 26, 696, 0, 0, 0, 697, 26, 0, 0, 0, 0, 0, 281,
- 0, 260, 314, 26, 276, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 698, 0, 377, 0, 377, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 258, 699, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 314, 0, 281, 260, 26, 0, 281, 0, 0, 0, 0, 0, 0,
- 0, 26, 0, 314, 0, 0, 0, 0, 0, 26, 0, 0, 0, 276, 314, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 281, 26, 0, 276, 0, 377, 0, 260, 0, 0, 0, 0, 0, 269,
- 276, 696, 0, 281, 0, 260, 0, 260, 0, 0, 360, 0, 0, 0, 0, 0,
- 0, 266, 26, 26, 26, 26, 0, 314, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 347,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 347, 26, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 700, 26, 26, 26, 277, 277, 277, 280, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 701, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 702, 26, 26, 26, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962,
- 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0,
- 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147,
- 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0,
- 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143,
- 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160,
- 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0,
- 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206,
- 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035,
- 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250,
- 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0,
- 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,
- 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,1093,1280, 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, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,
- 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177,
- 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0,
- 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,
- 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,
- 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130,
- 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5,
- 1434,1438,1443, 0,1450, 0,1455,1461,1514, 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,1446,1458,1468,1476,1480,1486,1517, 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,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522,
- 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567,
- 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549,
- 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559,
- 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0,
- 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648,
- 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662,
- 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0,
- 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671,
- 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0,
- 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142,
- 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381,
- 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181,
- 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,
- 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,
- 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,
- 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,
- 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,
- 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,
- 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,
- 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343,
- 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696,
- 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,
- 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,
- 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,
- 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,
- 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707,
- 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0,
- 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743,
- 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,
- 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0,
- 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790,
- 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800,
- 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24,
- 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714,
- 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,
- 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,
- 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825,
- 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829,
- 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515,
- 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518,
- 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830,
- 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0,
- 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0,
- 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847,
- 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0,
- 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0,
- 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0,
- 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0,
- 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890,
- 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897,
- 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0,
- 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917,
- 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924,
- 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929,
- 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825,
- 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500,
- 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679,
- 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722,
- 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540,
- 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589,
- 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101,
- 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110,
- 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801,
- 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610,
- 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494,
- 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748,
- 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161,
- 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727,
- 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684,
- 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566,
- 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729,
- 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525,
- 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0,
- 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213,
- 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458,
- 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591,
- 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735,
- 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171,
- 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325,
- 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438,
- 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526,
- 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693,
- 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777,
- 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916,
- 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0,
- 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599,
- 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954,1955, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121,
- 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142,
- 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169,
- 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185,
- 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206,
- 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224,
- 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39,
- 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266,
- 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286,
- 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852,
- 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324,
- 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351,
- 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50,
- 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78,
- 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55,
- 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861,
- 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436,
- 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467,
- 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873,
- 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875,
- 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531,
- 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559,
- 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73,
- 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898,
- 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902,
- 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904,
- 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81,
- 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669,
- 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686,
- 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719,
- 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753,
- 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925,
- 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800,
- 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816,
- 817, 818, 819, 820, 821, 935, 0, 0,
-};
-static const int16_t
-_hb_ucd_i16[196] =
-{
- 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2,
- 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1,
- 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, -1, 0, 3, 3, 3, -3,
- -3, -3, 0, 0, 0, 2016, 0, 0, 0, 0, 0, 2527, 1923, 1914, 1918, 0,
- 2250, 0, 0, 0, 0, 0, 0, 138, 0, 7, 0, 0, -7, 0, 0, 0,
- 1, -1, 1, -1, -1, 1, -1, 0, 1824, 0, 0, 0, 0, 0, 2104, 0,
- 2108, 2106, 0, 2106, 1316, 0, 0, 0, 0, 1, -1, 1, -1, -138, 0, 0,
- 1, -1, 8, 8, 8, 0, 7, 7, 0, 0, -8, -8, -8, -7, -7, 0,
- 1, -1, 0, 2,-1316, 1, -1, 0, -1, 1, -1, 1, -1, 3, 1, -1,
- -3, 1, -1, 1, -1, 0, 0,-1914,-1918, 0, 0,-1923,-1824, 0, 0, 0,
- 0,-2016, 0, 0, 1, -1, 0, 1, 0, 0,-2104, 0, 0, 0, 0,-2106,
- -2108,-2106, 0, 0, 1, -1,-2250, 0, 0, 0,-2527, 0, 0, -2, 0, 1,
- -1, 0, 1, -1,
-};
-
-static inline uint_fast8_t
-_hb_ucd_gc (unsigned u)
-{
- return u<1114110u?_hb_ucd_u8[6800+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
-}
-static inline uint_fast8_t
-_hb_ucd_ccc (unsigned u)
-{
- return u<125259u?_hb_ucd_u8[9184+(((_hb_ucd_u8[8128+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>3>>4)])<<4)+((u>>2>>3)&15u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u))]:0;
-}
-static inline unsigned
-_hb_ucd_b4 (const uint8_t* a, unsigned i)
-{
- return (a[i>>1]>>((i&1u)<<2))&15u;
-}
-static inline int_fast16_t
-_hb_ucd_bmg (unsigned u)
-{
- return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9932+(((_hb_ucd_u8[9812+(((_hb_ucd_b4(9684+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0;
-}
-static inline uint_fast8_t
-_hb_ucd_sc (unsigned u)
-{
- return u<918000u?_hb_ucd_u8[11454+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10718+(((_hb_ucd_u8[10268+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2;
-}
-static inline uint_fast16_t
-_hb_ucd_dm (unsigned u)
-{
- return u<195102u?_hb_ucd_u16[6008+(((_hb_ucd_u8[17460+(((_hb_ucd_u8[17078+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
-}
-
-
-#elif !defined(HB_NO_UCD_UNASSIGNED)
-
-static const uint8_t
_hb_ucd_u8[17868] =
{
0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7,
@@ -4611,6 +2826,1609 @@
}
+#elif !defined(HB_NO_UCD_UNASSIGNED)
+
+static const uint8_t
+_hb_ucd_u8[14744] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 11, 12, 13, 13, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 22, 22, 22, 22, 24, 7, 7,
+ 25, 26, 22, 22, 22, 27, 28, 29, 22, 30, 31, 32, 33, 34, 35, 36,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 22, 42,
+ 7, 7, 43, 7, 44, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 45, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 46,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 47,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 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, 64, 65, 66, 67, 68, 69, 70, 71, 69, 72, 73,
+ 69, 69, 64, 74, 64, 64, 75, 76, 77, 78, 79, 80, 81, 82, 69, 83,
+ 84, 85, 86, 87, 88, 89, 69, 69, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 90, 34, 34, 34, 34,
+ 91, 34, 34, 34, 34, 34, 34, 34, 34, 92, 34, 34, 93, 94, 95, 96,
+ 97, 98, 99,100,101,102,103,104, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,105,
+ 106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+ 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+ 107,107, 34, 34,108,109,110,111, 34, 34,112,113,114,115,116,117,
+ 118,119,120,121,122,123,124,125,126,127,128,129, 34, 34,130,131,
+ 132,133,134,135,136,137,138,139,140,141,142,122,143,144,145,146,
+ 147,148,149,150,151,152,153,122,154,155,122,156,157,158,159,122,
+ 160,161,162,163,164,165,166,122,167,168,169,170,122,171,172,173,
+ 34, 34, 34, 34, 34, 34, 34,174,175, 34,176,122,122,122,122,122,
+ 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,177,
+ 34, 34, 34, 34, 34, 34, 34, 34,178,122,122,122,122,122,122,122,
+ 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+ 122,122,122,122,122,122,122,122, 34, 34, 34, 34,179,122,122,122,
+ 34, 34, 34, 34,180,181,182,183,122,122,122,122,184,185,186,187,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,188,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34,189,190,122,122,122,122,122,
+ 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,191,
+ 34, 34,192, 34, 34,193,122,122,122,122,122,122,122,122,122,122,
+ 122,122,122,122,122,122,122,122,194,195,122,122,122,122,122,122,
+ 122,122,122,122,122,122,122,122,122,122,122,122,122,122,196,197,
+ 69,198,199,200,201,202,203,122,204,205,206,207,208,209,210,211,
+ 69, 69, 69, 69,212,213,122,122,122,122,122,122,122,122,214,122,
+ 215,216,217,122,122,218,122,122,122,219,122,122,122,122,122,220,
+ 34,221,222,122,122,122,122,122,223,224,225,122,226,227,122,122,
+ 228,229,230,231,232,122, 69,233, 69, 69, 69, 69, 69,234,235,236,
+ 237,238, 69, 69,239,240, 69,241,122,122,122,122,122,122,122,122,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,242, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34,
+ 244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34,246,122,122,122,122,122,122,122,122,
+ 34, 34, 34, 34,247,122,122,122,122,122,122,122,122,122,122,122,
+ 34, 34, 34, 34, 34, 34,248, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34,249,122,122,122,122,122,122,122,122,
+ 250,122,251,252,122,122,122,122,122,122,122,122,122,122,122,122,
+ 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,253,
+ 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2,
+ 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25,
+ 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32,
+ 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11,
+ 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11,
+ 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34,
+ 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32,
+ 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32,
+ 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41,
+ 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41,
+ 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10,
+ 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11,
+ 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34,
+ 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11,
+ 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16,
+ 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2,
+ 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62,
+ 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67,
+ 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43,
+ 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36,
+ 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79,
+ 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36,
+ 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44,
+ 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43,
+ 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43,
+ 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64,
+ 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44,
+ 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 44, 43, 43, 43, 43,
+ 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43,
+ 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86,
+ 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36,
+ 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36,
+ 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86,
+ 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62,
+ 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80,
+ 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86,
+ 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61,
+ 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44,
+ 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36,
+ 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44,
+ 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43,
+ 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87,
+ 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62,
+ 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36,
+ 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36,
+ 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44,
+ 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44,
+ 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44,
+ 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91,
+ 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87,
+ 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61,
+ 62, 94, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36,
+ 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77,
+ 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36,
+ 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36,
+ 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89,
+ 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44,
+ 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96,
+ 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36,
+ 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44,
+ 36, 36, 61, 81, 43, 43, 43, 80, 7, 7, 7, 7, 7, 44, 36, 36,
+ 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67,
+ 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86,
+ 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44,
+ 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43,
+ 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67,
+ 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44,
+ 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71,
+ 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43,
+ 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36,
+ 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67,
+ 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16,
+ 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44,
+ 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36,
+ 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43,
+ 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44,
+ 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44,
+ 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72,
+ 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44,
+ 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44,
+ 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44,
+ 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36,
+ 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86,
+ 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44,
+ 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44,
+ 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36,
+ 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44,
+ 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44,
+ 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7,
+ 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44,
+ 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44,
+ 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80,
+ 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57,
+ 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109,
+ 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36,
+ 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 44,
+ 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 64,
+ 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36,
+ 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2,
+ 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2,
+ 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2,
+ 16, 16, 16, 16,110, 44, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11,
+ 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43,
+ 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44,
+ 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16,
+ 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40,
+ 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11,
+ 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48,
+ 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112,
+ 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41,
+ 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41,
+ 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65,
+ 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124,
+ 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2,
+ 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65,
+ 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104,
+ 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20,
+ 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51,
+ 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44,
+ 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67,
+ 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11,
+ 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27,
+ 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44,
+ 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144,
+ 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67,
+ 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67,
+ 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8,
+ 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8,
+ 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44,
+ 67, 67, 67, 67, 67, 92, 44, 44, 27, 27, 27, 27, 27, 27, 67, 67,
+ 67, 67, 67, 67, 67, 27, 27, 27, 67, 67, 67, 26, 67, 67, 67, 67,
+ 26, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8,
+ 67, 67, 67, 67, 67, 67, 67, 26, 67, 67, 67, 67, 4, 4, 4, 4,
+ 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67,
+ 8, 8,129,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4,
+ 8,129,148,148,148,148,148,148,148,148,148,148,147, 8, 8, 8,
+ 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8,
+ 8, 8,144, 26, 8, 8,144, 67, 67, 67, 44, 67, 67, 67, 67, 67,
+ 67, 67, 67, 55, 67, 67, 67, 67, 32, 11, 32, 34, 34, 34, 34, 11,
+ 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,140, 67, 67,138, 34,149,
+ 43, 32, 44, 44, 93, 2, 99, 2, 16, 16, 16,150, 44, 44,150, 44,
+ 36, 36, 36, 36, 44, 44, 44, 52, 64, 44, 44, 44, 44, 44, 44, 57,
+ 36, 36, 36, 61, 44, 44, 44, 44, 36, 36, 36, 61, 36, 36, 36, 61,
+ 2,121,121, 2,125,126,121, 2, 2, 2, 2, 6, 2,108,121, 2,
+ 121, 4, 4, 4, 4, 2, 2, 88, 2, 2, 2, 2, 2,120, 2, 2,
+ 108,151, 2, 2, 2, 2, 2, 2, 67, 2,152,148,148,148,153, 44,
+ 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44,
+ 67, 67, 67, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44,
+ 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157,
+ 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67,
+ 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69,
+ 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67,
+ 67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27,
+ 36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164, 2,
+ 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70,
+ 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43,
+ 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44,
+ 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32,
+ 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32,
+ 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32,
+ 32, 32, 11, 11, 34,110, 44, 44, 32,150,150, 32, 32, 44, 44, 44,
+ 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36,
+ 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44,
+ 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2,
+ 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2,
+ 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93,
+ 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52,
+ 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36,
+ 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85,
+ 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44,
+ 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36,
+ 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86,
+ 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61,
+ 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40,
+ 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44,
+ 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36,
+ 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171,
+ 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71,
+ 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61,
+ 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41,
+ 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67,
+ 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148,
+ 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130,
+ 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2,
+ 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36,
+ 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40,
+ 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44,
+ 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44,
+ 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62,
+ 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67,
+ 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92,
+ 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44,
+ 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36,
+ 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44,
+ 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36,
+ 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16,
+ 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44,
+ 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93,
+ 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16,
+ 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44,
+ 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44,
+ 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62,
+ 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27,
+ 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27,
+ 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93,
+ 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27,
+ 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36,
+ 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44,
+ 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30,
+ 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36,
+ 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44,
+ 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27,
+ 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44,
+ 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44,
+ 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44,
+ 27, 27, 27, 27, 27, 27, 27,100, 36, 36, 36, 36, 36, 57,184, 44,
+ 36, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 57, 43,
+ 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44,
+ 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44,
+ 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43,
+ 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7,
+ 71, 70, 71, 44, 44, 44, 44, 57, 86, 87, 43, 85, 87, 60,185, 2,
+ 2, 80, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 70, 43, 43, 87, 43, 43, 43, 80, 7, 7, 7, 7, 7,
+ 2, 2, 94, 98, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44,
+ 36, 94, 86, 43, 43, 43, 43, 85, 98, 36, 63, 2, 59, 43, 60, 87,
+ 7, 7, 7, 7, 7, 63, 63, 2,179, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27,100, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 86, 87,
+ 43, 86, 85, 43, 2, 2, 2, 71, 70, 44, 44, 44, 44, 44, 44, 44,
+ 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62,
+ 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70,
+ 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62,
+ 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44,
+ 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44,
+ 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 94, 86, 43, 43, 43, 43,
+ 86, 43, 85, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 2, 93, 71,
+ 86, 87, 43, 43, 85, 85, 86, 87, 85, 43, 36, 72, 44, 44, 44, 44,
+ 36, 36, 36, 36, 36, 36, 36, 94, 86, 43, 43, 44, 86, 86, 43, 87,
+ 60, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 44,
+ 86, 87, 43, 43, 43, 85, 87, 87, 60, 2, 61, 44, 44, 44, 44, 44,
+ 2, 2, 2, 2, 2, 2, 64, 44, 36, 36, 36, 36, 36, 70, 87, 86,
+ 43, 43, 43, 87, 63, 44, 44, 44, 86, 43, 43, 87, 43, 43, 44, 44,
+ 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44,
+ 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36,
+ 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71,
+ 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36,
+ 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44,
+ 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60,
+ 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36,
+ 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2,
+ 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44,
+ 43, 43, 43, 80, 43, 43, 43, 87, 63, 2, 2, 44, 44, 44, 44, 44,
+ 2, 36, 36, 36, 36, 36, 36, 36, 44, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 89, 43, 43, 43, 85, 43, 87, 80, 44, 44, 44, 44,
+ 36, 36, 36, 61, 36, 62, 36, 36, 70, 43, 43, 80, 44, 80, 43, 57,
+ 43, 43, 43, 70, 44, 44, 44, 44, 36, 36, 36, 62, 61, 36, 36, 36,
+ 36, 36, 36, 36, 36, 86, 86, 90, 43, 89, 87, 87, 61, 44, 44, 44,
+ 36, 70, 85,107, 64, 44, 44, 44, 43, 94, 36, 36, 36, 36, 36, 36,
+ 36, 36, 86, 43, 43, 80, 44, 86, 85, 60, 2, 2, 2, 2, 2, 2,
+ 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67,
+ 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181,
+ 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44,
+ 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43,
+ 43, 43, 43, 44, 44, 44, 44, 44, 43, 43, 60, 44, 44, 44, 44, 44,
+ 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44,
+ 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 44, 44, 62, 36, 27, 27, 27, 30, 2, 64, 44, 44,
+ 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57,
+ 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44,
+ 86, 44, 44, 44, 44, 44, 44, 44, 40, 40, 52, 40, 40, 40, 52, 81,
+ 36, 61, 44, 44, 44, 44, 44, 44, 44, 61, 44, 44, 44, 44, 44, 44,
+ 36, 61, 62, 44, 44, 44, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44,
+ 36, 36, 36, 36, 36, 44, 50, 60, 65, 65, 44, 44, 44, 44, 44, 44,
+ 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 80, 44, 44, 44, 44,
+ 67, 67, 67, 92, 55, 67, 67, 67, 67, 67,186, 87, 43, 67,186, 86,
+ 86,187, 65, 65, 65, 84, 43, 43, 43, 76, 50, 43, 43, 43, 67, 67,
+ 67, 67, 67, 67, 67, 43, 43, 67, 67, 43, 76, 44, 44, 44, 44, 44,
+ 27, 27, 44, 44, 44, 44, 44, 44, 11, 11, 11, 11, 11, 16, 16, 16,
+ 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16,
+ 16, 16,110, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 47, 11, 44, 47, 48, 47, 48, 11, 47, 11,
+ 11, 11, 11, 16, 16,150,150, 16, 16, 16,150, 16, 16, 16, 16, 16,
+ 16, 16, 11, 48, 11, 47, 48, 11, 11, 11, 47, 11, 11, 11, 47, 16,
+ 16, 16, 16, 16, 11, 48, 11, 47, 11, 11, 47, 47, 44, 11, 11, 11,
+ 47, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11,
+ 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 44, 11, 11, 11, 11,
+ 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16,
+ 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16,
+ 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16,
+ 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 44, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 43, 43, 43, 76, 67, 50, 43, 43,
+ 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67,
+ 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43,
+ 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110,
+ 44, 44,150, 16, 16,110, 44, 44, 43, 43, 43, 80, 43, 43, 43, 43,
+ 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44,
+ 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 57,
+ 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77,
+ 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43,
+ 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43,
+ 36, 36, 36, 61, 36, 36, 62, 61, 36, 36, 61,179, 27, 27, 27, 27,
+ 16, 16, 43, 43, 43, 74, 44, 44, 27, 27, 27, 27, 27, 27,163, 27,
+ 188, 27,100, 44, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27,163,
+ 27, 27, 27, 27, 27, 27, 27, 44, 36, 36, 62, 36, 36, 36, 36, 36,
+ 62, 61, 61, 62, 62, 36, 36, 36, 36, 61, 36, 36, 62, 62, 44, 44,
+ 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62,
+ 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61,
+ 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36,
+ 8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67,
+ 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44,
+ 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44,
+ 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44,
+ 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67,
+ 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44,
+ 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 44, 44, 44, 44, 67,
+ 67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44,
+ 171,171,171,171,171,171,171, 44,171,171,171,171,171,171,171, 0,
+ 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13,
+ 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5,
+ 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20,
+ 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25,
+ 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 7, 5,
+ 6, 6, 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2,
+ 2, 9, 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26,
+ 26, 23, 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21,
+ 21, 2, 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7,
+ 21, 7, 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1,
+ 12, 2, 6, 2, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12,
+ 21, 6, 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7,
+ 2, 23, 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22,
+ 18, 2, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 2, 5, 6,
+ 8, 8, 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1,
+ 17, 17, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16,
+ 16, 21, 25, 22, 18, 21, 21, 29, 1, 2, 15, 6, 18, 6, 23, 2,
+ 12, 11, 9, 26, 26, 9, 26, 5, 5, 26, 14, 9, 5, 14, 14, 15,
+ 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21,
+ 21, 22, 18, 17, 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6,
+ 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9,
+ 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16,
+ 25, 17, 25, 2, 25, 24, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15,
+ 12, 17, 21, 1, 26, 10, 10, 1, 23, 15, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0,
+ 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19,
+ 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, 20, 0, 21, 22, 23, 0, 0, 0, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 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, 35,
+ 0, 36, 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, 37, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 38, 39, 0, 0, 0, 0, 0, 0, 40, 41, 42, 0, 43, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0,
+ 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11,
+ 12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19,
+ 16, 20, 16, 19, 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
+ 0, 0, 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48,
+ 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52,
+ 53, 0, 54, 0, 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0,
+ 58, 0, 0, 59, 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66,
+ 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0,
+ 72, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0,
+ 0, 0, 75, 76, 0, 77, 78, 0, 0, 79, 80, 0, 81, 62, 0, 82,
+ 83, 0, 0, 84, 85, 86, 0, 0, 0, 87, 0, 88, 0, 0, 51, 89,
+ 51, 0, 90, 0, 91, 0, 0, 0, 80, 0, 0, 0, 92, 93, 0, 94,
+ 95, 96, 97, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 98, 99, 0,
+ 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0,101,102, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,103, 0, 0,104, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,105,106, 0, 0,107, 0, 0, 0, 0, 0, 0,
+ 108, 0,109, 0,102, 0, 0, 0, 0, 0,110,111, 0, 0, 0, 0,
+ 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0,113, 0,114, 0, 0,
+ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, 0, 0,
+ 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, 0, 16,
+ 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, 22, 23,
+ 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, 30, 31,
+ 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, 0, 0,
+ 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, 39,
+ 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, 0, 44,
+ 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 48,
+ 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, 0, 0,
+ 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, 57, 58,
+ 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, 52, 0, 62, 63,
+ 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, 0, 68, 69, 70,
+ 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, 0, 0, 0, 79,
+ 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, 0, 0, 77, 82,
+ 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, 52, 0, 1, 78,
+ 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, 57, 0, 0, 0,
+ 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, 0, 91, 0, 0,
+ 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, 0, 0, 0, 94,
+ 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99, 0,
+ 0, 0, 0,100,101, 93, 0, 0,102, 0, 0, 0, 84, 0, 0,103,
+ 0, 0, 0,104,105, 0, 0,106,107, 0, 0, 0, 0, 0, 0,108,
+ 0, 0,109, 0, 0, 0, 0,110, 33, 0,111,112,113, 35, 0, 0,
+ 114, 0, 0, 0,115, 0, 0, 0, 0, 0, 0,116, 0, 0,117, 0,
+ 0, 0, 0,118, 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,
+ 119, 0, 0, 0, 0,120, 0, 0,121, 0, 0, 0, 0,119, 0, 0,
+ 122, 0, 0, 0, 0, 0, 0,123, 0, 0, 0,124, 0, 0, 0,125,
+ 0,126, 0, 0, 0, 0,127,128,129, 0,130, 0,131, 0, 0, 0,
+ 132,133,134, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,135, 0,
+ 0, 0,136, 0, 0,137, 0, 0,138, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, 9, 10,
+ 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 19, 1, 0, 0,
+ 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, 0, 0,
+ 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 37, 0, 0, 0,
+ 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, 43, 36, 44, 45,
+ 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, 0, 38, 48, 1,
+ 1, 49, 49, 50, 0, 0, 51, 0, 0, 0, 52, 1, 0, 0, 38, 14,
+ 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, 0, 55,
+ 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, 0, 60, 0, 0,
+ 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, 65, 0,
+ 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 69, 70, 0,
+ 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, 0, 78, 79, 0,
+ 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, 0, 62, 0, 0,
+ 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, 84, 0,
+ 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, 36, 10, 21, 87,
+ 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0,
+ 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 87, 9, 12, 4,
+ 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, 1, 1,
+ 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, 0, 0,
+ 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,101,102,
+ 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0,
+ 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, 78, 0, 0, 0,
+ 105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, 1, 14, 4, 12,
+ 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0,109, 61,
+ 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 19, 58, 0, 0, 0, 51,
+ 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, 0, 0,113, 0,
+ 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,113, 0, 0,
+ 0, 0,114, 0, 0, 0, 78, 55, 0, 38, 1, 58, 1, 58, 0, 0,
+ 63, 89, 0, 0,115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0,
+ 0, 0, 61, 0, 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0,
+ 89, 80, 0, 0, 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,
+ 116, 0, 0, 0, 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,
+ 122, 49, 23, 0, 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1,
+ 1, 1, 39, 1, 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123,
+ 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230,
+ 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220,
+ 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220,
+ 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0,
+ 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233,
+ 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230,
+ 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,
+ 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31,
+ 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0,
+ 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0,
+ 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230,
+ 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230,
+ 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220,
+ 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,
+ 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9,
+ 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107,
+ 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220,
+ 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,
+ 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0,
+ 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0,
+ 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220,
+ 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0,
+ 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230,
+ 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1,
+ 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228,
+ 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230,
+ 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0,
+ 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0,
+ 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0,
+ 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0,
+ 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33,
+ 17, 49, 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3,
+ 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3,
+ 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21,
+ 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3,
+ 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0,
+ 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0,
+ 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0,
+ 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0,
+ 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19,
+ 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+ 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39,
+ 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0,
+ 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47,
+ 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0,
+ 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57,
+ 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59,
+ 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60,
+ 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3,
+ 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0,
+ 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0,
+ 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0,
+ 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1,
+ 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0,
+ 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0,
+ 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20,
+ 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9,
+ 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21,
+ 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21,
+ 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9,
+ 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45,
+ 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1,
+ 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3,
+ 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13,
+ 13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 13, 42, 7, 7, 43, 7,
+ 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45, 0, 0, 1,
+ 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, 53, 54, 55, 56,
+ 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61,
+ 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88,
+ 89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96,
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+ 70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109,
+ 110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123,
+ 124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138,
+ 139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151,
+ 152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164,
+ 164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96,
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169,
+ 169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+ 96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173,
+ 173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182,
+ 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+ 182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182,
+ 182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96,
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189,
+ 190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+ 96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96,
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197,
+ 198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208,
+ 208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212,
+ 213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218,
+ 219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226,
+ 59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233,
+ 59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70,241, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
+ 70, 70,242, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
+ 70, 70, 70, 70,243, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+ 70, 70, 70, 70, 70,244, 96, 96, 96, 96, 96, 96, 96, 96,245, 96,
+ 246,247, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0,
+ 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0,
+ 19, 0, 19, 0, 0, 0, 0, 0, 26, 26, 1, 1, 1, 1, 9, 9,
+ 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2,
+ 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9,
+ 2, 9, 9, 9, 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 1,
+ 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 14, 14, 2,
+ 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 3, 3, 3, 3,
+ 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, 1, 3, 3, 3, 37, 37,
+ 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38,
+ 38, 38, 38, 38, 2, 2, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64,
+ 64, 64, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, 90, 2, 95, 95,
+ 95, 95, 2, 2, 95, 2, 3, 3, 3, 2, 3, 3, 2, 2, 3, 3,
+ 0, 3, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 0, 0,
+ 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 2, 2, 5, 5, 2,
+ 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5,
+ 5, 2, 2, 2, 2, 5, 5, 5, 2, 5, 2, 11, 11, 11, 11, 11,
+ 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 2,
+ 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 2, 11, 2, 2, 11, 2,
+ 11, 2, 2, 2, 11, 11, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 2, 10, 10, 2, 10, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2,
+ 10, 10, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2,
+ 21, 21, 21, 21, 2, 2, 21, 21, 2, 21, 2, 2, 21, 21, 2, 2,
+ 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 22, 2, 22, 22, 22, 22,
+ 2, 2, 2, 22, 22, 2, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22,
+ 22, 22, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 23,
+ 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 2, 2, 23, 23, 2, 2,
+ 2, 23, 16, 16, 16, 16, 16, 2, 16, 16, 2, 16, 16, 16, 16, 16,
+ 2, 2, 2, 16, 16, 2, 2, 2, 16, 16, 20, 20, 20, 20, 20, 2,
+ 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 2, 2, 2, 36, 36, 36, 36, 2, 36, 2, 36, 2, 2, 2, 2,
+ 36, 2, 2, 2, 2, 36, 36, 2, 36, 2, 36, 2, 2, 2, 2, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 2, 18,
+ 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 2, 18,
+ 2, 18, 18, 18, 2, 2, 18, 2, 18, 2, 25, 25, 25, 25, 2, 25,
+ 25, 25, 25, 2, 2, 2, 25, 2, 25, 25, 25, 0, 0, 0, 0, 25,
+ 25, 2, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 2, 8, 2, 8,
+ 2, 2, 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 30, 2,
+ 30, 30, 30, 30, 2, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 2,
+ 2, 2, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 34, 34,
+ 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0,
+ 35, 35, 35, 2, 2, 2, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2,
+ 2, 45, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 46, 46,
+ 46, 46, 46, 2, 46, 46, 31, 31, 31, 31, 31, 31, 2, 2, 32, 32,
+ 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 32, 2,
+ 2, 2, 32, 32, 32, 2, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48,
+ 48, 2, 48, 2, 2, 2, 52, 52, 52, 52, 52, 52, 2, 2, 52, 2,
+ 2, 2, 58, 58, 58, 58, 58, 58, 2, 2, 58, 58, 58, 2, 2, 2,
+ 58, 58, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91,
+ 91, 2, 91, 2, 2, 91, 91, 91, 2, 2, 1, 1, 1, 2, 62, 62,
+ 62, 62, 62, 2, 2, 2, 62, 62, 62, 2, 76, 76, 76, 76, 93, 93,
+ 93, 93, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 2, 2, 2, 70,
+ 70, 70, 73, 73, 73, 73, 6, 2, 2, 2, 8, 8, 8, 2, 2, 8,
+ 8, 8, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1,
+ 0, 0, 1, 1, 0, 2, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9,
+ 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19,
+ 19, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 9, 9, 1, 1,
+ 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 19, 0, 0,
+ 0, 2, 19, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2, 0, 0,
+ 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, 2, 2, 0, 0, 0, 0,
+ 2, 0, 56, 56, 56, 56, 2, 55, 55, 55, 61, 61, 61, 61, 2, 2,
+ 2, 61, 61, 2, 2, 2, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13,
+ 2, 13, 13, 13, 2, 2, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13,
+ 1, 1, 1, 1, 12, 12, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 0, 2, 26, 26, 26, 26, 26, 26, 26, 2, 12,
+ 12, 12, 12, 12, 12, 2, 12, 12, 12, 0, 39, 39, 39, 39, 39, 2,
+ 2, 2, 39, 39, 39, 2, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79,
+ 79, 79, 19, 19, 19, 2, 19, 19, 2, 19, 2, 19, 19, 19, 19, 19,
+ 2, 2, 2, 2, 19, 19, 60, 60, 60, 60, 60, 2, 2, 2, 65, 65,
+ 65, 65, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, 75, 75, 69, 69,
+ 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 2, 2, 2, 74, 12, 2,
+ 2, 2, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2,
+ 84, 84, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68,
+ 2, 2, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 92, 87, 87,
+ 87, 87, 87, 87, 87, 2, 19, 9, 19, 19, 19, 19, 0, 0, 87, 87,
+ 2, 2, 2, 2, 2, 12, 2, 2, 2, 4, 14, 2, 14, 2, 14, 14,
+ 2, 14, 14, 2, 14, 14, 2, 2, 2, 3, 3, 3, 0, 0, 2, 2,
+ 3, 3, 1, 1, 6, 6, 3, 2, 3, 3, 3, 2, 2, 0, 2, 0,
+ 0, 0, 0, 0, 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 49, 49,
+ 49, 49, 2, 49, 49, 49, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49,
+ 2, 2, 9, 2, 2, 2, 0, 1, 2, 2, 71, 71, 71, 71, 71, 2,
+ 2, 2, 67, 67, 67, 67, 67, 2, 2, 2, 42, 42, 42, 42, 2, 42,
+ 42, 42, 41, 41, 41, 41, 41, 41, 41, 2,118,118,118,118,118,118,
+ 118, 2, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59,
+ 2, 2, 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50,
+ 2, 2,135,135,135,135,106,106,106,106,104,104,104,104, 2, 2,
+ 2,104,161,161,161,161,161,161,161, 2,161,161, 2,161,161, 2,
+ 2, 2,110,110,110,110,110,110,110, 2,110,110, 2, 2, 19, 2,
+ 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47,
+ 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81,
+ 2, 81,120,120,120,120,116,116,116,116,116,116,116, 2, 2, 2,
+ 2,116,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2,
+ 2,128, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72,
+ 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 97, 97, 97, 97, 2, 2,
+ 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 57, 57, 57, 57, 57,
+ 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 88, 88,
+ 88, 88,117,117,117,117,112,112,112,112,112,112,112, 2, 2, 2,
+ 2,112, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 83, 83,
+ 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, 82, 2,122,122,
+ 122,122,122,122, 2, 2, 2,122,122,122,122, 2, 2, 2, 89, 89,
+ 89, 89, 89, 2, 2, 2,130,130,130,130,130,130,130, 2, 2, 2,
+ 130,130,144,144,144,144,144,144, 2, 2,156,156,156,156,156,156,
+ 2,156,156,156, 2, 2, 2, 3, 3, 3,147,147,147,147,148,148,
+ 148,148,148,148, 2, 2,158,158,158,158,158,158, 2, 2,153,153,
+ 153,153,149,149,149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94,
+ 2, 2, 2, 2, 94, 94, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85,
+ 85, 2, 2, 85, 2, 2,101,101,101,101,101, 2, 2, 2,101,101,
+ 2, 2, 96, 96, 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,
+ 111, 2,100,100,100,100,108,108,108,108,108,108, 2,108,108,108,
+ 2, 2,129,129,129,129,129,129,129, 2,129, 2,129,129,129,129,
+ 2,129,129,129, 2, 2,109,109,109,109,109,109,109, 2,109,109,
+ 2, 2,107,107,107,107, 2,107,107,107,107, 2, 2,107,107, 2,
+ 107,107,107,107, 2, 1,107,107, 2, 2,107, 2, 2, 2, 2, 2,
+ 2,107, 2, 2,107,107,137,137,137,137, 2,137,137,137,137,137,
+ 2, 2,124,124,124,124,124,124, 2, 2,123,123,123,123,123,123,
+ 2, 2,114,114,114,114,114, 2, 2, 2,114,114, 2, 2,102,102,
+ 102,102,102,102, 2, 2,126,126,126,126,126,126,126, 2, 2,126,
+ 126,126,142,142,142,142,125,125,125,125,125,125,125, 2, 2, 2,
+ 2,125,154,154,154,154,154,154,154, 2, 2,154, 2, 2, 2,154,
+ 154, 2,154,154, 2,154,154, 2, 2,154,154,154, 2, 2,150,150,
+ 150,150, 2, 2,150,150,150, 2, 2, 2,141,141,141,141,140,140,
+ 140,140,140,140,140, 2,121,121,121,121,121, 2, 2, 2, 7, 7,
+ 2, 2,133,133,133,133,133, 2,133,133,133,133,133, 2,133,133,
+ 2, 2,133, 2, 2, 2,134,134,134,134, 2, 2,134,134, 2,134,
+ 134,134,134,134,134, 2,138,138,138,138,138,138,138, 2,138,138,
+ 2,138, 2, 2,138, 2,138,138, 2, 2,143,143,143,143,143,143,
+ 2,143,143, 2,143,143,143,143,143, 2,143, 2, 2, 2,143,143,
+ 2, 2,145,145,145,145,145, 2, 2, 2,163,163,163,163,163, 2,
+ 163,163,163,163,163, 2, 2, 2,163,163,163,163, 2, 2, 86, 2,
+ 2, 2, 63, 63, 63, 63, 63, 63, 2, 2, 63, 63, 63, 2, 63, 2,
+ 2, 2,157,157,157,157,157,157,157, 2, 80, 80, 80, 80, 80, 80,
+ 2, 2,127,127,127,127,127,127,127, 2, 79, 2, 2, 2,115,115,
+ 115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,159,159,
+ 159,159,159,159,159, 2,159,159, 2, 2,103,103,103,103,103,103,
+ 2, 2,119,119,119,119,119,119, 2, 2,119,119, 2,119, 2,119,
+ 119,119,146,146,146,146,146,146,146, 2, 99, 99, 99, 99, 99, 99,
+ 99, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136,
+ 136,136,155,155,155,155,155,155, 2, 2,136, 2, 2, 2, 2, 17,
+ 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 17, 17, 17, 2, 2, 2,
+ 15, 2, 2, 17, 2, 2,139,139,139,139,105,105,105,105,105,105,
+ 105, 2,105, 2, 2, 2,105,105, 2, 2, 1, 1, 2, 2, 0, 0,
+ 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 2, 2, 0, 2, 2, 0,
+ 0, 2, 0, 2, 0, 2,131,131,131,131, 2, 2, 2,131, 2,131,
+ 131,131, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 2, 56, 56, 2,
+ 56, 56, 6, 6, 2, 2, 2, 2, 2, 6,151,151,151,151,151, 2,
+ 2, 2,151,151, 2, 2, 2, 2,151,151,160,160,160,160,160,160,
+ 160, 2,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164,
+ 164,164,164,164, 2, 2, 2, 30, 30, 2,113,113,113,113,113, 2,
+ 2,113,113,113,113, 2,132,132,132,132,132,132, 2, 2, 2, 2,
+ 132,132, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 2,
+ 3, 2, 3, 2, 3, 2, 3, 3, 2, 3, 15, 0, 0, 2, 13, 2,
+ 2, 2, 13, 13, 13, 2, 2, 0, 2, 2, 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14,
+ 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24,
+ 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35,
+ 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 41, 42, 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, 43, 44, 0, 45, 0, 0,
+ 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0,
+ 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0,
+ 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0,
+ 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61,
+ 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0,
+ 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0,110, 0,111,112,
+ 113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 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,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121,
+ 0,122,123,124,125,126, 0,127, 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,128,129,130,131,132,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, 0, 0, 0,158,159,160,161, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 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,165, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 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,169,170, 0,
+ 0, 0, 0,171,172, 0, 0, 0,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,201,202,203,204,205,206, 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,
+};
+static const uint16_t
+_hb_ucd_u16[10040] =
+{
+ 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12,
+ 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23,
+ 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31,
+ 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39,
+ 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13,
+ 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50,
+ 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58,
+ 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66,
+ 48, 67, 68, 69, 48, 70, 71, 48, 72, 73, 48, 48, 74, 32, 75, 32,
+ 76, 48, 48, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 83, 84, 91, 92, 93, 94, 95, 96, 97, 84, 98, 99, 100, 88, 101,
+ 102, 83, 84, 103, 104, 105, 88, 106, 107, 108, 109, 110, 111, 112, 94, 113,
+ 114, 115, 84, 116, 117, 118, 88, 119, 120, 115, 84, 121, 122, 123, 88, 124,
+ 125, 115, 48, 126, 127, 128, 88, 129, 130, 131, 48, 132, 133, 134, 94, 135,
+ 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140,
+ 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140,
+ 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48,
+ 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175,
+ 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183,
+ 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193,
+ 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199,
+ 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209,
+ 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140,
+ 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225,
+ 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235,
+ 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13,
+ 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250,
+ 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265,
+ 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278,
+ 279, 279, 279, 279, 279, 279, 279, 279, 280, 209, 281, 209, 209, 209, 209, 282,
+ 209, 283, 279, 284, 209, 285, 286, 209, 209, 209, 287, 140, 288, 140, 271, 271,
+ 271, 289, 209, 209, 209, 209, 290, 271, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 291, 292, 209, 209, 293, 209, 209, 209, 209, 209, 209, 294, 209,
+ 209, 209, 209, 209, 209, 209, 295, 296, 271, 297, 209, 209, 298, 279, 299, 279,
+ 300, 301, 279, 279, 279, 302, 279, 303, 209, 209, 209, 279, 304, 209, 209, 305,
+ 209, 306, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 307, 308,
+ 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313,
+ 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 321, 140, 140,
+ 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 325,
+ 326, 327, 328, 329, 136, 48, 48, 48, 48, 330, 178, 48, 48, 48, 48, 331,
+ 332, 48, 48, 136, 48, 48, 48, 48, 200, 333, 48, 48, 209, 209, 323, 48,
+ 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209,
+ 48, 48, 48, 48, 209, 209, 209, 209, 48, 338, 48, 48, 48, 48, 48, 48,
+ 151, 209, 209, 209, 287, 48, 48, 229, 339, 48, 340, 140, 13, 13, 341, 342,
+ 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349,
+ 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360,
+ 361, 48, 48, 362, 363, 192, 32, 364, 64, 48, 365, 48, 366, 367, 48, 151,
+ 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377,
+ 48, 48, 48, 378, 379, 380, 381, 382, 383, 384, 315, 11, 11, 385, 386, 11,
+ 11, 11, 11, 11, 48, 48, 387, 192, 48, 48, 388, 48, 389, 48, 48, 206,
+ 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391,
+ 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140,
+ 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48,
+ 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403,
+ 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410,
+ 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419,
+ 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71,
+ 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428,
+ 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430,
+ 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140,
+ 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439,
+ 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 140, 140, 140, 140,
+ 48, 48, 48, 314, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140,
+ 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453,
+ 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271,
+ 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467,
+ 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140,
+ 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474,
+ 48, 48, 475, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 271, 476,
+ 48, 48, 477, 478, 140, 140, 140, 479, 48, 464, 480, 48, 62, 481, 140, 48,
+ 482, 140, 140, 48, 483, 140, 48, 314, 484, 48, 48, 485, 486, 457, 487, 488,
+ 222, 48, 48, 489, 490, 48, 196, 192, 491, 48, 492, 493, 494, 48, 48, 495,
+ 222, 48, 48, 496, 497, 498, 499, 500, 48, 97, 501, 502, 503, 140, 140, 140,
+ 504, 505, 506, 48, 48, 507, 508, 192, 509, 83, 84, 510, 511, 512, 513, 514,
+ 48, 48, 48, 515, 516, 517, 478, 140, 48, 48, 48, 518, 519, 192, 140, 140,
+ 48, 48, 520, 521, 522, 523, 140, 140, 48, 48, 48, 524, 525, 192, 526, 140,
+ 48, 48, 527, 528, 192, 140, 140, 140, 48, 173, 529, 530, 314, 140, 140, 140,
+ 48, 48, 501, 531, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 532,
+ 533, 534, 48, 535, 536, 192, 140, 140, 140, 140, 537, 48, 48, 538, 539, 140,
+ 540, 48, 48, 541, 542, 543, 48, 48, 544, 545, 546, 48, 48, 48, 48, 196,
+ 547, 140, 140, 140, 140, 140, 140, 140, 84, 48, 520, 548, 549, 148, 175, 550,
+ 48, 551, 552, 553, 140, 140, 140, 140, 554, 48, 48, 555, 556, 192, 557, 48,
+ 558, 559, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 560,
+ 561, 115, 48, 562, 563, 192, 140, 140, 140, 140, 140, 100, 271, 564, 565, 566,
+ 48, 207, 140, 140, 140, 140, 140, 140, 272, 272, 272, 272, 272, 272, 567, 568,
+ 48, 48, 48, 48, 388, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 569,
+ 48, 48, 48, 570, 571, 572, 140, 140, 48, 48, 48, 48, 314, 140, 140, 140,
+ 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 573,
+ 48, 48, 48, 574, 575, 576, 577, 578, 48, 140, 140, 140, 140, 140, 140, 140,
+ 140, 140, 140, 140, 9, 9, 11, 11, 271, 579, 140, 140, 140, 140, 140, 140,
+ 48, 48, 48, 48, 580, 581, 582, 582, 583, 584, 140, 140, 140, 140, 585, 586,
+ 48, 48, 48, 48, 48, 48, 48, 440, 48, 48, 48, 48, 48, 199, 140, 140,
+ 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 587,
+ 48, 48, 588, 589, 140, 590, 591, 48, 48, 48, 48, 48, 48, 48, 48, 206,
+ 48, 48, 48, 48, 48, 48, 71, 151, 196, 592, 593, 140, 140, 140, 140, 140,
+ 32, 32, 594, 32, 595, 209, 209, 209, 209, 209, 209, 209, 323, 140, 140, 140,
+ 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 596, 209, 209, 209, 597, 598,
+ 599, 209, 600, 209, 209, 209, 288, 140, 209, 209, 209, 209, 601, 140, 140, 140,
+ 140, 140, 140, 140, 271, 602, 271, 602, 209, 209, 209, 209, 209, 287, 271, 461,
+ 9, 603, 11, 604, 605, 606, 241, 9, 607, 608, 609, 610, 611, 9, 603, 11,
+ 612, 613, 11, 614, 615, 616, 617, 9, 618, 11, 9, 603, 11, 604, 605, 11,
+ 241, 9, 607, 617, 9, 618, 11, 9, 603, 11, 619, 9, 620, 621, 622, 623,
+ 11, 624, 9, 625, 626, 627, 628, 11, 629, 9, 630, 11, 631, 632, 632, 632,
+ 32, 32, 32, 633, 32, 32, 634, 635, 636, 637, 45, 140, 140, 140, 140, 140,
+ 638, 639, 640, 140, 140, 140, 140, 140, 641, 642, 643, 27, 27, 27, 644, 140,
+ 645, 140, 140, 140, 140, 140, 140, 140, 48, 48, 151, 646, 647, 140, 140, 140,
+ 140, 48, 648, 140, 48, 48, 649, 650, 140, 140, 140, 140, 140, 48, 651, 192,
+ 140, 140, 140, 140, 140, 140, 652, 200, 48, 48, 48, 48, 653, 595, 140, 140,
+ 9, 9, 607, 11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499,
+ 271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140,
+ 659, 48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668,
+ 209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 669, 669, 669, 209, 324,
+ 670, 209, 209, 209, 209, 209, 209, 209, 209, 209, 671, 140, 140, 140, 672, 209,
+ 673, 209, 209, 325, 674, 675, 324, 140, 209, 209, 209, 209, 209, 209, 209, 676,
+ 209, 209, 209, 209, 209, 677, 426, 426, 209, 209, 209, 209, 209, 209, 209, 678,
+ 209, 209, 209, 209, 209, 176, 325, 427, 325, 209, 209, 209, 679, 176, 209, 209,
+ 679, 209, 671, 675, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 671, 426,
+ 674, 209, 209, 680, 681, 325, 674, 674, 209, 682, 209, 209, 288, 140, 140, 192,
+ 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 207, 48, 48, 48, 48,
+ 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 100, 140, 48, 204, 140, 140, 140, 140, 140, 140,
+ 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140,
+ 683, 140, 570, 570, 570, 570, 570, 570, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 140, 391, 391, 391, 391, 391, 391, 391, 684,
+ 391, 391, 391, 391, 391, 391, 391, 685, 0, 0, 0, 0, 1, 2, 1, 2,
+ 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9,
+ 10, 11, 12, 11, 11, 11, 13, 11, 14, 14, 14, 14, 14, 14, 14, 14,
+ 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 17, 18, 17, 17,
+ 19, 20, 21, 21, 22, 21, 23, 24, 25, 26, 27, 27, 28, 29, 27, 30,
+ 27, 27, 27, 27, 27, 31, 27, 27, 32, 33, 33, 33, 34, 27, 27, 27,
+ 35, 35, 35, 36, 37, 37, 37, 38, 39, 39, 40, 41, 42, 43, 44, 27,
+ 45, 46, 27, 27, 27, 27, 47, 27, 48, 48, 48, 48, 48, 49, 50, 48,
+ 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, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
+ 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 109, 110, 111, 112, 109,
+ 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 122, 123, 122, 124, 125, 125,
+ 126, 127, 128, 129, 130, 131, 125, 125, 132, 132, 132, 132, 133, 132, 134, 135,
+ 132, 133, 132, 136, 136, 137, 125, 125, 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 139, 139, 140, 139, 139, 141, 142, 142, 142, 142, 142, 142, 142, 142,
+ 143, 143, 143, 143, 144, 145, 143, 143, 144, 143, 143, 146, 147, 148, 143, 143,
+ 143, 147, 143, 143, 143, 149, 143, 150, 143, 151, 152, 152, 152, 152, 152, 153,
+ 154, 154, 154, 154, 154, 154, 154, 154, 155, 156, 157, 157, 157, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 168, 168, 168, 169, 170, 170,
+ 171, 172, 173, 173, 173, 173, 173, 174, 173, 173, 175, 154, 154, 154, 154, 176,
+ 177, 178, 179, 179, 180, 181, 182, 183, 184, 184, 185, 184, 186, 187, 168, 168,
+ 188, 189, 190, 190, 190, 191, 190, 192, 193, 193, 194, 8, 195, 125, 125, 125,
+ 196, 196, 196, 196, 197, 196, 196, 198, 199, 199, 199, 199, 200, 200, 200, 201,
+ 202, 202, 202, 203, 204, 205, 205, 205, 206, 139, 139, 207, 208, 209, 210, 211,
+ 4, 4, 212, 4, 4, 213, 214, 215, 4, 4, 4, 216, 8, 8, 8, 8,
+ 11, 217, 11, 11, 217, 218, 11, 219, 11, 11, 11, 220, 220, 221, 11, 222,
+ 223, 0, 0, 0, 0, 0, 224, 225, 226, 227, 0, 0, 228, 8, 8, 229,
+ 0, 0, 230, 231, 232, 0, 4, 4, 233, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 125, 235, 125, 0, 0,
+ 236, 236, 236, 236, 236, 236, 236, 236, 0, 0, 0, 0, 0, 0, 0, 237,
+ 0, 238, 0, 0, 0, 0, 0, 0, 239, 239, 239, 239, 239, 239, 4, 4,
+ 240, 240, 240, 240, 240, 240, 240, 241, 139, 139, 140, 242, 242, 242, 243, 244,
+ 143, 245, 246, 246, 246, 246, 14, 14, 0, 0, 0, 0, 0, 247, 125, 125,
+ 248, 249, 248, 248, 248, 248, 248, 250, 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 251, 125, 252, 253, 0, 254, 255, 256, 257, 257, 257,
+ 257, 258, 259, 260, 260, 260, 260, 261, 262, 263, 263, 264, 142, 142, 142, 142,
+ 265, 0, 263, 263, 0, 0, 266, 260, 142, 265, 0, 0, 0, 0, 142, 267,
+ 0, 0, 0, 0, 0, 260, 260, 268, 260, 260, 260, 260, 260, 269, 0, 0,
+ 248, 248, 248, 248, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270,
+ 271, 270, 270, 270, 272, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274,
+ 274, 274, 275, 125, 14, 14, 14, 14, 14, 14, 276, 276, 276, 276, 276, 277,
+ 0, 0, 278, 4, 4, 4, 4, 4, 279, 4, 4, 4, 280, 281, 125, 282,
+ 283, 283, 284, 285, 286, 286, 286, 287, 288, 288, 288, 288, 289, 290, 48, 48,
+ 291, 291, 292, 293, 293, 294, 142, 295, 296, 296, 296, 296, 297, 298, 138, 299,
+ 300, 300, 300, 301, 302, 303, 138, 138, 304, 304, 304, 304, 305, 306, 307, 308,
+ 309, 310, 246, 4, 4, 311, 312, 152, 152, 152, 152, 152, 307, 307, 313, 314,
+ 142, 142, 315, 142, 316, 142, 142, 317, 125, 125, 125, 125, 125, 125, 125, 125,
+ 248, 248, 248, 248, 248, 248, 318, 248, 248, 248, 248, 248, 248, 319, 125, 125,
+ 320, 321, 21, 322, 323, 27, 27, 27, 27, 27, 27, 27, 324, 325, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 326, 27, 27, 27, 27,
+ 27, 327, 27, 27, 328, 125, 125, 27, 8, 285, 329, 0, 0, 330, 331, 332,
+ 27, 27, 27, 27, 27, 27, 27, 333, 334, 0, 1, 2, 1, 2, 335, 259,
+ 260, 336, 142, 265, 337, 338, 339, 340, 341, 342, 343, 344, 345, 345, 125, 125,
+ 342, 342, 342, 342, 342, 342, 342, 346, 347, 0, 0, 348, 11, 11, 11, 11,
+ 349, 350, 351, 125, 125, 0, 0, 352, 353, 354, 355, 355, 355, 356, 357, 252,
+ 358, 358, 359, 360, 361, 362, 362, 363, 364, 365, 366, 366, 367, 368, 125, 125,
+ 369, 369, 369, 369, 369, 370, 370, 370, 371, 372, 373, 374, 374, 375, 374, 376,
+ 377, 377, 378, 379, 379, 379, 380, 381, 381, 382, 383, 384, 125, 125, 125, 125,
+ 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 386, 385, 387, 388, 125,
+ 389, 4, 4, 390, 125, 125, 125, 125, 391, 392, 392, 393, 394, 395, 396, 396,
+ 397, 398, 399, 125, 125, 125, 400, 401, 402, 403, 404, 405, 125, 125, 125, 125,
+ 406, 406, 407, 408, 407, 409, 407, 407, 410, 411, 412, 413, 414, 414, 415, 415,
+ 416, 416, 125, 125, 417, 417, 418, 419, 420, 420, 420, 421, 422, 423, 424, 425,
+ 426, 427, 428, 125, 125, 125, 125, 125, 429, 429, 429, 429, 430, 125, 125, 125,
+ 431, 431, 431, 432, 431, 431, 431, 433, 434, 434, 435, 436, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 27, 45, 437, 437, 438, 439, 125, 125, 125, 440,
+ 441, 441, 442, 443, 443, 444, 125, 445, 446, 125, 125, 447, 448, 125, 449, 450,
+ 451, 451, 451, 451, 452, 453, 451, 454, 455, 455, 455, 455, 456, 457, 458, 459,
+ 460, 460, 460, 461, 462, 463, 463, 464, 465, 465, 465, 465, 465, 465, 466, 467,
+ 468, 469, 468, 468, 470, 125, 125, 125, 471, 472, 473, 474, 474, 474, 475, 476,
+ 477, 478, 479, 480, 481, 482, 483, 484, 485, 485, 485, 485, 485, 486, 487, 125,
+ 488, 488, 488, 488, 489, 490, 125, 125, 491, 491, 491, 492, 491, 493, 125, 125,
+ 494, 494, 494, 494, 495, 496, 497, 125, 498, 498, 498, 499, 499, 125, 125, 125,
+ 500, 501, 502, 500, 503, 125, 125, 125, 504, 504, 504, 505, 125, 125, 125, 125,
+ 125, 125, 506, 506, 506, 506, 506, 507, 508, 509, 510, 511, 512, 513, 125, 125,
+ 125, 125, 514, 515, 515, 514, 516, 125, 517, 517, 517, 517, 518, 519, 519, 519,
+ 519, 519, 520, 154, 521, 521, 521, 522, 523, 125, 125, 125, 125, 125, 125, 125,
+ 524, 525, 525, 526, 527, 525, 528, 529, 529, 530, 531, 532, 125, 125, 125, 125,
+ 533, 534, 534, 535, 536, 537, 538, 539, 540, 541, 542, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 543, 544, 545, 546, 545, 547, 545, 548, 125, 125,
+ 125, 125, 125, 549, 550, 550, 550, 551, 552, 552, 552, 552, 552, 552, 552, 552,
+ 552, 553, 125, 125, 125, 125, 125, 125, 552, 552, 552, 552, 552, 552, 554, 555,
+ 552, 552, 552, 552, 556, 125, 125, 125, 125, 557, 557, 557, 557, 557, 557, 558,
+ 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 560, 125, 125,
+ 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 562, 125, 125, 125,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 563, 564, 565, 566, 567,
+ 567, 567, 567, 568, 569, 570, 571, 572, 573, 573, 573, 573, 574, 575, 576, 577,
+ 573, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 578, 578, 578, 578,
+ 578, 579, 125, 125, 125, 125, 125, 125, 580, 580, 580, 580, 581, 580, 580, 580,
+ 582, 580, 125, 125, 125, 125, 583, 584, 585, 585, 585, 585, 585, 585, 585, 585,
+ 585, 585, 585, 585, 585, 585, 585, 586, 587, 587, 587, 587, 587, 587, 587, 587,
+ 587, 587, 587, 587, 587, 588, 125, 125, 589, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 590, 591, 257, 257, 257, 257, 257, 257, 257,
+ 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 592, 593, 125, 594, 595, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 597,
+ 598, 598, 598, 598, 598, 598, 599, 600, 601, 602, 266, 125, 125, 125, 125, 125,
+ 8, 8, 603, 8, 604, 0, 0, 0, 0, 0, 0, 0, 266, 125, 125, 125,
+ 0, 0, 0, 0, 0, 0, 0, 605, 0, 0, 606, 0, 0, 0, 607, 608,
+ 609, 0, 610, 0, 0, 0, 235, 125, 11, 11, 11, 11, 611, 125, 125, 125,
+ 125, 125, 125, 125, 0, 266, 0, 266, 0, 0, 0, 0, 0, 234, 0, 612,
+ 0, 0, 0, 0, 0, 224, 0, 0, 0, 613, 614, 615, 616, 0, 0, 0,
+ 617, 618, 0, 619, 620, 621, 0, 0, 0, 0, 622, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 623, 0, 0, 0, 624, 624, 624, 624, 624, 624, 624, 624,
+ 625, 626, 627, 125, 125, 125, 125, 125, 4, 628, 629, 125, 125, 125, 125, 125,
+ 630, 631, 632, 14, 14, 14, 633, 125, 634, 125, 125, 125, 125, 125, 125, 125,
+ 635, 635, 636, 637, 638, 125, 125, 125, 125, 639, 640, 125, 641, 641, 641, 642,
+ 125, 125, 125, 125, 125, 643, 643, 644, 125, 125, 125, 125, 125, 125, 645, 646,
+ 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 648, 649, 125, 125,
+ 650, 650, 650, 650, 651, 652, 125, 125, 125, 125, 125, 125, 125, 125, 125, 334,
+ 0, 0, 0, 653, 125, 125, 125, 125, 334, 0, 0, 247, 125, 125, 125, 125,
+ 654, 27, 655, 656, 657, 658, 659, 660, 661, 662, 663, 662, 125, 125, 125, 664,
+ 0, 0, 252, 0, 0, 0, 0, 0, 0, 266, 226, 334, 334, 334, 0, 605,
+ 0, 0, 247, 125, 125, 125, 665, 0, 666, 0, 0, 252, 612, 667, 605, 125,
+ 0, 0, 0, 0, 0, 668, 350, 350, 0, 0, 0, 0, 0, 0, 0, 669,
+ 0, 0, 0, 0, 0, 285, 252, 228, 252, 0, 0, 0, 670, 285, 0, 0,
+ 670, 0, 247, 667, 125, 125, 125, 125, 0, 0, 0, 0, 0, 266, 247, 350,
+ 612, 0, 0, 671, 672, 252, 612, 612, 0, 330, 0, 0, 235, 125, 125, 285,
+ 248, 248, 248, 248, 248, 248, 125, 125, 248, 248, 248, 319, 248, 248, 248, 248,
+ 248, 318, 248, 248, 248, 248, 248, 248, 248, 248, 584, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 673, 125, 248, 318, 125, 125, 125, 125, 125, 125,
+ 248, 248, 248, 248, 674, 248, 248, 248, 248, 248, 248, 125, 125, 125, 125, 125,
+ 675, 125, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 1, 2, 2, 2,
+ 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2,
+ 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 8, 8, 8, 8, 16, 8, 8, 8, 17, 18, 18, 18,
+ 19, 19, 19, 19, 19, 20, 19, 19, 21, 22, 22, 22, 22, 22, 22, 22,
+ 22, 23, 21, 22, 22, 22, 23, 21, 24, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 12, 12, 25, 25, 26, 27, 25, 28, 12, 12, 29, 30, 29, 31,
+ 29, 29, 32, 32, 29, 29, 29, 29, 31, 29, 33, 7, 7, 34, 29, 29,
+ 35, 29, 29, 29, 29, 29, 29, 30, 36, 36, 36, 37, 36, 36, 36, 36,
+ 36, 36, 38, 39, 40, 40, 40, 40, 41, 12, 12, 12, 42, 42, 42, 42,
+ 42, 42, 43, 44, 45, 45, 45, 45, 45, 45, 45, 46, 45, 45, 45, 47,
+ 48, 48, 48, 48, 48, 48, 48, 49, 36, 36, 38, 12, 29, 29, 29, 50,
+ 51, 12, 29, 29, 52, 29, 29, 29, 53, 53, 53, 53, 54, 55, 53, 53,
+ 53, 56, 53, 53, 57, 58, 57, 59, 59, 57, 57, 57, 57, 57, 60, 57,
+ 61, 62, 63, 57, 57, 59, 59, 64, 12, 65, 12, 66, 57, 62, 57, 57,
+ 57, 57, 57, 64, 67, 67, 68, 69, 70, 71, 71, 71, 71, 71, 72, 71,
+ 72, 73, 74, 72, 68, 69, 70, 74, 75, 12, 67, 76, 12, 77, 71, 71,
+ 71, 68, 12, 12, 78, 78, 79, 80, 80, 79, 79, 79, 79, 79, 81, 79,
+ 81, 78, 82, 79, 79, 80, 80, 82, 83, 12, 12, 12, 79, 84, 79, 79,
+ 82, 12, 78, 79, 85, 85, 86, 87, 87, 86, 86, 86, 86, 86, 88, 86,
+ 88, 85, 89, 86, 86, 87, 87, 89, 12, 85, 12, 90, 86, 91, 86, 86,
+ 86, 86, 12, 12, 92, 93, 94, 92, 95, 96, 97, 95, 98, 99, 94, 92,
+ 100, 100, 96, 92, 94, 92, 95, 96, 99, 98, 12, 12, 12, 92, 100, 100,
+ 100, 100, 94, 12, 101, 101, 101, 102, 102, 101, 101, 101, 101, 101, 102, 101,
+ 101, 101, 103, 101, 101, 102, 102, 103, 12, 104, 105, 106, 101, 107, 101, 101,
+ 12, 108, 101, 101, 109, 109, 109, 110, 110, 109, 109, 109, 109, 109, 110, 109,
+ 109, 111, 112, 109, 109, 110, 110, 112, 12, 113, 12, 113, 109, 114, 109, 109,
+ 111, 12, 12, 12, 115, 115, 115, 116, 116, 115, 115, 115, 115, 115, 115, 115,
+ 115, 116, 116, 115, 12, 115, 115, 115, 115, 117, 115, 115, 118, 118, 119, 119,
+ 119, 120, 121, 119, 119, 119, 119, 119, 122, 119, 119, 123, 119, 120, 124, 125,
+ 119, 126, 119, 119, 12, 121, 119, 119, 121, 127, 12, 12, 128, 129, 129, 129,
+ 129, 129, 129, 129, 129, 129, 130, 131, 129, 129, 129, 12, 12, 12, 12, 12,
+ 132, 133, 134, 135, 135, 135, 135, 135, 135, 136, 135, 135, 135, 135, 135, 137,
+ 135, 138, 135, 134, 135, 135, 137, 135, 139, 139, 139, 139, 139, 139, 140, 139,
+ 139, 139, 139, 141, 140, 139, 139, 139, 139, 139, 139, 142, 139, 143, 144, 12,
+ 145, 145, 145, 145, 146, 146, 146, 146, 146, 147, 12, 148, 146, 146, 149, 146,
+ 150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 152, 153, 151, 154, 152, 153,
+ 152, 153, 151, 154, 152, 153, 151, 151, 151, 154, 151, 151, 151, 151, 154, 155,
+ 151, 151, 151, 156, 151, 151, 153, 12, 157, 157, 157, 157, 157, 158, 157, 158,
+ 159, 159, 159, 159, 160, 160, 160, 160, 160, 160, 160, 161, 162, 162, 162, 162,
+ 162, 162, 163, 164, 162, 162, 165, 12, 166, 166, 166, 166, 166, 167, 12, 168,
+ 169, 169, 169, 169, 169, 170, 12, 12, 171, 171, 171, 171, 171, 12, 12, 12,
+ 172, 172, 172, 173, 173, 12, 12, 12, 174, 174, 174, 174, 174, 174, 174, 175,
+ 174, 174, 175, 12, 176, 177, 178, 178, 178, 178, 179, 12, 178, 178, 178, 178,
+ 178, 178, 180, 12, 178, 178, 181, 12, 159, 182, 12, 12, 183, 183, 183, 183,
+ 183, 183, 183, 184, 183, 183, 183, 12, 185, 183, 183, 183, 186, 186, 186, 186,
+ 186, 186, 186, 187, 186, 188, 12, 12, 189, 189, 189, 189, 189, 189, 189, 12,
+ 189, 189, 190, 12, 189, 189, 191, 192, 193, 193, 193, 193, 193, 193, 193, 194,
+ 195, 195, 195, 195, 195, 195, 195, 196, 195, 195, 195, 197, 195, 195, 198, 12,
+ 195, 195, 195, 198, 7, 7, 7, 199, 200, 200, 200, 200, 200, 200, 200, 201,
+ 200, 200, 200, 202, 203, 203, 203, 203, 204, 204, 204, 204, 204, 12, 12, 204,
+ 205, 205, 205, 205, 205, 205, 206, 205, 205, 205, 207, 208, 209, 209, 209, 209,
+ 19, 19, 210, 12, 146, 146, 211, 212, 203, 203, 12, 12, 213, 7, 7, 7,
+ 214, 7, 215, 216, 0, 215, 217, 12, 2, 218, 219, 2, 2, 2, 2, 220,
+ 221, 218, 222, 2, 2, 2, 223, 2, 2, 2, 2, 224, 8, 225, 8, 225,
+ 8, 8, 226, 226, 8, 8, 8, 225, 8, 15, 8, 8, 8, 10, 8, 227,
+ 10, 15, 8, 14, 0, 0, 0, 228, 0, 229, 0, 0, 230, 0, 0, 231,
+ 0, 0, 0, 232, 2, 2, 2, 233, 234, 12, 12, 12, 235, 12, 12, 12,
+ 0, 236, 237, 0, 4, 0, 0, 0, 0, 0, 0, 4, 2, 2, 5, 12,
+ 0, 232, 12, 12, 0, 0, 232, 12, 238, 238, 238, 238, 0, 239, 0, 0,
+ 0, 240, 0, 0, 241, 241, 241, 241, 18, 18, 18, 18, 18, 12, 242, 18,
+ 243, 243, 243, 243, 243, 243, 12, 244, 245, 12, 12, 244, 151, 154, 12, 12,
+ 151, 154, 151, 154, 0, 0, 0, 246, 247, 247, 247, 247, 247, 247, 248, 247,
+ 247, 12, 12, 12, 247, 249, 12, 12, 0, 0, 0, 12, 0, 250, 0, 0,
+ 251, 247, 252, 253, 0, 0, 247, 0, 254, 255, 255, 255, 255, 255, 255, 255,
+ 255, 256, 257, 258, 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 259,
+ 12, 262, 263, 263, 263, 263, 263, 263, 264, 150, 150, 150, 150, 150, 150, 265,
+ 0, 12, 12, 12, 150, 150, 150, 266, 260, 260, 260, 261, 260, 260, 0, 0,
+ 267, 267, 267, 267, 267, 267, 267, 268, 267, 269, 12, 12, 270, 270, 270, 270,
+ 271, 271, 271, 271, 271, 271, 271, 12, 272, 272, 272, 272, 272, 272, 12, 12,
+ 237, 2, 2, 2, 2, 2, 231, 2, 2, 2, 273, 12, 274, 275, 276, 12,
+ 277, 2, 2, 2, 278, 278, 278, 278, 278, 278, 278, 279, 0, 0, 246, 12,
+ 280, 280, 280, 280, 280, 280, 12, 12, 281, 281, 281, 281, 281, 282, 12, 283,
+ 281, 281, 282, 12, 284, 284, 284, 284, 284, 284, 284, 285, 286, 286, 286, 286,
+ 286, 12, 12, 287, 150, 150, 150, 288, 289, 289, 289, 289, 289, 289, 289, 290,
+ 289, 289, 291, 292, 145, 145, 145, 293, 294, 294, 294, 294, 294, 295, 12, 12,
+ 294, 294, 294, 296, 294, 294, 296, 294, 297, 297, 297, 297, 298, 12, 12, 12,
+ 12, 12, 299, 297, 300, 300, 300, 300, 300, 301, 12, 12, 155, 154, 155, 154,
+ 155, 154, 12, 12, 2, 2, 3, 2, 2, 302, 303, 12, 300, 300, 300, 304,
+ 300, 300, 304, 12, 150, 12, 12, 12, 150, 265, 305, 150, 150, 150, 150, 12,
+ 247, 247, 247, 249, 247, 247, 249, 12, 2, 273, 12, 12, 306, 22, 12, 24,
+ 25, 26, 25, 307, 308, 309, 25, 25, 50, 12, 12, 12, 310, 29, 29, 29,
+ 29, 29, 29, 311, 312, 29, 29, 29, 29, 29, 12, 310, 7, 7, 7, 313,
+ 232, 0, 0, 0, 0, 232, 0, 12, 29, 314, 29, 29, 29, 29, 29, 315,
+ 316, 0, 0, 0, 0, 317, 260, 260, 260, 260, 260, 318, 319, 150, 319, 150,
+ 319, 150, 319, 288, 0, 232, 0, 232, 12, 12, 316, 246, 320, 320, 320, 321,
+ 320, 320, 320, 320, 320, 322, 320, 320, 320, 320, 322, 323, 320, 320, 320, 324,
+ 320, 320, 322, 12, 232, 131, 0, 0, 0, 131, 0, 0, 8, 8, 8, 14,
+ 0, 0, 0, 234, 325, 12, 12, 12, 0, 0, 0, 326, 327, 327, 327, 327,
+ 327, 327, 327, 328, 329, 329, 329, 329, 330, 12, 12, 12, 215, 0, 0, 0,
+ 331, 331, 331, 331, 331, 12, 12, 332, 333, 333, 333, 333, 333, 333, 334, 12,
+ 335, 335, 335, 335, 335, 335, 336, 12, 337, 337, 337, 337, 337, 337, 337, 338,
+ 339, 339, 339, 339, 339, 12, 339, 339, 339, 340, 12, 12, 341, 341, 341, 341,
+ 342, 342, 342, 342, 343, 343, 343, 343, 343, 343, 343, 344, 343, 343, 344, 12,
+ 345, 345, 345, 345, 345, 12, 345, 345, 345, 345, 345, 12, 346, 346, 346, 346,
+ 346, 346, 12, 12, 347, 347, 347, 347, 347, 12, 12, 348, 349, 349, 350, 349,
+ 350, 351, 349, 349, 351, 349, 349, 349, 351, 349, 351, 352, 353, 353, 353, 353,
+ 353, 354, 12, 12, 353, 355, 12, 12, 353, 353, 12, 12, 2, 274, 2, 2,
+ 356, 2, 273, 12, 357, 358, 359, 357, 357, 357, 357, 357, 357, 360, 361, 362,
+ 363, 363, 363, 363, 363, 364, 363, 363, 365, 365, 365, 365, 366, 366, 366, 366,
+ 366, 366, 366, 367, 12, 368, 366, 366, 369, 369, 369, 369, 370, 371, 372, 369,
+ 373, 373, 373, 373, 373, 373, 373, 374, 375, 375, 375, 375, 375, 375, 376, 377,
+ 378, 378, 378, 378, 379, 379, 379, 379, 379, 379, 12, 379, 380, 379, 379, 379,
+ 381, 382, 12, 381, 381, 383, 383, 381, 381, 381, 381, 381, 381, 384, 385, 386,
+ 381, 381, 387, 12, 388, 388, 388, 388, 389, 389, 389, 389, 390, 390, 390, 390,
+ 390, 391, 392, 390, 390, 391, 12, 12, 393, 393, 393, 393, 393, 394, 395, 393,
+ 396, 396, 396, 396, 396, 397, 396, 396, 398, 398, 398, 398, 399, 12, 398, 398,
+ 400, 400, 400, 400, 401, 12, 402, 403, 12, 12, 402, 400, 404, 404, 404, 404,
+ 404, 404, 405, 12, 406, 406, 406, 406, 407, 12, 12, 12, 407, 12, 408, 406,
+ 409, 409, 409, 409, 409, 409, 12, 12, 409, 409, 410, 12, 411, 411, 411, 411,
+ 411, 411, 412, 413, 413, 12, 12, 12, 12, 12, 12, 414, 415, 415, 415, 415,
+ 415, 415, 12, 12, 416, 416, 416, 416, 416, 416, 417, 12, 418, 418, 418, 418,
+ 418, 418, 419, 12, 420, 420, 420, 420, 420, 420, 420, 12, 421, 421, 421, 421,
+ 421, 422, 12, 12, 423, 423, 423, 423, 423, 423, 423, 424, 425, 423, 423, 423,
+ 423, 424, 12, 426, 427, 427, 427, 427, 428, 12, 12, 429, 430, 430, 430, 430,
+ 430, 430, 431, 12, 430, 430, 432, 12, 433, 433, 433, 433, 433, 434, 433, 433,
+ 433, 433, 12, 12, 435, 435, 435, 435, 435, 436, 12, 12, 437, 437, 437, 437,
+ 118, 119, 119, 119, 119, 127, 12, 12, 438, 438, 438, 438, 439, 438, 438, 438,
+ 440, 12, 12, 12, 441, 442, 443, 444, 441, 441, 441, 444, 441, 441, 445, 12,
+ 446, 446, 446, 446, 446, 446, 447, 12, 446, 446, 448, 12, 449, 450, 449, 451,
+ 451, 449, 449, 449, 449, 449, 452, 449, 452, 450, 453, 449, 449, 451, 451, 454,
+ 455, 456, 12, 450, 449, 457, 449, 455, 449, 455, 12, 12, 458, 458, 458, 458,
+ 458, 458, 458, 459, 460, 12, 12, 12, 461, 461, 461, 461, 461, 461, 12, 12,
+ 461, 461, 462, 12, 463, 463, 463, 463, 463, 464, 463, 463, 463, 463, 463, 464,
+ 465, 465, 465, 465, 465, 466, 12, 12, 465, 465, 467, 12, 178, 178, 178, 180,
+ 468, 468, 468, 468, 468, 468, 469, 12, 470, 470, 470, 470, 470, 470, 471, 472,
+ 470, 470, 470, 12, 470, 471, 12, 12, 473, 473, 473, 473, 473, 473, 473, 12,
+ 474, 474, 474, 474, 475, 12, 12, 476, 477, 478, 479, 477, 477, 480, 477, 477,
+ 477, 477, 477, 477, 477, 481, 482, 477, 477, 478, 12, 12, 477, 477, 483, 12,
+ 484, 484, 485, 484, 484, 484, 484, 484, 484, 486, 12, 12, 487, 487, 487, 487,
+ 487, 487, 12, 12, 488, 488, 488, 488, 489, 12, 12, 12, 490, 490, 490, 490,
+ 490, 490, 491, 12, 53, 53, 492, 12, 493, 493, 494, 493, 493, 493, 493, 493,
+ 493, 495, 493, 493, 493, 496, 12, 12, 493, 493, 493, 497, 498, 498, 498, 498,
+ 499, 498, 498, 498, 498, 498, 500, 498, 498, 501, 12, 12, 502, 503, 504, 502,
+ 502, 502, 502, 502, 502, 503, 505, 504, 502, 502, 12, 12, 502, 502, 506, 12,
+ 507, 508, 509, 507, 507, 507, 507, 507, 507, 507, 507, 510, 508, 507, 511, 12,
+ 507, 507, 512, 12, 513, 513, 513, 513, 513, 513, 514, 12, 515, 515, 515, 515,
+ 516, 515, 515, 515, 515, 515, 517, 518, 515, 515, 519, 12, 520, 12, 12, 12,
+ 100, 100, 100, 100, 96, 12, 12, 98, 521, 521, 521, 521, 521, 521, 522, 12,
+ 521, 521, 521, 523, 521, 524, 12, 12, 521, 12, 12, 12, 525, 525, 525, 525,
+ 526, 12, 12, 12, 527, 527, 527, 527, 527, 528, 12, 12, 529, 529, 529, 529,
+ 529, 530, 12, 12, 272, 272, 531, 12, 532, 532, 532, 532, 532, 532, 532, 533,
+ 532, 532, 534, 535, 536, 536, 536, 536, 536, 536, 536, 537, 536, 536, 538, 12,
+ 539, 539, 539, 539, 539, 539, 539, 540, 539, 540, 12, 12, 541, 541, 541, 541,
+ 541, 542, 12, 12, 541, 541, 543, 541, 543, 541, 541, 541, 541, 541, 12, 544,
+ 545, 545, 545, 545, 545, 545, 546, 12, 547, 547, 547, 547, 547, 547, 548, 549,
+ 547, 547, 12, 549, 550, 551, 12, 12, 249, 12, 12, 12, 552, 552, 552, 552,
+ 552, 552, 12, 12, 553, 553, 553, 553, 553, 554, 12, 12, 552, 552, 555, 12,
+ 260, 556, 260, 557, 558, 255, 255, 255, 559, 12, 12, 12, 560, 12, 12, 12,
+ 256, 561, 12, 12, 12, 260, 12, 12, 562, 562, 562, 562, 562, 562, 562, 12,
+ 563, 563, 563, 563, 563, 563, 564, 12, 563, 563, 563, 565, 563, 563, 565, 12,
+ 563, 563, 566, 563, 7, 7, 7, 567, 7, 199, 12, 12, 0, 246, 12, 12,
+ 0, 232, 316, 0, 0, 568, 228, 0, 0, 0, 568, 7, 213, 569, 7, 0,
+ 0, 0, 570, 228, 8, 225, 12, 12, 0, 0, 234, 12, 0, 0, 0, 229,
+ 571, 572, 316, 229, 0, 0, 240, 316, 0, 316, 0, 0, 0, 240, 232, 316,
+ 0, 229, 0, 229, 0, 0, 240, 232, 0, 573, 239, 0, 229, 0, 0, 0,
+ 0, 246, 0, 0, 0, 0, 0, 239, 574, 574, 574, 574, 574, 574, 574, 12,
+ 12, 12, 575, 574, 576, 574, 574, 574, 2, 2, 2, 273, 12, 275, 273, 12,
+ 241, 577, 241, 241, 241, 241, 578, 241, 579, 580, 577, 12, 19, 19, 19, 581,
+ 12, 12, 12, 582, 583, 583, 583, 583, 583, 583, 583, 584, 583, 583, 583, 585,
+ 583, 583, 585, 586, 587, 587, 587, 587, 587, 587, 587, 588, 589, 589, 589, 589,
+ 589, 589, 590, 591, 592, 592, 592, 592, 592, 592, 593, 12, 151, 154, 151, 594,
+ 151, 151, 151, 154, 595, 595, 595, 595, 595, 596, 595, 595, 595, 597, 12, 12,
+ 598, 598, 598, 598, 598, 598, 598, 12, 598, 598, 599, 600, 0, 234, 12, 12,
+ 29, 414, 29, 29, 601, 602, 414, 29, 50, 29, 603, 12, 604, 310, 603, 414,
+ 601, 602, 603, 603, 601, 602, 50, 29, 50, 29, 414, 605, 29, 29, 606, 29,
+ 29, 29, 29, 12, 414, 414, 606, 29, 51, 12, 12, 12, 12, 239, 0, 0,
+ 607, 12, 12, 12, 246, 12, 12, 12, 0, 0, 12, 0, 0, 232, 131, 0,
+ 0, 0, 12, 12, 0, 0, 0, 240, 0, 246, 12, 239, 608, 12, 12, 12,
+ 247, 247, 609, 12, 610, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962,
+ 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0,
+ 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147,
+ 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0,
+ 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143,
+ 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160,
+ 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0,
+ 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206,
+ 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035,
+ 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250,
+ 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0,
+ 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,
+ 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,1093,1280, 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, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,
+ 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177,
+ 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0,
+ 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,
+ 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,
+ 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130,
+ 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5,
+ 1434,1438,1443, 0,1450, 0,1455,1461,1514, 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,1446,1458,1468,1476,1480,1486,1517, 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,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522,
+ 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567,
+ 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549,
+ 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559,
+ 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0,
+ 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648,
+ 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662,
+ 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0,
+ 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671,
+ 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0,
+ 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142,
+ 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381,
+ 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181,
+ 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,
+ 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,
+ 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,
+ 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,
+ 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,
+ 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,
+ 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,
+ 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343,
+ 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696,
+ 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,
+ 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,
+ 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,
+ 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,
+ 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707,
+ 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0,
+ 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743,
+ 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,
+ 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0,
+ 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790,
+ 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800,
+ 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24,
+ 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714,
+ 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,
+ 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,
+ 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825,
+ 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829,
+ 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515,
+ 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518,
+ 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830,
+ 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0,
+ 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0,
+ 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847,
+ 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0,
+ 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0,
+ 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0,
+ 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0,
+ 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890,
+ 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897,
+ 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0,
+ 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917,
+ 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924,
+ 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929,
+ 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825,
+ 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500,
+ 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679,
+ 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722,
+ 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540,
+ 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589,
+ 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101,
+ 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110,
+ 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801,
+ 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610,
+ 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494,
+ 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748,
+ 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161,
+ 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727,
+ 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684,
+ 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566,
+ 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729,
+ 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525,
+ 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0,
+ 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213,
+ 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458,
+ 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591,
+ 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735,
+ 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171,
+ 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325,
+ 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438,
+ 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526,
+ 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693,
+ 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777,
+ 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916,
+ 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0,
+ 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599,
+ 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954,1955, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121,
+ 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142,
+ 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169,
+ 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185,
+ 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206,
+ 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224,
+ 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39,
+ 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266,
+ 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286,
+ 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852,
+ 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324,
+ 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351,
+ 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50,
+ 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78,
+ 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55,
+ 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861,
+ 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436,
+ 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467,
+ 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873,
+ 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875,
+ 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531,
+ 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559,
+ 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73,
+ 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898,
+ 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902,
+ 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904,
+ 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81,
+ 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669,
+ 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686,
+ 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719,
+ 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753,
+ 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925,
+ 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800,
+ 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816,
+ 817, 818, 819, 820, 821, 935, 0, 0,
+};
+static const int16_t
+_hb_ucd_i16[92] =
+{
+ 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16,
+ 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914,
+ 1918, 0, 2250, 0, 0, 138, 0, 7, -7, 0, -1, 1, 1824, 0, 2104, 0,
+ 2108, 2106, 0, 2106, 1316, 0, -1, -138, 8, 8, 8, 0, 7, 7, -8, -8,
+ -8, -7,-1316, 1, -1, 3, -3, 1, 0,-1914,-1918, 0, 0,-1923,-1824, 0,
+ 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0,
+};
+
+static inline uint_fast8_t
+_hb_ucd_gc (unsigned u)
+{
+ return u<1114110u?_hb_ucd_u8[6800+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
+}
+static inline uint_fast8_t
+_hb_ucd_ccc (unsigned u)
+{
+ return u<125259u?_hb_ucd_u8[8792+(((_hb_ucd_u8[8236+(((_hb_ucd_u8[7776+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
+}
+static inline unsigned
+_hb_ucd_b4 (const uint8_t* a, unsigned i)
+{
+ return (a[i>>1]>>((i&1u)<<2))&15u;
+}
+static inline int_fast16_t
+_hb_ucd_bmg (unsigned u)
+{
+ return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9684+(((_hb_ucd_u8[9452+(((_hb_ucd_u8[9356+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
+}
+static inline uint_fast8_t
+_hb_ucd_sc (unsigned u)
+{
+ return u<918000u?_hb_ucd_u8[11118+(((_hb_ucd_u16[4024+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10382+(((_hb_ucd_u8[9932+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
+}
+static inline uint_fast16_t
+_hb_ucd_dm (unsigned u)
+{
+ return u<195102u?_hb_ucd_u16[6728+(((_hb_ucd_u8[13944+(((_hb_ucd_u8[13562+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
+}
+
+
#else
static const uint8_t
diff --git a/src/hb-ucd.cc b/src/hb-ucd.cc
index baea224..4c8b1ee 100644
--- a/src/hb-ucd.cc
+++ b/src/hb-ucd.cc
@@ -129,12 +129,16 @@
hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab,
void *user_data HB_UNUSED)
{
+ // Hangul is handled algorithmically.
if (_hb_ucd_compose_hangul (a, b, ab)) return true;
hb_codepoint_t u = 0;
if ((a & 0xFFFFF800u) == 0x0000u && (b & 0xFFFFFF80) == 0x0300u)
{
+ /* If "a" is small enough and "b" is in the U+0300 range,
+ * the composition data is encoded in a 32bit array sorted
+ * by "a,b" pair. */
uint32_t k = HB_CODEPOINT_ENCODE3_11_7_14 (a, b, 0);
const uint32_t *v = hb_bsearch (k,
_hb_ucd_dm2_u32_map,
@@ -146,6 +150,8 @@
}
else
{
+ /* Otherwise it is stored in a 64bit array sorted by
+ * "a,b" pair. */
uint64_t k = HB_CODEPOINT_ENCODE3 (a, b, 0);
const uint64_t *v = hb_bsearch (k,
_hb_ucd_dm2_u64_map,
@@ -170,15 +176,22 @@
unsigned i = _hb_ucd_dm (ab);
+ /* If no data, there's no decomposition. */
if (likely (!i)) return false;
i--;
+ /* Check if it's a single-character decomposition. */
if (i < ARRAY_LENGTH (_hb_ucd_dm1_p0_map) + ARRAY_LENGTH (_hb_ucd_dm1_p2_map))
{
+ /* Single-character decompositions currently are only in plane 0 or plane 2. */
if (i < ARRAY_LENGTH (_hb_ucd_dm1_p0_map))
+ {
+ /* Plane 0. */
*a = _hb_ucd_dm1_p0_map[i];
+ }
else
{
+ /* Plane 2. */
i -= ARRAY_LENGTH (_hb_ucd_dm1_p0_map);
*a = 0x20000 | _hb_ucd_dm1_p2_map[i];
}
@@ -187,8 +200,10 @@
}
i -= ARRAY_LENGTH (_hb_ucd_dm1_p0_map) + ARRAY_LENGTH (_hb_ucd_dm1_p2_map);
+ /* Otherwise they are encoded either in a 32bit array or a 64bit array. */
if (i < ARRAY_LENGTH (_hb_ucd_dm2_u32_map))
{
+ /* 32bit array. */
uint32_t v = _hb_ucd_dm2_u32_map[i];
*a = HB_CODEPOINT_DECODE3_11_7_14_1 (v);
*b = HB_CODEPOINT_DECODE3_11_7_14_2 (v);
@@ -196,6 +211,7 @@
}
i -= ARRAY_LENGTH (_hb_ucd_dm2_u32_map);
+ /* 64bit array. */
uint64_t v = _hb_ucd_dm2_u64_map[i];
*a = HB_CODEPOINT_DECODE3_1 (v);
*b = HB_CODEPOINT_DECODE3_2 (v);
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index c1795dc..9a6471e 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -377,20 +377,30 @@
hb_destroy_func_t destroy) \
{ \
if (hb_object_is_immutable (ufuncs)) \
- return; \
+ goto fail; \
+ \
+ if (!func) \
+ { \
+ if (destroy) \
+ destroy (user_data); \
+ destroy = nullptr; \
+ user_data = ufuncs->parent->user_data.name; \
+ } \
\
if (ufuncs->destroy.name) \
ufuncs->destroy.name (ufuncs->user_data.name); \
\
- if (func) { \
+ if (func) \
ufuncs->func.name = func; \
- ufuncs->user_data.name = user_data; \
- ufuncs->destroy.name = destroy; \
- } else { \
+ else \
ufuncs->func.name = ufuncs->parent->func.name; \
- ufuncs->user_data.name = ufuncs->parent->user_data.name; \
- ufuncs->destroy.name = nullptr; \
- } \
+ ufuncs->user_data.name = user_data; \
+ ufuncs->destroy.name = destroy; \
+ return; \
+ \
+fail: \
+ if (destroy) \
+ destroy (user_data); \
}
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index 50f71ce..9648e02 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -355,7 +355,7 @@
return nullptr;
}
- memcpy(new_sfnt_data, orig_sfnt_data, length);
+ hb_memcpy(new_sfnt_data, orig_sfnt_data, length);
OT::name &name = StructAtOffset<OT::name> (new_sfnt_data, name_table_offset);
name.format = 0;
@@ -478,11 +478,11 @@
hb_font_t *font,
unsigned int font_size)
{
- memset (lf, 0, sizeof (*lf));
+ hb_memset (lf, 0, sizeof (*lf));
lf->lfHeight = - (int) font_size;
lf->lfCharSet = DEFAULT_CHARSET;
- memcpy (lf->lfFaceName, font->face->data.uniscribe->face_name, sizeof (lf->lfFaceName));
+ hb_memcpy (lf->lfFaceName, font->face->data.uniscribe->face_name, sizeof (lf->lfFaceName));
return true;
}
diff --git a/src/hb-vector.hh b/src/hb-vector.hh
index a6d9f6b..9b52f5c 100644
--- a/src/hb-vector.hh
+++ b/src/hb-vector.hh
@@ -35,7 +35,7 @@
template <typename Type,
bool sorted=false>
-struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty_t>::type
+struct hb_vector_t
{
typedef Type item_t;
static constexpr unsigned item_size = hb_static_size (Type);
@@ -53,9 +53,10 @@
hb_requires (hb_is_iterable (Iterable))>
hb_vector_t (const Iterable &o) : hb_vector_t ()
{
- if (hb_iter (o).is_random_access_iterator)
- alloc (hb_len (hb_iter (o)));
- hb_copy (o, *this);
+ auto iter = hb_iter (o);
+ if (iter.is_random_access_iterator)
+ alloc (hb_len (iter));
+ hb_copy (iter, *this);
}
hb_vector_t (const hb_vector_t &o) : hb_vector_t ()
{
@@ -83,6 +84,9 @@
allocated = length = 0;
arrayZ = nullptr;
}
+ void init0 ()
+ {
+ }
void fini ()
{
@@ -94,7 +98,11 @@
void reset ()
{
if (unlikely (in_error ()))
- allocated = length; // Big hack!
+ /* Big Hack! We don't know the true allocated size before
+ * an allocation failure happened. But we know it was at
+ * least as big as length. Restore it to that and continue
+ * as if error did not happen. */
+ allocated = length;
resize (0);
}
@@ -122,7 +130,7 @@
}
hb_bytes_t as_bytes () const
- { return hb_bytes_t ((const char *) arrayZ, length * item_size); }
+ { return hb_bytes_t ((const char *) arrayZ, get_size ()); }
bool operator == (const hb_vector_t &o) const { return as_array () == o.as_array (); }
bool operator != (const hb_vector_t &o) const { return !(*this == o); }
@@ -164,14 +172,10 @@
operator iter_t () const { return iter (); }
operator writer_t () { return writer (); }
- c_array_t sub_array (unsigned int start_offset, unsigned int count) const
- { return as_array ().sub_array (start_offset, count); }
- c_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
- { return as_array ().sub_array (start_offset, count); }
- array_t sub_array (unsigned int start_offset, unsigned int count)
- { return as_array ().sub_array (start_offset, count); }
- array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
- { return as_array ().sub_array (start_offset, count); }
+ /* Faster range-based for loop. */
+ Type *begin () const { return arrayZ; }
+ Type *end () const { return arrayZ + length; }
+
hb_sorted_array_t<Type> as_sorted_array ()
{ return hb_sorted_array (arrayZ, length); }
@@ -240,12 +244,11 @@
if (likely (new_array))
{
for (unsigned i = 0; i < length; i++)
+ {
new (std::addressof (new_array[i])) Type ();
- for (unsigned i = 0; i < (unsigned) length; i++)
new_array[i] = std::move (arrayZ[i]);
- unsigned old_length = length;
- shrink_vector (0);
- length = old_length;
+ arrayZ[i].~Type ();
+ }
hb_free (arrayZ);
}
return new_array;
@@ -277,7 +280,14 @@
copy_vector (const hb_vector_t &other)
{
length = other.length;
- hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size);
+#ifndef HB_OPTIMIZE_SIZE
+ if (sizeof (T) >= sizeof (long long))
+ /* This runs faster because of alignment. */
+ for (unsigned i = 0; i < length; i++)
+ arrayZ[i] = other.arrayZ[i];
+ else
+#endif
+ hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size);
}
template <typename T = Type,
hb_enable_if (!hb_is_trivially_copyable (T) &&
@@ -309,15 +319,6 @@
}
}
- template <typename T = Type,
- hb_enable_if (hb_is_trivially_destructible(T))>
- void
- shrink_vector (unsigned size)
- {
- length = size;
- }
- template <typename T = Type,
- hb_enable_if (!hb_is_trivially_destructible(T))>
void
shrink_vector (unsigned size)
{
@@ -328,17 +329,6 @@
}
}
- template <typename T = Type,
- hb_enable_if (hb_is_trivially_copy_assignable(T))>
- void
- shift_down_vector (unsigned i)
- {
- memmove (static_cast<void *> (&arrayZ[i - 1]),
- static_cast<void *> (&arrayZ[i]),
- (length - i) * sizeof (Type));
- }
- template <typename T = Type,
- hb_enable_if (!hb_is_trivially_copy_assignable(T))>
void
shift_down_vector (unsigned i)
{
@@ -381,16 +371,22 @@
return true;
}
- bool resize (int size_)
+ bool resize (int size_, bool initialize = true)
{
unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
if (!alloc (size))
return false;
if (size > length)
- grow_vector (size);
+ {
+ if (initialize)
+ grow_vector (size);
+ }
else if (size < length)
- shrink_vector (size);
+ {
+ if (initialize)
+ shrink_vector (size);
+ }
length = size;
return true;
@@ -399,13 +395,13 @@
Type pop ()
{
if (!length) return Null (Type);
- Type v = arrayZ[length - 1];
+ Type v {std::move (arrayZ[length - 1])};
arrayZ[length - 1].~Type ();
length--;
return v;
}
- void remove (unsigned int i)
+ void remove_ordered (unsigned int i)
{
if (unlikely (i >= length))
return;
@@ -414,6 +410,18 @@
length--;
}
+ template <bool Sorted = sorted,
+ hb_enable_if (!Sorted)>
+ void remove_unordered (unsigned int i)
+ {
+ if (unlikely (i >= length))
+ return;
+ if (i != length - 1)
+ arrayZ[i] = std::move (arrayZ[length - 1]);
+ arrayZ[length - 1].~Type ();
+ length--;
+ }
+
void shrink (int size_)
{
unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
@@ -425,10 +433,8 @@
/* Sorting API. */
- void qsort (int (*cmp)(const void*, const void*))
+ void qsort (int (*cmp)(const void*, const void*) = Type::cmp)
{ as_array ().qsort (cmp); }
- void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1)
- { as_array ().qsort (start, end); }
/* Unsorted search API. */
template <typename T>
diff --git a/src/hb-version.h b/src/hb-version.h
index 8d6ec66..1070262 100644
--- a/src/hb-version.h
+++ b/src/hb-version.h
@@ -41,26 +41,26 @@
*
* The major component of the library version available at compile-time.
*/
-#define HB_VERSION_MAJOR 5
+#define HB_VERSION_MAJOR 6
/**
* HB_VERSION_MINOR:
*
* The minor component of the library version available at compile-time.
*/
-#define HB_VERSION_MINOR 3
+#define HB_VERSION_MINOR 0
/**
* HB_VERSION_MICRO:
*
* The micro component of the library version available at compile-time.
*/
-#define HB_VERSION_MICRO 1
+#define HB_VERSION_MICRO 0
/**
* HB_VERSION_STRING:
*
* A string literal containing the library version available at compile-time.
*/
-#define HB_VERSION_STRING "5.3.1"
+#define HB_VERSION_STRING "6.0.0"
/**
* HB_VERSION_ATLEAST:
diff --git a/src/hb.hh b/src/hb.hh
index 8ec638a..410d090 100644
--- a/src/hb.hh
+++ b/src/hb.hh
@@ -126,6 +126,7 @@
/* Ignored intentionally. */
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED
#pragma GCC diagnostic ignored "-Wclass-memaccess"
+#pragma GCC diagnostic ignored "-Wcast-function-type-strict" // https://github.com/harfbuzz/harfbuzz/pull/3859#issuecomment-1295409126
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#pragma GCC diagnostic ignored "-Wformat-zero-length"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
diff --git a/src/main.cc b/src/main.cc
index 99e1528..bb18ebe 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -58,7 +58,8 @@
const char *data = hb_blob_get_data (blob, &length);
char output_path[255];
- sprintf (output_path, "out/svg-%u-%u.svg%s",
+ snprintf (output_path, sizeof output_path,
+ "out/svg-%u-%u.svg%s",
glyph_id,
face_index,
// append "z" if the content is gzipped, https://stackoverflow.com/a/6059405
@@ -112,7 +113,7 @@
const char *data = hb_blob_get_data (blob, &length);
char output_path[255];
- sprintf (output_path, "out/png-%u-%u-%u.png", glyph_id, strike, face_index);
+ snprintf (output_path, sizeof output_path, "out/png-%u-%u-%u.png", glyph_id, strike, face_index);
FILE *f = fopen (output_path, "wb");
fwrite (data, 1, length, f);
@@ -224,7 +225,7 @@
}
char output_path[255];
- sprintf (output_path, "out/colr-%u-%u-%u.svg", gid, palette, face_index);
+ snprintf (output_path, sizeof output_path, "out/colr-%u-%u-%u.svg", gid, palette, face_index);
FILE *f = fopen (output_path, "wb");
fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\""
" viewBox=\"%d %d %d %d\">\n",
@@ -274,7 +275,7 @@
}
char output_path[255];
- sprintf (output_path, "out/%u-%u.svg", face_index, gid);
+ snprintf (output_path, sizeof output_path, "out/%u-%u.svg", face_index, gid);
FILE *f = fopen (output_path, "wb");
fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\""
" viewBox=\"%d %d %d %d\"><path d=\"",
diff --git a/src/meson.build b/src/meson.build
index ba3470f..5d01d98 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -56,6 +56,7 @@
'hb-map.hh',
'hb-meta.hh',
'hb-ms-feature-ranges.hh',
+ 'hb-multimap.hh',
'hb-mutex.hh',
'hb-null.hh',
'hb-number.cc',
@@ -414,33 +415,40 @@
libharfbuzz_link_language = 'c'
+hb_features = configuration_data()
+
if conf.get('HAVE_FREETYPE', 0) == 1
hb_sources += hb_ft_sources
hb_headers += hb_ft_headers
harfbuzz_deps += [freetype_dep]
+ hb_features.set('HB_HAS_FREETYPE', 1)
endif
if conf.get('HAVE_GDI', 0) == 1
hb_sources += hb_gdi_sources
hb_headers += hb_gdi_headers
harfbuzz_deps += gdi_uniscribe_deps
+ hb_features.set('HB_HAS_GDI', 1)
endif
if conf.get('HAVE_GRAPHITE2', 0) == 1
hb_sources += hb_graphite2_sources
hb_headers += hb_graphite2_headers
harfbuzz_deps += [graphite2_dep, graphite_dep]
+ hb_features.set('HB_HAS_GRAPHITE', 1)
endif
if conf.get('HAVE_GLIB', 0) == 1
hb_sources += hb_glib_sources
hb_headers += hb_glib_headers
harfbuzz_deps += [glib_dep]
+ hb_features.set('HB_HAS_GLIB', 1)
endif
if conf.get('HAVE_UNISCRIBE', 0) == 1
hb_sources += hb_uniscribe_sources
hb_headers += hb_uniscribe_headers
+ hb_features.set('HB_HAS_UNISCRIBE', 1)
endif
if conf.get('HAVE_DIRECTWRITE', 0) == 1
@@ -448,12 +456,14 @@
hb_headers += hb_directwrite_headers
# hb-directwrite needs a C++ linker
libharfbuzz_link_language = 'cpp'
+ hb_features.set('HB_HAS_DIRECTWRITE', 1)
endif
if conf.get('HAVE_CORETEXT', 0) == 1
hb_sources += hb_coretext_sources
hb_headers += hb_coretext_headers
harfbuzz_deps += coretext_deps
+ hb_features.set('HB_HAS_CORETEXT', 1)
endif
have_icu = conf.get('HAVE_ICU', 0) == 1
@@ -463,8 +473,17 @@
hb_sources += hb_icu_sources
hb_headers += hb_icu_headers
harfbuzz_deps += [icu_dep]
+ hb_features.set('HB_HAS_ICU', 1)
endif
+hb_features_h = configure_file(input: 'hb-features.h.in',
+ output: 'hb-features.h',
+ configuration: hb_features,
+ install: true,
+ install_dir: get_option('includedir') / meson.project_name())
+
+# Base and default-included sources and headers
+
# harfbuzz
gen_def = find_program('gen-def.py')
@@ -580,6 +599,7 @@
'test-iter': ['test-iter.cc', 'hb-static.cc'],
'test-machinery': ['test-machinery.cc', 'hb-static.cc'],
'test-map': ['test-map.cc', 'hb-static.cc'],
+ 'test-multimap': ['test-multimap.cc', 'hb-static.cc'],
'test-number': ['test-number.cc', 'hb-number.cc'],
'test-ot-tag': ['hb-ot-tag.cc'],
'test-priority-queue': ['test-priority-queue.cc', 'hb-static.cc'],
@@ -657,8 +677,8 @@
have_gobject = conf.get('HAVE_GOBJECT', 0) == 1
cmake_config = configuration_data()
-cmake_config.set('libdir', '${prefix}/@0@'.format(get_option('libdir')))
-cmake_config.set('includedir', '${prefix}/@0@'.format(get_option('includedir')))
+cmake_config.set('libdir', get_option('prefix') / get_option('libdir'))
+cmake_config.set('includedir', get_option('prefix') / get_option('includedir'))
cmake_config.set('HB_LIBTOOL_VERSION_INFO', hb_libtool_version_info)
cmake_config.set('have_gobject', '@0@'.format(have_gobject))
configure_file(input: 'harfbuzz-config.cmake.in',
diff --git a/src/sample.py b/src/sample.py
index fd85048..5d04e80 100755
--- a/src/sample.py
+++ b/src/sample.py
@@ -2,6 +2,8 @@
import sys
import array
+import gi
+gi.require_version('HarfBuzz', '0.0')
from gi.repository import HarfBuzz as hb
from gi.repository import GLib
diff --git a/src/test-array.cc b/src/test-array.cc
index 6c88813..28cd023 100644
--- a/src/test-array.cc
+++ b/src/test-array.cc
@@ -70,6 +70,9 @@
int
main (int argc, char **argv)
{
+ /* The following fails on MSVC. */
+ // assert (sizeof (hb_array_t<int>) == sizeof (hb_sorted_array_t<int>));
+
test_reverse ();
test_reverse_range ();
test_reverse_invalid ();
diff --git a/src/test-buffer-serialize.cc b/src/test-buffer-serialize.cc
index bbebcbe..8a88792 100644
--- a/src/test-buffer-serialize.cc
+++ b/src/test-buffer-serialize.cc
@@ -43,10 +43,8 @@
#ifndef HB_NO_BUFFER_SERIALIZE
- if (argc != 2) {
- fprintf (stderr, "usage: %s font-file\n", argv[0]);
- exit (1);
- }
+ if (argc < 2)
+ argv[1] = (char *) "/dev/null";
hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]);
assert (blob);
@@ -58,7 +56,7 @@
hb_font_t *font = hb_font_create (face);
hb_face_destroy (face);
hb_font_set_scale (font, upem, upem);
- hb_ot_font_set_funcs (font);
+ //hb_ot_font_set_funcs (font);
#ifdef HAVE_FREETYPE
//hb_ft_font_set_funcs (font);
#endif
diff --git a/src/test-iter.cc b/src/test-iter.cc
index c37d1e7..bb966d4 100644
--- a/src/test-iter.cc
+++ b/src/test-iter.cc
@@ -319,13 +319,36 @@
;
/* The result should be something like 0->10, 1->11, ..., 9->19 */
assert (hb_map_get (result, 9) == 19);
+ hb_map_destroy (result);
+
+ /* Like above, but passing hb_set_t instead of hb_set_t * */
+ temp1 = 10;
+ temp2 = 0;
+ result =
+ + hb_iter (src)
+ | hb_map ([&] (int i) -> hb_set_t
+ {
+ hb_set_t set;
+ for (unsigned int i = 0; i < temp1; ++i)
+ hb_set_add (&set, i);
+ temp1++;
+ return set;
+ })
+ | hb_reduce ([&] (hb_map_t *acc, hb_set_t value) -> hb_map_t *
+ {
+ hb_map_set (acc, temp2++, hb_set_get_population (&value));
+ return acc;
+ }, hb_map_create ())
+ ;
+ /* The result should be something like 0->10, 1->11, ..., 9->19 */
+ assert (hb_map_get (result, 9) == 19);
+ hb_map_destroy (result);
unsigned int temp3 = 0;
+ hb_iter(src)
| hb_map([&] (int i) { return ++temp3; })
| hb_reduce([&] (float acc, int value) { return acc + value; }, 0)
;
- hb_map_destroy (result);
+ hb_iter (src)
| hb_drain
diff --git a/src/test-map.cc b/src/test-map.cc
index 357a8b0..da77a2f 100644
--- a/src/test-map.cc
+++ b/src/test-map.cc
@@ -179,20 +179,43 @@
hb_hashmap_t<vector_t, vector_t> m1;
- m1.set (vector_t (), vector_t ());
m1.set (vector_t (), vector_t {1});
m1.set (vector_t {1}, vector_t {2});
+ m1 << hb_pair_t<vector_t, vector_t> {vector_t {2}, vector_t ()};
+
assert (m1.get (vector_t ()) == vector_t {1});
assert (m1.get (vector_t {1}) == vector_t {2});
}
+ /* Test moving values */
+ {
+ using vector_t = hb_vector_t<unsigned>;
+
+ hb_hashmap_t<vector_t, vector_t> m1;
+ vector_t v {3};
+ assert (v.length == 1);
+ m1 << hb_pair_t<vector_t, vector_t> {vector_t {3}, v};
+ assert (v.length == 1);
+ m1 << hb_pair_t<vector_t, vector_t&&> {vector_t {4}, std::move (v)};
+ assert (v.length == 0);
+ m1 << hb_pair_t<vector_t&&, vector_t> {vector_t {4}, vector_t {5}};
+ m1 << hb_pair_t<vector_t&&, vector_t&&> {vector_t {4}, vector_t {5}};
+
+ hb_hashmap_t<vector_t, vector_t> m2;
+ vector_t v2 {3};
+ m2.set (vector_t {4}, v2);
+ assert (v2.length == 1);
+ m2.set (vector_t {5}, std::move (v2));
+ assert (v2.length == 0);
+ }
+
/* Test hb::shared_ptr. */
- hb_hash (hb::shared_ptr<hb_set_t> ());
{
hb_hashmap_t<hb::shared_ptr<hb_set_t>, hb::shared_ptr<hb_set_t>> m;
- m.get (hb::shared_ptr<hb_set_t> ());
+ m.set (hb::shared_ptr<hb_set_t> (hb_set_get_empty ()),
+ hb::shared_ptr<hb_set_t> (hb_set_get_empty ()));
m.get (hb::shared_ptr<hb_set_t> (hb_set_get_empty ()));
m.iter ();
m.keys ();
@@ -202,12 +225,14 @@
m.values_ref ();
}
/* Test hb::unique_ptr. */
- hb_hash (hb::unique_ptr<hb_set_t> ());
{
hb_hashmap_t<hb::unique_ptr<hb_set_t>, hb::unique_ptr<hb_set_t>> m;
- m.get (hb::unique_ptr<hb_set_t> ());
+ m.set (hb::unique_ptr<hb_set_t> (hb_set_get_empty ()),
+ hb::unique_ptr<hb_set_t> (hb_set_get_empty ()));
m.get (hb::unique_ptr<hb_set_t> (hb_set_get_empty ()));
+ hb::unique_ptr<hb_set_t> *v;
+ m.has (hb::unique_ptr<hb_set_t> (hb_set_get_empty ()), &v);
m.iter_ref ();
m.keys_ref ();
m.values_ref ();
@@ -234,11 +259,48 @@
hb::shared_ptr<hb_map_t> p1 {m1};
hb::shared_ptr<hb_map_t> p2 {m2};
m.set (p1,1);
-
+
assert (m.has (p2));
m1->set (2,4);
assert (!m.has (p2));
}
+ /* Test value type with hb_bytes_t. */
+ {
+ hb_hashmap_t<int, hb_bytes_t> m;
+ char c_str[] = "Test";
+ hb_bytes_t bytes (c_str);
+
+ m.set (1, bytes);
+ assert (m.has (1));
+ }
+ /* Test operators. */
+ {
+ hb_map_t m1, m2, m3;
+ m1.set (1, 2);
+ m1.set (2, 4);
+ m2.set (1, 2);
+ m2.set (2, 4);
+ m3.set (1, 3);
+ m3.set (3, 5);
+
+ assert (m1 == m2);
+ assert (m1 != m3);
+ assert (!(m2 == m3));
+
+ m2 = m3;
+ assert (m2.has (1));
+ assert (!m2.has (2));
+ assert (m2.has (3));
+
+ assert (m3.has (3));
+ }
+ /* Test reset. */
+ {
+ hb_hashmap_t<int, hb_set_t> m;
+ m.set (1, hb_set_t {1, 2, 3});
+ m.reset ();
+ }
+
return 0;
}
diff --git a/src/test-multimap.cc b/src/test-multimap.cc
new file mode 100644
index 0000000..8cd8f52
--- /dev/null
+++ b/src/test-multimap.cc
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2022 Behdad Esfahbod
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "hb.hh"
+#include "hb-multimap.hh"
+
+int
+main (int argc, char **argv)
+{
+ hb_multimap_t m;
+
+ assert (m.get (10).length == 0);
+
+ m.add (10, 11);
+ assert (m.get (10).length == 1);
+
+ m.add (10, 12);
+ assert (m.get (10).length == 2);
+
+ m.add (10, 13);
+ assert (m.get (10).length == 3);
+ assert (m.get (10)[0] == 11);
+ assert (m.get (10)[1] == 12);
+ assert (m.get (10)[2] == 13);
+
+ assert (m.get (11).length == 0);
+ m.add (11, 14);
+ assert (m.get (10).length == 3);
+ assert (m.get (11).length == 1);
+ assert (m.get (12).length == 0);
+ assert (m.get (10)[0] == 11);
+ assert (m.get (10)[1] == 12);
+ assert (m.get (10)[2] == 13);
+ assert (m.get (11)[0] == 14);
+ assert (m.get (12)[0] == 0); // Array fallback value
+
+ return 0;
+}
diff --git a/src/test-repacker.cc b/src/test-repacker.cc
index cd8789f..94ff084 100644
--- a/src/test-repacker.cc
+++ b/src/test-repacker.cc
@@ -35,7 +35,7 @@
hb_serialize_context_t* c)
{
char* obj = c->allocate_size<char> (len);
- memcpy (obj, value, len);
+ hb_memcpy (obj, value, len);
}
static void start_object(const char* tag,
@@ -1476,6 +1476,7 @@
graph_t graph (c.object_graph ());
graph.sort_shortest_distance ();
+ assert (!graph.in_error ());
assert(strncmp (graph.object (4).head, "abc", 3) == 0);
assert(graph.object (4).real_links.length == 3);
diff --git a/src/test-set.cc b/src/test-set.cc
index 983a159..e760c98 100644
--- a/src/test-set.cc
+++ b/src/test-set.cc
@@ -34,6 +34,7 @@
hb_set_t v1 {1, 2};
hb_set_t v2 {v1};
assert (v1.get_population () == 2);
+ assert (hb_len (hb_iter (v1)) == 2);
assert (v2.get_population () == 2);
}
@@ -51,6 +52,7 @@
hb_set_t s {1, 2};
hb_set_t v (std::move (s));
assert (s.get_population () == 0);
+ assert (hb_len (hb_iter (s)) == 0);
assert (v.get_population () == 2);
}
@@ -86,11 +88,14 @@
hb_set_t s;
s.add (18);
- s.add (12);
+ s << 12;
+
+ /* Sink a range. */
+ s << hb_pair_t<hb_codepoint_t, hb_codepoint_t> {1, 3};
hb_set_t v (hb_iter (s));
- assert (v.get_population () == 2);
+ assert (v.get_population () == 5);
}
/* Test initializing from initializer list and swapping. */
diff --git a/src/test-vector.cc b/src/test-vector.cc
index 37bec30..65e51c6 100644
--- a/src/test-vector.cc
+++ b/src/test-vector.cc
@@ -26,12 +26,14 @@
#include "hb.hh"
#include "hb-vector.hh"
#include "hb-set.hh"
+#include "hb-map.hh"
#include <string>
int
main (int argc, char **argv)
{
+ assert (sizeof (hb_vector_t<int>) == sizeof (hb_sorted_vector_t<int>));
/* Test copy constructor. */
{
@@ -160,7 +162,24 @@
v2 = v;
- v2.remove (50);
+ v2.remove_ordered (50);
+ v2.remove_unordered (50);
+ }
+
+ {
+ hb_vector_t<hb_set_t> v;
+ hb_set_t s {1, 5, 7};
+ v.push (s);
+ v << s;
+ assert (s.get_population () == 3);
+ v << std::move (s);
+ assert (s.get_population () == 0);
+ }
+
+ {
+ hb_vector_t<hb_map_t> v;
+ hb_map_t m;
+ v.push (m);
}
return 0;
diff --git a/subprojects/freetype2.wrap b/subprojects/freetype2.wrap
index 43ab8fa..1ff89ec 100644
--- a/subprojects/freetype2.wrap
+++ b/subprojects/freetype2.wrap
@@ -1,7 +1,9 @@
-[wrap-git]
-directory=freetype
-url=https://gitlab.freedesktop.org/freetype/freetype.git
-revision=VER-2-11-0
+[wrap-file]
+directory = freetype-2.12.1
+source_url = https://download.savannah.gnu.org/releases/freetype/freetype-2.12.1.tar.xz
+source_filename = freetype-2.12.1.tar.xz
+source_hash = 4766f20157cc4cf0cd292f80bf917f92d1c439b243ac3018debf6b9140c41a7f
+wrapdb_version = 2.12.1-2
[provide]
freetype2 = freetype_dep
diff --git a/subprojects/glib.wrap b/subprojects/glib.wrap
index 9143090..a865af4 100644
--- a/subprojects/glib.wrap
+++ b/subprojects/glib.wrap
@@ -1,10 +1,11 @@
-[wrap-git]
-directory=glib
-url=https://gitlab.gnome.org/GNOME/glib.git
-depth=1
[email protected]:GNOME/glib.git
-revision=2.58.1
+[wrap-file]
+directory = glib-2.74.1
+source_url = https://download.gnome.org/sources/glib/2.74/glib-2.74.1.tar.xz
+source_fallback_url = https://ftp.acc.umu.se/pub/gnome/sources/glib/2.74/glib-2.74.1.tar.xz
+source_filename = glib-2.74.1.tar.xz
+source_hash = 0ab981618d1db47845e56417b0d7c123f81a3427b2b9c93f5a46ff5bbb964964
+wrapdb_version = 2.74.1-1
[provide]
-glib-2.0 = libglib_dep
-gobject-2.0 = libgobject_dep
+dependency_names = gthread-2.0, gobject-2.0, gmodule-no-export-2.0, gmodule-export-2.0, gmodule-2.0, glib-2.0, gio-2.0, gio-windows-2.0, gio-unix-2.0
+program_names = glib-genmarshal, glib-mkenums, glib-compile-schemas, glib-compile-resources, gio-querymodules, gdbus-codegen
diff --git a/subprojects/google-benchmark.wrap b/subprojects/google-benchmark.wrap
index 268ddf9..6205cd7 100644
--- a/subprojects/google-benchmark.wrap
+++ b/subprojects/google-benchmark.wrap
@@ -1,11 +1,12 @@
[wrap-file]
-directory = benchmark-1.6.0
-source_url = https://github.com/google/benchmark/archive/refs/tags/v1.6.0.tar.gz
-source_filename = benchmark-1.6.0.tar.gz
-source_hash = 1f71c72ce08d2c1310011ea6436b31e39ccab8c2db94186d26657d41747c85d6
-patch_filename = google-benchmark_1.6.0-1_patch.zip
-patch_url = https://wrapdb.mesonbuild.com/v2/google-benchmark_1.6.0-1/get_patch
-patch_hash = f2feff0641a5ebf6b893a4f49ea0bff566ba866ee993c5c3aef62ff40cdc6b14
+directory = benchmark-1.7.1
+source_url = https://github.com/google/benchmark/archive/refs/tags/v1.7.1.tar.gz
+source_filename = benchmark-1.7.1.tar.gz
+source_hash = 6430e4092653380d9dc4ccb45a1e2dc9259d581f4866dc0759713126056bc1d7
+patch_filename = google-benchmark_1.7.1-1_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/google-benchmark_1.7.1-1/get_patch
+patch_hash = 9c6694328ac971cd781aa67c45c64291c087f118e23b75946f52670caacf49b7
+wrapdb_version = 1.7.1-1
[provide]
benchmark = google_benchmark_dep
diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap
new file mode 100644
index 0000000..23af071
--- /dev/null
+++ b/subprojects/zlib.wrap
@@ -0,0 +1,12 @@
+[wrap-file]
+directory = zlib-1.2.13
+source_url = http://zlib.net/fossils/zlib-1.2.13.tar.gz
+source_filename = zlib-1.2.13.tar.gz
+source_hash = b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30
+patch_filename = zlib_1.2.13-2_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.2.13-2/get_patch
+patch_hash = a7abea3ad65dc2c291ad5fbbf5355d0585a7f7b8c935d4a74335b8fe18684506
+wrapdb_version = 1.2.13-2
+
+[provide]
+zlib = zlib_dep
diff --git a/test/api/fonts/nameID.override.expected.ttf b/test/api/fonts/nameID.override.expected.ttf
new file mode 100644
index 0000000..d17ea83
--- /dev/null
+++ b/test/api/fonts/nameID.override.expected.ttf
Binary files differ
diff --git a/test/api/test-subset-nameids.c b/test/api/test-subset-nameids.c
index b58a86c..e51b470 100644
--- a/test/api/test-subset-nameids.c
+++ b/test/api/test-subset-nameids.c
@@ -67,6 +67,44 @@
hb_face_destroy (face_expected);
}
+#ifdef HB_EXPERIMENTAL_API
+static void
+test_subset_name_overrides (void)
+{
+ hb_face_t *face_origin = hb_test_open_font_file ("fonts/nameID.origin.ttf");
+ hb_face_t *face_expected = hb_test_open_font_file ("fonts/nameID.override.expected.ttf");
+
+ char str1[] = "Roboto Test";
+ char str1_3[] = "Roboto Test unicode platform";
+ char str2[] = "Bold";
+ char str6[] = "Roboto-Bold";
+ char str12[] = "Non ascii test Ü";
+ char str16[] = "Roboto-test-inserting";
+
+ hb_set_t *name_ids = hb_set_create();
+ hb_face_t *face_subset;
+ hb_set_add_range (name_ids, 0, 15);
+
+ hb_subset_input_t *subset_input = hb_subset_test_create_input_from_nameids (name_ids);
+ hb_subset_input_override_name_table (subset_input, 1, 1, 0, 0, str1, -1);
+ hb_subset_input_override_name_table (subset_input, 1, 3, 1, 0x409, str1_3, -1);
+ hb_subset_input_override_name_table (subset_input, 2, 1, 0, 0, str2, 4);
+ hb_subset_input_override_name_table (subset_input, 6, 1, 0, 0, str6, -1);
+ hb_subset_input_override_name_table (subset_input, 12, 1, 0, 0, str12, -1);
+ hb_subset_input_override_name_table (subset_input, 14, 1, 0, 0, NULL, -1);
+ hb_subset_input_override_name_table (subset_input, 16, 1, 0, 0, str16, -1);
+
+ face_subset = hb_subset_test_create_subset (face_origin, subset_input);
+ hb_set_destroy (name_ids);
+
+ hb_subset_test_check (face_expected, face_subset, HB_TAG ('n','a','m','e'));
+
+ hb_face_destroy (face_subset);
+ hb_face_destroy (face_origin);
+ hb_face_destroy (face_expected);
+}
+#endif
+
int
main (int argc, char **argv)
{
@@ -74,6 +112,9 @@
hb_test_add (test_subset_nameids);
hb_test_add (test_subset_nameids_with_dup_strs);
+#ifdef HB_EXPERIMENTAL_API
+ hb_test_add (test_subset_name_overrides);
+#endif
return hb_test_run();
}
diff --git a/test/api/test-unicode.c b/test/api/test-unicode.c
index 4ec718b..857308b 100644
--- a/test/api/test-unicode.c
+++ b/test/api/test-unicode.c
@@ -754,9 +754,9 @@
/* Since uf is immutable now, the following setter should do nothing. */
p->func_setter (uf, (get_func_t) a_is_for_arabic_get_script, &data[1], free_up);
- g_assert (data[0].freed && !data[1].freed);
+ g_assert (data[0].freed && data[1].freed);
hb_unicode_funcs_destroy (uf);
- g_assert (data[0].freed && !data[1].freed);
+ g_assert (data[0].freed && data[1].freed);
}
}
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-6635625931735040 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-6635625931735040
new file mode 100644
index 0000000..333ebaa
--- /dev/null
+++ b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-6635625931735040
Binary files differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5845846876356608 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5845846876356608
new file mode 100644
index 0000000..faf2e85
--- /dev/null
+++ b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5845846876356608
Binary files differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-6164014466203648 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-6164014466203648
new file mode 100644
index 0000000..3a15ab2
--- /dev/null
+++ b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-6164014466203648
Binary files differ
diff --git a/test/fuzzing/graphs/clusterfuzz-testcase-minimized-hb-repacker-fuzzer-5390364397928448 b/test/fuzzing/graphs/clusterfuzz-testcase-minimized-hb-repacker-fuzzer-5390364397928448
new file mode 100644
index 0000000..54ee816
--- /dev/null
+++ b/test/fuzzing/graphs/clusterfuzz-testcase-minimized-hb-repacker-fuzzer-5390364397928448
Binary files differ
diff --git a/test/fuzzing/graphs/clusterfuzz-testcase-minimized-hb-repacker-fuzzer-6014493291577344 b/test/fuzzing/graphs/clusterfuzz-testcase-minimized-hb-repacker-fuzzer-6014493291577344
new file mode 100644
index 0000000..a29d1e2
--- /dev/null
+++ b/test/fuzzing/graphs/clusterfuzz-testcase-minimized-hb-repacker-fuzzer-6014493291577344
Binary files differ
diff --git a/test/fuzzing/graphs/clusterfuzz-testcase-minimized-hb-repacker-fuzzer-6714085985353728 b/test/fuzzing/graphs/clusterfuzz-testcase-minimized-hb-repacker-fuzzer-6714085985353728
new file mode 100644
index 0000000..aeee90b
--- /dev/null
+++ b/test/fuzzing/graphs/clusterfuzz-testcase-minimized-hb-repacker-fuzzer-6714085985353728
Binary files differ
diff --git a/test/fuzzing/graphs/crash-3bf72494aa4c9f8cbbcbf887fdc2a2858c87feb4 b/test/fuzzing/graphs/crash-3bf72494aa4c9f8cbbcbf887fdc2a2858c87feb4
new file mode 100644
index 0000000..ff8da7b
--- /dev/null
+++ b/test/fuzzing/graphs/crash-3bf72494aa4c9f8cbbcbf887fdc2a2858c87feb4
Binary files differ
diff --git a/test/fuzzing/graphs/crash-442bfac994a3d9929cf06262ae9fb00f6ee1f774 b/test/fuzzing/graphs/crash-442bfac994a3d9929cf06262ae9fb00f6ee1f774
new file mode 100644
index 0000000..0160ce5
--- /dev/null
+++ b/test/fuzzing/graphs/crash-442bfac994a3d9929cf06262ae9fb00f6ee1f774
Binary files differ
diff --git a/test/fuzzing/graphs/leak-a77f29b25edb873729f3ab120148fdb213cfa527 b/test/fuzzing/graphs/leak-a77f29b25edb873729f3ab120148fdb213cfa527
new file mode 100644
index 0000000..58b4075
--- /dev/null
+++ b/test/fuzzing/graphs/leak-a77f29b25edb873729f3ab120148fdb213cfa527
Binary files differ
diff --git a/test/fuzzing/graphs/noto_nastaliq_urdu b/test/fuzzing/graphs/noto_nastaliq_urdu
new file mode 100644
index 0000000..2e3cab8
--- /dev/null
+++ b/test/fuzzing/graphs/noto_nastaliq_urdu
Binary files differ
diff --git a/test/fuzzing/hb-repacker-fuzzer.cc b/test/fuzzing/hb-repacker-fuzzer.cc
new file mode 100644
index 0000000..0b06fd2
--- /dev/null
+++ b/test/fuzzing/hb-repacker-fuzzer.cc
@@ -0,0 +1,145 @@
+#include "hb-fuzzer.hh"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "hb-subset-repacker.h"
+
+typedef struct
+{
+ uint16_t parent;
+ uint16_t child;
+ uint16_t position;
+ uint8_t width;
+} link_t;
+
+/* The fuzzer seed contains a serialized representation of a object graph which forms
+ * the input graph to the repacker call. The binary format is:
+ *
+ * table tag: 4 bytes
+ * number of objects: 2 bytes
+ * objects[number of objects]:
+ * blob size: 2 bytes
+ * blob: blob size bytes
+ * num of real links: 2 bytes
+ * links[number of real links]: link_t struct
+ *
+ * TODO(garretrieger): add optional virtual links
+ */
+
+template <typename T>
+bool read(const uint8_t** data, size_t* size, T* out)
+{
+ if (*size < sizeof (T)) return false;
+
+ memcpy(out, *data, sizeof (T));
+
+ *data += sizeof (T);
+ *size -= sizeof (T);
+
+ return true;
+}
+
+void cleanup (hb_object_t* objects, uint16_t num_objects)
+{
+ for (uint32_t i = 0; i < num_objects; i++)
+ {
+ free (objects[i].head);
+ free (objects[i].real_links);
+ }
+}
+
+void add_links_to_objects (hb_object_t* objects, uint16_t num_objects,
+ link_t* links, uint16_t num_links)
+{
+ unsigned* link_count = (unsigned*) calloc (num_objects, sizeof (unsigned));
+
+ for (uint32_t i = 0; i < num_links; i++)
+ {
+ uint16_t parent_idx = links[i].parent;
+ link_count[parent_idx]++;
+ }
+
+ for (uint32_t i = 0; i < num_objects; i++)
+ {
+ objects[i].num_real_links = link_count[i];
+ objects[i].real_links = (hb_link_t*) calloc (link_count[i], sizeof (hb_link_t));
+ objects[i].num_virtual_links = 0;
+ objects[i].virtual_links = nullptr;
+ }
+
+ for (uint32_t i = 0; i < num_links; i++)
+ {
+ uint16_t parent_idx = links[i].parent;
+ uint16_t child_idx = links[i].child + 1; // All indices are shifted by 1 by the null object.
+ hb_link_t* link = &(objects[parent_idx].real_links[link_count[parent_idx] - 1]);
+
+ link->width = links[i].width;
+ link->position = links[i].position;
+ link->objidx = child_idx;
+ link_count[parent_idx]--;
+ }
+
+ free (link_count);
+}
+
+extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
+{
+ // TODO(garretrieger): move graph validity checks into repacker graph creation.
+ alloc_state = _fuzzing_alloc_state (data, size);
+
+ uint16_t num_objects = 0;
+ hb_object_t* objects = nullptr;
+
+ uint16_t num_real_links = 0;
+ link_t* links = nullptr;
+
+ hb_tag_t table_tag;
+ if (!read<hb_tag_t> (&data, &size, &table_tag)) goto end;
+ if (!read<uint16_t> (&data, &size, &num_objects)) goto end;
+
+ objects = (hb_object_t*) calloc (num_objects, sizeof (hb_object_t));
+ for (uint32_t i = 0; i < num_objects; i++)
+ {
+ uint16_t blob_size;
+ if (!read<uint16_t> (&data, &size, &blob_size)) goto end;
+ if (size < blob_size) goto end;
+
+ char* copy = (char*) calloc (1, blob_size);
+ memcpy (copy, data, blob_size);
+ objects[i].head = (char*) copy;
+ objects[i].tail = (char*) (copy + blob_size);
+
+ size -= blob_size;
+ data += blob_size;
+ }
+
+ if (!read<uint16_t> (&data, &size, &num_real_links)) goto end;
+ links = (link_t*) calloc (num_real_links, sizeof (link_t));
+ for (uint32_t i = 0; i < num_real_links; i++)
+ {
+ if (!read<link_t> (&data, &size, &links[i])) goto end;
+
+ if (links[i].parent >= num_objects)
+ goto end;
+ }
+
+ add_links_to_objects (objects, num_objects,
+ links, num_real_links);
+
+ hb_blob_destroy (hb_subset_repack_or_fail (table_tag,
+ objects,
+ num_objects));
+
+end:
+ if (objects)
+ {
+ cleanup (objects, num_objects);
+ free (objects);
+ }
+ free (links);
+
+ return 0;
+}
diff --git a/test/fuzzing/meson.build b/test/fuzzing/meson.build
index 3aba9eb..d38ca8f 100644
--- a/test/fuzzing/meson.build
+++ b/test/fuzzing/meson.build
@@ -5,6 +5,10 @@
'hb-draw-fuzzer.cc',
]
+if get_option('experimental_api')
+ tests += 'hb-repacker-fuzzer.cc'
+endif
+
foreach file_name : tests
test_name = file_name.split('.')[0]
@@ -19,6 +23,10 @@
extra_cpp_args += '-DHB_IS_IN_FUZZER'
endif
+ if get_option('experimental_api')
+ extra_cpp_args += '-DHB_EXPERIMENTAL_API'
+ endif
+
exe = executable(test_name, sources,
cpp_args: cpp_args + extra_cpp_args,
include_directories: [incconfig, incsrc],
@@ -55,6 +63,20 @@
suite: ['fuzzing', 'slow'],
)
+if get_option('experimental_api')
+ test('repacker_fuzzer', find_program('run-repacker-fuzzer-tests.py'),
+ args: [
+ hb_repacker_fuzzer_exe,
+ ],
+ # as the tests are ran concurrently let's raise acceptable time here
+ # ideally better to break and let meson handles them in parallel
+ timeout: 300,
+ workdir: meson.current_build_dir() / '..' / '..',
+ env: env,
+ suite: ['fuzzing', 'slow'],
+ )
+endif
+
test('draw_fuzzer', find_program('run-draw-fuzzer-tests.py'),
args: [
hb_draw_fuzzer_exe,
diff --git a/test/fuzzing/run-repacker-fuzzer-tests.py b/test/fuzzing/run-repacker-fuzzer-tests.py
new file mode 100644
index 0000000..85a23e1
--- /dev/null
+++ b/test/fuzzing/run-repacker-fuzzer-tests.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+
+import sys, os, subprocess, tempfile, shutil
+
+
+def cmd (command):
+ # https://stackoverflow.com/a/4408409 as we might have huge output sometimes
+ with tempfile.TemporaryFile () as tempf:
+ p = subprocess.Popen (command, stderr=tempf)
+
+ try:
+ p.wait ()
+ tempf.seek (0)
+ text = tempf.read ()
+
+ #TODO: Detect debug mode with a better way
+ is_debug_mode = b"SANITIZE" in text
+
+ return ("" if is_debug_mode else text.decode ("utf-8").strip ()), p.returncode
+ except subprocess.TimeoutExpired:
+ return 'error: timeout, ' + ' '.join (command), 1
+
+
+srcdir = os.getenv ("srcdir", ".")
+EXEEXT = os.getenv ("EXEEXT", "")
+top_builddir = os.getenv ("top_builddir", ".")
+hb_repacker_fuzzer = os.path.join (top_builddir, "hb-repacker-fuzzer" + EXEEXT)
+
+if not os.path.exists (hb_repacker_fuzzer):
+ if len (sys.argv) < 2 or not os.path.exists (sys.argv[1]):
+ sys.exit ("""Failed to find hb-repacker-fuzzer binary automatically,
+please provide it as the first argument to the tool""")
+
+ hb_repacker_fuzzer = sys.argv[1]
+
+print ('hb_repacker_fuzzer:', hb_repacker_fuzzer)
+fails = 0
+
+valgrind = None
+if os.getenv ('RUN_VALGRIND', ''):
+ valgrind = shutil.which ('valgrind')
+ if valgrind is None:
+ sys.exit ("""Valgrind requested but not found.""")
+
+def run_dir (parent_path):
+ global fails
+ for file in os.listdir (parent_path):
+ path = os.path.join(parent_path, file)
+ print ("running repacker fuzzer against %s" % path)
+ if valgrind:
+ text, returncode = cmd ([valgrind, '--leak-check=full', '--error-exitcode=1', hb_repacker_fuzzer, path])
+ else:
+ text, returncode = cmd ([hb_repacker_fuzzer, path])
+ if 'error' in text:
+ returncode = 1
+
+ if (not valgrind or returncode) and text.strip ():
+ print (text)
+
+ if returncode != 0:
+ print ("failed for %s" % path)
+ fails = fails + 1
+
+
+run_dir (os.path.join (srcdir, "graphs"))
+
+if fails:
+ sys.exit ("%d repacker fuzzer related tests failed." % fails)
diff --git a/test/shape/data/in-house/fonts/5f73fff1ffc07b5a99a90c0909609f2b09fef274.ttf b/test/shape/data/in-house/fonts/5f73fff1ffc07b5a99a90c0909609f2b09fef274.ttf
new file mode 100644
index 0000000..f94d2aa
--- /dev/null
+++ b/test/shape/data/in-house/fonts/5f73fff1ffc07b5a99a90c0909609f2b09fef274.ttf
Binary files differ
diff --git a/test/shape/data/in-house/fonts/9d8c53cb64b8747abdd2b70755cce2ee0eb42ef7.ttf b/test/shape/data/in-house/fonts/9d8c53cb64b8747abdd2b70755cce2ee0eb42ef7.ttf
new file mode 100644
index 0000000..9c9f942
--- /dev/null
+++ b/test/shape/data/in-house/fonts/9d8c53cb64b8747abdd2b70755cce2ee0eb42ef7.ttf
Binary files differ
diff --git a/test/shape/data/in-house/fonts/a232bb734d4c6c898a44506547d19768f0eba6a6.ttf b/test/shape/data/in-house/fonts/a232bb734d4c6c898a44506547d19768f0eba6a6.ttf
new file mode 100644
index 0000000..e0325bb
--- /dev/null
+++ b/test/shape/data/in-house/fonts/a232bb734d4c6c898a44506547d19768f0eba6a6.ttf
Binary files differ
diff --git a/test/shape/data/in-house/tests/indic-special-cases.tests b/test/shape/data/in-house/tests/indic-special-cases.tests
index 016f894..d563dec 100644
--- a/test/shape/data/in-house/tests/indic-special-cases.tests
+++ b/test/shape/data/in-house/tests/indic-special-cases.tests
@@ -2,3 +2,7 @@
../fonts/3cae6bfe5b57c07ba81ddbd54c02fe4f3a1e3bf6.ttf;;U+0CB0,U+200D,U+0CCD,U+0C95;[gid2=0+1334|gid6=0+358]
../fonts/3cae6bfe5b57c07ba81ddbd54c02fe4f3a1e3bf6.ttf;;U+0CB0,U+0CCD,U+200D,U+0C95;[gid2=0+1334|gid6=0+358]
../fonts/e716f6bd00a108d186b7e9f47b4515565f784f36.ttf;;U+0C1A,U+0C3F,U+0C32,U+0C4D,U+0C15,U+0C42,U+0C30,U+0C4D;[civoweltelu=0+766|latelu=2+709|uuvowelsigntelu=2+661|kasubscripttelu=2+483|rahalanttelu=6+593]
+../fonts/9d8c53cb64b8747abdd2b70755cce2ee0eb42ef7.ttf;;U+0915,U+093F,U+094E,U+093C;[uni094E=0+273|uni093C=0+0|ivowelsign03deva=0+259|uni0915=0+762]
+../fonts/9d8c53cb64b8747abdd2b70755cce2ee0eb42ef7.ttf;;U+0915,U+093F,U+093C,U+094E;[uni094E=0+273|ivowelsign00deva=0+259|uni093C=0+0|uni0915=0+762]
+../fonts/5f73fff1ffc07b5a99a90c0909609f2b09fef274.ttf;;U+0A15,U+0A40,U+0A02;[uni0A15=0+505|uni0A40=0+427|uni0A02=0+0]
+../fonts/5f73fff1ffc07b5a99a90c0909609f2b09fef274.ttf;;U+0A15,U+0A02,U+0A40;[uni0A15=0+505|uni0A02=0+0|uni0A40=0+427]
diff --git a/test/shape/data/in-house/tests/myanmar-misc.tests b/test/shape/data/in-house/tests/myanmar-misc.tests
index 5273863..8ba0be4 100644
--- a/test/shape/data/in-house/tests/myanmar-misc.tests
+++ b/test/shape/data/in-house/tests/myanmar-misc.tests
@@ -1 +1,2 @@
../fonts/065b01e54f35f0d849fd43bd5b936212739a50cb.ttf;;U+101A,U+1035;[ya_e_above=0+1000]
+../fonts/a232bb734d4c6c898a44506547d19768f0eba6a6.ttf;;U+1000,U+1031,U+1084;[e_shn=0+592|_e=0+618|ka=0+1124]
diff --git a/test/subset/data/Makefile.am b/test/subset/data/Makefile.am
index 8ee6923..e6d2325 100644
--- a/test/subset/data/Makefile.am
+++ b/test/subset/data/Makefile.am
@@ -7,6 +7,7 @@
EXTRA_DIST += \
$(TESTS) \
+ $(DISABLED_TESTS) \
expected/32bit_var_store \
expected/basics \
expected/full-font \
@@ -55,6 +56,10 @@
expected/math \
expected/math_coverage_offset \
expected/post \
+ expected/full_instance \
+ expected/instance_feature_variations \
+ expected/instantiate_glyf \
+ expected/pin_all_at_default \
fonts \
profiles \
$(NULL)
diff --git a/test/subset/data/Makefile.sources b/test/subset/data/Makefile.sources
index 798db64..845a77e 100644
--- a/test/subset/data/Makefile.sources
+++ b/test/subset/data/Makefile.sources
@@ -47,6 +47,10 @@
tests/math.tests \
tests/math_coverage_offset.tests \
tests/post.tests \
+ tests/full_instance.tests \
+ tests/instance_feature_variations.tests \
+ tests/instantiate_glyf.tests \
+ tests/pin_all_at_default.tests \
$(NULL)
# TODO: re-enable once colrv1 subsetting is stabilized.
@@ -57,5 +61,6 @@
XFAIL_TESTS = \
$(NULL)
+# Disabled because instancing is only available w/ experimental API on.
DISABLED_TESTS = \
$(NULL)
diff --git a/test/subset/data/expected/full_instance/Roboto-Variable.no-prune-unicode-ranges.retain-all-codepoint.wght=150,wdth=80.ttf b/test/subset/data/expected/full_instance/Roboto-Variable.no-prune-unicode-ranges.retain-all-codepoint.wght=150,wdth=80.ttf
new file mode 100644
index 0000000..ca2aeef
--- /dev/null
+++ b/test/subset/data/expected/full_instance/Roboto-Variable.no-prune-unicode-ranges.retain-all-codepoint.wght=150,wdth=80.ttf
Binary files differ
diff --git a/test/subset/data/expected/full_instance/Roboto-Variable.no-prune-unicode-ranges.retain-all-codepoint.wght=300,wdth=90.ttf b/test/subset/data/expected/full_instance/Roboto-Variable.no-prune-unicode-ranges.retain-all-codepoint.wght=300,wdth=90.ttf
new file mode 100644
index 0000000..04be94e
--- /dev/null
+++ b/test/subset/data/expected/full_instance/Roboto-Variable.no-prune-unicode-ranges.retain-all-codepoint.wght=300,wdth=90.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test-retain-gids.41,42,43.otf b/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test-retain-gids.41,42,43.otf
index 70dd0fd..5ae5d5b 100644
--- a/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test-retain-gids.41,42,43.otf
+++ b/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test-retain-gids.41,42,43.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test-retain-gids.41,42.otf b/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test-retain-gids.41,42.otf
index f9349f6..cfe6648 100644
--- a/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test-retain-gids.41,42.otf
+++ b/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test-retain-gids.41,42.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test-retain-gids.retain-all-codepoint.otf
index 07e6ad5..0e98d1a 100644
--- a/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test-retain-gids.retain-all-codepoint.otf
+++ b/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test-retain-gids.retain-all-codepoint.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test.41,42,43.otf b/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test.41,42,43.otf
index 070f9ec..6530ab6 100644
--- a/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test.41,42,43.otf
+++ b/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test.41,42,43.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test.41,42.otf b/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test.41,42.otf
index 60fd45c..cac1abb 100644
--- a/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test.41,42.otf
+++ b/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test.41,42.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test.retain-all-codepoint.otf b/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test.retain-all-codepoint.otf
index 07e6ad5..0e98d1a 100644
--- a/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test.retain-all-codepoint.otf
+++ b/test/subset/data/expected/layout.context/gpos_context2_multiple_subrules_f1.layout-test.retain-all-codepoint.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gdef-attachlist/IndicTestJalandhar-Regular.default.retain-all-codepoint.ttf b/test/subset/data/expected/layout.gdef-attachlist/IndicTestJalandhar-Regular.default.retain-all-codepoint.ttf
index ab0c1d1..c64ef97 100644
--- a/test/subset/data/expected/layout.gdef-attachlist/IndicTestJalandhar-Regular.default.retain-all-codepoint.ttf
+++ b/test/subset/data/expected/layout.gdef-attachlist/IndicTestJalandhar-Regular.default.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.gdef-attachlist/IndicTestJalandhar-Regular.drop-hints.retain-all-codepoint.ttf b/test/subset/data/expected/layout.gdef-attachlist/IndicTestJalandhar-Regular.drop-hints.retain-all-codepoint.ttf
index 2306381..b4a2677 100644
--- a/test/subset/data/expected/layout.gdef-attachlist/IndicTestJalandhar-Regular.drop-hints.retain-all-codepoint.ttf
+++ b/test/subset/data/expected/layout.gdef-attachlist/IndicTestJalandhar-Regular.drop-hints.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.gdef-attachlist/IndicTestJalandhar-Regular.keep-gdef.retain-all-codepoint.ttf b/test/subset/data/expected/layout.gdef-attachlist/IndicTestJalandhar-Regular.keep-gdef.retain-all-codepoint.ttf
index ab0c1d1..c64ef97 100644
--- a/test/subset/data/expected/layout.gdef-attachlist/IndicTestJalandhar-Regular.keep-gdef.retain-all-codepoint.ttf
+++ b/test/subset/data/expected/layout.gdef-attachlist/IndicTestJalandhar-Regular.keep-gdef.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test-retain-gids.41,42,43.otf b/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test-retain-gids.41,42,43.otf
index 1d3f3cd..f6b78bc 100644
--- a/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test-retain-gids.41,42,43.otf
+++ b/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test-retain-gids.41,42,43.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test-retain-gids.41,42.otf b/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test-retain-gids.41,42.otf
index 5a0d0c4..6f2e7ef 100644
--- a/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test-retain-gids.41,42.otf
+++ b/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test-retain-gids.41,42.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test-retain-gids.retain-all-codepoint.otf
index b3d6ae9..ff0595a 100644
--- a/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test-retain-gids.retain-all-codepoint.otf
+++ b/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test-retain-gids.retain-all-codepoint.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test.41,42,43.otf b/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test.41,42,43.otf
index 0a693c6..8086051 100644
--- a/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test.41,42,43.otf
+++ b/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test.41,42,43.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test.41,42.otf b/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test.41,42.otf
index 128c1d4..0a26e0f 100644
--- a/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test.41,42.otf
+++ b/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test.41,42.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test.retain-all-codepoint.otf b/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test.retain-all-codepoint.otf
index b3d6ae9..ff0595a 100644
--- a/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test.retain-all-codepoint.otf
+++ b/test/subset/data/expected/layout.gsub5/gsub_context2_multiple_subrules_f2.layout-test.retain-all-codepoint.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.627,644,62D,628.ttf b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.627,644,62D,628.ttf
index cbfad3d..e402e57 100644
--- a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.627,644,62D,628.ttf
+++ b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.627,644,62D,628.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.633,6D2.ttf b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.633,6D2.ttf
index f4938d8..5683d04 100644
--- a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.633,6D2.ttf
+++ b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.633,6D2.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.63A,64A,631.ttf b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.63A,64A,631.ttf
index 6ac7bcd..e19feda 100644
--- a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.63A,64A,631.ttf
+++ b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.63A,64A,631.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.retain-all-codepoint.ttf b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.retain-all-codepoint.ttf
index ba99d30..ea153c9 100644
--- a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.retain-all-codepoint.ttf
+++ b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.default.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.627,644,62D,628.ttf b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.627,644,62D,628.ttf
index 81ee9e8..fb9746e 100644
--- a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.627,644,62D,628.ttf
+++ b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.627,644,62D,628.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.633,6D2.ttf b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.633,6D2.ttf
index 3f5367a..81319fd 100644
--- a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.633,6D2.ttf
+++ b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.633,6D2.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.63A,64A,631.ttf b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.63A,64A,631.ttf
index 2610a64..b9aa70b 100644
--- a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.63A,64A,631.ttf
+++ b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.63A,64A,631.ttf
Binary files differ
diff --git a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.retain-all-codepoint.ttf b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.retain-all-codepoint.ttf
index e41720c..4458d5f 100644
--- a/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.retain-all-codepoint.ttf
+++ b/test/subset/data/expected/layout.notonastaliqurdu/NotoNastaliqUrdu-Regular.retain-gids.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/tests/full_instance.tests b/test/subset/data/tests/full_instance.tests
index 1b08673..f99e5eb 100644
--- a/test/subset/data/tests/full_instance.tests
+++ b/test/subset/data/tests/full_instance.tests
@@ -3,6 +3,7 @@
PROFILES:
default.txt
+no-prune-unicode-ranges.txt
SUBSETS:
*
diff --git a/test/subset/generate-expected-outputs.py b/test/subset/generate-expected-outputs.py
index 48b2f913..2b7a87f 100755
--- a/test/subset/generate-expected-outputs.py
+++ b/test/subset/generate-expected-outputs.py
@@ -45,6 +45,7 @@
args = ["fonttools", "subset", input_path]
args.extend(["--drop-tables+=DSIG",
"--drop-tables-=sbix",
+ "--no-harfbuzz-repacker", # disable harfbuzz repacker so we aren't comparing to ourself.
"--unicodes=%s" % unicodes,
"--output-file=%s" % fonttools_path])
args.extend(profile_flags)
diff --git a/test/subset/meson.build b/test/subset/meson.build
index 319d8bb..77a2029 100644
--- a/test/subset/meson.build
+++ b/test/subset/meson.build
@@ -40,8 +40,8 @@
'colr_glyphs',
'math',
'math_coverage_offset',
-# TODO: re-enable once colrv1 subsetting is stabilized.
-# 'colrv1.notoemoji',
+ # TODO: re-enable once colrv1 subsetting is stabilized.
+ # 'colrv1.notoemoji',
'colrv1',
'colr_with_components',
'cbdt',
@@ -49,11 +49,10 @@
'glyph_names',
'post',
'32bit_var_store',
-# instacing tests, enable when --instance is not experimental
-# 'pin_all_at_default',
-# 'instantiate_glyf',
-# 'full_instance',
-# 'instance_feature_variations',
+ 'pin_all_at_default',
+ 'instantiate_glyf',
+ 'full_instance',
+ 'instance_feature_variations',
]
repack_tests = [
@@ -65,7 +64,6 @@
'space_splitting',
]
-
run_test = find_program('run-tests.py')
foreach t : tests
diff --git a/test/subset/run-tests.py b/test/subset/run-tests.py
index 6a2146d..db3c042 100755
--- a/test/subset/run-tests.py
+++ b/test/subset/run-tests.py
@@ -47,14 +47,16 @@
print (' expected_file %s' % os.path.abspath (expected_file))
return 1
-def run_test (test, should_check_ots):
+def run_test (test, should_check_ots, preprocess):
out_file = os.path.join (tempfile.mkdtemp (), test.get_font_name () + '-subset' + test.get_font_extension ())
cli_args = ["--font-file=" + test.font_path,
"--output-file=" + out_file,
"--unicodes=%s" % test.unicodes (),
- "--preprocess-face",
"--drop-tables+=DSIG",
"--drop-tables-=sbix"]
+ if preprocess:
+ cli_args.extend(["--preprocess-face",])
+
cli_args.extend (test.get_profile_flags ())
if test.get_instance_flags ():
cli_args.extend (["--instance=%s" % ','.join(test.get_instance_flags ())])
@@ -142,7 +144,10 @@
print ("Running tests in " + path)
test_suite = SubsetTestSuite (path, f.read ())
for test in test_suite.tests ():
- fails += run_test (test, has_ots)
+ # Tests are run with and without preprocessing, results should be the
+ # same between them.
+ fails += run_test (test, has_ots, False)
+ fails += run_test (test, has_ots, True)
if fails != 0:
sys.exit ("%d test(s) failed." % fails)
diff --git a/util/hb-subset.cc b/util/hb-subset.cc
index f2606c7..bd4dea2 100644
--- a/util/hb-subset.cc
+++ b/util/hb-subset.cc
@@ -34,11 +34,7 @@
static hb_face_t* preprocess_face(hb_face_t* face)
{
- #ifdef HB_EXPERIMENTAL_API
return hb_subset_preprocess (face);
- #else
- return hb_face_reference(face);
- #endif
}
/*
@@ -120,7 +116,7 @@
for (unsigned i = 0; i < num_iterations; i++)
{
hb_face_destroy (new_face);
- new_face = hb_subset_or_fail (face, input);
+ new_face = hb_subset_or_fail (orig_face, input);
}
bool success = new_face;
@@ -664,7 +660,6 @@
return true;
}
-#ifdef HB_EXPERIMENTAL_API
#ifndef HB_NO_VAR
static gboolean
parse_instance (const char *name,
@@ -729,7 +724,6 @@
return true;
}
#endif
-#endif
template <GOptionArgFunc line_parser, bool allow_comments=true>
static gboolean
@@ -840,7 +834,7 @@
GOptionEntry glyphset_entries[] =
{
- {"gids", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_gids,
+ {"gids", 'g', 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_gids,
"Specify glyph IDs or ranges to include in the subset.\n"
" "
"Use --gids-=... to subtract codepoints from the current set.", "list of glyph indices/ranges or *"},
@@ -854,13 +848,13 @@
{"glyphs-file", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_file_for<parse_glyphs>, "Specify file to read glyph names from", "filename"},
- {"text", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_text, "Specify text to include in the subset. Use --text-=... to subtract codepoints from the current set.", "string"},
+ {"text", 't', 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_text, "Specify text to include in the subset. Use --text-=... to subtract codepoints from the current set.", "string"},
{"text-", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, (gpointer) &parse_text, "Specify text to remove from the subset", "string"},
{"text+", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, (gpointer) &parse_text, "Specify text to include in the subset", "string"},
{"text-file", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_file_for<parse_text, false>,"Specify file to read text from", "filename"},
- {"unicodes", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_unicodes,
+ {"unicodes", 'u', 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_unicodes,
"Specify Unicode codepoints or ranges to include in the subset. Use * to include all codepoints.\n"
" "
"--unicodes-=... can be used to subtract codepoints from the current set.\n"
@@ -901,7 +895,6 @@
{"drop-tables", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_drop_tables, "Drop the specified tables. Use --drop-tables-=... to subtract from the current set.", "list of string table tags or *"},
{"drop-tables+", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, (gpointer) &parse_drop_tables, "Drop the specified tables.", "list of string table tags or *"},
{"drop-tables-", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, (gpointer) &parse_drop_tables, "Drop the specified tables.", "list of string table tags or *"},
-#ifdef HB_EXPERIMENTAL_API
#ifndef HB_NO_VAR
{"instance", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_instance,
"(Partially|Fully) Instantiate a variable font. A location consists of the tag of a variation axis, followed by '=', followed by a\n"
@@ -911,7 +904,6 @@
"Note: currently only fully instancing to the default location is supported\n",
"list of comma separated axis-locations"},
#endif
-#endif
{nullptr}
};
add_group (other_entries,
diff --git a/util/helper-cairo.hh b/util/helper-cairo.hh
index 6df92e5..a8463de 100644
--- a/util/helper-cairo.hh
+++ b/util/helper-cairo.hh
@@ -29,7 +29,9 @@
#include "view-options.hh"
#include "output-options.hh"
-#include "helper-cairo-ft.hh"
+#ifdef HAVE_CAIRO_FT
+# include "helper-cairo-ft.hh"
+#endif
#include "helper-cairo-user.hh"
#include <cairo.h>
@@ -71,21 +73,35 @@
{
const char *env = getenv ("HB_DRAW");
if (!env)
+#if 1
+ /* Following branch disabled because we prefer our
+ * OpenType extensions working, ie going through hb-draw,
+ * over avoiding the obscure cairo bug. */
+ return true;
+#else
+ /* Older cairo had a bug in rendering COLRv0 fonts in
+ * right-to-left direction. */
return cairo_version () >= CAIRO_VERSION_ENCODE (1, 17, 5);
+#endif
+
return atoi (env);
}
static inline cairo_scaled_font_t *
helper_cairo_create_scaled_font (const font_options_t *font_opts)
{
- bool use_hb_draw = helper_cairo_use_hb_draw (font_opts);
hb_font_t *font = hb_font_reference (font_opts->font);
+#ifdef HAVE_CAIRO_FT
+ bool use_hb_draw = helper_cairo_use_hb_draw (font_opts);
cairo_font_face_t *cairo_face;
if (use_hb_draw)
cairo_face = helper_cairo_create_user_font_face (font_opts);
else
cairo_face = helper_cairo_create_ft_font_face (font_opts);
+#else
+ cairo_font_face_t *cairo_face = helper_cairo_create_user_font_face (font_opts);
+#endif
cairo_matrix_t ctm, font_matrix;
cairo_font_options_t *font_options;
@@ -94,8 +110,10 @@
cairo_matrix_init_scale (&font_matrix,
font_opts->font_size_x,
font_opts->font_size_y);
- if (use_hb_draw)
+#ifdef HAVE_CAIRO_FT
+ if (!use_hb_draw)
font_matrix.xy = -font_opts->slant * font_opts->font_size_x;
+#endif
font_options = cairo_font_options_create ();
cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
@@ -122,10 +140,14 @@
static inline bool
helper_cairo_scaled_font_has_color (cairo_scaled_font_t *scaled_font)
{
+#ifdef HAVE_CAIRO_FT
if (helper_cairo_user_font_face_has_data (cairo_scaled_font_get_font_face (scaled_font)))
return helper_cairo_user_scaled_font_has_color (scaled_font);
else
return helper_cairo_ft_scaled_font_has_color (scaled_font);
+#else
+ return helper_cairo_user_scaled_font_has_color (scaled_font);
+#endif
}
diff --git a/util/meson.build b/util/meson.build
index fdab620..1367405 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -17,8 +17,7 @@
util_deps = [freetype_dep, cairo_dep, cairo_ft_dep, glib_dep]
if conf.get('HAVE_GLIB', 0) == 1
- if conf.get('HAVE_FREETYPE', 0) == 1 and conf.get('HAVE_CAIRO_FT', 0) == 1
-
+ if conf.get('HAVE_CAIRO', 0) == 1
hb_view = executable('hb-view', hb_view_sources,
cpp_args: cpp_args,
include_directories: [incconfig, incsrc],
diff --git a/util/shape-consumer.hh b/util/shape-consumer.hh
index 2115189..8ee4bd6 100644
--- a/util/shape-consumer.hh
+++ b/util/shape-consumer.hh
@@ -61,11 +61,11 @@
for (unsigned int n = num_iterations; n; n--)
{
- const char *error = nullptr;
-
populate_buffer (buffer, text, text_len, app.text_before, app.text_after);
if (n == 1)
output.consume_text (buffer, text, text_len, utf8_clusters);
+
+ const char *error = nullptr;
if (!shape (app.font, buffer, &error))
{
failed = true;