changeset 5890:8a95f38503fe

8008249: Sync ICU into JDK : Reviewed-by: bae, jgodinez
author prr
date Fri, 15 Feb 2013 11:25:43 -0800
parents 3e2d47699a54
children f4718907cb4c
files make/sun/font/FILES_c.gmk src/share/native/sun/font/layout/ContextualGlyphInsertion.h src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.cpp src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.h src/share/native/sun/font/layout/ContextualGlyphSubstProc2.cpp src/share/native/sun/font/layout/ContextualGlyphSubstProc2.h src/share/native/sun/font/layout/ContextualGlyphSubstitution.h src/share/native/sun/font/layout/GXLayoutEngine2.cpp src/share/native/sun/font/layout/GXLayoutEngine2.h src/share/native/sun/font/layout/IndicClassTables.cpp src/share/native/sun/font/layout/IndicRearrangement.h src/share/native/sun/font/layout/IndicRearrangementProcessor2.cpp src/share/native/sun/font/layout/IndicRearrangementProcessor2.h src/share/native/sun/font/layout/IndicReordering.cpp src/share/native/sun/font/layout/IndicReordering.h src/share/native/sun/font/layout/LEFontInstance.h src/share/native/sun/font/layout/LEGlyphFilter.h src/share/native/sun/font/layout/LEInsertionList.h src/share/native/sun/font/layout/LEScripts.h src/share/native/sun/font/layout/LETypes.h src/share/native/sun/font/layout/LayoutEngine.cpp src/share/native/sun/font/layout/LayoutEngine.h src/share/native/sun/font/layout/LigatureSubstProc2.cpp src/share/native/sun/font/layout/LigatureSubstProc2.h src/share/native/sun/font/layout/LigatureSubstitution.h src/share/native/sun/font/layout/LookupProcessor.cpp src/share/native/sun/font/layout/MPreFixups.cpp src/share/native/sun/font/layout/MorphStateTables.h src/share/native/sun/font/layout/MorphTables.h src/share/native/sun/font/layout/MorphTables2.cpp src/share/native/sun/font/layout/NonContextualGlyphSubst.h src/share/native/sun/font/layout/NonContextualGlyphSubstProc2.cpp src/share/native/sun/font/layout/NonContextualGlyphSubstProc2.h src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp src/share/native/sun/font/layout/ScriptAndLanguageTags.cpp src/share/native/sun/font/layout/ScriptAndLanguageTags.h src/share/native/sun/font/layout/SegmentArrayProcessor2.cpp src/share/native/sun/font/layout/SegmentArrayProcessor2.h src/share/native/sun/font/layout/SegmentSingleProcessor2.cpp src/share/native/sun/font/layout/SegmentSingleProcessor2.h src/share/native/sun/font/layout/SimpleArrayProcessor2.cpp src/share/native/sun/font/layout/SimpleArrayProcessor2.h src/share/native/sun/font/layout/SingleTableProcessor2.cpp src/share/native/sun/font/layout/SingleTableProcessor2.h src/share/native/sun/font/layout/StateTableProcessor2.cpp src/share/native/sun/font/layout/StateTableProcessor2.h src/share/native/sun/font/layout/StateTables.h src/share/native/sun/font/layout/SubtableProcessor2.cpp src/share/native/sun/font/layout/SubtableProcessor2.h src/share/native/sun/font/layout/TrimmedArrayProcessor2.cpp src/share/native/sun/font/layout/TrimmedArrayProcessor2.h
diffstat 51 files changed, 3882 insertions(+), 97 deletions(-) [+]
line wrap: on
line diff
--- a/make/sun/font/FILES_c.gmk	Thu Feb 14 19:51:51 2013 +0400
+++ b/make/sun/font/FILES_c.gmk	Fri Feb 15 11:25:43 2013 -0800
@@ -106,7 +106,21 @@
         OpenTypeLayoutEngine.cpp \
         ThaiLayoutEngine.cpp \
         ScriptAndLanguageTags.cpp \
-        FontInstanceAdapter.cpp
+        FontInstanceAdapter.cpp \
+        ContextualGlyphInsertionProc2.cpp \
+        ContextualGlyphSubstProc2.cpp \
+        GXLayoutEngine2.cpp \
+        IndicRearrangementProcessor2.cpp \
+        LigatureSubstProc2.cpp \
+        MorphTables2.cpp \
+        NonContextualGlyphSubstProc2.cpp \
+        SegmentArrayProcessor2.cpp \
+        SegmentSingleProcessor2.cpp \
+        SimpleArrayProcessor2.cpp \
+        SingleTableProcessor2.cpp \
+        StateTableProcessor2.cpp \
+        SubtableProcessor2.cpp \
+        TrimmedArrayProcessor2.cpp
 
 
 ifeq ($(PLATFORM),windows)
--- a/src/share/native/sun/font/layout/ContextualGlyphInsertion.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/ContextualGlyphInsertion.h	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -49,6 +49,11 @@
 {
 };
 
+struct ContextualGlyphInsertionHeader2 : MorphStateTableHeader2
+{
+    le_uint32 insertionTableOffset;
+};
+
 enum ContextualGlyphInsertionFlags
 {
     cgiSetMark                  = 0x8000,
@@ -61,11 +66,17 @@
     cgiMarkedInsertCountMask    = 0x001F
 };
 
-struct LigatureSubstitutionStateEntry : StateEntry
+struct ContextualGlyphInsertionStateEntry : StateEntry
 {
     ByteOffset currentInsertionListOffset;
     ByteOffset markedInsertionListOffset;
 };
 
+struct ContextualGlyphInsertionStateEntry2 : StateEntry2
+{
+    le_uint16 currentInsertionListIndex;
+    le_uint16 markedInsertionListIndex;
+};
+
 U_NAMESPACE_END
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,168 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "StateTables.h"
+#include "MorphStateTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "ContextualGlyphInsertionProc2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2)
+
+ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
+  : StateTableProcessor2(morphSubtableHeader)
+{
+    contextualGlyphHeader = (const ContextualGlyphInsertionHeader2 *) morphSubtableHeader;
+    le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
+    insertionTable = ((le_uint16 *) ((char *)&stateTableHeader->stHeader + insertionTableOffset));
+    entryTable = (const ContextualGlyphInsertionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
+}
+
+ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2()
+{
+}
+
+void ContextualGlyphInsertionProcessor2::beginStateTable()
+{
+    markGlyph = 0;
+}
+
+le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
+{
+    const ContextualGlyphInsertionStateEntry2 *entry = &entryTable[index];
+    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();
+            }
+        }
+    }
+
+    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();
+            }
+        }
+    }
+
+    if (flags & cgiSetMark) {
+        markGlyph = currGlyph;
+    }
+
+    if (!(flags & cgiDontAdvance)) {
+        currGlyph += dir;
+    }
+
+    return newState;
+}
+
+void ContextualGlyphInsertionProcessor2::endStateTable()
+{
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,89 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __CONTEXTUALGLYPHINSERTIONPROCESSOR2_H
+#define __CONTEXTUALGLYPHINSERTIONPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "ContextualGlyphInsertionProc2.h"
+#include "ContextualGlyphInsertion.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class ContextualGlyphInsertionProcessor2 : public StateTableProcessor2
+{
+public:
+    virtual void beginStateTable();
+
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
+
+    virtual void endStateTable();
+
+    ContextualGlyphInsertionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    virtual ~ContextualGlyphInsertionProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+private:
+    ContextualGlyphInsertionProcessor2();
+
+protected:
+    le_int32 markGlyph;
+    const le_uint16* insertionTable;
+    const ContextualGlyphInsertionStateEntry2 *entryTable;
+    const ContextualGlyphInsertionHeader2 *contextualGlyphHeader;
+
+};
+
+U_NAMESPACE_END
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,160 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "StateTables.h"
+#include "MorphStateTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "ContextualGlyphSubstProc2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+#include <stdio.h>
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2)
+
+ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
+  : StateTableProcessor2(morphSubtableHeader)
+{
+    contextualGlyphHeader = (const ContextualGlyphHeader2 *) morphSubtableHeader;
+    le_uint32 perGlyphTableOffset = SWAPL(contextualGlyphHeader->perGlyphTableOffset);
+    perGlyphTable = ((le_uint32 *) ((char *)&stateTableHeader->stHeader + perGlyphTableOffset));
+    entryTable = (const ContextualGlyphStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
+}
+
+ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2()
+{
+}
+
+void ContextualGlyphSubstitutionProcessor2::beginStateTable()
+{
+    markGlyph = 0;
+}
+
+le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
+{
+    const ContextualGlyphStateEntry2 *entry = &entryTable[index];
+    le_uint16 newState = SWAPW(entry->newStateIndex);
+    le_uint16 flags = SWAPW(entry->flags);
+    le_int16 markIndex = SWAPW(entry->markIndex);
+    le_int16 currIndex = SWAPW(entry->currIndex);
+
+    if (markIndex != -1) {
+        le_uint32 offset = SWAPL(perGlyphTable[markIndex]);
+        LEGlyphID mGlyph = glyphStorage[markGlyph];
+        TTGlyphID newGlyph = lookup(offset, mGlyph);
+        glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
+    }
+
+    if (currIndex != -1) {
+        le_uint32 offset = SWAPL(perGlyphTable[currIndex]);
+        LEGlyphID thisGlyph = glyphStorage[currGlyph];
+        TTGlyphID newGlyph = lookup(offset, thisGlyph);
+        glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
+    }
+
+    if (flags & cgsSetMark) {
+        markGlyph = currGlyph;
+    }
+
+    if (!(flags & cgsDontAdvance)) {
+        currGlyph += dir;
+    }
+
+    return newState;
+}
+
+TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid)
+{
+    LookupTable *lookupTable = ((LookupTable *) ((char *)perGlyphTable + offset));
+    le_int16 format = SWAPW(lookupTable->format);
+    TTGlyphID newGlyph = 0xFFFF;
+
+    switch (format) {
+        case ltfSimpleArray: {
+#ifdef TEST_FORMAT
+            // Disabled pending for design review
+            SimpleArrayLookupTable *lookupTable0 = (SimpleArrayLookupTable *) lookupTable;
+            TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
+            newGlyph = SWAPW(lookupTable0->valueArray[glyphCode]);
+#endif
+            break;
+        }
+        case ltfSegmentSingle: {
+#ifdef TEST_FORMAT
+            // Disabled pending for design review
+            SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) lookupTable;
+            const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid);
+            if (segment != NULL) {
+                newGlyph = SWAPW(segment->value);
+            }
+#endif
+            break;
+        }
+        case ltfSegmentArray: {
+            printf("Context Lookup Table Format4: specific interpretation needed!\n");
+            break;
+        }
+        case ltfSingleTable:
+        {
+#ifdef TEST_FORMAT
+            // Disabled pending for design review
+            SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) lookupTable;
+            const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
+            if (segment != NULL) {
+                newGlyph = SWAPW(segment->value);
+            }
+#endif
+            break;
+        }
+        case ltfTrimmedArray: {
+            TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) lookupTable;
+            TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph);
+            TTGlyphID lastGlyph  = firstGlyph + SWAPW(lookupTable8->glyphCount);
+            TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
+            if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) {
+                newGlyph = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]);
+            }
+        }
+        default:
+            break;
+    }
+    return newGlyph;
+}
+
+void ContextualGlyphSubstitutionProcessor2::endStateTable()
+{
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,92 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __CONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H
+#define __CONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "ContextualGlyphSubstitution.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class ContextualGlyphSubstitutionProcessor2 : public StateTableProcessor2
+{
+public:
+    virtual void beginStateTable();
+
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
+
+    virtual void endStateTable();
+
+    ContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    virtual ~ContextualGlyphSubstitutionProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+private:
+    ContextualGlyphSubstitutionProcessor2();
+    TTGlyphID lookup(le_uint32 offset, LEGlyphID gid);
+
+protected:
+    const le_uint32* perGlyphTable;
+    const ContextualGlyphStateEntry2 *entryTable;
+
+    le_int16 perGlyphTableFormat;
+    le_int32 markGlyph;
+
+    const ContextualGlyphHeader2 *contextualGlyphHeader;
+
+};
+
+U_NAMESPACE_END
+#endif
--- a/src/share/native/sun/font/layout/ContextualGlyphSubstitution.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/ContextualGlyphSubstitution.h	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -49,6 +49,11 @@
     ByteOffset  substitutionTableOffset;
 };
 
+struct ContextualGlyphHeader2 : MorphStateTableHeader2
+{
+    le_uint32  perGlyphTableOffset; // no more substitution tables
+};
+
 enum ContextualGlyphSubstitutionFlags
 {
     cgsSetMark      = 0x8000,
@@ -62,5 +67,11 @@
     WordOffset currOffset;
 };
 
