--- a/jdk/src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.cpp Tue Feb 26 10:07:26 2013 -0800
+++ b/jdk/src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.cpp Thu Mar 07 10:02:20 2013 -0800
@@ -43,13 +43,15 @@
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2)
-ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
- : StateTableProcessor2(morphSubtableHeader)
+ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(
+ const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+ : StateTableProcessor2(morphSubtableHeader, success)
{
- contextualGlyphHeader = (const ContextualGlyphInsertionHeader2 *) morphSubtableHeader;
- le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
- insertionTable = ((le_uint16 *) ((char *)&stateTableHeader->stHeader + insertionTableOffset));
- entryTable = (const ContextualGlyphInsertionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
+ contextualGlyphHeader = LEReferenceTo<ContextualGlyphInsertionHeader2>(morphSubtableHeader, success);
+ if(LE_FAILURE(success) || !contextualGlyphHeader.isValid()) return;
+ le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
+ insertionTable = LEReferenceToArrayOf<le_uint16>(stHeader, success, insertionTableOffset, LE_UNBOUNDED_ARRAY);
+ entryTable = LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
}
ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2()
@@ -61,93 +63,62 @@
markGlyph = 0;
}
-le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
+void ContextualGlyphInsertionProcessor2::doInsertion(LEGlyphStorage &glyphStorage,
+ le_int16 atGlyph,
+ le_int16 &index,
+ le_int16 count,
+ le_bool /* isKashidaLike */,
+ le_bool isBefore,
+ LEErrorCode &success) {
+ LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(atGlyph, count + 1, success);
+
+ if(LE_FAILURE(success) || insertGlyphs==NULL) {
+ return;
+ }
+
+ // Note: Kashida vs Split Vowel seems to only affect selection and highlighting.
+ // We note the flag, but do not layout different.
+ // https://developer.apple.com/fonts/TTRefMan/RM06/Chap6mort.html
+
+ le_int16 targetIndex = 0;
+ if(isBefore) {
+ // insert at beginning
+ insertGlyphs[targetIndex++] = glyphStorage[atGlyph];
+ } else {
+ // insert at end
+ insertGlyphs[count] = glyphStorage[atGlyph];
+ }
+
+ while(count--) {
+ insertGlyphs[targetIndex++] = insertionTable.getObject(index++, success);
+ }
+ glyphStorage.applyInsertions();
+}
+
+le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
+ EntryTableIndex2 index, LEErrorCode &success)
{
- const ContextualGlyphInsertionStateEntry2 *entry = &entryTable[index];
+ const ContextualGlyphInsertionStateEntry2 *entry = entryTable.getAlias(index, success);
+
+ if(LE_FAILURE(success)) return 0; // TODO- which state?
+
le_uint16 newState = SWAPW(entry->newStateIndex);
le_uint16 flags = SWAPW(entry->flags);
- le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
+
le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
- int i = 0;
-
if (markIndex > 0) {
le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
- if (!(flags & cgiMarkedIsKashidaLike)) {
- // extra glyph(s) will be added directly before/after the specified marked glyph
- if (!(flags & cgiMarkInsertBefore)) {
- LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
- for (i = 0; i < count; i++, markIndex++) {
- insertGlyphs[i] = insertionTable[markIndex];
- }
- insertGlyphs[i] = glyphStorage[markGlyph];
- glyphStorage.applyInsertions();
- } else {
- LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
- insertGlyphs[0] = glyphStorage[markGlyph];
- for (i = 1; i < count + 1; i++, markIndex++) {
- insertGlyphs[i] = insertionTable[markIndex];
- }
- glyphStorage.applyInsertions();
- }
- } else {
- // inserted as a split-vowel-like insertion
- // extra glyph(s) will be inserted some distance away from the marked glyph
- if (!(flags & cgiMarkInsertBefore)) {
- LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
- for (i = 0; i < count; i++, markIndex++) {
- insertGlyphs[i] = insertionTable[markIndex];
- }
- insertGlyphs[i] = glyphStorage[markGlyph];
- glyphStorage.applyInsertions();
- } else {
- LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
- insertGlyphs[0] = glyphStorage[markGlyph];
- for (i = 1; i < count + 1; i++, markIndex++) {
- insertGlyphs[i] = insertionTable[markIndex];
- }
- glyphStorage.applyInsertions();
- }
- }
+ le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike);
+ le_bool isBefore = (flags & cgiMarkInsertBefore);
+ doInsertion(glyphStorage, markGlyph, markIndex, count, isKashidaLike, isBefore, success);
}
+ le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
if (currIndex > 0) {
le_int16 count = flags & cgiCurrentInsertCountMask;
- if (!(flags & cgiCurrentIsKashidaLike)) {
- // extra glyph(s) will be added directly before/after the specified current glyph
- if (!(flags & cgiCurrentInsertBefore)) {
- LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
- for (i = 0; i < count; i++, currIndex++) {
- insertGlyphs[i] = insertionTable[currIndex];
- }
- insertGlyphs[i] = glyphStorage[currGlyph];
- glyphStorage.applyInsertions();
- } else {
- LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
- insertGlyphs[0] = glyphStorage[currGlyph];
- for (i = 1; i < count + 1; i++, currIndex++) {
- insertGlyphs[i] = insertionTable[currIndex];
- }
- glyphStorage.applyInsertions();
- }
- } else {
- // inserted as a split-vowel-like insertion
- // extra glyph(s) will be inserted some distance away from the current glyph
- if (!(flags & cgiCurrentInsertBefore)) {
- LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
- for (i = 0; i < count; i++, currIndex++) {
- insertGlyphs[i] = insertionTable[currIndex];
- }
- insertGlyphs[i] = glyphStorage[currGlyph];
- glyphStorage.applyInsertions();
- } else {
- LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
- insertGlyphs[0] = glyphStorage[currGlyph];
- for (i = 1; i < count + 1; i++, currIndex++) {
- insertGlyphs[i] = insertionTable[currIndex];
- }
- glyphStorage.applyInsertions();
- }
- }
+ le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike);
+ le_bool isBefore = (flags & cgiCurrentInsertBefore);
+ doInsertion(glyphStorage, currGlyph, currIndex, count, isKashidaLike, isBefore, success);
}
if (flags & cgiSetMark) {