PluginProbe
PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin / 1.9.0
PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin v1.9.0
trunk 1.5 1.6 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 All 71 releases
pdf-print / mpdf / classes / sea.php

sea.php in PDF & Print by BestWebSoft – WordPress Posts and Pages PDF Generator Plugin 1.9.0, at mpdf/classes/sea.php

349 lines 10.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3
4 class SEA {
5
6 // South East Asian shaper
7
8 // sea_category
9 const OT_X = 0;
10 const OT_C = 1;
11 const OT_IV = 2; # Independent Vowel
12 const OT_T = 3; # Tone Marks
13 const OT_H = 4; # Halant
14 const OT_A = 10; # Anusvara
15 const OT_GB = 12; # Generic Base (OT_DOTTEDCIRCLE in Indic)
16 const OT_CM = 17; # Consonant Medial
17 const OT_MR = 22; # Medial Ra
18 const OT_VAbv = 26;
19 const OT_VBlw = 27;
20 const OT_VPre = 28;
21 const OT_VPst = 29;
22 // ? From Indic categories
23 const OT_ZWNJ = 5;
24 const OT_ZWJ = 6;
25 const OT_M = 7;
26 const OT_SM = 8;
27 const OT_VD = 9;
28 const OT_NBSP = 11;
29 const OT_RS = 13;
30 const OT_Coeng = 14;
31 const OT_Repha = 15;
32 const OT_Ra = 16;
33
34 // Based on sea_category used to make string to find syllables
35 // OT_ to string character (using e.g. OT_C from INDIC) hb-ot-shape-complex-sea-private.hh
36 public static $sea_category_char = array(
37 'x',
38 'C',
39 'V',
40 'T',
41 'H',
42 'x',
43 'x',
44 'x',
45 'x',
46 'x',
47 'A',
48 'x',
49 'G',
50 'x',
51 'x',
52 'x',
53 'x',
54 'M',
55 'x',
56 'x',
57 'x',
58 'x',
59 'R',
60 'x',
61 'x',
62 'x',
63 'a',
64 'b',
65 'p',
66 't',
67 );
68
69
70 /* Visual positions in a syllable from left to right. */
71 // sea_position
72 const POS_START = 0;
73
74 const POS_RA_TO_BECOME_REPH = 1;
75 const POS_PRE_M = 2;
76 const POS_PRE_C = 3;
77
78 const POS_BASE_C = 4;
79 const POS_AFTER_MAIN = 5;
80
81 const POS_ABOVE_C = 6;
82
83 const POS_BEFORE_SUB = 7;
84 const POS_BELOW_C = 8;
85 const POS_AFTER_SUB = 9;
86
87 const POS_BEFORE_POST = 10;
88 const POS_POST_C = 11;
89 const POS_AFTER_POST = 12;
90
91 const POS_FINAL_C = 13;
92 const POS_SMVD = 14;
93
94 const POS_END = 15;
95
96
97
98 public static function set_sea_properties(&$info, $scriptblock ) {
99 $u = $info['uni'];
100 $type = self::sea_get_categories($u);
101 $cat = ($type & 0x7F);
102 $pos = ($type >> 8);
103
104 /*
105 * Re-assign category
106 */
107 // Medial Ra
108 if ($u == 0x1A55 || $u == 0xAA34) { $cat = self::OT_MR; }
109
110 /*
111 * Re-assign position.
112 */
113 if ($cat == self::OT_M) { // definitely "OT_M" in HarfBuzz - although this does not seem to have been defined ? should be OT_MR
114 switch ($pos) {
115 case self::POS_PRE_C: $cat = self::OT_VPre; break;
116 case self::POS_ABOVE_C: $cat = self::OT_VAbv; break;
117 case self::POS_BELOW_C: $cat = self::OT_VBlw; break;
118 case self::POS_POST_C: $cat = self::OT_VPst; break;
119 }
120 }
121
122 $info['sea_category'] = $cat;
123 $info['sea_position'] = $pos;
124 }
125
126 // syllable_type
127 const CONSONANT_SYLLABLE = 0;
128 const BROKEN_CLUSTER = 1;
129 const NON_SEA_CLUSTER = 2;
130
131
132
133 public static function set_syllables(&$o, $s, &$broken_syllables) {
134 $ptr = 0;
135 $syllable_serial = 1;
136 $broken_syllables = false;
137 while($ptr < strlen($s)) {
138 $match = '';
139 $syllable_length = 1;
140 $syllable_type = self::NON_SEA_CLUSTER ;
141
142 // CONSONANT_SYLLABLE Consonant syllable
143 if (preg_match('/^(C|V|G)(p|a|b|t|HC|M|R|T|A)*/', substr($s,$ptr), $ma)) {
144 $syllable_length = strlen($ma[0]);
145 $syllable_type = self::CONSONANT_SYLLABLE ;
146 }
147 // BROKEN_CLUSTER syllable
148 else if (preg_match('/^(p|a|b|t|HC|M|R|T|A)+/', substr($s,$ptr), $ma)) {
149 $syllable_length = strlen($ma[0]);
150 $syllable_type = self::BROKEN_CLUSTER ;
151 $broken_syllables = true;
152 }
153
154 for ($i = $ptr; $i < $ptr+$syllable_length; $i++) { $o[$i]['syllable'] = ($syllable_serial << 4) | $syllable_type; }
155 $ptr += $syllable_length ;
156 $syllable_serial++;
157 if ($syllable_serial == 16) $syllable_serial = 1;
158 }
159 }
160
161 public static function initial_reordering(&$info, $GSUBdata, $broken_syllables, $scriptblock, $dottedcircle) {
162
163 if ($broken_syllables && $dottedcircle) { self::insert_dotted_circles ($info, $dottedcircle); }
164
165 $count = count($info);
166 if (!$count) return;
167 $last = 0;
168 $last_syllable = $info[0]['syllable'];
169 for ($i = 1; $i < $count; $i++) {
170 if ($last_syllable != $info[$i]['syllable']) {
171 self::initial_reordering_syllable ($info, $GSUBdata, $scriptblock, $last, $i);
172 $last = $i;
173 $last_syllable = $info[$last]['syllable'];
174 }
175 }
176 self::initial_reordering_syllable($info, $GSUBdata, $scriptblock, $last, $count);
177 }
178
179 public static function insert_dotted_circles(&$info, $dottedcircle) {
180 $idx = 0;
181 $last_syllable = 0;
182 while ($idx < count($info)) {
183 $syllable = $info[$idx]['syllable'];
184 $syllable_type = ($syllable & 0x0F);
185 if ($last_syllable != $syllable && $syllable_type == self::BROKEN_CLUSTER) {
186 $last_syllable = $syllable;
187 $dottedcircle[0]['syllable'] = $info[$idx]['syllable'];
188 array_splice($info, $idx, 0, $dottedcircle);
189 }
190 else
191 $idx++;
192 }
193 }
194
195
196
197
198 public static function initial_reordering_syllable (&$info, $GSUBdata, $scriptblock, $start, $end) {
199 /* broken_cluster: We already inserted dotted-circles, so just call the standalone_cluster. */
200
201 $syllable_type = ($info[$start]['syllable'] & 0x0F);
202 if ($syllable_type==self::NON_SEA_CLUSTER ) { return; }
203 if ($syllable_type==self::BROKEN_CLUSTER) {
204 /* For dotted-circle, this is what Uniscribe does:
205 * If dotted-circle is the last glyph, it just does nothing. */
206 if ($info[$end - 1]['sea_category'] == self::OT_GB) {
207 return;
208 }
209 }
210
211 $base = $start;
212 $i = $start;
213 for (; $i < $base; $i++)
214 $info[$i]['sea_position'] = self::POS_PRE_C;
215 if ($i < $end) {
216 $info[$i]['sea_position'] = self::POS_BASE_C;
217 $i++;
218 }
219 for (; $i < $end; $i++) {
220 if ($info[$i]['sea_category'] == self::OT_MR) { /* Pre-base reordering */
221 $info[$i]['sea_position'] = self::POS_PRE_C;
222 continue;
223 }
224 if ($info[$i]['sea_category'] == self::OT_VPre) { /* Left matra */
225 $info[$i]['sea_position'] = self::POS_PRE_M;
226 continue;
227 }
228 $info[$i]['sea_position'] = self::POS_AFTER_MAIN;
229 }
230
231 /* Sit tight, rock 'n roll! */
232 self::bubble_sort ($info, $start, $end - $start);
233
234 }
235
236 public static function final_reordering (&$info, $GSUBdata, $scriptblock) {
237 $count = count($info);
238 if (!$count) return;
239 $last = 0;
240 $last_syllable = $info[0]['syllable'];
241 for ($i = 1; $i < $count; $i++) {
242 if ($last_syllable != $info[$i]['syllable']) {
243 self::final_reordering_syllable ($info, $GSUBdata, $scriptblock, $last, $i);
244 $last = $i;
245 $last_syllable = $info[$last]['syllable'];
246 }
247 }
248 self::final_reordering_syllable ($info, $GSUBdata, $scriptblock, $last, $count);
249
250 }
251
252 public static function final_reordering_syllable (&$info, $GSUBdata, $scriptblock, $start, $end) {
253 /*
254 * Nothing to do here at present!
255 */
256
257 }
258
259
260
261
262 public static $sea_table = array(
263
264 /* New Tai Lue (1980..19DF) */
265
266 /* 1980 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
267 /* 1988 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
268 /* 1990 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
269 /* 1998 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
270 /* 19A0 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
271 /* 19A8 */ 3841, 3841, 3841, 3841, 3840, 3840, 3840, 3840,
272 /* 19B0 */ 2823, 2823, 2823, 2823, 2823, 775, 775, 775,
273 /* 19B8 */ 2823, 2823, 775, 2823, 2823, 2823, 2823, 2823,
274 /* 19C0 */ 2823, 3857, 3857, 3857, 3857, 3857, 3857, 3857,
275 /* 19C8 */ 3843, 3843, 3840, 3840, 3840, 3840, 3840, 3840,
276 /* 19D0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840,
277 /* 19D8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840,
278
279 /* Tai Tham (1A20..1AAF) */
280
281 /* 1A20 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
282 /* 1A28 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
283 /* 1A30 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
284 /* 1A38 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
285 /* 1A40 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
286 /* 1A48 */ 3841, 3841, 3841, 3841, 3841, 3842, 3842, 3842,
287 /* 1A50 */3842, 3842, 3842, 3841, 3841, 3857, 3857, 3857,
288 /* 1A58 */ 3857, 3857, 3857, 3857, 3857, 3857, 3857, 3840,
289 /* 1A60 */ 3844, 2823, 1543, 2823, 2823, 1543, 1543, 1543,
290 /* 1A68 */ 1543, 2055, 2055, 1543, 2055, 2823, 775, 775,
291 /* 1A70 */ 775, 775, 775, 1543, 1543, 3843, 3843, 3843,
292 /* 1A78 */ 3843, 3843, 3840, 3840, 3840, 3840, 3840, 3840,
293 /* 1A80 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840,
294 /* 1A88 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840,
295 /* 1A90 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840,
296 /* 1A98 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840,
297 /* 1AA0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840,
298 /* 1AA8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840,
299
300 /* Cham (AA00..AA5F) */
301
302 /* AA00 */ 3842, 3842, 3842, 3842, 3842, 3842, 3841, 3841,
303 /* AA08 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
304 /* AA10 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
305 /* AA18 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
306 /* AA20 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841,
307 /* AA28 */ 3841, 1543, 1543, 1543, 1543, 2055, 1543, 775,
308 /* AA30 */ 775, 1543, 2055, 3857, 3857, 3857, 3857, 3840,
309 /* AA38 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840,
310 /* AA40 */ 3857, 3857, 3857, 3857, 3857, 3857, 3857, 3857,
311 /* AA48 */ 3857, 3857, 3857, 3857, 3857, 3857, 3840, 3840,
312 /* AA50 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840,
313 /* AA58 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840,
314
315 );
316
317
318
319 public static function sea_get_categories ($u) {
320 if (0x1980 <= $u && $u <= 0x19DF) return self::$sea_table[$u - 0x1980]; // offset 0 for New Tai Lue
321 if (0x1A20 <= $u && $u <= 0x1AAF) return self::$sea_table[$u - 0x1A20 + 96]; // offset for Tai Tham
322 if (0xAA00 <= $u && $u <= 0xAA5F) return self::$sea_table[$u - 0xAA00 + 96 + 144]; // Cham
323 if ($u == 0x00A0) return 3851; // (ISC_CP | (IMC_x << 8))
324 if ($u == 0x25CC) return 3851; // (ISC_CP | (IMC_x << 8))
325 return 3840; // (ISC_x | (IMC_x << 8))
326 }
327
328
329 public static function bubble_sort(&$arr, $start, $len) {
330 if ($len<2) { return;}
331 $k = $start+$len-2;
332 while ($k >= $start) {
333 for ($j=$start; $j<=$k; $j++) {
334 if ($arr[$j]['sea_position'] > $arr[$j + 1]['sea_position']) {
335 $t = $arr[$j];
336 $arr[$j] = $arr[$j + 1];
337 $arr[$j + 1] = $t;
338 }
339 }
340 $k--;
341 }
342 }
343
344
345
346
347 } // end Class
348
349 ?>