]> git.saurik.com Git - apple/icu.git/blame - icuSources/layout/ContextualGlyphInsertionProc2.cpp
ICU-511.35.tar.gz
[apple/icu.git] / icuSources / layout / ContextualGlyphInsertionProc2.cpp
CommitLineData
51004dcb
A
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
17U_NAMESPACE_BEGIN
18
19UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2)
20
21ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
22 : StateTableProcessor2(morphSubtableHeader)
23{
24 contextualGlyphHeader = (const ContextualGlyphInsertionHeader2 *) morphSubtableHeader;
25 le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
26 insertionTable = ((le_uint16 *) ((char *)&stateTableHeader->stHeader + insertionTableOffset));
27 entryTable = (const ContextualGlyphInsertionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
28}
29
30ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2()
31{
32}
33
34void ContextualGlyphInsertionProcessor2::beginStateTable()
35{
36 markGlyph = 0;
37}
38
39le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
40{
41 const ContextualGlyphInsertionStateEntry2 *entry = &entryTable[index];
42 le_uint16 newState = SWAPW(entry->newStateIndex);
43 le_uint16 flags = SWAPW(entry->flags);
44 le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
45 le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
46 int i = 0;
47
48 if (markIndex > 0) {
49 le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
50 if (!(flags & cgiMarkedIsKashidaLike)) {
51 // extra glyph(s) will be added directly before/after the specified marked glyph
52 if (!(flags & cgiMarkInsertBefore)) {
53 LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
54 for (i = 0; i < count; i++, markIndex++) {
55 insertGlyphs[i] = insertionTable[markIndex];
56 }
57 insertGlyphs[i] = glyphStorage[markGlyph];
58 glyphStorage.applyInsertions();
59 } else {
60 LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
61 insertGlyphs[0] = glyphStorage[markGlyph];
62 for (i = 1; i < count + 1; i++, markIndex++) {
63 insertGlyphs[i] = insertionTable[markIndex];
64 }
65 glyphStorage.applyInsertions();
66 }
67 } else {
68 // inserted as a split-vowel-like insertion
69 // extra glyph(s) will be inserted some distance away from the marked glyph
70 if (!(flags & cgiMarkInsertBefore)) {
71 LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
72 for (i = 0; i < count; i++, markIndex++) {
73 insertGlyphs[i] = insertionTable[markIndex];
74 }
75 insertGlyphs[i] = glyphStorage[markGlyph];
76 glyphStorage.applyInsertions();
77 } else {
78 LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
79 insertGlyphs[0] = glyphStorage[markGlyph];
80 for (i = 1; i < count + 1; i++, markIndex++) {
81 insertGlyphs[i] = insertionTable[markIndex];
82 }
83 glyphStorage.applyInsertions();
84 }
85 }
86 }
87
88 if (currIndex > 0) {
89 le_int16 count = flags & cgiCurrentInsertCountMask;
90 if (!(flags & cgiCurrentIsKashidaLike)) {
91 // extra glyph(s) will be added directly before/after the specified current glyph
92 if (!(flags & cgiCurrentInsertBefore)) {
93 LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
94 for (i = 0; i < count; i++, currIndex++) {
95 insertGlyphs[i] = insertionTable[currIndex];
96 }
97 insertGlyphs[i] = glyphStorage[currGlyph];
98 glyphStorage.applyInsertions();
99 } else {
100 LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
101 insertGlyphs[0] = glyphStorage[currGlyph];
102 for (i = 1; i < count + 1; i++, currIndex++) {
103 insertGlyphs[i] = insertionTable[currIndex];
104 }
105 glyphStorage.applyInsertions();
106 }
107 } else {
108 // inserted as a split-vowel-like insertion
109 // extra glyph(s) will be inserted some distance away from the current glyph
110 if (!(flags & cgiCurrentInsertBefore)) {
111 LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
112 for (i = 0; i < count; i++, currIndex++) {
113 insertGlyphs[i] = insertionTable[currIndex];
114 }
115 insertGlyphs[i] = glyphStorage[currGlyph];
116 glyphStorage.applyInsertions();
117 } else {
118 LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
119 insertGlyphs[0] = glyphStorage[currGlyph];
120 for (i = 1; i < count + 1; i++, currIndex++) {
121 insertGlyphs[i] = insertionTable[currIndex];
122 }
123 glyphStorage.applyInsertions();
124 }
125 }
126 }
127
128 if (flags & cgiSetMark) {
129 markGlyph = currGlyph;
130 }
131
132 if (!(flags & cgiDontAdvance)) {
133 currGlyph += dir;
134 }
135
136 return newState;
137}
138
139void ContextualGlyphInsertionProcessor2::endStateTable()
140{
141}
142
143U_NAMESPACE_END