author | prr |
Thu, 21 Jun 2018 12:54:30 -0700 | |
changeset 50826 | f5b95be8b6e2 |
parent 50352 | 25db2c8f3cf8 |
child 54232 | 7c11a7cc7c1d |
permissions | -rw-r--r-- |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
1 |
/* |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
2 |
* Copyright © 2010,2012 Google, Inc. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
3 |
* |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
4 |
* This is part of HarfBuzz, a text shaping library. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
5 |
* |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
6 |
* Permission is hereby granted, without written agreement and without |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
7 |
* license or royalty fees, to use, copy, modify, and distribute this |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
8 |
* software and its documentation for any purpose, provided that the |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
9 |
* above copyright notice and the following two paragraphs appear in |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
10 |
* all copies of this software. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
11 |
* |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
12 |
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
13 |
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
14 |
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
15 |
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
16 |
* DAMAGE. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
17 |
* |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
18 |
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
19 |
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
20 |
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
21 |
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
22 |
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
23 |
* |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
24 |
* Google Author(s): Behdad Esfahbod |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
25 |
*/ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
26 |
|
48274 | 27 |
#include "hb-private.hh" |
28 |
#include "hb-debug.hh" |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
29 |
#include "hb-ot-shape-complex-arabic-private.hh" |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
30 |
#include "hb-ot-shape-private.hh" |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
31 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
32 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
33 |
/* buffer var allocations */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
34 |
#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
35 |
|
40435 | 36 |
#define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0 |
37 |
||
38 |
/* See: |
|
50352 | 39 |
* https://github.com/harfbuzz/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */ |
40435 | 40 |
#define HB_ARABIC_GENERAL_CATEGORY_IS_WORD(gen_cat) \ |
48274 | 41 |
(FLAG_UNSAFE (gen_cat) & \ |
40435 | 42 |
(FLAG (HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) | \ |
43 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE) | \ |
|
44 |
/*FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) |*/ \ |
|
45 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER) | \ |
|
46 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | \ |
|
47 |
/*FLAG (HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER) |*/ \ |
|
48 |
/*FLAG (HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER) |*/ \ |
|
49 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \ |
|
50 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \ |
|
51 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | \ |
|
52 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) | \ |
|
53 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER) | \ |
|
54 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER) | \ |
|
55 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL) | \ |
|
56 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL) | \ |
|
57 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL) | \ |
|
58 |
FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL))) |
|
59 |
||
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
60 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
61 |
/* |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
62 |
* Joining types: |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
63 |
*/ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
64 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
65 |
/* |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
66 |
* Bits used in the joining tables |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
67 |
*/ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
68 |
enum hb_arabic_joining_type_t { |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
69 |
JOINING_TYPE_U = 0, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
70 |
JOINING_TYPE_L = 1, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
71 |
JOINING_TYPE_R = 2, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
72 |
JOINING_TYPE_D = 3, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
73 |
JOINING_TYPE_C = JOINING_TYPE_D, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
74 |
JOINING_GROUP_ALAPH = 4, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
75 |
JOINING_GROUP_DALATH_RISH = 5, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
76 |
NUM_STATE_MACHINE_COLS = 6, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
77 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
78 |
JOINING_TYPE_T = 7, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
79 |
JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
80 |
}; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
81 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
82 |
#include "hb-ot-shape-complex-arabic-table.hh" |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
83 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
84 |
static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
85 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
86 |
unsigned int j_type = joining_type(u); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
87 |
if (likely (j_type != JOINING_TYPE_X)) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
88 |
return j_type; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
89 |
|
48274 | 90 |
return (FLAG_UNSAFE(gen_cat) & |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
91 |
(FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
92 |
FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
93 |
FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT)) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
94 |
) ? JOINING_TYPE_T : JOINING_TYPE_U; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
95 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
96 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
97 |
#define FEATURE_IS_SYRIAC(tag) hb_in_range<unsigned char> ((unsigned char) (tag), '2', '3') |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
98 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
99 |
static const hb_tag_t arabic_features[] = |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
100 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
101 |
HB_TAG('i','s','o','l'), |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
102 |
HB_TAG('f','i','n','a'), |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
103 |
HB_TAG('f','i','n','2'), |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
104 |
HB_TAG('f','i','n','3'), |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
105 |
HB_TAG('m','e','d','i'), |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
106 |
HB_TAG('m','e','d','2'), |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
107 |
HB_TAG('i','n','i','t'), |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
108 |
HB_TAG_NONE |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
109 |
}; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
110 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
111 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
112 |
/* Same order as the feature array */ |
40435 | 113 |
enum arabic_action_t { |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
114 |
ISOL, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
115 |
FINA, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
116 |
FIN2, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
117 |
FIN3, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
118 |
MEDI, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
119 |
MED2, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
120 |
INIT, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
121 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
122 |
NONE, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
123 |
|
40435 | 124 |
ARABIC_NUM_FEATURES = NONE, |
125 |
||
126 |
/* We abuse the same byte for other things... */ |
|
127 |
STCH_FIXED, |
|
128 |
STCH_REPEATING, |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
129 |
}; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
130 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
131 |
static const struct arabic_state_table_entry { |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
132 |
uint8_t prev_action; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
133 |
uint8_t curr_action; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
134 |
uint16_t next_state; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
135 |
} arabic_state_table[][NUM_STATE_MACHINE_COLS] = |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
136 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
137 |
/* jt_U, jt_L, jt_R, jt_D, jg_ALAPH, jg_DALATH_RISH */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
138 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
139 |
/* State 0: prev was U, not willing to join. */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
140 |
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, }, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
141 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
142 |
/* State 1: prev was R or ISOL/ALAPH, not willing to join. */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
143 |
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, }, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
144 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
145 |
/* State 2: prev was D/L in ISOL form, willing to join. */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
146 |
{ {NONE,NONE,0}, {NONE,ISOL,2}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, }, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
147 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
148 |
/* State 3: prev was D in FINA form, willing to join. */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
149 |
{ {NONE,NONE,0}, {NONE,ISOL,2}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, }, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
150 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
151 |
/* State 4: prev was FINA ALAPH, not willing to join. */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
152 |
{ {NONE,NONE,0}, {NONE,ISOL,2}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, }, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
153 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
154 |
/* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
155 |
{ {NONE,NONE,0}, {NONE,ISOL,2}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, }, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
156 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
157 |
/* State 6: prev was DALATH/RISH, not willing to join. */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
158 |
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, } |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
159 |
}; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
160 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
161 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
162 |
static void |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
163 |
nuke_joiners (const hb_ot_shape_plan_t *plan, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
164 |
hb_font_t *font, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
165 |
hb_buffer_t *buffer); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
166 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
167 |
static void |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
168 |
arabic_fallback_shape (const hb_ot_shape_plan_t *plan, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
169 |
hb_font_t *font, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
170 |
hb_buffer_t *buffer); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
171 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
172 |
static void |
40435 | 173 |
record_stch (const hb_ot_shape_plan_t *plan, |
174 |
hb_font_t *font, |
|
175 |
hb_buffer_t *buffer); |
|
176 |
||
177 |
static void |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
178 |
collect_features_arabic (hb_ot_shape_planner_t *plan) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
179 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
180 |
hb_ot_map_builder_t *map = &plan->map; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
181 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
182 |
/* We apply features according to the Arabic spec, with pauses |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
183 |
* in between most. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
184 |
* |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
185 |
* The pause between init/medi/... and rlig is required. See eg: |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
186 |
* https://bugzilla.mozilla.org/show_bug.cgi?id=644184 |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
187 |
* |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
188 |
* The pauses between init/medi/... themselves are not necessarily |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
189 |
* needed as only one of those features is applied to any character. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
190 |
* The only difference it makes is when fonts have contextual |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
191 |
* substitutions. We now follow the order of the spec, which makes |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
192 |
* for better experience if that's what Uniscribe is doing. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
193 |
* |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
194 |
* At least for Arabic, looks like Uniscribe has a pause between |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
195 |
* rlig and calt. Otherwise the IranNastaliq's ALLAH ligature won't |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
196 |
* work. However, testing shows that rlig and calt are applied |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
197 |
* together for Mongolian in Uniscribe. As such, we only add a |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
198 |
* pause for Arabic, not other scripts. |
48274 | 199 |
* |
200 |
* A pause after calt is required to make KFGQPC Uthmanic Script HAFS |
|
50352 | 201 |
* work correctly. See https://github.com/harfbuzz/harfbuzz/issues/505 |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
202 |
*/ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
203 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
204 |
map->add_gsub_pause (nuke_joiners); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
205 |
|
40435 | 206 |
map->add_global_bool_feature (HB_TAG('s','t','c','h')); |
207 |
map->add_gsub_pause (record_stch); |
|
208 |
||
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
209 |
map->add_global_bool_feature (HB_TAG('c','c','m','p')); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
210 |
map->add_global_bool_feature (HB_TAG('l','o','c','l')); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
211 |
|
48274 | 212 |
map->add_gsub_pause (nullptr); |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
213 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
214 |
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
215 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
216 |
bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
217 |
map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_NONE); |
48274 | 218 |
map->add_gsub_pause (nullptr); |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
219 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
220 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
221 |
map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
222 |
if (plan->props.script == HB_SCRIPT_ARABIC) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
223 |
map->add_gsub_pause (arabic_fallback_shape); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
224 |
|
48274 | 225 |
/* No pause after rclt. See 98460779bae19e4d64d29461ff154b3527bf8420. */ |
226 |
map->add_global_bool_feature (HB_TAG('r','c','l','t')); |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
227 |
map->add_global_bool_feature (HB_TAG('c','a','l','t')); |
48274 | 228 |
map->add_gsub_pause (nullptr); |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
229 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
230 |
/* The spec includes 'cswh'. Earlier versions of Windows |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
231 |
* used to enable this by default, but testing suggests |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
232 |
* that Windows 8 and later do not enable it by default, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
233 |
* and spec now says 'Off by default'. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
234 |
* We disabled this in ae23c24c32. |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
235 |
* Note that IranNastaliq uses this feature extensively |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
236 |
* to fixup broken glyph sequences. Oh well... |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
237 |
* Test case: U+0643,U+0640,U+0631. */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
238 |
//map->add_global_bool_feature (HB_TAG('c','s','w','h')); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
239 |
map->add_global_bool_feature (HB_TAG('m','s','e','t')); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
240 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
241 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
242 |
#include "hb-ot-shape-complex-arabic-fallback.hh" |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
243 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
244 |
struct arabic_shape_plan_t |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
245 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
246 |
ASSERT_POD (); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
247 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
248 |
/* The "+ 1" in the next array is to accommodate for the "NONE" command, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
249 |
* which is not an OpenType feature, but this simplifies the code by not |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
250 |
* having to do a "if (... < NONE) ..." and just rely on the fact that |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
251 |
* mask_array[NONE] == 0. */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
252 |
hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1]; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
253 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
254 |
arabic_fallback_plan_t *fallback_plan; |
40435 | 255 |
|
256 |
unsigned int do_fallback : 1; |
|
257 |
unsigned int has_stch : 1; |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
258 |
}; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
259 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
260 |
void * |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
261 |
data_create_arabic (const hb_ot_shape_plan_t *plan) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
262 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
263 |
arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof (arabic_shape_plan_t)); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
264 |
if (unlikely (!arabic_plan)) |
48274 | 265 |
return nullptr; |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
266 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
267 |
arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC; |
40435 | 268 |
arabic_plan->has_stch = !!plan->map.get_1_mask (HB_TAG ('s','t','c','h')); |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
269 |
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) { |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
270 |
arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
271 |
arabic_plan->do_fallback = arabic_plan->do_fallback && |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
272 |
(FEATURE_IS_SYRIAC (arabic_features[i]) || |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
273 |
plan->map.needs_fallback (arabic_features[i])); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
274 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
275 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
276 |
return arabic_plan; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
277 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
278 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
279 |
void |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
280 |
data_destroy_arabic (void *data) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
281 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
282 |
arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) data; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
283 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
284 |
arabic_fallback_plan_destroy (arabic_plan->fallback_plan); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
285 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
286 |
free (data); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
287 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
288 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
289 |
static void |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
290 |
arabic_joining (hb_buffer_t *buffer) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
291 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
292 |
unsigned int count = buffer->len; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
293 |
hb_glyph_info_t *info = buffer->info; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
294 |
unsigned int prev = (unsigned int) -1, state = 0; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
295 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
296 |
/* Check pre-context */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
297 |
for (unsigned int i = 0; i < buffer->context_len[0]; i++) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
298 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
299 |
unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i])); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
300 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
301 |
if (unlikely (this_type == JOINING_TYPE_T)) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
302 |
continue; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
303 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
304 |
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
305 |
state = entry->next_state; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
306 |
break; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
307 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
308 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
309 |
for (unsigned int i = 0; i < count; i++) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
310 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
311 |
unsigned int this_type = get_joining_type (info[i].codepoint, _hb_glyph_info_get_general_category (&info[i])); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
312 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
313 |
if (unlikely (this_type == JOINING_TYPE_T)) { |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
314 |
info[i].arabic_shaping_action() = NONE; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
315 |
continue; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
316 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
317 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
318 |
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
319 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
320 |
if (entry->prev_action != NONE && prev != (unsigned int) -1) |
48274 | 321 |
{ |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
322 |
info[prev].arabic_shaping_action() = entry->prev_action; |
48274 | 323 |
buffer->unsafe_to_break (prev, i + 1); |
324 |
} |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
325 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
326 |
info[i].arabic_shaping_action() = entry->curr_action; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
327 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
328 |
prev = i; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
329 |
state = entry->next_state; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
330 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
331 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
332 |
for (unsigned int i = 0; i < buffer->context_len[1]; i++) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
333 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
334 |
unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[1][i])); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
335 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
336 |
if (unlikely (this_type == JOINING_TYPE_T)) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
337 |
continue; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
338 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
339 |
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type]; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
340 |
if (entry->prev_action != NONE && prev != (unsigned int) -1) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
341 |
info[prev].arabic_shaping_action() = entry->prev_action; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
342 |
break; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
343 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
344 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
345 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
346 |
static void |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
347 |
mongolian_variation_selectors (hb_buffer_t *buffer) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
348 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
349 |
/* Copy arabic_shaping_action() from base to Mongolian variation selectors. */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
350 |
unsigned int count = buffer->len; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
351 |
hb_glyph_info_t *info = buffer->info; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
352 |
for (unsigned int i = 1; i < count; i++) |
48274 | 353 |
if (unlikely (hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x180Bu, 0x180Du))) |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
354 |
info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action(); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
355 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
356 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
357 |
void |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
358 |
setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
359 |
hb_buffer_t *buffer, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
360 |
hb_script_t script) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
361 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
362 |
HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
363 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
364 |
arabic_joining (buffer); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
365 |
if (script == HB_SCRIPT_MONGOLIAN) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
366 |
mongolian_variation_selectors (buffer); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
367 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
368 |
unsigned int count = buffer->len; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
369 |
hb_glyph_info_t *info = buffer->info; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
370 |
for (unsigned int i = 0; i < count; i++) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
371 |
info[i].mask |= arabic_plan->mask_array[info[i].arabic_shaping_action()]; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
372 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
373 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
374 |
static void |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
375 |
setup_masks_arabic (const hb_ot_shape_plan_t *plan, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
376 |
hb_buffer_t *buffer, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
377 |
hb_font_t *font HB_UNUSED) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
378 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
379 |
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
380 |
setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
381 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
382 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
383 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
384 |
static void |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
385 |
nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
386 |
hb_font_t *font HB_UNUSED, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
387 |
hb_buffer_t *buffer) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
388 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
389 |
unsigned int count = buffer->len; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
390 |
hb_glyph_info_t *info = buffer->info; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
391 |
for (unsigned int i = 0; i < count; i++) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
392 |
if (_hb_glyph_info_is_zwj (&info[i])) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
393 |
_hb_glyph_info_flip_joiners (&info[i]); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
394 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
395 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
396 |
static void |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
397 |
arabic_fallback_shape (const hb_ot_shape_plan_t *plan, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
398 |
hb_font_t *font, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
399 |
hb_buffer_t *buffer) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
400 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
401 |
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
402 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
403 |
if (!arabic_plan->do_fallback) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
404 |
return; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
405 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
406 |
retry: |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
407 |
arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) hb_atomic_ptr_get (&arabic_plan->fallback_plan); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
408 |
if (unlikely (!fallback_plan)) |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
409 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
410 |
/* This sucks. We need a font to build the fallback plan... */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
411 |
fallback_plan = arabic_fallback_plan_create (plan, font); |
48274 | 412 |
if (unlikely (!hb_atomic_ptr_cmpexch (&(const_cast<arabic_shape_plan_t *> (arabic_plan))->fallback_plan, nullptr, fallback_plan))) { |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
413 |
arabic_fallback_plan_destroy (fallback_plan); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
414 |
goto retry; |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
415 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
416 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
417 |
|
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
418 |
arabic_fallback_plan_shape (fallback_plan, font, buffer); |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
419 |
} |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
420 |
|
40435 | 421 |
/* |
422 |
* Stretch feature: "stch". |
|
423 |
* See example here: |
|
50826 | 424 |
* https://docs.microsoft.com/en-us/typography/script-development/syriac |
40435 | 425 |
* We implement this in a generic way, such that the Arabic subtending |
426 |
* marks can use it as well. |
|
427 |
*/ |
|
428 |
||
429 |
static void |
|
430 |
record_stch (const hb_ot_shape_plan_t *plan, |
|
431 |
hb_font_t *font, |
|
432 |
hb_buffer_t *buffer) |
|
433 |
{ |
|
434 |
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; |
|
435 |
if (!arabic_plan->has_stch) |
|
436 |
return; |
|
437 |
||
438 |
/* 'stch' feature was just applied. Look for anything that multiplied, |
|
439 |
* and record it for stch treatment later. Note that rtlm, frac, etc |
|
440 |
* are applied before stch, but we assume that they didn't result in |
|
441 |
* anything multiplying into 5 pieces, so it's safe-ish... */ |
|
442 |
||
443 |
unsigned int count = buffer->len; |
|
444 |
hb_glyph_info_t *info = buffer->info; |
|
445 |
for (unsigned int i = 0; i < count; i++) |
|
446 |
if (unlikely (_hb_glyph_info_multiplied (&info[i]))) |
|
447 |
{ |
|
448 |
unsigned int comp = _hb_glyph_info_get_lig_comp (&info[i]); |
|
449 |
info[i].arabic_shaping_action() = comp % 2 ? STCH_REPEATING : STCH_FIXED; |
|
450 |
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH; |
|
451 |
} |
|
452 |
} |
|
453 |
||
454 |
static void |
|
455 |
apply_stch (const hb_ot_shape_plan_t *plan, |
|
456 |
hb_buffer_t *buffer, |
|
457 |
hb_font_t *font) |
|
458 |
{ |
|
459 |
if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH))) |
|
460 |
return; |
|
461 |
||
462 |
/* The Arabic shaper currently always processes in RTL mode, so we should |
|
463 |
* stretch / position the stretched pieces to the left / preceding glyphs. */ |
|
464 |
||
465 |
/* We do a two pass implementation: |
|
466 |
* First pass calculates the exact number of extra glyphs we need, |
|
467 |
* We then enlarge buffer to have that much room, |
|
468 |
* Second pass applies the stretch, copying things to the end of buffer. |
|
469 |
*/ |
|
470 |
||
471 |
int sign = font->x_scale < 0 ? -1 : +1; |
|
472 |
unsigned int extra_glyphs_needed = 0; // Set during MEASURE, used during CUT |
|
473 |
typedef enum { MEASURE, CUT } step_t; |
|
474 |
||
475 |
for (step_t step = MEASURE; step <= CUT; step = (step_t) (step + 1)) |
|
476 |
{ |
|
477 |
unsigned int count = buffer->len; |
|
478 |
hb_glyph_info_t *info = buffer->info; |
|
479 |
hb_glyph_position_t *pos = buffer->pos; |
|
480 |
unsigned int new_len = count + extra_glyphs_needed; // write head during CUT |
|
481 |
unsigned int j = new_len; |
|
482 |
for (unsigned int i = count; i; i--) |
|
483 |
{ |
|
484 |
if (!hb_in_range<unsigned> (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING)) |
|
485 |
{ |
|
486 |
if (step == CUT) |
|
487 |
{ |
|
488 |
--j; |
|
489 |
info[j] = info[i - 1]; |
|
490 |
pos[j] = pos[i - 1]; |
|
491 |
} |
|
492 |
continue; |
|
493 |
} |
|
494 |
||
495 |
/* Yay, justification! */ |
|
496 |
||
497 |
hb_position_t w_total = 0; // Total to be filled |
|
498 |
hb_position_t w_fixed = 0; // Sum of fixed tiles |
|
499 |
hb_position_t w_repeating = 0; // Sum of repeating tiles |
|
500 |
int n_fixed = 0; |
|
501 |
int n_repeating = 0; |
|
502 |
||
503 |
unsigned int end = i; |
|
504 |
while (i && |
|
505 |
hb_in_range<unsigned> (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING)) |
|
506 |
{ |
|
507 |
i--; |
|
508 |
hb_position_t width = font->get_glyph_h_advance (info[i].codepoint); |
|
509 |
if (info[i].arabic_shaping_action() == STCH_FIXED) |
|
510 |
{ |
|
511 |
w_fixed += width; |
|
512 |
n_fixed++; |
|
513 |
} |
|
514 |
else |
|
515 |
{ |
|
516 |
w_repeating += width; |
|
517 |
n_repeating++; |
|
518 |
} |
|
519 |
} |
|
520 |
unsigned int start = i; |
|
521 |
unsigned int context = i; |
|
522 |
while (context && |
|
523 |
!hb_in_range<unsigned> (info[context - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING) && |
|
524 |
(_hb_glyph_info_is_default_ignorable (&info[context - 1]) || |
|
525 |
HB_ARABIC_GENERAL_CATEGORY_IS_WORD (_hb_glyph_info_get_general_category (&info[context - 1])))) |
|
526 |
{ |
|
527 |
context--; |
|
528 |
w_total += pos[context].x_advance; |
|
529 |
} |
|
530 |
i++; // Don't touch i again. |
|
531 |
||
48274 | 532 |
DEBUG_MSG (ARABIC, nullptr, "%s stretch at (%d,%d,%d)", |
40435 | 533 |
step == MEASURE ? "measuring" : "cutting", context, start, end); |
48274 | 534 |
DEBUG_MSG (ARABIC, nullptr, "rest of word: count=%d width %d", start - context, w_total); |
535 |
DEBUG_MSG (ARABIC, nullptr, "fixed tiles: count=%d width=%d", n_fixed, w_fixed); |
|
536 |
DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%d", n_repeating, w_repeating); |
|
40435 | 537 |
|
538 |
/* Number of additional times to repeat each repeating tile. */ |
|
539 |
int n_copies = 0; |
|
540 |
||
541 |
hb_position_t w_remaining = w_total - w_fixed; |
|
542 |
if (sign * w_remaining > sign * w_repeating && sign * w_repeating > 0) |
|
543 |
n_copies = (sign * w_remaining) / (sign * w_repeating) - 1; |
|
544 |
||
545 |
/* See if we can improve the fit by adding an extra repeat and squeezing them together a bit. */ |
|
546 |
hb_position_t extra_repeat_overlap = 0; |
|
547 |
hb_position_t shortfall = sign * w_remaining - sign * w_repeating * (n_copies + 1); |
|
48274 | 548 |
if (shortfall > 0 && n_repeating > 0) |
40435 | 549 |
{ |
550 |
++n_copies; |
|
551 |
hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining; |
|
552 |
if (excess > 0) |
|
553 |
extra_repeat_overlap = excess / (n_copies * n_repeating); |
|
554 |
} |
|
555 |
||
556 |
if (step == MEASURE) |
|
557 |
{ |
|
558 |
extra_glyphs_needed += n_copies * n_repeating; |
|
48274 | 559 |
DEBUG_MSG (ARABIC, nullptr, "will add extra %d copies of repeating tiles", n_copies); |
40435 | 560 |
} |
561 |
else |
|
562 |
{ |
|
48274 | 563 |
buffer->unsafe_to_break (context, end); |
40435 | 564 |
hb_position_t x_offset = 0; |
565 |
for (unsigned int k = end; k > start; k--) |
|
566 |
{ |
|
567 |
hb_position_t width = font->get_glyph_h_advance (info[k - 1].codepoint); |
|
568 |
||
569 |
unsigned int repeat = 1; |
|
570 |
if (info[k - 1].arabic_shaping_action() == STCH_REPEATING) |
|
571 |
repeat += n_copies; |
|
572 |
||
48274 | 573 |
DEBUG_MSG (ARABIC, nullptr, "appending %d copies of glyph %d; j=%d", |
40435 | 574 |
repeat, info[k - 1].codepoint, j); |
575 |
for (unsigned int n = 0; n < repeat; n++) |
|
576 |
{ |
|
577 |
x_offset -= width; |
|
578 |
if (n > 0) |
|
579 |
x_offset += extra_repeat_overlap; |
|
580 |
pos[k - 1].x_offset = x_offset; |
|
581 |
/* Append copy. */ |
|
582 |
--j; |
|
583 |
info[j] = info[k - 1]; |
|
584 |
pos[j] = pos[k - 1]; |
|
585 |
} |
|
586 |
} |
|
587 |
} |
|
588 |
} |
|
589 |
||
590 |
if (step == MEASURE) |
|
591 |
{ |
|
592 |
if (unlikely (!buffer->ensure (count + extra_glyphs_needed))) |
|
593 |
break; |
|
594 |
} |
|
595 |
else |
|
596 |
{ |
|
597 |
assert (j == 0); |
|
598 |
buffer->len = new_len; |
|
599 |
} |
|
600 |
} |
|
601 |
} |
|
602 |
||
603 |
||
604 |
static void |
|
605 |
postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan, |
|
606 |
hb_buffer_t *buffer, |
|
607 |
hb_font_t *font) |
|
608 |
{ |
|
609 |
apply_stch (plan, buffer, font); |
|
610 |
||
611 |
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); |
|
612 |
} |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
613 |
|
50826 | 614 |
/* https://unicode.org/reports/tr53/tr53-1.pdf */ |
48274 | 615 |
|
616 |
static hb_codepoint_t |
|
617 |
modifier_combining_marks[] = |
|
618 |
{ |
|
619 |
0x0654u, /* ARABIC HAMZA ABOVE */ |
|
620 |
0x0655u, /* ARABIC HAMZA BELOW */ |
|
621 |
0x0658u, /* ARABIC MARK NOON GHUNNA */ |
|
622 |
0x06DCu, /* ARABIC SMALL HIGH SEEN */ |
|
623 |
0x06E3u, /* ARABIC SMALL LOW SEEN */ |
|
624 |
0x06E7u, /* ARABIC SMALL HIGH YEH */ |
|
625 |
0x06E8u, /* ARABIC SMALL HIGH NOON */ |
|
626 |
0x08F3u, /* ARABIC SMALL HIGH WAW */ |
|
627 |
}; |
|
628 |
||
629 |
static inline bool |
|
630 |
info_is_mcm (const hb_glyph_info_t &info) |
|
631 |
{ |
|
632 |
hb_codepoint_t u = info.codepoint; |
|
633 |
for (unsigned int i = 0; i < ARRAY_LENGTH (modifier_combining_marks); i++) |
|
634 |
if (u == modifier_combining_marks[i]) |
|
635 |
return true; |
|
636 |
return false; |
|
637 |
} |
|
638 |
||
639 |
static void |
|
640 |
reorder_marks_arabic (const hb_ot_shape_plan_t *plan, |
|
641 |
hb_buffer_t *buffer, |
|
642 |
unsigned int start, |
|
643 |
unsigned int end) |
|
644 |
{ |
|
645 |
hb_glyph_info_t *info = buffer->info; |
|
646 |
||
50352 | 647 |
DEBUG_MSG (ARABIC, buffer, "Reordering marks from %d to %d", start, end); |
648 |
||
48274 | 649 |
unsigned int i = start; |
650 |
for (unsigned int cc = 220; cc <= 230; cc += 10) |
|
651 |
{ |
|
50352 | 652 |
DEBUG_MSG (ARABIC, buffer, "Looking for %d's starting at %d", cc, i); |
48274 | 653 |
while (i < end && info_cc(info[i]) < cc) |
654 |
i++; |
|
50352 | 655 |
DEBUG_MSG (ARABIC, buffer, "Looking for %d's stopped at %d", cc, i); |
48274 | 656 |
|
657 |
if (i == end) |
|
658 |
break; |
|
659 |
||
660 |
if (info_cc(info[i]) > cc) |
|
661 |
continue; |
|
662 |
||
663 |
unsigned int j = i; |
|
50352 | 664 |
while (j < end && info_cc(info[j]) == cc && info_is_mcm (info[j])) |
48274 | 665 |
j++; |
666 |
||
667 |
if (i == j) |
|
668 |
continue; |
|
669 |
||
50352 | 670 |
DEBUG_MSG (ARABIC, buffer, "Found %d's from %d to %d", cc, i, j); |
671 |
||
48274 | 672 |
/* Shift it! */ |
50352 | 673 |
DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d", cc, i, j); |
48274 | 674 |
hb_glyph_info_t temp[HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS]; |
675 |
assert (j - i <= ARRAY_LENGTH (temp)); |
|
676 |
buffer->merge_clusters (start, j); |
|
677 |
memmove (temp, &info[i], (j - i) * sizeof (hb_glyph_info_t)); |
|
678 |
memmove (&info[start + j - i], &info[start], (i - start) * sizeof (hb_glyph_info_t)); |
|
679 |
memmove (&info[start], temp, (j - i) * sizeof (hb_glyph_info_t)); |
|
680 |
||
50352 | 681 |
/* Renumber CC such that the reordered sequence is still sorted. |
682 |
* 22 and 26 are chosen because they are smaller than all Arabic categories, |
|
683 |
* and are folded back to 220/230 respectively during fallback mark positioning. |
|
684 |
* |
|
685 |
* We do this because the CGJ-handling logic in the normalizer relies on |
|
686 |
* mark sequences having an increasing order even after this reordering. |
|
687 |
* https://github.com/harfbuzz/harfbuzz/issues/554 |
|
688 |
* This, however, does break some obscure sequences, where the normalizer |
|
689 |
* might compose a sequence that it should not. For example, in the seequence |
|
690 |
* ALEF, HAMZAH, MADDAH, we should NOT try to compose ALEF+MADDAH, but with this |
|
691 |
* renumbering, we will. |
|
692 |
*/ |
|
693 |
unsigned int new_start = start + j - i; |
|
694 |
unsigned int new_cc = cc == 220 ? HB_MODIFIED_COMBINING_CLASS_CCC22 : HB_MODIFIED_COMBINING_CLASS_CCC26; |
|
695 |
while (start < new_start) |
|
696 |
{ |
|
697 |
_hb_glyph_info_set_modified_combining_class (&info[start], new_cc); |
|
698 |
start++; |
|
699 |
} |
|
48274 | 700 |
|
701 |
i = j; |
|
702 |
} |
|
703 |
} |
|
704 |
||
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
705 |
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
706 |
{ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
707 |
collect_features_arabic, |
48274 | 708 |
nullptr, /* override_features */ |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
709 |
data_create_arabic, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
710 |
data_destroy_arabic, |
48274 | 711 |
nullptr, /* preprocess_text */ |
40435 | 712 |
postprocess_glyphs_arabic, |
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
713 |
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, |
48274 | 714 |
nullptr, /* decompose */ |
715 |
nullptr, /* compose */ |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
716 |
setup_masks_arabic, |
48274 | 717 |
nullptr, /* disable_otl */ |
718 |
reorder_marks_arabic, |
|
34414
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
719 |
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
720 |
true, /* fallback_position */ |
e496a8d8fc8a
8143177: Integrate harfbuzz opentype layout engine per JEP 258
prr
parents:
diff
changeset
|
721 |
}; |