+struct ContextualGlyphStateEntry2 : StateEntry2
+{
+    le_uint16 markIndex;
+    le_uint16 currIndex;
+};
+
 U_NAMESPACE_END
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/GXLayoutEngine2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,91 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "LayoutEngine.h"
+#include "GXLayoutEngine2.h"
+#include "LEGlyphStorage.h"
+#include "MorphTables.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine2)
+
+GXLayoutEngine2::GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader2 *morphTable, le_int32 typoFlags, LEErrorCode &success)
+    : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMorphTable(morphTable)
+{
+    // nothing else to do?
+}
+
+GXLayoutEngine2::~GXLayoutEngine2()
+{
+    reset();
+}
+
+// apply 'morx' table
+le_int32 GXLayoutEngine2::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphStorage &glyphStorage, LEErrorCode &success)
+{
+    if (LE_FAILURE(success)) {
+        return 0;
+    }
+
+    if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
+        success = LE_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success);
+
+    if (LE_FAILURE(success)) {
+        return 0;
+    }
+
+    fMorphTable->process(glyphStorage, fTypoFlags);
+    return count;
+}
+
+// apply positional tables
+void GXLayoutEngine2::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/,
+                                          LEGlyphStorage &/*glyphStorage*/, LEErrorCode &success)
+{
+    if (LE_FAILURE(success)) {
+        return;
+    }
+
+    if (chars == NULL || offset < 0 || count < 0) {
+        success = LE_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    // FIXME: no positional processing yet...
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/GXLayoutEngine2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,149 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __GXLAYOUTENGINE2_H
+#define __GXLAYOUTENGINE2_H
+
+#include "LETypes.h"
+#include "LayoutEngine.h"
+
+#include "MorphTables.h"
+
+U_NAMESPACE_BEGIN
+
+class LEFontInstance;
+class LEGlyphStorage;
+
+/**
+ * This class implements layout for QuickDraw GX or Apple Advanced Typograyph (AAT)
+ * fonts. A font is a GX or AAT font if it contains a 'mort' table. See Apple's
+ * TrueType Reference Manual (http://fonts.apple.com/TTRefMan/index.html) for details.
+ * Information about 'mort' tables is in the chapter titled "Font Files."
+ *
+ * @internal
+ */
+class GXLayoutEngine2 : public LayoutEngine
+{
+public:
+    /**
+     * This is the main constructor. It constructs an instance of GXLayoutEngine for
+     * a particular font, script and language. It takes the 'mort' table as a parameter since
+     * LayoutEngine::layoutEngineFactory has to read the 'mort' table to know that it has a
+     * GX font.
+     *
+     * Note: GX and AAT fonts don't contain any script and language specific tables, so
+     * the script and language are ignored.
+     *
+     * @param fontInstance - the font
+     * @param scriptCode - the script
+     * @param langaugeCode - the language
+     * @param morphTable - the 'mort' table
+     * @param success - set to an error code if the operation fails
+     *
+     * @see LayoutEngine::layoutEngineFactory
+     * @see ScriptAndLangaugeTags.h for script and language codes
+     *
+     * @internal
+     */
+    GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader2 *morphTable, le_int32 typoFlags, LEErrorCode &success);
+
+    /**
+     * The destructor, virtual for correct polymorphic invocation.
+     *
+     * @internal
+     */
+    virtual ~GXLayoutEngine2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+protected:
+
+    /**
+     * The address of the 'mort' table
+     *
+     * @internal
+     */
+    const MorphTableHeader2 *fMorphTable;
+
+    /**
+     * This method does GX layout using the font's 'mort' table. It converts the
+     * input character codes to glyph indices using mapCharsToGlyphs, and then
+     * applies the 'mort' table.
+     *
+     * Input parameters:
+     * @param chars - the input character context
+     * @param offset - the index of the first character to process
+     * @param count - the number of characters to process
+     * @param max - the number of characters in the input context
+     * @param rightToLeft - <code>TRUE</code> if the text is in a right to left directional run
+     * @param glyphStorage - the glyph storage object. The glyph and char index arrays will be set.
+     *
+     * Output parameters:
+     * @param success - set to an error code if the operation fails
+     *
+     * @return the number of glyphs in the glyph index array
+     *
+     * @internal
+     */
+    virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
+        LEGlyphStorage &glyphStorage, LEErrorCode &success);
+
+    /**
+     * This method adjusts the glyph positions using the font's
+     * 'kern', 'trak', 'bsln', 'opbd' and 'just' tables.
+     *
+     * Input parameters:
+     * @param glyphStorage - the object holding the glyph storage. The positions will be updated as needed.
+     *
+     * Output parameters:
+     * @param success - set to an error code if the operation fails
+     *
+     * @internal
+     */
+    virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
+                                      LEGlyphStorage &glyphStorage, LEErrorCode &success);
+
+};
+
+U_NAMESPACE_END
+#endif
--- a/src/share/native/sun/font/layout/IndicClassTables.cpp	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/IndicClassTables.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -186,13 +186,15 @@
 };
 
 // FIXME: Should some of the bb's be pb's? (KA, NA, MA, YA, VA, etc. (approx 13))
+// U+C43 and U+C44 are _lm here not _dr.  Similar to the situation with U+CC3 and
+// U+CC4 in Kannada below.
 static const IndicClassTable::CharClass teluCharClasses[] =
 {
     _xx, _mp, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0C00 - 0C0F
     _iv, _xx, _iv, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, // 0C10 - 0C1F
     _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _bb, // 0C20 - 0C2F
     _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _xx, _xx, _da, _da, // 0C30 - 0C3F
-    _da, _dr, _dr, _dr, _dr, _xx, _a1, _da, _s1, _xx, _da, _da, _da, _vr, _xx, _xx, // 0C40 - 0C4F
+    _da, _dr, _dr, _lm, _lm, _xx, _a1, _da, _s1, _xx, _da, _da, _da, _vr, _xx, _xx, // 0C40 - 0C4F
     _xx, _xx, _xx, _xx, _xx, _da, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0C50 - 0C5F
     _iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx  // 0C60 - 0C6F
 };
--- a/src/share/native/sun/font/layout/IndicRearrangement.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/IndicRearrangement.h	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -49,6 +49,10 @@
 {
 };
 
+struct IndicRearrangementSubtableHeader2 : MorphStateTableHeader2
+{
+};
+
 enum IndicRearrangementFlags
 {
     irfMarkFirst    = 0x8000,
@@ -85,6 +89,10 @@
 {
 };
 
+struct IndicRearrangementStateEntry2 : StateEntry2
+{
+};
+
 U_NAMESPACE_END
 #endif
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,423 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "StateTables.h"
+#include "MorphStateTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "IndicRearrangementProcessor2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)
+
+IndicRearrangementProcessor2::IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
+  : StateTableProcessor2(morphSubtableHeader)
+{
+    indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader2 *) morphSubtableHeader;
+    entryTable = (const IndicRearrangementStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
+}
+
+IndicRearrangementProcessor2::~IndicRearrangementProcessor2()
+{
+}
+
+void IndicRearrangementProcessor2::beginStateTable()
+{
+    firstGlyph = 0;
+    lastGlyph = 0;
+}
+
+le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
+{
+    const IndicRearrangementStateEntry2 *entry = &entryTable[index];
+    le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state
+    IndicRearrangementFlags  flags =  (IndicRearrangementFlags) SWAPW(entry->flags);
+
+    if (flags & irfMarkFirst) {
+        firstGlyph = currGlyph;
+    }
+
+    if (flags & irfMarkLast) {
+        lastGlyph = currGlyph;
+    }
+
+    doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask));
+
+    if (!(flags & irfDontAdvance)) {
+        currGlyph += dir;
+    }
+
+    return newState; // index to new state
+}
+
+void IndicRearrangementProcessor2::endStateTable()
+{
+}
+
+void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const
+{
+    LEGlyphID a, b, c, d;
+    le_int32 ia, ib, ic, id, ix, x;
+    LEErrorCode success = LE_NO_ERROR;
+
+    switch(verb)
+    {
+    case irvNoAction:
+        break;
+
+    case irvxA:
+        a = glyphStorage[firstGlyph];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        x = firstGlyph + 1;
+
+        while (x <= lastGlyph) {
+            glyphStorage[x - 1] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x - 1, ix, success);
+            x += 1;
+        }
+
+        glyphStorage[lastGlyph] = a;
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    case irvDx:
+        d = glyphStorage[lastGlyph];
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = lastGlyph - 1;
+
+        while (x >= firstGlyph) {
+            glyphStorage[x + 1] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x + 1, ix, success);
+            x -= 1;
+        }
+
+        glyphStorage[firstGlyph] = d;
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        break;
+
+    case irvDxA:
+        a = glyphStorage[firstGlyph];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        id = glyphStorage.getCharIndex(lastGlyph,  success);
+
+        glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
+        glyphStorage[lastGlyph] = a;
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(lastGlyph,  ia, success);
+        break;
+
+    case irvxAB:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        x = firstGlyph + 2;
+
+        while (x <= lastGlyph) {
+            glyphStorage[x - 2] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x - 2, ix, success);
+            x += 1;
+        }
+
+        glyphStorage[lastGlyph - 1] = a;
+        glyphStorage[lastGlyph] = b;
+
+        glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
+        glyphStorage.setCharIndex(lastGlyph, ib, success);
+        break;
+
+    case irvxBA:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        x = firstGlyph + 2;
+
+        while (x <= lastGlyph) {
+            glyphStorage[x - 2] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x - 2, ix, success);
+            x += 1;
+        }
+
+        glyphStorage[lastGlyph - 1] = b;
+        glyphStorage[lastGlyph] = a;
+
+        glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    case irvCDx:
+        c = glyphStorage[lastGlyph - 1];
+        d = glyphStorage[lastGlyph];
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = lastGlyph - 2;
+
+        while (x >= firstGlyph) {
+            glyphStorage[x + 2] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x + 2, ix, success);
+            x -= 1;
+        }
+
+        glyphStorage[firstGlyph] = c;
+        glyphStorage[firstGlyph + 1] = d;
+
+        glyphStorage.setCharIndex(firstGlyph, ic, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, id, success);
+        break;
+
+    case irvDCx:
+        c = glyphStorage[lastGlyph - 1];
+        d = glyphStorage[lastGlyph];
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = lastGlyph - 2;
+
+        while (x >= firstGlyph) {
+            glyphStorage[x + 2] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x + 2, ix, success);
+            x -= 1;
+        }
+
+        glyphStorage[firstGlyph] = d;
+        glyphStorage[firstGlyph + 1] = c;
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
+        break;
+
+    case irvCDxA:
+        a = glyphStorage[firstGlyph];
+        c = glyphStorage[lastGlyph - 1];
+        d = glyphStorage[lastGlyph];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = lastGlyph - 2;
+
+        while (x > firstGlyph) {
+            glyphStorage[x + 1] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x + 1, ix, success);
+            x -= 1;
+        }
+
+        glyphStorage[firstGlyph] = c;
+        glyphStorage[firstGlyph + 1] = d;
+        glyphStorage[lastGlyph] = a;
+
+        glyphStorage.setCharIndex(firstGlyph, ic, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, id, success);
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    case irvDCxA:
+        a = glyphStorage[firstGlyph];
+        c = glyphStorage[lastGlyph - 1];
+        d = glyphStorage[lastGlyph];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = lastGlyph - 2;
+
+        while (x > firstGlyph) {
+            glyphStorage[x + 1] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x + 1, ix, success);
+            x -= 1;
+        }
+
+        glyphStorage[firstGlyph] = d;
+        glyphStorage[firstGlyph + 1] = c;
+        glyphStorage[lastGlyph] = a;
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    case irvDxAB:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+        d = glyphStorage[lastGlyph];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = firstGlyph + 2;
+
+        while (x < lastGlyph) {
+            glyphStorage[x - 2] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x - 2, ix, success);
+            x += 1;
+        }
+
+        glyphStorage[firstGlyph] = d;
+        glyphStorage[lastGlyph - 1] = a;
+        glyphStorage[lastGlyph] = b;
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
+        glyphStorage.setCharIndex(lastGlyph, ib, success);
+        break;
+
+    case irvDxBA:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+        d = glyphStorage[lastGlyph];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = firstGlyph + 2;
+
+        while (x < lastGlyph) {
+            glyphStorage[x - 2] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x - 2, ix, success);
+            x += 1;
+        }
+
+        glyphStorage[firstGlyph] = d;
+        glyphStorage[lastGlyph - 1] = b;
+        glyphStorage[lastGlyph] = a;
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    case irvCDxAB:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+
+        glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
+        glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
+
+        glyphStorage[lastGlyph - 1] = a;
+        glyphStorage[lastGlyph] = b;
+
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+
+        glyphStorage.setCharIndex(firstGlyph, ic, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, id, success);
+
+        glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
+        glyphStorage.setCharIndex(lastGlyph, ib, success);
+        break;
+
+    case irvCDxBA:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+
+        glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
+        glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
+
+        glyphStorage[lastGlyph - 1] = b;
+        glyphStorage[lastGlyph] = a;
+
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+
+        glyphStorage.setCharIndex(firstGlyph, ic, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, id, success);
+
+        glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    case irvDCxAB:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+
+        glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
+        glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
+
+        glyphStorage[lastGlyph - 1] = a;
+        glyphStorage[lastGlyph] = b;
+
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
+
+        glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
+        glyphStorage.setCharIndex(lastGlyph, ib, success);
+        break;
+
+    case irvDCxBA:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+
+        glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
+        glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
+
+        glyphStorage[lastGlyph - 1] = b;
+        glyphStorage[lastGlyph] = a;
+
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
+
+        glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    default:
+        break;
+    }
+
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,88 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __INDICREARRANGEMENTPROCESSOR2_H
+#define __INDICREARRANGEMENTPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor.h"
+#include "StateTableProcessor2.h"
+#include "IndicRearrangement.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class IndicRearrangementProcessor2 : public StateTableProcessor2
+{
+public:
+    virtual void beginStateTable();
+
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
+
+    virtual void endStateTable();
+
+    void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const;
+
+    IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    virtual ~IndicRearrangementProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+protected:
+    le_int32 firstGlyph;
+    le_int32 lastGlyph;
+
+    const IndicRearrangementStateEntry2 *entryTable;
+    const IndicRearrangementSubtableHeader2 *indicRearrangementSubtableHeader;
+
+};
+
+U_NAMESPACE_END
+#endif
--- a/src/share/native/sun/font/layout/IndicReordering.cpp	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/IndicReordering.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -266,7 +266,7 @@
                                         le_uint32 saveAuxData = fGlyphStorage.getAuxData(i+inv_count,success);
                     const SplitMatra *splitMatra = classTable->getSplitMatra(matraClass);
                     int j;
