diff --git a/.circleci/config.yml b/.circleci/config.yml index 906f4ba85..320813ad3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,38 +2,55 @@ version: 2 jobs: - macos-llvm-gcc-4.2: + macos-10.12.6-aat-fonts: macos: - xcode: "8.3.3" + xcode: "9.2.0" steps: - checkout - - run: brew update-reset - - run: brew install wget pkg-config libtool ragel freetype glib cairo - - run: wget https://packages.macports.org/llvm-gcc42/llvm-gcc42-2336.11_3+universal.darwin_15.i386-x86_64.tbz2 && tar zxvf llvm-gcc42-2336.11_3+universal.darwin_15.i386-x86_64.tbz2 - - run: CC=$PWD/opt/local/bin/llvm-gcc-4.2 CXX=$PWD/opt/local/bin/llvm-g++-4.2 ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo - # Ignoring assembler complains, https://stackoverflow.com/a/39867021 - - run: make 2>&1 | grep -v -e '^/var/folders/*' -e '^[[:space:]]*\.section' -e '^[[:space:]]*\^[[:space:]]*~*' + - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget pkg-config libtool ragel freetype glib cairo + - run: ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo + - run: make -j4 - run: make check || .ci/fail.sh - macos-notest-apple-gcc-i686-4.2: + macos-10.13.6-aat-fonts: macos: - xcode: "8.3.3" + xcode: "10.1.0" steps: - checkout - - run: brew update-reset - - run: brew install wget pkg-config libtool ragel - - run: wget https://packages.macports.org/apple-gcc42/apple-gcc42-5666.3_15+universal.darwin_15.i386-x86_64.tbz2 && tar zxvf apple-gcc42-5666.3_15+universal.darwin_15.i386-x86_64.tbz2 - - run: CPP=$PWD/opt/local/bin/i686-apple-darwin15-cpp-apple-4.2.1 CC=$PWD/opt/local/bin/i686-apple-darwin15-gcc-apple-4.2.1 CXX=$PWD/opt/local/bin/i686-apple-darwin15-g++-apple-4.2.1 ./autogen.sh - # Ignoring assembler complains, https://stackoverflow.com/a/39867021 - - run: make 2>&1 | grep -v -e '^/var/folders/*' -e '^[[:space:]]*\.section' -e '^[[:space:]]*\^[[:space:]]*~*' + - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget pkg-config libtool ragel freetype glib cairo + - run: ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo + - run: make -j4 + - run: make check || .ci/fail.sh + + # macos-llvm-gcc-4.2: + # macos: + # xcode: "8.3.3" + # steps: + # - checkout + # - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget pkg-config libtool ragel freetype glib cairo + # - run: wget https://packages.macports.org/llvm-gcc42/llvm-gcc42-2336.11_3+universal.darwin_15.i386-x86_64.tbz2 && tar zxvf llvm-gcc42-2336.11_3+universal.darwin_15.i386-x86_64.tbz2 + # - run: CC=$PWD/opt/local/bin/llvm-gcc-4.2 CXX=$PWD/opt/local/bin/llvm-g++-4.2 ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo + # # Ignoring assembler complains, https://stackoverflow.com/a/39867021 + # - run: make 2>&1 | grep -v -e '^/var/folders/*' -e '^[[:space:]]*\.section' -e '^[[:space:]]*\^[[:space:]]*~*' + # - run: make check || .ci/fail.sh + + # macos-notest-apple-gcc-i686-4.2: + # macos: + # xcode: "8.3.3" + # steps: + # - checkout + # - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget pkg-config libtool ragel + # - run: wget https://packages.macports.org/apple-gcc42/apple-gcc42-5666.3_15+universal.darwin_15.i386-x86_64.tbz2 && tar zxvf apple-gcc42-5666.3_15+universal.darwin_15.i386-x86_64.tbz2 + # - run: CPP=$PWD/opt/local/bin/i686-apple-darwin15-cpp-apple-4.2.1 CC=$PWD/opt/local/bin/i686-apple-darwin15-gcc-apple-4.2.1 CXX=$PWD/opt/local/bin/i686-apple-darwin15-g++-apple-4.2.1 ./autogen.sh + # # Ignoring assembler complains, https://stackoverflow.com/a/39867021 + # - run: make 2>&1 | grep -v -e '^/var/folders/*' -e '^[[:space:]]*\.section' -e '^[[:space:]]*\^[[:space:]]*~*' macos-notest-ios: macos: xcode: "10.0.0" steps: - checkout - - run: brew update-reset - - run: brew install cmake + - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake # not needed to be a framework but we like to test that also # TODO: wrong way of targeting iOS as it doesn't point to iOS headers thus building # CoreText support is not possible, after the fix feel free HB_IOS from CMake altogether @@ -302,6 +319,8 @@ workflows: build: jobs: # macOS + - macos-10.12.6-aat-fonts + - macos-10.13.6-aat-fonts #- macos-llvm-gcc-4.2 #- macos-notest-apple-gcc-i686-4.2 - macos-notest-ios diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 000000000..e9b8ab481 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,7 @@ +comment: off + +coverage: + status: + project: + default: + threshold: 1% diff --git a/configure.ac b/configure.ac index 95ab48f80..e9db42a78 100644 --- a/configure.ac +++ b/configure.ac @@ -508,6 +508,7 @@ test/api/Makefile test/fuzzing/Makefile test/shaping/Makefile test/shaping/data/Makefile +test/shaping/data/aots/Makefile test/shaping/data/in-house/Makefile test/shaping/data/text-rendering-tests/Makefile test/subset/Makefile diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 66a64d8f9..27353389d 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -112,6 +112,11 @@ + + Apple Advanced Typography API + + + Integration API diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 63d5f6cef..5c45153c3 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -3,6 +3,17 @@ HB_H_IN HB_OT_H_IN +
+hb-aat-layout +HB_AAT_LAYOUT_NO_SELECTOR_INDEX +hb_aat_layout_feature_type_t +hb_aat_layout_get_feature_types +hb_aat_layout_feature_type_get_name_id +hb_aat_layout_feature_selector_t +hb_aat_layout_feature_selector_info_t +hb_aat_layout_feature_type_get_selector_infos +
+
hb-blob hb_blob_create @@ -161,6 +172,10 @@ hb_ot_layout_table_choose_script hb_ot_layout_table_find_script hb_ot_tag_from_language hb_ot_tags_from_script +HB_OT_VAR_NO_AXIS_INDEX +hb_ot_var_axis_t +hb_ot_var_find_axis +hb_ot_var_get_axes hb_set_invert hb_unicode_eastasian_width_func_t hb_unicode_eastasian_width @@ -581,14 +596,12 @@ 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_NO_AXIS_INDEX -hb_ot_var_axis_t hb_ot_var_has_data -hb_ot_var_find_axis -hb_ot_var_get_axis_count -hb_ot_var_get_axes hb_ot_var_axis_flags_t -hb_ot_var_axis_get_flags +hb_ot_var_axis_info_t +hb_ot_var_find_axis_info +hb_ot_var_get_axis_count +hb_ot_var_get_axis_infos hb_ot_var_get_named_instance_count hb_ot_var_named_instance_get_subfamily_name_id hb_ot_var_named_instance_get_postscript_name_id diff --git a/docs/usermanual-clusters.xml b/docs/usermanual-clusters.xml index 7b2c7adc7..f48e89c20 100644 --- a/docs/usermanual-clusters.xml +++ b/docs/usermanual-clusters.xml @@ -5,306 +5,538 @@ ]> - Clusters - - In shaping text, a cluster is a sequence of - code points that needs to be treated as a single, indivisible unit. - - - When you add text to a HB buffer, each character is associated with - a cluster value. This is an arbitrary number as - far as HB is concerned. - - - Most clients will use UTF-8, UTF-16, or UTF-32 indices, but the - actual number does not matter. Moreover, it is not required for the - cluster values to be monotonically increasing, but pretty much all - of HB's tests are performed on monotonically increasing cluster - numbers. Nevertheless, there is no such assumption in the code - itself. With that in mind, let's examine what happens with cluster - values during shaping under each cluster-level. - - - HarfBuzz provides three levels of clustering - support. Level 0 is the default behavior and reproduces the behavior - of the old HarfBuzz library. Level 1 tweaks this behavior slightly - to produce better results, so level 1 clustering is recommended for - code that is not required to implement backward compatibility with - the old HarfBuzz. - - - Level 2 differs significantly in how it treats cluster values. - Levels 0 and 1 both process ligatures and glyph decomposition by - merging clusters; level 2 does not. - - - The conceptual model for what the cluster values mean, in levels 0 - and 1, is this: - - - - - the sequence of cluster values will always remain monotone - - - - - each value represents a single cluster - - - - - each cluster contains one or more glyphs and one or more - characters - - - - - Assuming that initial cluster numbers were monotonically increasing - and distinct, then all adjacent glyphs having the same cluster - number belong to the same cluster, and all characters belong to the - cluster that has the highest number not larger than their initial - cluster number. This will become clearer with an example. - - - - A clustering example for levels 0 and 1 - - Let's say we start with the following character sequence and cluster - values: - - - A,B,C,D,E - 0,1,2,3,4 - - - We then map the characters to glyphs. For simplicity, let's assume - that each character maps to the corresponding, identical-looking - glyph: - - - A,B,C,D,E - 0,1,2,3,4 - - - Now if, for example, B and C - ligate, then the clusters to which they belong "merge". - This merged cluster takes for its cluster number the minimum of all - the cluster numbers of the clusters that went in. In this case, we - get: - - - A,BC,D,E - 0,1 ,3,4 - - - Now let's assume that the BC glyph decomposes - into three components, and D also decomposes into - two. The components each inherit the cluster value of their parent: - - - A,BC0,BC1,BC2,D0,D1,E - 0,1 ,1 ,1 ,3 ,3 ,4 - - - Now if BC2 and D0 ligate, then - their clusters (numbers 1 and 3) merge into - min(1,3) = 1: - - - A,BC0,BC1,BC2D0,D1,E - 0,1 ,1 ,1 ,1 ,4 - - - At this point, cluster 1 means: the character sequence - BCD is represented by glyphs - BC0,BC1,BC2D0,D1 and cannot be broken down any - further. - - - - Reordering in levels 0 and 1 - - Another common operation in the more complex shapers is when things - reorder. In those cases, to maintain monotone clusters, HB merges - the clusters of everything in the reordering sequence. For example, - let's again start with the character sequence: - - - A,B,C,D,E - 0,1,2,3,4 - - - If D is reordered before B, - then the B, C, and - D clusters merge, and we get: - - - A,D,B,C,E - 0,1,1,1,4 - - - This is clearly not ideal, but it is the only sensible way to - maintain monotone indices and retain the true relationship between - glyphs and characters. - - - - The distinction between levels 0 and 1 - - So, the above is pretty much what cluster levels 0 and 1 do. The - only difference between the two is this: in level 0, at the very - beginning of the shaping process, we also merge clusters between - base characters and all Unicode marks (combining or not) following - them. E.g.: - - - A,acute,B - 0,1 ,2 - - - will become: - - - A,acute,B - 0,0 ,2 - - - This is the default behavior. We do it because Windows did it and - old HarfBuzz did it, so this remained the default. But this behavior - makes it impossible to color diacritic marks differently from their - base characters. That's why in level 1 we do not perform this - initial merging step. - - - For clients, level 0 is more convenient if they rely on HarfBuzz - clusters for cursor positioning. But that's wrong anyway: cursor - positions should be determined based on Unicode grapheme boundaries, - NOT shaping clusters. As such, level 1 clusters are preferred. - - - One last note about levels 0 and 1. We currently don't allow a - MultipleSubst lookup to replace a glyph with zero - glyphs (i.e., to delete a glyph). But in some other situations, - glyphs can be deleted. In those cases, if the glyph being deleted is - the last glyph of its cluster, we make sure to merge the cluster - with a neighboring cluster. - - - This is, primarily, to make sure that the starting cluster of the - text always has the cluster index pointing to the start of the text - for the run; more than one client currently relies on this - guarantee. - - - Incidentally, Apple's CoreText does something else to maintain the - same promise: it inserts a glyph with id 65535 at the beginning of - the glyph string if the glyph corresponding to the first character - in the run was deleted. HarfBuzz might do something similar in the - future. - - - - Level 2 - - Level 2 is a different beast from levels 0 and 1. It is simple to - describe, but hard to make sense of. It simply doesn't do any - cluster merging whatsoever. When things ligate or otherwise multiple - glyphs turn into one, the cluster value of the first glyph is - retained. - - - Here are a few examples of why processing cluster values produced at - this level might be tricky: - - - Ligatures with combining marks +
+ Clusters - Imagine capital letters are bases and lower case letters are - combining marks. With an input sequence like this: + In text shaping, a cluster is a sequence of + characters that needs to be treated as a single, indivisible + unit. + + + A cluster is distinct from a grapheme, + which is the smallest unit of a writing system or script, + because clusters are only relevant for script shaping and the + layout of glyphs. + + + For example, a grapheme may be a letter, a number, a logogram, + or a symbol. When two letters form a ligature, however, they + combine into a single glyph. They are therefore part of the same + cluster and are treated as a unit — even though the two + original, underlying letters are separate graphemes. + + + During the shaping process, there are several shaping operations + that may merge adjacent characters (for example, when two code + points form a ligature or a conjunct form and are replaced by a + single glyph) or split one character into several (for example, + when decomposing a code point through the + ccmp feature). + + + HarfBuzz tracks clusters independently from how these + shaping operations affect the individual glyphs that comprise the + output HarfBuzz returns in a buffer. Consequently, + a client program using HarfBuzz can utilize the cluster + information to implement features such as: + + + + + Correctly positioning the cursor within a shaped text run, + even when characters have formed ligatures, composed or + decomposed, reordered, or undergone other shaping operations. + + + + + Correctly highlighting a text selection that includes some, + but not all, of the characters in a word. + + + + + Applying text attributes (such as color or underlining) to + part, but not all, of a word. + + + + + Generating output document formats (such as PDF) with + embedded text that can be fully extracted. + + + + + Determining the mapping between input characters and output + glyphs, such as which glyphs are ligatures. + + + + + Performing line-breaking, justification, and other + line-level or paragraph-level operations that must be done + after shaping is complete, but which require character-level + properties. + + + + + When you add text to a HarfBuzz buffer, each code point must be + assigned a cluster value. + + + This cluster value is an arbitrary number; HarfBuzz uses it only + to distinguish between clusters. Many client programs will use + the index of each code point in the input text stream as the + cluster value. This is for the sake of convenience; the actual + value does not matter. + + + Client programs can choose how HarfBuzz handles clusters during + shaping by setting the + cluster_level of the + buffer. HarfBuzz offers three levels of + clustering support for this property: + + + + Level 0 is the default and + reproduces the behavior of the old HarfBuzz library. + + + The distinguishing feature of level 0 behavior is that, at + the beginning of processing the buffer, all code points that + are categorized as marks, + modifier symbols, or + Emoji extended pictographic modifiers, + as well as the Zero Width Joiner and + Zero Width Non-Joiner code points, are + assigned the cluster value of the closest preceding code + point from different category. + + + In essence, whenever a base character is followed by a mark + character or a sequence of mark characters, those marks are + reassigned to the same initial cluster value as the base + character. This reassignment is referred to as + "merging" the affected clusters. This behavior is based on + the Grapheme Cluster Boundary specification in Unicode + Technical Report 29. + + + Client programs can specify level 0 behavior for a buffer by + setting its cluster_level to + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES. + + + + + Level 1 tweaks the old behavior + slightly to produce better results. Therefore, level 1 + clustering is recommended for code that is not required to + implement backward compatibility with the old HarfBuzz. + + + Level 1 differs from level 0 by not merging the + clusters of marks and other modifier code points with the + preceding "base" code point's cluster. By preserving the + separate cluster values of these marks and modifier code + points, script shapers can perform additional operations + that might lead to improved results (for example, reordering + a sequence of marks). + + + Client programs can specify level 1 behavior for a buffer by + setting its cluster_level to + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS. + + + + + Level 2 differs significantly in how it + treats cluster values. In level 2, HarfBuzz never merges + clusters. + + + This difference can be seen most clearly when HarfBuzz processes + ligature substitutions and glyph decompositions. In level 0 + and level 1, ligatures and glyph decomposition both involve + merging clusters; in level 2, neither of these operations + triggers a merge. + + + Client programs can specify level 2 behavior for a buffer by + setting its cluster_level to + HB_BUFFER_CLUSTER_LEVEL_CHARACTERS. + + + + + As mentioned earlier, client programs using HarfBuzz often + assign initial cluster values in a buffer by reusing the indices + of the code points in the input text. This gives a sequence of + cluster values that is monotonically increasing (for example, + 0,1,2,3,4,5). + + + It is not required that the cluster values + in a buffer be monotonically increasing. However, if the initial + cluster values in a buffer are monotonic and the buffer is + configured to use cluster level 0 or 1, then HarfBuzz + guarantees that the final cluster values in the shaped buffer + will also be monotonic. No such guarantee is made for cluster + level 2. + + + In levels 0 and 1, HarfBuzz implements the following conceptual + model for cluster values: + + + + + If the sequence of input cluster values is monotonic, the + sequence of cluster values will remain monotonic. + + + + + Each cluster value represents a single cluster. + + + + + Each cluster contains one or more glyphs and one or more + characters. + + + + + In practice, this model offers several benefits. Assuming that + the initial cluster values were monotonically increasing + and distinct before shaping began, then, in the final output: + + + + + All adjacent glyphs having the same final cluster + value belong to the same cluster. + + + + + Each character belongs to the cluster that has the highest + cluster value not larger than its + initial cluster value. + + + + +
+
+ A clustering example for levels 0 and 1 + + The guarantees and benefits of level 0 and level 1 can be seen + with some examples. First, let us examine what happens with cluster + values when shaping involves cluster merging with ligatures and + decomposition. + + + Let's say we start with the following character sequence (top row) and + initial cluster values (bottom row): - A,a,B,b,C,c - 0,1,2,3,4,5 - + A,B,C,D,E + 0,1,2,3,4 + - if A,B,C ligate, then here are the cluster - values one would get under the various levels: - - - level 0: + During shaping, HarfBuzz maps these characters to glyphs from + the font. For simplicity, let us assume that each character maps + to the corresponding, identical-looking glyph: - ABC,a,b,c - 0 ,0,0,0 - + A,B,C,D,E + 0,1,2,3,4 + - level 1: + Now if, for example, B and C + form a ligature, then the clusters to which they belong + "merge". This merged cluster takes for its cluster + value the minimum of all the cluster values of the clusters that + went in to the ligature. In this case, we get: - ABC,a,b,c - 0 ,0,0,5 - + A,BC,D,E + 0,1 ,3,4 + - level 2: + because 1 is the minimum of the set {1,2}, which were the + cluster values of B and + C. + + + Next, let us say that the BC ligature glyph + decomposes into three components, and D also + decomposes into two components. These components each inherit the + cluster value of their parent: - ABC,a,b,c - 0 ,1,3,5 - + A,BC0,BC1,BC2,D0,D1,E + 0,1 ,1 ,1 ,3 ,3 ,4 + - Making sense of the last example is the hardest for a client, - because there is nothing in the cluster values to suggest that - B and C ligated with - A. - - - - Reordering - - Another tricky case is when things reorder. Under level 2: + Next, if BC2 and D0 form a + ligature, then their clusters (cluster values 1 and 3) merge into + min(1,3) = 1: - A,B,C,D,E - 0,1,2,3,4 - + A,BC0,BC1,BC2D0,D1,E + 0,1 ,1 ,1 ,1 ,4 + - Now imagine D moves before - B: + At this point, cluster 1 means: the character sequence + BCD is represented by glyphs + BC0,BC1,BC2D0,D1 and cannot be broken down any + further. + +
+
+ Reordering in levels 0 and 1 + + Another common operation in the more complex shapers is glyph + reordering. In order to maintain a monotonic cluster sequence + when glyph reordering takes place, HarfBuzz merges the clusters + of everything in the reordering sequence. + + + For example, let us again start with the character sequence (top + row) and initial cluster values (bottom row): - A,D,B,C,E - 0,3,1,2,4 - + A,B,C,D,E + 0,1,2,3,4 + - Now, if D ligates with B, we + If D is reordered to before B, + then HarfBuzz merges the B, + C, and D clusters, and we get: - A,DB,C,E - 0,3 ,2,4 - + A,D,B,C,E + 0,1,1,1,4 + - In a different scenario, A and - B could have ligated - before D reordered; that - would have resulted in: + This is clearly not ideal, but it is the only sensible way to + maintain a monotonic sequence of cluster values and retain the + true relationship between glyphs and characters. + +
+
+ The distinction between levels 0 and 1 + + The preceding examples demonstrate the main effects of using + cluster levels 0 and 1. The only difference between the two + levels is this: in level 0, at the very beginning of the shaping + process, HarfBuzz also merges clusters between any base character + and all Unicode marks (combining or not) that follow it. + + + For example, let us start with the following character sequence + (top row) and accompanying initial cluster values (bottom row): - AB,D,C,E - 0 ,3,2,4 - + A,acute,B + 0,1 ,2 + - There's no way to differentiate between these two scenarios based - on the cluster numbers alone. + The acute is a Unicode mark. If HarfBuzz is + using cluster level 0 on this sequence, then the + A and acute clusters will + merge, and the result will become: + + + A,acute,B + 0,0 ,2 + + + This initial cluster merging is the default behavior of the + Windows shaping engine, and the old HarfBuzz codebase copied + that behavior to maintain compatibility. Consequently, it has + remained the default behavior in the new HarfBuzz codebase. - Another problem happens with ligatures under level 2 if the - direction of the text is forced to opposite of its natural - direction (e.g. left-to-right Arabic). But that's too much of a - corner case to worry about. + But this initial cluster-merging behavior makes it impossible to + color diacritic marks differently from their base + characters. That is why, in level 1, HarfBuzz does not perform + the initial merging step. - - + + For client programs that rely on HarfBuzz cluster values to + perform cursor positioning, level 0 is more convenient. But + relying on cluster boundaries for cursor positioning is wrong: cursor + positions should be determined based on Unicode grapheme + boundaries, not on shaping-cluster boundaries. As such, level 1 + clusters are preferred. + + + One last note about levels 0 and 1. HarfBuzz currently does not allow a + MultipleSubst lookup to replace a glyph with zero + glyphs (in other words, to delete a glyph). But, in some other situations, + glyphs can be deleted. In those cases, if the glyph being deleted is + the last glyph of its cluster, HarfBuzz makes sure to merge the cluster + with a neighboring cluster. + + + This is done primarily to make sure that the starting cluster of the + text always has the cluster index pointing to the start of the text + for the run; more than one client currently relies on this + guarantee. + + + Incidentally, Apple's CoreText does something else to maintain the + same promise: it inserts a glyph with id 65535 at the beginning of + the glyph string if the glyph corresponding to the first character + in the run was deleted. HarfBuzz might do something similar in the + future. + +
+
+ Level 2 + + HarfBuzz's level 2 cluster behavior uses a significantly + different model than that of level 0 and level 1. + + + The level 2 behavior is easy to describe, but it may be + difficult to understand in practical terms. In brief, level 2 + performs no merging of clusters whatsoever. + + + When glyphs form a ligature (or when some other feature + substitutes multiple glyphs with one glyph), the cluster value + of the first glyph is retained as the cluster value for the + ligature. However, no subsequent clusters — including + marks and modifiers — are affected. + + + Level 2 cluster behavior is less complex than level 0 or level + 1, but there are a few cases in which processing cluster values + produced at level 2 may be tricky. + +
+ Ligatures with combining marks in level 2 + + The first example of how HarfBuzz's level 2 cluster behavior + can be tricky is when the text to be shaped includes combining + marks attached to ligatures. + + + Let us start with an input sequence with the following + characters (top row) and initial cluster values (bottom row): + + + A,acute,B,breve,C,circumflex + 0,1 ,2,3 ,4,5 + + + If the sequence A,B,C forms a ligature, + then these are the cluster values HarfBuzz will return under + the various cluster levels: + + + Level 0: + + + ABC,acute,breve,circumflex + 0 ,0 ,0 ,0 + + + Level 1: + + + ABC,acute,breve,circumflex + 0 ,0 ,0 ,5 + + + Level 2: + + + ABC,acute,breve,circumflex + 0 ,1 ,3 ,5 + + + Making sense of the level 2 result is the hardest for a client + program, because there is nothing in the cluster values that + indicates that B and C + formed a ligature with A. + + + In contrast, the "merged" cluster values of the mark glyphs + that are seen in the level 0 and level 1 output are evidence + that a ligature substitution took place. + +
+
+ Reordering in level 2 + + Another example of how HarfBuzz's level 2 cluster behavior + can be tricky is when glyphs reorder. Consider an input sequence + with the following characters (top row) and initial cluster + values (bottom row): + + + A,B,C,D,E + 0,1,2,3,4 + + + Now imagine D moves before + B in a reordering operation. The cluster + values will then be: + + + A,D,B,C,E + 0,3,1,2,4 + + + Next, if D forms a ligature with + B, the output is: + + + A,DB,C,E + 0,3 ,2,4 + + + However, in a different scenario, in which the shaping rules + of the script instead caused A and + B to form a ligature + before the D reordered, the + result would be: + + + AB,D,C,E + 0 ,3,2,4 + + + There is no way for a client program to differentiate between + these two scenarios based on the cluster values + alone. Consequently, client programs that use level 2 might + need to undertake additional work in order to manage cursor + positioning, text attributes, or other desired features. + +
+
+ Other considerations in level 2 + + There may be other problems encountered with ligatures under + level 2, such as if the direction of the text is forced to + opposite of its natural direction (for example, left-to-right + Arabic). But, generally speaking, these other scenarios are + minor corner cases that are too obscure for most client + programs to need to worry about. + +
+
diff --git a/docs/usermanual-getting-started.xml b/docs/usermanual-getting-started.xml index 9e16ecbf2..932bd9471 100644 --- a/docs/usermanual-getting-started.xml +++ b/docs/usermanual-getting-started.xml @@ -157,7 +157,8 @@ #include <hb-ft.h> - FT_New_Face(ft_library, font_path, index, &face) + FT_New_Face(ft_library, font_path, index, &face); + FT_Set_Char_Size(face, 0, 1000, 0, 0); hb_font_t *font = hb_ft_font_create(face); diff --git a/src/Makefile.am b/src/Makefile.am index b3cc42f3f..c726cf2a6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -424,6 +424,8 @@ HarfBuzz_0_0_gir_CFLAGS = \ -DHB_H_IN \ -DHB_OT_H \ -DHB_OT_H_IN \ + -DHB_AAT_H \ + -DHB_AAT_H_IN \ -DHB_GOBJECT_H \ -DHB_GOBJECT_H_IN \ -DHB_EXTERN= \ diff --git a/src/Makefile.sources b/src/Makefile.sources index b15aeea48..b1a3d0a29 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -192,6 +192,8 @@ HB_OT_RAGEL_sources = \ $(NULL) HB_OT_headers = \ + hb-aat.h \ + hb-aat-layout.h \ hb-ot.h \ hb-ot-color.h \ hb-ot-font.h \ diff --git a/src/gen-use-table.py b/src/gen-use-table.py index a8a7a2326..099f6a185 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -50,6 +50,8 @@ data[0][0x20F0] = defaults[0] # TODO https://github.com/roozbehp/unicode-data/issues/9 data[0][0x11C44] = 'Consonant_Placeholder' data[0][0x11C45] = 'Consonant_Placeholder' +# TODO https://github.com/harfbuzz/harfbuzz/pull/1399 +data[0][0x111C8] = 'Consonant_Placeholder' for u in range (0xFE00, 0xFE0F + 1): data[0][u] = defaults[0] @@ -168,7 +170,7 @@ def is_BASE(U, UISC, UGC): def is_BASE_IND(U, UISC, UGC): #SPEC-DRAFT return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po) return (UISC in [Consonant_Dead, Modifying_Letter] or - (UGC == Po and not U in [0x104B, 0x104E, 0x2022, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or + (UGC == Po and not U in [0x104B, 0x104E, 0x2022, 0x111C8, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or False # SPEC-DRAFT-OUTDATED! U == 0x002D ) def is_BASE_NUM(U, UISC, UGC): @@ -354,6 +356,9 @@ def map_to_use(data): # TODO: https://github.com/harfbuzz/harfbuzz/issues/1105 if U == 0x11134: UISC = Gemination_Mark + # TODO: https://github.com/harfbuzz/harfbuzz/pull/1399 + if U == 0x111C9: UISC = Consonant_Final + values = [k for k,v in items if v(U,UISC,UGC)] assert len(values) == 1, "%s %s %s %s" % (hex(U), UISC, UGC, values) USE = values[0] diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 6572b26d8..c0b0e3751 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -69,13 +69,15 @@ struct LookupFormat0 UnsizedArrayOf arrayZ; /* Array of lookup values, indexed by glyph index. */ public: - DEFINE_SIZE_ARRAY (2, arrayZ); + DEFINE_SIZE_UNBOUNDED (2); }; template struct LookupSegmentSingle { + enum { TerminationWordCount = 2 }; + inline int cmp (hb_codepoint_t g) const { return g < first ? -1 : g <= last ? 0 : +1 ; } @@ -134,6 +136,8 @@ struct LookupFormat2 template struct LookupSegmentArray { + enum { TerminationWordCount = 2 }; + inline const T* get_value (hb_codepoint_t glyph_id, const void *base) const { return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr; @@ -204,6 +208,8 @@ struct LookupFormat4 template struct LookupSingle { + enum { TerminationWordCount = 1 }; + inline int cmp (hb_codepoint_t g) const { return glyph.cmp (g); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -357,6 +363,14 @@ struct Lookup } } + inline typename T::type get_class (hb_codepoint_t glyph_id, + unsigned int num_glyphs, + unsigned int outOfRange) const + { + const T *v = get_value (glyph_id, num_glyphs); + return v ? *v : outOfRange; + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -436,8 +450,10 @@ struct Entry * which ensures that data has a simple sanitize(). To be determined * if I need to remove that as well. * - * XXX Because we are a template, our DEFINE_SIZE_STATIC assertion - * wouldn't be checked. */ + * HOWEVER! Because we are a template, our DEFINE_SIZE_STATIC + * assertion wouldn't be checked, hence the line below. */ + static_assert (T::static_size, ""); + return_trace (c->check_struct (this)); } @@ -472,7 +488,7 @@ struct StateTable { typedef typename Types::HBUINT HBUINT; typedef typename Types::HBUSHORT HBUSHORT; - typedef typename Types::ClassType ClassType; + typedef typename Types::ClassTypeNarrow ClassType; enum State { @@ -630,6 +646,7 @@ struct StateTable DEFINE_SIZE_STATIC (4 * sizeof (HBUINT)); }; +template struct ClassTable { inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int outOfRange) const @@ -637,6 +654,12 @@ struct ClassTable unsigned int i = glyph_id - firstGlyph; return i >= classArray.len ? outOfRange : classArray.arrayZ[i]; } + inline unsigned int get_class (hb_codepoint_t glyph_id, + unsigned int num_glyphs HB_UNUSED, + unsigned int outOfRange) const + { + return get_class (glyph_id, outOfRange); + } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -644,7 +667,7 @@ struct ClassTable } protected: GlyphID firstGlyph; /* First glyph index included in the trimmed array. */ - ArrayOf classArray; /* The class codes (indexed by glyph index minus + ArrayOf classArray; /* The class codes (indexed by glyph index minus * firstGlyph). */ public: DEFINE_SIZE_ARRAY (4, classArray); @@ -655,15 +678,9 @@ struct ObsoleteTypes static const bool extended = false; typedef HBUINT16 HBUINT; typedef HBUINT8 HBUSHORT; - struct ClassType : ClassTable - { - inline unsigned int get_class (hb_codepoint_t glyph_id, - unsigned int num_glyphs HB_UNUSED, - unsigned int outOfRange) const - { - return ClassTable::get_class (glyph_id, outOfRange); - } - }; + typedef ClassTable ClassTypeNarrow; + typedef ClassTable ClassTypeWide; + template static inline unsigned int offsetToIndex (unsigned int offset, const void *base, @@ -672,6 +689,13 @@ struct ObsoleteTypes return (offset - ((const char *) array - (const char *) base)) / sizeof (T); } template + static inline unsigned int byteOffsetToIndex (unsigned int offset, + const void *base, + const T *array) + { + return offsetToIndex (offset, base, array); + } + template static inline unsigned int wordOffsetToIndex (unsigned int offset, const void *base, const T *array) @@ -684,16 +708,9 @@ struct ExtendedTypes static const bool extended = true; typedef HBUINT32 HBUINT; typedef HBUINT16 HBUSHORT; - struct ClassType : Lookup - { - inline unsigned int get_class (hb_codepoint_t glyph_id, - unsigned int num_glyphs, - unsigned int outOfRange) const - { - const HBUINT16 *v = get_value (glyph_id, num_glyphs); - return v ? *v : outOfRange; - } - }; + typedef Lookup ClassTypeNarrow; + typedef Lookup ClassTypeWide; + template static inline unsigned int offsetToIndex (unsigned int offset, const void *base, @@ -702,6 +719,13 @@ struct ExtendedTypes return offset; } template + static inline unsigned int byteOffsetToIndex (unsigned int offset, + const void *base, + const T *array) + { + return offset / 2; + } + template static inline unsigned int wordOffsetToIndex (unsigned int offset, const void *base, const T *array) diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 87ab4abd3..4e63ec8e8 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -39,6 +39,27 @@ namespace AAT { struct SettingName { + friend struct FeatureName; + + int cmp (hb_aat_layout_feature_selector_t key) const + { return (int) key - (int) setting; } + + inline hb_aat_layout_feature_selector_t get_selector (void) const + { return (hb_aat_layout_feature_selector_t) (unsigned) setting; } + + inline void get_info (hb_aat_layout_feature_selector_info_t *s, + hb_aat_layout_feature_selector_t default_selector) const + { + s->name_id = nameIndex; + + s->enable = (hb_aat_layout_feature_selector_t) (unsigned int) setting; + s->disable = default_selector == HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID ? + (hb_aat_layout_feature_selector_t) (s->enable + 1) : + default_selector; + + s->reserved = 0; + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -51,35 +72,76 @@ struct SettingName public: DEFINE_SIZE_STATIC (4); }; +DECLARE_NULL_NAMESPACE_BYTES (AAT, SettingName); + +struct feat; struct FeatureName { + int cmp (hb_aat_layout_feature_type_t key) const + { return (int) key - (int) feature; } + enum { - Exclusive = 0x8000, /* If set, the feature settings are mutually exclusive. */ - NotDefault = 0x4000, /* If clear, then the setting with an index of 0 in + Exclusive = 0x8000, /* If set, the feature settings are mutually exclusive. */ + NotDefault = 0x4000, /* If clear, then the setting with an index of 0 in * the setting name array for this feature should * be taken as the default for the feature * (if one is required). If set, then bits 0-15 of this * featureFlags field contain the index of the setting * which is to be taken as the default. */ - IndexMask = 0x00FF /* If bits 30 and 31 are set, then these sixteen bits + IndexMask = 0x00FF /* If bits 30 and 31 are set, then these sixteen bits * indicate the index of the setting in the setting name * array for this feature which should be taken * as the default. */ }; + inline unsigned int get_selector_infos (unsigned int start_offset, + unsigned int *selectors_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */ + unsigned int *pdefault_index, /* OUT. May be NULL. */ + const void *base) const + { + hb_array_t< const SettingName> settings_table = (base+settingTableZ).as_array (nSettings); + + static_assert (Index::NOT_FOUND_INDEX == HB_AAT_LAYOUT_NO_SELECTOR_INDEX, ""); + + hb_aat_layout_feature_selector_t default_selector = HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID; + unsigned int default_index = Index::NOT_FOUND_INDEX; + if (featureFlags & Exclusive) + { + default_index = (featureFlags & NotDefault) ? featureFlags & IndexMask : 0; + default_selector = settings_table[default_index].get_selector (); + } + if (pdefault_index) + *pdefault_index = default_index; + + if (selectors_count) + { + hb_array_t arr = settings_table.sub_array (start_offset, selectors_count); + unsigned int count = arr.len; + for (unsigned int i = 0; i < count; i++) + settings_table[start_offset + i].get_info (&selectors[i], default_selector); + } + return settings_table.len; + } + + inline hb_aat_layout_feature_type_t get_feature_type () const + { return (hb_aat_layout_feature_type_t) (unsigned int) feature; } + + inline hb_ot_name_id_t get_feature_name_id () const { return nameIndex; } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - (base+settingTable).sanitize (c, nSettings))); + (base+settingTableZ).sanitize (c, nSettings))); } protected: HBUINT16 feature; /* Feature type. */ HBUINT16 nSettings; /* The number of records in the setting name array. */ LOffsetTo, false> - settingTable; /* Offset in bytes from the beginning of this table to + settingTableZ; /* Offset in bytes from the beginning of this table to * this feature's setting name array. The actual type of * record this offset refers to will depend on the * exclusivity value, as described below. */ @@ -95,11 +157,47 @@ struct feat { static const hb_tag_t tableTag = HB_AAT_TAG_feat; + inline bool has_data (void) const { return version.to_int (); } + + inline unsigned int get_feature_types (unsigned int start_offset, + unsigned int *count, + hb_aat_layout_feature_type_t *features) const + { + unsigned int feature_count = featureNameCount; + if (count && *count) + { + unsigned int len = MIN (feature_count - start_offset, *count); + for (unsigned int i = 0; i < len; i++) + features[i] = namesZ[i + start_offset].get_feature_type (); + *count = len; + } + return featureNameCount; + } + + inline const FeatureName& get_feature (hb_aat_layout_feature_type_t feature_type) const + { + return namesZ.bsearch (featureNameCount, feature_type); + } + + inline hb_ot_name_id_t get_feature_name_id (hb_aat_layout_feature_type_t feature) const + { return get_feature (feature).get_feature_name_id (); } + + inline unsigned int get_selector_infos (hb_aat_layout_feature_type_t feature_type, + unsigned int start_offset, + unsigned int *selectors_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */ + unsigned int *default_index /* OUT. May be NULL. */) const + { + return get_feature (feature_type).get_selector_infos (start_offset, selectors_count, selectors, + default_index, this); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - names.sanitize (c, featureNameCount, this))); + version.major == 1 && + namesZ.sanitize (c, featureNameCount, this))); } protected: @@ -109,8 +207,8 @@ struct feat /* The number of entries in the feature name array. */ HBUINT16 reserved1; /* Reserved (set to zero). */ HBUINT32 reserved2; /* Reserved (set to zero). */ - UnsizedArrayOf - names; /* The feature name array. */ + SortedUnsizedArrayOf + namesZ; /* The feature name array. */ public: DEFINE_SIZE_STATIC (24); }; diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index f075a270a..7caf45d5d 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -49,7 +49,7 @@ kerxTupleKern (int value, const void *base, hb_aat_apply_context_t *c) { - if (likely (!tupleCount)) return value; + if (likely (!tupleCount || !c)) return value; unsigned int offset = value; const FWORD *pv = &StructAtOffset (base, offset); @@ -93,21 +93,11 @@ struct KernPair template struct KerxSubTableFormat0 { - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { - hb_glyph_pair_t pair = {left, right}; - int i = pairs.bsearch (pair); - if (i == -1) return 0; - return pairs[i].get_kerning (); - } - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, - hb_aat_apply_context_t *c) const + hb_aat_apply_context_t *c = nullptr) const { hb_glyph_pair_t pair = {left, right}; - int i = pairs.bsearch (pair); - if (i == -1) return 0; - int v = pairs[i].get_kerning (); + int v = pairs.bsearch (pair).get_kerning (); return kerxTupleKern (v, header.tuple_count (), this, c); } @@ -265,7 +255,7 @@ struct KerxSubTableFormat1 unsigned int tuple_count = MAX (1u, table->header.tuple_count ()); unsigned int kern_idx = Format1EntryT::kernActionIndex (entry); - kern_idx = Types::offsetToIndex (kern_idx, &table->machine, kernAction.arrayZ); + kern_idx = Types::byteOffsetToIndex (kern_idx, &table->machine, kernAction.arrayZ); const FWORD *actions = &kernAction[kern_idx]; if (!c->sanitizer.check_array (actions, depth, tuple_count)) { @@ -402,9 +392,13 @@ struct KerxSubTableFormat2 unsigned int num_glyphs = c->sanitizer.get_num_glyphs (); unsigned int l = (this+leftClassTable).get_class (left, num_glyphs, 0); unsigned int r = (this+rightClassTable).get_class (right, num_glyphs, 0); - unsigned int offset = l + r; - const FWORD *v = &StructAtOffset (&(this+array), offset); + + const UnsizedArrayOf &arrayZ = this+array; + unsigned int kern_idx = l + r; + kern_idx = Types::offsetToIndex (kern_idx, this, &arrayZ); + const FWORD *v = &arrayZ[kern_idx]; if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + return kerxTupleKern (*v, header.tuple_count (), this, c); } @@ -447,19 +441,13 @@ struct KerxSubTableFormat2 c->check_range (this, array))); } - /* Note: - * OT kern table specifies ClassTable as having 16-bit entries, whereas - * AAT kern table specifies them as having 8bit entries. - * I've not seen any fonts with this format in kern table. - * We follow AAT. */ - protected: KernSubTableHeader header; HBUINT rowWidth; /* The width, in bytes, of a row in the table. */ - OffsetTo + OffsetTo leftClassTable; /* Offset from beginning of this subtable to * left-hand class table. */ - OffsetTo + OffsetTo rightClassTable;/* Offset from beginning of this subtable to * right-hand class table. */ OffsetTo, HBUINT, false> @@ -812,6 +800,7 @@ struct KerxSubTable { TRACE_SANITIZE (this); if (!u.header.sanitize (c) || + u.header.length <= u.header.static_size || !c->check_range (this, u.header.length)) return_trace (false); @@ -842,6 +831,21 @@ struct KerxTable /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ inline const T* thiz (void) const { return static_cast (this); } + inline bool has_state_machine (void) const + { + typedef typename T::SubTable SubTable; + + const SubTable *st = &thiz()->firstSubTable; + unsigned int count = thiz()->tableCount; + for (unsigned int i = 0; i < count; i++) + { + if (st->get_type () == 1) + return true; + st = &StructAfter (*st); + } + return false; + } + inline bool has_cross_stream (void) const { typedef typename T::SubTable SubTable; @@ -920,9 +924,11 @@ struct KerxTable if (reverse) c->buffer->reverse (); - c->sanitizer.set_object (*st); - - ret |= st->dispatch (c); + { + /* See comment in sanitize() for conditional here. */ + hb_sanitize_with_object_t with (&c->sanitizer, i < count - 1 ? st : (const SubTable *) nullptr); + ret |= st->dispatch (c); + } if (reverse) c->buffer->reverse (); @@ -951,8 +957,20 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { + if (unlikely (!st->u.header.sanitize (c))) + return_trace (false); + /* OpenType kern table has 2-byte subtable lengths. That's limiting. + * MS implementation also only supports one subtable, of format 0, + * anyway. Certain versions of some fonts, like Calibry, contain + * kern subtable that exceeds 64kb. Looks like, the subtable length + * is simply ignored. Which makes sense. It's only needed if you + * have multiple subtables. To handle such fonts, we just ignore + * the length for the last subtable. */ + hb_sanitize_with_object_t with (c, i < count - 1 ? st : (const SubTable *) nullptr); + if (unlikely (!st->sanitize (c))) return_trace (false); + st = &StructAfter (*st); } diff --git a/src/hb-aat-layout-lcar-table.hh b/src/hb-aat-layout-lcar-table.hh index 43ac74f9c..40d34f59b 100644 --- a/src/hb-aat-layout-lcar-table.hh +++ b/src/hb-aat-layout-lcar-table.hh @@ -52,10 +52,10 @@ struct lcar const OffsetTo* entry_offset = lookup.get_value (glyph, font->face->get_num_glyphs ()); const LigCaretClassEntry& array = entry_offset ? this+*entry_offset : Null (LigCaretClassEntry); - if (caret_count && *caret_count) + if (caret_count) { - const HBINT16 *arr = array.sub_array (start_offset, caret_count); - unsigned int count = *caret_count; + hb_array_t arr = array.sub_array (start_offset, caret_count); + unsigned int count = arr.len; for (unsigned int i = 0; i < count; ++i) switch (format) { diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 430732702..171ee4a10 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -911,14 +911,22 @@ struct ChainSubtable } } + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + hb_sanitize_with_object_t with (&c->sanitizer, this); + return_trace (dispatch (c)); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); if (!length.sanitize (c) || - length < min_size || + length <= min_size || !c->check_range (this, length)) return_trace (false); + hb_sanitize_with_object_t with (c, this); return_trace (dispatch (c)); } @@ -949,21 +957,21 @@ struct Chain unsigned int count = featureCount; for (unsigned i = 0; i < count; i++) { - const Feature &feature = featureZ[i]; - uint16_t type = feature.featureType; - uint16_t setting = feature.featureSetting; + const Feature &feature = featureZ[i]; + hb_aat_layout_feature_type_t type = (hb_aat_layout_feature_type_t) (unsigned int) feature.featureType; + hb_aat_layout_feature_selector_t setting = (hb_aat_layout_feature_selector_t) (unsigned int) feature.featureSetting; retry: - const hb_aat_map_builder_t::feature_info_t *info = map->features.bsearch (type); + const hb_aat_map_builder_t::feature_info_t *info = map->features.bsearch ((uint16_t) type); if (info && info->setting == setting) { flags &= feature.disableFlags; flags |= feature.enableFlags; } - else if (type == 3/*kLetterCaseType*/ && setting == 3/*kSmallCapsSelector*/) + else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE && setting == HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS) { /* Deprecated. https://github.com/harfbuzz/harfbuzz/issues/1342 */ - type = 37/*kLowerCaseType*/; - setting = 1/*kLowerCaseSmallCapsSelector*/; + type = HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE; + setting = HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS; goto retry; } } @@ -1026,9 +1034,7 @@ struct Chain if (reverse) c->buffer->reverse (); - c->sanitizer.set_object (*subtable); - - subtable->dispatch (c); + subtable->apply (c); if (reverse) c->buffer->reverse (); diff --git a/src/hb-aat-layout-trak-table.hh b/src/hb-aat-layout-trak-table.hh index 91c0f4562..5474d1d11 100644 --- a/src/hb-aat-layout-trak-table.hh +++ b/src/hb-aat-layout-trak-table.hh @@ -133,7 +133,6 @@ struct TrackData if (!sizes) return 0.; if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes); - /* TODO bfind() */ hb_array_t size_table ((base+sizeTable).arrayZ, sizes); unsigned int size_index; for (size_index = 0; size_index < sizes - 1; size_index++) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index d9580c152..727da42a8 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -1,5 +1,6 @@ /* * Copyright © 2017 Google, Inc. + * Copyright © 2018 Ebrahim Byagowi * * This is part of HarfBuzz, a text shaping library. * @@ -30,7 +31,7 @@ #include "hb-aat-layout.hh" #include "hb-aat-layout-ankr-table.hh" #include "hb-aat-layout-bsln-table.hh" // Just so we compile it; unused otherwise. -#include "hb-aat-layout-feat-table.hh" // Just so we compile it; unused otherwise. +#include "hb-aat-layout-feat-table.hh" #include "hb-aat-layout-just-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" @@ -38,86 +39,96 @@ #include "hb-aat-ltag-table.hh" +/** + * SECTION:hb-aat-layout + * @title: hb-aat-layout + * @short_description: Apple Advanced Typography Layout + * @include: hb-aat.h + * + * Functions for querying OpenType Layout features in the font face. + **/ + + /* Table data courtesy of Apple. Converted from mnemonics to integers * when moving to this file. */ static const hb_aat_feature_mapping_t feature_mappings[] = { - {HB_TAG ('a','f','r','c'), 11/*kFractionsType*/, 1/*kVerticalFractionsSelector*/, 0/*kNoFractionsSelector*/}, - {HB_TAG ('c','2','p','c'), 38/*kUpperCaseType*/, 2/*kUpperCasePetiteCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, - {HB_TAG ('c','2','s','c'), 38/*kUpperCaseType*/, 1/*kUpperCaseSmallCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, - {HB_TAG ('c','a','l','t'), 36/*kContextualAlternatesType*/, 0/*kContextualAlternatesOnSelector*/, 1/*kContextualAlternatesOffSelector*/}, - {HB_TAG ('c','a','s','e'), 33/*kCaseSensitiveLayoutType*/, 0/*kCaseSensitiveLayoutOnSelector*/, 1/*kCaseSensitiveLayoutOffSelector*/}, - {HB_TAG ('c','l','i','g'), 1/*kLigaturesType*/, 18/*kContextualLigaturesOnSelector*/, 19/*kContextualLigaturesOffSelector*/}, - {HB_TAG ('c','p','s','p'), 33/*kCaseSensitiveLayoutType*/, 2/*kCaseSensitiveSpacingOnSelector*/, 3/*kCaseSensitiveSpacingOffSelector*/}, - {HB_TAG ('c','s','w','h'), 36/*kContextualAlternatesType*/, 4/*kContextualSwashAlternatesOnSelector*/, 5/*kContextualSwashAlternatesOffSelector*/}, - {HB_TAG ('d','l','i','g'), 1/*kLigaturesType*/, 4/*kRareLigaturesOnSelector*/, 5/*kRareLigaturesOffSelector*/}, - {HB_TAG ('e','x','p','t'), 20/*kCharacterShapeType*/, 10/*kExpertCharactersSelector*/, 16}, - {HB_TAG ('f','r','a','c'), 11/*kFractionsType*/, 2/*kDiagonalFractionsSelector*/, 0/*kNoFractionsSelector*/}, - {HB_TAG ('f','w','i','d'), 22/*kTextSpacingType*/, 1/*kMonospacedTextSelector*/, 7}, - {HB_TAG ('h','a','l','t'), 22/*kTextSpacingType*/, 6/*kAltHalfWidthTextSelector*/, 7}, - {HB_TAG ('h','i','s','t'), 1/*kLigaturesType*/, 20/*kHistoricalLigaturesOnSelector*/, 21/*kHistoricalLigaturesOffSelector*/}, - {HB_TAG ('h','k','n','a'), 34/*kAlternateKanaType*/, 0/*kAlternateHorizKanaOnSelector*/, 1/*kAlternateHorizKanaOffSelector*/, }, - {HB_TAG ('h','l','i','g'), 1/*kLigaturesType*/, 20/*kHistoricalLigaturesOnSelector*/, 21/*kHistoricalLigaturesOffSelector*/}, - {HB_TAG ('h','n','g','l'), 23/*kTransliterationType*/, 1/*kHanjaToHangulSelector*/, 0/*kNoTransliterationSelector*/}, - {HB_TAG ('h','o','j','o'), 20/*kCharacterShapeType*/, 12/*kHojoCharactersSelector*/, 16}, - {HB_TAG ('h','w','i','d'), 22/*kTextSpacingType*/, 2/*kHalfWidthTextSelector*/, 7}, - {HB_TAG ('i','t','a','l'), 32/*kItalicCJKRomanType*/, 2/*kCJKItalicRomanOnSelector*/, 3/*kCJKItalicRomanOffSelector*/}, - {HB_TAG ('j','p','0','4'), 20/*kCharacterShapeType*/, 11/*kJIS2004CharactersSelector*/, 16}, - {HB_TAG ('j','p','7','8'), 20/*kCharacterShapeType*/, 2/*kJIS1978CharactersSelector*/, 16}, - {HB_TAG ('j','p','8','3'), 20/*kCharacterShapeType*/, 3/*kJIS1983CharactersSelector*/, 16}, - {HB_TAG ('j','p','9','0'), 20/*kCharacterShapeType*/, 4/*kJIS1990CharactersSelector*/, 16}, - {HB_TAG ('l','i','g','a'), 1/*kLigaturesType*/, 2/*kCommonLigaturesOnSelector*/, 3/*kCommonLigaturesOffSelector*/}, - {HB_TAG ('l','n','u','m'), 21/*kNumberCaseType*/, 1/*kUpperCaseNumbersSelector*/, 2}, - {HB_TAG ('m','g','r','k'), 15/*kMathematicalExtrasType*/, 10/*kMathematicalGreekOnSelector*/, 11/*kMathematicalGreekOffSelector*/}, - {HB_TAG ('n','l','c','k'), 20/*kCharacterShapeType*/, 13/*kNLCCharactersSelector*/, 16}, - {HB_TAG ('o','n','u','m'), 21/*kNumberCaseType*/, 0/*kLowerCaseNumbersSelector*/, 2}, - {HB_TAG ('o','r','d','n'), 10/*kVerticalPositionType*/, 3/*kOrdinalsSelector*/, 0/*kNormalPositionSelector*/}, - {HB_TAG ('p','a','l','t'), 22/*kTextSpacingType*/, 5/*kAltProportionalTextSelector*/, 7}, - {HB_TAG ('p','c','a','p'), 37/*kLowerCaseType*/, 2/*kLowerCasePetiteCapsSelector*/, 0/*kDefaultLowerCaseSelector*/}, - {HB_TAG ('p','k','n','a'), 22/*kTextSpacingType*/, 0/*kProportionalTextSelector*/, 7}, - {HB_TAG ('p','n','u','m'), 6/*kNumberSpacingType*/, 1/*kProportionalNumbersSelector*/, 4}, - {HB_TAG ('p','w','i','d'), 22/*kTextSpacingType*/, 0/*kProportionalTextSelector*/, 7}, - {HB_TAG ('q','w','i','d'), 22/*kTextSpacingType*/, 4/*kQuarterWidthTextSelector*/, 7}, - {HB_TAG ('r','u','b','y'), 28/*kRubyKanaType*/, 2/*kRubyKanaOnSelector*/, 3/*kRubyKanaOffSelector*/}, - {HB_TAG ('s','i','n','f'), 10/*kVerticalPositionType*/, 4/*kScientificInferiorsSelector*/, 0/*kNormalPositionSelector*/}, - {HB_TAG ('s','m','c','p'), 37/*kLowerCaseType*/, 1/*kLowerCaseSmallCapsSelector*/, 0/*kDefaultLowerCaseSelector*/}, - {HB_TAG ('s','m','p','l'), 20/*kCharacterShapeType*/, 1/*kSimplifiedCharactersSelector*/, 16}, - {HB_TAG ('s','s','0','1'), 35/*kStylisticAlternativesType*/, 2/*kStylisticAltOneOnSelector*/, 3/*kStylisticAltOneOffSelector*/}, - {HB_TAG ('s','s','0','2'), 35/*kStylisticAlternativesType*/, 4/*kStylisticAltTwoOnSelector*/, 5/*kStylisticAltTwoOffSelector*/}, - {HB_TAG ('s','s','0','3'), 35/*kStylisticAlternativesType*/, 6/*kStylisticAltThreeOnSelector*/, 7/*kStylisticAltThreeOffSelector*/}, - {HB_TAG ('s','s','0','4'), 35/*kStylisticAlternativesType*/, 8/*kStylisticAltFourOnSelector*/, 9/*kStylisticAltFourOffSelector*/}, - {HB_TAG ('s','s','0','5'), 35/*kStylisticAlternativesType*/, 10/*kStylisticAltFiveOnSelector*/, 11/*kStylisticAltFiveOffSelector*/}, - {HB_TAG ('s','s','0','6'), 35/*kStylisticAlternativesType*/, 12/*kStylisticAltSixOnSelector*/, 13/*kStylisticAltSixOffSelector*/}, - {HB_TAG ('s','s','0','7'), 35/*kStylisticAlternativesType*/, 14/*kStylisticAltSevenOnSelector*/, 15/*kStylisticAltSevenOffSelector*/}, - {HB_TAG ('s','s','0','8'), 35/*kStylisticAlternativesType*/, 16/*kStylisticAltEightOnSelector*/, 17/*kStylisticAltEightOffSelector*/}, - {HB_TAG ('s','s','0','9'), 35/*kStylisticAlternativesType*/, 18/*kStylisticAltNineOnSelector*/, 19/*kStylisticAltNineOffSelector*/}, - {HB_TAG ('s','s','1','0'), 35/*kStylisticAlternativesType*/, 20/*kStylisticAltTenOnSelector*/, 21/*kStylisticAltTenOffSelector*/}, - {HB_TAG ('s','s','1','1'), 35/*kStylisticAlternativesType*/, 22/*kStylisticAltElevenOnSelector*/, 23/*kStylisticAltElevenOffSelector*/}, - {HB_TAG ('s','s','1','2'), 35/*kStylisticAlternativesType*/, 24/*kStylisticAltTwelveOnSelector*/, 25/*kStylisticAltTwelveOffSelector*/}, - {HB_TAG ('s','s','1','3'), 35/*kStylisticAlternativesType*/, 26/*kStylisticAltThirteenOnSelector*/, 27/*kStylisticAltThirteenOffSelector*/}, - {HB_TAG ('s','s','1','4'), 35/*kStylisticAlternativesType*/, 28/*kStylisticAltFourteenOnSelector*/, 29/*kStylisticAltFourteenOffSelector*/}, - {HB_TAG ('s','s','1','5'), 35/*kStylisticAlternativesType*/, 30/*kStylisticAltFifteenOnSelector*/, 31/*kStylisticAltFifteenOffSelector*/}, - {HB_TAG ('s','s','1','6'), 35/*kStylisticAlternativesType*/, 32/*kStylisticAltSixteenOnSelector*/, 33/*kStylisticAltSixteenOffSelector*/}, - {HB_TAG ('s','s','1','7'), 35/*kStylisticAlternativesType*/, 34/*kStylisticAltSeventeenOnSelector*/, 35/*kStylisticAltSeventeenOffSelector*/}, - {HB_TAG ('s','s','1','8'), 35/*kStylisticAlternativesType*/, 36/*kStylisticAltEighteenOnSelector*/, 37/*kStylisticAltEighteenOffSelector*/}, - {HB_TAG ('s','s','1','9'), 35/*kStylisticAlternativesType*/, 38/*kStylisticAltNineteenOnSelector*/, 39/*kStylisticAltNineteenOffSelector*/}, - {HB_TAG ('s','s','2','0'), 35/*kStylisticAlternativesType*/, 40/*kStylisticAltTwentyOnSelector*/, 41/*kStylisticAltTwentyOffSelector*/}, - {HB_TAG ('s','u','b','s'), 10/*kVerticalPositionType*/, 2/*kInferiorsSelector*/, 0/*kNormalPositionSelector*/}, - {HB_TAG ('s','u','p','s'), 10/*kVerticalPositionType*/, 1/*kSuperiorsSelector*/, 0/*kNormalPositionSelector*/}, - {HB_TAG ('s','w','s','h'), 36/*kContextualAlternatesType*/, 2/*kSwashAlternatesOnSelector*/, 3/*kSwashAlternatesOffSelector*/}, - {HB_TAG ('t','i','t','l'), 19/*kStyleOptionsType*/, 4/*kTitlingCapsSelector*/, 0/*kNoStyleOptionsSelector*/}, - {HB_TAG ('t','n','a','m'), 20/*kCharacterShapeType*/, 14/*kTraditionalNamesCharactersSelector*/, 16}, - {HB_TAG ('t','n','u','m'), 6/*kNumberSpacingType*/, 0/*kMonospacedNumbersSelector*/, 4}, - {HB_TAG ('t','r','a','d'), 20/*kCharacterShapeType*/, 0/*kTraditionalCharactersSelector*/, 16}, - {HB_TAG ('t','w','i','d'), 22/*kTextSpacingType*/, 3/*kThirdWidthTextSelector*/, 7}, - {HB_TAG ('u','n','i','c'), 3/*kLetterCaseType*/, 14, 15}, - {HB_TAG ('v','a','l','t'), 22/*kTextSpacingType*/, 5/*kAltProportionalTextSelector*/, 7}, - {HB_TAG ('v','e','r','t'), 4/*kVerticalSubstitutionType*/, 0/*kSubstituteVerticalFormsOnSelector*/, 1/*kSubstituteVerticalFormsOffSelector*/}, - {HB_TAG ('v','h','a','l'), 22/*kTextSpacingType*/, 6/*kAltHalfWidthTextSelector*/, 7}, - {HB_TAG ('v','k','n','a'), 34/*kAlternateKanaType*/, 2/*kAlternateVertKanaOnSelector*/, 3/*kAlternateVertKanaOffSelector*/}, - {HB_TAG ('v','p','a','l'), 22/*kTextSpacingType*/, 5/*kAltProportionalTextSelector*/, 7}, - {HB_TAG ('v','r','t','2'), 4/*kVerticalSubstitutionType*/, 0/*kSubstituteVerticalFormsOnSelector*/, 1/*kSubstituteVerticalFormsOffSelector*/}, - {HB_TAG ('z','e','r','o'), 14/*kTypographicExtrasType*/, 4/*kSlashedZeroOnSelector*/, 5/*kSlashedZeroOffSelector*/}, + {HB_TAG ('a','f','r','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS}, + {HB_TAG ('c','2','p','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE}, + {HB_TAG ('c','2','s','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE}, + {HB_TAG ('c','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF}, + {HB_TAG ('c','a','s','e'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF}, + {HB_TAG ('c','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF}, + {HB_TAG ('c','p','s','p'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF}, + {HB_TAG ('c','s','w','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF}, + {HB_TAG ('d','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF}, + {HB_TAG ('e','x','p','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('f','r','a','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS}, + {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('h','i','s','t'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF}, + {HB_TAG ('h','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF}, + {HB_TAG ('h','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF}, + {HB_TAG ('h','n','g','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION, HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION}, + {HB_TAG ('h','o','j','o'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('h','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('i','t','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN, HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF}, + {HB_TAG ('j','p','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('j','p','7','8'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('j','p','8','3'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('j','p','9','0'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('l','i','g','a'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF}, + {HB_TAG ('l','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS, (hb_aat_layout_feature_selector_t) 2}, + {HB_TAG ('m','g','r','k'), HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS, HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF}, + {HB_TAG ('n','l','c','k'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('o','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS, (hb_aat_layout_feature_selector_t) 2}, + {HB_TAG ('o','r','d','n'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, + {HB_TAG ('p','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('p','c','a','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE}, + {HB_TAG ('p','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS, (hb_aat_layout_feature_selector_t) 4}, + {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF}, + {HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, + {HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE}, + {HB_TAG ('s','m','p','l'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('s','s','0','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF}, + {HB_TAG ('s','s','0','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF}, + {HB_TAG ('s','s','0','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF}, + {HB_TAG ('s','s','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF}, + {HB_TAG ('s','s','0','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF}, + {HB_TAG ('s','s','0','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF}, + {HB_TAG ('s','s','0','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF}, + {HB_TAG ('s','s','0','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF}, + {HB_TAG ('s','s','0','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF}, + {HB_TAG ('s','s','1','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF}, + {HB_TAG ('s','s','1','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF}, + {HB_TAG ('s','s','1','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF}, + {HB_TAG ('s','s','1','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF}, + {HB_TAG ('s','s','1','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF}, + {HB_TAG ('s','s','1','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF}, + {HB_TAG ('s','s','1','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF}, + {HB_TAG ('s','s','1','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF}, + {HB_TAG ('s','s','1','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF}, + {HB_TAG ('s','s','1','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF}, + {HB_TAG ('s','s','2','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF}, + {HB_TAG ('s','u','b','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, + {HB_TAG ('s','u','p','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, + {HB_TAG ('s','w','s','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF}, + {HB_TAG ('t','i','t','l'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS}, + {HB_TAG ('t','n','a','m'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('t','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS, (hb_aat_layout_feature_selector_t) 4}, + {HB_TAG ('t','r','a','d'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('t','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('u','n','i','c'), HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE, (hb_aat_layout_feature_selector_t) 14, (hb_aat_layout_feature_selector_t) 15}, + {HB_TAG ('v','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('v','e','r','t'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, + {HB_TAG ('v','h','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('v','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF}, + {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('v','r','t','2'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, + {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF}, }; const hb_aat_feature_mapping_t * @@ -297,3 +308,65 @@ _hb_aat_language_get (hb_face_t *face, { return face->table.ltag->get_language (i); } + +/** + * hb_aat_layout_get_feature_types: + * @face: a face object + * @start_offset: iteration's start offset + * @feature_count:(inout) (allow-none): buffer size as input, filled size as output + * @features: (out caller-allocates) (array length=feature_count): features buffer + * + * Return value: Number of all available feature types. + * + * Since: REPLACEME + */ +unsigned int +hb_aat_layout_get_feature_types (hb_face_t *face, + unsigned int start_offset, + unsigned int *feature_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */) +{ + return face->table.feat->get_feature_types (start_offset, feature_count, features); +} + +/** + * hb_aat_layout_feature_type_get_name_id: + * @face: a face object + * @feature_type: feature id + * + * Return value: Name ID index + * + * Since: REPLACEME + */ +hb_ot_name_id_t +hb_aat_layout_feature_type_get_name_id (hb_face_t *face, + hb_aat_layout_feature_type_t feature_type) +{ return face->table.feat->get_feature_name_id (feature_type); } + +/** + * hb_aat_layout_feature_type_get_selectors: + * @face: a face object + * @feature_type: feature id + * @start_offset: iteration's start offset + * @selector_count: (inout) (allow-none): buffer size as input, filled size as output + * @selectors: (out caller-allocates) (array length=selector_count): settings buffer + * @default_index: (out) (allow-none): index of default selector if any + * + * If upon return, @default_index is set to #HB_AAT_LAYOUT_NO_SELECTOR_INDEX, then + * the feature type is non-exclusive. Otherwise, @default_index is the index of + * the selector that is selected by default. + * + * Return value: Number of all available feature selectors. + * + * Since: REPLACEME + */ +unsigned int +hb_aat_layout_feature_type_get_selector_infos (hb_face_t *face, + hb_aat_layout_feature_type_t feature_type, + unsigned int start_offset, + unsigned int *selector_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */ + unsigned int *default_index /* OUT. May be NULL. */) +{ + return face->table.feat->get_selector_infos (feature_type, start_offset, selector_count, selectors, default_index); +} diff --git a/src/hb-aat-layout.h b/src/hb-aat-layout.h new file mode 100644 index 000000000..5912e012b --- /dev/null +++ b/src/hb-aat-layout.h @@ -0,0 +1,462 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * 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_AAT_H_IN +#error "Include instead." +#endif + +#ifndef HB_AAT_LAYOUT_H +#define HB_AAT_LAYOUT_H + +#include "hb.h" + +#include "hb-ot.h" + +HB_BEGIN_DECLS + +/** + * hb_aat_layout_feature_type_t: + * + * + * Since: REPLACEME + */ +typedef enum +{ + HB_AAT_LAYOUT_FEATURE_TYPE_INVALID = 0xFFFF, + + HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC = 0, + HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1, + HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION = 2, + HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3, + HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4, + HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT = 5, + HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING = 6, + HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE = 8, + HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE = 9, + HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION = 10, + HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS = 11, + HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE = 13, + HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS = 14, + HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS = 15, + HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE = 16, + HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES = 17, + HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE = 18, + HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS = 19, + HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE = 20, + HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE = 21, + HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING = 22, + HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION = 23, + HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE = 24, + HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE = 25, + HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE = 26, + HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE = 27, + HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA = 28, + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE = 29, + HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE = 30, + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE = 31, + HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN = 32, + HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT = 33, + HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA = 34, + HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES = 35, + HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES = 36, + HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE = 37, + HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE = 38, + HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39, + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103, + + _HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/ +} hb_aat_layout_feature_type_t; + +/** + * hb_aat_layout_feature_selector_t: + * + * + * Since: REPLACEME + */ +typedef enum +{ + HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID = 0xFFFF, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_OFF = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_ON = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_OFF = 11, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_ON = 12, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_OFF = 13, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_ON = 14, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF = 15, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_ON = 16, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_OFF = 17, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON = 18, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF = 19, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON = 20, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF = 21, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_UNCONNECTED = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PARTIALLY_CONNECTED = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CURSIVE = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_AND_LOWER_CASE = 0, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_CAPS = 1, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_LOWER_CASE = 2, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS = 3, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS = 4, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS = 5, /* deprecated */ + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_NUMBERS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_NUMBERS = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_OFF = 9, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_SHOW_DIACRITICS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HIDE_DIACRITICS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DECOMPOSE_DIACRITICS = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS = 4, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_OFF = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_ON = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_OFF = 11, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF = 11, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ORNAMENTS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DINGBATS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PI_CHARACTERS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FLEURONS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DECORATIVE_BORDERS = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INTERNATIONAL_SYMBOLS = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MATH_SYMBOLS = 6, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ALTERNATES = 0, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL1 = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL2 = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL3 = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL4 = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL5 = 4, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DISPLAY_TEXT = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ENGRAVED_TEXT = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ILLUMINATED_CAPS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TALL_CAPS = 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_ONE = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_TWO = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_THREE = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FOUR = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FIVE = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS = 11, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS = 12, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS = 13, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS = 14, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT = 6, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HIRAGANA_TO_KATAKANA = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_KATAKANA_TO_HIRAGANA = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_KANA_TO_ROMANIZATION = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_HIRAGANA = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_KATAKANA = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_ONE = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_TWO = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_THREE = 9, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ANNOTATION = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_BOX_ANNOTATION = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ROUNDED_BOX_ANNOTATION = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CIRCLE_ANNOTATION = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_CIRCLE_ANNOTATION = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PARENTHESIS_ANNOTATION = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIOD_ANNOTATION = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMAN_NUMERAL_ANNOTATION = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAMOND_ANNOTATION = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_BOX_ANNOTATION = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION= 10, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_KANA = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_KANA = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_IDEOGRAPHS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_IDEOGRAPHS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_IDEOGRAPHS = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_OFF = 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_RUBY_KANA = 0, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF instead */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA = 1, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON instead */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_ONE = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_TWO = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_THREE = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FOUR = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FIVE = 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_ONE = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_TWO = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_THREE = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FOUR = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FIVE = 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_ITALIC_ROMAN = 0, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF instead */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN = 1, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON instead */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLISTIC_ALTERNATES = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF = 11, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON = 12, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF = 13, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON = 14, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF = 15, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON = 16, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF = 17, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON = 18, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF = 19, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON = 20, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF = 21, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON = 22, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF = 23, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON = 24, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF = 25, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON = 26, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF = 27, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON = 28, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF = 29, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON = 30, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF = 31, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON = 32, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF = 33, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON = 34, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF = 35, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON = 36, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF = 37, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON = 38, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF = 39, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON = 40, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF = 41, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF= 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_CJK_ROMAN = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_CJK_ROMAN = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3, + + _HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/ +} hb_aat_layout_feature_selector_t; + +HB_EXTERN unsigned int +hb_aat_layout_get_feature_types (hb_face_t *face, + unsigned int start_offset, + unsigned int *feature_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */); + +HB_EXTERN hb_ot_name_id_t +hb_aat_layout_feature_type_get_name_id (hb_face_t *face, + hb_aat_layout_feature_type_t feature_type); + +typedef struct hb_aat_layout_feature_selector_info_t +{ + hb_ot_name_id_t name_id; + hb_aat_layout_feature_selector_t enable; + hb_aat_layout_feature_selector_t disable; + /*< private >*/ + unsigned int reserved; +} hb_aat_layout_feature_selector_info_t; + +#define HB_AAT_LAYOUT_NO_SELECTOR_INDEX 0xFFFFu + +HB_EXTERN unsigned int +hb_aat_layout_feature_type_get_selector_infos (hb_face_t *face, + hb_aat_layout_feature_type_t feature_type, + unsigned int start_offset, + unsigned int *selector_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */ + unsigned int *default_index /* OUT. May be NULL. */); + + +HB_END_DECLS + +#endif /* HB_AAT_LAYOUT_H */ diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index 1d3407971..5fd47ed62 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -35,9 +35,9 @@ struct hb_aat_feature_mapping_t { hb_tag_t otFeatureTag; - uint16_t aatFeatureType; - uint16_t selectorToEnable; - uint16_t selectorToDisable; + hb_aat_layout_feature_type_t aatFeatureType; + hb_aat_layout_feature_selector_t selectorToEnable; + hb_aat_layout_feature_selector_t selectorToDisable; static inline int cmp (const void *key_, const void *entry_) { diff --git a/src/hb-aat-map.cc b/src/hb-aat-map.cc index 8bc1a0c61..1c65a6759 100644 --- a/src/hb-aat-map.cc +++ b/src/hb-aat-map.cc @@ -37,8 +37,8 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, if (tag == HB_TAG ('a','a','l','t')) { feature_info_t *info = features.push(); - info->type = 17/*kCharacterAlternativesType*/; - info->setting = value; + info->type = HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES; + info->setting = (hb_aat_layout_feature_selector_t) value; return; } diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh index 07454b2c1..b033e3368 100644 --- a/src/hb-aat-map.hh +++ b/src/hb-aat-map.hh @@ -65,8 +65,8 @@ struct hb_aat_map_builder_t public: struct feature_info_t { - uint16_t type; - uint16_t setting; + hb_aat_layout_feature_type_t type; + hb_aat_layout_feature_selector_t setting; unsigned seq; /* For stable sorting only. */ static int cmp (const void *pa, const void *pb) @@ -77,9 +77,9 @@ struct hb_aat_map_builder_t (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0); } - int cmp (const short unsigned int *ty) const + int cmp (unsigned int ty) const { - return (type != *ty) ? (type < *ty ? -1 : 1) : 0; + return (type != ty) ? (type < ty ? -1 : 1) : 0; } }; diff --git a/src/hb-aat.h b/src/hb-aat.h new file mode 100644 index 000000000..c14313d1e --- /dev/null +++ b/src/hb-aat.h @@ -0,0 +1,38 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * 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_AAT_H +#define HB_AAT_H +#define HB_AAT_H_IN + +#include "hb.h" + +#include "hb-aat-layout.h" + +HB_BEGIN_DECLS + +HB_END_DECLS + +#undef HB_AAT_H_IN +#endif /* HB_AAT_H */ diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index 64ed257bd..265de1267 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -282,7 +282,7 @@ struct hb_atomic_int_t template struct hb_atomic_ptr_t { - typedef typename hb_remove_pointer

