38 #include "CanonShaping.h" |
39 #include "CanonShaping.h" |
39 #include "HanLayoutEngine.h" |
40 #include "HanLayoutEngine.h" |
40 #include "IndicLayoutEngine.h" |
41 #include "IndicLayoutEngine.h" |
41 #include "KhmerLayoutEngine.h" |
42 #include "KhmerLayoutEngine.h" |
42 #include "ThaiLayoutEngine.h" |
43 #include "ThaiLayoutEngine.h" |
|
44 //#include "TibetanLayoutEngine.h" |
43 #include "GXLayoutEngine.h" |
45 #include "GXLayoutEngine.h" |
44 #include "ScriptAndLanguageTags.h" |
46 #include "ScriptAndLanguageTags.h" |
45 #include "CharSubstitutionFilter.h" |
47 #include "CharSubstitutionFilter.h" |
46 |
48 |
47 #include "LEGlyphStorage.h" |
49 #include "LEGlyphStorage.h" |
52 #include "MorphTables.h" |
54 #include "MorphTables.h" |
53 |
55 |
54 #include "DefaultCharMapper.h" |
56 #include "DefaultCharMapper.h" |
55 |
57 |
56 #include "KernTable.h" |
58 #include "KernTable.h" |
|
59 |
|
60 U_NAMESPACE_BEGIN |
57 |
61 |
58 const LEUnicode32 DefaultCharMapper::controlChars[] = { |
62 const LEUnicode32 DefaultCharMapper::controlChars[] = { |
59 0x0009, 0x000A, 0x000D, |
63 0x0009, 0x000A, 0x000D, |
60 /*0x200C, 0x200D,*/ 0x200E, 0x200F, |
64 /*0x200C, 0x200D,*/ 0x200E, 0x200F, |
61 0x2028, 0x2029, 0x202A, 0x202B, 0x202C, 0x202D, 0x202E, |
65 0x2028, 0x2029, 0x202A, 0x202B, 0x202C, 0x202D, 0x202E, |
143 {ccmpFeatureTag, ccmpFeatureMask} |
148 {ccmpFeatureTag, ccmpFeatureMask} |
144 }; |
149 }; |
145 |
150 |
146 static const le_int32 canonFeatureMapCount = LE_ARRAY_SIZE(canonFeatureMap); |
151 static const le_int32 canonFeatureMapCount = LE_ARRAY_SIZE(canonFeatureMap); |
147 |
152 |
148 LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, |
153 LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags) |
149 le_int32 languageCode, le_int32 typoFlags) |
154 : fGlyphStorage(NULL), fFontInstance(fontInstance), fScriptCode(scriptCode), fLanguageCode(languageCode), |
150 : fGlyphStorage(NULL), fFontInstance(fontInstance), fScriptCode(scriptCode), |
155 fTypoFlags(typoFlags) |
151 fLanguageCode(languageCode), fTypoFlags(typoFlags) |
|
152 { |
156 { |
153 fGlyphStorage = new LEGlyphStorage(); |
157 fGlyphStorage = new LEGlyphStorage(); |
154 } |
158 } |
155 |
159 |
156 le_int32 LayoutEngine::getGlyphCount() const |
160 le_int32 LayoutEngine::getGlyphCount() const |
157 { |
161 { |
158 return fGlyphStorage->getGlyphCount(); |
162 return fGlyphStorage->getGlyphCount(); |
159 } |
163 } |
160 |
164 |
161 void LayoutEngine::getCharIndices(le_int32 charIndices[], le_int32 indexBase, |
165 void LayoutEngine::getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const |
162 LEErrorCode &success) const |
|
163 { |
166 { |
164 fGlyphStorage->getCharIndices(charIndices, indexBase, success); |
167 fGlyphStorage->getCharIndices(charIndices, indexBase, success); |
165 } |
168 } |
166 |
169 |
167 void LayoutEngine::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const |
170 void LayoutEngine::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const |
168 { |
171 { |
169 fGlyphStorage->getCharIndices(charIndices, success); |
172 fGlyphStorage->getCharIndices(charIndices, success); |
170 } |
173 } |
171 |
174 |
172 // Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits |
175 // Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits |
173 void LayoutEngine::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, |
176 void LayoutEngine::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const |
174 LEErrorCode &success) const |
|
175 { |
177 { |
176 fGlyphStorage->getGlyphs(glyphs, extraBits, success); |
178 fGlyphStorage->getGlyphs(glyphs, extraBits, success); |
177 } |
179 } |
178 |
180 |
179 void LayoutEngine::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const |
181 void LayoutEngine::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const |
216 void LayoutEngine::getGlyphPositions(float positions[], LEErrorCode &success) const |
218 void LayoutEngine::getGlyphPositions(float positions[], LEErrorCode &success) const |
217 { |
219 { |
218 fGlyphStorage->getGlyphPositions(positions, success); |
220 fGlyphStorage->getGlyphPositions(positions, success); |
219 } |
221 } |
220 |
222 |
221 void LayoutEngine::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, |
223 void LayoutEngine::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const |
222 LEErrorCode &success) const |
|
223 { |
224 { |
224 fGlyphStorage->getGlyphPosition(glyphIndex, x, y, success); |
225 fGlyphStorage->getGlyphPosition(glyphIndex, x, y, success); |
225 } |
226 } |
226 |
227 |
227 le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, |
228 le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, |
228 le_int32 count, le_int32 max, le_bool rightToLeft, LEUnicode *&outChars, |
229 LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success) |
229 LEGlyphStorage &glyphStorage, LEErrorCode &success) |
|
230 { |
230 { |
231 if (LE_FAILURE(success)) { |
231 if (LE_FAILURE(success)) { |
232 return 0; |
232 return 0; |
233 } |
233 } |
234 |
234 |
235 if (offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { |
235 if (offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { |
236 success = LE_ILLEGAL_ARGUMENT_ERROR; |
236 success = LE_ILLEGAL_ARGUMENT_ERROR; |
237 return 0; |
237 return 0; |
238 } |
238 } |
239 |
239 |
240 if ((fTypoFlags & 0x4) == 0) { // no canonical processing |
240 const GlyphSubstitutionTableHeader *canonGSUBTable = (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable; |
241 return count; |
|
242 } |
|
243 |
|
244 const GlyphSubstitutionTableHeader *canonGSUBTable = |
|
245 (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable; |
|
246 LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode); |
241 LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode); |
247 LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode); |
242 LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode); |
248 le_int32 i, dir = 1, out = 0, outCharCount = count; |
243 le_int32 i, dir = 1, out = 0, outCharCount = count; |
249 |
244 |
250 if (canonGSUBTable->coversScript(scriptTag)) { |
245 if (canonGSUBTable->coversScript(scriptTag)) { |
254 |
249 |
255 // This is the cheapest way to get mark reordering only for Hebrew. |
250 // This is the cheapest way to get mark reordering only for Hebrew. |
256 // We could just do the mark reordering for all scripts, but most |
251 // We could just do the mark reordering for all scripts, but most |
257 // of them probably don't need it... |
252 // of them probably don't need it... |
258 if (fScriptCode == hebrScriptCode) { |
253 if (fScriptCode == hebrScriptCode) { |
259 reordered = LE_NEW_ARRAY(LEUnicode, count); |
254 reordered = LE_NEW_ARRAY(LEUnicode, count); |
260 |
255 |
261 if (reordered == NULL) { |
256 if (reordered == NULL) { |
262 success = LE_MEMORY_ALLOCATION_ERROR; |
257 success = LE_MEMORY_ALLOCATION_ERROR; |
263 return 0; |
258 return 0; |
264 } |
259 } |
265 |
260 |
266 CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, |
261 CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, glyphStorage); |
267 reordered, glyphStorage); |
262 inChars = reordered; |
268 inChars = reordered; |
|
269 } |
263 } |
270 |
264 |
271 glyphStorage.allocateGlyphArray(count, rightToLeft, success); |
265 glyphStorage.allocateGlyphArray(count, rightToLeft, success); |
272 glyphStorage.allocateAuxData(success); |
266 glyphStorage.allocateAuxData(success); |
273 |
267 |
287 |
281 |
288 if (reordered != NULL) { |
282 if (reordered != NULL) { |
289 LE_DELETE_ARRAY(reordered); |
283 LE_DELETE_ARRAY(reordered); |
290 } |
284 } |
291 |
285 |
292 outCharCount = canonGSUBTable->process(glyphStorage, rightToLeft, scriptTag, |
286 outCharCount = canonGSUBTable->process(glyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE); |
293 langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE); |
|
294 |
287 |
295 out = (rightToLeft? count - 1 : 0); |
288 out = (rightToLeft? count - 1 : 0); |
296 |
289 |
297 outChars = LE_NEW_ARRAY(LEUnicode, outCharCount); |
290 outChars = LE_NEW_ARRAY(LEUnicode, outCharCount); |
298 for (i = 0; i < outCharCount; i += 1, out += dir) { |
291 for (i = 0; i < outCharCount; i += 1, out += dir) { |
303 } |
296 } |
304 |
297 |
305 return outCharCount; |
298 return outCharCount; |
306 } |
299 } |
307 |
300 |
308 |
301 le_int32 LayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, |
309 le_int32 LayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, |
302 LEGlyphStorage &glyphStorage, LEErrorCode &success) |
310 le_int32 count, le_int32 max, le_bool rightToLeft, |
|
311 LEGlyphStorage &glyphStorage, LEErrorCode &success) |
|
312 { |
303 { |
313 if (LE_FAILURE(success)) { |
304 if (LE_FAILURE(success)) { |
314 return 0; |
305 return 0; |
315 } |
306 } |
316 |
307 |
317 if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || |
308 if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { |
318 offset + count > max) { |
|
319 |
|
320 success = LE_ILLEGAL_ARGUMENT_ERROR; |
309 success = LE_ILLEGAL_ARGUMENT_ERROR; |
321 return 0; |
310 return 0; |
322 } |
311 } |
323 |
312 |
324 LEUnicode *outChars = NULL; |
313 LEUnicode *outChars = NULL; |
325 le_int32 outCharCount = characterProcessing(chars, offset, count, max, |
314 le_int32 outCharCount = characterProcessing(chars, offset, count, max, rightToLeft, outChars, glyphStorage, success); |
326 rightToLeft, outChars, glyphStorage, success); |
|
327 |
315 |
328 if (outChars != NULL) { |
316 if (outChars != NULL) { |
329 mapCharsToGlyphs(outChars, 0, outCharCount, rightToLeft, rightToLeft, |
317 mapCharsToGlyphs(outChars, 0, outCharCount, rightToLeft, rightToLeft, glyphStorage, success); |
330 glyphStorage, success); |
318 LE_DELETE_ARRAY(outChars); // FIXME: a subclass may have allocated this, in which case this delete might not work... |
331 // FIXME: a subclass may have allocated this, in which case this delete |
|
332 // might not work... |
|
333 LE_DELETE_ARRAY(outChars); |
|
334 } else { |
319 } else { |
335 mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, |
320 mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success); |
336 glyphStorage, success); |
|
337 } |
321 } |
338 |
322 |
339 return glyphStorage.getGlyphCount(); |
323 return glyphStorage.getGlyphCount(); |
340 } |
324 } |
341 |
325 |
342 // Input: glyphs |
326 // Input: glyphs |
343 // Output: positions |
327 // Output: positions |
344 void LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage, |
328 void LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y, LEErrorCode &success) |
345 float x, float y, LEErrorCode &success) |
|
346 { |
329 { |
347 if (LE_FAILURE(success)) { |
330 if (LE_FAILURE(success)) { |
348 return; |
331 return; |
349 } |
332 } |
350 |
333 |
367 } |
350 } |
368 |
351 |
369 glyphStorage.setPosition(glyphCount, x, y, success); |
352 glyphStorage.setPosition(glyphCount, x, y, success); |
370 } |
353 } |
371 |
354 |
372 void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, |
355 void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, |
373 le_int32 count, le_bool reverse, |
356 LEGlyphStorage &glyphStorage, LEErrorCode &success) |
374 LEGlyphStorage &glyphStorage, LEErrorCode &success) |
|
375 { |
357 { |
376 if (LE_FAILURE(success)) { |
358 if (LE_FAILURE(success)) { |
377 return; |
359 return; |
378 } |
360 } |
379 |
361 |
433 } |
414 } |
434 |
415 |
435 glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success); |
416 glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success); |
436 } |
417 } |
437 |
418 |
438 void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, |
419 void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, le_bool reverse, LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success) |
439 le_bool reverse, LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, |
|
440 LEErrorCode &success) |
|
441 { |
420 { |
442 float xAdjust = 0; |
421 float xAdjust = 0; |
443 le_int32 c = 0, direction = 1, p; |
422 le_int32 c = 0, direction = 1, p; |
444 le_int32 glyphCount = glyphStorage.getGlyphCount(); |
423 le_int32 glyphCount = glyphStorage.getGlyphCount(); |
445 |
424 |
482 const void *LayoutEngine::getFontTable(LETag tableTag) const |
461 const void *LayoutEngine::getFontTable(LETag tableTag) const |
483 { |
462 { |
484 return fFontInstance->getFontTable(tableTag); |
463 return fFontInstance->getFontTable(tableTag); |
485 } |
464 } |
486 |
465 |
487 void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, |
466 void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, |
488 le_int32 count, le_bool reverse, le_bool mirror, |
467 LEGlyphStorage &glyphStorage, LEErrorCode &success) |
489 LEGlyphStorage &glyphStorage, LEErrorCode &success) |
|
490 { |
468 { |
491 if (LE_FAILURE(success)) { |
469 if (LE_FAILURE(success)) { |
492 return; |
470 return; |
493 } |
471 } |
494 |
472 |
495 glyphStorage.allocateGlyphArray(count, reverse, success); |
473 glyphStorage.allocateGlyphArray(count, reverse, success); |
496 |
474 |
497 DefaultCharMapper charMapper(TRUE, mirror); |
475 DefaultCharMapper charMapper(TRUE, mirror); |
498 |
476 |
499 fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse, |
477 fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse, &charMapper, glyphStorage); |
500 &charMapper, glyphStorage); |
|
501 } |
478 } |
502 |
479 |
503 // Input: characters, font? |
480 // Input: characters, font? |
504 // Output: glyphs, positions, char indices |
481 // Output: glyphs, positions, char indices |
505 // Returns: number of glyphs |
482 // Returns: number of glyphs |
506 le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, |
483 le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, |
507 le_int32 count, le_int32 max, le_bool rightToLeft, |
484 float x, float y, LEErrorCode &success) |
508 float x, float y, LEErrorCode &success) |
|
509 { |
485 { |
510 if (LE_FAILURE(success)) { |
486 if (LE_FAILURE(success)) { |
511 return 0; |
487 return 0; |
512 } |
488 } |
513 |
489 |
514 if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || |
490 if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { |
515 offset + count > max) { |
|
516 |
|
517 success = LE_ILLEGAL_ARGUMENT_ERROR; |
491 success = LE_ILLEGAL_ARGUMENT_ERROR; |
518 return 0; |
492 return 0; |
519 } |
493 } |
520 |
494 |
521 le_int32 glyphCount; |
495 le_int32 glyphCount; |
522 |
496 |
523 glyphCount = computeGlyphs(chars, offset, count, max, rightToLeft, |
497 glyphCount = computeGlyphs(chars, offset, count, max, rightToLeft, *fGlyphStorage, success); |
524 *fGlyphStorage, success); |
|
525 positionGlyphs(*fGlyphStorage, x, y, success); |
498 positionGlyphs(*fGlyphStorage, x, y, success); |
526 adjustGlyphPositions(chars, offset, count, rightToLeft, *fGlyphStorage, success); |
499 adjustGlyphPositions(chars, offset, count, rightToLeft, *fGlyphStorage, success); |
527 |
500 |
528 return glyphCount; |
501 return glyphCount; |
529 } |
502 } |
531 void LayoutEngine::reset() |
504 void LayoutEngine::reset() |
532 { |
505 { |
533 fGlyphStorage->reset(); |
506 fGlyphStorage->reset(); |
534 } |
507 } |
535 |
508 |
536 LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, |
509 LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success) |
537 le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success) |
|
538 { |
510 { |
539 // 3 -> kerning and ligatures |
511 // 3 -> kerning and ligatures |
540 return LayoutEngine::layoutEngineFactory(fontInstance, scriptCode, |
512 return LayoutEngine::layoutEngineFactory(fontInstance, scriptCode, languageCode, 3, success); |
541 languageCode, 3, success); |
513 } |
542 } |
514 |
543 |
515 LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) |
544 LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, |
|
545 le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, |
|
546 LEErrorCode &success) |
|
547 { |
516 { |
548 static const le_uint32 gsubTableTag = LE_GSUB_TABLE_TAG; |
517 static const le_uint32 gsubTableTag = LE_GSUB_TABLE_TAG; |
549 static const le_uint32 mortTableTag = LE_MORT_TABLE_TAG; |
518 static const le_uint32 mortTableTag = LE_MORT_TABLE_TAG; |
550 |
519 |
551 if (LE_FAILURE(success)) { |
520 if (LE_FAILURE(success)) { |
552 return NULL; |
521 return NULL; |
553 } |
522 } |
554 |
523 |
555 // code2000 has GPOS kern feature tags for latn script |
524 const GlyphSubstitutionTableHeader *gsubTable = (const GlyphSubstitutionTableHeader *) fontInstance->getFontTable(gsubTableTag); |
556 |
|
557 const GlyphSubstitutionTableHeader *gsubTable = |
|
558 (const GlyphSubstitutionTableHeader *) fontInstance->getFontTable(gsubTableTag); |
|
559 LayoutEngine *result = NULL; |
525 LayoutEngine *result = NULL; |
560 LETag scriptTag = 0x00000000; |
526 LETag scriptTag = 0x00000000; |
561 LETag languageTag = 0x00000000; |
527 LETag languageTag = 0x00000000; |
562 |
528 |
563 if (gsubTable != NULL && |
529 if (gsubTable != NULL && gsubTable->coversScript(scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode))) { |
564 gsubTable->coversScript(scriptTag = |
|
565 OpenTypeLayoutEngine::getScriptTag(scriptCode))) { |
|
566 |
|
567 switch (scriptCode) { |
530 switch (scriptCode) { |
568 case bengScriptCode: |
531 case bengScriptCode: |
569 case devaScriptCode: |
532 case devaScriptCode: |
570 case gujrScriptCode: |
533 case gujrScriptCode: |
571 case kndaScriptCode: |
534 case kndaScriptCode: |
573 case oryaScriptCode: |
536 case oryaScriptCode: |
574 case guruScriptCode: |
537 case guruScriptCode: |
575 case tamlScriptCode: |
538 case tamlScriptCode: |
576 case teluScriptCode: |
539 case teluScriptCode: |
577 case sinhScriptCode: |
540 case sinhScriptCode: |
578 result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, |
541 result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); |
579 languageCode, typoFlags, gsubTable); |
|
580 break; |
542 break; |
581 |
543 |
582 case arabScriptCode: |
544 case arabScriptCode: |
583 result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, |
545 result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); |
584 languageCode, typoFlags, gsubTable); |
|
585 break; |
546 break; |
586 |
547 |
587 case haniScriptCode: |
548 case haniScriptCode: |
588 languageTag = OpenTypeLayoutEngine::getLangSysTag(languageCode); |
549 languageTag = OpenTypeLayoutEngine::getLangSysTag(languageCode); |
589 |
550 |
591 case korLanguageCode: |
552 case korLanguageCode: |
592 case janLanguageCode: |
553 case janLanguageCode: |
593 case zhtLanguageCode: |
554 case zhtLanguageCode: |
594 case zhsLanguageCode: |
555 case zhsLanguageCode: |
595 if (gsubTable->coversScriptAndLanguage(scriptTag, languageTag, TRUE)) { |
556 if (gsubTable->coversScriptAndLanguage(scriptTag, languageTag, TRUE)) { |
596 result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, |
557 result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); |
597 languageCode, typoFlags, gsubTable); |
|
598 break; |
558 break; |
599 } |
559 } |
600 |
560 |
601 // note: falling through to default case. |
561 // note: falling through to default case. |
602 default: |
562 default: |
603 result = new OpenTypeLayoutEngine(fontInstance, scriptCode, |
563 result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); |
604 languageCode, typoFlags, gsubTable); |
|
605 break; |
564 break; |
606 } |
565 } |
607 |
566 |
608 break; |
567 break; |
|
568 #if 0 |
|
569 case tibtScriptCode: |
|
570 result = new TibetanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); |
|
571 break; |
|
572 #endif |
609 |
573 |
610 case khmrScriptCode: |
574 case khmrScriptCode: |
611 result = new KhmerOpenTypeLayoutEngine(fontInstance, scriptCode, |
575 result = new KhmerOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); |
612 languageCode, typoFlags, gsubTable); |
|
613 break; |
576 break; |
614 |
577 |
615 default: |
578 default: |
616 result = new OpenTypeLayoutEngine(fontInstance, scriptCode, |
579 result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); |
617 languageCode, typoFlags, gsubTable); |
|
618 break; |
580 break; |
619 } |
581 } |
620 } else { |
582 } else { |
621 const MorphTableHeader *morphTable = |
583 const MorphTableHeader *morphTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag); |
622 (MorphTableHeader *) fontInstance->getFontTable(mortTableTag); |
|
623 |
584 |
624 if (morphTable != NULL) { |
585 if (morphTable != NULL) { |
625 result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable); |
586 result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable); |
626 } else { |
587 } else { |
627 switch (scriptCode) { |
588 switch (scriptCode) { |
634 case guruScriptCode: |
595 case guruScriptCode: |
635 case tamlScriptCode: |
596 case tamlScriptCode: |
636 case teluScriptCode: |
597 case teluScriptCode: |
637 case sinhScriptCode: |
598 case sinhScriptCode: |
638 { |
599 { |
639 result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, |
600 result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); |
640 languageCode, typoFlags); |
|
641 break; |
601 break; |
642 } |
602 } |
643 |
603 |
644 case arabScriptCode: |
604 case arabScriptCode: |
645 result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, |
605 //case hebrScriptCode: |
646 languageCode, typoFlags); |
606 result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); |
647 break; |
607 break; |
|
608 |
|
609 //case hebrScriptCode: |
|
610 // return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); |
648 |
611 |
649 case thaiScriptCode: |
612 case thaiScriptCode: |
650 result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); |
613 result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); |
651 break; |
614 break; |
652 |
615 |