-                    for (j = 0 ; *(splitMatra)[j] != 0 ; j++) {
+                    for (j = 0 ; j < SM_MAX_PIECES && *(splitMatra)[j] != 0 ; j++) {
                         LEUnicode piece = (*splitMatra)[j];
                                                 if ( j == 0 ) {
                                                         fOutChars[i+inv_count] = piece;
@@ -357,7 +357,7 @@
                 const SplitMatra *splitMatra = classTable->getSplitMatra(matraClass);
                 int i;
 
-                for (i = 0; i < 3 && (*splitMatra)[i] != 0; i += 1) {
+                for (i = 0; i < SM_MAX_PIECES && (*splitMatra)[i] != 0; i += 1) {
                     LEUnicode piece = (*splitMatra)[i];
                     IndicClassTable::CharClass pieceClass = classTable->getCharClass(piece);
 
@@ -1224,7 +1224,6 @@
 
 
     LEUnicode currentChar;
-    LEUnicode virama;
     LEUnicode workChars[2];
     LEGlyphStorage workGlyphs;
 
@@ -1232,14 +1231,17 @@
 
     //le_int32 offset = 0;
 
+#if 0
+// TODO:  Should this section of code have actually been doing something?
     // First find the relevant virama for the script we are dealing with
-
+    LEUnicode virama;
     for ( currentChar = classTable->firstChar ; currentChar <= classTable->lastChar ; currentChar++ ) {
         if ( classTable->isVirama(currentChar)) {
             virama = currentChar;
             break;
         }
     }
+#endif
 
     for ( currentChar = classTable->firstChar ; currentChar <= classTable->lastChar ; currentChar++ ) {
         if ( classTable->isConsonant(currentChar)) {
--- a/src/share/native/sun/font/layout/IndicReordering.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/IndicReordering.h	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -96,7 +96,9 @@
 #define SF_POST_BASE_LIMIT_MASK  0x0000FFFFU
 #define SF_NO_POST_BASE_LIMIT    0x00007FFFU
 
-typedef LEUnicode SplitMatra[3];
+#define SM_MAX_PIECES 3
+
+typedef LEUnicode SplitMatra[SM_MAX_PIECES];
 
 class MPreFixups;
 class LEGlyphStorage;
--- a/src/share/native/sun/font/layout/LEFontInstance.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/LEFontInstance.h	Fri Feb 15 11:25:43 2013 -0800
@@ -190,6 +190,25 @@
      */
     virtual const void *getFontTable(LETag tableTag) const = 0;
 
+    /**
+     * This method reads a table from the font. Note that in general,
+     * it only makes sense to call this method on an <code>LEFontInstance</code>
+     * which represents a physical font - i.e. one which has been returned by
+     * <code>getSubFont()</code>. This is because each subfont in a composite font
+     * will have different tables, and there's no way to know which subfont to access.
+     *
+     * Subclasses which represent composite fonts should always return <code>NULL</code>.
+     *
+     * This version sets a length, for range checking.
+     *
+     * @param tableTag - the four byte table tag. (e.g. 'cmap')
+     * @param length - ignored on entry, on exit will be the length of the table if known, or -1 if unknown.
+     * @return the address of the table in memory, or <code>NULL</code>
+     *         if the table doesn't exist.
+     * @internal
+     */
+    virtual const void* getFontTable(LETag tableTag, size_t &length) const { length=-1; return getFontTable(tableTag); }  /* -1 = unknown length */
+
     virtual void *getKernPairs() const = 0;
     virtual void  setKernPairs(void *pairs) const = 0;
 
--- a/src/share/native/sun/font/layout/LEGlyphFilter.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/LEGlyphFilter.h	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -36,6 +36,7 @@
 
 U_NAMESPACE_BEGIN
 
+#ifndef U_HIDE_INTERNAL_API
 /**
  * This is a helper class that is used to
  * recognize a set of glyph indices.
@@ -63,6 +64,7 @@
      */
     virtual le_bool accept(LEGlyphID glyph) const = 0;
 };
+#endif  /* U_HIDE_INTERNAL_API */
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/LEInsertionList.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/LEInsertionList.h	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  **********************************************************************
- *   Copyright (C) 1998-2008, International Business Machines
+ *   Copyright (C) 1998-2013, International Business Machines
  *   Corporation and others.  All Rights Reserved.
  **********************************************************************
  */
@@ -39,6 +39,7 @@
 
 struct InsertionRecord;
 
+#ifndef U_HIDE_INTERNAL_API
 /**
  * This class encapsulates the callback used by <code>LEInsertionList</code>
  * to apply an insertion from the insertion list.
@@ -194,6 +195,7 @@
      */
     le_bool  append;
 };
+#endif  /* U_HIDE_INTERNAL_API */
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/LEScripts.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/LEScripts.h	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2010. All Rights Reserved.
+ * (C) Copyright IBM Corp. 1998-2013. All Rights Reserved.
  *
  * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
  * YOU REALLY KNOW WHAT YOU'RE DOING.
@@ -241,8 +241,27 @@
     palmScriptCode = 144,
     sindScriptCode = 145,
     waraScriptCode = 146,
+/**
+ * @stable ICU 4.8
+ */
 
-    scriptCodeCount = 147
+    afakScriptCode = 147,
+    jurcScriptCode = 148,
+    mrooScriptCode = 149,
+    nshuScriptCode = 150,
+    shrdScriptCode = 151,
+    soraScriptCode = 152,
+    takrScriptCode = 153,
+    tangScriptCode = 154,
+    woleScriptCode = 155,
+/**
+ * @stable ICU 49
+ */
+
+    khojScriptCode = 156,
+    tirhScriptCode = 157,
+
+    scriptCodeCount = 158
 };
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/LETypes.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/LETypes.h	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -50,14 +50,15 @@
 #endif
 
 #include "unicode/utypes.h"
+
+#ifdef __cplusplus
 #include "unicode/uobject.h"
+#endif
+
 #ifdef LE_USE_CMEMORY
 #include "cmemory.h"
 #endif
-#endif /* not standalone */
-
-
-U_NAMESPACE_BEGIN
+#endif
 
 /*!
  * \file
@@ -296,12 +297,14 @@
  */
 typedef UChar32 LEUnicode32;
 
+#ifndef U_HIDE_DEPRECATED_API
 /**
  * Used to represent 16-bit Unicode code points.
  *
  * @deprecated since ICU 2.4. Use LEUnicode16 instead
  */
 typedef UChar LEUnicode;
+#endif  /* U_HIDE_DEPRECATED_API */
 
 /**
  * Used to hold a pair of (x, y) values which represent a point.
@@ -325,7 +328,7 @@
     float fY;
 };
 
-#ifndef XP_CPLUSPLUS
+#ifndef __cplusplus
 /**
  * Used to hold a pair of (x, y) values which represent a point.
  *
@@ -335,6 +338,7 @@
 #endif
 
 
+#ifndef U_HIDE_INTERNAL_API
 /**
  * A convenience macro to get the length of an array.
  *
@@ -373,7 +377,52 @@
  * @internal
  */
 #define LE_DELETE_ARRAY(array) uprv_free((void *) (array))
-#endif
+#else
+/* !LE_USE_CMEMORY - Not using ICU memory - use C std lib versions */
+
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * A convenience macro to get the length of an array.
+ *
+ * @internal
+ */
+#define LE_ARRAY_SIZE(array) (sizeof array / sizeof array[0])
+
+/**
+ * A convenience macro for copying an array.
+ *
+ * @internal
+ */
+#define LE_ARRAY_COPY(dst, src, count) memcpy((void *) (dst), (void *) (src), (count) * sizeof (src)[0])
+
+/**
+ * Allocate an array of basic types. This is used to isolate the rest of
+ * the LayoutEngine code from cmemory.h.
+ *
+ * @internal
+ */
+#define LE_NEW_ARRAY(type, count) (type *) malloc((count) * sizeof(type))
+
+/**
+ * Re-allocate an array of basic types. This is used to isolate the rest of
+ * the LayoutEngine code from cmemory.h.
+ *
+ * @internal
+ */
+#define LE_GROW_ARRAY(array, newSize) realloc((void *) (array), (newSize) * sizeof (array)[0])
+
+ /**
+ * Free an array of basic types. This is used to isolate the rest of
+ * the LayoutEngine code from cmemory.h.
+ *
+ * @internal
+ */
+#define LE_DELETE_ARRAY(array) free((void *) (array))
+
+#endif  /* LE_USE_CMEMORY */
+#endif  /* U_HIDE_INTERNAL_API */
 
 /**
  * A macro to construct the four-letter tags used to
@@ -536,7 +585,7 @@
     LE_RAND_FEATURE_TAG = 0x72616E64UL, /**< 'rand' */
     LE_RLIG_FEATURE_TAG = 0x726C6967UL, /**< 'rlig' */
     LE_RPHF_FEATURE_TAG = 0x72706866UL, /**< 'rphf' */
-        LE_RKRF_FEATURE_TAG = 0x726B7266UL, /**< 'rkrf' */
+    LE_RKRF_FEATURE_TAG = 0x726B7266UL, /**< 'rkrf' */
     LE_RTBD_FEATURE_TAG = 0x72746264UL, /**< 'rtbd' */
     LE_RTLA_FEATURE_TAG = 0x72746C61UL, /**< 'rtla' */
     LE_RUBY_FEATURE_TAG = 0x72756279UL, /**< 'ruby' */
@@ -588,6 +637,66 @@
 };
 
 /**
+ * @internal
+ */
+enum LEFeatureENUMs {
+  LE_Kerning_FEATURE_ENUM = 0,   /**< Requests Kerning. Formerly LayoutEngine::kTypoFlagKern */
+  LE_Ligatures_FEATURE_ENUM = 1, /**< Requests Ligatures. Formerly LayoutEngine::kTypoFlagLiga */
+  LE_NoCanon_FEATURE_ENUM = 2, /**< Requests No Canonical Processing */
+  LE_CLIG_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_DLIG_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_HLIG_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_LIGA_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_RLIG_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SMCP_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_FRAC_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_AFRC_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_ZERO_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SWSH_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_CSWH_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SALT_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_NALT_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_RUBY_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS01_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS02_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS03_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS04_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS05_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS06_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS07_FEATURE_ENUM,   /**< Feature specific enum */
+
+  LE_CHAR_FILTER_FEATURE_ENUM = 31, /**< Apply CharSubstitutionFilter */
+  LE_FEATURE_ENUM_MAX = LE_CHAR_FILTER_FEATURE_ENUM
+};
+
+#define LE_Kerning_FEATURE_FLAG   (1 << LE_Kerning_FEATURE_ENUM)
+#define LE_Ligatures_FEATURE_FLAG (1 << LE_Ligatures_FEATURE_ENUM)
+#define LE_NoCanon_FEATURE_FLAG (1 << LE_NoCanon_FEATURE_ENUM)
+#define LE_CLIG_FEATURE_FLAG (1 << LE_CLIG_FEATURE_ENUM)
+#define LE_DLIG_FEATURE_FLAG (1 << LE_DLIG_FEATURE_ENUM)
+#define LE_HLIG_FEATURE_FLAG (1 << LE_HLIG_FEATURE_ENUM)
+#define LE_LIGA_FEATURE_FLAG (1 << LE_LIGA_FEATURE_ENUM)
+#define LE_RLIG_FEATURE_FLAG (1 << LE_RLIG_FEATURE_ENUM)
+#define LE_SMCP_FEATURE_FLAG (1 << LE_SMCP_FEATURE_ENUM)
+#define LE_FRAC_FEATURE_FLAG (1 << LE_FRAC_FEATURE_ENUM)
+#define LE_AFRC_FEATURE_FLAG (1 << LE_AFRC_FEATURE_ENUM)
+#define LE_ZERO_FEATURE_FLAG (1 << LE_ZERO_FEATURE_ENUM)
+#define LE_SWSH_FEATURE_FLAG (1 << LE_SWSH_FEATURE_ENUM)
+#define LE_CSWH_FEATURE_FLAG (1 << LE_CSWH_FEATURE_ENUM)
+#define LE_SALT_FEATURE_FLAG (1 << LE_SALT_FEATURE_ENUM)
+#define LE_NALT_FEATURE_FLAG (1 << LE_NALT_FEATURE_ENUM)
+#define LE_RUBY_FEATURE_FLAG (1 << LE_RUBY_FEATURE_ENUM)
+#define LE_SS01_FEATURE_FLAG (1 << LE_SS01_FEATURE_ENUM)
+#define LE_SS02_FEATURE_FLAG (1 << LE_SS02_FEATURE_ENUM)
+#define LE_SS03_FEATURE_FLAG (1 << LE_SS03_FEATURE_ENUM)
+#define LE_SS04_FEATURE_FLAG (1 << LE_SS04_FEATURE_ENUM)
+#define LE_SS05_FEATURE_FLAG (1 << LE_SS05_FEATURE_ENUM)
+#define LE_SS06_FEATURE_FLAG (1 << LE_SS06_FEATURE_ENUM)
+#define LE_SS07_FEATURE_FLAG (1 << LE_SS07_FEATURE_ENUM)
+
+#define LE_CHAR_FILTER_FEATURE_FLAG (1 << LE_CHAR_FILTER_FEATURE_ENUM)
+
+/**
  * Error codes returned by the LayoutEngine.
  *
  * @stable ICU 2.4
@@ -611,7 +720,7 @@
 };
 #endif
 
-#ifndef XP_CPLUSPLUS
+#ifndef __cplusplus
 /**
  * Error codes returned by the LayoutEngine.
  *
@@ -638,7 +747,4 @@
 #define LE_FAILURE(code) (U_FAILURE((UErrorCode)code))
 #endif
 
-U_NAMESPACE_END
-#endif
-
-
+#endif /* __LETYPES_H */
--- a/src/share/native/sun/font/layout/LayoutEngine.cpp	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/LayoutEngine.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -33,6 +33,7 @@
 #include "LETypes.h"
 #include "LEScripts.h"
 #include "LELanguages.h"
+#include "LESwaps.h"
 
 #include "LayoutEngine.h"
 #include "ArabicLayoutEngine.h"
@@ -44,6 +45,8 @@
 #include "ThaiLayoutEngine.h"
 #include "TibetanLayoutEngine.h"
 #include "GXLayoutEngine.h"
+#include "GXLayoutEngine2.h"
+
 #include "ScriptAndLanguageTags.h"
 #include "CharSubstitutionFilter.h"
 
@@ -63,6 +66,10 @@
 /* Leave this copyright notice here! It needs to go somewhere in this library. */
 static const char copyright[] = U_COPYRIGHT_STRING;
 
+/* TODO: remove these? */
+const le_int32 LayoutEngine::kTypoFlagKern = LE_Kerning_FEATURE_FLAG;
+const le_int32 LayoutEngine::kTypoFlagLiga = LE_Ligatures_FEATURE_FLAG;
+
 const LEUnicode32 DefaultCharMapper::controlChars[] = {
     0x0009, 0x000A, 0x000D,
     /*0x200C, 0x200D,*/ 0x200E, 0x200F,
@@ -251,7 +258,7 @@
         return 0;
     }
 
-    if ((fTypoFlags & 0x4) == 0) { // no canonical processing
+    if ((fTypoFlags & LE_NoCanon_FEATURE_FLAG) == 0) { // no canonical processing
       return count;
     }
 
@@ -572,6 +579,7 @@
 {
     static const le_uint32 gsubTableTag = LE_GSUB_TABLE_TAG;
     static const le_uint32 mortTableTag = LE_MORT_TABLE_TAG;
+    static const le_uint32 morxTableTag = LE_MORX_TABLE_TAG;
 
     if (LE_FAILURE(success)) {
         return NULL;
@@ -608,6 +616,11 @@
             result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
             break;
 
+        case hebrScriptCode:
+            // Disable hebrew ligatures since they have only archaic uses, see ticket #8318
+            result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags & ~kTypoFlagLiga, gsubTable, success);
+            break;
+
         case hangScriptCode:
             result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
             break;
@@ -646,26 +659,29 @@
             break;
         }
     } else {
-        const MorphTableHeader *morphTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag);
-
-        if (morphTable != NULL) {
-            result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable, success);
+        MorphTableHeader2 *morxTable = (MorphTableHeader2 *)fontInstance->getFontTable(morxTableTag);
+        if (morxTable != NULL) {
+            result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success);
         } else {
-            switch (scriptCode) {
-            case bengScriptCode:
-            case devaScriptCode:
-            case gujrScriptCode:
-            case kndaScriptCode:
-            case mlymScriptCode:
-            case oryaScriptCode:
-            case guruScriptCode:
-            case tamlScriptCode:
-            case teluScriptCode:
-            case sinhScriptCode:
-            {
-                result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
-                break;
-            }
+            const MorphTableHeader *mortTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag);
+            if (mortTable != NULL) { // mort
+                result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, mortTable, success);
+            } else {
+                switch (scriptCode) {
+                    case bengScriptCode:
+                    case devaScriptCode:
+                    case gujrScriptCode:
+                    case kndaScriptCode:
+                    case mlymScriptCode:
+                    case oryaScriptCode:
+                    case guruScriptCode:
+                    case tamlScriptCode:
+                    case teluScriptCode:
+                    case sinhScriptCode:
+                    {
+                        result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
+                        break;
+                    }
 
             case arabScriptCode:
             //case hebrScriptCode:
@@ -683,9 +699,10 @@
                 result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
                 break;
 
-            default:
-                result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
-                break;
+                    default:
+                        result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
+                        break;
+                }
             }
         }
     }