::value T; + typedef typename hb_remove_pointer (P) T; inline void init (T* v_ = nullptr) { set_relaxed (v_); } inline void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } diff --git a/src/hb-blob.hh b/src/hb-blob.hh index 802b1f07e..bf2132bda 100644 --- a/src/hb-blob.hh +++ b/src/hb-blob.hh @@ -60,7 +60,7 @@ struct hb_blob_t template inline const Type* as (void) const { - return length < Type::min_size ? &Null(Type) : reinterpret_cast (data); + return length < hb_null_size (Type) ? &Null(Type) : reinterpret_cast (data); } inline hb_bytes_t as_bytes (void) const { @@ -86,7 +86,7 @@ struct hb_blob_t template struct hb_blob_ptr_t { - typedef typename hb_remove_pointer

::value T; + typedef typename hb_remove_pointer (P) T; inline hb_blob_ptr_t (hb_blob_t *b_ = nullptr) : b (b_) {} inline hb_blob_t * operator = (hb_blob_t *b_) { return b = b_; } diff --git a/src/hb-common.cc b/src/hb-common.cc index 37be8a34e..c3cffccb1 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -204,7 +204,7 @@ static const char canon_map[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0, - '-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-', 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0 @@ -276,7 +276,7 @@ struct hb_language_item_t { static hb_atomic_ptr_t langs; -#ifdef HB_USE_ATEXIT +#if HB_USE_ATEXIT static void free_langs (void) { @@ -323,7 +323,7 @@ retry: goto retry; } -#ifdef HB_USE_ATEXIT +#if HB_USE_ATEXIT if (!first_lang) atexit (free_langs); /* First person registers atexit() callback. */ #endif @@ -780,18 +780,18 @@ parse_uint32 (const char **pp, const char *end, uint32_t *pv) #ifdef USE_XLOCALE -#ifdef HB_USE_ATEXIT +#if HB_USE_ATEXIT static void free_static_C_locale (void); #endif -static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t::value, +static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t { static inline HB_LOCALE_T create (void) { HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C"); -#ifdef HB_USE_ATEXIT +#if HB_USE_ATEXIT atexit (free_static_C_locale); #endif @@ -807,7 +807,7 @@ static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t (what, obj, nullptr, true, plevel ? *plevel : 1, -1, + _hb_debug_msg (what, obj, func, true, plevel ? *plevel : 1, -1, "return %s (line %d)", hb_printer_t().print (v), line); if (plevel) --*plevel; @@ -325,17 +327,21 @@ struct hb_auto_trace_t<0, ret_t> const char *message, ...) HB_PRINTF_FUNC(6, 7) {} - inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } + inline ret_t ret (ret_t v, + const char *func HB_UNUSED = 0, + unsigned int line HB_UNUSED = 0) { return v; } }; /* For disabled tracing; optimize out everything. * https://github.com/harfbuzz/harfbuzz/pull/605 */ template struct hb_no_trace_t { - inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } + inline ret_t ret (ret_t v, + const char *func HB_UNUSED = "", + unsigned int line HB_UNUSED = 0) { return v; } }; -#define return_trace(RET) return trace.ret (RET, __LINE__) +#define return_trace(RET) return trace.ret (RET, HB_FUNC, __LINE__) /* diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h index e39b79f74..a74431f05 100644 --- a/src/hb-deprecated.h +++ b/src/hb-deprecated.h @@ -241,6 +241,43 @@ HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) hb_tag_t hb_ot_tag_from_language (hb_language_t language); +typedef unsigned int hb_ot_name_id_t; /* Since is in hb-ot.h */ + +/** + * HB_OT_VAR_NO_AXIS_INDEX: + * + * Since: 1.4.2 + * Deprecated: REPLACEME + */ +#define HB_OT_VAR_NO_AXIS_INDEX 0xFFFFFFFFu + +/** + * hb_ot_var_axis_t: + * + * Since: 1.4.2 + * Deprecated: REPLACEME + */ +typedef struct hb_ot_var_axis_t +{ + hb_tag_t tag; + hb_ot_name_id_t name_id; + float min_value; + float default_value; + float max_value; +} hb_ot_var_axis_t; + +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_var_get_axis_infos) unsigned int +hb_ot_var_get_axes (hb_face_t *face, + unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_t *axes_array /* OUT */); + +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_var_find_axis_info) hb_bool_t +hb_ot_var_find_axis (hb_face_t *face, + hb_tag_t axis_tag, + unsigned int *axis_index, + hb_ot_var_axis_t *axis_info); + #endif HB_END_DECLS diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index da8aad013..577359601 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -559,10 +559,16 @@ struct hb_bytes_t unsigned int len; }; +template +struct hb_sorted_array_t; + template struct hb_array_t { + static_assert ((bool) (unsigned) hb_static_size (Type), ""); + inline hb_array_t (void) : arrayZ (nullptr), len (0) {} + inline hb_array_t (const hb_array_t &o) : arrayZ (o.arrayZ), len (o.len) {} inline hb_array_t (Type *array_, unsigned int len_) : arrayZ (array_), len (len_) {} inline Type& operator [] (unsigned int i) const @@ -571,39 +577,160 @@ struct hb_array_t return arrayZ[i]; } - inline unsigned int get_size (void) const { return len * sizeof (Type); } - - template - inline bool sanitize (hb_sanitize_context_t *c) const - { return c->check_array (arrayZ, len); } - template inline operator T * (void) const { return arrayZ; } inline Type * operator & (void) const { return arrayZ; } - inline hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const + inline unsigned int get_size (void) const { return len * sizeof (Type); } + + inline hb_array_t sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const { + if (!seg_count) return hb_array_t (); + unsigned int count = len; if (unlikely (start_offset > count)) count = 0; else count -= start_offset; - count = MIN (count, seg_count); + count = *seg_count = MIN (count, *seg_count); return hb_array_t (arrayZ + start_offset, count); } + inline hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const + { return sub_array (start_offset, &seg_count); } inline hb_bytes_t as_bytes (void) const + { return hb_bytes_t (arrayZ, len * sizeof (Type)); } + + template + inline Type *lsearch (const T &x, + Type *not_found = nullptr) { - return hb_bytes_t (arrayZ, len * sizeof (Type)); + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + if (!this->arrayZ[i].cmp (x)) + return &this->arrayZ[i]; + return not_found; + } + template + inline const Type *lsearch (const T &x, + const Type *not_found = nullptr) const + { + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + if (!this->arrayZ[i].cmp (x)) + return &this->arrayZ[i]; + return not_found; } - inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } + inline hb_sorted_array_t qsort (int (*cmp)(const void*, const void*)) + { + ::qsort (arrayZ, len, sizeof (Type), cmp); + return hb_sorted_array_t (*this); + } + inline hb_sorted_array_t qsort (void) + { + ::qsort (arrayZ, len, sizeof (Type), Type::cmp); + return hb_sorted_array_t (*this); + } + inline void qsort (unsigned int start, unsigned int end) + { + end = MIN (end, len); + assert (start <= end); + ::qsort (arrayZ + start, end - start, sizeof (Type), Type::cmp); + } + inline void free (void) + { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } + + template + inline bool sanitize (hb_sanitize_context_t *c) const + { return c->check_array (arrayZ, len); } + + public: Type *arrayZ; unsigned int len; }; template -inline hb_array_t hb_array (T *array, unsigned int len) { return hb_array_t (array, len); } +inline hb_array_t hb_array (T *array, unsigned int len) +{ return hb_array_t (array, len); } + +enum hb_bfind_not_found_t +{ + HB_BFIND_NOT_FOUND_DONT_STORE, + HB_BFIND_NOT_FOUND_STORE, + HB_BFIND_NOT_FOUND_STORE_CLOSEST, +}; + +template +struct hb_sorted_array_t : hb_array_t +{ + inline hb_sorted_array_t (void) : hb_array_t () {} + inline hb_sorted_array_t (const hb_array_t &o) : hb_array_t (o) {} + inline hb_sorted_array_t (Type *array_, unsigned int len_) : hb_array_t (array_, len_) {} + + inline 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 *) (this))->sub_array (start_offset, seg_count)); } + inline hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const + { return sub_array (start_offset, &seg_count); } + + template + inline Type *bsearch (const T &x, Type *not_found = nullptr) + { + unsigned int i; + return bfind (x, &i) ? &this->arrayZ[i] : not_found; + } + template + inline const Type *bsearch (const T &x, const Type *not_found = nullptr) const + { + unsigned int i; + return bfind (x, &i) ? &this->arrayZ[i] : not_found; + } + template + inline bool bfind (const T &x, unsigned int *i = nullptr, + hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const + { + int min = 0, max = (int) this->len - 1; + const Type *array = this->arrayZ; + while (min <= max) + { + int mid = ((unsigned int) min + (unsigned int) max) / 2; + int c = array[mid].cmp (x); + if (c < 0) + max = mid - 1; + else if (c > 0) + min = mid + 1; + else + { + if (i) + *i = mid; + return true; + } + } + if (i) + { + switch (not_found) + { + case HB_BFIND_NOT_FOUND_DONT_STORE: + break; + + case HB_BFIND_NOT_FOUND_STORE: + *i = to_store; + break; + + case HB_BFIND_NOT_FOUND_STORE_CLOSEST: + if (max < 0 || (max < (int) this->len && array[max].cmp (x) > 0)) + max++; + *i = max; + break; + } + } + return false; + } +}; +template +inline hb_sorted_array_t hb_sorted_array (T *array, unsigned int len) +{ return hb_sorted_array_t (array, len); } struct HbOpOr diff --git a/src/hb-face.cc b/src/hb-face.cc index e23842fb1..5b33784f4 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -588,10 +588,10 @@ struct hb_face_builder_data_t { struct table_entry_t { - inline int cmp (const hb_tag_t *t) const + inline int cmp (hb_tag_t t) const { - if (*t < tag) return -1; - if (*t > tag) return -1; + if (t < tag) return -1; + if (t > tag) return -1; return 0; } diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 9b9d787de..633e0ecd2 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -478,7 +478,7 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, return true; } -#ifdef HB_USE_ATEXIT +#if HB_USE_ATEXIT static void free_static_ft_funcs (void); #endif @@ -504,7 +504,7 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t::value, +static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t { static inline FT_Library create (void) @@ -757,7 +757,7 @@ static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_tu._member.static_size) + sizeof(this->u._member) == (size)); \ - static const unsigned int min_size = (size) + DEFINE_COMPILES_ASSERTION ((void) this->u._member.static_size) \ + DEFINE_INSTANCE_ASSERTION (sizeof(this->u._member) == (size)) \ + enum { null_size = (size) }; \ + enum { min_size = (size) } #define DEFINE_SIZE_MIN(size) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \ - static const unsigned int min_size = (size) + DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \ + enum { null_size = (size) }; \ + enum { min_size = (size) } + +#define DEFINE_SIZE_UNBOUNDED(size) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \ + enum { min_size = (size) } #define DEFINE_SIZE_ARRAY(size, array) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \ DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])) \ + enum { null_size = (size) }; \ enum { min_size = (size) } #define DEFINE_SIZE_ARRAY_SIZED(size, array) \ - inline unsigned int get_size (void) const { return (size - (array).min_size + (array).get_size ()); } \ - DEFINE_SIZE_ARRAY(size, array) - -#define DEFINE_SIZE_ARRAY2(size, array1, array2) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \ - DEFINE_COMPILES_ASSERTION ((void) (array1)[0].static_size; (void) (array2)[0].static_size) \ - static const unsigned int min_size = (size) + inline unsigned int get_size (void) const { return (size - (array).min_size + (array).get_size ()); } \ + DEFINE_SIZE_ARRAY(size, array) /* @@ -256,26 +259,36 @@ struct hb_sanitize_context_t : inline void set_max_ops (int max_ops_) { max_ops = max_ops_; } - /* TODO - * This set_object() thing is to use sanitize at runtime lookup - * application time. This is very distinct from the regular - * sanitizer operation, so, eventually, separate into another - * type and make hb_aat_apply_context_t use that one instead - * of abusing this one. - */ template - inline void set_object (const T& obj) + inline void set_object (const T *obj) { - this->start = (const char *) &obj; - this->end = (const char *) &obj + obj.get_size (); + reset_object (); + + if (!obj) return; + + const char *obj_start = (const char *) obj; + const char *obj_end = (const char *) obj + obj->get_size (); + assert (obj_start <= obj_end); /* Must not overflow. */ + + if (unlikely (obj_end < this->start || this->end < obj_start)) + this->start = this->end = nullptr; + else + { + this->start = MAX (this->start, obj_start); + this->end = MIN (this->end , obj_end ); + } + } + + inline void reset_object (void) + { + this->start = this->blob->data; + this->end = this->start + this->blob->length; assert (this->start <= this->end); /* Must not overflow. */ } inline void start_processing (void) { - this->start = this->blob->data; - this->end = this->start + this->blob->length; - assert (this->start <= this->end); /* Must not overflow. */ + reset_object (); this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, (unsigned) HB_SANITIZE_MAX_OPS_MIN); this->edit_count = 0; @@ -469,6 +482,23 @@ struct hb_sanitize_context_t : bool num_glyphs_set; }; +struct hb_sanitize_with_object_t +{ + template + inline hb_sanitize_with_object_t (hb_sanitize_context_t *c, + const T& obj) : c (c) + { + c->set_object (obj); + } + inline ~hb_sanitize_with_object_t (void) + { + c->reset_object (); + } + + private: + hb_sanitize_context_t *c; +}; + /* * Serialize @@ -691,6 +721,12 @@ struct BEInt } inline operator Type (void) const { +#if defined(__GNUC__) || defined(__clang__) + /* Spoon-feed the compiler a big-endian integer with alignment 1. + * https://github.com/harfbuzz/harfbuzz/pull/1398 */ + struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; + return __builtin_bswap16 (((packed_uint16_t *) this)->v); +#endif return (v[0] << 8) + (v[1] ); } diff --git a/src/hb-null.hh b/src/hb-null.hh index bc9438d5c..080e0b542 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -38,21 +38,60 @@ #define HB_NULL_POOL_SIZE 9880 +/* Use SFINAE to sniff whether T has min_size; in which case return T::null_size, + * otherwise return sizeof(T). */ + +/* The hard way... + * https://stackoverflow.com/questions/7776448/sfinae-tried-with-bool-gives-compiler-error-template-argument-tvalue-invol + */ + +template struct _hb_bool_type {}; + +template +struct _hb_null_size +{ enum { value = sizeof (T) }; }; +template +struct _hb_null_size > +{ enum { value = T::null_size }; }; + +template +struct hb_null_size +{ enum { value = _hb_null_size >::value }; }; +#define hb_null_size(T) hb_null_size::value + +/* This doesn't belong here, but since is copy/paste from above, put it here. */ + +template +struct _hb_static_size +{ enum { value = sizeof (T) }; }; +template +struct _hb_static_size > +{ enum { value = T::static_size }; }; + +template +struct hb_static_size +{ enum { value = _hb_static_size >::value }; }; +#define hb_static_size(T) hb_static_size::value + + +/* + * Null() + */ extern HB_INTERNAL hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; /* Generic nul-content Null objects. */ template static inline Type const & Null (void) { - static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); return *reinterpret_cast (_hb_NullPool); } -#define Null(Type) Null::value>::value>() +#define Null(Type) Null () /* Specializations for arbitrary-content Null objects expressed in bytes. */ #define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \ } /* Close namespace. */ \ - extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size]; \ + extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size]; \ template <> \ /*static*/ inline const Namespace::Type& Null (void) { \ return *reinterpret_cast (_hb_Null_##Namespace##_##Type); \ @@ -60,7 +99,7 @@ static inline Type const & Null (void) { namespace Namespace { \ static_assert (true, "Just so we take semicolon after.") #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ - const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size] + const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size] /* Specializations for arbitrary-content Null objects expressed as struct initializer. */ #define DECLARE_NULL_INSTANCE(Type) \ @@ -85,12 +124,12 @@ extern HB_INTERNAL /* CRAP pool: Common Region for Access Protection. */ template static inline Type& Crap (void) { - static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); Type *obj = reinterpret_cast (_hb_CrapPool); memcpy (obj, &Null(Type), sizeof (*obj)); return *obj; } -#define Crap(Type) Crap::value>::value>() +#define Crap(Type) Crap () template struct CrapOrNull { @@ -110,7 +149,7 @@ struct CrapOrNull { template struct hb_nonnull_ptr_t { - typedef typename hb_remove_pointer

::value T; + typedef typename hb_remove_pointer (P) T; inline hb_nonnull_ptr_t (T *v_ = nullptr) : v (v_) {} inline T * operator = (T *v_) { return v = v_; } diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 2ef6d775f..af68892ab 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -111,12 +111,7 @@ typedef struct OffsetTable { Tag t; t.set (tag); - /* Linear-search for small tables to work around fonts with unsorted - * table list. */ - int i = tables.len < 64 ? tables.lsearch (t) : tables.bsearch (t); - if (table_index) - *table_index = i == -1 ? (unsigned) Index::NOT_FOUND_INDEX : (unsigned) i; - return i != -1; + return tables.bfind (t, table_index, HB_BFIND_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX); } inline const TableRecord& get_table_by_tag (hb_tag_t tag) const { diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index b1fcd6877..f4d0238ea 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -231,22 +231,31 @@ struct FixedVersion * Use: (base+offset) */ -template struct assert_has_min_size { static_assert (Type::min_size > 0, ""); }; -template struct assert_has_min_size {}; +template +struct _hb_has_null +{ + static inline const Type *get_null (void) { return nullptr; } + static inline Type *get_crap (void) { return nullptr; } +}; +template +struct _hb_has_null +{ + static inline const Type *get_null (void) { return &Null(Type); } + static inline Type *get_crap (void) { return &Crap(Type); } +}; template struct OffsetTo : Offset { - static_assert (sizeof (assert_has_min_size) || true, ""); - inline const Type& operator () (const void *base) const { - if (unlikely (this->is_null ())) return Null (Type); + if (unlikely (this->is_null ())) return *_hb_has_null::get_null (); return StructAtOffset (base, *this); } inline Type& operator () (void *base) const { if (unlikely (this->is_null ())) return Crap (Type); + if (unlikely (this->is_null ())) return *_hb_has_null::get_crap (); return StructAtOffset (base, *this); } @@ -322,6 +331,7 @@ struct OffsetTo : Offset DEFINE_SIZE_STATIC (sizeof (OffsetType)); }; template struct LOffsetTo : OffsetTo {}; + template static inline const Type& operator + (const Base &base, const OffsetTo &offset) { return offset (base); } template @@ -335,6 +345,8 @@ static inline Type& operator + (Base &base, OffsetTo template struct UnsizedArrayOf { + static_assert ((bool) (unsigned) hb_static_size (Type), ""); + enum { item_size = Type::static_size }; HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type); @@ -358,8 +370,20 @@ struct UnsizedArrayOf inline unsigned int get_size (unsigned int len) const { return len * Type::static_size; } - inline hb_array_t as_array (unsigned int len) { return hb_array_t (arrayZ, len); } - inline hb_array_t as_array (unsigned int len) const { return hb_array_t (arrayZ, len); } + inline hb_array_t as_array (unsigned int len) + { return hb_array (arrayZ, len); } + inline hb_array_t as_array (unsigned int len) const + { return hb_array (arrayZ, len); } + + template + inline Type &lsearch (unsigned int len, const T &x, Type ¬_found = Crap (Type)) + { return *as_array (len).lsearch (x, ¬_found); } + template + inline const Type &lsearch (unsigned int len, const T &x, const Type ¬_found = Null (Type)) const + { return *as_array (len).lsearch (x, ¬_found); } + + inline void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1) + { as_array (len).qsort (start, end); } inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { @@ -406,7 +430,7 @@ struct UnsizedArrayOf public: Type arrayZ[VAR]; public: - DEFINE_SIZE_ARRAY (0, arrayZ); + DEFINE_SIZE_UNBOUNDED (0); }; /* Unsized array of offset's */ @@ -419,8 +443,17 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf { inline const Type& operator [] (unsigned int i) const { - return this+this->arrayZ[i]; + const OffsetTo *p = &this->arrayZ[i]; + if (unlikely (p < this->arrayZ)) return Null (Type); /* Overflowed. */ + return this+*p; } + inline Type& operator [] (unsigned int i) + { + const OffsetTo *p = &this->arrayZ[i]; + if (unlikely (p < this->arrayZ)) return Crap (Type); /* Overflowed. */ + return this+*p; + } + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { @@ -435,26 +468,39 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf } }; +/* An array with sorted elements. Supports binary searching. */ +template +struct SortedUnsizedArrayOf : UnsizedArrayOf +{ + inline hb_sorted_array_t as_array (unsigned int len) + { return hb_sorted_array (this->arrayZ, len); } + inline hb_sorted_array_t as_array (unsigned int len) const + { return hb_sorted_array (this->arrayZ, len); } + + template + inline Type &bsearch (unsigned int len, const T &x, Type ¬_found = Crap (Type)) + { return *as_array (len).bsearch (x, ¬_found); } + template + inline const Type &bsearch (unsigned int len, const T &x, const Type ¬_found = Null (Type)) const + { return *as_array (len).bsearch (x, ¬_found); } + template + inline bool bfind (unsigned int len, const T &x, unsigned int *i = nullptr, + hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const + { return as_array (len).bfind (x, i, not_found, to_store); } +}; + + /* An array with a number of elements. */ template struct ArrayOf { + static_assert ((bool) (unsigned) hb_static_size (Type), ""); + enum { item_size = Type::static_size }; HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType); - inline const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const - { - unsigned int count = len; - if (unlikely (start_offset > count)) - count = 0; - else - count -= start_offset; - count = MIN (count, *pcount); - *pcount = count; - return arrayZ + start_offset; - } - inline const Type& operator [] (unsigned int i) const { if (unlikely (i >= len)) return Null (Type); @@ -469,6 +515,20 @@ struct ArrayOf inline unsigned int get_size (void) const { return len.static_size + len * Type::static_size; } + inline hb_array_t as_array (void) + { return hb_array (arrayZ, len); } + inline hb_array_t as_array (void) const + { return hb_array (arrayZ, len); } + + inline hb_array_t sub_array (unsigned int start_offset, unsigned int count) const + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t sub_array (unsigned int start_offset, unsigned int *count /* IN/OUT */) const + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t sub_array (unsigned int start_offset, unsigned int count) + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t sub_array (unsigned int start_offset, unsigned int *count /* IN/OUT */) + { return as_array ().sub_array (start_offset, count);} + inline bool serialize (hb_serialize_context_t *c, unsigned int items_len) { @@ -528,20 +588,15 @@ struct ArrayOf return_trace (true); } - template - inline int lsearch (const SearchType &x) const - { - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - if (!this->arrayZ[i].cmp (x)) - return i; - return -1; - } + template + inline Type &lsearch (const T &x, Type ¬_found = Crap (Type)) + { return *as_array ().lsearch (x, ¬_found); } + template + inline const Type &lsearch (const T &x, const Type ¬_found = Null (Type)) const + { return *as_array ().lsearch (x, ¬_found); } - inline void qsort (void) - { - ::qsort (arrayZ, len, sizeof (Type), Type::cmp); - } + inline void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) + { as_array ().qsort (start, end); } inline bool sanitize_shallow (hb_sanitize_context_t *c) const { @@ -723,22 +778,31 @@ struct ArrayOfM1 template struct SortedArrayOf : ArrayOf { - template - inline int bsearch (const SearchType &x) const - { - /* Hand-coded bsearch here since this is in the hot inner loop. */ - const Type *arr = this->arrayZ; - int min = 0, max = (int) this->len - 1; - while (min <= max) - { - int mid = ((unsigned int) min + (unsigned int) max) / 2; - int c = arr[mid].cmp (x); - if (c < 0) max = mid - 1; - else if (c > 0) min = mid + 1; - else return mid; - } - return -1; - } + inline hb_sorted_array_t as_array (void) + { return hb_sorted_array (this->arrayZ, this->len); } + inline hb_sorted_array_t as_array (void) const + { return hb_sorted_array (this->arrayZ, this->len); } + + inline hb_array_t sub_array (unsigned int start_offset, unsigned int count) const + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t sub_array (unsigned int start_offset, unsigned int *count /* IN/OUT */) const + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t sub_array (unsigned int start_offset, unsigned int count) + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t sub_array (unsigned int start_offset, unsigned int *count /* IN/OUT */) + { return as_array ().sub_array (start_offset, count);} + + template + inline Type &bsearch (const T &x, Type ¬_found = Crap (Type)) + { return *as_array ().bsearch (x, ¬_found); } + template + inline const Type &bsearch (const T &x, const Type ¬_found = Null (Type)) const + { return *as_array ().bsearch (x, ¬_found); } + template + inline bool bfind (const T &x, unsigned int *i = nullptr, + hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const + { return as_array ().bfind (x, i, not_found, to_store); } }; /* @@ -810,15 +874,36 @@ struct VarSizedBinSearchArrayOf HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (VarSizedBinSearchArrayOf, Type); + inline bool last_is_terminator (void) const + { + if (unlikely (!header.nUnits)) return false; + + /* Gah. + * + * "The number of termination values that need to be included is table-specific. + * The value that indicates binary search termination is 0xFFFF." */ + const HBUINT16 *words = &StructAtOffset (&bytesZ, (header.nUnits - 1) * header.unitSize); + unsigned int count = Type::TerminationWordCount; + for (unsigned int i = 0; i < count; i++) + if (words[i] != 0xFFFFu) + return false; + return true; + } + inline const Type& operator [] (unsigned int i) const { - if (unlikely (i >= header.nUnits)) return Null (Type); + if (unlikely (i >= get_length ())) return Null (Type); return StructAtOffset (&bytesZ, i * header.unitSize); } inline Type& operator [] (unsigned int i) { + if (unlikely (i >= get_length ())) return Crap (Type); return StructAtOffset (&bytesZ, i * header.unitSize); } + inline unsigned int get_length (void) const + { + return header.nUnits - last_is_terminator (); + } inline unsigned int get_size (void) const { return header.static_size + header.nUnits * header.unitSize; } @@ -842,7 +927,7 @@ struct VarSizedBinSearchArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = header.nUnits; + unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!(*this)[i].sanitize (c, base))) return_trace (false); @@ -853,7 +938,7 @@ struct VarSizedBinSearchArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = header.nUnits; + unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!(*this)[i].sanitize (c, base, user_data))) return_trace (false); @@ -864,7 +949,7 @@ struct VarSizedBinSearchArrayOf inline const Type *bsearch (const T &key) const { unsigned int size = header.unitSize; - int min = 0, max = (int) header.nUnits - 1; + int min = 0, max = (int) get_length () - 1; while (min <= max) { int mid = ((unsigned int) min + (unsigned int) max) / 2; diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index b7d17018a..cdc610be3 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -417,6 +417,7 @@ struct CmapSubtableLongGroup public: DEFINE_SIZE_STATIC (12); }; +DECLARE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup); template struct CmapSubtableTrimmed @@ -467,10 +468,7 @@ struct CmapSubtableLongSegmented inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { - int i = groups.bsearch (codepoint); - if (i == -1) - return false; - hb_codepoint_t gid = T::group_get_glyph (groups[i], codepoint); + hb_codepoint_t gid = T::group_get_glyph (groups.bsearch (codepoint), codepoint); if (!gid) return false; *glyph = gid; @@ -517,7 +515,8 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented { static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, hb_codepoint_t u) - { return group.glyphID + (u - group.startCharCode); } + { return likely (group.startCharCode <= group.endCharCode) ? + group.glyphID + (u - group.startCharCode) : 0; } bool serialize (hb_serialize_context_t *c, @@ -673,16 +672,12 @@ struct VariationSelectorRecord hb_codepoint_t *glyph, const void *base) const { - int i; - const DefaultUVS &defaults = base+defaultUVS; - i = defaults.bsearch (codepoint); - if (i != -1) + if ((base+defaultUVS).bfind (codepoint)) return GLYPH_VARIANT_USE_DEFAULT; - const NonDefaultUVS &nonDefaults = base+nonDefaultUVS; - i = nonDefaults.bsearch (codepoint); - if (i != -1 && nonDefaults[i].glyphID) + const UVSMapping &nonDefault = (base+nonDefaultUVS).bsearch (codepoint); + if (nonDefault.glyphID) { - *glyph = nonDefaults[i].glyphID; + *glyph = nonDefault.glyphID; return GLYPH_VARIANT_FOUND; } return GLYPH_VARIANT_NOT_FOUND; @@ -722,7 +717,7 @@ struct CmapSubtableFormat14 hb_codepoint_t variation_selector, hb_codepoint_t *glyph) const { - return record[record.bsearch (variation_selector)].get_glyph (codepoint, glyph, this); + return record.bsearch (variation_selector).get_glyph (codepoint, glyph, this); } inline void collect_variation_selectors (hb_set_t *out) const @@ -734,7 +729,7 @@ struct CmapSubtableFormat14 inline void collect_variation_unicodes (hb_codepoint_t variation_selector, hb_set_t *out) const { - record[record.bsearch (variation_selector)].collect_unicodes (out, this); + record.bsearch (variation_selector).collect_unicodes (out, this); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -863,14 +858,6 @@ struct cmap hb_vector_t format12_groups; }; - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - likely (version == 0) && - encodingRecord.sanitize (c, this)); - } - inline bool _create_plan (const hb_subset_plan_t *plan, subset_plan *cmap_plan) const { @@ -1164,11 +1151,21 @@ struct cmap key.platformID.set (platform_id); key.encodingID.set (encoding_id); - int result = encodingRecord.bsearch (key); - if (result == -1 || !encodingRecord[result].subtable) + const EncodingRecord &result = encodingRecord.bsearch (key); + if (!result.subtable) return nullptr; - return &(this+encodingRecord[result].subtable); + return &(this+result.subtable); + } + + public: + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + likely (version == 0) && + encodingRecord.sanitize (c, this)); } protected: diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index fa40223b7..84c343325 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -66,13 +66,6 @@ struct BaseGlyphRecord inline int cmp (hb_codepoint_t g) const { return g < glyphId ? -1 : g > glyphId ? 1 : 0; } - static int cmp (const void *pa, const void *pb) - { - const hb_codepoint_t *a = (const hb_codepoint_t *) pa; - const BaseGlyphRecord *b = (const BaseGlyphRecord *) pb; - return b->cmp (*a); - } - inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -103,12 +96,7 @@ struct COLR unsigned int *count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */) const { - const BaseGlyphRecord *rec = (BaseGlyphRecord *) bsearch (&glyph, - &(this+baseGlyphsZ), - numBaseGlyphs, - sizeof (BaseGlyphRecord), - BaseGlyphRecord::cmp); - const BaseGlyphRecord &record = rec ? *rec : Null (BaseGlyphRecord); + const BaseGlyphRecord &record = (this+baseGlyphsZ).bsearch (numBaseGlyphs, glyph); hb_array_t all_layers ((this+layersZ).arrayZ, numLayers); hb_array_t glyph_layers = all_layers.sub_array (record.firstLayerIdx, @@ -137,7 +125,7 @@ struct COLR protected: HBUINT16 version; /* Table version number (starts at 0). */ HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */ - LOffsetTo, false> + LOffsetTo, false> baseGlyphsZ; /* Offset to Base Glyph records. */ LOffsetTo, false> layersZ; /* Offset to Layer Records. */ diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index bad8ef549..ad3551035 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -103,8 +103,7 @@ struct SVG inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const { - const SortedArrayOf &docs = this+svgDocEntries; - return docs[docs.bsearch (glyph_id)]; + return (this+svgDocEntries).bsearch (glyph_id); } inline bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh index 7cefdb765..27042c190 100644 --- a/src/hb-ot-face.hh +++ b/src/hb-ot-face.hh @@ -67,6 +67,7 @@ HB_OT_TABLE(AAT, trak) \ HB_OT_TABLE(AAT, lcar) \ HB_OT_TABLE(AAT, ltag) \ + HB_OT_TABLE(AAT, feat) \ /* OpenType variations. */ \ HB_OT_TABLE(OT, fvar) \ HB_OT_TABLE(OT, avar) \ diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 4ddee4f86..3491b605d 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -249,7 +249,7 @@ hb_ot_get_font_v_extents (hb_font_t *font, return vmtx.has_font_extents; } -#ifdef HB_USE_ATEXIT +#if HB_USE_ATEXIT static void free_static_ot_funcs (void); #endif @@ -275,7 +275,7 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t dataZ; /* Location data. */ public: - DEFINE_SIZE_ARRAY (0, dataZ); + DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always + * check the size externally, allow Null() object of it by + * defining it MIN() instead. */ }; @@ -465,7 +467,9 @@ struct glyf protected: UnsizedArrayOf dataZ; /* Glyphs data. */ public: - DEFINE_SIZE_ARRAY (0, dataZ); + DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always + * check the size externally, allow Null() object of it by + * defining it MIN() instead. */ }; struct glyf_accelerator_t : glyf::accelerator_t {}; diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 14e065684..b57ebaea8 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -154,7 +154,7 @@ struct KernSubTable KernSubTableFormat3 format3; } u; public: - DEFINE_SIZE_MIN (0); + DEFINE_SIZE_MIN (KernSubTableHeader::static_size); }; @@ -274,6 +274,15 @@ struct kern inline bool has_data (void) const { return u.version32; } inline unsigned int get_type (void) const { return u.major; } + inline bool has_state_machine (void) const + { + switch (get_type ()) { + case 0: return u.ot.has_state_machine (); + case 1: return u.aat.has_state_machine (); + default:return false; + } + } + inline bool has_cross_stream (void) const { switch (get_type ()) { diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 36faf6bb6..cc1af1572 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -128,15 +128,7 @@ struct RecordArrayOf : SortedArrayOf > } inline bool find_index (hb_tag_t tag, unsigned int *index) const { - /* If we want to allow non-sorted data, we can lsearch(). */ - int i = this->/*lsearch*/bsearch (tag); - if (i != -1) { - if (index) *index = i; - return true; - } else { - if (index) *index = Index::NOT_FOUND_INDEX; - return false; - } + return this->bfind (tag, index, HB_BFIND_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX); } }; @@ -802,11 +794,11 @@ struct Lookup HBUINT16 lookupFlag; /* Lookup qualifiers */ ArrayOf subTable; /* Array of SubTables */ - HBUINT16 markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets +/*HBUINT16 markFilteringSetX[VAR];*//* Index (base 0) into GDEF mark glyph sets * structure. This field is only present if bit * UseMarkFilteringSet of lookup flags is set. */ public: - DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX); + DEFINE_SIZE_ARRAY (6, subTable); }; typedef OffsetListOf LookupList; @@ -823,8 +815,8 @@ struct CoverageFormat1 private: inline unsigned int get_coverage (hb_codepoint_t glyph_id) const { - int i = glyphArray.bsearch (glyph_id); - static_assert ((((unsigned int) -1) == NOT_COVERED), ""); + unsigned int i; + glyphArray.bfind (glyph_id, &i, HB_BFIND_NOT_FOUND_STORE, NOT_COVERED); return i; } @@ -896,12 +888,10 @@ struct CoverageFormat2 private: inline unsigned int get_coverage (hb_codepoint_t glyph_id) const { - int i = rangeRecord.bsearch (glyph_id); - if (i != -1) { - const RangeRecord &range = rangeRecord[i]; - return (unsigned int) range.value + (glyph_id - range.start); - } - return NOT_COVERED; + const RangeRecord &range = rangeRecord.bsearch (glyph_id); + return likely (range.start <= range.end) ? + (unsigned int) range.value + (glyph_id - range.start) : + NOT_COVERED; } inline bool serialize (hb_serialize_context_t *c, @@ -1194,10 +1184,7 @@ struct ClassDefFormat1 private: inline unsigned int get_class (hb_codepoint_t glyph_id) const { - unsigned int i = (unsigned int) (glyph_id - startGlyph); - if (unlikely (i < classValue.len)) - return classValue[i]; - return 0; + return classValue[(unsigned int) (glyph_id - startGlyph)]; } inline bool sanitize (hb_sanitize_context_t *c) const @@ -1265,10 +1252,10 @@ struct ClassDefFormat1 } protected: - HBUINT16 classFormat; /* Format identifier--format = 1 */ - GlyphID startGlyph; /* First GlyphID of the classValueArray */ + HBUINT16 classFormat; /* Format identifier--format = 1 */ + GlyphID startGlyph; /* First GlyphID of the classValueArray */ ArrayOf - classValue; /* Array of Class Values--one per GlyphID */ + classValue; /* Array of Class Values--one per GlyphID */ public: DEFINE_SIZE_ARRAY (6, classValue); }; @@ -1280,10 +1267,7 @@ struct ClassDefFormat2 private: inline unsigned int get_class (hb_codepoint_t glyph_id) const { - int i = rangeRecord.bsearch (glyph_id); - if (unlikely (i != -1)) - return rangeRecord[i].value; - return 0; + return rangeRecord.bsearch (glyph_id).value; } inline bool sanitize (hb_sanitize_context_t *c) const @@ -1586,9 +1570,9 @@ struct VarData HBUINT16 itemCount; HBUINT16 shortCount; ArrayOf regionIndices; - UnsizedArrayOfbytesX; +/*UnsizedArrayOfbytesX;*/ public: - DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX); + DEFINE_SIZE_ARRAY (6, regionIndices); }; struct VariationStore diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index 22e07f7a4..a0ae27e75 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -61,9 +61,10 @@ struct AttachList const AttachPoint &points = this+attachPoint[index]; - if (point_count) { - const HBUINT16 *array = points.sub_array (start_offset, point_count); - unsigned int count = *point_count; + if (point_count) + { + hb_array_t array = points.sub_array (start_offset, point_count); + unsigned int count = array.len; for (unsigned int i = 0; i < count; i++) point_array[i] = array[i]; } @@ -216,9 +217,10 @@ struct LigGlyph unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const { - if (caret_count) { - const OffsetTo *array = carets.sub_array (start_offset, caret_count); - unsigned int count = *caret_count; + if (caret_count) + { + hb_array_t > array = carets.sub_array (start_offset, caret_count); + unsigned int count = array.len; for (unsigned int i = 0; i < count; i++) caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id, var_store); } @@ -406,9 +408,20 @@ struct GDEF } } + HB_INTERNAL bool is_blacklisted (hb_blob_t *blob, + hb_face_t *face) const; + struct accelerator_t { - HB_INTERNAL void init (hb_face_t *face); + inline void init (hb_face_t *face) + { + this->table = hb_sanitize_context_t().reference_table (face); + if (unlikely (this->table->is_blacklisted (this->table.get_blob (), face))) + { + hb_blob_destroy (this->table.get_blob ()); + this->table = hb_blob_get_empty (); + } + } inline void fini (void) { diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 907fd4631..2589218de 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1643,6 +1643,9 @@ struct GPOS : GSUBGPOS inline bool sanitize (hb_sanitize_context_t *c) const { return GSUBGPOS::sanitize (c); } + HB_INTERNAL bool is_blacklisted (hb_blob_t *blob, + hb_face_t *face) const; + typedef GSUBGPOS::accelerator_t accelerator_t; }; diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 715317b59..27bd440da 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1449,7 +1449,10 @@ struct SubstLookup : Lookup hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index); - c->flush (); + /* While in theory we should flush here, it will cause timeouts because a recursive + * lookup can keep growing the glyph set. Skip, and outer loop will retry up to + * HB_CLOSURE_MAX_STAGES time, which should be enough for every realistic font. */ + //c->flush (); return ret; } @@ -1483,6 +1486,9 @@ struct GSUB : GSUBGPOS inline bool sanitize (hb_sanitize_context_t *c) const { return GSUBGPOS::sanitize (c); } + HB_INTERNAL bool is_blacklisted (hb_blob_t *blob, + hb_face_t *face) const; + typedef GSUBGPOS::accelerator_t accelerator_t; }; diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 3d70c55c2..a9bfee155 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -2753,6 +2753,11 @@ struct GSUBGPOS inline void init (hb_face_t *face) { this->table = hb_sanitize_context_t().reference_table (face); + if (unlikely (this->table->is_blacklisted (this->table.get_blob (), face))) + { + hb_blob_destroy (this->table.get_blob ()); + this->table = hb_blob_get_empty (); + } this->lookup_count = table->get_lookup_count (); diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 092633c5d..d0b22efe3 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -34,15 +34,17 @@ #include "hb-ot-map.hh" #include "hb-map.hh" +#include "hb-ot-kern-table.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-layout-base-table.hh" // Just so we compile it; unused otherwise #include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise -#include "hb-ot-kern-table.hh" #include "hb-ot-name-table.hh" +#include "hb-ot-os2-table.hh" #include "hb-aat-layout-lcar-table.hh" +#include "hb-aat-layout-morx-table.hh" /** @@ -65,6 +67,12 @@ hb_ot_layout_has_kerning (hb_face_t *face) return face->table.kern->has_data (); } +bool +hb_ot_layout_has_machine_kerning (hb_face_t *face) +{ + return face->table.kern->has_state_machine (); +} + bool hb_ot_layout_has_cross_kerning (hb_face_t *face) { @@ -89,10 +97,9 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan, * GDEF */ -static bool -_hb_ot_blacklist_gdef (unsigned int gdef_len, - unsigned int gsub_len, - unsigned int gpos_len) +bool +OT::GDEF::is_blacklisted (hb_blob_t *blob, + hb_face_t *face) const { /* The ugly business of blacklisting individual fonts' tables happen here! * See this thread for why we finally had to bend in and do this: @@ -111,8 +118,10 @@ _hb_ot_blacklist_gdef (unsigned int gdef_len, * https://bugzilla.mozilla.org/show_bug.cgi?id=1279693 * https://bugzilla.mozilla.org/show_bug.cgi?id=1279875 */ -#define ENCODE(x,y,z) ((int64_t) (x) << 32 | (int64_t) (y) << 16 | (z)) - switch ENCODE(gdef_len, gsub_len, gpos_len) +#define ENCODE(x,y,z) (((uint64_t) (x) << 48) | ((uint64_t) (y) << 24) | (uint64_t) (z)) + switch ENCODE(blob->length, + face->table.GSUB->table.get_length (), + face->table.GPOS->table.get_length ()) { /* sha1sum:c5ee92f0bca4bfb7d06c4d03e8cf9f9cf75d2e8a Windows 7? timesi.ttf */ case ENCODE (442, 2874, 42038): @@ -191,20 +200,6 @@ _hb_ot_blacklist_gdef (unsigned int gdef_len, return false; } -void -OT::GDEF::accelerator_t::init (hb_face_t *face) -{ - this->table = hb_sanitize_context_t().reference_table (face); - - if (unlikely (_hb_ot_blacklist_gdef (this->table.get_length (), - face->table.GSUB->table.get_length (), - face->table.GPOS->table.get_length ()))) - { - hb_blob_destroy (this->table.get_blob ()); - this->table = hb_blob_get_empty (); - } -} - static void _hb_ot_layout_set_glyph_props (hb_font_t *font, hb_buffer_t *buffer) @@ -291,6 +286,38 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, * GSUB/GPOS */ +bool +OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED, + hb_face_t *face) const +{ + /* Mac OS X prefers morx over GSUB. It also ships with various Indic fonts, + * all by 'MUTF' foundry (Tamil MN, Tamil Sangam MN, etc.), that have broken + * GSUB/GPOS tables. Some have GSUB with zero scripts, those are ignored by + * our morx/GSUB preference code. But if GSUB has non-zero scripts, we tend + * to prefer it over morx because we want to be consistent with other OpenType + * shapers. + * + * To work around broken Indic Mac system fonts, we ignore GSUB table if + * OS/2 VendorId is 'MUTF' and font has morx table as well. + * + * https://github.com/harfbuzz/harfbuzz/issues/1410 + * https://github.com/harfbuzz/harfbuzz/issues/1348 + * https://github.com/harfbuzz/harfbuzz/issues/1391 + */ + if (unlikely (face->table.OS2->achVendID == HB_TAG ('M','U','T','F') && + face->table.morx->has_data ())) + return true; + + return false; +} + +bool +OT::GPOS::is_blacklisted (hb_blob_t *blob HB_UNUSED, + hb_face_t *face HB_UNUSED) const +{ + return false; +} + static const OT::GSUBGPOS& get_gsubgpos_table (hb_face_t *face, hb_tag_t table_tag) diff --git a/src/hb-ot-layout.hh b/src/hb-ot-layout.hh index db85508d2..a00b940b2 100644 --- a/src/hb-ot-layout.hh +++ b/src/hb-ot-layout.hh @@ -48,6 +48,9 @@ struct hb_ot_shape_plan_t; HB_INTERNAL bool hb_ot_layout_has_kerning (hb_face_t *face); +HB_INTERNAL bool +hb_ot_layout_has_machine_kerning (hb_face_t *face); + HB_INTERNAL bool hb_ot_layout_has_cross_kerning (hb_face_t *face); diff --git a/src/hb-ot-map.hh b/src/hb-ot-map.hh index 8e1f5aa8c..0a5a4fbcb 100644 --- a/src/hb-ot-map.hh +++ b/src/hb-ot-map.hh @@ -57,8 +57,8 @@ struct hb_ot_map_t unsigned int auto_zwj : 1; unsigned int random : 1; - inline int cmp (const hb_tag_t *tag_) const - { return *tag_ < tag ? -1 : *tag_ > tag ? 1 : 0; } + inline int cmp (const hb_tag_t tag_) const + { return tag_ < tag ? -1 : tag_ > tag ? 1 : 0; } }; struct lookup_map_t { diff --git a/src/hb-ot-math-table.hh b/src/hb-ot-math-table.hh index b87304979..153a41795 100644 --- a/src/hb-ot-math-table.hh +++ b/src/hb-ot-math-table.hh @@ -509,9 +509,8 @@ struct MathGlyphAssembly if (parts_count) { int scale = font->dir_scale (direction); - const MathGlyphPartRecord *arr = - partRecords.sub_array (start_offset, parts_count); - unsigned int count = *parts_count; + hb_array_t arr = partRecords.sub_array (start_offset, parts_count); + unsigned int count = arr.len; for (unsigned int i = 0; i < count; i++) arr[i].extract (parts[i], scale, font); } @@ -556,9 +555,8 @@ struct MathGlyphConstruction if (variants_count) { int scale = font->dir_scale (direction); - const MathGlyphVariantRecord *arr = - mathGlyphVariantRecord.sub_array (start_offset, variants_count); - unsigned int count = *variants_count; + hb_array_t arr = mathGlyphVariantRecord.sub_array (start_offset, variants_count); + unsigned int count = arr.len; for (unsigned int i = 0; i < count; i++) { variants[i].glyph = arr[i].variantGlyph; diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh index f80303cc8..98df3e780 100644 --- a/src/hb-ot-post-table.hh +++ b/src/hb-ot-post-table.hh @@ -61,12 +61,12 @@ struct postV2Tail ArrayOf glyphNameIndex; /* This is not an offset, but is the * ordinal number of the glyph in 'post' * string tables. */ - UnsizedArrayOf - namesX; /* Glyph names with length bytes [variable] +/*UnsizedArrayOf + namesX;*/ /* Glyph names with length bytes [variable] * (a Pascal string). */ public: - DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX); + DEFINE_SIZE_ARRAY (2, glyphNameIndex); }; struct post diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc index ca7b5a9b2..8fdf2f4bc 100644 --- a/src/hb-ot-shape-complex-myanmar.cc +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -391,27 +391,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar = }; -/* Uniscribe seems to have a shaper for 'mymr' that is like the - * generic shaper, except that it zeros mark advances GDEF_LATE. */ -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old = -{ - nullptr, /* collect_features */ - nullptr, /* override_features */ - nullptr, /* data_create */ - nullptr, /* data_destroy */ - nullptr, /* preprocess_text */ - nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, - nullptr, /* decompose */ - nullptr, /* compose */ - nullptr, /* setup_masks */ - HB_TAG_NONE, /* gpos_tag */ - nullptr, /* reorder_marks */ - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, - true, /* fallback_position */ -}; - - /* Ugly Zawgyi encoding. * Disable all auto processing. * https://github.com/harfbuzz/harfbuzz/issues/1162 */ diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index bfc92d3b5..2f3eb703e 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -544,7 +544,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11190 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 111B0 */ B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, - /* 111C0 */ H, B, R, R, O, O, O, O, O, FM, CMBlw, VAbv, VBlw, O, O, O, + /* 111C0 */ H, B, R, R, O, O, O, O, GB, FBlw, CMBlw, VAbv, VBlw, O, O, O, /* 111D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Sinhala Archaic Numbers */ diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index af25b07f8..2e3f202f5 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -432,7 +432,8 @@ record_pref (const hb_ot_shape_plan_t *plan HB_UNUSED, static inline bool is_halant (const hb_glyph_info_t &info) { - return info.use_category() == USE_H && !_hb_glyph_info_ligated (&info); + return (info.use_category() == USE_H || info.use_category() == USE_HVM) && + !_hb_glyph_info_ligated (&info); } static void @@ -449,19 +450,38 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) hb_glyph_info_t *info = buffer->info; -#define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB)) +#define POST_BASE_FLAGS64 (FLAG64 (USE_FM) | \ + FLAG64 (USE_FAbv) | \ + FLAG64 (USE_FBlw) | \ + FLAG64 (USE_FPst) | \ + FLAG64 (USE_MAbv) | \ + FLAG64 (USE_MBlw) | \ + FLAG64 (USE_MPst) | \ + FLAG64 (USE_MPre) | \ + FLAG64 (USE_VAbv) | \ + FLAG64 (USE_VBlw) | \ + FLAG64 (USE_VPst) | \ + FLAG64 (USE_VPre) | \ + FLAG64 (USE_VMAbv) | \ + FLAG64 (USE_VMBlw) | \ + FLAG64 (USE_VMPst) | \ + FLAG64 (USE_VMPre)) /* Move things forward. */ if (info[start].use_category() == USE_R && end - start > 1) { - /* Got a repha. Reorder it to after first base, before first halant. */ + /* Got a repha. Reorder it towards the end, but before the first post-base + * glyph. */ for (unsigned int i = start + 1; i < end; i++) - if ((FLAG_UNSAFE (info[i].use_category()) & (BASE_FLAGS)) || is_halant (info[i])) + { + bool is_post_base_glyph = (FLAG64_UNSAFE (info[i].use_category()) & POST_BASE_FLAGS64) || + is_halant (info[i]); + if (is_post_base_glyph || i == end - 1) { - /* If we hit a halant, move before it; otherwise it's a base: move to it's - * place, and shift things in between backward. */ + /* If we hit a post-base glyph, move before it; otherwise move to the + * end. Shift things in between backward. */ - if (is_halant (info[i])) + if (is_post_base_glyph) i--; buffer->merge_clusters (start, i + 1); @@ -471,21 +491,19 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) break; } + } } /* Move things back. */ - unsigned int j = end; + unsigned int j = start; for (unsigned int i = start; i < end; i++) { uint32_t flag = FLAG_UNSAFE (info[i].use_category()); - if ((flag & (BASE_FLAGS)) || is_halant (info[i])) + if (is_halant (info[i])) { - /* If we hit a halant, move after it; otherwise it's a base: move to it's - * place, and shift things in between backward. */ - if (is_halant (info[i])) - j = i + 1; - else - j = i; + /* If we hit a halant, move after it; otherwise move to the beginning, and + * shift things in between forward. */ + j = i + 1; } else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) && /* Only move the first component of a MultipleSubst. */ diff --git a/src/hb-ot-shape-complex.hh b/src/hb-ot-shape-complex.hh index 2944d745c..a2499de9c 100644 --- a/src/hb-ot-shape-complex.hh +++ b/src/hb-ot-shape-complex.hh @@ -57,7 +57,6 @@ enum hb_ot_shape_zero_width_marks_type_t { HB_COMPLEX_SHAPER_IMPLEMENT (indic) \ HB_COMPLEX_SHAPER_IMPLEMENT (khmer) \ HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \ - HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \ HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_zawgyi) \ HB_COMPLEX_SHAPER_IMPLEMENT (thai) \ HB_COMPLEX_SHAPER_IMPLEMENT (use) \ @@ -269,12 +268,25 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_khmer; case HB_SCRIPT_MYANMAR: - if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2')) - return &_hb_ot_complex_shaper_myanmar; - else if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','r')) - return &_hb_ot_complex_shaper_myanmar_old; - else + /* If the designer designed the font for the 'DFLT' script, + * (or we ended up arbitrarily pick 'latn'), use the default shaper. + * Otherwise, use the specific shaper. + * + * If designer designed for 'mymr' tag, also send to default + * shaper. That's tag used from before Myanmar shaping spec + * was developed. The shaping spec uses 'mym2' tag. */ + if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') || + planner->map.chosen_script[0] == HB_TAG ('l','a','t','n') || + planner->map.chosen_script[0] == HB_TAG ('m','y','m','r')) return &_hb_ot_complex_shaper_default; + else + return &_hb_ot_complex_shaper_myanmar; + + + /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ + case HB_SCRIPT_MYANMAR_ZAWGYI: + + return &_hb_ot_complex_shaper_myanmar_zawgyi; /* Unicode-2.0 additions */ @@ -375,10 +387,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_default; else return &_hb_ot_complex_shaper_use; - - /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ - case HB_SCRIPT_MYANMAR_ZAWGYI: - return &_hb_ot_complex_shaper_myanmar_zawgyi; } } diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index ccee8d343..ef9743578 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -76,10 +76,16 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac props (*props), map (face, props), aat_map (face, props), - apply_morx (_hb_apply_morx (face)), - shaper (apply_morx ? - &_hb_ot_complex_shaper_default : - hb_ot_shape_complex_categorize (this)) {} + apply_morx (_hb_apply_morx (face)) +{ + shaper = hb_ot_shape_complex_categorize (this); + + script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE; + script_fallback_mark_positioning = shaper->fallback_position; + + if (apply_morx) + shaper = &_hb_ot_complex_shaper_default; +} void hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, @@ -140,10 +146,17 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.apply_kern = true; } - bool has_kern_mark = plan.apply_kern && hb_ot_layout_has_cross_kerning (face); - plan.zero_marks = !plan.apply_morx && !plan.apply_kerx && !has_kern_mark; + plan.zero_marks = script_zero_marks && + !plan.apply_kerx && + (!plan.apply_kern || !hb_ot_layout_has_machine_kerning (face)); plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k')); - plan.fallback_mark_positioning = !plan.apply_gpos && plan.zero_marks; + + plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos && + !plan.apply_kerx && + (!plan.apply_kern || !hb_ot_layout_has_cross_kerning (face)); + + plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing && + script_fallback_mark_positioning; /* Currently we always apply trak. */ plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face); @@ -158,6 +171,7 @@ hb_ot_shape_plan_t::init0 (hb_face_t *face, hb_ot_shape_planner_t planner (face, &key->props); + hb_ot_shape_collect_features (&planner, key->user_features, key->num_user_features); @@ -811,17 +825,16 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c) hb_glyph_info_t *info = c->buffer->info; hb_glyph_position_t *pos = c->buffer->pos; - /* If the font has no GPOS, AND, no fallback positioning will - * happen, AND, direction is forward, then when zeroing mark - * widths, we shift the mark with it, such that the mark - * is positioned hanging over the previous glyph. When + /* If the font has no GPOS and direction is forward, then when + * zeroing mark widths, we shift the mark with it, such that the + * mark is positioned hanging over the previous glyph. When * direction is backward we don't shift and it will end up * hanging over the next glyph after the final reordering. - * If fallback positinoing happens or GPOS is present, we don't - * care. + * + * Note: If fallback positinoing happens, we don't care about + * this as it will be overriden. */ - bool adjust_offsets_when_zeroing = c->plan->fallback_mark_positioning && - !c->plan->shaper->fallback_position && + bool adjust_offsets_when_zeroing = c->plan->adjust_mark_positioning_when_zeroing && HB_DIRECTION_IS_FORWARD (c->buffer->props.direction); /* We change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */ @@ -877,7 +890,7 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c) &pos[i].x_offset, &pos[i].y_offset); - if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position) + if (c->plan->fallback_mark_positioning) _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer); } diff --git a/src/hb-ot-shape.hh b/src/hb-ot-shape.hh index 397634c25..6e1478d00 100644 --- a/src/hb-ot-shape.hh +++ b/src/hb-ot-shape.hh @@ -77,6 +77,7 @@ struct hb_ot_shape_plan_t bool zero_marks : 1; bool fallback_glyph_classes : 1; bool fallback_mark_positioning : 1; + bool adjust_mark_positioning_when_zeroing : 1; bool apply_gpos : 1; bool apply_kerx : 1; @@ -113,6 +114,8 @@ struct hb_ot_shape_planner_t hb_ot_map_builder_t map; hb_aat_map_builder_t aat_map; bool apply_morx : 1; + bool script_zero_marks : 1; + bool script_fallback_mark_positioning : 1; const struct hb_ot_complex_shaper_t *shaper; HB_INTERNAL hb_ot_shape_planner_t (hb_face_t *face, diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 47c2516f3..fed334e8a 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -65,7 +65,7 @@ struct InstanceRecord // * instance. */ public: - DEFINE_SIZE_ARRAY (4, coordinatesZ); + DEFINE_SIZE_UNBOUNDED (4); }; struct AxisRecord @@ -109,40 +109,46 @@ struct fvar axisSize == 20 && /* Assumed in our code. */ instanceSize >= axisCount * 4 + 4 && get_axes ().sanitize (c) && - c->check_range (&get_instance (0), instanceCount, instanceSize)); + c->check_range (get_instance (0), instanceCount, instanceSize)); } inline unsigned int get_axis_count (void) const { return axisCount; } - inline bool get_axis (unsigned int index, hb_ot_var_axis_t *info) const + inline void get_axis_deprecated (unsigned int axis_index, + hb_ot_var_axis_t *info) const { - if (info) - { - const AxisRecord &axis = get_axes ()[index]; - info->tag = axis.axisTag; - info->name_id = axis.axisNameID; - info->default_value = axis.defaultValue / 65536.; - /* Ensure order, to simplify client math. */ - info->min_value = MIN (info->default_value, axis.minValue / 65536.); - info->max_value = MAX (info->default_value, axis.maxValue / 65536.); - } - - return true; + const AxisRecord &axis = get_axes ()[axis_index]; + info->tag = axis.axisTag; + info->name_id = axis.axisNameID; + info->default_value = axis.defaultValue / 65536.; + /* Ensure order, to simplify client math. */ + info->min_value = MIN (info->default_value, axis.minValue / 65536.); + info->max_value = MAX (info->default_value, axis.maxValue / 65536.); } - inline hb_ot_var_axis_flags_t get_axis_flags (unsigned int index) const + inline void get_axis_info (unsigned int axis_index, + hb_ot_var_axis_info_t *info) const { - const AxisRecord &axis = get_axes ()[index]; - return (hb_ot_var_axis_flags_t) (unsigned int) axis.flags; + const AxisRecord &axis = get_axes ()[axis_index]; + info->axis_index = axis_index; + info->tag = axis.axisTag; + info->name_id = axis.axisNameID; + info->flags = (hb_ot_var_axis_flags_t) (unsigned int) axis.flags; + info->default_value = axis.defaultValue / 65536.; + /* Ensure order, to simplify client math. */ + info->min_value = MIN (info->default_value, axis.minValue / 65536.); + info->max_value = MAX (info->default_value, axis.maxValue / 65536.); + info->reserved = 0; } - inline unsigned int get_axis_infos (unsigned int start_offset, - unsigned int *axes_count /* IN/OUT */, - hb_ot_var_axis_t *axes_array /* OUT */) const + inline unsigned int get_axes_deprecated (unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_t *axes_array /* OUT */) const { if (axes_count) { + /* TODO Rewrite as hb_array_t<>::sub-array() */ unsigned int count = axisCount; start_offset = MIN (start_offset, count); @@ -153,32 +159,70 @@ struct fvar *axes_count = count; for (unsigned int i = 0; i < count; i++) - get_axis (start_offset + i, axes_array + i); + get_axis_deprecated (start_offset + i, axes_array + i); } return axisCount; } - inline bool find_axis (hb_tag_t tag, unsigned int *index, hb_ot_var_axis_t *info) const + inline unsigned int get_axis_infos (unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_info_t *axes_array /* OUT */) const + { + if (axes_count) + { + /* TODO Rewrite as hb_array_t<>::sub-array() */ + unsigned int count = axisCount; + start_offset = MIN (start_offset, count); + + count -= start_offset; + axes_array += start_offset; + + count = MIN (count, *axes_count); + *axes_count = count; + + for (unsigned int i = 0; i < count; i++) + get_axis_info (start_offset + i, axes_array + i); + } + return axisCount; + } + + inline bool find_axis_deprecated (hb_tag_t tag, + unsigned int *axis_index, + hb_ot_var_axis_t *info) const { const AxisRecord *axes = get_axes (); unsigned int count = get_axis_count (); for (unsigned int i = 0; i < count; i++) if (axes[i].axisTag == tag) { - if (index) - *index = i; - return get_axis (i, info); + if (axis_index) + *axis_index = i; + get_axis_deprecated (i, info); + return true; + } + if (axis_index) + *axis_index = HB_OT_VAR_NO_AXIS_INDEX; + return false; + } + + inline bool find_axis_info (hb_tag_t tag, + hb_ot_var_axis_info_t *info) const + { + const AxisRecord *axes = get_axes (); + unsigned int count = get_axis_count (); + for (unsigned int i = 0; i < count; i++) + if (axes[i].axisTag == tag) + { + get_axis_info (i, info); + return true; } - if (index) - *index = HB_OT_VAR_NO_AXIS_INDEX; return false; } inline int normalize_axis_value (unsigned int axis_index, float v) const { - hb_ot_var_axis_t axis; - if (!get_axis (axis_index, &axis)) - return 0; + hb_ot_var_axis_info_t axis; + get_axis_info (axis_index, &axis); v = MAX (MIN (v, axis.max_value), axis.min_value); /* Clamp. */ @@ -194,25 +238,28 @@ struct fvar inline unsigned int get_instance_count (void) const { return instanceCount; } - inline hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int index) const + inline hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int instance_index) const { - const InstanceRecord &instance = get_instance (index); - return instance.subfamilyNameID; + const InstanceRecord *instance = get_instance (instance_index); + if (unlikely (!instance)) return HB_OT_NAME_ID_INVALID; + return instance->subfamilyNameID; } - inline hb_ot_name_id_t get_instance_postscript_name_id (unsigned int index) const + inline hb_ot_name_id_t get_instance_postscript_name_id (unsigned int instance_index) const { - const InstanceRecord &instance = get_instance (index); + const InstanceRecord *instance = get_instance (instance_index); + if (unlikely (!instance)) return HB_OT_NAME_ID_INVALID; if (instanceSize >= axisCount * 4 + 6) - return StructAfter (instance.get_coordinates (axisCount)); + return StructAfter (instance->get_coordinates (axisCount)); return HB_OT_NAME_ID_INVALID; } - inline unsigned int get_instance_coords (unsigned int index, + inline unsigned int get_instance_coords (unsigned int instance_index, unsigned int *coords_length, /* IN/OUT */ float *coords /* OUT */) const { - if (unlikely (index >= instanceCount)) + const InstanceRecord *instance = get_instance (instance_index); + if (unlikely (!instance)) { if (coords_length) *coords_length = 0; @@ -221,9 +268,8 @@ struct fvar if (coords_length && *coords_length) { - const InstanceRecord &instance = get_instance (index); - hb_array_t instanceCoords = instance.get_coordinates (axisCount) - .sub_array (0, *coords_length); + hb_array_t instanceCoords = instance->get_coordinates (axisCount) + .sub_array (0, *coords_length); for (unsigned int i = 0; i < instanceCoords.len; i++) coords[i] = instanceCoords.arrayZ[i].to_float (); } @@ -234,12 +280,11 @@ struct fvar inline hb_array_t get_axes (void) const { return hb_array (&(this+firstAxis), axisCount); } - inline const InstanceRecord &get_instance (unsigned int i) const + inline const InstanceRecord *get_instance (unsigned int i) const { - if (unlikely (i >= instanceCount)) return Null (InstanceRecord); - - return StructAtOffset (&StructAfter (get_axes ()), - i * instanceSize); + if (unlikely (i >= instanceCount)) return nullptr; + return &StructAtOffset (&StructAfter (get_axes ()), + i * instanceSize); } protected: diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc index 9ad2f861e..56d248178 100644 --- a/src/hb-ot-var.cc +++ b/src/hb-ot-var.cc @@ -53,7 +53,6 @@ * @face: #hb_face_t to test * * This function allows to verify the presence of OpenType variation data on the face. - * Alternatively, use hb_ot_var_get_axis_count(). * * Return value: true if face has a `fvar' table and false otherwise * @@ -80,6 +79,7 @@ hb_ot_var_get_axis_count (hb_face_t *face) * hb_ot_var_get_axes: * * Since: 1.4.2 + * Deprecated: REPLACEME **/ unsigned int hb_ot_var_get_axes (hb_face_t *face, @@ -87,13 +87,14 @@ hb_ot_var_get_axes (hb_face_t *face, unsigned int *axes_count /* IN/OUT */, hb_ot_var_axis_t *axes_array /* OUT */) { - return face->table.fvar->get_axis_infos (start_offset, axes_count, axes_array); + return face->table.fvar->get_axes_deprecated (start_offset, axes_count, axes_array); } /** * hb_ot_var_find_axis: * * Since: 1.4.2 + * Deprecated: REPLACEME **/ hb_bool_t hb_ot_var_find_axis (hb_face_t *face, @@ -101,21 +102,37 @@ hb_ot_var_find_axis (hb_face_t *face, unsigned int *axis_index, hb_ot_var_axis_t *axis_info) { - return face->table.fvar->find_axis (axis_tag, axis_index, axis_info); + return face->table.fvar->find_axis_deprecated (axis_tag, axis_index, axis_info); } /** - * hb_ot_var_axis_get_flags: + * hb_ot_var_get_axis_infos: * * Since: REPLACEME **/ -hb_ot_var_axis_flags_t -hb_ot_var_axis_get_flags (hb_face_t *face, - unsigned int axis_index) +HB_EXTERN unsigned int +hb_ot_var_get_axis_infos (hb_face_t *face, + unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_info_t *axes_array /* OUT */) { - return face->table.fvar->get_axis_flags (axis_index); + return face->table.fvar->get_axis_infos (start_offset, axes_count, axes_array); } +/** + * hb_ot_var_find_axis_info: + * + * Since: REPLACEME + **/ +HB_EXTERN hb_bool_t +hb_ot_var_find_axis_info (hb_face_t *face, + hb_tag_t axis_tag, + hb_ot_var_axis_info_t *axis_info) +{ + return face->table.fvar->find_axis_info (axis_tag, axis_info); +} + + /* * Named instances. */ @@ -168,10 +185,10 @@ hb_ot_var_normalize_variations (hb_face_t *face, const OT::fvar &fvar = *face->table.fvar; for (unsigned int i = 0; i < variations_length; i++) { - unsigned int axis_index; - if (hb_ot_var_find_axis (face, variations[i].tag, &axis_index, nullptr) && - axis_index < coords_length) - coords[axis_index] = fvar.normalize_axis_value (axis_index, variations[i].value); + hb_ot_var_axis_info_t info; + if (hb_ot_var_find_axis_info (face, variations[i].tag, &info) && + info.axis_index < coords_length) + coords[info.axis_index] = fvar.normalize_axis_value (info.axis_index, variations[i].value); } face->table.avar->map_coords (coords, coords_length); diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h index 79ce7d72b..779be1043 100644 --- a/src/hb-ot-var.h +++ b/src/hb-ot-var.h @@ -47,19 +47,6 @@ HB_BEGIN_DECLS * fvar / avar */ -/** - * hb_ot_var_axis_t: - * - * Since: 1.4.2 - */ -typedef struct hb_ot_var_axis_t { - hb_tag_t tag; - hb_ot_name_id_t name_id; - float min_value; - float default_value; - float max_value; -} hb_ot_var_axis_t; - HB_EXTERN hb_bool_t hb_ot_var_has_data (hb_face_t *face); @@ -68,28 +55,10 @@ hb_ot_var_has_data (hb_face_t *face); * Variation axes. */ -/** - * HB_OT_VAR_NO_AXIS_INDEX: - * - * Since: 1.4.2 - */ -#define HB_OT_VAR_NO_AXIS_INDEX 0xFFFFFFFFu HB_EXTERN unsigned int hb_ot_var_get_axis_count (hb_face_t *face); -HB_EXTERN unsigned int -hb_ot_var_get_axes (hb_face_t *face, - unsigned int start_offset, - unsigned int *axes_count /* IN/OUT */, - hb_ot_var_axis_t *axes_array /* OUT */); - -HB_EXTERN hb_bool_t -hb_ot_var_find_axis (hb_face_t *face, - hb_tag_t axis_tag, - unsigned int *axis_index, - hb_ot_var_axis_t *axis_info); - /** * hb_ot_var_axis_flags_t: * @HB_OT_VAR_AXIS_FLAG_HIDDEN: The axis should not be exposed directly in user interfaces. @@ -97,12 +66,39 @@ hb_ot_var_find_axis (hb_face_t *face, * Since: REPLACEME */ typedef enum { /*< flags >*/ - HB_OT_VAR_AXIS_FLAG_HIDDEN = 0x0001u, + HB_OT_VAR_AXIS_FLAG_HIDDEN = 0x00000001u, + + _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/ } hb_ot_var_axis_flags_t; -HB_EXTERN hb_ot_var_axis_flags_t -hb_ot_var_axis_get_flags (hb_face_t *face, - unsigned int axis_index); +/** + * hb_ot_var_axis_info_t: + * + * Since: REPLACEME + */ +typedef struct hb_ot_var_axis_info_t +{ + unsigned int axis_index; + hb_tag_t tag; + hb_ot_name_id_t name_id; + hb_ot_var_axis_flags_t flags; + float min_value; + float default_value; + float max_value; + /*< private >*/ + unsigned int reserved; +} hb_ot_var_axis_info_t; + +HB_EXTERN unsigned int +hb_ot_var_get_axis_infos (hb_face_t *face, + unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_info_t *axes_array /* OUT */); + +HB_EXTERN hb_bool_t +hb_ot_var_find_axis_info (hb_face_t *face, + hb_tag_t axis_tag, + hb_ot_var_axis_info_t *axis_info); /* diff --git a/src/hb-ot-vorg-table.hh b/src/hb-ot-vorg-table.hh index a4a24bbbd..5a00bfc35 100644 --- a/src/hb-ot-vorg-table.hh +++ b/src/hb-ot-vorg-table.hh @@ -63,11 +63,10 @@ struct VORG inline int get_y_origin (hb_codepoint_t glyph) const { - int i = vertYOrigins.bsearch (glyph); - if (i != -1) - return vertYOrigins[i].vertOriginY; - - return defaultVertOriginY; + unsigned int i; + if (!vertYOrigins.bfind (glyph, &i)) + return defaultVertOriginY; + return vertYOrigins[i].vertOriginY; } inline bool _subset (const hb_subset_plan_t *plan HB_UNUSED, diff --git a/src/hb-set.hh b/src/hb-set.hh index bc26ed3c0..8b7a0f3d0 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -45,7 +45,7 @@ struct hb_set_t struct page_map_t { - inline int cmp (const page_map_t *o) const { return (int) o->major - (int) major; } + inline int cmp (const page_map_t &o) const { return (int) o.major - (int) major; } uint32_t major; uint32_t index; @@ -341,11 +341,11 @@ struct hb_set_t { /* TODO perform op even if !successful. */ if (unlikely (!successful)) return; - page_t *p = page_for (g); - if (!p) + page_t *page = page_for (g); + if (!page) return; dirty (); - p->del (g); + page->del (g); } inline void del_range (hb_codepoint_t a, hb_codepoint_t b) { @@ -357,10 +357,10 @@ struct hb_set_t } inline bool has (hb_codepoint_t g) const { - const page_t *p = page_for (g); - if (!p) + const page_t *page = page_for (g); + if (!page) return false; - return p->has (g); + return page->has (g); } inline bool intersects (hb_codepoint_t first, hb_codepoint_t last) const @@ -544,7 +544,7 @@ struct hb_set_t page_map_t map = {get_major (*codepoint), 0}; unsigned int i; - page_map.bfind (map, &i); + page_map.bfind (map, &i, HB_BFIND_NOT_FOUND_STORE_CLOSEST); if (i < page_map.len && page_map[i].major == map.major) { if (pages[page_map[i].index].next (codepoint)) @@ -575,7 +575,7 @@ struct hb_set_t page_map_t map = {get_major (*codepoint), 0}; unsigned int i; - page_map.bfind (map, &i); + page_map.bfind (map, &i, HB_BFIND_NOT_FOUND_STORE_CLOSEST); if (i < page_map.len && page_map[i].major == map.major) { if (pages[page_map[i].index].previous (codepoint)) @@ -670,7 +670,7 @@ struct hb_set_t { page_map_t map = {get_major (g), pages.len}; unsigned int i; - if (!page_map.bfind (map, &i)) + if (!page_map.bfind (map, &i, HB_BFIND_NOT_FOUND_STORE_CLOSEST)) { if (!resize (pages.len + 1)) return nullptr; diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 270da3d77..45f3a6916 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -48,7 +48,7 @@ **/ -#ifdef HB_USE_ATEXIT +#if HB_USE_ATEXIT static void free_static_shaper_list (void); #endif @@ -69,7 +69,7 @@ static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_tinit (); -#ifdef HB_USE_ATEXIT +#if HB_USE_ATEXIT atexit (free_static_uniscribe_shaper_funcs); #endif @@ -261,7 +261,7 @@ static struct hb_uniscribe_shaper_funcs_lazy_loader_t : hb_lazy_loader_t +template struct hb_vector_t { + static_assert ((bool) (unsigned) hb_static_size (Type), ""); + typedef Type ItemType; enum { item_size = sizeof (Type) }; - HB_NO_COPY_ASSIGN_TEMPLATE2 (hb_vector_t, Type, StaticSize); + HB_NO_COPY_ASSIGN_TEMPLATE2 (hb_vector_t, Type, PreallocedCount); inline hb_vector_t (void) { init (); } inline ~hb_vector_t (void) { fini (); } @@ -45,7 +47,7 @@ struct hb_vector_t private: unsigned int allocated; /* == 0 means allocation failed. */ Type *arrayZ_; - Type static_array[StaticSize]; + Type static_array[PreallocedCount]; public: void init (void) @@ -89,6 +91,16 @@ struct hb_vector_t return arrayZ()[i]; } + inline hb_array_t as_array (void) + { return hb_array (arrayZ(), len); } + inline hb_array_t as_array (void) const + { return hb_array (arrayZ(), len); } + + inline hb_sorted_array_t as_sorted_array (void) + { return hb_sorted_array (arrayZ(), len); } + inline hb_sorted_array_t as_sorted_array (void) const + { return hb_sorted_array (arrayZ(), len); } + template inline operator T * (void) { return arrayZ(); } template inline operator const T * (void) const { return arrayZ(); } @@ -209,75 +221,28 @@ struct hb_vector_t } inline void qsort (int (*cmp)(const void*, const void*)) - { - ::qsort (arrayZ(), len, sizeof (Type), cmp); - } - - inline void qsort (void) - { - ::qsort (arrayZ(), len, sizeof (Type), Type::cmp); - } - - inline void qsort (unsigned int start, unsigned int end) - { - ::qsort (arrayZ() + start, end - start, sizeof (Type), Type::cmp); - } + { as_array ().qsort (cmp); } + inline void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) + { as_array ().qsort (start, end); } template - inline Type *lsearch (const T &x) - { - Type *array = arrayZ(); - for (unsigned int i = 0; i < len; i++) - if (0 == array[i].cmp (&x)) - return &array[i]; - return nullptr; - } + inline Type *lsearch (const T &x, Type *not_found = nullptr) + { return as_array ().lsearch (x, not_found); } template - inline const Type *lsearch (const T &x) const - { - const Type *array = arrayZ(); - for (unsigned int i = 0; i < len; i++) - if (0 == array[i].cmp (&x)) - return &array[i]; - return nullptr; - } + inline const Type *lsearch (const T &x, const Type *not_found = nullptr) const + { return as_array ().lsearch (x, not_found); } template - inline Type *bsearch (const T &x) - { - unsigned int i; - return bfind (x, &i) ? &arrayZ()[i] : nullptr; - } + inline Type *bsearch (const T &x, Type *not_found = nullptr) + { return as_sorted_array ().bsearch (x, not_found); } template - inline const Type *bsearch (const T &x) const - { - unsigned int i; - return bfind (x, &i) ? &arrayZ()[i] : nullptr; - } + inline const Type *bsearch (const T &x, const Type *not_found = nullptr) const + { return as_sorted_array ().bsearch (x, not_found); } template - inline bool bfind (const T &x, unsigned int *i) const - { - int min = 0, max = (int) this->len - 1; - const Type *array = this->arrayZ(); - while (min <= max) - { - int mid = ((unsigned int) min + (unsigned int) max) / 2; - int c = array[mid].cmp (&x); - if (c < 0) - max = mid - 1; - else if (c > 0) - min = mid + 1; - else - { - *i = mid; - return true; - } - } - if (max < 0 || (max < (int) this->len && array[max].cmp (&x) > 0)) - max++; - *i = max; - return false; - } + inline bool bfind (const T &x, unsigned int *i = nullptr, + hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const + { return as_sorted_array ().bfind (x, i, not_found, to_store); } }; diff --git a/src/hb.hh b/src/hb.hh index 16ccf87ce..6df0a55b1 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -47,6 +47,10 @@ #define HB_H_IN #include "hb-ot.h" #define HB_OT_H_IN +#include "hb-aat.h" +#define HB_AAT_H_IN + +#include "hb-aat.h" #include #include @@ -281,7 +285,7 @@ static int errno = 0; /* Use something better? */ # endif #endif -#if HAVE_ATEXIT +#if defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT) /* atexit() is only safe to be called from shared libraries on certain * platforms. Whitelist. * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */ @@ -313,6 +317,9 @@ static int errno = 0; /* Use something better? */ #ifdef HB_NO_ATEXIT # undef HB_USE_ATEXIT #endif +#ifndef HB_USE_ATEXIT +# define HB_USE_ATEXIT 0 +#endif #define HB_STMT_START do #define HB_STMT_END while (0) @@ -443,9 +450,11 @@ typedef uint64_t hb_vector_size_impl_t; * For example, for testing "x ∈ {x1, x2, x3}" use: * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) */ -#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned int)(x) < 32) + (1U << (unsigned int)(x))) -#define FLAG_UNSAFE(x) ((unsigned int)(x) < 32 ? (1U << (unsigned int)(x)) : 0) +#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x))) +#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0) #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) +#define FLAG64(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x))) +#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0) /* Size signifying variable-sized array */ @@ -503,10 +512,13 @@ _hb_memalign(void **memptr, size_t alignment, size_t size) /* Some really basic things everyone wants. */ template struct hb_remove_const { typedef T value; }; template struct hb_remove_const { typedef T value; }; +#define hb_remove_const(T) hb_remove_const::value template struct hb_remove_reference { typedef T value; }; template struct hb_remove_reference { typedef T value; }; +#define hb_remove_reference(T) hb_remove_reference::value template struct hb_remove_pointer { typedef T value; }; template struct hb_remove_pointer { typedef T value; }; +#define hb_remove_pointer(T) hb_remove_pointer::value /* Headers we include for everyone. Keep sorted. They express dependency amongst diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 02c7f49fa..9aba2d12a 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -28,6 +28,7 @@ check_PROGRAMS = $(TEST_PROGS) noinst_PROGRAMS = $(TEST_PROGS) TEST_PROGS = \ + test-aat-layout \ test-baseline \ test-blob \ test-buffer \ diff --git a/test/api/fonts/aat-feat.ttf b/test/api/fonts/aat-feat.ttf new file mode 100644 index 000000000..1ff99a2dd Binary files /dev/null and b/test/api/fonts/aat-feat.ttf differ diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c new file mode 100644 index 000000000..358fac879 --- /dev/null +++ b/test/api/test-aat-layout.c @@ -0,0 +1,118 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb-test.h" + +#include +#include +#include + +/* Unit tests for hb-aat.h */ + +static hb_face_t *face; +static hb_face_t *sbix; + +static void +test_aat_get_feature_types (void) +{ + hb_aat_layout_feature_type_t features[3]; + unsigned int count = 3; + g_assert_cmpuint (11, ==, hb_aat_layout_get_feature_types (face, 0, &count, features)); + + g_assert_cmpuint (1, ==, features[0]); + g_assert_cmpuint (3, ==, features[1]); + g_assert_cmpuint (6, ==, features[2]); + + g_assert_cmpuint (258, ==, hb_aat_layout_feature_type_get_name_id (face, features[0])); + g_assert_cmpuint (261, ==, hb_aat_layout_feature_type_get_name_id (face, features[1])); + g_assert_cmpuint (265, ==, hb_aat_layout_feature_type_get_name_id (face, features[2])); +} + +static void +test_aat_get_feature_selectors (void) +{ + unsigned int default_index; + hb_aat_layout_feature_selector_info_t settings[3]; + unsigned int count = 3; + + g_assert_cmpuint (4, ==, hb_aat_layout_feature_type_get_selector_infos (face, + HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, + 0, &count, settings, + &default_index)); + g_assert_cmpuint (3, ==, count); + g_assert_cmpuint (0, ==, default_index); + + g_assert_cmpuint (0, ==, settings[0].enable); + g_assert_cmpuint (294, ==, settings[0].name_id); + + g_assert_cmpuint (1, ==, settings[1].enable); + g_assert_cmpuint (295, ==, settings[1].name_id); + + g_assert_cmpuint (2, ==, settings[2].enable); + g_assert_cmpuint (296, ==, settings[2].name_id); + + count = 3; + g_assert_cmpuint (4, ==, hb_aat_layout_feature_type_get_selector_infos (face, + HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, + 3, &count, settings, + &default_index)); + g_assert_cmpuint (1, ==, count); + g_assert_cmpuint (0, ==, default_index); + + g_assert_cmpuint (3, ==, settings[0].enable); + g_assert_cmpuint (297, ==, settings[0].name_id); + + count = 1; + g_assert_cmpuint (1, ==, hb_aat_layout_feature_type_get_selector_infos (face, + HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, + 0, &count, settings, + &default_index)); + g_assert_cmpuint (1, ==, count); + g_assert_cmpuint (HB_AAT_LAYOUT_NO_SELECTOR_INDEX, ==, default_index); + + g_assert_cmpuint (8, ==, settings[0].enable); + g_assert_cmpuint (308, ==, settings[0].name_id); + + count = 100; + g_assert_cmpuint (0, ==, hb_aat_layout_feature_type_get_selector_infos (face, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, + 0, &count, settings, + NULL)); + g_assert_cmpuint (0, ==, count); +} + +int +main (int argc, char **argv) +{ + hb_test_init (&argc, &argv); + + hb_test_add (test_aat_get_feature_types); + hb_test_add (test_aat_get_feature_selectors); + + face = hb_test_open_font_file ("fonts/aat-feat.ttf"); + sbix = hb_test_open_font_file ("fonts/chromacheck-sbix.ttf"); + unsigned int status = hb_test_run (); + hb_face_destroy (sbix); + hb_face_destroy (face); + return status; +} diff --git a/test/api/test-c.c b/test/api/test-c.c index 061f35cdc..b4518adbc 100644 --- a/test/api/test-c.c +++ b/test/api/test-c.c @@ -33,6 +33,7 @@ #include #include +#include #ifdef HAVE_GLIB #include diff --git a/test/api/test-ot-face.c b/test/api/test-ot-face.c index d6eefbaaf..757bc1f85 100644 --- a/test/api/test-ot-face.c +++ b/test/api/test-ot-face.c @@ -93,7 +93,7 @@ test_face (hb_face_t *face, hb_ot_name_get_utf32 (face, cp, NULL, NULL, NULL); hb_ot_var_get_axis_count (face); - hb_ot_var_get_axes (face, 0, NULL, NULL); + hb_ot_var_get_axis_infos (face, 0, NULL, NULL); hb_ot_var_normalize_variations (face, NULL, 0, NULL, 0); hb_ot_var_normalize_coords (face, 0, NULL, NULL); diff --git a/test/api/test-ot-tag.c b/test/api/test-ot-tag.c index c0329bffc..82a57dc0b 100644 --- a/test/api/test-ot-tag.c +++ b/test/api/test-ot-tag.c @@ -449,6 +449,9 @@ test_ot_tag_language (void) /* A UN M.49 region code, not an extended language subtag */ test_tag_from_language ("ARA", "ar-001"); + + /* An invalid tag */ + test_tag_from_language ("TRK", "tr@foo=bar"); } static void diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5634620935110656 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5634620935110656 new file mode 100644 index 000000000..39f9c3ce9 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5634620935110656 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5716208469409792 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5716208469409792 new file mode 100644 index 000000000..00915d68a Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5716208469409792 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5722888989048832 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5722888989048832 new file mode 100644 index 000000000..df1556b53 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5722888989048832 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5067936541179904 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5067936541179904 new file mode 100644 index 000000000..9f57f7bee Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5067936541179904 differ diff --git a/test/shaping/CMakeLists.txt b/test/shaping/CMakeLists.txt index 7c2c9990e..8e33edeec 100644 --- a/test/shaping/CMakeLists.txt +++ b/test/shaping/CMakeLists.txt @@ -5,6 +5,16 @@ if (HB_BUILD_UTILS) add_test (NAME ${test} COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $ "data/in-house/${test}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + set_property (TEST ${test} PROPERTY SKIP_RETURN_CODE 77) + endforeach () + + file (READ "${CMAKE_CURRENT_SOURCE_DIR}/data/aots/Makefile.sources" INHOUSE) + extract_make_variable (TESTS ${INHOUSE}) + foreach (test IN ITEMS ${TESTS}) + add_test (NAME ${test} + COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $ "data/aots/${test}" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + set_property (TEST ${test} PROPERTY SKIP_RETURN_CODE 77) endforeach () file (READ "${CMAKE_CURRENT_SOURCE_DIR}/data/text-rendering-tests/Makefile.sources" TEXTRENDERING) @@ -13,5 +23,6 @@ if (HB_BUILD_UTILS) add_test (NAME ${test} COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $ "data/text-rendering-tests/${test}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + set_property (TEST ${test} PROPERTY SKIP_RETURN_CODE 77) endforeach () endif () diff --git a/test/shaping/data/Makefile.am b/test/shaping/data/Makefile.am index 4f2c11366..01f6c5a32 100644 --- a/test/shaping/data/Makefile.am +++ b/test/shaping/data/Makefile.am @@ -4,6 +4,7 @@ NULL = SUBDIRS = \ in-house \ text-rendering-tests \ + aots \ $(NULL) # Convenience targets: diff --git a/test/shaping/data/aots/COPYING b/test/shaping/data/aots/COPYING new file mode 100644 index 000000000..d000f23b2 --- /dev/null +++ b/test/shaping/data/aots/COPYING @@ -0,0 +1,13 @@ +Copyright 2000-2016 Adobe Systems Incorporated. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use these files except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/test/shaping/data/aots/Makefile.am b/test/shaping/data/aots/Makefile.am new file mode 100644 index 000000000..3b1faee5f --- /dev/null +++ b/test/shaping/data/aots/Makefile.am @@ -0,0 +1,37 @@ +# Process this file with automake to produce Makefile.in + +NULL = + +# Convenience targets: +lib: + @$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src lib + +EXTRA_DIST = \ + COPYING \ + fonts \ + $(TESTS) \ + $(NULL) + +TEST_EXTENSIONS = .tests +TESTS_LOG_COMPILER = $(srcdir)/../../run-tests.py $(top_builddir)/util/hb-shape$(EXEEXT) + +init-aots: + git clone https://github.com/adobe-type-tools/aots $(srcdir)/aots + make -C$(srcdir)/aots + make -C$(srcdir)/aots/harfbuzz + touch $(srcdir)/init-aots + +update-tests: init-aots lib + cp $(srcdir)/hb-aots-tester.cpp $(srcdir)/aots/harfbuzz/hb-aots-tester.cpp + $(CXX) -Wno-narrowing $(srcdir)/aots/harfbuzz/hb-aots-tester.cpp \ + -I$(top_srcdir)/src/ -o $(srcdir)/aots/harfbuzz/aots \ + -L$(top_builddir)/src/.libs -lharfbuzz + rm -rf $(srcdir)/tests/ + mkdir $(srcdir)/tests/ + export LD_LIBRARY_PATH=$(realpath $(top_builddir)/src/.libs); cd $(srcdir)/aots/harfbuzz; ./aots + +.PHONY: update-tests + +include Makefile.sources + +-include $(top_srcdir)/git.mk diff --git a/test/shaping/data/aots/Makefile.sources b/test/shaping/data/aots/Makefile.sources new file mode 100644 index 000000000..93396824a --- /dev/null +++ b/test/shaping/data/aots/Makefile.sources @@ -0,0 +1,126 @@ +TESTS = \ + tests/classdef1_empty.tests \ + tests/classdef1_multiple.tests \ + tests/classdef1_single.tests \ + tests/classdef1.tests \ + tests/classdef2_empty.tests \ + tests/classdef2_multiple.tests \ + tests/classdef2_single.tests \ + tests/classdef2.tests \ + tests/gpos_chaining1_boundary.tests \ + tests/gpos_chaining1_lookupflag.tests \ + tests/gpos_chaining1_multiple_subrules.tests \ + tests/gpos_chaining1_next_glyph.tests \ + tests/gpos_chaining1_simple.tests \ + tests/gpos_chaining1_successive.tests \ + tests/gpos_chaining2_boundary.tests \ + tests/gpos_chaining2_lookupflag.tests \ + tests/gpos_chaining2_multiple_subrules.tests \ + tests/gpos_chaining2_next_glyph.tests \ + tests/gpos_chaining2_simple.tests \ + tests/gpos_chaining2_successive.tests \ + tests/gpos_chaining3_boundary.tests \ + tests/gpos_chaining3_lookupflag.tests \ + tests/gpos_chaining3_next_glyph.tests \ + tests/gpos_chaining3_simple.tests \ + tests/gpos_chaining3_successive.tests \ + tests/gpos_context1_boundary.tests \ + tests/gpos_context1_expansion.tests \ + tests/gpos_context1_lookupflag.tests \ + tests/gpos_context1_multiple_subrules.tests \ + tests/gpos_context1_next_glyph.tests \ + tests/gpos_context1_simple.tests \ + tests/gpos_context1_successive.tests \ + tests/gpos_context2_boundary.tests \ + tests/gpos_context2_classes.tests \ + tests/gpos_context2_expansion.tests \ + tests/gpos_context2_lookupflag.tests \ + tests/gpos_context2_multiple_subrules.tests \ + tests/gpos_context2_next_glyph.tests \ + tests/gpos_context2_simple.tests \ + tests/gpos_context2_successive.tests \ + tests/gpos_context3_boundary.tests \ + tests/gpos_context3_lookupflag.tests \ + tests/gpos_context3_next_glyph.tests \ + tests/gpos_context3_simple.tests \ + tests/gpos_context3_successive.tests \ + tests/gpos1_1_lookupflag.tests \ + tests/gpos1_1_simple.tests \ + tests/gpos1_2_lookupflag.tests \ + tests/gpos1_2.tests \ + tests/gpos2_1_lookupflag.tests \ + tests/gpos2_1_next_glyph.tests \ + tests/gpos2_1_simple.tests \ + tests/gpos2_1.tests \ + tests/gpos2_2.tests \ + tests/gpos3_lookupflag.tests \ + tests/gpos3.tests \ + tests/gpos4_lookupflag.tests \ + tests/gpos4_multiple_anchors.tests \ + tests/gpos4_simple.tests \ + tests/gpos5.tests \ + tests/gpos6.tests \ + tests/gpos7_1.tests \ + tests/gpos9.tests \ + tests/gsub_chaining1_boundary.tests \ + tests/gsub_chaining1_lookupflag.tests \ + tests/gsub_chaining1_multiple_subrules.tests \ + tests/gsub_chaining1_next_glyph.tests \ + tests/gsub_chaining1_simple.tests \ + tests/gsub_chaining1_successive.tests \ + tests/gsub_chaining2_boundary.tests \ + tests/gsub_chaining2_lookupflag.tests \ + tests/gsub_chaining2_multiple_subrules.tests \ + tests/gsub_chaining2_next_glyph.tests \ + tests/gsub_chaining2_simple.tests \ + tests/gsub_chaining2_successive.tests \ + tests/gsub_chaining3_boundary.tests \ + tests/gsub_chaining3_lookupflag.tests \ + tests/gsub_chaining3_next_glyph.tests \ + tests/gsub_chaining3_simple.tests \ + tests/gsub_chaining3_successive.tests \ + tests/gsub_context1_boundary.tests \ + tests/gsub_context1_expansion.tests \ + tests/gsub_context1_lookupflag.tests \ + tests/gsub_context1_multiple_subrules.tests \ + tests/gsub_context1_next_glyph.tests \ + tests/gsub_context1_simple.tests \ + tests/gsub_context1_successive.tests \ + tests/gsub_context2_boundary.tests \ + tests/gsub_context2_classes.tests \ + tests/gsub_context2_expansion.tests \ + tests/gsub_context2_lookupflag.tests \ + tests/gsub_context2_multiple_subrules.tests \ + tests/gsub_context2_next_glyph.tests \ + tests/gsub_context2_simple.tests \ + tests/gsub_context2_successive.tests \ + tests/gsub_context3_boundary.tests \ + tests/gsub_context3_lookupflag.tests \ + tests/gsub_context3_next_glyph.tests \ + tests/gsub_context3_simple.tests \ + tests/gsub_context3_successive.tests \ + tests/gsub1_1_lookupflag.tests \ + tests/gsub1_1_modulo.tests \ + tests/gsub1_1_simple.tests \ + tests/gsub1_2_lookupflag.tests \ + tests/gsub1_2_simple.tests \ + tests/gsub2_1_lookupflag.tests \ + tests/gsub2_1_multiple_sequences.tests \ + tests/gsub2_1_simple.tests \ + tests/gsub3_1_lookupflag.tests \ + tests/gsub3_1_multiple.tests \ + tests/gsub3_1_simple.tests \ + tests/gsub4_1_lookupflag.tests \ + tests/gsub4_1_multiple_ligatures.tests \ + tests/gsub4_1_multiple_ligsets.tests \ + tests/gsub4_1_simple.tests \ + tests/gsub7.tests \ + tests/lookupflag_ignore_attach.tests \ + tests/lookupflag_ignore_base.tests \ + tests/lookupflag_ignore_combination.tests \ + tests/lookupflag_ignore_ligatures.tests \ + tests/lookupflag_ignore_marks.tests \ + $(NULL) + +DISABLED_TESTS = \ + $(NULL) diff --git a/test/shaping/data/aots/fonts/classdef1_font1.otf b/test/shaping/data/aots/fonts/classdef1_font1.otf new file mode 100644 index 000000000..f0add6983 Binary files /dev/null and b/test/shaping/data/aots/fonts/classdef1_font1.otf differ diff --git a/test/shaping/data/aots/fonts/classdef1_font2.otf b/test/shaping/data/aots/fonts/classdef1_font2.otf new file mode 100644 index 000000000..f01876dd1 Binary files /dev/null and b/test/shaping/data/aots/fonts/classdef1_font2.otf differ diff --git a/test/shaping/data/aots/fonts/classdef1_font3.otf b/test/shaping/data/aots/fonts/classdef1_font3.otf new file mode 100644 index 000000000..2a0f9cc8f Binary files /dev/null and b/test/shaping/data/aots/fonts/classdef1_font3.otf differ diff --git a/test/shaping/data/aots/fonts/classdef1_font4.otf b/test/shaping/data/aots/fonts/classdef1_font4.otf new file mode 100644 index 000000000..9c0f41c51 Binary files /dev/null and b/test/shaping/data/aots/fonts/classdef1_font4.otf differ diff --git a/test/shaping/data/aots/fonts/classdef2_font1.otf b/test/shaping/data/aots/fonts/classdef2_font1.otf new file mode 100644 index 000000000..2e2faafee Binary files /dev/null and b/test/shaping/data/aots/fonts/classdef2_font1.otf differ diff --git a/test/shaping/data/aots/fonts/classdef2_font2.otf b/test/shaping/data/aots/fonts/classdef2_font2.otf new file mode 100644 index 000000000..2e2a1af78 Binary files /dev/null and b/test/shaping/data/aots/fonts/classdef2_font2.otf differ diff --git a/test/shaping/data/aots/fonts/classdef2_font3.otf b/test/shaping/data/aots/fonts/classdef2_font3.otf new file mode 100644 index 000000000..14c911938 Binary files /dev/null and b/test/shaping/data/aots/fonts/classdef2_font3.otf differ diff --git a/test/shaping/data/aots/fonts/classdef2_font4.otf b/test/shaping/data/aots/fonts/classdef2_font4.otf new file mode 100644 index 000000000..c75c883a0 Binary files /dev/null and b/test/shaping/data/aots/fonts/classdef2_font4.otf differ diff --git a/test/shaping/data/aots/fonts/cmap0_font1.otf b/test/shaping/data/aots/fonts/cmap0_font1.otf new file mode 100644 index 000000000..772f9a748 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap0_font1.otf differ diff --git a/test/shaping/data/aots/fonts/cmap10_font1.otf b/test/shaping/data/aots/fonts/cmap10_font1.otf new file mode 100644 index 000000000..023e94561 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap10_font1.otf differ diff --git a/test/shaping/data/aots/fonts/cmap10_font2.otf b/test/shaping/data/aots/fonts/cmap10_font2.otf new file mode 100644 index 000000000..5202f7946 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap10_font2.otf differ diff --git a/test/shaping/data/aots/fonts/cmap12_font1.otf b/test/shaping/data/aots/fonts/cmap12_font1.otf new file mode 100644 index 000000000..2d74b3a90 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap12_font1.otf differ diff --git a/test/shaping/data/aots/fonts/cmap14_font1.otf b/test/shaping/data/aots/fonts/cmap14_font1.otf new file mode 100644 index 000000000..a8e941d8f Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap14_font1.otf differ diff --git a/test/shaping/data/aots/fonts/cmap2_font1.otf b/test/shaping/data/aots/fonts/cmap2_font1.otf new file mode 100644 index 000000000..a123d9ca6 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap2_font1.otf differ diff --git a/test/shaping/data/aots/fonts/cmap4_font1.otf b/test/shaping/data/aots/fonts/cmap4_font1.otf new file mode 100644 index 000000000..516ed8e97 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap4_font1.otf differ diff --git a/test/shaping/data/aots/fonts/cmap4_font2.otf b/test/shaping/data/aots/fonts/cmap4_font2.otf new file mode 100644 index 000000000..0f678a3e1 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap4_font2.otf differ diff --git a/test/shaping/data/aots/fonts/cmap4_font3.otf b/test/shaping/data/aots/fonts/cmap4_font3.otf new file mode 100644 index 000000000..2034ecd43 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap4_font3.otf differ diff --git a/test/shaping/data/aots/fonts/cmap4_font4.otf b/test/shaping/data/aots/fonts/cmap4_font4.otf new file mode 100644 index 000000000..450508e3b Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap4_font4.otf differ diff --git a/test/shaping/data/aots/fonts/cmap6_font1.otf b/test/shaping/data/aots/fonts/cmap6_font1.otf new file mode 100644 index 000000000..10b64a782 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap6_font1.otf differ diff --git a/test/shaping/data/aots/fonts/cmap6_font2.otf b/test/shaping/data/aots/fonts/cmap6_font2.otf new file mode 100644 index 000000000..2d2957fda Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap6_font2.otf differ diff --git a/test/shaping/data/aots/fonts/cmap8_font1.otf b/test/shaping/data/aots/fonts/cmap8_font1.otf new file mode 100644 index 000000000..791b9e357 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap8_font1.otf differ diff --git a/test/shaping/data/aots/fonts/cmap_composition_font1.otf b/test/shaping/data/aots/fonts/cmap_composition_font1.otf new file mode 100644 index 000000000..c79071739 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap_composition_font1.otf differ diff --git a/test/shaping/data/aots/fonts/cmap_subtableselection_font1.otf b/test/shaping/data/aots/fonts/cmap_subtableselection_font1.otf new file mode 100644 index 000000000..8929f8ab2 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap_subtableselection_font1.otf differ diff --git a/test/shaping/data/aots/fonts/cmap_subtableselection_font2.otf b/test/shaping/data/aots/fonts/cmap_subtableselection_font2.otf new file mode 100644 index 000000000..26110921f Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap_subtableselection_font2.otf differ diff --git a/test/shaping/data/aots/fonts/cmap_subtableselection_font3.otf b/test/shaping/data/aots/fonts/cmap_subtableselection_font3.otf new file mode 100644 index 000000000..9f3933155 Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap_subtableselection_font3.otf differ diff --git a/test/shaping/data/aots/fonts/cmap_subtableselection_font4.otf b/test/shaping/data/aots/fonts/cmap_subtableselection_font4.otf new file mode 100644 index 000000000..83ae88efb Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap_subtableselection_font4.otf differ diff --git a/test/shaping/data/aots/fonts/cmap_subtableselection_font5.otf b/test/shaping/data/aots/fonts/cmap_subtableselection_font5.otf new file mode 100644 index 000000000..8b614adeb Binary files /dev/null and b/test/shaping/data/aots/fonts/cmap_subtableselection_font5.otf differ diff --git a/test/shaping/data/aots/fonts/gpos1_1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos1_1_lookupflag_f1.otf new file mode 100644 index 000000000..3245425df Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos1_1_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos1_1_simple_f1.otf b/test/shaping/data/aots/fonts/gpos1_1_simple_f1.otf new file mode 100644 index 000000000..c5f888822 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos1_1_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos1_1_simple_f2.otf b/test/shaping/data/aots/fonts/gpos1_1_simple_f2.otf new file mode 100644 index 000000000..905d0a398 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos1_1_simple_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos1_1_simple_f3.otf b/test/shaping/data/aots/fonts/gpos1_1_simple_f3.otf new file mode 100644 index 000000000..550be87e8 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos1_1_simple_f3.otf differ diff --git a/test/shaping/data/aots/fonts/gpos1_1_simple_f4.otf b/test/shaping/data/aots/fonts/gpos1_1_simple_f4.otf new file mode 100644 index 000000000..448bc8b83 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos1_1_simple_f4.otf differ diff --git a/test/shaping/data/aots/fonts/gpos1_2_font1.otf b/test/shaping/data/aots/fonts/gpos1_2_font1.otf new file mode 100644 index 000000000..3e7b7bc42 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos1_2_font1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos1_2_font2.otf b/test/shaping/data/aots/fonts/gpos1_2_font2.otf new file mode 100644 index 000000000..ba9d224f7 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos1_2_font2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos2_1_font6.otf b/test/shaping/data/aots/fonts/gpos2_1_font6.otf new file mode 100644 index 000000000..cd4ea94c6 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos2_1_font6.otf differ diff --git a/test/shaping/data/aots/fonts/gpos2_1_font7.otf b/test/shaping/data/aots/fonts/gpos2_1_font7.otf new file mode 100644 index 000000000..2871acc01 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos2_1_font7.otf differ diff --git a/test/shaping/data/aots/fonts/gpos2_1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos2_1_lookupflag_f1.otf new file mode 100644 index 000000000..600378243 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos2_1_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos2_1_lookupflag_f2.otf b/test/shaping/data/aots/fonts/gpos2_1_lookupflag_f2.otf new file mode 100644 index 000000000..9d0a273c0 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos2_1_lookupflag_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos2_1_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gpos2_1_next_glyph_f1.otf new file mode 100644 index 000000000..64d6c2c97 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos2_1_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos2_1_next_glyph_f2.otf b/test/shaping/data/aots/fonts/gpos2_1_next_glyph_f2.otf new file mode 100644 index 000000000..3d8c37ae7 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos2_1_next_glyph_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos2_1_simple_f1.otf b/test/shaping/data/aots/fonts/gpos2_1_simple_f1.otf new file mode 100644 index 000000000..c947776aa Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos2_1_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos2_2_font1.otf b/test/shaping/data/aots/fonts/gpos2_2_font1.otf new file mode 100644 index 000000000..dde370a0e Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos2_2_font1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos2_2_font2.otf b/test/shaping/data/aots/fonts/gpos2_2_font2.otf new file mode 100644 index 000000000..63d874a26 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos2_2_font2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos2_2_font3.otf b/test/shaping/data/aots/fonts/gpos2_2_font3.otf new file mode 100644 index 000000000..b5306764d Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos2_2_font3.otf differ diff --git a/test/shaping/data/aots/fonts/gpos2_2_font4.otf b/test/shaping/data/aots/fonts/gpos2_2_font4.otf new file mode 100644 index 000000000..b549e0239 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos2_2_font4.otf differ diff --git a/test/shaping/data/aots/fonts/gpos2_2_font5.otf b/test/shaping/data/aots/fonts/gpos2_2_font5.otf new file mode 100644 index 000000000..64c40bba9 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos2_2_font5.otf differ diff --git a/test/shaping/data/aots/fonts/gpos3_font1.otf b/test/shaping/data/aots/fonts/gpos3_font1.otf new file mode 100644 index 000000000..9b6d39acd Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos3_font1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos3_font2.otf b/test/shaping/data/aots/fonts/gpos3_font2.otf new file mode 100644 index 000000000..dee57855e Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos3_font2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos3_font3.otf b/test/shaping/data/aots/fonts/gpos3_font3.otf new file mode 100644 index 000000000..7522660d9 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos3_font3.otf differ diff --git a/test/shaping/data/aots/fonts/gpos4_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos4_lookupflag_f1.otf new file mode 100644 index 000000000..b141116af Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos4_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos4_lookupflag_f2.otf b/test/shaping/data/aots/fonts/gpos4_lookupflag_f2.otf new file mode 100644 index 000000000..84e48437c Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos4_lookupflag_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos4_multiple_anchors_1.otf b/test/shaping/data/aots/fonts/gpos4_multiple_anchors_1.otf new file mode 100644 index 000000000..025f69b31 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos4_multiple_anchors_1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos4_simple_1.otf b/test/shaping/data/aots/fonts/gpos4_simple_1.otf new file mode 100644 index 000000000..da54a1fd1 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos4_simple_1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos5_font1.otf b/test/shaping/data/aots/fonts/gpos5_font1.otf new file mode 100644 index 000000000..8c48fb679 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos5_font1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos6_font1.otf b/test/shaping/data/aots/fonts/gpos6_font1.otf new file mode 100644 index 000000000..f7f92cc37 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos6_font1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos7_1_font1.otf b/test/shaping/data/aots/fonts/gpos7_1_font1.otf new file mode 100644 index 000000000..ced8907e9 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos7_1_font1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos9_font1.otf b/test/shaping/data/aots/fonts/gpos9_font1.otf new file mode 100644 index 000000000..e99c25a04 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos9_font1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos9_font2.otf b/test/shaping/data/aots/fonts/gpos9_font2.otf new file mode 100644 index 000000000..9ae824bae Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos9_font2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f1.otf new file mode 100644 index 000000000..44c4117a0 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f2.otf new file mode 100644 index 000000000..431b08fed Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f3.otf b/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f3.otf new file mode 100644 index 000000000..1bac49ab9 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f3.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f4.otf b/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f4.otf new file mode 100644 index 000000000..3d377829c Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f4.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining1_lookupflag_f1.otf new file mode 100644 index 000000000..a83342a12 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining1_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_multiple_subrules_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining1_multiple_subrules_f1.otf new file mode 100644 index 000000000..07bf55c41 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining1_multiple_subrules_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining1_multiple_subrules_f2.otf new file mode 100644 index 000000000..dc3754b56 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining1_multiple_subrules_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining1_next_glyph_f1.otf new file mode 100644 index 000000000..17852c2d0 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining1_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_simple_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining1_simple_f1.otf new file mode 100644 index 000000000..31cbe77d1 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining1_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_simple_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining1_simple_f2.otf new file mode 100644 index 000000000..3293ad8c2 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining1_simple_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_successive_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining1_successive_f1.otf new file mode 100644 index 000000000..4c8666321 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining1_successive_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f1.otf new file mode 100644 index 000000000..49210fb95 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f2.otf new file mode 100644 index 000000000..456fc9b64 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f3.otf b/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f3.otf new file mode 100644 index 000000000..768492a89 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f3.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f4.otf b/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f4.otf new file mode 100644 index 000000000..2670da652 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f4.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining2_lookupflag_f1.otf new file mode 100644 index 000000000..e8cce567e Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining2_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_multiple_subrules_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining2_multiple_subrules_f1.otf new file mode 100644 index 000000000..f182c7f3c Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining2_multiple_subrules_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining2_multiple_subrules_f2.otf new file mode 100644 index 000000000..d24896a13 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining2_multiple_subrules_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining2_next_glyph_f1.otf new file mode 100644 index 000000000..f6bbda472 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining2_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_simple_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining2_simple_f1.otf new file mode 100644 index 000000000..1805a034b Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining2_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_simple_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining2_simple_f2.otf new file mode 100644 index 000000000..1df12f528 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining2_simple_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_successive_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining2_successive_f1.otf new file mode 100644 index 000000000..a3aadafb4 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining2_successive_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f1.otf new file mode 100644 index 000000000..4f13bdd6b Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f2.otf new file mode 100644 index 000000000..48be5dda3 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f3.otf b/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f3.otf new file mode 100644 index 000000000..a10068bb5 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f3.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f4.otf b/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f4.otf new file mode 100644 index 000000000..8030ac0eb Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f4.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining3_lookupflag_f1.otf new file mode 100644 index 000000000..7864ce02e Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining3_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining3_next_glyph_f1.otf new file mode 100644 index 000000000..20a7966c5 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining3_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_simple_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining3_simple_f1.otf new file mode 100644 index 000000000..2c633280e Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining3_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_simple_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining3_simple_f2.otf new file mode 100644 index 000000000..6ef8fb118 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining3_simple_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_successive_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining3_successive_f1.otf new file mode 100644 index 000000000..8e8439d9e Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_chaining3_successive_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context1_boundary_f1.otf b/test/shaping/data/aots/fonts/gpos_context1_boundary_f1.otf new file mode 100644 index 000000000..22bb3eacd Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context1_boundary_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context1_boundary_f2.otf b/test/shaping/data/aots/fonts/gpos_context1_boundary_f2.otf new file mode 100644 index 000000000..7e4c0e198 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context1_boundary_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context1_expansion_f1.otf b/test/shaping/data/aots/fonts/gpos_context1_expansion_f1.otf new file mode 100644 index 000000000..f7c60f68b Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context1_expansion_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos_context1_lookupflag_f1.otf new file mode 100644 index 000000000..e9b03ae13 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context1_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context1_lookupflag_f2.otf b/test/shaping/data/aots/fonts/gpos_context1_lookupflag_f2.otf new file mode 100644 index 000000000..b9998cd05 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context1_lookupflag_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context1_multiple_subrules_f1.otf b/test/shaping/data/aots/fonts/gpos_context1_multiple_subrules_f1.otf new file mode 100644 index 000000000..6f1aafaa2 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context1_multiple_subrules_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context1_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gpos_context1_multiple_subrules_f2.otf new file mode 100644 index 000000000..ed9a38764 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context1_multiple_subrules_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context1_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gpos_context1_next_glyph_f1.otf new file mode 100644 index 000000000..6007d54cf Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context1_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context1_simple_f1.otf b/test/shaping/data/aots/fonts/gpos_context1_simple_f1.otf new file mode 100644 index 000000000..5e6cd9ed3 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context1_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context1_simple_f2.otf b/test/shaping/data/aots/fonts/gpos_context1_simple_f2.otf new file mode 100644 index 000000000..b4fddb33b Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context1_simple_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context1_successive_f1.otf b/test/shaping/data/aots/fonts/gpos_context1_successive_f1.otf new file mode 100644 index 000000000..eb0f962e1 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context1_successive_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_boundary_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_boundary_f1.otf new file mode 100644 index 000000000..3fce49709 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_boundary_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_boundary_f2.otf b/test/shaping/data/aots/fonts/gpos_context2_boundary_f2.otf new file mode 100644 index 000000000..5b4e01233 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_boundary_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_classes_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_classes_f1.otf new file mode 100644 index 000000000..585b511c4 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_classes_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_classes_f2.otf b/test/shaping/data/aots/fonts/gpos_context2_classes_f2.otf new file mode 100644 index 000000000..411d58e6d Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_classes_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_expansion_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_expansion_f1.otf new file mode 100644 index 000000000..4b2d36ae7 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_expansion_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_lookupflag_f1.otf new file mode 100644 index 000000000..1c0c48086 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_lookupflag_f2.otf b/test/shaping/data/aots/fonts/gpos_context2_lookupflag_f2.otf new file mode 100644 index 000000000..bf20d8460 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_lookupflag_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_multiple_subrules_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_multiple_subrules_f1.otf new file mode 100644 index 000000000..05b6b73cb Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_multiple_subrules_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gpos_context2_multiple_subrules_f2.otf new file mode 100644 index 000000000..f79712cc4 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_multiple_subrules_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_next_glyph_f1.otf new file mode 100644 index 000000000..1b5a256fd Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_simple_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_simple_f1.otf new file mode 100644 index 000000000..9aaec44ff Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_simple_f2.otf b/test/shaping/data/aots/fonts/gpos_context2_simple_f2.otf new file mode 100644 index 000000000..c789b2ef2 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_simple_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context2_successive_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_successive_f1.otf new file mode 100644 index 000000000..b89bfb7b8 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context2_successive_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context3_boundary_f1.otf b/test/shaping/data/aots/fonts/gpos_context3_boundary_f1.otf new file mode 100644 index 000000000..f8949d475 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context3_boundary_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context3_boundary_f2.otf b/test/shaping/data/aots/fonts/gpos_context3_boundary_f2.otf new file mode 100644 index 000000000..ceb7452a8 Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context3_boundary_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context3_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos_context3_lookupflag_f1.otf new file mode 100644 index 000000000..40b55ee0e Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context3_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context3_lookupflag_f2.otf b/test/shaping/data/aots/fonts/gpos_context3_lookupflag_f2.otf new file mode 100644 index 000000000..bcf4d17ec Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context3_lookupflag_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context3_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gpos_context3_next_glyph_f1.otf new file mode 100644 index 000000000..6f9d9197f Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context3_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context3_simple_f1.otf b/test/shaping/data/aots/fonts/gpos_context3_simple_f1.otf new file mode 100644 index 000000000..470c2ed3e Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context3_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gpos_context3_successive_f1.otf b/test/shaping/data/aots/fonts/gpos_context3_successive_f1.otf new file mode 100644 index 000000000..aeb9bbdfa Binary files /dev/null and b/test/shaping/data/aots/fonts/gpos_context3_successive_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub1_1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub1_1_lookupflag_f1.otf new file mode 100644 index 000000000..a539b95d6 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub1_1_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub1_1_modulo_f1.otf b/test/shaping/data/aots/fonts/gsub1_1_modulo_f1.otf new file mode 100644 index 000000000..7ba237920 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub1_1_modulo_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub1_1_simple_f1.otf b/test/shaping/data/aots/fonts/gsub1_1_simple_f1.otf new file mode 100644 index 000000000..c21fcd3f0 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub1_1_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub1_2_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub1_2_lookupflag_f1.otf new file mode 100644 index 000000000..b13af6e7c Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub1_2_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub1_2_simple_f1.otf b/test/shaping/data/aots/fonts/gsub1_2_simple_f1.otf new file mode 100644 index 000000000..d3851b332 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub1_2_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub2_1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub2_1_lookupflag_f1.otf new file mode 100644 index 000000000..8330ad4cf Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub2_1_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub2_1_multiple_sequences_f1.otf b/test/shaping/data/aots/fonts/gsub2_1_multiple_sequences_f1.otf new file mode 100644 index 000000000..c912937e6 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub2_1_multiple_sequences_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub2_1_simple_f1.otf b/test/shaping/data/aots/fonts/gsub2_1_simple_f1.otf new file mode 100644 index 000000000..584a7f555 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub2_1_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub3_1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub3_1_lookupflag_f1.otf new file mode 100644 index 000000000..4ccf55f4a Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub3_1_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub3_1_multiple_f1.otf b/test/shaping/data/aots/fonts/gsub3_1_multiple_f1.otf new file mode 100644 index 000000000..075f1962d Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub3_1_multiple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub3_1_simple_f1.otf b/test/shaping/data/aots/fonts/gsub3_1_simple_f1.otf new file mode 100644 index 000000000..201f0f237 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub3_1_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub4_1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub4_1_lookupflag_f1.otf new file mode 100644 index 000000000..08ec01a72 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub4_1_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub4_1_multiple_ligatures_f1.otf b/test/shaping/data/aots/fonts/gsub4_1_multiple_ligatures_f1.otf new file mode 100644 index 000000000..90da33160 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub4_1_multiple_ligatures_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub4_1_multiple_ligatures_f2.otf b/test/shaping/data/aots/fonts/gsub4_1_multiple_ligatures_f2.otf new file mode 100644 index 000000000..4383ba938 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub4_1_multiple_ligatures_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub4_1_multiple_ligsets_f1.otf b/test/shaping/data/aots/fonts/gsub4_1_multiple_ligsets_f1.otf new file mode 100644 index 000000000..cea1b1aee Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub4_1_multiple_ligsets_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub4_1_simple_f1.otf b/test/shaping/data/aots/fonts/gsub4_1_simple_f1.otf new file mode 100644 index 000000000..50c713a85 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub4_1_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub7_font1.otf b/test/shaping/data/aots/fonts/gsub7_font1.otf new file mode 100644 index 000000000..b920398a5 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub7_font1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub7_font2.otf b/test/shaping/data/aots/fonts/gsub7_font2.otf new file mode 100644 index 000000000..c98bafb51 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub7_font2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f1.otf new file mode 100644 index 000000000..444d93174 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f2.otf b/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f2.otf new file mode 100644 index 000000000..2268647d7 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f3.otf b/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f3.otf new file mode 100644 index 000000000..a59294749 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f3.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f4.otf b/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f4.otf new file mode 100644 index 000000000..f3f6b8c28 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f4.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining1_lookupflag_f1.otf new file mode 100644 index 000000000..47e4c64dd Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining1_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_multiple_subrules_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining1_multiple_subrules_f1.otf new file mode 100644 index 000000000..741362c8c Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining1_multiple_subrules_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gsub_chaining1_multiple_subrules_f2.otf new file mode 100644 index 000000000..67801f210 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining1_multiple_subrules_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining1_next_glyph_f1.otf new file mode 100644 index 000000000..655000aad Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining1_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_simple_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining1_simple_f1.otf new file mode 100644 index 000000000..c7709656a Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining1_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_simple_f2.otf b/test/shaping/data/aots/fonts/gsub_chaining1_simple_f2.otf new file mode 100644 index 000000000..8999e3f7c Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining1_simple_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_successive_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining1_successive_f1.otf new file mode 100644 index 000000000..ad472ece2 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining1_successive_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f1.otf new file mode 100644 index 000000000..845c2560a Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f2.otf b/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f2.otf new file mode 100644 index 000000000..af0ad1f78 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f3.otf b/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f3.otf new file mode 100644 index 000000000..28679c867 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f3.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f4.otf b/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f4.otf new file mode 100644 index 000000000..14746c6e8 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f4.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining2_lookupflag_f1.otf new file mode 100644 index 000000000..2f4feedf1 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining2_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_multiple_subrules_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining2_multiple_subrules_f1.otf new file mode 100644 index 000000000..6edeb6bb0 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining2_multiple_subrules_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gsub_chaining2_multiple_subrules_f2.otf new file mode 100644 index 000000000..ae0298fd2 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining2_multiple_subrules_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining2_next_glyph_f1.otf new file mode 100644 index 000000000..878666f5c Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining2_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_simple_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining2_simple_f1.otf new file mode 100644 index 000000000..e8609309d Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining2_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_simple_f2.otf b/test/shaping/data/aots/fonts/gsub_chaining2_simple_f2.otf new file mode 100644 index 000000000..4fdde3323 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining2_simple_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_successive_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining2_successive_f1.otf new file mode 100644 index 000000000..90f9f731c Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining2_successive_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f1.otf new file mode 100644 index 000000000..1aea8bee2 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f2.otf b/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f2.otf new file mode 100644 index 000000000..97c92c38a Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f3.otf b/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f3.otf new file mode 100644 index 000000000..3b8513eb5 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f3.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f4.otf b/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f4.otf new file mode 100644 index 000000000..e81d00ed5 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f4.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining3_lookupflag_f1.otf new file mode 100644 index 000000000..47c1007c0 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining3_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining3_next_glyph_f1.otf new file mode 100644 index 000000000..9160eda2b Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining3_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_simple_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining3_simple_f1.otf new file mode 100644 index 000000000..5982eb512 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining3_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_simple_f2.otf b/test/shaping/data/aots/fonts/gsub_chaining3_simple_f2.otf new file mode 100644 index 000000000..359b12602 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining3_simple_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_successive_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining3_successive_f1.otf new file mode 100644 index 000000000..ae39d9207 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_chaining3_successive_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context1_boundary_f1.otf b/test/shaping/data/aots/fonts/gsub_context1_boundary_f1.otf new file mode 100644 index 000000000..0267cabfb Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context1_boundary_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context1_boundary_f2.otf b/test/shaping/data/aots/fonts/gsub_context1_boundary_f2.otf new file mode 100644 index 000000000..24b1716fd Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context1_boundary_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context1_expansion_f1.otf b/test/shaping/data/aots/fonts/gsub_context1_expansion_f1.otf new file mode 100644 index 000000000..c1dda8078 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context1_expansion_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub_context1_lookupflag_f1.otf new file mode 100644 index 000000000..60676ab50 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context1_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context1_lookupflag_f2.otf b/test/shaping/data/aots/fonts/gsub_context1_lookupflag_f2.otf new file mode 100644 index 000000000..bcb56e419 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context1_lookupflag_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context1_multiple_subrules_f1.otf b/test/shaping/data/aots/fonts/gsub_context1_multiple_subrules_f1.otf new file mode 100644 index 000000000..52cd86161 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context1_multiple_subrules_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context1_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gsub_context1_multiple_subrules_f2.otf new file mode 100644 index 000000000..891356a08 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context1_multiple_subrules_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context1_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gsub_context1_next_glyph_f1.otf new file mode 100644 index 000000000..2786dedc6 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context1_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context1_simple_f1.otf b/test/shaping/data/aots/fonts/gsub_context1_simple_f1.otf new file mode 100644 index 000000000..ebdaf22a7 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context1_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context1_simple_f2.otf b/test/shaping/data/aots/fonts/gsub_context1_simple_f2.otf new file mode 100644 index 000000000..d4a3fbfce Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context1_simple_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context1_successive_f1.otf b/test/shaping/data/aots/fonts/gsub_context1_successive_f1.otf new file mode 100644 index 000000000..ce2dce5d4 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context1_successive_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_boundary_f1.otf b/test/shaping/data/aots/fonts/gsub_context2_boundary_f1.otf new file mode 100644 index 000000000..6f46192dc Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_boundary_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_boundary_f2.otf b/test/shaping/data/aots/fonts/gsub_context2_boundary_f2.otf new file mode 100644 index 000000000..ef19d8774 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_boundary_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_classes_f1.otf b/test/shaping/data/aots/fonts/gsub_context2_classes_f1.otf new file mode 100644 index 000000000..85077601a Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_classes_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_classes_f2.otf b/test/shaping/data/aots/fonts/gsub_context2_classes_f2.otf new file mode 100644 index 000000000..ceb74b2cb Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_classes_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_expansion_f1.otf b/test/shaping/data/aots/fonts/gsub_context2_expansion_f1.otf new file mode 100644 index 000000000..c12f0ac7a Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_expansion_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub_context2_lookupflag_f1.otf new file mode 100644 index 000000000..a0fada4f4 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_lookupflag_f2.otf b/test/shaping/data/aots/fonts/gsub_context2_lookupflag_f2.otf new file mode 100644 index 000000000..cd40a5d0a Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_lookupflag_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_multiple_subrules_f1.otf b/test/shaping/data/aots/fonts/gsub_context2_multiple_subrules_f1.otf new file mode 100644 index 000000000..53be20d56 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_multiple_subrules_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gsub_context2_multiple_subrules_f2.otf new file mode 100644 index 000000000..6bcc0cb30 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_multiple_subrules_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gsub_context2_next_glyph_f1.otf new file mode 100644 index 000000000..4ca4e4897 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_simple_f1.otf b/test/shaping/data/aots/fonts/gsub_context2_simple_f1.otf new file mode 100644 index 000000000..16aae9d2e Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_simple_f2.otf b/test/shaping/data/aots/fonts/gsub_context2_simple_f2.otf new file mode 100644 index 000000000..fc31262e6 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_simple_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context2_successive_f1.otf b/test/shaping/data/aots/fonts/gsub_context2_successive_f1.otf new file mode 100644 index 000000000..cf1a89c1e Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context2_successive_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context3_boundary_f1.otf b/test/shaping/data/aots/fonts/gsub_context3_boundary_f1.otf new file mode 100644 index 000000000..01cd29dba Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context3_boundary_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context3_boundary_f2.otf b/test/shaping/data/aots/fonts/gsub_context3_boundary_f2.otf new file mode 100644 index 000000000..6fa5f05a3 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context3_boundary_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context3_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub_context3_lookupflag_f1.otf new file mode 100644 index 000000000..94371b4d1 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context3_lookupflag_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context3_lookupflag_f2.otf b/test/shaping/data/aots/fonts/gsub_context3_lookupflag_f2.otf new file mode 100644 index 000000000..d8150df42 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context3_lookupflag_f2.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context3_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gsub_context3_next_glyph_f1.otf new file mode 100644 index 000000000..93533b81c Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context3_next_glyph_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context3_simple_f1.otf b/test/shaping/data/aots/fonts/gsub_context3_simple_f1.otf new file mode 100644 index 000000000..a1cd98c43 Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context3_simple_f1.otf differ diff --git a/test/shaping/data/aots/fonts/gsub_context3_successive_f1.otf b/test/shaping/data/aots/fonts/gsub_context3_successive_f1.otf new file mode 100644 index 000000000..d8b3d5ccb Binary files /dev/null and b/test/shaping/data/aots/fonts/gsub_context3_successive_f1.otf differ diff --git a/test/shaping/data/aots/fonts/lookupflag_ignore_attach_f1.otf b/test/shaping/data/aots/fonts/lookupflag_ignore_attach_f1.otf new file mode 100644 index 000000000..80651f1d6 Binary files /dev/null and b/test/shaping/data/aots/fonts/lookupflag_ignore_attach_f1.otf differ diff --git a/test/shaping/data/aots/fonts/lookupflag_ignore_base_f1.otf b/test/shaping/data/aots/fonts/lookupflag_ignore_base_f1.otf new file mode 100644 index 000000000..3c242b0d1 Binary files /dev/null and b/test/shaping/data/aots/fonts/lookupflag_ignore_base_f1.otf differ diff --git a/test/shaping/data/aots/fonts/lookupflag_ignore_combination_f1.otf b/test/shaping/data/aots/fonts/lookupflag_ignore_combination_f1.otf new file mode 100644 index 000000000..b88359a8f Binary files /dev/null and b/test/shaping/data/aots/fonts/lookupflag_ignore_combination_f1.otf differ diff --git a/test/shaping/data/aots/fonts/lookupflag_ignore_ligatures_f1.otf b/test/shaping/data/aots/fonts/lookupflag_ignore_ligatures_f1.otf new file mode 100644 index 000000000..1dc0c237c Binary files /dev/null and b/test/shaping/data/aots/fonts/lookupflag_ignore_ligatures_f1.otf differ diff --git a/test/shaping/data/aots/fonts/lookupflag_ignore_marks_f1.otf b/test/shaping/data/aots/fonts/lookupflag_ignore_marks_f1.otf new file mode 100644 index 000000000..aa429de3a Binary files /dev/null and b/test/shaping/data/aots/fonts/lookupflag_ignore_marks_f1.otf differ diff --git a/test/shaping/data/aots/hb-aots-tester.cpp b/test/shaping/data/aots/hb-aots-tester.cpp new file mode 100644 index 000000000..bd46dec36 --- /dev/null +++ b/test/shaping/data/aots/hb-aots-tester.cpp @@ -0,0 +1,344 @@ +/*____________________________________________________________________________ + + Copyright 2000-2016 Adobe Systems Incorporated. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use these files except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +____________________________________________________________________________*/ + +#include "stdlib.h" +#include "stdio.h" +#include "string.h" +#include "hb.h" +#include "hb-ot.h" + +static const bool verbose = true; + + +hb_feature_t *gFeatures; +int gNbFeatures; + + hb_buffer_t *runTest(const char *testName, + const char *fontfileName, + unsigned int *in, int nbIn, + unsigned int *select, int nbSelect) +{ + FILE *f = fopen (fontfileName, "rb"); + fseek(f, 0, SEEK_END); + long fontsize = ftell(f); + fseek(f, 0, SEEK_SET); + char *fontdata = (char *)malloc (fontsize); + fread(fontdata, fontsize, 1, f); + fclose(f); + + if (verbose) { + printf ("------------------------------- %s\n", testName); + } + + // setup font + hb_blob_t *blob = hb_blob_create(fontdata, fontsize, + HB_MEMORY_MODE_WRITABLE, + 0, 0); + hb_face_t *face = hb_face_create(blob, 0); + hb_font_t *font = hb_font_create(face); + unsigned int upem = hb_face_get_upem (face); + + hb_font_set_scale(font, upem, upem); + hb_ot_font_set_funcs (font); + + // setup buffer + hb_buffer_t *buffer = hb_buffer_create(); + hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); + hb_buffer_set_script(buffer, HB_SCRIPT_LATIN); + hb_buffer_set_language(buffer, hb_language_from_string("en", 2)); + + hb_buffer_add_utf32(buffer, in, nbIn, 0, nbIn); + + // setup features + hb_feature_t *features; + int nbFeatures; + + if (nbSelect == 0) + { + nbFeatures = 1; + + features = (hb_feature_t *) malloc (sizeof (*features)); + features[0].tag = HB_TAG('t', 'e', 's', 't'); + features[0].value = 1; + features[0].start = 0; + features[0].end = 0xffffffff; + } + else + { + nbFeatures = 0; + + features = (hb_feature_t *) malloc (sizeof (*features) * nbSelect); + for (int i = 0; i < nbSelect; i++) { + if (select[i] != -1) { + features[nbFeatures].tag = HB_TAG('t', 'e', 's', 't'); + features[nbFeatures].value = select[i]; + features[nbFeatures].start = i; + features[nbFeatures].end = i + 1; + nbFeatures++; + } + } + } + gFeatures = features; + gNbFeatures = nbFeatures; + + // shape + hb_shape(font, buffer, features, nbFeatures); + + hb_blob_destroy(blob); + hb_font_destroy(font); + hb_face_destroy(face); + //free(features); + + return buffer; +} + + +void printArray (const char* s, int *a, int n) +{ + printf ("%s %d : ", s, n); + for (int i = 0; i < n; i++) { + printf (" %d", a[i]); + } + printf ("\n"); +} + +void printUArray (const char* s, unsigned int *a, int n) +{ + printArray (s, (int *) a, n); +} + +bool gsub_test(const char *testName, + const char *fontfileName, + int nbIn, unsigned int *in, + int nbSelect, unsigned int *select, + int nbExpected, unsigned int *expected) +{ + hb_buffer_t *buffer = runTest(testName, + fontfileName, + in, nbIn, + select, nbSelect); + + // verify + hb_glyph_info_t *actual = hb_buffer_get_glyph_infos(buffer, 0); + unsigned int nbActual = hb_buffer_get_length(buffer); + + bool ok = true; + + if (nbActual != nbExpected) + ok = false; + else { + for (int i = 0; i < nbActual; i++) { + if (actual[i].codepoint != expected [i]) { + ok = false; + break; + } + } + } + + + char test_name[255]; + sprintf (test_name, "../../tests/%.*s.tests", (int) (strrchr (testName, '_') - testName), testName); + FILE *tests_file = fopen (test_name, "a+"); + if (!ok) fprintf (tests_file, "#"); + fprintf (tests_file, "../fonts/%s:--features=\"", fontfileName + 9); + for (unsigned int i = 0; i < gNbFeatures; i++) + { + if (i != 0) fprintf (tests_file, ","); + char buf[255]; + hb_feature_to_string (&gFeatures[i], buf, sizeof (buf)); + fprintf (tests_file, "%s", buf); + } + free (gFeatures); + fprintf (tests_file, "\" --no-clusters --no-glyph-names --no-positions:"); + + for (unsigned int i = 0; i < nbIn; i++) + { + if (i != 0) fprintf (tests_file, ","); + fprintf (tests_file, "U+%04X", in[i]); + } + + fprintf (tests_file, ":["); + for (unsigned int i = 0; i < nbActual; i++) + { + if (i != 0) fprintf (tests_file, "|"); + fprintf (tests_file, "%d", expected[i]); + } + fprintf (tests_file, "]"); + + fprintf (tests_file, "\n"); + fclose (tests_file); + + + if (! ok) { + printf ("******* GSUB %s\n", testName); + + printf ("expected %d:", nbExpected); + for (int i = 0; i < nbExpected; i++) { + printf (" %d", expected[i]); } + printf ("\n"); + + printf (" actual %d:", nbActual); + for (int i = 0; i < nbActual; i++) { + printf (" %d", actual[i].codepoint); } + printf ("\n"); + + } + + hb_buffer_destroy(buffer); + + return ok; +} + +bool gpos_test(const char *testName, + const char *fontfileName, + int nbIn, + unsigned int *in, + int nbOut, + unsigned int *out, + int *x, + int *y) +{ + hb_buffer_t *buffer = runTest(testName, + fontfileName, + in, nbIn, + 0, 0); + + // verify + unsigned int nbActual; + hb_glyph_info_t *actual = hb_buffer_get_glyph_infos(buffer, &nbActual); + hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); + + unsigned int *actualG = (unsigned int *) malloc(sizeof(*actualG) * nbActual); + int *actualX = (int *) malloc(sizeof(*actualX) * nbActual); + int *actualY = (int *) malloc(sizeof(*actualY) * nbActual); + int curX = 0; + int curY = 0; + for (int i = 0; i < nbActual; i++) { + actualG[i] = actual[i].codepoint; + actualX[i] = curX + pos[i].x_offset; + actualY[i] = curY + pos[i].y_offset; + + actualX[i] -= 1500 * i; + + curX += pos[i].x_advance; + curY += pos[i].y_advance; + } + + bool nbOk = true; + bool xOk = true; + bool yOk = true; + + if (nbActual != nbOut) + nbOk = false; + else { + for (int i = 0; i < nbActual; i++) { + if (actualX[i] != x[i]) { + xOk = false; + } + if (actualY[i] != y[i]) { + yOk = false; + } + } + } + + bool ok = (nbOk && xOk && yOk); + if (! ok) { + printf ("******* GPOS %s\n", testName); + + if (! (nbOk && xOk)) { + printArray ("expectedX", x, nbOut); + printArray ("actualX ", actualX, nbActual); + + printf ("xadv/pos:"); + for (int i = 0; i < nbOut; i++) { + printf (" %d/%d", pos[i].x_advance, pos[i].x_offset); + } + printf ("\n"); + } + + if (! (nbOk && yOk)) { + printArray ("expectedY", y, nbOut); + printArray ("actualY ", actualY, nbActual); + + printf ("yadv/pos:"); + for (int i = 0; i < nbOut; i++) { + printf (" %d/%d", pos[i].y_advance, pos[i].y_offset); + } + printf ("\n"); + } + } + + + char test_name[255]; + sprintf (test_name, "../../tests/%.*s.tests", (int) (strrchr (testName, '_') - testName), testName); + FILE *tests_file = fopen (test_name, "a+"); + if (!ok) fprintf (tests_file, "#"); + fprintf (tests_file, "../fonts/%s:--features=\"", fontfileName + 9); + for (unsigned int i = 0; i < gNbFeatures; i++) + { + if (i != 0) fprintf (tests_file, ","); + char buf[255]; + hb_feature_to_string (&gFeatures[i], buf, sizeof (buf)); + fprintf (tests_file, "%s", buf); + } + free (gFeatures); + fprintf (tests_file, "\" --no-clusters --no-glyph-names --ned:"); + + for (unsigned int i = 0; i < nbIn; i++) + { + if (i != 0) fprintf (tests_file, ","); + fprintf (tests_file, "U+%04X", in[i]); + } + + fprintf (tests_file, ":["); + for (unsigned int i = 0; i < nbActual; i++) + { + if (i != 0) fprintf (tests_file, "|"); + fprintf (tests_file, "%d", /*it should be "out[i]"*/ actualG[i]); + + int expected_x = x[i] + 1500*i; + int expected_y = y[i]; + if (expected_x || expected_y) fprintf (tests_file, "@%d,%d", expected_x, expected_y); + } + fprintf (tests_file, "]"); + + fprintf (tests_file, "\n"); + fclose (tests_file); + + + hb_buffer_destroy(buffer); + + free(actualG); + free(actualX); + free(actualY); + + return ok; +} + + +int main(int argc, char **argv) +{ + int failures = 0; + int pass = 0; + +#include "hb-aots-tester.h" + + printf ("%d failures, %d pass\n", failures, pass); +} + + + diff --git a/test/shaping/data/aots/tests/classdef1.tests b/test/shaping/data/aots/tests/classdef1.tests new file mode 100644 index 000000000..40ded45e7 --- /dev/null +++ b/test/shaping/data/aots/tests/classdef1.tests @@ -0,0 +1 @@ +../fonts/classdef1_font4.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18|19|20|21] diff --git a/test/shaping/data/aots/tests/classdef1_empty.tests b/test/shaping/data/aots/tests/classdef1_empty.tests new file mode 100644 index 000000000..71d87f1c3 --- /dev/null +++ b/test/shaping/data/aots/tests/classdef1_empty.tests @@ -0,0 +1 @@ +../fonts/classdef1_font2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|23|24|25|21] diff --git a/test/shaping/data/aots/tests/classdef1_multiple.tests b/test/shaping/data/aots/tests/classdef1_multiple.tests new file mode 100644 index 000000000..c813f4949 --- /dev/null +++ b/test/shaping/data/aots/tests/classdef1_multiple.tests @@ -0,0 +1 @@ +../fonts/classdef1_font3.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+001B,U+001C,U+001D,U+001E,U+001F,U+0020,U+0021,U+0022,U+0023,U+0024:[20|23|24|25|24|26|27|28|28|29|30|31|34|33|34|35|37|38|38|39] diff --git a/test/shaping/data/aots/tests/classdef1_single.tests b/test/shaping/data/aots/tests/classdef1_single.tests new file mode 100644 index 000000000..b0196d3fa --- /dev/null +++ b/test/shaping/data/aots/tests/classdef1_single.tests @@ -0,0 +1 @@ +../fonts/classdef2_font1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|23|24|25|21] diff --git a/test/shaping/data/aots/tests/classdef2.tests b/test/shaping/data/aots/tests/classdef2.tests new file mode 100644 index 000000000..d8c7b1484 --- /dev/null +++ b/test/shaping/data/aots/tests/classdef2.tests @@ -0,0 +1 @@ +../fonts/classdef2_font4.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18|19|20|21] diff --git a/test/shaping/data/aots/tests/classdef2_empty.tests b/test/shaping/data/aots/tests/classdef2_empty.tests new file mode 100644 index 000000000..a8fd62950 --- /dev/null +++ b/test/shaping/data/aots/tests/classdef2_empty.tests @@ -0,0 +1 @@ +../fonts/classdef2_font2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|23|24|25|21] diff --git a/test/shaping/data/aots/tests/classdef2_multiple.tests b/test/shaping/data/aots/tests/classdef2_multiple.tests new file mode 100644 index 000000000..39e68351f --- /dev/null +++ b/test/shaping/data/aots/tests/classdef2_multiple.tests @@ -0,0 +1 @@ +../fonts/classdef2_font3.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+001B,U+001C,U+001D,U+001E,U+001F,U+0020,U+0021,U+0022,U+0023,U+0024:[20|23|24|25|24|26|27|28|28|29|30|31|34|33|34|35|37|38|38|39] diff --git a/test/shaping/data/aots/tests/classdef2_single.tests b/test/shaping/data/aots/tests/classdef2_single.tests new file mode 100644 index 000000000..b0196d3fa --- /dev/null +++ b/test/shaping/data/aots/tests/classdef2_single.tests @@ -0,0 +1 @@ +../fonts/classdef2_font1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|23|24|25|21] diff --git a/test/shaping/data/aots/tests/gpos1_1_lookupflag.tests b/test/shaping/data/aots/tests/gpos1_1_lookupflag.tests new file mode 100644 index 000000000..88d7dd740 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos1_1_lookupflag.tests @@ -0,0 +1 @@ +../fonts/gpos1_1_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18@1500,0|19@3000,0|20@4200,0|21@6000,0] diff --git a/test/shaping/data/aots/tests/gpos1_1_simple.tests b/test/shaping/data/aots/tests/gpos1_1_simple.tests new file mode 100644 index 000000000..101da9c49 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos1_1_simple.tests @@ -0,0 +1,4 @@ +../fonts/gpos1_1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18@1300,0|19@3000,0|20@4300,0|21@6000,0] +../fonts/gpos1_1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18@1500,-200|19@3000,0|20@4500,-200|21@6000,0] +../fonts/gpos1_1_simple_f3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18@1500,0|19@2800,0|20@4300,0|21@5600,0] +#../fonts/gpos1_1_simple_f4.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18@1500,0|19@3000,-200|20@4500,-200|21@6000,-400] diff --git a/test/shaping/data/aots/tests/gpos1_2.tests b/test/shaping/data/aots/tests/gpos1_2.tests new file mode 100644 index 000000000..3ddfa4490 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos1_2.tests @@ -0,0 +1 @@ +../fonts/gpos1_2_font1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18@1300,0|19@3000,0|20@4200,0|21@6000,0] diff --git a/test/shaping/data/aots/tests/gpos1_2_lookupflag.tests b/test/shaping/data/aots/tests/gpos1_2_lookupflag.tests new file mode 100644 index 000000000..82bcc4307 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos1_2_lookupflag.tests @@ -0,0 +1 @@ +../fonts/gpos1_2_font2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18@1500,0|19@3000,0|20@4200,0|21@6000,0] diff --git a/test/shaping/data/aots/tests/gpos2_1.tests b/test/shaping/data/aots/tests/gpos2_1.tests new file mode 100644 index 000000000..4d8b5e968 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos2_1.tests @@ -0,0 +1,2 @@ +../fonts/gpos2_1_font6.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0011,U+0012,U+0014,U+0011:[17|18@1300,0|19@3000,-100|17@4500,0|18@5700,0|20@7500,-400|17@9000,0] +../fonts/gpos2_1_font7.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0011,U+0012,U+0014,U+0011,U+0015,U+0016,U+0011:[17|18@1300,0|19@3000,-100|17@4500,0|18@5700,0|20@7500,-400|17@9000,0|21@10000,0|22@12000,-600|17@13500,0] diff --git a/test/shaping/data/aots/tests/gpos2_1_lookupflag.tests b/test/shaping/data/aots/tests/gpos2_1_lookupflag.tests new file mode 100644 index 000000000..ce445a118 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos2_1_lookupflag.tests @@ -0,0 +1,2 @@ +../fonts/gpos2_1_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0013,U+0014,U+0011,U+0013,U+0012,U+0014,U+0011:[17|19@1300,0|20@3000,-100|17@4500,0|19@5800,0|18@7500,0|20@9000,-100|17@10500,0] +../fonts/gpos2_1_lookupflag_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0013,U+0014,U+0011,U+0013,U+0012,U+0014,U+0011:[17|19@1500,0|20@2800,-100|17@4300,0|19@5800,0|18@7100,0|20@8600,-100|17@10100,0] diff --git a/test/shaping/data/aots/tests/gpos2_1_next_glyph.tests b/test/shaping/data/aots/tests/gpos2_1_next_glyph.tests new file mode 100644 index 000000000..7f27eeed7 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos2_1_next_glyph.tests @@ -0,0 +1,2 @@ +../fonts/gpos2_1_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0012,U+0012,U+0012,U+0012:[18@-100,0|18@1500,-100|18@2900,0|18@4500,-100] +../fonts/gpos2_1_next_glyph_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0012,U+0012,U+0012,U+0012:[18@-100,0|18@1400,0|18@2900,0|18@4500,0] diff --git a/test/shaping/data/aots/tests/gpos2_1_simple.tests b/test/shaping/data/aots/tests/gpos2_1_simple.tests new file mode 100644 index 000000000..71e8c81e5 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos2_1_simple.tests @@ -0,0 +1,2 @@ +../fonts/gpos2_1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0011,U+0012,U+0014:[17|18@1300,0|19@3000,-100|17@4500,0|18@6000,0|20@7500,0] +../fonts/gpos2_1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012:[17|18@1500,0] diff --git a/test/shaping/data/aots/tests/gpos2_2.tests b/test/shaping/data/aots/tests/gpos2_2.tests new file mode 100644 index 000000000..7be07f7d8 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos2_2.tests @@ -0,0 +1,5 @@ +../fonts/gpos2_2_font1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0011,U+0012,U+0014:[17|18@1300,0|19@3000,-100|17@4500,0|18@6000,0|20@7500,0] +../fonts/gpos2_2_font2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0013,U+0014,U+0011,U+0013,U+0012,U+0014,U+0011:[17|19@1300,0|20@3000,-100|17@4500,0|19@5800,0|18@7500,0|20@9000,-100|17@10500,0] +../fonts/gpos2_2_font3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0013,U+0014,U+0011,U+0013,U+0012,U+0014,U+0011:[17|19@1500,0|20@2800,-100|17@4300,0|19@5800,0|18@7100,0|20@8600,-100|17@10100,0] +../fonts/gpos2_2_font4.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0012,U+0012,U+0012,U+0012:[18@-100,0|18@1500,-100|18@2900,0|18@4500,-100] +../fonts/gpos2_2_font5.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0012,U+0012,U+0012,U+0012:[18@-100,0|18@1400,0|18@2900,0|18@4500,0] diff --git a/test/shaping/data/aots/tests/gpos3.tests b/test/shaping/data/aots/tests/gpos3.tests new file mode 100644 index 000000000..d6f37bfff --- /dev/null +++ b/test/shaping/data/aots/tests/gpos3.tests @@ -0,0 +1,11 @@ +#../fonts/gpos3_font1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0011:[17|18@1500,0|19@1599,99|17@4500,0] +../fonts/gpos3_font1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0011,U+0013,U+0011:[17|18@1500,0|17@3000,0|19@4500,0|17@6000,0] +#../fonts/gpos3_font3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0012,U+0011:[17|18@1500,0|18@1600,100|17@4500,0] +#../fonts/gpos3_font3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0011:[17|18@1500,0|19@1599,99|17@4500,0] +#../fonts/gpos3_font3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0014,U+0012,U+0011:[17|20@1500,0|18@1602,102|17@4500,0] +#../fonts/gpos3_font3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0014,U+0013,U+0011:[17|20@1500,0|19@1601,101|17@4500,0] +../fonts/gpos3_font3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0014,U+0011:[17|18@1500,0|20@3000,0|17@4500,0] +../fonts/gpos3_font3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0013,U+0012,U+0011:[17|19@1500,0|18@3000,0|17@4500,0] +../fonts/gpos3_font3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0013,U+0014,U+0011:[17|19@1500,0|20@3000,0|17@4500,0] +../fonts/gpos3_font3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012:[17|18@1500,0] +../fonts/gpos3_font3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0015,U+0015,U+0015:[17|18@1500,0|21@3000,0|21@4500,0|21@6000,0] diff --git a/test/shaping/data/aots/tests/gpos3_lookupflag.tests b/test/shaping/data/aots/tests/gpos3_lookupflag.tests new file mode 100644 index 000000000..13d593ca9 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos3_lookupflag.tests @@ -0,0 +1,2 @@ +#../fonts/gpos3_font2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0015,U+0013,U+0011:[17|18@1500,0|21@3000,0|19@1599,99|17@6000,0] +#../fonts/gpos3_font2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0015,U+0015,U+0015,U+0013,U+0011:[17|18@1500,0|21@3000,0|21@4500,0|21@6000,0|19@1599,99|17@9000,0] diff --git a/test/shaping/data/aots/tests/gpos4_lookupflag.tests b/test/shaping/data/aots/tests/gpos4_lookupflag.tests new file mode 100644 index 000000000..9d041bff2 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos4_lookupflag.tests @@ -0,0 +1,2 @@ +#../fonts/gpos4_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0011,U+0013,U+0011:[17|18@1500,0|17@3000,0|19@4500,0|17@6000,0] +#../fonts/gpos4_lookupflag_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0011:[17|18@1500,0|19@3000,0|17@4500,0] diff --git a/test/shaping/data/aots/tests/gpos4_multiple_anchors.tests b/test/shaping/data/aots/tests/gpos4_multiple_anchors.tests new file mode 100644 index 000000000..af9a1f5fa --- /dev/null +++ b/test/shaping/data/aots/tests/gpos4_multiple_anchors.tests @@ -0,0 +1 @@ +#../fonts/gpos4_multiple_anchors_1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0013,U+0014,U+0015,U+0016,U+0012,U+0013,U+0014,U+0015,U+0016:[17|19@-100,-80|20@-91,-71|21@-102,-82|22@-93,-73|18@7500,0|19@7420,-60|20@7429,-51|21@7418,-62|22@7427,-53] diff --git a/test/shaping/data/aots/tests/gpos4_simple.tests b/test/shaping/data/aots/tests/gpos4_simple.tests new file mode 100644 index 000000000..5d605079d --- /dev/null +++ b/test/shaping/data/aots/tests/gpos4_simple.tests @@ -0,0 +1,5 @@ +#../fonts/gpos4_simple_1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0011:[17|18@1500,0|19@1400,-80|17@4500,0] +#../fonts/gpos4_simple_1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0011,U+0013,U+0011:[17|17@1500,0|19@3000,0|17@4500,0] +#../fonts/gpos4_simple_1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0019,U+0019,U+0013,U+0011:[25|25@1500,0|19@3000,0|17@4500,0] +#../fonts/gpos4_simple_1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0013,U+0011:[17|18@1500,0|19@1400,-80|19@1400,-80|17@6000,0] +#../fonts/gpos4_simple_1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0014,U+0013,U+0011:[17|18@1500,0|20@3000,0|19@1400,-80|17@6000,0] diff --git a/test/shaping/data/aots/tests/gpos5.tests b/test/shaping/data/aots/tests/gpos5.tests new file mode 100644 index 000000000..a20a0b9ea --- /dev/null +++ b/test/shaping/data/aots/tests/gpos5.tests @@ -0,0 +1,2 @@ +#../fonts/gpos5_font1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+001E,U+0013,U+001F,U+0011:[17|18@1500,0|19@1400,-80|17@4500,0] +#../fonts/gpos5_font1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+001E,U+001F,U+0013,U+0011:[17|18@1500,0|19@1401,-79|17@4500,0] diff --git a/test/shaping/data/aots/tests/gpos6.tests b/test/shaping/data/aots/tests/gpos6.tests new file mode 100644 index 000000000..e5f9b3cd5 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos6.tests @@ -0,0 +1,3 @@ +#../fonts/gpos6_font1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0011:[17|18@1500,0|19@1400,-80|17@4500,0] +#../fonts/gpos6_font1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0011,U+0013,U+0011:[17|17@1500,0|19@3000,0|17@4500,0] +#../fonts/gpos6_font1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0014,U+0014,U+0013,U+0011:[20|20@1500,0|19@3000,0|17@4500,0] diff --git a/test/shaping/data/aots/tests/gpos7_1.tests b/test/shaping/data/aots/tests/gpos7_1.tests new file mode 100644 index 000000000..954c8cbc6 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos7_1.tests @@ -0,0 +1,2 @@ +../fonts/gpos7_1_font1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18@1600,0|19@3200,0|20@4800,0|21@6000,0] +../fonts/gpos7_1_font1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0011,U+0012,U+0013,U+0011:[17|18@1500,0|17@3000,0|18@4500,0|19@6000,0|17@7500,0] diff --git a/test/shaping/data/aots/tests/gpos9.tests b/test/shaping/data/aots/tests/gpos9.tests new file mode 100644 index 000000000..cb2033308 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos9.tests @@ -0,0 +1,2 @@ +../fonts/gpos9_font1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18@1300,0|19@3000,0|20@4300,0|21@6000,0] +../fonts/gpos9_font2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0011,U+0012,U+0013,U+0014,U+0015,U+0011:[17|18@1300,0|19@2700,0|20@4300,0|21@5700,0|17@7500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining1_boundary.tests b/test/shaping/data/aots/tests/gpos_chaining1_boundary.tests new file mode 100644 index 000000000..646ff2cf9 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining1_boundary.tests @@ -0,0 +1,4 @@ +../fonts/gpos_chaining1_boundary_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0|0@7500,0] +../fonts/gpos_chaining1_boundary_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4500,0|23@6000,0|0@7500,0] +../fonts/gpos_chaining1_boundary_f3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4500,0|23@6000,0|0@7500,0] +../fonts/gpos_chaining1_boundary_f4.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3000,0|22@4520,0|23@6000,0|0@7500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining1_lookupflag.tests b/test/shaping/data/aots/tests/gpos_chaining1_lookupflag.tests new file mode 100644 index 000000000..d0e6e2e0a --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining1_lookupflag.tests @@ -0,0 +1 @@ +#../fonts/gpos_chaining1_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+005A,U+0015,U+005B,U+0016,U+005C,U+0017,U+005D,U+005E,U+0018,U+005A,U+0019,U+005B,U+001A,U+0000:[0|20@1500,0|90@3000,0|21@4500,0|91@6000,0|22@7500,0|92@9000,0|23@10520,0|93@12000,0|94@13500,0|24@15000,0|90@16500,0|25@18000,0|91@19500,0|26@21000,0|0@22500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining1_multiple_subrules.tests b/test/shaping/data/aots/tests/gpos_chaining1_multiple_subrules.tests new file mode 100644 index 000000000..51bbe03be --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining1_multiple_subrules.tests @@ -0,0 +1,2 @@ +../fonts/gpos_chaining1_multiple_subrules_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4500,0|23@6000,0|24@7500,0|0@9000,0|20@10500,0|21@12000,0|22@13520,0|23@15000,0|0@16500,0] +../fonts/gpos_chaining1_multiple_subrules_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3000,0|22@4520,0|23@6000,0|24@7500,0|0@9000,0|20@10500,0|21@12000,0|22@13520,0|23@15000,0|0@16500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining1_next_glyph.tests b/test/shaping/data/aots/tests/gpos_chaining1_next_glyph.tests new file mode 100644 index 000000000..f8be40456 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining1_next_glyph.tests @@ -0,0 +1 @@ +../fonts/gpos_chaining1_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4520,0|23@6020,0|0@7500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining1_simple.tests b/test/shaping/data/aots/tests/gpos_chaining1_simple.tests new file mode 100644 index 000000000..37efa11fd --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining1_simple.tests @@ -0,0 +1,11 @@ +../fonts/gpos_chaining1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4520,0|23@6000,0|0@7500,0] +../fonts/gpos_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[0|20@1500,0|21@3000,0|22@4520,0|23@6000,0|24@7500,0|25@9000,0|26@10500,0|0@12000,0] +../fonts/gpos_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+0000,U+0000:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0|24@7500,0|25@9000,0|0@10500,0|0@12000,0] +../fonts/gpos_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0|24@7500,0|25@9000,0] +../fonts/gpos_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0|24@7500,0] +../fonts/gpos_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0000,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[0|0@1500,0|21@3000,0|22@4500,0|23@6000,0|24@7500,0|25@9000,0|26@10500,0|0@12000,0] +../fonts/gpos_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[21|22@1500,0|23@3000,0|24@4500,0|25@6000,0|26@7500,0|0@9000,0] +../fonts/gpos_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[22|23@1500,0|24@3000,0|25@4500,0|26@6000,0|0@7500,0] +../fonts/gpos_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0000,U+0018,U+0019,U+001A,U+0000:[0|20@1500,0|21@3000,0|22@4500,0|0@6000,0|24@7500,0|25@9000,0|26@10500,0|0@12000,0] +../fonts/gpos_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0] +../fonts/gpos_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016:[0|20@1500,0|21@3000,0|22@4500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining1_successive.tests b/test/shaping/data/aots/tests/gpos_chaining1_successive.tests new file mode 100644 index 000000000..7a829cf72 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining1_successive.tests @@ -0,0 +1 @@ +../fonts/gpos_chaining1_successive_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0019,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000:[0|25@1500,0|20@3000,0|21@4520,0|22@6020,0|23@7500,0|24@9000,0|0@10500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining2_boundary.tests b/test/shaping/data/aots/tests/gpos_chaining2_boundary.tests new file mode 100644 index 000000000..c35b8c776 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining2_boundary.tests @@ -0,0 +1,4 @@ +../fonts/gpos_chaining2_boundary_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0|0@7500,0] +../fonts/gpos_chaining2_boundary_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4500,0|23@6000,0|0@7500,0] +../fonts/gpos_chaining2_boundary_f3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4500,0|23@6000,0|0@7500,0] +../fonts/gpos_chaining2_boundary_f4.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3000,0|22@4520,0|23@6000,0|0@7500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining2_lookupflag.tests b/test/shaping/data/aots/tests/gpos_chaining2_lookupflag.tests new file mode 100644 index 000000000..8b50e1499 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining2_lookupflag.tests @@ -0,0 +1 @@ +#../fonts/gpos_chaining2_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+005A,U+0015,U+005B,U+0016,U+005C,U+0017,U+005D,U+005E,U+0018,U+005A,U+0019,U+005B,U+001A,U+0000:[0|20@1500,0|90@3000,0|21@4500,0|91@6000,0|22@7500,0|92@9000,0|23@10520,0|93@12000,0|94@13500,0|24@15000,0|90@16500,0|25@18000,0|91@19500,0|26@21000,0|0@22500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining2_multiple_subrules.tests b/test/shaping/data/aots/tests/gpos_chaining2_multiple_subrules.tests new file mode 100644 index 000000000..8ddc8b223 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining2_multiple_subrules.tests @@ -0,0 +1,2 @@ +../fonts/gpos_chaining2_multiple_subrules_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4500,0|23@6000,0|24@7500,0|0@9000,0|20@10500,0|21@12000,0|22@13520,0|23@15000,0|0@16500,0] +../fonts/gpos_chaining2_multiple_subrules_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3000,0|22@4520,0|23@6000,0|24@7500,0|0@9000,0|20@10500,0|21@12000,0|22@13520,0|23@15000,0|0@16500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining2_next_glyph.tests b/test/shaping/data/aots/tests/gpos_chaining2_next_glyph.tests new file mode 100644 index 000000000..34170f218 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining2_next_glyph.tests @@ -0,0 +1 @@ +../fonts/gpos_chaining2_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4520,0|23@6020,0|0@7500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining2_simple.tests b/test/shaping/data/aots/tests/gpos_chaining2_simple.tests new file mode 100644 index 000000000..32fda1b5d --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining2_simple.tests @@ -0,0 +1,11 @@ +../fonts/gpos_chaining2_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4520,0|23@6000,0|0@7500,0] +../fonts/gpos_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[0|20@1500,0|21@3000,0|22@4520,0|23@6000,0|24@7500,0|25@9000,0|26@10500,0|0@12000,0] +../fonts/gpos_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+0000,U+0000:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0|24@7500,0|25@9000,0|0@10500,0|0@12000,0] +../fonts/gpos_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0|24@7500,0|25@9000,0] +../fonts/gpos_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0|24@7500,0] +../fonts/gpos_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0000,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[0|0@1500,0|21@3000,0|22@4500,0|23@6000,0|24@7500,0|25@9000,0|26@10500,0|0@12000,0] +../fonts/gpos_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[21|22@1500,0|23@3000,0|24@4500,0|25@6000,0|26@7500,0|0@9000,0] +../fonts/gpos_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[22|23@1500,0|24@3000,0|25@4500,0|26@6000,0|0@7500,0] +../fonts/gpos_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0000,U+0018,U+0019,U+001A,U+0000:[0|20@1500,0|21@3000,0|22@4500,0|0@6000,0|24@7500,0|25@9000,0|26@10500,0|0@12000,0] +../fonts/gpos_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0] +../fonts/gpos_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016:[0|20@1500,0|21@3000,0|22@4500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining2_successive.tests b/test/shaping/data/aots/tests/gpos_chaining2_successive.tests new file mode 100644 index 000000000..e930863c4 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining2_successive.tests @@ -0,0 +1 @@ +../fonts/gpos_chaining2_successive_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0019,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000:[0|25@1500,0|20@3000,0|21@4520,0|22@6020,0|23@7500,0|24@9000,0|0@10500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining3_boundary.tests b/test/shaping/data/aots/tests/gpos_chaining3_boundary.tests new file mode 100644 index 000000000..f74dedf6b --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining3_boundary.tests @@ -0,0 +1,4 @@ +../fonts/gpos_chaining3_boundary_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0|0@7500,0] +../fonts/gpos_chaining3_boundary_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4500,0|23@6000,0|0@7500,0] +../fonts/gpos_chaining3_boundary_f3.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4500,0|23@6000,0|0@7500,0] +../fonts/gpos_chaining3_boundary_f4.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3000,0|22@4520,0|23@6000,0|0@7500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining3_lookupflag.tests b/test/shaping/data/aots/tests/gpos_chaining3_lookupflag.tests new file mode 100644 index 000000000..0165fb590 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining3_lookupflag.tests @@ -0,0 +1 @@ +#../fonts/gpos_chaining3_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+005A,U+0015,U+005B,U+0016,U+005C,U+0017,U+005D,U+005E,U+0018,U+005A,U+0019,U+005B,U+001A,U+0000:[0|20@1500,0|90@3000,0|21@4500,0|91@6000,0|22@7500,0|92@9000,0|23@10520,0|93@12000,0|94@13500,0|24@15000,0|90@16500,0|25@18000,0|91@19500,0|26@21000,0|0@22500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining3_next_glyph.tests b/test/shaping/data/aots/tests/gpos_chaining3_next_glyph.tests new file mode 100644 index 000000000..614bc2eac --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining3_next_glyph.tests @@ -0,0 +1 @@ +../fonts/gpos_chaining3_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0016,U+0015,U+0016,U+0015,U+0016,U+0015,U+0000:[0|22@1500,0|21@3020,0|22@4500,0|21@6020,0|22@7500,0|21@9000,0|0@10500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining3_simple.tests b/test/shaping/data/aots/tests/gpos_chaining3_simple.tests new file mode 100644 index 000000000..f5977c23d --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining3_simple.tests @@ -0,0 +1,11 @@ +../fonts/gpos_chaining3_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4520,0|23@6000,0|0@7500,0] +../fonts/gpos_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[0|20@1500,0|21@3000,0|22@4520,0|23@6000,0|24@7500,0|25@9000,0|26@10500,0|0@12000,0] +../fonts/gpos_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+0000,U+0000:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0|24@7500,0|25@9000,0|0@10500,0|0@12000,0] +../fonts/gpos_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0|24@7500,0|25@9000,0] +../fonts/gpos_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0|24@7500,0] +../fonts/gpos_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0000,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[0|0@1500,0|21@3000,0|22@4500,0|23@6000,0|24@7500,0|25@9000,0|26@10500,0|0@12000,0] +../fonts/gpos_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[21|22@1500,0|23@3000,0|24@4500,0|25@6000,0|26@7500,0|0@9000,0] +../fonts/gpos_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[22|23@1500,0|24@3000,0|25@4500,0|26@6000,0|0@7500,0] +../fonts/gpos_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0000,U+0018,U+0019,U+001A,U+0000:[0|20@1500,0|21@3000,0|22@4500,0|0@6000,0|24@7500,0|25@9000,0|26@10500,0|0@12000,0] +../fonts/gpos_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017:[0|20@1500,0|21@3000,0|22@4500,0|23@6000,0] +../fonts/gpos_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016:[0|20@1500,0|21@3000,0|22@4500,0] diff --git a/test/shaping/data/aots/tests/gpos_chaining3_successive.tests b/test/shaping/data/aots/tests/gpos_chaining3_successive.tests new file mode 100644 index 000000000..fa5a50ca2 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_chaining3_successive.tests @@ -0,0 +1 @@ +../fonts/gpos_chaining3_successive_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0019,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000:[0|25@1500,0|20@3000,0|21@4520,0|22@6020,0|23@7500,0|24@9000,0|0@10500,0] diff --git a/test/shaping/data/aots/tests/gpos_context1_boundary.tests b/test/shaping/data/aots/tests/gpos_context1_boundary.tests new file mode 100644 index 000000000..1db8fef33 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context1_boundary.tests @@ -0,0 +1,2 @@ +../fonts/gpos_context1_boundary_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20@1500,0|20@3000,0|20@4500,0|20@6000,0|20@7500,0|0@9000,0] +../fonts/gpos_context1_boundary_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20@1520,0|20@3020,0|20@4520,0|20@6020,0|20@7520,0|0@9000,0] diff --git a/test/shaping/data/aots/tests/gpos_context1_expansion.tests b/test/shaping/data/aots/tests/gpos_context1_expansion.tests new file mode 100644 index 000000000..2fc54d54b --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context1_expansion.tests @@ -0,0 +1 @@ +../fonts/gpos_context1_expansion_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0000:[0|20@1500,0|21@3000,0|22@4500,0|0@6000,0] diff --git a/test/shaping/data/aots/tests/gpos_context1_lookupflag.tests b/test/shaping/data/aots/tests/gpos_context1_lookupflag.tests new file mode 100644 index 000000000..9e8fcd6e4 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context1_lookupflag.tests @@ -0,0 +1,2 @@ +#../fonts/gpos_context1_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+005A,U+0015,U+005B,U+005C,U+0016,U+0000:[0|20@1520,0|90@3000,0|21@4520,0|91@6000,0|92@7500,0|22@9020,0|0@10500,0] +#../fonts/gpos_context1_lookupflag_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+005A,U+0015,U+005B,U+005C,U+0016,U+0000:[0|20@1500,0|90@3000,0|21@4520,0|91@6000,0|92@7500,0|22@9000,0|0@10500,0] diff --git a/test/shaping/data/aots/tests/gpos_context1_multiple_subrules.tests b/test/shaping/data/aots/tests/gpos_context1_multiple_subrules.tests new file mode 100644 index 000000000..b994f04e2 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context1_multiple_subrules.tests @@ -0,0 +1,2 @@ +../fonts/gpos_context1_multiple_subrules_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0000,U+0014,U+0015,U+0000:[0|20@1520,0|21@3000,0|22@4500,0|0@6000,0|20@7500,0|21@9020,0|0@10500,0] +../fonts/gpos_context1_multiple_subrules_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0000,U+0014,U+0015,U+0000:[0|20@1500,0|21@3020,0|22@4500,0|0@6000,0|20@7500,0|21@9020,0|0@10500,0] diff --git a/test/shaping/data/aots/tests/gpos_context1_next_glyph.tests b/test/shaping/data/aots/tests/gpos_context1_next_glyph.tests new file mode 100644 index 000000000..e67d63583 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context1_next_glyph.tests @@ -0,0 +1 @@ +../fonts/gpos_context1_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20@1520,0|20@3000,0|20@4520,0|20@6000,0|20@7500,0|0@9000,0] diff --git a/test/shaping/data/aots/tests/gpos_context1_simple.tests b/test/shaping/data/aots/tests/gpos_context1_simple.tests new file mode 100644 index 000000000..4a88e0ada --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context1_simple.tests @@ -0,0 +1,3 @@ +../fonts/gpos_context1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0000:[0|20@1520,0|21@3020,0|22@4520,0|0@6000,0] +../fonts/gpos_context1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0000,U+0014,U+0015,U+0000:[0|20@1500,0|0@3000,0|20@4500,0|21@6000,0|0@7500,0] +../fonts/gpos_context1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20@1500,0|20@3020,0|20@4500,0|20@6000,0|20@7500,0|0@9000,0] diff --git a/test/shaping/data/aots/tests/gpos_context1_successive.tests b/test/shaping/data/aots/tests/gpos_context1_successive.tests new file mode 100644 index 000000000..172d35040 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context1_successive.tests @@ -0,0 +1 @@ +../fonts/gpos_context1_successive_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4520,0|23@6000,0|0@7500,0] diff --git a/test/shaping/data/aots/tests/gpos_context2_boundary.tests b/test/shaping/data/aots/tests/gpos_context2_boundary.tests new file mode 100644 index 000000000..ef63fbbbb --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context2_boundary.tests @@ -0,0 +1,2 @@ +../fonts/gpos_context2_boundary_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20@1500,0|20@3000,0|20@4500,0|20@6000,0|20@7500,0|0@9000,0] +../fonts/gpos_context2_boundary_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20@1520,0|20@3020,0|20@4520,0|20@6020,0|20@7520,0|0@9000,0] diff --git a/test/shaping/data/aots/tests/gpos_context2_classes.tests b/test/shaping/data/aots/tests/gpos_context2_classes.tests new file mode 100644 index 000000000..5a3d008a8 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context2_classes.tests @@ -0,0 +1,2 @@ +../fonts/gpos_context2_classes_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+001A,U+001C,U+0018,U+0000,U+0015,U+001B,U+001A,U+0018,U+0000,U+0016,U+001B,U+001A,U+0018:[0|20@1500,0|26@3020,0|28@4500,0|24@6000,0|0@7500,0|21@9000,0|27@10520,0|26@12000,0|24@13500,0|0@15000,0|22@16500,0|27@18000,0|26@19500,0|24@21000,0] +../fonts/gpos_context2_classes_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0016,U+001B,U+001A,U+0018,U+0000,U+0018,U+0018,U+001D,U+0016,U+0000,U+0016,U+001B,U+001A,U+0018:[0|22@1500,0|27@3020,0|26@4500,0|24@6000,0|0@7500,0|24@9000,0|24@10500,0|29@12020,0|22@13500,0|0@15000,0|22@16500,0|27@18020,0|26@19500,0|24@21000,0] diff --git a/test/shaping/data/aots/tests/gpos_context2_expansion.tests b/test/shaping/data/aots/tests/gpos_context2_expansion.tests new file mode 100644 index 000000000..67ed9786e --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context2_expansion.tests @@ -0,0 +1 @@ +../fonts/gpos_context2_expansion_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0000:[0|20@1500,0|21@3000,0|22@4500,0|0@6000,0] diff --git a/test/shaping/data/aots/tests/gpos_context2_lookupflag.tests b/test/shaping/data/aots/tests/gpos_context2_lookupflag.tests new file mode 100644 index 000000000..f48e82502 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context2_lookupflag.tests @@ -0,0 +1,2 @@ +#../fonts/gpos_context2_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+005A,U+0015,U+005B,U+005C,U+0016,U+0000:[0|20@1520,0|90@3000,0|21@4520,0|91@6000,0|92@7500,0|22@9020,0|0@10500,0] +#../fonts/gpos_context2_lookupflag_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+005A,U+0015,U+005B,U+005C,U+0016,U+0000:[0|20@1500,0|90@3000,0|21@4520,0|91@6000,0|92@7500,0|22@9000,0|0@10500,0] diff --git a/test/shaping/data/aots/tests/gpos_context2_multiple_subrules.tests b/test/shaping/data/aots/tests/gpos_context2_multiple_subrules.tests new file mode 100644 index 000000000..44893723d --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context2_multiple_subrules.tests @@ -0,0 +1,2 @@ +../fonts/gpos_context2_multiple_subrules_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0000,U+0014,U+0015,U+0000:[0|20@1520,0|21@3000,0|22@4500,0|0@6000,0|20@7500,0|21@9020,0|0@10500,0] +../fonts/gpos_context2_multiple_subrules_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0000,U+0014,U+0015,U+0000:[0|20@1500,0|21@3020,0|22@4500,0|0@6000,0|20@7500,0|21@9020,0|0@10500,0] diff --git a/test/shaping/data/aots/tests/gpos_context2_next_glyph.tests b/test/shaping/data/aots/tests/gpos_context2_next_glyph.tests new file mode 100644 index 000000000..e736b3bd6 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context2_next_glyph.tests @@ -0,0 +1 @@ +../fonts/gpos_context2_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20@1520,0|20@3000,0|20@4520,0|20@6000,0|20@7500,0|0@9000,0] diff --git a/test/shaping/data/aots/tests/gpos_context2_simple.tests b/test/shaping/data/aots/tests/gpos_context2_simple.tests new file mode 100644 index 000000000..edbc0be33 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context2_simple.tests @@ -0,0 +1,3 @@ +../fonts/gpos_context2_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0000:[0|20@1520,0|21@3020,0|22@4520,0|0@6000,0] +../fonts/gpos_context2_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0000,U+0014,U+0015,U+0000:[0|20@1500,0|0@3000,0|20@4500,0|21@6000,0|0@7500,0] +../fonts/gpos_context2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20@1500,0|20@3020,0|20@4500,0|20@6000,0|20@7500,0|0@9000,0] diff --git a/test/shaping/data/aots/tests/gpos_context2_successive.tests b/test/shaping/data/aots/tests/gpos_context2_successive.tests new file mode 100644 index 000000000..8b098d59d --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context2_successive.tests @@ -0,0 +1 @@ +../fonts/gpos_context2_successive_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4520,0|23@6000,0|0@7500,0] diff --git a/test/shaping/data/aots/tests/gpos_context3_boundary.tests b/test/shaping/data/aots/tests/gpos_context3_boundary.tests new file mode 100644 index 000000000..de3c05740 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context3_boundary.tests @@ -0,0 +1,2 @@ +../fonts/gpos_context3_boundary_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20@1500,0|20@3000,0|20@4500,0|20@6000,0|20@7500,0|0@9000,0] +../fonts/gpos_context3_boundary_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20@1520,0|20@3020,0|20@4520,0|20@6020,0|20@7520,0|0@9000,0] diff --git a/test/shaping/data/aots/tests/gpos_context3_lookupflag.tests b/test/shaping/data/aots/tests/gpos_context3_lookupflag.tests new file mode 100644 index 000000000..21f851b97 --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context3_lookupflag.tests @@ -0,0 +1,2 @@ +#../fonts/gpos_context3_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+005A,U+0015,U+005B,U+005C,U+0016,U+0000:[0|20@1520,0|90@3000,0|21@4520,0|91@6000,0|92@7500,0|22@9020,0|0@10500,0] +#../fonts/gpos_context3_lookupflag_f2.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+005A,U+0015,U+005B,U+005C,U+0016,U+0000:[0|20@1500,0|90@3000,0|21@4520,0|91@6000,0|92@7500,0|22@9000,0|0@10500,0] diff --git a/test/shaping/data/aots/tests/gpos_context3_next_glyph.tests b/test/shaping/data/aots/tests/gpos_context3_next_glyph.tests new file mode 100644 index 000000000..049b156aa --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context3_next_glyph.tests @@ -0,0 +1 @@ +../fonts/gpos_context3_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20@1520,0|20@3000,0|20@4520,0|20@6000,0|20@7500,0|0@9000,0] diff --git a/test/shaping/data/aots/tests/gpos_context3_simple.tests b/test/shaping/data/aots/tests/gpos_context3_simple.tests new file mode 100644 index 000000000..3e544f04e --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context3_simple.tests @@ -0,0 +1,2 @@ +../fonts/gpos_context3_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0000:[0|20@1520,0|21@3020,0|22@4520,0|0@6000,0] +../fonts/gpos_context3_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0000,U+0014,U+0015,U+0000,U+0014,U+0015,U+0016,U+0000:[0|20@1500,0|0@3000,0|20@4500,0|21@6000,0|0@7500,0|20@9020,0|21@10520,0|22@12020,0|0@13500,0] diff --git a/test/shaping/data/aots/tests/gpos_context3_successive.tests b/test/shaping/data/aots/tests/gpos_context3_successive.tests new file mode 100644 index 000000000..bfcf24acb --- /dev/null +++ b/test/shaping/data/aots/tests/gpos_context3_successive.tests @@ -0,0 +1 @@ +../fonts/gpos_context3_successive_f1.otf:--features="test" --no-clusters --no-glyph-names --ned:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20@1500,0|21@3020,0|22@4520,0|23@6000,0|0@7500,0] diff --git a/test/shaping/data/aots/tests/gsub1_1_lookupflag.tests b/test/shaping/data/aots/tests/gsub1_1_lookupflag.tests new file mode 100644 index 000000000..8865af8c7 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub1_1_lookupflag.tests @@ -0,0 +1 @@ +../fonts/gsub1_1_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18|24|20|21] diff --git a/test/shaping/data/aots/tests/gsub1_1_modulo.tests b/test/shaping/data/aots/tests/gsub1_1_modulo.tests new file mode 100644 index 000000000..bbfff5ee2 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub1_1_modulo.tests @@ -0,0 +1 @@ +../fonts/gsub1_1_modulo_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015,U+0016,U+0017,U+0018:[17|18|17|24|23|18|23|24] diff --git a/test/shaping/data/aots/tests/gsub1_1_simple.tests b/test/shaping/data/aots/tests/gsub1_1_simple.tests new file mode 100644 index 000000000..a3a13859c --- /dev/null +++ b/test/shaping/data/aots/tests/gsub1_1_simple.tests @@ -0,0 +1 @@ +../fonts/gsub1_1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|23|24|20|21] diff --git a/test/shaping/data/aots/tests/gsub1_2_lookupflag.tests b/test/shaping/data/aots/tests/gsub1_2_lookupflag.tests new file mode 100644 index 000000000..887e0479e --- /dev/null +++ b/test/shaping/data/aots/tests/gsub1_2_lookupflag.tests @@ -0,0 +1 @@ +../fonts/gsub1_2_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|18|19|25|21] diff --git a/test/shaping/data/aots/tests/gsub1_2_simple.tests b/test/shaping/data/aots/tests/gsub1_2_simple.tests new file mode 100644 index 000000000..d65789738 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub1_2_simple.tests @@ -0,0 +1 @@ +../fonts/gsub1_2_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|22|19|25|21] diff --git a/test/shaping/data/aots/tests/gsub2_1_lookupflag.tests b/test/shaping/data/aots/tests/gsub2_1_lookupflag.tests new file mode 100644 index 000000000..e28e59cde --- /dev/null +++ b/test/shaping/data/aots/tests/gsub2_1_lookupflag.tests @@ -0,0 +1 @@ +../fonts/gsub2_1_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0011:[17|18|22|23|17] diff --git a/test/shaping/data/aots/tests/gsub2_1_multiple_sequences.tests b/test/shaping/data/aots/tests/gsub2_1_multiple_sequences.tests new file mode 100644 index 000000000..12cbbf606 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub2_1_multiple_sequences.tests @@ -0,0 +1 @@ +../fonts/gsub2_1_multiple_sequences_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0011:[17|20|21|22|23|17] diff --git a/test/shaping/data/aots/tests/gsub2_1_simple.tests b/test/shaping/data/aots/tests/gsub2_1_simple.tests new file mode 100644 index 000000000..d1d09690b --- /dev/null +++ b/test/shaping/data/aots/tests/gsub2_1_simple.tests @@ -0,0 +1,2 @@ +../fonts/gsub2_1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013:[17|20|21|22|19] +../fonts/gsub2_1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0012:[17|20|21|22|19|20|21|22] diff --git a/test/shaping/data/aots/tests/gsub3_1_lookupflag.tests b/test/shaping/data/aots/tests/gsub3_1_lookupflag.tests new file mode 100644 index 000000000..193c5c4a0 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub3_1_lookupflag.tests @@ -0,0 +1 @@ +../fonts/gsub3_1_lookupflag_f1.otf:--features="-test[4],test[5],test[6]=2,-test[7]" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0012,U+0012,U+0013,U+0013,U+0013,U+0013,U+0011:[17|18|18|18|19|22|23|19|17] diff --git a/test/shaping/data/aots/tests/gsub3_1_multiple.tests b/test/shaping/data/aots/tests/gsub3_1_multiple.tests new file mode 100644 index 000000000..7b1c032e1 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub3_1_multiple.tests @@ -0,0 +1 @@ +../fonts/gsub3_1_multiple_f1.otf:--features="-test[1],test[2],test[3]=2,-test[4],-test[5],test[6],test[7]=2,-test[8]" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0012,U+0012,U+0012,U+0013,U+0013,U+0013,U+0013,U+0011:[17|18|20|21|18|19|22|23|19|17] diff --git a/test/shaping/data/aots/tests/gsub3_1_simple.tests b/test/shaping/data/aots/tests/gsub3_1_simple.tests new file mode 100644 index 000000000..b8a28d15a --- /dev/null +++ b/test/shaping/data/aots/tests/gsub3_1_simple.tests @@ -0,0 +1 @@ +#../fonts/gsub3_1_simple_f1.otf:--features="-test[1],test[3],test[5]=2,test[7]=3,-test[9],test[11]" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0011,U+0012,U+0011,U+0012,U+0011,U+0012,U+0011,U+0012,U+0011,U+0012,U+0011:[17|18|17|20|17|21|17|22|17|18|17|20|17] diff --git a/test/shaping/data/aots/tests/gsub4_1_lookupflag.tests b/test/shaping/data/aots/tests/gsub4_1_lookupflag.tests new file mode 100644 index 000000000..c2c5242a4 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub4_1_lookupflag.tests @@ -0,0 +1 @@ +../fonts/gsub4_1_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0018,U+0012,U+0018,U+0013,U+0018,U+0018,U+0014,U+0018,U+0011,U+0012,U+0013,U+0016,U+0014:[17|24|23|24|24|24|24|17|18|19|22|20] diff --git a/test/shaping/data/aots/tests/gsub4_1_multiple_ligatures.tests b/test/shaping/data/aots/tests/gsub4_1_multiple_ligatures.tests new file mode 100644 index 000000000..33c1a09f9 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub4_1_multiple_ligatures.tests @@ -0,0 +1,2 @@ +../fonts/gsub4_1_multiple_ligatures_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0011,U+0012,U+0013,U+0016,U+0014:[17|23|17|24|22|20] +../fonts/gsub4_1_multiple_ligatures_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0011,U+0012,U+0013,U+0016,U+0014:[17|24|20|17|24|22|20] diff --git a/test/shaping/data/aots/tests/gsub4_1_multiple_ligsets.tests b/test/shaping/data/aots/tests/gsub4_1_multiple_ligsets.tests new file mode 100644 index 000000000..a63aeed42 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub4_1_multiple_ligsets.tests @@ -0,0 +1 @@ +../fonts/gsub4_1_multiple_ligsets_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0015,U+0014,U+0013,U+0016:[17|23|21|24|22] diff --git a/test/shaping/data/aots/tests/gsub4_1_simple.tests b/test/shaping/data/aots/tests/gsub4_1_simple.tests new file mode 100644 index 000000000..aa4bb4b2e --- /dev/null +++ b/test/shaping/data/aots/tests/gsub4_1_simple.tests @@ -0,0 +1 @@ +../fonts/gsub4_1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0011,U+0012,U+0013,U+0016,U+0014:[17|23|17|18|19|22|20] diff --git a/test/shaping/data/aots/tests/gsub7.tests b/test/shaping/data/aots/tests/gsub7.tests new file mode 100644 index 000000000..e95b1c784 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub7.tests @@ -0,0 +1,2 @@ +../fonts/gsub7_font1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|23|24|20|21] +../fonts/gsub7_font2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|23|29|20|21] diff --git a/test/shaping/data/aots/tests/gsub_chaining1_boundary.tests b/test/shaping/data/aots/tests/gsub_chaining1_boundary.tests new file mode 100644 index 000000000..6d99d9747 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining1_boundary.tests @@ -0,0 +1,4 @@ +../fonts/gsub_chaining1_boundary_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|21|22|23|0] +../fonts/gsub_chaining1_boundary_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|22|23|0] +../fonts/gsub_chaining1_boundary_f3.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|22|23|0] +../fonts/gsub_chaining1_boundary_f4.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|21|62|23|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining1_lookupflag.tests b/test/shaping/data/aots/tests/gsub_chaining1_lookupflag.tests new file mode 100644 index 000000000..7883c0a89 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining1_lookupflag.tests @@ -0,0 +1 @@ +../fonts/gsub_chaining1_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+005A,U+0015,U+005B,U+0016,U+005C,U+0017,U+005D,U+005E,U+0018,U+005A,U+0019,U+005B,U+001A,U+0000:[0|20|90|21|91|22|92|63|93|94|24|90|25|91|26|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining1_multiple_subrules.tests b/test/shaping/data/aots/tests/gsub_chaining1_multiple_subrules.tests new file mode 100644 index 000000000..28a52250a --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining1_multiple_subrules.tests @@ -0,0 +1,2 @@ +../fonts/gsub_chaining1_multiple_subrules_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|22|23|24|0|20|21|62|23|0] +../fonts/gsub_chaining1_multiple_subrules_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|21|62|23|24|0|20|21|62|23|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining1_next_glyph.tests b/test/shaping/data/aots/tests/gsub_chaining1_next_glyph.tests new file mode 100644 index 000000000..82f9d95c0 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining1_next_glyph.tests @@ -0,0 +1 @@ +../fonts/gsub_chaining1_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|62|63|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining1_simple.tests b/test/shaping/data/aots/tests/gsub_chaining1_simple.tests new file mode 100644 index 000000000..23e091f2a --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining1_simple.tests @@ -0,0 +1,11 @@ +../fonts/gsub_chaining1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|62|23|0] +../fonts/gsub_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[0|20|21|62|23|24|25|26|0] +../fonts/gsub_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+0000,U+0000:[0|20|21|22|23|24|25|0|0] +../fonts/gsub_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019:[0|20|21|22|23|24|25] +../fonts/gsub_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018:[0|20|21|22|23|24] +../fonts/gsub_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0000,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[0|0|21|22|23|24|25|26|0] +../fonts/gsub_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[21|22|23|24|25|26|0] +../fonts/gsub_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[22|23|24|25|26|0] +../fonts/gsub_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0000,U+0018,U+0019,U+001A,U+0000:[0|20|21|22|0|24|25|26|0] +../fonts/gsub_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017:[0|20|21|22|23] +../fonts/gsub_chaining1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016:[0|20|21|22] diff --git a/test/shaping/data/aots/tests/gsub_chaining1_successive.tests b/test/shaping/data/aots/tests/gsub_chaining1_successive.tests new file mode 100644 index 000000000..ab3cfb1b2 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining1_successive.tests @@ -0,0 +1 @@ +../fonts/gsub_chaining1_successive_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0019,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000:[0|25|20|61|63|24|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining2_boundary.tests b/test/shaping/data/aots/tests/gsub_chaining2_boundary.tests new file mode 100644 index 000000000..b06c620ca --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining2_boundary.tests @@ -0,0 +1,4 @@ +../fonts/gsub_chaining2_boundary_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|21|22|23|0] +../fonts/gsub_chaining2_boundary_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|22|23|0] +../fonts/gsub_chaining2_boundary_f3.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|22|23|0] +../fonts/gsub_chaining2_boundary_f4.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|21|62|23|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining2_lookupflag.tests b/test/shaping/data/aots/tests/gsub_chaining2_lookupflag.tests new file mode 100644 index 000000000..372b3436e --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining2_lookupflag.tests @@ -0,0 +1 @@ +../fonts/gsub_chaining2_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+005A,U+0015,U+005B,U+0016,U+005C,U+0017,U+005D,U+005E,U+0018,U+005A,U+0019,U+005B,U+001A,U+0000:[0|20|90|21|91|22|92|63|93|94|24|90|25|91|26|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining2_multiple_subrules.tests b/test/shaping/data/aots/tests/gsub_chaining2_multiple_subrules.tests new file mode 100644 index 000000000..e2fbb5cb2 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining2_multiple_subrules.tests @@ -0,0 +1,2 @@ +../fonts/gsub_chaining2_multiple_subrules_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|22|23|24|0|20|21|62|23|0] +../fonts/gsub_chaining2_multiple_subrules_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|21|62|23|24|0|20|21|62|23|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining2_next_glyph.tests b/test/shaping/data/aots/tests/gsub_chaining2_next_glyph.tests new file mode 100644 index 000000000..84c82522b --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining2_next_glyph.tests @@ -0,0 +1 @@ +../fonts/gsub_chaining2_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|62|63|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining2_simple.tests b/test/shaping/data/aots/tests/gsub_chaining2_simple.tests new file mode 100644 index 000000000..53fa7e85e --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining2_simple.tests @@ -0,0 +1,11 @@ +../fonts/gsub_chaining2_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|62|23|0] +../fonts/gsub_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[0|20|21|62|23|24|25|26|0] +../fonts/gsub_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+0000,U+0000:[0|20|21|22|23|24|25|0|0] +../fonts/gsub_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019:[0|20|21|22|23|24|25] +../fonts/gsub_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018:[0|20|21|22|23|24] +../fonts/gsub_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0000,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[0|0|21|22|23|24|25|26|0] +../fonts/gsub_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[21|22|23|24|25|26|0] +../fonts/gsub_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[22|23|24|25|26|0] +../fonts/gsub_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0000,U+0018,U+0019,U+001A,U+0000:[0|20|21|22|0|24|25|26|0] +../fonts/gsub_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017:[0|20|21|22|23] +../fonts/gsub_chaining2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016:[0|20|21|22] diff --git a/test/shaping/data/aots/tests/gsub_chaining2_successive.tests b/test/shaping/data/aots/tests/gsub_chaining2_successive.tests new file mode 100644 index 000000000..71cbe0dd9 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining2_successive.tests @@ -0,0 +1 @@ +../fonts/gsub_chaining2_successive_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0019,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000:[0|25|20|61|63|24|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining3_boundary.tests b/test/shaping/data/aots/tests/gsub_chaining3_boundary.tests new file mode 100644 index 000000000..c01dc4b01 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining3_boundary.tests @@ -0,0 +1,4 @@ +../fonts/gsub_chaining3_boundary_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|21|22|23|0] +../fonts/gsub_chaining3_boundary_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|22|23|0] +../fonts/gsub_chaining3_boundary_f3.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|22|23|0] +../fonts/gsub_chaining3_boundary_f4.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|21|62|23|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining3_lookupflag.tests b/test/shaping/data/aots/tests/gsub_chaining3_lookupflag.tests new file mode 100644 index 000000000..be2147bf4 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining3_lookupflag.tests @@ -0,0 +1 @@ +../fonts/gsub_chaining3_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+005A,U+0015,U+005B,U+0016,U+005C,U+0017,U+005D,U+005E,U+0018,U+005A,U+0019,U+005B,U+001A,U+0000:[0|20|90|21|91|22|92|63|93|94|24|90|25|91|26|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining3_next_glyph.tests b/test/shaping/data/aots/tests/gsub_chaining3_next_glyph.tests new file mode 100644 index 000000000..2493c1e90 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining3_next_glyph.tests @@ -0,0 +1 @@ +../fonts/gsub_chaining3_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0016,U+0015,U+0016,U+0015,U+0016,U+0015,U+0000:[0|22|61|22|61|22|21|0] diff --git a/test/shaping/data/aots/tests/gsub_chaining3_simple.tests b/test/shaping/data/aots/tests/gsub_chaining3_simple.tests new file mode 100644 index 000000000..eb2416787 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining3_simple.tests @@ -0,0 +1,11 @@ +../fonts/gsub_chaining3_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|62|23|0] +../fonts/gsub_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[0|20|21|62|23|24|25|26|0] +../fonts/gsub_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019,U+0000,U+0000:[0|20|21|22|23|24|25|0|0] +../fonts/gsub_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018,U+0019:[0|20|21|22|23|24|25] +../fonts/gsub_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0018:[0|20|21|22|23|24] +../fonts/gsub_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0000,U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[0|0|21|22|23|24|25|26|0] +../fonts/gsub_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0015,U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[21|22|23|24|25|26|0] +../fonts/gsub_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0016,U+0017,U+0018,U+0019,U+001A,U+0000:[22|23|24|25|26|0] +../fonts/gsub_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0000,U+0018,U+0019,U+001A,U+0000:[0|20|21|22|0|24|25|26|0] +../fonts/gsub_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017:[0|20|21|22|23] +../fonts/gsub_chaining3_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016:[0|20|21|22] diff --git a/test/shaping/data/aots/tests/gsub_chaining3_successive.tests b/test/shaping/data/aots/tests/gsub_chaining3_successive.tests new file mode 100644 index 000000000..edcade193 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_chaining3_successive.tests @@ -0,0 +1 @@ +../fonts/gsub_chaining3_successive_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0019,U+0014,U+0015,U+0016,U+0017,U+0018,U+0000:[0|25|20|61|63|24|0] diff --git a/test/shaping/data/aots/tests/gsub_context1_boundary.tests b/test/shaping/data/aots/tests/gsub_context1_boundary.tests new file mode 100644 index 000000000..9b1189266 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context1_boundary.tests @@ -0,0 +1,2 @@ +../fonts/gsub_context1_boundary_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20|20|20|20|20|0] +../fonts/gsub_context1_boundary_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|60|60|60|60|60|0] diff --git a/test/shaping/data/aots/tests/gsub_context1_expansion.tests b/test/shaping/data/aots/tests/gsub_context1_expansion.tests new file mode 100644 index 000000000..92714c5a8 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context1_expansion.tests @@ -0,0 +1 @@ +../fonts/gsub_context1_expansion_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0000:[0|20|61|62|63|22|0] diff --git a/test/shaping/data/aots/tests/gsub_context1_lookupflag.tests b/test/shaping/data/aots/tests/gsub_context1_lookupflag.tests new file mode 100644 index 000000000..c5d976058 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context1_lookupflag.tests @@ -0,0 +1,2 @@ +../fonts/gsub_context1_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+005A,U+0015,U+005B,U+005C,U+0016,U+0000:[0|60|90|61|91|92|62|0] +../fonts/gsub_context1_lookupflag_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+005A,U+0015,U+005B,U+005C,U+0016,U+0000:[0|20|90|61|91|92|0] diff --git a/test/shaping/data/aots/tests/gsub_context1_multiple_subrules.tests b/test/shaping/data/aots/tests/gsub_context1_multiple_subrules.tests new file mode 100644 index 000000000..febc41906 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context1_multiple_subrules.tests @@ -0,0 +1,2 @@ +../fonts/gsub_context1_multiple_subrules_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0000,U+0014,U+0015,U+0000:[0|60|21|22|0|20|61|0] +../fonts/gsub_context1_multiple_subrules_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0000,U+0014,U+0015,U+0000:[0|20|61|22|0|20|61|0] diff --git a/test/shaping/data/aots/tests/gsub_context1_next_glyph.tests b/test/shaping/data/aots/tests/gsub_context1_next_glyph.tests new file mode 100644 index 000000000..12414c342 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context1_next_glyph.tests @@ -0,0 +1 @@ +../fonts/gsub_context1_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|60|20|60|20|20|0] diff --git a/test/shaping/data/aots/tests/gsub_context1_simple.tests b/test/shaping/data/aots/tests/gsub_context1_simple.tests new file mode 100644 index 000000000..44252ecc4 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context1_simple.tests @@ -0,0 +1,3 @@ +../fonts/gsub_context1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0000:[0|60|61|62|0] +../fonts/gsub_context1_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0000,U+0014,U+0015,U+0000:[0|20|0|20|21|0] +../fonts/gsub_context1_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20|60|20|20|20|0] diff --git a/test/shaping/data/aots/tests/gsub_context1_successive.tests b/test/shaping/data/aots/tests/gsub_context1_successive.tests new file mode 100644 index 000000000..e68d6b29f --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context1_successive.tests @@ -0,0 +1 @@ +../fonts/gsub_context1_successive_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|63|0] diff --git a/test/shaping/data/aots/tests/gsub_context2_boundary.tests b/test/shaping/data/aots/tests/gsub_context2_boundary.tests new file mode 100644 index 000000000..2054277eb --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context2_boundary.tests @@ -0,0 +1,2 @@ +../fonts/gsub_context2_boundary_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20|20|20|20|20|0] +../fonts/gsub_context2_boundary_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|60|60|60|60|60|0] diff --git a/test/shaping/data/aots/tests/gsub_context2_classes.tests b/test/shaping/data/aots/tests/gsub_context2_classes.tests new file mode 100644 index 000000000..2e44007e7 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context2_classes.tests @@ -0,0 +1,2 @@ +../fonts/gsub_context2_classes_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+001A,U+001C,U+0018,U+0000,U+0015,U+001B,U+001A,U+0018,U+0000,U+0016,U+001B,U+001A,U+0018:[0|20|66|28|24|0|21|67|26|24|0|22|27|26|24] +../fonts/gsub_context2_classes_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0016,U+001B,U+001A,U+0018,U+0000,U+0018,U+0018,U+001D,U+0016,U+0000,U+0016,U+001B,U+001A,U+0018:[0|22|67|26|24|0|24|24|69|22|0|22|67|26|24] diff --git a/test/shaping/data/aots/tests/gsub_context2_expansion.tests b/test/shaping/data/aots/tests/gsub_context2_expansion.tests new file mode 100644 index 000000000..af0ce71c0 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context2_expansion.tests @@ -0,0 +1 @@ +../fonts/gsub_context2_expansion_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0000:[0|20|61|62|63|22|0] diff --git a/test/shaping/data/aots/tests/gsub_context2_lookupflag.tests b/test/shaping/data/aots/tests/gsub_context2_lookupflag.tests new file mode 100644 index 000000000..ac419498c --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context2_lookupflag.tests @@ -0,0 +1,2 @@ +../fonts/gsub_context2_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+005A,U+0015,U+005B,U+005C,U+0016,U+0000:[0|60|90|61|91|92|62|0] +../fonts/gsub_context2_lookupflag_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+005A,U+0015,U+005B,U+005C,U+0016,U+0000:[0|20|90|61|91|92|0] diff --git a/test/shaping/data/aots/tests/gsub_context2_multiple_subrules.tests b/test/shaping/data/aots/tests/gsub_context2_multiple_subrules.tests new file mode 100644 index 000000000..75225cd2a --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context2_multiple_subrules.tests @@ -0,0 +1,2 @@ +../fonts/gsub_context2_multiple_subrules_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0000,U+0014,U+0015,U+0000:[0|60|21|22|0|20|61|0] +../fonts/gsub_context2_multiple_subrules_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0000,U+0014,U+0015,U+0000:[0|20|61|22|0|20|61|0] diff --git a/test/shaping/data/aots/tests/gsub_context2_next_glyph.tests b/test/shaping/data/aots/tests/gsub_context2_next_glyph.tests new file mode 100644 index 000000000..020d05fc6 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context2_next_glyph.tests @@ -0,0 +1 @@ +../fonts/gsub_context2_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|60|20|60|20|20|0] diff --git a/test/shaping/data/aots/tests/gsub_context2_simple.tests b/test/shaping/data/aots/tests/gsub_context2_simple.tests new file mode 100644 index 000000000..5863605a4 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context2_simple.tests @@ -0,0 +1,3 @@ +../fonts/gsub_context2_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0000:[0|60|61|62|0] +../fonts/gsub_context2_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0000,U+0014,U+0015,U+0000:[0|20|0|20|21|0] +../fonts/gsub_context2_simple_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20|60|20|20|20|0] diff --git a/test/shaping/data/aots/tests/gsub_context2_successive.tests b/test/shaping/data/aots/tests/gsub_context2_successive.tests new file mode 100644 index 000000000..9aeeac71e --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context2_successive.tests @@ -0,0 +1 @@ +../fonts/gsub_context2_successive_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|63|0] diff --git a/test/shaping/data/aots/tests/gsub_context3_boundary.tests b/test/shaping/data/aots/tests/gsub_context3_boundary.tests new file mode 100644 index 000000000..8b40afdc2 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context3_boundary.tests @@ -0,0 +1,2 @@ +../fonts/gsub_context3_boundary_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|20|20|20|20|20|0] +../fonts/gsub_context3_boundary_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|60|60|60|60|60|0] diff --git a/test/shaping/data/aots/tests/gsub_context3_lookupflag.tests b/test/shaping/data/aots/tests/gsub_context3_lookupflag.tests new file mode 100644 index 000000000..03c0647e9 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context3_lookupflag.tests @@ -0,0 +1,2 @@ +../fonts/gsub_context3_lookupflag_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+005A,U+0015,U+005B,U+005C,U+0016,U+0000:[0|60|90|61|91|92|62|0] +../fonts/gsub_context3_lookupflag_f2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+005A,U+0015,U+005B,U+005C,U+0016,U+0000:[0|20|90|61|91|92|0] diff --git a/test/shaping/data/aots/tests/gsub_context3_next_glyph.tests b/test/shaping/data/aots/tests/gsub_context3_next_glyph.tests new file mode 100644 index 000000000..b28381b95 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context3_next_glyph.tests @@ -0,0 +1 @@ +../fonts/gsub_context3_next_glyph_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0014,U+0014,U+0014,U+0014,U+0000:[0|60|20|60|20|20|0] diff --git a/test/shaping/data/aots/tests/gsub_context3_simple.tests b/test/shaping/data/aots/tests/gsub_context3_simple.tests new file mode 100644 index 000000000..ec264eaa0 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context3_simple.tests @@ -0,0 +1,2 @@ +../fonts/gsub_context3_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0000:[0|60|61|62|0] +../fonts/gsub_context3_simple_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0000,U+0014,U+0015,U+0000,U+0014,U+0015,U+0016,U+0000:[0|20|0|20|21|0|60|61|62|0] diff --git a/test/shaping/data/aots/tests/gsub_context3_successive.tests b/test/shaping/data/aots/tests/gsub_context3_successive.tests new file mode 100644 index 000000000..b987a61f2 --- /dev/null +++ b/test/shaping/data/aots/tests/gsub_context3_successive.tests @@ -0,0 +1 @@ +../fonts/gsub_context3_successive_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0000,U+0014,U+0015,U+0016,U+0017,U+0000:[0|20|61|63|0] diff --git a/test/shaping/data/aots/tests/lookupflag_ignore_attach.tests b/test/shaping/data/aots/tests/lookupflag_ignore_attach.tests new file mode 100644 index 000000000..55ae5385e --- /dev/null +++ b/test/shaping/data/aots/tests/lookupflag_ignore_attach.tests @@ -0,0 +1,5 @@ +#../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+000D,U+001A,U+000A:[10|15|10] +#../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+0015,U+000D,U+0016,U+0017,U+001D,U+001A,U+000A:[10|15|21|22|23|29|10] +#../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+0015,U+000D,U+0016,U+001B,U+001A,U+000A:[10|11|21|13|22|27|26|10] +#../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+001B,U+000D,U+0016,U+0017,U+001A,U+000A:[10|11|27|13|22|23|26|10] +#../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+001B,U+000D,U+000E,U+0017,U+001A,U+000A:[10|11|27|13|14|23|26|10] diff --git a/test/shaping/data/aots/tests/lookupflag_ignore_base.tests b/test/shaping/data/aots/tests/lookupflag_ignore_base.tests new file mode 100644 index 000000000..5f0bfdbde --- /dev/null +++ b/test/shaping/data/aots/tests/lookupflag_ignore_base.tests @@ -0,0 +1,2 @@ +../fonts/lookupflag_ignore_base_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|23|21] +../fonts/lookupflag_ignore_base_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0018,U+0018,U+0013,U+0019,U+0014,U+0015:[17|23|24|24|25|21] diff --git a/test/shaping/data/aots/tests/lookupflag_ignore_combination.tests b/test/shaping/data/aots/tests/lookupflag_ignore_combination.tests new file mode 100644 index 000000000..d34f16a14 --- /dev/null +++ b/test/shaping/data/aots/tests/lookupflag_ignore_combination.tests @@ -0,0 +1,3 @@ +../fonts/lookupflag_ignore_combination_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+001A,U+0013,U+0014,U+0015:[17|23|26|21] +../fonts/lookupflag_ignore_combination_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+001A,U+0013,U+0018,U+001E,U+001F,U+0014,U+0015:[17|23|26|24|30|31|21] +../fonts/lookupflag_ignore_combination_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+001A,U+0013,U+0018,U+001E,U+0020,U+0014,U+0015:[17|18|26|19|24|30|32|20|21] diff --git a/test/shaping/data/aots/tests/lookupflag_ignore_ligatures.tests b/test/shaping/data/aots/tests/lookupflag_ignore_ligatures.tests new file mode 100644 index 000000000..feb31d809 --- /dev/null +++ b/test/shaping/data/aots/tests/lookupflag_ignore_ligatures.tests @@ -0,0 +1,3 @@ +../fonts/lookupflag_ignore_ligatures_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+001A,U+001B,U+0013,U+001B,U+0014,U+0015:[17|23|26|27|27|21] +../fonts/lookupflag_ignore_ligatures_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+001A,U+0018,U+0013,U+001B,U+0014,U+0015:[17|18|26|24|19|27|20|21] +../fonts/lookupflag_ignore_ligatures_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+001A,U+002A,U+0013,U+001B,U+0014,U+0015:[17|18|26|42|19|27|20|21] diff --git a/test/shaping/data/aots/tests/lookupflag_ignore_marks.tests b/test/shaping/data/aots/tests/lookupflag_ignore_marks.tests new file mode 100644 index 000000000..962659924 --- /dev/null +++ b/test/shaping/data/aots/tests/lookupflag_ignore_marks.tests @@ -0,0 +1 @@ +../fonts/lookupflag_ignore_marks_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+001C,U+001D,U+0013,U+001D,U+0014,U+0015:[17|23|28|29|29|21] diff --git a/test/shaping/data/in-house/Makefile.sources b/test/shaping/data/in-house/Makefile.sources index e5f105c78..0e9a3a21e 100644 --- a/test/shaping/data/in-house/Makefile.sources +++ b/test/shaping/data/in-house/Makefile.sources @@ -29,10 +29,12 @@ TESTS = \ tests/indic-special-cases.tests \ tests/indic-syllable.tests \ tests/indic-vowel-letter-spoofing.tests \ + tests/kern-format2.tests \ tests/khmer-mark-order.tests \ tests/khmer-misc.tests \ tests/language-tags.tests \ tests/ligature-id.tests \ + tests/macos.tests \ tests/mark-attachment.tests \ tests/mark-filtering-sets.tests \ tests/mongolian-variation-selector.tests \ diff --git a/test/shaping/data/in-house/fonts/4afb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf b/test/shaping/data/in-house/fonts/4afb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf new file mode 100644 index 000000000..274fc0817 Binary files /dev/null and b/test/shaping/data/in-house/fonts/4afb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf differ diff --git a/test/shaping/data/in-house/fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf b/test/shaping/data/in-house/fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf new file mode 100644 index 000000000..5a47a396c Binary files /dev/null and b/test/shaping/data/in-house/fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf differ diff --git a/test/shaping/data/in-house/fonts/e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf b/test/shaping/data/in-house/fonts/e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf new file mode 100644 index 000000000..b1605c45d Binary files /dev/null and b/test/shaping/data/in-house/fonts/e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf differ diff --git a/test/shaping/data/in-house/tests/kern-format2.tests b/test/shaping/data/in-house/tests/kern-format2.tests new file mode 100644 index 000000000..f7cd840df --- /dev/null +++ b/test/shaping/data/in-house/tests/kern-format2.tests @@ -0,0 +1,3 @@ +../fonts/e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf::U+0061,U+0062,U+0063,U+0064,U+0065,U+0066,U+0067,U+0068,U+0069,U+006A,U+006B,U+006C,U+006D,U+006E,U+006F,U+0070:[a=0+626|b=1+672|c=2+564|d=3@-15,0+657|e=4+621|f=5+403|g=6@-10,0+662|h=7+666|i=8+316|j=9+316|k=10+591|l=11+316|m=12+1021|n=13+666|o=14+644|p=15+672] +../fonts/e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf::U+0063,U+006B,U+0063,U+006B,U+0063,U+006B:[c=0+579|k=1+591|c=2+579|k=3+591|c=4+579|k=5+591] +../fonts/e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf::U+0041,U+0056:[A=0+701|V=1@-40,0+703] diff --git a/test/shaping/data/in-house/tests/macos.tests b/test/shaping/data/in-house/tests/macos.tests new file mode 100644 index 000000000..8bce25302 --- /dev/null +++ b/test/shaping/data/in-house/tests/macos.tests @@ -0,0 +1,31 @@ +# 10.12.6 +/System/Library/Fonts/Helvetica.dfont@c7bec2785a4c402b7809b5e35337c3d24c18e281:--shaper ot --font-funcs ot:U+006D,U+0300:[m=0+1706|gravecmb=0@-284,10+0] +/System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062:--shaper ot --font-funcs ot:U+006D,U+0300:[mgrave=0+1912] +/System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39:--shaper ot --font-funcs ot:U+0066,U+0069:[fi=0+1139] +/Library/Fonts/Khmer MN.ttc@5f5b1072df99b7355d3066ea85fe82969d13c94a:--shaper ot --font-funcs ot:U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] +/Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d:--shaper ot --font-funcs ot:U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] +/System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39:--shaper ot --font-funcs ot:U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] +/System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062:--shaper ot --font-funcs ot:U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] +/Library/Fonts/Apple Chancery.ttf@5fc49ae9bce39e2105864323183b68ea34c9e562:--shaper ot --font-funcs ot:U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1098] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--shaper ot --font-funcs ot:U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--shaper ot --font-funcs ot:U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--shaper ot --font-funcs ot:U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--shaper ot --font-funcs ot:U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165] +/System/Library/Fonts/SFNSDisplay.ttf@92787c30716672737e9059bc367c15d04fbc1ced:--shaper ot --font-funcs ot:U+0056,U+0041,U+0056,U+0041:[gid265=0+1227|gid4=1@-65,0+1162|gid265=2@-65,0+1162|gid4=3@-65,0+1227] +/System/Library/Fonts/Apple Color Emoji.ttc@d2fe8a134483aa48a43a9d1e4b7204d37a4abdf5:--remove-default-ignorables --shaper ot --font-funcs ot:U+1F468,U+200D,U+1F469,U+200D,U+1F467,U+200D,U+1F466:[u1F46A.MWGB=0+800] + +# 10.13.6 +/System/Library/Fonts/Helvetica.ttc@8a928f9866299d2455f41360202b7a3b48503a5e:--shaper ot --font-funcs ot:U+006D,U+0300:[m=0+1706|gravecmb=0@-284,10+0] +/System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269:--shaper ot --font-funcs ot:U+006D,U+0300:[mgrave=0+1912] +/System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c:--shaper ot --font-funcs ot:U+0066,U+0069:[fi=0+1139] +/Library/Fonts/Khmer MN.ttc@782ba6cf3fca0512ab348dfe08345a2d5dc5bf2c:--shaper ot --font-funcs ot:U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] +/Library/Fonts/Tamil MN.ttc@3de37f3f8f3cb6015b093fbd6e9d323daaf6fb1d:--shaper ot --font-funcs ot:U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] +/System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c:--shaper ot --font-funcs ot:U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] +/System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269:--shaper ot --font-funcs ot:U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] +/Library/Fonts/Apple Chancery.ttf@4ec49cba0d4e68d025ada0498c4df1b2f9fd57ac:--shaper ot --font-funcs ot:U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1098] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--shaper ot --font-funcs ot:U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--shaper ot --font-funcs ot:U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--shaper ot --font-funcs ot:U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--shaper ot --font-funcs ot:U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165] +/System/Library/Fonts/SFNSDisplay.ttf@c8948f464ff822a5f9bbf2e12d0e4e32268815aa:--shaper ot --font-funcs ot:U+0056,U+0041,U+0056,U+0041:[gid332=0+1227|gid4=1@-65,0+1162|gid332=2@-65,0+1162|gid4=3@-65,0+1227] +/System/Library/Fonts/Apple Color Emoji.ttc@2e09b1f3d42c3821cc6c4ac5b6ce16237ab0d496:--remove-default-ignorables --shaper ot --font-funcs ot:U+1F468,U+200D,U+1F469,U+200D,U+1F467,U+200D,U+1F466:[u1F46A.MWGB=0+800] diff --git a/test/shaping/data/in-house/tests/use-syllable.tests b/test/shaping/data/in-house/tests/use-syllable.tests index d8f1dff14..6a247ed0c 100644 --- a/test/shaping/data/in-house/tests/use-syllable.tests +++ b/test/shaping/data/in-house/tests/use-syllable.tests @@ -9,3 +9,4 @@ ../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+11042,U+11046:[brm_KA=0+754|brm_vowelEE=0@-383,0+0|brm_virama=0@-524,0+0] ../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+11044,U+11046:[brm_KA=0+754|brm_vowelOO=0@-647,0+0|brm_virama=0@-524,0+0] ../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+1103C:[brm_KA=0+754|brm_vowelU=0@-403,0+0] +../fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf::U+111C8,U+111C9,U+111C9:[u111C8=0+500|u111C9=0@-500,0+0|u111C9=0@-500,0+0] diff --git a/test/shaping/data/in-house/tests/use.tests b/test/shaping/data/in-house/tests/use.tests index 18d1991e2..dd2a3a27f 100644 --- a/test/shaping/data/in-house/tests/use.tests +++ b/test/shaping/data/in-house/tests/use.tests @@ -9,3 +9,6 @@ ../fonts/2a670df15b73a5dc75a5cc491bde5ac93c5077dc.ttf::U+11124,U+11131,U+11134:[u11124=0+514|u11131=0+0|uni25CC=0+547|u11134=0+0] ../fonts/573d3a3177c9a8646e94c8a0d7b224334340946a.ttf:--font-funcs=ft:U+11410,U+11442,U+11411,U+11440,U+11443,U+11410,U+11442,U+11411,U+11441,U+11443:[E_dv.alt=0+275|Ga.icd=0+367|Gha.diag=0@100,0+386|AA_dv.alt=0+208|Candrabindu=0@17,-8+0|E_dv.alt=5+275|Ga.icd=5+367|Gha.diag=5@100,0+386|AU_dv_part.alt=5+213|Candrabindu.sm=5@-52,179+0] ../fonts/dcf774ca21062e7439f98658b18974ea8b956d0c.ttf::U+11328,U+1134D,U+1CF4:[gid1=0+793|gid2=0+0|gid3=0+0] +../fonts/4afb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf::U+1C00,U+1C27,U+1C28,U+1C34,U+1C35:[uni1C35=0+500|uni1C34=0+500|uni1C28=0+500|uni1C27=0+500|uni1C00=0+500] +../fonts/4afb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf::U+0D4E,U+0D15,U+0D4D,U+0D15,U+0D46:[uni0D15=0+500|uni0D4E=0+500|uni0D4D=0+500|uni0D46=3+500|uni0D15=3+500] +../fonts/4afb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf::U+1102D,U+11046,U+11013,U+11046,U+11013,U+11046:[u11013=0+500|u11046_u11013=0+500|u1102D_u11046=0+500|u11046=0+500] diff --git a/test/shaping/run-tests.py b/test/shaping/run-tests.py index abb25ab3e..26853e4ee 100755 --- a/test/shaping/run-tests.py +++ b/test/shaping/run-tests.py @@ -2,7 +2,7 @@ from __future__ import print_function, division, absolute_import -import sys, os, subprocess +import sys, os, subprocess, hashlib, tempfile, shutil def cmd(command): global process @@ -27,7 +27,9 @@ process = subprocess.Popen ([hb_shape, '--batch'], stdout=subprocess.PIPE, stderr=sys.stdout) +passes = 0 fails = 0 +skips = 0 if not len (args): args = ['-'] @@ -45,24 +47,59 @@ for filename in args: f = open (filename) for line in f: + comment = False + if line.startswith ("#"): + comment = True + line = line[1:] + + if line.startswith (' '): + if not reference: + print ("#%s" % line) + continue + + line = line.strip () + if not line: + continue + fontfile, options, unicodes, glyphs_expected = line.split (":") - cwd = os.path.dirname(filename) - fontfile = os.path.normpath (os.path.join (cwd, fontfile)) + if fontfile.startswith ('/') or fontfile.startswith ('"/'): + fontfile, expected_hash = fontfile.split('@') + + try: + with open (fontfile, 'rb') as ff: + actual_hash = hashlib.sha1 (ff.read()).hexdigest ().strip () + if actual_hash != expected_hash: + print ('different version of %s found; Expected hash %s, got %s; skipping.' % + (fontfile, expected_hash, actual_hash)) + skips += 1 + continue + except: + print ('%s not found, skip.' % fontfile) + skips += 1 + continue + else: + cwd = os.path.dirname(filename) + fontfile = os.path.normpath (os.path.join (cwd, fontfile)) extra_options = ["--shaper=ot"] - glyphs_expected = glyphs_expected.strip() if glyphs_expected != '*': extra_options.append("--verify") - if line.startswith ("#"): + if comment: if not reference: - print ("# %s %s --unicodes %s" % (hb_shape, fontfile, unicodes)) + print ('# %s "%s" --unicodes %s' % (hb_shape, fontfile, unicodes)) continue if not reference: - print ("%s %s %s %s --unicodes %s" % + print ('%s "%s" %s %s --unicodes %s' % (hb_shape, fontfile, ' '.join(extra_options), options, unicodes)) + # hack to support fonts with space on run-tests.py, after several other tries... + if ' ' in fontfile: + new_fontfile = os.path.join (tempfile.gettempdir (), 'tmpfile') + shutil.copyfile(fontfile, new_fontfile) + fontfile = new_fontfile + glyphs1 = cmd ([hb_shape, "--font-funcs=ft", fontfile] + extra_options + ["--unicodes", unicodes] + (options.split (' ') if options else [])) @@ -74,7 +111,9 @@ for filename in args: if glyphs1 != glyphs2 and glyphs_expected != '*': print ("FT funcs: " + glyphs1) # file=sys.stderr print ("OT funcs: " + glyphs2) # file=sys.stderr - fails = fails + 1 + fails += 1 + else: + passes += 1 if reference: print (":".join ([fontfile, options, unicodes, glyphs1])) @@ -83,13 +122,20 @@ for filename in args: if glyphs1.strip() != glyphs_expected and glyphs_expected != '*': print ("Actual: " + glyphs1) # file=sys.stderr print ("Expected: " + glyphs_expected) # file=sys.stderr - fails = fails + 1 + fails += 1 + else: + passes += 1 -if fails != 0: - if not reference: - print (str (fails) + " tests failed.") # file=sys.stderr - sys.exit (1) - -else: - if not reference: +if not reference: + print ("%d tests passed; %d failed; %d skipped." % (passes, fails, skips)) # file=sys.stderr + if not (fails + passes): + print ("No tests ran.") + elif not (fails + skips): print ("All tests passed.") + +if fails: + sys.exit (1) +elif passes: + sys.exit (0) +else: + sys.exit (77)