1 /*
2 *
3 * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
4 *
5 */
6
7 #include "LETypes.h"
8 #include "MorphTables.h"
9 #include "StateTables.h"
10 #include "MorphStateTables.h"
11 #include "SubtableProcessor2.h"
12 #include "StateTableProcessor2.h"
13 #include "ContextualGlyphInsertionProc2.h"
14 #include "LEGlyphStorage.h"
15 #include "LESwaps.h"
16
17 U_NAMESPACE_BEGIN
18
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2)19 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2)
20
21 ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(
22 const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
23 : StateTableProcessor2(morphSubtableHeader, success)
24 {
25 contextualGlyphHeader = LEReferenceTo<ContextualGlyphInsertionHeader2>(morphSubtableHeader, success);
26 if(LE_FAILURE(success) || !contextualGlyphHeader.isValid()) return;
27 le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
28 insertionTable = LEReferenceToArrayOf<le_uint16>(stHeader, success, insertionTableOffset, LE_UNBOUNDED_ARRAY);
29 entryTable = LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
30 }
31
~ContextualGlyphInsertionProcessor2()32 ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2()
33 {
34 }
35
beginStateTable()36 void ContextualGlyphInsertionProcessor2::beginStateTable()
37 {
38 markGlyph = 0;
39 }
40
doInsertion(LEGlyphStorage & glyphStorage,le_int16 atGlyph,le_int16 & index,le_int16 count,le_bool,le_bool isBefore,LEErrorCode & success)41 void ContextualGlyphInsertionProcessor2::doInsertion(LEGlyphStorage &glyphStorage,
42 le_int16 atGlyph,
43 le_int16 &index,
44 le_int16 count,
45 le_bool /* isKashidaLike */,
46 le_bool isBefore,
47 LEErrorCode &success) {
48 LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(atGlyph, count + 1, success);
49
50 if(LE_FAILURE(success) || insertGlyphs==NULL) {
51 return;
52 }
53
54 // Note: Kashida vs Split Vowel seems to only affect selection and highlighting.
55 // We note the flag, but do not layout different.
56 // https://developer.apple.com/fonts/TTRefMan/RM06/Chap6mort.html
57
58 le_int16 targetIndex = 0;
59 if(isBefore) {
60 // insert at beginning
61 insertGlyphs[targetIndex++] = glyphStorage[atGlyph];
62 } else {
63 // insert at end
64 insertGlyphs[count] = glyphStorage[atGlyph];
65 }
66
67 while(count--) {
68 insertGlyphs[targetIndex++] = insertionTable.getObject(index++, success);
69 }
70 glyphStorage.applyInsertions();
71 }
72
processStateEntry(LEGlyphStorage & glyphStorage,le_int32 & currGlyph,EntryTableIndex2 index,LEErrorCode & success)73 le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
74 EntryTableIndex2 index, LEErrorCode &success)
75 {
76 const ContextualGlyphInsertionStateEntry2 *entry = entryTable.getAlias(index, success);
77
78 if(LE_FAILURE(success)) return 0; // TODO- which state?
79
80 le_uint16 newState = SWAPW(entry->newStateIndex);
81 le_uint16 flags = SWAPW(entry->flags);
82
83 le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
84 if (markIndex > 0) {
85 le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
86 le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike);
87 le_bool isBefore = (flags & cgiMarkInsertBefore);
88 doInsertion(glyphStorage, markGlyph, markIndex, count, isKashidaLike, isBefore, success);
89 }
90
91 le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
92 if (currIndex > 0) {
93 le_int16 count = flags & cgiCurrentInsertCountMask;
94 le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike);
95 le_bool isBefore = (flags & cgiCurrentInsertBefore);
96 doInsertion(glyphStorage, currGlyph, currIndex, count, isKashidaLike, isBefore, success);
97 }
98
99 if (flags & cgiSetMark) {
100 markGlyph = currGlyph;
101 }
102
103 if (!(flags & cgiDontAdvance)) {
104 currGlyph += dir;
105 }
106
107 return newState;
108 }
109
endStateTable()110 void ContextualGlyphInsertionProcessor2::endStateTable()
111 {
112 }
113
114 U_NAMESPACE_END
115