--- a/src/share/native/sun/font/layout/LayoutEngine.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/LayoutEngine.h	Fri Feb 15 11:25:43 2013 -0800
@@ -26,7 +26,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -90,6 +90,14 @@
  * @stable ICU 2.8
  */
 class U_LAYOUT_API LayoutEngine : public UObject {
+public:
+#ifndef U_HIDE_INTERNAL_API
+    /** @internal Flag to request kerning. Use LE_Kerning_FEATURE_FLAG instead. */
+    static const le_int32 kTypoFlagKern;
+    /** @internal Flag to request ligatures. Use LE_Ligatures_FEATURE_FLAG instead. */
+    static const le_int32 kTypoFlagLiga;
+#endif  /* U_HIDE_INTERNAL_API */
+
 protected:
     /**
      * The object which holds the glyph storage
@@ -140,6 +148,7 @@
      */
     le_bool fFilterZeroWidth;
 
+#ifndef U_HIDE_INTERNAL_API
     /**
      * This constructs an instance for a given font, script and language. Subclass constructors
      * must call this constructor.
@@ -161,7 +170,10 @@
                  le_int32 languageCode,
                  le_int32 typoFlags,
                  LEErrorCode &success);
+#endif  /* U_HIDE_INTERNAL_API */
 
+    // Do not enclose the protected default constructor with #ifndef U_HIDE_INTERNAL_API
+    // or else the compiler will create a public default constructor.
     /**
      * This overrides the default no argument constructor to make it
      * difficult for clients to call it. Clients are expected to call
@@ -302,6 +314,7 @@
      */
     virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
+#ifndef U_HIDE_INTERNAL_API
     /**
      * This is a convenience method that forces the advance width of mark
      * glyphs to be zero, which is required for proper selection and highlighting.
@@ -336,7 +349,7 @@
      * @internal
      */
     static void adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, le_bool reverse, LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success);
-
+#endif  /* U_HIDE_INTERNAL_API */
 
 public:
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/LigatureSubstProc2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,141 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp and Others. 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "StateTables.h"
+#include "MorphStateTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "LigatureSubstProc2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+#define ExtendedComplement(m) ((le_int32) (~((le_uint32) (m))))
+#define SignBit(m) ((ExtendedComplement(m) >> 1) & (le_int32)(m))
+#define SignExtend(v,m) (((v) & SignBit(m))? ((v) | ExtendedComplement(m)): (v))
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor2)
+
+LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
+  : StateTableProcessor2(morphSubtableHeader)
+{
+    ligatureSubstitutionHeader = (const LigatureSubstitutionHeader2 *) morphSubtableHeader;
+    ligActionOffset = SWAPL(ligatureSubstitutionHeader->ligActionOffset);
+    componentOffset = SWAPL(ligatureSubstitutionHeader->componentOffset);
+    ligatureOffset = SWAPL(ligatureSubstitutionHeader->ligatureOffset);
+
+    entryTable = (const LigatureSubstitutionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
+}
+
+LigatureSubstitutionProcessor2::~LigatureSubstitutionProcessor2()
+{
+}
+
+void LigatureSubstitutionProcessor2::beginStateTable()
+{
+    m = -1;
+}
+
+le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
+{
+    const LigatureSubstitutionStateEntry2 *entry = &entryTable[index];
+    le_uint16 nextStateIndex = SWAPW(entry->nextStateIndex);
+    le_uint16 flags = SWAPW(entry->entryFlags);
+    le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex);
+
+    if (flags & lsfSetComponent) {
+        if (++m >= nComponents) {
+            m = 0;
+        }
+        componentStack[m] = currGlyph;
+    }
+
+    ByteOffset actionOffset = flags & lsfPerformAction;
+
+    if (actionOffset != 0) {
+        const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + ligActionOffset) + ligActionIndex;
+        const TTGlyphID *ligatureTable = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + ligatureOffset);
+        LigatureActionEntry action;
+        le_int32 offset, i = 0;
+        le_int32 stack[nComponents];
+        le_int16 mm = -1;
+
+        const le_uint16 *componentTable = (const le_uint16 *)((char *) &ligatureSubstitutionHeader->stHeader + componentOffset);
+
+        do {
+            le_uint32 componentGlyph = componentStack[m--]; // pop off
+
+            action = SWAPL(*ap++);
+
+            if (m < 0) {
+                m = nComponents - 1;
+            }
+
+            offset = action & lafComponentOffsetMask;
+            if (offset != 0) {
+
+                i += SWAPW(componentTable[LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask))]);
+
+                if (action & (lafLast | lafStore))  {
+                    TTGlyphID ligatureGlyph = SWAPW(ligatureTable[i]);
+                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
+                    stack[++mm] = componentGlyph;
+                    i = 0;
+                } else {
+                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
+                }
+            }
+        } while (!(action & lafLast));
+
+        while (mm >= 0) {
+            if (++m >= nComponents) {
+                m = 0;
+            }
+
+            componentStack[m] = stack[mm--];
+        }
+    }
+
+    if (!(flags & lsfDontAdvance)) {
+        currGlyph += dir;
+    }
+
+    return nextStateIndex;
+}
+
+void LigatureSubstitutionProcessor2::endStateTable()
+{
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/LigatureSubstProc2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,96 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __LIGATURESUBSTITUTIONPROCESSOR2_H
+#define __LIGATURESUBSTITUTIONPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "LigatureSubstitution.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+#define nComponents 16
+
+class LigatureSubstitutionProcessor2 : public StateTableProcessor2
+{
+public:
+    virtual void beginStateTable();
+
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
+
+    virtual void endStateTable();
+
+    LigatureSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    virtual ~LigatureSubstitutionProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+private:
+    LigatureSubstitutionProcessor2();
+
+protected:
+    le_uint32 ligActionOffset;
+    le_uint32 componentOffset;
+    le_uint32 ligatureOffset;
+
+    const LigatureSubstitutionStateEntry2 *entryTable;
+
+    le_int32 componentStack[nComponents];
+    le_int16 m;
+
+    const LigatureSubstitutionHeader2 *ligatureSubstitutionHeader;
+
+};
+
+U_NAMESPACE_END
+#endif
--- a/src/share/native/sun/font/layout/LigatureSubstitution.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/LigatureSubstitution.h	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -52,17 +52,32 @@
     ByteOffset ligatureTableOffset;
 };
 
+struct LigatureSubstitutionHeader2 : MorphStateTableHeader2
+{
+    le_uint32 ligActionOffset;
+    le_uint32 componentOffset;
+    le_uint32 ligatureOffset;
+};
+
 enum LigatureSubstitutionFlags
 {
     lsfSetComponent     = 0x8000,
     lsfDontAdvance      = 0x4000,
-    lsfActionOffsetMask = 0x3FFF
+    lsfActionOffsetMask = 0x3FFF, // N/A in morx
+    lsfPerformAction    = 0x2000
 };
 
 struct LigatureSubstitutionStateEntry : StateEntry
 {
 };
 
+struct LigatureSubstitutionStateEntry2
+{
+    le_uint16 nextStateIndex;
+    le_uint16 entryFlags;
+    le_uint16 ligActionIndex;
+};
+
 typedef le_uint32 LigatureActionEntry;
 
 enum LigatureActionFlags
--- a/src/share/native/sun/font/layout/LookupProcessor.cpp	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/LookupProcessor.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -95,10 +95,9 @@
 
         if (selectMask != 0) {
             const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup);
-
-            if (!lookupTable)
+            if (!lookupTable) {
                 continue;
-
+            }
             le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
 
             glyphIterator.reset(lookupFlags, selectMask);
@@ -125,6 +124,10 @@
     }
 
     const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex);
+    if (lookupTable == NULL) {
+        success = LE_INTERNAL_ERROR;
+        return 0;
+    }
     le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
     GlyphIterator tempIterator(*glyphIterator, lookupFlags);
     le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success);
@@ -139,9 +142,9 @@
 
     for (le_uint16 lookup = 0; lookup < lookupCount; lookup += 1) {
         le_uint16 lookupListIndex = SWAPW(featureTable->lookupListIndexArray[lookup]);
-
-        if (lookupListIndex >= lookupSelectCount)
+        if (lookupListIndex >= lookupSelectCount) {
             continue;
+        }
 
         lookupSelectArray[lookupListIndex] |= featureMask;
         lookupOrderArray[store++] = lookupListIndex;
@@ -220,11 +223,15 @@
         le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
 
         featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
+        if (!featureTable) {
+             continue;
+        }
+        featureReferences += SWAPW(featureTable->lookupCount);
+    }
 
-        if (!featureTable)
-            continue;
-
-        featureReferences += SWAPW(featureTable->lookupCount);
+    if (!featureTable) {
+        success = LE_INTERNAL_ERROR;
+        return;
     }
 
     if (requiredFeatureIndex != 0xFFFF) {
--- a/src/share/native/sun/font/layout/MPreFixups.cpp	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/MPreFixups.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 2002-2008 - All Rights Reserved
+ * (C) Copyright IBM Corp. 2002-2013 - All Rights Reserved
  *
  */
 
@@ -65,9 +65,9 @@
     }
 }
 
-void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& leSuccess)
+void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& success)
 {
-    if (LE_FAILURE(leSuccess)) {
+    if (LE_FAILURE(success)) {
         return;
     }
 
--- a/src/share/native/sun/font/layout/MorphStateTables.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/MorphStateTables.h	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -49,5 +49,10 @@
     StateTableHeader stHeader;
 };
 
+struct MorphStateTableHeader2 : MorphSubtableHeader2
+{
+    StateTableHeader2 stHeader;
+};
+
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/MorphTables.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/MorphTables.h	Fri Feb 15 11:25:43 2013 -0800
@@ -76,6 +76,7 @@
 };
 
 typedef le_int16 SubtableCoverage;
+typedef le_uint32 SubtableCoverage2;
 
 enum SubtableCoverageFlags
 {
@@ -105,6 +106,302 @@
     void process(LEGlyphStorage &glyphStorage) const;
 };
 
+enum SubtableCoverageFlags2
+{
+    scfVertical2 = 0x80000000,
+    scfReverse2  = 0x40000000,
+    scfIgnoreVt2 = 0x20000000,
+    scfReserved2 = 0x1FFFFF00,
+    scfTypeMask2 = 0x000000FF
+};
+
+struct MorphSubtableHeader2
+{
+    le_uint32           length;
+    SubtableCoverage2    coverage;
+    FeatureFlags        subtableFeatures;
+
+    void process(LEGlyphStorage &glyphStorage) const;
+};
+
+struct ChainHeader2
+{
+    FeatureFlags        defaultFlags;
+    le_uint32           chainLength;
+    le_uint32           nFeatureEntries;
+    le_uint32           nSubtables;
+    FeatureTableEntry   featureTable[ANY_NUMBER];
+};
+
+struct MorphTableHeader2
+{
+    le_int32    version;
+    le_uint32   nChains;
+    ChainHeader2 chains[ANY_NUMBER];
+
+    void process(LEGlyphStorage &glyphStorage, le_int32 typoFlags) const;
+};
+
+/*
+ * AAT Font Features
+ * source: https://developer.apple.com/fonts/registry/
+ * (plus addition from ATS/SFNTLayoutTypes.h)
+ */
+
+enum {
+
+   allTypographicFeaturesType = 0,
+
+      allTypeFeaturesOnSelector            = 0,
+      allTypeFeaturesOffSelector           = 1,
+
+   ligaturesType = 1,
+
+      requiredLigaturesOnSelector          = 0,
+      requiredLigaturesOffSelector         = 1,
+      commonLigaturesOnSelector            = 2,
+      commonLigaturesOffSelector           = 3,
+      rareLigaturesOnSelector              = 4,
+      rareLigaturesOffSelector             = 5,
+      logosOnSelector                      = 6,
+      logosOffSelector                     = 7,
+      rebusPicturesOnSelector              = 8,
+      rebusPicturesOffSelector             = 9,
+      diphthongLigaturesOnSelector         = 10,
+      diphthongLigaturesOffSelector        = 11,
+      squaredLigaturesOnSelector           = 12,
+      squaredLigaturesOffSelector          = 13,
+      abbrevSquaredLigaturesOnSelector     = 14,
+      abbrevSquaredLigaturesOffSelector    = 15,
+      symbolLigaturesOnSelector            = 16,
+      symbolLigaturesOffSelector           = 17,
+      contextualLigaturesOnSelector        = 18,
+      contextualLigaturesOffSelector       = 19,
+      historicalLigaturesOnSelector        = 20,
+      historicalLigaturesOffSelector       = 21,
+
+   cursiveConnectionType = 2,
+
+      unconnectedSelector                  = 0,
+      partiallyConnectedSelector           = 1,
+      cursiveSelector                      = 2,
+
+   letterCaseType = 3,
+
+      upperAndLowerCaseSelector            = 0,
+      allCapsSelector                      = 1,
+      allLowerCaseSelector                 = 2,
+      smallCapsSelector                    = 3,
+      initialCapsSelector                  = 4,
+      initialCapsAndSmallCapsSelector      = 5,
+
+   verticalSubstitutionType = 4,
+
+      substituteVerticalFormsOnSelector    = 0,
+      substituteVerticalFormsOffSelector   = 1,
+
+   linguisticRearrangementType = 5,
+
+      linguisticRearrangementOnSelector    = 0,
+      linguisticRearrangementOffSelector   = 1,
+
+   numberSpacingType = 6,
+
+      monospacedNumbersSelector            = 0,
+      proportionalNumbersSelector          = 1,
+
+   /*
+   appleReserved1Type = 7,
+   */
+
+   smartSwashType = 8,
+
+      wordInitialSwashesOnSelector         = 0,
+      wordInitialSwashesOffSelector        = 1,
+      wordFinalSwashesOnSelector           = 2,
+      wordFinalSwashesOffSelector          = 3,
+      lineInitialSwashesOnSelector         = 4,
+      lineInitialSwashesOffSelector        = 5,
+      lineFinalSwashesOnSelector           = 6,
+      lineFinalSwashesOffSelector          = 7,
+      nonFinalSwashesOnSelector            = 8,
+      nonFinalSwashesOffSelector           = 9,
+
+   diacriticsType = 9,
+
+      showDiacriticsSelector               = 0,
+      hideDiacriticsSelector               = 1,
+      decomposeDiacriticsSelector          = 2,
+
+   verticalPositionType = 10,
+
+      normalPositionSelector               = 0,
+      superiorsSelector                    = 1,
+      inferiorsSelector                    = 2,
+      ordinalsSelector                     = 3,
+
+   fractionsType = 11,
+
+      noFractionsSelector                  = 0,
+      verticalFractionsSelector            = 1,
+      diagonalFractionsSelector            = 2,
+
+   /*
+   appleReserved2Type = 12,
+   */
+
+   overlappingCharactersType = 13,
+
+      preventOverlapOnSelector             = 0,
+      preventOverlapOffSelector            = 1,
+
+   typographicExtrasType = 14,
+
+      hyphensToEmDashOnSelector            = 0,
+      hyphensToEmDashOffSelector           = 1,
+      hyphenToEnDashOnSelector             = 2,
+      hyphenToEnDashOffSelector            = 3,
+      unslashedZeroOnSelector              = 4,
+      slashedZeroOffSelector               = 4,
+      unslashedZeroOffSelector             = 5,
+      slashedZeroOnSelector                = 5,
+      formInterrobangOnSelector            = 6,
+      formInterrobangOffSelector           = 7,
+      smartQuotesOnSelector                = 8,
+      smartQuotesOffSelector               = 9,
+      periodsToEllipsisOnSelector          = 10,
+      periodsToEllipsisOffSelector         = 11,
+
+   mathematicalExtrasType = 15,
+
+      hyphenToMinusOnSelector              = 0,
+      hyphenToMinusOffSelector             = 1,
+      asteriskToMultiplyOnSelector         = 2,
+      asteriskToMultiplyOffSelector        = 3,
+      slashToDivideOnSelector              = 4,
+      slashToDivideOffSelector             = 5,
+      inequalityLigaturesOnSelector        = 6,
+      inequalityLigaturesOffSelector       = 7,
+      exponentsOnSelector                  = 8,
+      exponentsOffSelector                 = 9,
+
+   ornamentSetsType = 16,
+
+      noOrnamentsSelector                  = 0,
+      dingbatsSelector                     = 1,
+      piCharactersSelector                 = 2,
+      fleuronsSelector                     = 3,
+      decorativeBordersSelector            = 4,
+      internationalSymbolsSelector         = 5,
+      mathSymbolsSelector                  = 6,
+
+   characterAlternativesType = 17,
+
+      noAlternatesSelector                 = 0,
+
+   designComplexityType = 18,
+
+      designLevel1Selector                 = 0,
+      designLevel2Selector                 = 1,
+      designLevel3Selector                 = 2,
+      designLevel4Selector                 = 3,
+      designLevel5Selector                 = 4,
+      designLevel6Selector                 = 5,
+      designLevel7Selector                 = 6,
+
+   styleOptionsType = 19,
+
+      noStyleOptionsSelector               = 0,
+      displayTextSelector                  = 1,
+      engravedTextSelector                 = 2,
+      illuminatedCapsSelector              = 3,
+      titlingCapsSelector                  = 4,
+      tallCapsSelector                     = 5,
+
+   characterShapeType = 20,
+
+      traditionalCharactersSelector        = 0,
+      simplifiedCharactersSelector         = 1,
+      jis1978CharactersSelector            = 2,
+      jis1983CharactersSelector            = 3,
+      jis1990CharactersSelector            = 4,
+      traditionalAltOneSelector            = 5,
+      traditionalAltTwoSelector            = 6,
+      traditionalAltThreeSelector          = 7,
+      traditionalAltFourSelector           = 8,
+      traditionalAltFiveSelector           = 9,
+      expertCharactersSelector             = 10,
+
+   numberCaseType = 21,
+
+      lowerCaseNumbersSelector             = 0,
+      upperCaseNumbersSelector             = 1,
+
+   textSpacingType = 22,
+
+      proportionalTextSelector             = 0,
+      monospacedTextSelector               = 1,
+      halfWidthTextSelector                = 2,
+      normallySpacedTextSelector           = 3,
+
+   transliterationType = 23,
+
+      noTransliterationSelector            = 0,
+      hanjaToHangulSelector                = 1,
+      hiraganaToKatakanaSelector           = 2,
+      katakanaToHiraganaSelector           = 3,
+      kanaToRomanizationSelector           = 4,
+      romanizationToHiraganaSelector       = 5,
+      romanizationToKatakanaSelector       = 6,
+      hanjaToHangulAltOneSelector          = 7,
+      hanjaToHangulAltTwoSelector          = 8,
+      hanjaToHangulAltThreeSelector        = 9,
+
+   annotationType = 24,
+
+      noAnnotationSelector                 = 0,
+      boxAnnotationSelector                = 1,
+      roundedBoxAnnotationSelector         = 2,
+      circleAnnotationSelector             = 3,
+      invertedCircleAnnotationSelector     = 4,
+      parenthesisAnnotationSelector        = 5,
+      periodAnnotationSelector             = 6,
+      romanNumeralAnnotationSelector       = 7,
+      diamondAnnotationSelector            = 8,
+
+   kanaSpacingType = 25,
+
+      fullWidthKanaSelector                = 0,
+      proportionalKanaSelector             = 1,
+
+   ideographicSpacingType = 26,
+
+      fullWidthIdeographsSelector          = 0,
+      proportionalIdeographsSelector       = 1,
+
+   cjkRomanSpacingType = 103,
+
+      halfWidthCJKRomanSelector            = 0,
+      proportionalCJKRomanSelector         = 1,
+      defaultCJKRomanSelector              = 2,
+      fullWidthCJKRomanSelector            = 3,
+
+   rubyKanaType = 28,
+
+      rubyKanaOnSelector                = 2,
+      rubyKanaOffSelector               = 3,
+
+/* The following types are provided for compatibility; note that
+   their use is deprecated. */
+
+   adobeCharacterSpacingType = 100,        /* prefer 22 */
+   adobeKanaSpacingType = 101,             /* prefer 25 */
+   adobeKanjiSpacingType = 102,            /* prefer 26 */
+   adobeSquareLigatures = 104,             /* prefer 1 */
+
+   lastFeatureType = -1
+};
+
 U_NAMESPACE_END
 #endif
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/MorphTables2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,229 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * (C) Copyright IBM Corp. and others 1998 - 2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "LayoutTables.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "IndicRearrangementProcessor2.h"
+#include "ContextualGlyphSubstProc2.h"
+#include "LigatureSubstProc2.h"
+#include "NonContextualGlyphSubstProc2.h"
+#include "ContextualGlyphInsertionProc2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+void MorphTableHeader2::process(LEGlyphStorage &glyphStorage, le_int32 typoFlags) const
+{
+    const ChainHeader2 *chainHeader = chains;
+    le_uint32 chainCount = SWAPL(this->nChains);
+    le_uint32 chain;
+
+    for (chain = 0; chain < chainCount; chain++) {
+        FeatureFlags flag = SWAPL(chainHeader->defaultFlags);
+        le_uint32 chainLength = SWAPL(chainHeader->chainLength);
+        le_uint32 nFeatureEntries = SWAPL(chainHeader->nFeatureEntries);
+        le_uint32 nSubtables = SWAPL(chainHeader->nSubtables);
+        const MorphSubtableHeader2 *subtableHeader =
+            (const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries];
+        le_uint32 subtable;
+
+        if (typoFlags != 0) {
+           le_uint32 featureEntry;
+
+            // Feature subtables
+            for (featureEntry = 0; featureEntry < nFeatureEntries; featureEntry++) {
+                FeatureTableEntry featureTableEntry = chains->featureTable[featureEntry];
+                le_int16 featureType = SWAPW(featureTableEntry.featureType);
+                le_int16 featureSetting = SWAPW(featureTableEntry.featureSetting);
+                le_uint32 enableFlags = SWAPL(featureTableEntry.enableFlags);
+                le_uint32 disableFlags = SWAPL(featureTableEntry.disableFlags);
+                switch (featureType) {
+                    case ligaturesType:
+                        if ((typoFlags & LE_Ligatures_FEATURE_ENUM ) && (featureSetting ^ 0x1)){
+                            flag &= disableFlags;
+                            flag |= enableFlags;
+                        } else {
+                            if (((typoFlags & LE_RLIG_FEATURE_FLAG) && featureSetting == requiredLigaturesOnSelector) ||
+                                ((typoFlags & LE_CLIG_FEATURE_FLAG) && featureSetting == contextualLigaturesOnSelector) ||
+                                ((typoFlags & LE_HLIG_FEATURE_FLAG) && featureSetting == historicalLigaturesOnSelector) ||
+                                ((typoFlags & LE_LIGA_FEATURE_FLAG) && featureSetting == commonLigaturesOnSelector)) {
+                                flag &= disableFlags;
+                                flag |= enableFlags;
+                            }
+                        }
+                        break;
+                    case letterCaseType:
+                        if ((typoFlags & LE_SMCP_FEATURE_FLAG) && featureSetting == smallCapsSelector) {
+                            flag &= disableFlags;
+                            flag |= enableFlags;
+                        }
+                        break;
+                    case verticalSubstitutionType:
+                        break;
+                    case linguisticRearrangementType:
+                        break;
+                    case numberSpacingType:
+                        break;
+                    case smartSwashType:
+                        if ((typoFlags & LE_SWSH_FEATURE_FLAG) && (featureSetting ^ 0x1)){
+                            flag &= disableFlags;
+                            flag |= enableFlags;
+                        }
+                        break;
+                    case diacriticsType:
+                        break;
+                    case verticalPositionType:
+                        break;
+                    case fractionsType:
+                        if (((typoFlags & LE_FRAC_FEATURE_FLAG) && featureSetting == diagonalFractionsSelector) ||
+                            ((typoFlags & LE_AFRC_FEATURE_FLAG) && featureSetting == verticalFractionsSelector)) {
+                            flag &= disableFlags;
+                            flag |= enableFlags;
+                        } else {
+                            flag &= disableFlags;
+                        }
+                        break;
+                    case typographicExtrasType:
+                        if ((typoFlags & LE_ZERO_FEATURE_FLAG) && featureSetting == slashedZeroOnSelector) {
+                            flag &= disableFlags;
+                            flag |= enableFlags;
+                        }
+                        break;
+                    case mathematicalExtrasType:
+                        break;
+                    case ornamentSetsType:
+                        break;
+                    case characterAlternativesType:
+                        break;
+                    case designComplexityType:
+                        if (((typoFlags & LE_SS01_FEATURE_FLAG) && featureSetting == designLevel1Selector) ||
+                            ((typoFlags & LE_SS02_FEATURE_FLAG) && featureSetting == designLevel2Selector) ||
+                            ((typoFlags & LE_SS03_FEATURE_FLAG) && featureSetting == designLevel3Selector) ||
+                            ((typoFlags & LE_SS04_FEATURE_FLAG) && featureSetting == designLevel4Selector) ||
+                            ((typoFlags & LE_SS05_FEATURE_FLAG) && featureSetting == designLevel5Selector) ||
+                            ((typoFlags & LE_SS06_FEATURE_FLAG) && featureSetting == designLevel6Selector) ||
+                            ((typoFlags & LE_SS07_FEATURE_FLAG) && featureSetting == designLevel7Selector)) {
+
+                            flag &= disableFlags;
+                            flag |= enableFlags;
+                        }
+                        break;
+                    case styleOptionsType:
+                        break;
+                    case characterShapeType:
+                        break;
+                    case numberCaseType:
+                        break;
+                    case textSpacingType:
+                        break;
+                    case transliterationType:
+                        break;
+                    case annotationType:
+                        if ((typoFlags & LE_NALT_FEATURE_FLAG) && featureSetting == circleAnnotationSelector) {
+                            flag &= disableFlags;
+                            flag |= enableFlags;
+                        }
+                        break;
+                    case kanaSpacingType:
+                        break;
+                    case ideographicSpacingType:
+                        break;
+                    case rubyKanaType:
+                        if ((typoFlags & LE_RUBY_FEATURE_FLAG) && featureSetting == rubyKanaOnSelector) {
+                            flag &= disableFlags;
+                            flag |= enableFlags;
+                        }
+                        break;
+                    case cjkRomanSpacingType:
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+
+        for (subtable = 0; subtable < nSubtables; subtable++) {
+            le_uint32 length = SWAPL(subtableHeader->length);
+            le_uint32 coverage = SWAPL(subtableHeader->coverage);
+            FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
+            // should check coverage more carefully...
+            if (((coverage & scfIgnoreVt2) || !(coverage & scfVertical2)) && (subtableFeatures & flag) != 0) {
+                subtableHeader->process(glyphStorage);
+            }
+            subtableHeader = (const MorphSubtableHeader2 *) ((char *)subtableHeader + length);
+        }
+        chainHeader = (const ChainHeader2 *)((char *)chainHeader + chainLength);
+    }
+}
+
+void MorphSubtableHeader2::process(LEGlyphStorage &glyphStorage) const
+{
+    SubtableProcessor2 *processor = NULL;
+
+    switch (SWAPL(coverage) & scfTypeMask2)
+    {
+    case mstIndicRearrangement:
+        processor = new IndicRearrangementProcessor2(this);
+        break;
+
+    case mstContextualGlyphSubstitution:
+        processor = new ContextualGlyphSubstitutionProcessor2(this);
+        break;
+
+    case mstLigatureSubstitution:
+        processor = new LigatureSubstitutionProcessor2(this);
+        break;
+
+    case mstReservedUnused:
+        break;
+
+    case mstNonContextualGlyphSubstitution:
+        processor = NonContextualGlyphSubstitutionProcessor2::createInstance(this);
+        break;
+
+
+    case mstContextualGlyphInsertion:
+        processor = new ContextualGlyphInsertionProcessor2(this);
+        break;
+
+    default:
+        break;
+    }
+
+    if (processor != NULL) {
+        processor->process(glyphStorage);
+        delete processor;
+    }
+}
+
+U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/NonContextualGlyphSubst.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/NonContextualGlyphSubst.h	Fri Feb 15 11:25:43 2013 -0800
@@ -26,7 +26,7 @@
 /*
  *
  *
- * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -50,6 +50,11 @@
     LookupTable table;
 };
 
+struct NonContextualGlyphSubstitutionHeader2 : MorphSubtableHeader2
+{
+    LookupTable table;
+};
+
 U_NAMESPACE_END
 #endif
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/NonContextualGlyphSubstProc2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "NonContextualGlyphSubst.h"
+#include "NonContextualGlyphSubstProc2.h"
+#include "SimpleArrayProcessor2.h"
+#include "SegmentSingleProcessor2.h"
+#include "SegmentArrayProcessor2.h"
+#include "SingleTableProcessor2.h"
+#include "TrimmedArrayProcessor2.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcessor2()
+{
+}
+
+NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
+    : SubtableProcessor2(morphSubtableHeader)
+{
+}
+
+NonContextualGlyphSubstitutionProcessor2::~NonContextualGlyphSubstitutionProcessor2()
+{
+}
+
+SubtableProcessor2 *NonContextualGlyphSubstitutionProcessor2::createInstance(const MorphSubtableHeader2 *morphSubtableHeader)
+{
+    const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
+
+    switch (SWAPW(header->table.format))
+    {
+    case ltfSimpleArray:
+        return new SimpleArrayProcessor2(morphSubtableHeader);
+
+    case ltfSegmentSingle:
+        return new SegmentSingleProcessor2(morphSubtableHeader);
+
+    case ltfSegmentArray:
+        return new SegmentArrayProcessor2(morphSubtableHeader);
+
+    case ltfSingleTable:
+        return new SingleTableProcessor2(morphSubtableHeader);
+
+    case ltfTrimmedArray:
+        return new TrimmedArrayProcessor2(morphSubtableHeader);
+
+    default:
+        return NULL;
+    }
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/NonContextualGlyphSubstProc2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,68 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __NONCONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H
+#define __NONCONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "NonContextualGlyphSubst.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class NonContextualGlyphSubstitutionProcessor2 : public SubtableProcessor2
+{
+public:
+    virtual void process(LEGlyphStorage &glyphStorage) = 0;
+
+    static SubtableProcessor2 *createInstance(const MorphSubtableHeader2 *morphSubtableHeader);
+
+protected:
+    NonContextualGlyphSubstitutionProcessor2();
+    NonContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+
+    virtual ~NonContextualGlyphSubstitutionProcessor2();
+
+private:
+    NonContextualGlyphSubstitutionProcessor2(const NonContextualGlyphSubstitutionProcessor2 &other); // forbid copying of this class
+    NonContextualGlyphSubstitutionProcessor2 &operator=(const NonContextualGlyphSubstitutionProcessor2 &other); // forbid copying of this class
+};
+
+U_NAMESPACE_END
+#endif
--- a/src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -26,7 +26,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -64,11 +64,27 @@
 #define loclFeatureTag LE_LOCL_FEATURE_TAG
 #define caltFeatureTag LE_CALT_FEATURE_TAG
 
-// 'dlig' not used at the moment
-#define dligFeatureTag 0x646C6967
+#define dligFeatureTag LE_DLIG_FEATURE_TAG
+#define rligFeatureTag LE_RLIG_FEATURE_TAG
+#define paltFeatureTag LE_PALT_FEATURE_TAG
 
-// 'palt'
-#define paltFeatureTag 0x70616C74
+#define hligFeatureTag LE_HLIG_FEATURE_TAG
+#define smcpFeatureTag LE_SMCP_FEATURE_TAG
+#define fracFeatureTag LE_FRAC_FEATURE_TAG
+#define afrcFeatureTag LE_AFRC_FEATURE_TAG
+#define zeroFeatureTag LE_ZERO_FEATURE_TAG
+#define swshFeatureTag LE_SWSH_FEATURE_TAG
+#define cswhFeatureTag LE_CSWH_FEATURE_TAG
+#define saltFeatureTag LE_SALT_FEATURE_TAG
+#define naltFeatureTag LE_NALT_FEATURE_TAG
+#define rubyFeatureTag LE_RUBY_FEATURE_TAG
+#define ss01FeatureTag LE_SS01_FEATURE_TAG
+#define ss02FeatureTag LE_SS02_FEATURE_TAG
+#define ss03FeatureTag LE_SS03_FEATURE_TAG
+#define ss04FeatureTag LE_SS04_FEATURE_TAG
+#define ss05FeatureTag LE_SS05_FEATURE_TAG
+#define ss06FeatureTag LE_SS06_FEATURE_TAG
+#define ss07FeatureTag LE_SS07_FEATURE_TAG
 
 #define ccmpFeatureMask 0x80000000UL
 #define ligaFeatureMask 0x40000000UL
@@ -80,10 +96,27 @@
 #define loclFeatureMask 0x01000000UL
 #define caltFeatureMask 0x00800000UL
 
+#define dligFeatureMask 0x00400000UL
+#define rligFeatureMask 0x00200000UL
+#define hligFeatureMask 0x00100000UL
+#define smcpFeatureMask 0x00080000UL
+#define fracFeatureMask 0x00040000UL
+#define afrcFeatureMask 0x00020000UL
+#define zeroFeatureMask 0x00010000UL
+#define swshFeatureMask 0x00008000UL
+#define cswhFeatureMask 0x00004000UL
+#define saltFeatureMask 0x00002000UL
+#define naltFeatureMask 0x00001000UL
+#define rubyFeatureMask 0x00000800UL
+#define ss01FeatureMask 0x00000400UL
+#define ss02FeatureMask 0x00000200UL
+#define ss03FeatureMask 0x00000100UL
+#define ss04FeatureMask 0x00000080UL
+#define ss05FeatureMask 0x00000040UL
+#define ss06FeatureMask 0x00000020UL
+#define ss07FeatureMask 0x00000010UL
+
 #define minimalFeatures     (ccmpFeatureMask | markFeatureMask | mkmkFeatureMask | loclFeatureMask | caltFeatureMask)
-#define ligaFeatures        (ligaFeatureMask | cligFeatureMask | minimalFeatures)
-#define kernFeatures        (kernFeatureMask | paltFeatureMask | minimalFeatures)
-#define kernAndLigaFeatures (ligaFeatures    | kernFeatures)
 
 static const FeatureMap featureMap[] =
 {
@@ -95,7 +128,24 @@
     {markFeatureTag, markFeatureMask},
     {mkmkFeatureTag, mkmkFeatureMask},
     {loclFeatureTag, loclFeatureMask},
-    {caltFeatureTag, caltFeatureMask}
+    {caltFeatureTag, caltFeatureMask},
+    {hligFeatureTag, hligFeatureMask},
+    {smcpFeatureTag, smcpFeatureMask},
+    {fracFeatureTag, fracFeatureMask},
+    {afrcFeatureTag, afrcFeatureMask},
+    {zeroFeatureTag, zeroFeatureMask},
+    {swshFeatureTag, swshFeatureMask},
+    {cswhFeatureTag, cswhFeatureMask},
+    {saltFeatureTag, saltFeatureMask},
+    {naltFeatureTag, naltFeatureMask},
+    {rubyFeatureTag, rubyFeatureMask},
+    {ss01FeatureTag, ss01FeatureMask},
+    {ss02FeatureTag, ss02FeatureMask},
+    {ss03FeatureTag, ss03FeatureMask},
+    {ss04FeatureTag, ss04FeatureMask},
+    {ss05FeatureTag, ss05FeatureMask},
+    {ss06FeatureTag, ss06FeatureMask},
+    {ss07FeatureTag, ss07FeatureMask}
 };
 
 static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
@@ -110,17 +160,65 @@
     static const le_uint32 gposTableTag = LE_GPOS_TABLE_TAG;
     const GlyphPositioningTableHeader *gposTable = (const GlyphPositioningTableHeader *) getFontTable(gposTableTag);
 
-    // todo: switch to more flags and bitfield rather than list of feature tags?
-    switch (typoFlags & ~0x80000000L) {
-    case 0: break; // default
-    case 1: fFeatureMask = kernFeatures; break;
-    case 2: fFeatureMask = ligaFeatures; break;
-    case 3: fFeatureMask = kernAndLigaFeatures; break;
-    default: break;
+    switch (typoFlags & (LE_SS01_FEATURE_FLAG
+                         | LE_SS02_FEATURE_FLAG
+                         | LE_SS03_FEATURE_FLAG
+                         | LE_SS04_FEATURE_FLAG
+                         | LE_SS05_FEATURE_FLAG
+                         | LE_SS06_FEATURE_FLAG
+                         | LE_SS07_FEATURE_FLAG)) {
+        case LE_SS01_FEATURE_FLAG:
+            fFeatureMask |= ss01FeatureMask;
+            break;
+        case LE_SS02_FEATURE_FLAG:
+            fFeatureMask |= ss02FeatureMask;
+            break;
+        case LE_SS03_FEATURE_FLAG:
+            fFeatureMask |= ss03FeatureMask;
+            break;
+        case LE_SS04_FEATURE_FLAG:
+            fFeatureMask |= ss04FeatureMask;
+            break;
+        case LE_SS05_FEATURE_FLAG:
+            fFeatureMask |= ss05FeatureMask;
+            break;
+        case LE_SS06_FEATURE_FLAG:
+            fFeatureMask |= ss06FeatureMask;
+            break;
+        case LE_SS07_FEATURE_FLAG:
+            fFeatureMask |= ss07FeatureMask;
+            break;
     }
 
-    if (typoFlags & 0x80000000L) {
-        fSubstitutionFilter = new CharSubstitutionFilter(fontInstance);
+    if (typoFlags & LE_Kerning_FEATURE_FLAG) {
+      fFeatureMask |= (kernFeatureMask | paltFeatureMask);
+      // Convenience.
+    }
+    if (typoFlags & LE_Ligatures_FEATURE_FLAG) {
+      fFeatureMask |= (ligaFeatureMask | cligFeatureMask);
+      // Convenience TODO: should add: .. dligFeatureMask | rligFeatureMask ?
+    }
+    if (typoFlags & LE_CLIG_FEATURE_FLAG) fFeatureMask |= cligFeatureMask;
+    if (typoFlags & LE_DLIG_FEATURE_FLAG) fFeatureMask |= dligFeatureMask;
+    if (typoFlags & LE_HLIG_FEATURE_FLAG) fFeatureMask |= hligFeatureMask;
+    if (typoFlags & LE_LIGA_FEATURE_FLAG) fFeatureMask |= ligaFeatureMask;
+    if (typoFlags & LE_RLIG_FEATURE_FLAG) fFeatureMask |= rligFeatureMask;
+    if (typoFlags & LE_SMCP_FEATURE_FLAG) fFeatureMask |= smcpFeatureMask;
+    if (typoFlags & LE_FRAC_FEATURE_FLAG) fFeatureMask |= fracFeatureMask;
+    if (typoFlags & LE_AFRC_FEATURE_FLAG) fFeatureMask |= afrcFeatureMask;
+    if (typoFlags & LE_ZERO_FEATURE_FLAG) fFeatureMask |= zeroFeatureMask;
+    if (typoFlags & LE_SWSH_FEATURE_FLAG) fFeatureMask |= swshFeatureMask;
+    if (typoFlags & LE_CSWH_FEATURE_FLAG) fFeatureMask |= cswhFeatureMask;
+    if (typoFlags & LE_SALT_FEATURE_FLAG) fFeatureMask |= saltFeatureMask;
+    if (typoFlags & LE_RUBY_FEATURE_FLAG) fFeatureMask |= rubyFeatureMask;
+    if (typoFlags & LE_NALT_FEATURE_FLAG) {
+      // Mutually exclusive with ALL other features. http://www.microsoft.com/typography/otspec/features_ko.htm
+      fFeatureMask = naltFeatureMask;
+    }
+
+    if (typoFlags & LE_CHAR_FILTER_FEATURE_FLAG) {
+      // This isn't a font feature, but requests a Char Substitution Filter
+      fSubstitutionFilter = new CharSubstitutionFilter(fontInstance);
     }
 
     setScriptAndLanguageTags();
@@ -325,7 +423,7 @@
 {
     LEUnicode *outChars = NULL;
     LEGlyphStorage fakeGlyphStorage;
-    le_int32 outCharCount, outGlyphCount, fakeGlyphCount;
+    le_int32 outCharCount, outGlyphCount;
 
     if (LE_FAILURE(success)) {
         return 0;
@@ -343,11 +441,13 @@
     }
 
     if (outChars != NULL) {
-        fakeGlyphCount = glyphProcessing(outChars, 0, outCharCount, outCharCount, rightToLeft, fakeGlyphStorage, success);
+        // le_int32 fakeGlyphCount =
+        glyphProcessing(outChars, 0, outCharCount, outCharCount, rightToLeft, fakeGlyphStorage, success);
         LE_DELETE_ARRAY(outChars); // FIXME: a subclass may have allocated this, in which case this delete might not work...
         //adjustGlyphs(outChars, 0, outCharCount, rightToLeft, fakeGlyphs, fakeGlyphCount);
     } else {
-        fakeGlyphCount = glyphProcessing(chars, offset, count, max, rightToLeft, fakeGlyphStorage, success);
+        // le_int32 fakeGlyphCount =
+        glyphProcessing(chars, offset, count, max, rightToLeft, fakeGlyphStorage, success);
         //adjustGlyphs(chars, offset, count, rightToLeft, fakeGlyphs, fakeGlyphCount);
     }
 
--- a/src/share/native/sun/font/layout/ScriptAndLanguageTags.cpp	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/ScriptAndLanguageTags.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2010. All Rights Reserved.
+ * (C) Copyright IBM Corp. 1998-2013. All Rights Reserved.
  *
  * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
  * YOU REALLY KNOW WHAT YOU'RE DOING.
@@ -186,7 +186,18 @@
     nbatScriptTag, /* 'nbat' (NBAT) */
     palmScriptTag, /* 'palm' (PALM) */
     sindScriptTag, /* 'sind' (SIND) */
-    waraScriptTag  /* 'wara' (WARA) */
+    waraScriptTag, /* 'wara' (WARA) */
+    afakScriptTag, /* 'afak' (AFAK) */
+    jurcScriptTag, /* 'jurc' (JURC) */
+    mrooScriptTag, /* 'mroo' (MROO) */
+    nshuScriptTag, /* 'nshu' (NSHU) */
+    shrdScriptTag, /* 'shrd' (SHARADA) */
+    soraScriptTag, /* 'sora' (SORA_SOMPENG) */
+    takrScriptTag, /* 'takr' (TAKRI) */
+    tangScriptTag, /* 'tang' (TANG) */
+    woleScriptTag, /* 'wole' (WOLE) */
+    khojScriptTag, /* 'khoj' (KHOJ) */
+    tirhScriptTag  /* 'tirh' (TIRH) */
 };
 
 const LETag OpenTypeLayoutEngine::languageTags[] = {
--- a/src/share/native/sun/font/layout/ScriptAndLanguageTags.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/ScriptAndLanguageTags.h	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2010. All Rights Reserved.
+ * (C) Copyright IBM Corp. 1998-2013. All Rights Reserved.
  *
  * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
  * YOU REALLY KNOW WHAT YOU'RE DOING.
@@ -201,6 +201,17 @@
 const LETag palmScriptTag = 0x70616C6D; /* 'palm' (PALM) */
 const LETag sindScriptTag = 0x73696E64; /* 'sind' (SIND) */
 const LETag waraScriptTag = 0x77617261; /* 'wara' (WARA) */
+const LETag afakScriptTag = 0x6166616B; /* 'afak' (AFAK) */
+const LETag jurcScriptTag = 0x6A757263; /* 'jurc' (JURC) */
+const LETag mrooScriptTag = 0x6D726F6F; /* 'mroo' (MROO) */
+const LETag nshuScriptTag = 0x6E736875; /* 'nshu' (NSHU) */
+const LETag shrdScriptTag = 0x73687264; /* 'shrd' (SHARADA) */
+const LETag soraScriptTag = 0x736F7261; /* 'sora' (SORA_SOMPENG) */
+const LETag takrScriptTag = 0x74616B72; /* 'takr' (TAKRI) */
+const LETag tangScriptTag = 0x74616E67; /* 'tang' (TANG) */
+const LETag woleScriptTag = 0x776F6C65; /* 'wole' (WOLE) */
+const LETag khojScriptTag = 0x6B686F6A; /* 'khoj' (KHOJ) */
+const LETag tirhScriptTag = 0x74697268; /* 'tirh' (TIRH) */
 
 const LETag nullScriptTag = 0x00000000; /* ''     (NULL) */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/SegmentArrayProcessor2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "NonContextualGlyphSubst.h"
+#include "NonContextualGlyphSubstProc2.h"
+#include "SegmentArrayProcessor2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SegmentArrayProcessor2)
+
+SegmentArrayProcessor2::SegmentArrayProcessor2()
+{
+}
+
+SegmentArrayProcessor2::SegmentArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
+  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader)
+{
+    const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
+
+    segmentArrayLookupTable = (const SegmentArrayLookupTable *) &header->table;
+}
+
+SegmentArrayProcessor2::~SegmentArrayProcessor2()
+{
+}
+
+void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage)
+{
+    const LookupSegment *segments = segmentArrayLookupTable->segments;
+    le_int32 glyphCount = glyphStorage.getGlyphCount();
+    le_int32 glyph;
+
+    for (glyph = 0; glyph < glyphCount; glyph += 1) {
+        LEGlyphID thisGlyph = glyphStorage[glyph];
+        const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segments, thisGlyph);
+
+        if (lookupSegment != NULL)  {
+            TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph);
+            le_int16  offset = SWAPW(lookupSegment->value);
+
+            if (offset != 0) {
+                TTGlyphID  *glyphArray = (TTGlyphID *) ((char *) subtableHeader + offset);
+                TTGlyphID   newGlyph   = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]);
+
+                glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
+            }
+        }
+    }
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/SegmentArrayProcessor2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,82 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __SEGMENTARRAYPROCESSOR_H
+#define __SEGMENTARRAYPROCESSOR_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "NonContextualGlyphSubst.h"
+#include "NonContextualGlyphSubstProc2.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class SegmentArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2
+{
+public:
+    virtual void process(LEGlyphStorage &glyphStorage);
+
+    SegmentArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+
+    virtual ~SegmentArrayProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+private:
+    SegmentArrayProcessor2();
+
+protected:
+    const SegmentArrayLookupTable *segmentArrayLookupTable;
+
+};
+
+U_NAMESPACE_END
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/SegmentSingleProcessor2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,79 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "NonContextualGlyphSubst.h"
+#include "NonContextualGlyphSubstProc2.h"
+#include "SegmentSingleProcessor2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SegmentSingleProcessor2)
+
+SegmentSingleProcessor2::SegmentSingleProcessor2()
+{
+}
+
+SegmentSingleProcessor2::SegmentSingleProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
+  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader)
+{
+    const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
+
+    segmentSingleLookupTable = (const SegmentSingleLookupTable *) &header->table;
+}
+
+SegmentSingleProcessor2::~SegmentSingleProcessor2()
+{
+}
+
+void SegmentSingleProcessor2::process(LEGlyphStorage &glyphStorage)
+{
+    const LookupSegment *segments = segmentSingleLookupTable->segments;
+    le_int32 glyphCount = glyphStorage.getGlyphCount();
+    le_int32 glyph;
+
+    for (glyph = 0; glyph < glyphCount; glyph += 1) {
+        LEGlyphID thisGlyph = glyphStorage[glyph];
+        const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segments, thisGlyph);
+
+        if (lookupSegment != NULL) {
+            TTGlyphID   newGlyph  = (TTGlyphID) LE_GET_GLYPH(thisGlyph) + SWAPW(lookupSegment->value);
+
+            glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
+        }
+    }
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/SegmentSingleProcessor2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,82 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __SEGMENTSINGLEPROCESSOR_H
+#define __SEGMENTSINGLEPROCESSOR_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "NonContextualGlyphSubst.h"
+#include "NonContextualGlyphSubstProc2.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class SegmentSingleProcessor2 : public NonContextualGlyphSubstitutionProcessor2
+{
+public:
+    virtual void process(LEGlyphStorage &glyphStorage);
+
+    SegmentSingleProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+
+    virtual ~SegmentSingleProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+private:
+    SegmentSingleProcessor2();
+
+protected:
+    const SegmentSingleLookupTable *segmentSingleLookupTable;
+
+};
+
+U_NAMESPACE_END
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/SimpleArrayProcessor2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,76 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "NonContextualGlyphSubst.h"
+#include "NonContextualGlyphSubstProc2.h"
+#include "SimpleArrayProcessor2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleArrayProcessor2)
+
+SimpleArrayProcessor2::SimpleArrayProcessor2()
+{
+}
+
+SimpleArrayProcessor2::SimpleArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
+  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader)
+{
+    const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
+
+    simpleArrayLookupTable = (const SimpleArrayLookupTable *) &header->table;
+}
+
+SimpleArrayProcessor2::~SimpleArrayProcessor2()
+{
+}
+
+void SimpleArrayProcessor2::process(LEGlyphStorage &glyphStorage)
+{
+    le_int32 glyphCount = glyphStorage.getGlyphCount();
+    le_int32 glyph;
+
+    for (glyph = 0; glyph < glyphCount; glyph += 1) {
+        LEGlyphID thisGlyph = glyphStorage[glyph];
+        if (LE_GET_GLYPH(thisGlyph) < 0xFFFF) {
+            TTGlyphID newGlyph = SWAPW(simpleArrayLookupTable->valueArray[LE_GET_GLYPH(thisGlyph)]);
+
+            glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
+        }
+    }
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/SimpleArrayProcessor2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,82 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __SIMPLEARRAYPROCESSOR2_H
+#define __SIMPLEARRAYPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "NonContextualGlyphSubst.h"
+#include "NonContextualGlyphSubstProc2.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class SimpleArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2
+{
+public:
+    virtual void process(LEGlyphStorage &glyphStorage);
+
+    SimpleArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+
+    virtual ~SimpleArrayProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+private:
+    SimpleArrayProcessor2();
+
+protected:
+    const SimpleArrayLookupTable *simpleArrayLookupTable;
+
+};
+
+U_NAMESPACE_END
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/SingleTableProcessor2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,76 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "NonContextualGlyphSubst.h"
+#include "NonContextualGlyphSubstProc2.h"
+#include "SingleTableProcessor2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SingleTableProcessor2)
+
+SingleTableProcessor2::SingleTableProcessor2()
+{
+}
+
+SingleTableProcessor2::SingleTableProcessor2(const MorphSubtableHeader2 *moprhSubtableHeader)
+  : NonContextualGlyphSubstitutionProcessor2(moprhSubtableHeader)
+{
+    const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) moprhSubtableHeader;
+
+    singleTableLookupTable = (const SingleTableLookupTable *) &header->table;
+}
+
+SingleTableProcessor2::~SingleTableProcessor2()
+{
+}
+
+void SingleTableProcessor2::process(LEGlyphStorage &glyphStorage)
+{
+    const LookupSingle *entries = singleTableLookupTable->entries;
+    le_int32 glyph;
+    le_int32 glyphCount = glyphStorage.getGlyphCount();
+
+    for (glyph = 0; glyph < glyphCount; glyph += 1) {
+        const LookupSingle *lookupSingle = singleTableLookupTable->lookupSingle(entries, glyphStorage[glyph]);
+
+        if (lookupSingle != NULL) {
+            glyphStorage[glyph] = SWAPW(lookupSingle->value);
+        }
+    }
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/SingleTableProcessor2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,82 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __SINGLETABLEPROCESSOR2_H
+#define __SINGLETABLEPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "NonContextualGlyphSubst.h"
+#include "NonContextualGlyphSubstProc2.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class SingleTableProcessor2 : public NonContextualGlyphSubstitutionProcessor2
+{
+public:
+    virtual void process(LEGlyphStorage &glyphStorage);
+
+    SingleTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+
+    virtual ~SingleTableProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+private:
+    SingleTableProcessor2();
+
+protected:
+    const SingleTableLookupTable *singleTableLookupTable;
+
+};
+
+U_NAMESPACE_END
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/StateTableProcessor2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,193 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "StateTables.h"
+#include "MorphStateTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+#include "LookupTables.h"
+#include <stdio.h>
+
+U_NAMESPACE_BEGIN
+
+StateTableProcessor2::StateTableProcessor2()
+{
+}
+
+StateTableProcessor2::StateTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
+  : SubtableProcessor2(morphSubtableHeader)
+{
+    stateTableHeader = (const MorphStateTableHeader2 *) morphSubtableHeader;
+    nClasses = SWAPL(stateTableHeader->stHeader.nClasses);
+    classTableOffset = SWAPL(stateTableHeader->stHeader.classTableOffset);
+    stateArrayOffset = SWAPL(stateTableHeader->stHeader.stateArrayOffset);
+    entryTableOffset = SWAPL(stateTableHeader->stHeader.entryTableOffset);
+
+    classTable = (LookupTable *) ((char *) &stateTableHeader->stHeader + classTableOffset);
+    format = SWAPW(classTable->format);
+
+    stateArray = (const EntryTableIndex2 *) ((char *) &stateTableHeader->stHeader + stateArrayOffset);
+}
+
+StateTableProcessor2::~StateTableProcessor2()
+{
+}
+
+void StateTableProcessor2::process(LEGlyphStorage &glyphStorage)
+{
+    // Start at state 0
+    // XXX: How do we know when to start at state 1?
+    le_uint16 currentState = 0;
+    le_int32 glyphCount = glyphStorage.getGlyphCount();
+
+    le_int32 currGlyph = 0;
+    if ((coverage & scfReverse2) != 0) {  // process glyphs in descending order
+        currGlyph = glyphCount - 1;
+        dir = -1;
+    } else {
+        dir = 1;
+    }
+
+    beginStateTable();
+    switch (format) {
+        case ltfSimpleArray: {
+#ifdef TEST_FORMAT
+            SimpleArrayLookupTable *lookupTable0 = (SimpleArrayLookupTable *) classTable;
+            while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
+                LookupValue classCode = classCodeOOB;
+                if (currGlyph == glyphCount || currGlyph == -1) {
+                    // XXX: How do we handle EOT vs. EOL?
+                    classCode = classCodeEOT;
+                } else {
+                    LEGlyphID gid = glyphStorage[currGlyph];
+                    TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
+
+                    if (glyphCode == 0xFFFF) {
+                        classCode = classCodeDEL;
+                    } else {
+                        classCode = SWAPW(lookupTable0->valueArray[gid]);
+                    }
+                }
+                EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
+                currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); // return a zero-based index instead of a byte offset
+            }
+#endif
+            break;
+        }
+        case ltfSegmentSingle: {
+            SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) classTable;
+            while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
+                LookupValue classCode = classCodeOOB;
+                if (currGlyph == glyphCount || currGlyph == -1) {
+                    // XXX: How do we handle EOT vs. EOL?
+                    classCode = classCodeEOT;
+                } else {
+                    LEGlyphID gid = glyphStorage[currGlyph];
+                    TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
+
+                    if (glyphCode == 0xFFFF) {
+                        classCode = classCodeDEL;
+                    } else {
+                        const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid);
+                        if (segment != NULL) {
+                            classCode = SWAPW(segment->value);
+                        }
+                    }
+                }
+                EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
+                currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
+            }
+            break;
+        }
+        case ltfSegmentArray: {
+            printf("Lookup Table Format4: specific interpretation needed!\n");
+            break;
+        }
+        case ltfSingleTable: {
+            SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) classTable;
+            while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
+                LookupValue classCode = classCodeOOB;
+                if (currGlyph == glyphCount || currGlyph == -1) {
+                    // XXX: How do we handle EOT vs. EOL?
+                    classCode = classCodeEOT;
+                } else {
+                    LEGlyphID gid = glyphStorage[currGlyph];
+                    TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
+
+                    if (glyphCode == 0xFFFF) {
+                        classCode = classCodeDEL;
+                    } else {
+                        const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
+                        if (segment != NULL) {
+                            classCode = SWAPW(segment->value);
+                        }
+                    }
+                }
+                EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
+                currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
+            }
+            break;
+        }
+        case ltfTrimmedArray: {
+            TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) classTable;
+            TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph);
+            TTGlyphID lastGlyph  = firstGlyph + SWAPW(lookupTable8->glyphCount);
+
+            while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
+                LookupValue classCode = classCodeOOB;
+                if (currGlyph == glyphCount || currGlyph == -1) {
+                    // XXX: How do we handle EOT vs. EOL?
+                    classCode = classCodeEOT;
+                } else {
+                    TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]);
+                    if (glyphCode == 0xFFFF) {
+                        classCode = classCodeDEL;
+                    } else if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) {
+                        classCode = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]);
+                    }
+                }
+                EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
+                currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
+            }
+            break;
+        }
+        default:
+            break;
+    }
+
+    endStateTable();
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/StateTableProcessor2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,84 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __STATETABLEPROCESSOR2_H
+#define __STATETABLEPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "MorphStateTables.h"
+#include "SubtableProcessor2.h"
+#include "LookupTables.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class StateTableProcessor2 : public SubtableProcessor2
+{
+public:
+    void process(LEGlyphStorage &glyphStorage);
+
+    virtual void beginStateTable() = 0;
+
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index) = 0;
+
+    virtual void endStateTable() = 0;
+
+protected:
+    StateTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    virtual ~StateTableProcessor2();
+
+    StateTableProcessor2();
+
+    le_int32  dir;
+    le_uint16 format;
+    le_uint32 nClasses;
+    le_uint32 classTableOffset;
+    le_uint32 stateArrayOffset;
+    le_uint32 entryTableOffset;
+
+    const LookupTable *classTable;
+    const EntryTableIndex2 *stateArray;
+    const MorphStateTableHeader2 *stateTableHeader;
+
+private:
+    StateTableProcessor2(const StateTableProcessor2 &other); // forbid copying of this class
+    StateTableProcessor2 &operator=(const StateTableProcessor2 &other); // forbid copying of this class
+};
+
+U_NAMESPACE_END
+#endif
--- a/src/share/native/sun/font/layout/StateTables.h	Thu Feb 14 19:51:51 2013 +0400
+++ b/src/share/native/sun/font/layout/StateTables.h	Fri Feb 15 11:25:43 2013 -0800
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -50,6 +50,14 @@
     ByteOffset entryTableOffset;
 };
 
+struct StateTableHeader2
+{
+    le_uint32 nClasses;
+    le_uint32 classTableOffset;
+    le_uint32 stateArrayOffset;
+    le_uint32 entryTableOffset;
+};
+
 enum ClassCodes
 {
     classCodeEOT = 0,
@@ -85,6 +93,14 @@
     le_int16    flags;
 };
 
+typedef le_uint16 EntryTableIndex2;
+
+struct StateEntry2 // same struct different interpretation
+{
+    le_uint16    newStateIndex;
+    le_uint16    flags;
+};
+
 U_NAMESPACE_END
 #endif
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/SubtableProcessor2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,56 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+SubtableProcessor2::SubtableProcessor2()
+{
+}
+
+SubtableProcessor2::SubtableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
+{
+    subtableHeader = morphSubtableHeader;
+
+    length = SWAPL(subtableHeader->length);
+    coverage = SWAPL(subtableHeader->coverage);
+    subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
+}
+
+SubtableProcessor2::~SubtableProcessor2()
+{
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/SubtableProcessor2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,70 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __SUBTABLEPROCESSOR2_H
+#define __SUBTABLEPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class SubtableProcessor2 : public UMemory {
+public:
+    virtual void process(LEGlyphStorage &glyphStorage) = 0;
+    virtual ~SubtableProcessor2();
+
+protected:
+    SubtableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+
+    SubtableProcessor2();
+
+    le_uint32 length;
+    SubtableCoverage2 coverage;
+    FeatureFlags subtableFeatures;
+
+    const MorphSubtableHeader2 *subtableHeader;
+
+private:
+
+    SubtableProcessor2(const SubtableProcessor2 &other); // forbid copying of this class
+    SubtableProcessor2 &operator=(const SubtableProcessor2 &other); // forbid copying of this class
+};
+
+U_NAMESPACE_END
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/TrimmedArrayProcessor2.cpp	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,80 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "NonContextualGlyphSubst.h"
+#include "NonContextualGlyphSubstProc2.h"
+#include "TrimmedArrayProcessor2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TrimmedArrayProcessor2)
+
+TrimmedArrayProcessor2::TrimmedArrayProcessor2()
+{
+}
+
+TrimmedArrayProcessor2::TrimmedArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
+  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader)
+{
+    const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
+
+    trimmedArrayLookupTable = (const TrimmedArrayLookupTable *) &header->table;
+    firstGlyph = SWAPW(trimmedArrayLookupTable->firstGlyph);
+    lastGlyph = firstGlyph + SWAPW(trimmedArrayLookupTable->glyphCount);
+}
+
+TrimmedArrayProcessor2::~TrimmedArrayProcessor2()
+{
+}
+
+void TrimmedArrayProcessor2::process(LEGlyphStorage &glyphStorage)
+{
+    le_int32 glyphCount = glyphStorage.getGlyphCount();
+    le_int32 glyph;
+
+    for (glyph = 0; glyph < glyphCount; glyph += 1) {
+        LEGlyphID thisGlyph = glyphStorage[glyph];
+        TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph);
+
+        if ((ttGlyph > firstGlyph) && (ttGlyph < lastGlyph)) {
+            TTGlyphID newGlyph = SWAPW(trimmedArrayLookupTable->valueArray[ttGlyph - firstGlyph]);
+
+            glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
+        }
+    }
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/TrimmedArrayProcessor2.h	Fri Feb 15 11:25:43 2013 -0800
@@ -0,0 +1,84 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __TRIMMEDARRAYPROCESSOR2_H
+#define __TRIMMEDARRAYPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "NonContextualGlyphSubst.h"
+#include "NonContextualGlyphSubstProc2.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class TrimmedArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2
+{
+public:
+    virtual void process(LEGlyphStorage &glyphStorage);
+
+    TrimmedArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+
+    virtual ~TrimmedArrayProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+private:
+    TrimmedArrayProcessor2();
+
+protected:
+    TTGlyphID firstGlyph;
+    TTGlyphID lastGlyph;
+    const TrimmedArrayLookupTable *trimmedArrayLookupTable;
+
+};
+
+U_NAMESPACE_END
+#endif