changeset 5979:245c2dce7225

8001031: Better font processing. Reviewed-by: vadim, prr, mschoene
author srl
date Mon, 04 Mar 2013 12:29:30 -0800
parents 4f7b8bc95616
children af6be9d7aed7
files src/share/native/sun/font/FontInstanceAdapter.cpp src/share/native/sun/font/FontInstanceAdapter.h src/share/native/sun/font/fontscalerdefs.h src/share/native/sun/font/layout/AlternateSubstSubtables.cpp src/share/native/sun/font/layout/AlternateSubstSubtables.h src/share/native/sun/font/layout/ArabicLayoutEngine.cpp src/share/native/sun/font/layout/ArabicLayoutEngine.h src/share/native/sun/font/layout/ArabicShaping.cpp src/share/native/sun/font/layout/ArabicShaping.h src/share/native/sun/font/layout/AttachmentPosnSubtables.h src/share/native/sun/font/layout/CanonData.cpp src/share/native/sun/font/layout/CanonShaping.cpp src/share/native/sun/font/layout/CanonShaping.h src/share/native/sun/font/layout/ClassDefinitionTables.cpp src/share/native/sun/font/layout/ClassDefinitionTables.h src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.cpp src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.h src/share/native/sun/font/layout/ContextualGlyphSubstProc.cpp src/share/native/sun/font/layout/ContextualGlyphSubstProc.h src/share/native/sun/font/layout/ContextualGlyphSubstProc2.cpp src/share/native/sun/font/layout/ContextualGlyphSubstProc2.h src/share/native/sun/font/layout/ContextualSubstSubtables.cpp src/share/native/sun/font/layout/ContextualSubstSubtables.h src/share/native/sun/font/layout/CoverageTables.h src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp src/share/native/sun/font/layout/CursiveAttachmentSubtables.h src/share/native/sun/font/layout/DeviceTables.h src/share/native/sun/font/layout/ExtensionSubtables.cpp src/share/native/sun/font/layout/Features.cpp src/share/native/sun/font/layout/GDEFMarkFilter.cpp src/share/native/sun/font/layout/GDEFMarkFilter.h src/share/native/sun/font/layout/GXLayoutEngine.cpp src/share/native/sun/font/layout/GXLayoutEngine.h src/share/native/sun/font/layout/GXLayoutEngine2.cpp src/share/native/sun/font/layout/GXLayoutEngine2.h src/share/native/sun/font/layout/GlyphDefinitionTables.cpp src/share/native/sun/font/layout/GlyphDefinitionTables.h src/share/native/sun/font/layout/GlyphIterator.cpp src/share/native/sun/font/layout/GlyphIterator.h src/share/native/sun/font/layout/GlyphLookupTables.cpp src/share/native/sun/font/layout/GlyphLookupTables.h src/share/native/sun/font/layout/GlyphPositioningTables.cpp src/share/native/sun/font/layout/GlyphPositioningTables.h src/share/native/sun/font/layout/GlyphPosnLookupProc.cpp src/share/native/sun/font/layout/GlyphPosnLookupProc.h src/share/native/sun/font/layout/GlyphSubstLookupProc.cpp src/share/native/sun/font/layout/GlyphSubstLookupProc.h src/share/native/sun/font/layout/GlyphSubstitutionTables.cpp src/share/native/sun/font/layout/GlyphSubstitutionTables.h src/share/native/sun/font/layout/HanLayoutEngine.cpp src/share/native/sun/font/layout/HanLayoutEngine.h src/share/native/sun/font/layout/HangulLayoutEngine.cpp src/share/native/sun/font/layout/HangulLayoutEngine.h src/share/native/sun/font/layout/ICUFeatures.h src/share/native/sun/font/layout/IndicLayoutEngine.cpp src/share/native/sun/font/layout/IndicLayoutEngine.h src/share/native/sun/font/layout/IndicRearrangementProcessor.cpp src/share/native/sun/font/layout/IndicRearrangementProcessor.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/KernTable.cpp src/share/native/sun/font/layout/KernTable.h src/share/native/sun/font/layout/KhmerLayoutEngine.cpp src/share/native/sun/font/layout/KhmerLayoutEngine.h src/share/native/sun/font/layout/LEScripts.h src/share/native/sun/font/layout/LETableReference.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/LigatureSubstProc.cpp src/share/native/sun/font/layout/LigatureSubstProc.h src/share/native/sun/font/layout/LigatureSubstProc2.cpp src/share/native/sun/font/layout/LigatureSubstProc2.h src/share/native/sun/font/layout/LigatureSubstSubtables.cpp src/share/native/sun/font/layout/LigatureSubstSubtables.h src/share/native/sun/font/layout/LookupProcessor.cpp src/share/native/sun/font/layout/LookupProcessor.h src/share/native/sun/font/layout/LookupTables.cpp src/share/native/sun/font/layout/LookupTables.h src/share/native/sun/font/layout/Lookups.cpp src/share/native/sun/font/layout/Lookups.h src/share/native/sun/font/layout/MarkArrays.h src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp src/share/native/sun/font/layout/MarkToBasePosnSubtables.h src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.h src/share/native/sun/font/layout/MarkToMarkPosnSubtables.cpp src/share/native/sun/font/layout/MarkToMarkPosnSubtables.h src/share/native/sun/font/layout/MorphTables.cpp src/share/native/sun/font/layout/MorphTables.h src/share/native/sun/font/layout/MorphTables2.cpp src/share/native/sun/font/layout/MultipleSubstSubtables.cpp src/share/native/sun/font/layout/MultipleSubstSubtables.h src/share/native/sun/font/layout/NonContextualGlyphSubstProc.cpp src/share/native/sun/font/layout/NonContextualGlyphSubstProc.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/OpenTypeLayoutEngine.h src/share/native/sun/font/layout/OpenTypeTables.h src/share/native/sun/font/layout/OpenTypeUtilities.cpp src/share/native/sun/font/layout/OpenTypeUtilities.h src/share/native/sun/font/layout/PairPositioningSubtables.cpp src/share/native/sun/font/layout/PairPositioningSubtables.h src/share/native/sun/font/layout/ScriptAndLanguage.cpp src/share/native/sun/font/layout/ScriptAndLanguage.h src/share/native/sun/font/layout/SegmentArrayProcessor.cpp src/share/native/sun/font/layout/SegmentArrayProcessor.h src/share/native/sun/font/layout/SegmentArrayProcessor2.cpp src/share/native/sun/font/layout/SegmentArrayProcessor2.h src/share/native/sun/font/layout/SegmentSingleProcessor.cpp src/share/native/sun/font/layout/SegmentSingleProcessor.h src/share/native/sun/font/layout/SegmentSingleProcessor2.cpp src/share/native/sun/font/layout/SegmentSingleProcessor2.h src/share/native/sun/font/layout/ShapingTypeData.cpp src/share/native/sun/font/layout/SimpleArrayProcessor.cpp src/share/native/sun/font/layout/SimpleArrayProcessor.h src/share/native/sun/font/layout/SimpleArrayProcessor2.cpp src/share/native/sun/font/layout/SimpleArrayProcessor2.h src/share/native/sun/font/layout/SinglePositioningSubtables.cpp src/share/native/sun/font/layout/SinglePositioningSubtables.h src/share/native/sun/font/layout/SingleSubstitutionSubtables.cpp src/share/native/sun/font/layout/SingleSubstitutionSubtables.h src/share/native/sun/font/layout/SingleTableProcessor.cpp src/share/native/sun/font/layout/SingleTableProcessor.h src/share/native/sun/font/layout/SingleTableProcessor2.cpp src/share/native/sun/font/layout/SingleTableProcessor2.h src/share/native/sun/font/layout/StateTableProcessor.cpp src/share/native/sun/font/layout/StateTableProcessor.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/SubtableProcessor.cpp src/share/native/sun/font/layout/SubtableProcessor.h src/share/native/sun/font/layout/SubtableProcessor2.cpp src/share/native/sun/font/layout/SubtableProcessor2.h src/share/native/sun/font/layout/ThaiLayoutEngine.cpp src/share/native/sun/font/layout/TibetanLayoutEngine.cpp src/share/native/sun/font/layout/TibetanLayoutEngine.h src/share/native/sun/font/layout/TrimmedArrayProcessor.cpp src/share/native/sun/font/layout/TrimmedArrayProcessor.h src/share/native/sun/font/layout/TrimmedArrayProcessor2.cpp src/share/native/sun/font/layout/TrimmedArrayProcessor2.h src/share/native/sun/font/layout/ValueRecords.h src/share/native/sun/font/sunFont.c
diffstat 146 files changed, 1915 insertions(+), 1035 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/native/sun/font/FontInstanceAdapter.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/FontInstanceAdapter.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -66,8 +66,21 @@
     yScalePixelsToUnits = upem / yppem;
 };
 
+
 const void *FontInstanceAdapter::getFontTable(LETag tableTag) const
 {
+  size_t ignored = 0;
+  return getFontTable(tableTag, ignored);
+}
+
+static const LETag cacheMap[LAYOUTCACHE_ENTRIES] = {
+  GPOS_TAG, GDEF_TAG, GSUB_TAG, MORT_TAG, MORX_TAG, KERN_TAG
+};
+
+const void *FontInstanceAdapter::getFontTable(LETag tableTag, size_t &length) const
+{
+  length = 0;
+
   if (!layoutTables) { // t1 font
     return 0;
   }
@@ -75,14 +88,19 @@
   // cache in font's pscaler object
   // font disposer will handle for us
 
-  switch(tableTag) {
-  case GSUB_TAG: if (layoutTables->gsub_len != -1) return (void*)layoutTables->gsub; break;
-  case GPOS_TAG: if (layoutTables->gpos_len != -1) return (void*)layoutTables->gpos; break;
-  case GDEF_TAG: if (layoutTables->gdef_len != -1) return (void*)layoutTables->gdef; break;
-  case MORT_TAG: if (layoutTables->mort_len != -1) return (void*)layoutTables->mort; break;
-  case KERN_TAG: if (layoutTables->kern_len != -1) return (void*)layoutTables->kern; break;
-  default:
-   //fprintf(stderr, "unexpected table request from font instance adapter: %x\n", tableTag);
+  int cacheIdx;
+  for (cacheIdx=0;cacheIdx<LAYOUTCACHE_ENTRIES;cacheIdx++) {
+    if (tableTag==cacheMap[cacheIdx]) break;
+  }
+
+  if (cacheIdx<LAYOUTCACHE_ENTRIES) { // if found
+    if (layoutTables->entries[cacheIdx].len != -1) {
+      length = layoutTables->entries[cacheIdx].len;
+      return layoutTables->entries[cacheIdx].ptr;
+    }
+  } else {
+    //fprintf(stderr, "unexpected table request from font instance adapter: %x\n", tableTag);
+    // (don't load any other tables)
     return 0;
   }
 
@@ -96,16 +114,13 @@
     env->GetByteArrayRegion(tableBytes, 0, len, result);
   }
 
-  switch(tableTag) {
-  case GSUB_TAG: layoutTables->gsub = (void*)result; layoutTables->gsub_len = len; break;
-  case GPOS_TAG: layoutTables->gpos = (void*)result; layoutTables->gpos_len = len; break;
-  case GDEF_TAG: layoutTables->gdef = (void*)result; layoutTables->gdef_len = len; break;
-  case MORT_TAG: layoutTables->mort = (void*)result; layoutTables->mort_len = len; break;
-  case KERN_TAG: layoutTables->kern = (void*)result; layoutTables->kern_len = len; break;
-  default: break;
+  if (cacheIdx<LAYOUTCACHE_ENTRIES) { // if cacheable table
+    layoutTables->entries[cacheIdx].len = len;
+    layoutTables->entries[cacheIdx].ptr = (const void*)result;
   }
 
-  return (void*)result;
+  length = len;
+  return (const void*)result;
 };
 
 LEGlyphID FontInstanceAdapter::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
--- a/src/share/native/sun/font/FontInstanceAdapter.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/FontInstanceAdapter.h	Mon Mar 04 12:29:30 2013 -0800
@@ -86,6 +86,7 @@
     // tables are cached with the native font scaler data
     // only supports gsub, gpos, gdef, mort tables at present
     virtual const void *getFontTable(LETag tableTag) const;
+    virtual const void *getFontTable(LETag tableTag, size_t &len) const;
 
     virtual void *getKernPairs() const {
         return layoutTables->kernPairs;
--- a/src/share/native/sun/font/fontscalerdefs.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/fontscalerdefs.h	Mon Mar 04 12:29:30 2013 -0800
@@ -120,20 +120,19 @@
 #define GPOS_TAG 0x47504F53 /* 'GPOS' */
 #define GDEF_TAG 0x47444546 /* 'GDEF' */
 #define MORT_TAG 0x6D6F7274 /* 'mort' */
+#define MORX_TAG 0x6D6F7278 /* 'morx' */
 #define KERN_TAG 0x6B65726E /* 'kern' */
 
+typedef struct TTLayoutTableCacheEntry {
+  const void* ptr;
+  int   len;
+} TTLayoutTableCacheEntry;
+
+#define LAYOUTCACHE_ENTRIES 6
+
 typedef struct TTLayoutTableCache {
-    void* gsub;
-    void* gpos;
-    void* gdef;
-    void* mort;
-    void* kern;
-    void* kernPairs;
-    int gsub_len;
-    int gpos_len;
-    int gdef_len;
-    int mort_len;
-    int kern_len;
+  TTLayoutTableCacheEntry entries[LAYOUTCACHE_ENTRIES];
+  void* kernPairs;
 } TTLayoutTableCache;
 
 #include "sunfontids.h"
--- a/src/share/native/sun/font/layout/AlternateSubstSubtables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/AlternateSubstSubtables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -39,19 +39,20 @@
 
 U_NAMESPACE_BEGIN
 
-le_uint32 AlternateSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
+le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSubstitutionSubtable> &base,
+                                       GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
 {
     // NOTE: For now, we'll just pick the first alternative...
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
 
-    if (coverageIndex >= 0) {
+    if (coverageIndex >= 0 && LE_SUCCESS(success)) {
         le_uint16 altSetCount = SWAPW(alternateSetCount);
 
         if (coverageIndex < altSetCount) {
             Offset alternateSetTableOffset = SWAPW(alternateSetTableOffsetArray[coverageIndex]);
-            const AlternateSetTable *alternateSetTable =
-                (const AlternateSetTable *) ((char *) this + alternateSetTableOffset);
+            const LEReferenceTo<AlternateSetTable> alternateSetTable(base, success,
+                                  (const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
             TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]);
 
             if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) {
--- a/src/share/native/sun/font/layout/AlternateSubstSubtables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/AlternateSubstSubtables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -51,13 +51,17 @@
     TTGlyphID alternateArray[ANY_NUMBER];
 };
 
+LE_VAR_ARRAY(AlternateSetTable, alternateArray)
+
 struct AlternateSubstitutionSubtable : GlyphSubstitutionSubtable
 {
     le_uint16 alternateSetCount;
     Offset    alternateSetTableOffsetArray[ANY_NUMBER];
 
-    le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const;
+    le_uint32 process(const LEReferenceTo<AlternateSubstitutionSubtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
 };
 
+LE_VAR_ARRAY(AlternateSubstitutionSubtable, alternateSetTableOffsetArray)
+
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/ArabicLayoutEngine.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ArabicLayoutEngine.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -58,15 +58,18 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)
 
-ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                        le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
+ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
+                                                       le_int32 languageCode, le_int32 typoFlags,
+                                                       const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable,
+                                                       LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
 {
     fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
     fFeatureOrder = TRUE;
 }
 
-ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
+ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
+                                                       le_int32 languageCode,
                                                        le_int32 typoFlags, LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
 {
@@ -88,8 +91,9 @@
 // Input: characters
 // Output: characters, char indices, tags
 // Returns: output character count
-le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
-        LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
+le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count,
+                                                         le_int32 max, le_bool rightToLeft, LEUnicode *&outChars,
+                                                         LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
     if (LE_FAILURE(success)) {
         return 0;
@@ -137,22 +141,21 @@
         return;
     }
 
-    if (fGPOSTable != NULL) {
+    if (!fGPOSTable.isEmpty()) {
         OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);
-    } else if (fGDEFTable != NULL) {
-        GDEFMarkFilter filter(fGDEFTable);
-
+    } else if (!fGDEFTable.isEmpty()) {
+        GDEFMarkFilter filter(fGDEFTable, success);
         adjustMarkGlyphs(glyphStorage, &filter, success);
     } else {
-        GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
-        GDEFMarkFilter filter(gdefTable);
+        LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
+        GDEFMarkFilter filter(gdefTable, success);
 
         adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
     }
 }
 
 UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
-    : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
+  : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
 {
     fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
     fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
@@ -232,7 +235,7 @@
         return;
     }
 
-    GDEFMarkFilter filter(fGDEFTable);
+    GDEFMarkFilter filter(fGDEFTable, success);
 
     adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
 }
--- a/src/share/native/sun/font/layout/ArabicLayoutEngine.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ArabicLayoutEngine.h	Mon Mar 04 12:29:30 2013 -0800
@@ -75,7 +75,7 @@
      * @internal
      */
     ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                            le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
+                            le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
 
     /**
      * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/ArabicShaping.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ArabicShaping.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -58,14 +58,16 @@
 */
 ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
 {
-    const ClassDefinitionTable *joiningTypes = (const ClassDefinitionTable *) ArabicShaping::shapingTypeTable;
-    le_int32 joiningType = joiningTypes->getGlyphClass(c);
+  LEErrorCode success = LE_NO_ERROR;
+  const LEReferenceTo<ClassDefinitionTable> joiningTypes((const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
+                                                         ArabicShaping::shapingTypeTableLen);
+  le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success);
 
-    if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT) {
-        return ArabicShaping::shapeTypes[joiningType];
-    }
+  if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT && LE_SUCCESS(success)) {
+    return ArabicShaping::shapeTypes[joiningType];
+  }
 
-    return ArabicShaping::ST_NOSHAPE_NONE;
+  return ArabicShaping::ST_NOSHAPE_NONE;
 }
 
 #define isolFeatureTag LE_ISOL_FEATURE_TAG
--- a/src/share/native/sun/font/layout/ArabicShaping.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ArabicShaping.h	Mon Mar 04 12:29:30 2013 -0800
@@ -93,6 +93,8 @@
     static ShapeType getShapeType(LEUnicode c);
 
     static const le_uint8 shapingTypeTable[];
+    static const size_t   shapingTypeTableLen;
+
     static const ShapeType shapeTypes[];
 
     static void adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage);
--- a/src/share/native/sun/font/layout/AttachmentPosnSubtables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/AttachmentPosnSubtables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -52,14 +52,14 @@
     Offset    markArrayOffset;
     Offset    baseArrayOffset;
 
-    inline le_int32  getBaseCoverage(LEGlyphID baseGlyphId) const;
+    inline le_int32  getBaseCoverage(const LETableReference &base, LEGlyphID baseGlyphId, LEErrorCode &success) const;
 
     le_uint32 process(GlyphIterator *glyphIterator) const;
 };
 
-inline le_int32 AttachmentPositioningSubtable::getBaseCoverage(LEGlyphID baseGlyphID) const
+inline le_int32 AttachmentPositioningSubtable::getBaseCoverage(const LETableReference &base, LEGlyphID baseGlyphID, LEErrorCode &success) const
 {
-    return getGlyphCoverage(baseCoverageTableOffset, baseGlyphID);
+  return getGlyphCoverage(base, baseCoverageTableOffset, baseGlyphID, success);
 }
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/CanonData.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/CanonData.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -3641,4 +3641,9 @@
     0x00, 0xE6, 0xD2, 0x42, 0xD2, 0x44, 0x00, 0xE6
 };
 
+
+const size_t CanonShaping::glyphSubstitutionTableLen = sizeof(glyphSubstitutionTable)/sizeof(glyphSubstitutionTable[0]);
+
+const size_t CanonShaping::glyphDefinitionTableLen = sizeof(glyphDefinitionTable)/sizeof(glyphDefinitionTable[0]);
+
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/CanonShaping.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/CanonShaping.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -59,15 +59,15 @@
 void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
                                 LEUnicode *outChars, LEGlyphStorage &glyphStorage)
 {
-    const GlyphDefinitionTableHeader *gdefTable = (const GlyphDefinitionTableHeader *) glyphDefinitionTable;
-    const ClassDefinitionTable *classTable = gdefTable->getMarkAttachClassDefinitionTable();
+    LEErrorCode success = LE_NO_ERROR;
+    LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
+    LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success);
     le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount);
     le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);
-    LEErrorCode status = LE_NO_ERROR;
     le_int32 i;
 
     for (i = 0; i < charCount; i += 1) {
-        combiningClasses[i] = classTable->getGlyphClass((LEGlyphID) inChars[i]);
+      combiningClasses[i] = classTable->getGlyphClass(classTable, (LEGlyphID) inChars[i], success);
         indices[i] = i;
     }
 
@@ -96,7 +96,7 @@
         le_int32 index = indices[i];
 
         outChars[i] = inChars[index];
-        glyphStorage.setCharIndex(out, index, status);
+        glyphStorage.setCharIndex(out, index, success);
     }
 
     LE_DELETE_ARRAY(indices);
--- a/src/share/native/sun/font/layout/CanonShaping.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/CanonShaping.h	Mon Mar 04 12:29:30 2013 -0800
@@ -42,7 +42,9 @@
 {
 public:
     static const le_uint8 glyphSubstitutionTable[];
+    static const size_t   glyphSubstitutionTableLen;
     static const le_uint8 glyphDefinitionTable[];
+    static const size_t   glyphDefinitionTableLen;
 
     static void reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
                                    LEUnicode *outChars, LEGlyphStorage &glyphStorage);
--- a/src/share/native/sun/font/layout/ClassDefinitionTables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ClassDefinitionTables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -37,24 +37,51 @@
 
 U_NAMESPACE_BEGIN
 
-le_int32 ClassDefinitionTable::getGlyphClass(LEGlyphID glyphID) const
+le_int32 ClassDefinitionTable::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
 {
+  LEReferenceTo<ClassDefinitionTable> thisRef(base, success);
+  if (LE_FAILURE(success)) return 0;
+
+  switch(SWAPW(classFormat)) {
+    case 0:
+        return 0;
+
+    case 1:
+    {
+      const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success);
+      return f1Table->getGlyphClass(f1Table, glyphID, success);
+    }
+
+    case 2:
+    {
+      const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success);
+      return  f2Table->getGlyphClass(f2Table, glyphID, success);
+    }
+
+    default:
+        return 0;
+  }
+}
+
+le_bool ClassDefinitionTable::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
+{
+    LEReferenceTo<ClassDefinitionTable> thisRef(base, success);
+    if (LE_FAILURE(success)) return 0;
+
     switch(SWAPW(classFormat)) {
     case 0:
         return 0;
 
     case 1:
     {
-        const ClassDefFormat1Table *f1Table = (const ClassDefFormat1Table *) this;
-
-        return f1Table->getGlyphClass(glyphID);
+      const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success);
+      return f1Table->hasGlyphClass(f1Table, glyphClass, success);
     }
 
     case 2:
     {
-        const ClassDefFormat2Table *f2Table = (const ClassDefFormat2Table *) this;
-
-        return f2Table->getGlyphClass(glyphID);
+      const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success);
+      return f2Table->hasGlyphClass(f2Table, glyphClass, success);
     }
 
     default:
@@ -62,51 +89,32 @@
     }
 }
 
-le_bool ClassDefinitionTable::hasGlyphClass(le_int32 glyphClass) const
+le_int32 ClassDefFormat1Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
 {
-    switch(SWAPW(classFormat)) {
-    case 0:
-        return 0;
+    if(LE_FAILURE(success)) return 0;
 
-    case 1:
-    {
-        const ClassDefFormat1Table *f1Table = (const ClassDefFormat1Table *) this;
-
-        return f1Table->hasGlyphClass(glyphClass);
-    }
-
-    case 2:
-    {
-        const ClassDefFormat2Table *f2Table = (const ClassDefFormat2Table *) this;
-
-        return f2Table->hasGlyphClass(glyphClass);
-    }
-
-    default:
-        return 0;
-    }
-}
-
-le_int32 ClassDefFormat1Table::getGlyphClass(LEGlyphID glyphID) const
-{
+    le_uint16 count = SWAPW(glyphCount);
+    LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count);
     TTGlyphID ttGlyphID  = (TTGlyphID) LE_GET_GLYPH(glyphID);
     TTGlyphID firstGlyph = SWAPW(startGlyph);
-    TTGlyphID lastGlyph  = firstGlyph + SWAPW(glyphCount);
+    TTGlyphID lastGlyph  = firstGlyph + count;
 
-    if (ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) {
-        return SWAPW(classValueArray[ttGlyphID - firstGlyph]);
+    if (LE_SUCCESS(success) && ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) {
+      return SWAPW( classValueArrayRef(ttGlyphID - firstGlyph, success) );
     }
 
     return 0;
 }
 
-le_bool ClassDefFormat1Table::hasGlyphClass(le_int32 glyphClass) const
+le_bool ClassDefFormat1Table::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
 {
-    le_uint16 count  = SWAPW(glyphCount);
+    if(LE_FAILURE(success)) return 0;
+    le_uint16 count = SWAPW(glyphCount);
+    LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count);
     int i;
 
-    for (i = 0; i < count; i += 1) {
-        if (SWAPW(classValueArray[i]) == glyphClass) {
+    for (i = 0; LE_SUCCESS(success)&& (i < count); i += 1) {
+      if (SWAPW(classValueArrayRef(i,success)) == glyphClass) {
             return TRUE;
         }
     }
@@ -114,27 +122,31 @@
     return FALSE;
 }
 
-le_int32 ClassDefFormat2Table::getGlyphClass(LEGlyphID glyphID) const
+le_int32 ClassDefFormat2Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
 {
+    if(LE_FAILURE(success)) return 0;
     TTGlyphID ttGlyph    = (TTGlyphID) LE_GET_GLYPH(glyphID);
     le_uint16 rangeCount = SWAPW(classRangeCount);
+    LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount);
     le_int32  rangeIndex =
-        OpenTypeUtilities::getGlyphRangeIndex(ttGlyph, classRangeRecordArray, rangeCount);
+      OpenTypeUtilities::getGlyphRangeIndex(ttGlyph, classRangeRecordArrayRef, success);
 
-    if (rangeIndex < 0) {
+    if (rangeIndex < 0 || LE_FAILURE(success)) {
         return 0;
     }
 
-    return SWAPW(classRangeRecordArray[rangeIndex].rangeValue);
+    return SWAPW(classRangeRecordArrayRef(rangeIndex, success).rangeValue);
 }
 
-le_bool ClassDefFormat2Table::hasGlyphClass(le_int32 glyphClass) const
+le_bool ClassDefFormat2Table::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
 {
+    if(LE_FAILURE(success)) return 0;
     le_uint16 rangeCount = SWAPW(classRangeCount);
+    LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount);
     int i;
 
-    for (i = 0; i < rangeCount; i += 1) {
-        if (SWAPW(classRangeRecordArray[i].rangeValue) == glyphClass) {
+    for (i = 0; i < rangeCount && LE_SUCCESS(success); i += 1) {
+      if (SWAPW(classRangeRecordArrayRef(i,success).rangeValue) == glyphClass) {
             return TRUE;
         }
     }
--- a/src/share/native/sun/font/layout/ClassDefinitionTables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ClassDefinitionTables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -46,8 +46,20 @@
 {
     le_uint16 classFormat;
 
-    le_int32  getGlyphClass(LEGlyphID glyphID) const;
-    le_bool   hasGlyphClass(le_int32 glyphClass) const;
+    le_int32  getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
+    le_bool   hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
+
+  le_int32 getGlyphClass(LEGlyphID glyphID) const {
+    LETableReference base((const le_uint8*)this);
+    LEErrorCode ignored = LE_NO_ERROR;
+    return getGlyphClass(base,glyphID,ignored);
+  }
+
+  le_bool hasGlyphClass(le_int32 glyphClass) const {
+    LETableReference base((const le_uint8*)this);
+    LEErrorCode ignored = LE_NO_ERROR;
+    return hasGlyphClass(base,glyphClass,ignored);
+  }
 };
 
 struct ClassDefFormat1Table : ClassDefinitionTable
@@ -56,9 +68,11 @@
     le_uint16  glyphCount;
     le_uint16  classValueArray[ANY_NUMBER];
 
-    le_int32 getGlyphClass(LEGlyphID glyphID) const;
-    le_bool  hasGlyphClass(le_int32 glyphClass) const;
+    le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
+    le_bool  hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
 };
+LE_VAR_ARRAY(ClassDefFormat1Table, classValueArray)
+
 
 struct ClassRangeRecord
 {
@@ -72,9 +86,10 @@
     le_uint16        classRangeCount;
     GlyphRangeRecord classRangeRecordArray[ANY_NUMBER];
 
-    le_int32 getGlyphClass(LEGlyphID glyphID) const;
-    le_bool hasGlyphClass(le_int32 glyphClass) const;
+    le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
+    le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
 };
+LE_VAR_ARRAY(ClassDefFormat2Table, classRangeRecordArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -43,13 +43,15 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2)
 
-ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
-  : StateTableProcessor2(morphSubtableHeader)
+ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(
+         const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : StateTableProcessor2(morphSubtableHeader, success)
 {
-    contextualGlyphHeader = (const ContextualGlyphInsertionHeader2 *) morphSubtableHeader;
-    le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
-    insertionTable = ((le_uint16 *) ((char *)&stateTableHeader->stHeader + insertionTableOffset));
-    entryTable = (const ContextualGlyphInsertionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
+  contextualGlyphHeader = LEReferenceTo<ContextualGlyphInsertionHeader2>(morphSubtableHeader, success);
+  if(LE_FAILURE(success) || !contextualGlyphHeader.isValid()) return;
+  le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
+  insertionTable = LEReferenceToArrayOf<le_uint16>(stHeader, success, insertionTableOffset, LE_UNBOUNDED_ARRAY);
+  entryTable = LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
 }
 
 ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2()
@@ -61,93 +63,62 @@
     markGlyph = 0;
 }
 
-le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
+void ContextualGlyphInsertionProcessor2::doInsertion(LEGlyphStorage &glyphStorage,
+                                                     le_int16 atGlyph,
+                                                     le_int16 &index,
+                                                     le_int16 count,
+                                                     le_bool /* isKashidaLike */,
+                                                     le_bool isBefore,
+                                                     LEErrorCode &success) {
+  LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(atGlyph, count + 1, success);
+
+  if(LE_FAILURE(success) || insertGlyphs==NULL) {
+    return;
+  }
+
+  // Note: Kashida vs Split Vowel seems to only affect selection and highlighting.
+  // We note the flag, but do not layout different.
+  // https://developer.apple.com/fonts/TTRefMan/RM06/Chap6mort.html
+
+  le_int16 targetIndex = 0;
+  if(isBefore) {
+    // insert at beginning
+    insertGlyphs[targetIndex++] = glyphStorage[atGlyph];
+  } else {
+    // insert at end
+    insertGlyphs[count] = glyphStorage[atGlyph];
+  }
+
+  while(count--) {
+    insertGlyphs[targetIndex++] = insertionTable.getObject(index++, success);
+  }
+  glyphStorage.applyInsertions();
+}
+
+le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
+                                                                EntryTableIndex2 index, LEErrorCode &success)
 {
-    const ContextualGlyphInsertionStateEntry2 *entry = &entryTable[index];
+    const ContextualGlyphInsertionStateEntry2 *entry = entryTable.getAlias(index, success);
+
+    if(LE_FAILURE(success)) return 0; // TODO- which state?
+
     le_uint16 newState = SWAPW(entry->newStateIndex);
     le_uint16 flags = SWAPW(entry->flags);
-    le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
+
     le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
-    int i = 0;
-
     if (markIndex > 0) {
         le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
-        if (!(flags & cgiMarkedIsKashidaLike)) {
-            // extra glyph(s) will be added directly before/after the specified marked glyph
-            if (!(flags & cgiMarkInsertBefore)) {
-                LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
-                for (i = 0; i < count; i++, markIndex++) {
-                    insertGlyphs[i] = insertionTable[markIndex];
-                }
-                insertGlyphs[i] = glyphStorage[markGlyph];
-                glyphStorage.applyInsertions();
-            } else {
-                LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
-                insertGlyphs[0] = glyphStorage[markGlyph];
-                for (i = 1; i < count + 1; i++, markIndex++) {
-                    insertGlyphs[i] = insertionTable[markIndex];
-                }
-                glyphStorage.applyInsertions();
-            }
-        } else {
-            // inserted as a split-vowel-like insertion
-            // extra glyph(s) will be inserted some distance away from the marked glyph
-            if (!(flags & cgiMarkInsertBefore)) {
-                LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
-                for (i = 0; i < count; i++, markIndex++) {
-                    insertGlyphs[i] = insertionTable[markIndex];
-                }
-                insertGlyphs[i] = glyphStorage[markGlyph];
-                glyphStorage.applyInsertions();
-            } else {
-                LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(markGlyph, count + 1);
-                insertGlyphs[0] = glyphStorage[markGlyph];
-                for (i = 1; i < count + 1; i++, markIndex++) {
-                    insertGlyphs[i] = insertionTable[markIndex];
-                }
-                glyphStorage.applyInsertions();
-            }
-        }
+        le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike);
+        le_bool isBefore = (flags & cgiMarkInsertBefore);
+        doInsertion(glyphStorage, markGlyph, markIndex, count, isKashidaLike, isBefore, success);
     }
 
+    le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
     if (currIndex > 0) {
         le_int16 count = flags & cgiCurrentInsertCountMask;
-        if (!(flags & cgiCurrentIsKashidaLike)) {
-            // extra glyph(s) will be added directly before/after the specified current glyph
-            if (!(flags & cgiCurrentInsertBefore)) {
-                LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
-                for (i = 0; i < count; i++, currIndex++) {
-                    insertGlyphs[i] = insertionTable[currIndex];
-                }
-                insertGlyphs[i] = glyphStorage[currGlyph];
-                glyphStorage.applyInsertions();
-            } else {
-                LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
-                insertGlyphs[0] = glyphStorage[currGlyph];
-                for (i = 1; i < count + 1; i++, currIndex++) {
-                    insertGlyphs[i] = insertionTable[currIndex];
-                }
-                glyphStorage.applyInsertions();
-            }
-        } else {
-            // inserted as a split-vowel-like insertion
-            // extra glyph(s) will be inserted some distance away from the current glyph
-            if (!(flags & cgiCurrentInsertBefore)) {
-                LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
-                for (i = 0; i < count; i++, currIndex++) {
-                    insertGlyphs[i] = insertionTable[currIndex];
-                }
-                insertGlyphs[i] = glyphStorage[currGlyph];
-                glyphStorage.applyInsertions();
-            } else {
-                LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(currGlyph, count + 1);
-                insertGlyphs[0] = glyphStorage[currGlyph];
-                for (i = 1; i < count + 1; i++, currIndex++) {
-                    insertGlyphs[i] = insertionTable[currIndex];
-                }
-                glyphStorage.applyInsertions();
-            }
-        }
+        le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike);
+        le_bool isBefore = (flags & cgiCurrentInsertBefore);
+        doInsertion(glyphStorage, currGlyph, currIndex, count, isKashidaLike, isBefore, success);
     }
 
     if (flags & cgiSetMark) {
--- a/src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -53,11 +53,12 @@
 public:
     virtual void beginStateTable();
 
-    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage,
+                                        le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
 
     virtual void endStateTable();
 
-    ContextualGlyphInsertionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    ContextualGlyphInsertionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
     virtual ~ContextualGlyphInsertionProcessor2();
 
     /**
@@ -77,12 +78,28 @@
 private:
     ContextualGlyphInsertionProcessor2();
 
+    /**
+     * Perform the actual insertion
+     * @param atGlyph index of glyph to insert at
+     * @param index index into the insertionTable (in/out)
+     * @param count number of insertions
+     * @param isKashidaLike Kashida like (vs Split Vowel like). No effect currently.
+     * @param isBefore if true, insert extra glyphs before the marked glyph
+     */
+    void doInsertion(LEGlyphStorage &glyphStorage,
+                              le_int16 atGlyph,
+                              le_int16 &index,
+                              le_int16 count,
+                              le_bool isKashidaLike,
+                              le_bool isBefore,
+                              LEErrorCode &success);
+
+
 protected:
     le_int32 markGlyph;
-    const le_uint16* insertionTable;
-    const ContextualGlyphInsertionStateEntry2 *entryTable;
-    const ContextualGlyphInsertionHeader2 *contextualGlyphHeader;
-
+    LEReferenceToArrayOf<le_uint16> insertionTable;
+    LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2> entryTable;
+    LEReferenceTo<ContextualGlyphInsertionHeader2> contextualGlyphHeader;
 };
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/ContextualGlyphSubstProc.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -43,13 +43,18 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor)
 
-ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader)
-  : StateTableProcessor(morphSubtableHeader)
+ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+  : StateTableProcessor(morphSubtableHeader, success), entryTable(), contextualGlyphSubstitutionHeader(morphSubtableHeader, success)
 {
-    contextualGlyphSubstitutionHeader = (const ContextualGlyphSubstitutionHeader *) morphSubtableHeader;
-    substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
+  contextualGlyphSubstitutionHeader.orphan();
+  substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
 
-    entryTable = (const ContextualGlyphSubstitutionStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
+
+  entryTable = LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry>(stateTableHeader, success,
+                                                                           (const ContextualGlyphSubstitutionStateEntry*)(&stateTableHeader->stHeader),
+                                                                           entryTableOffset, LE_UNBOUNDED_ARRAY);
+  int16Table = LEReferenceToArrayOf<le_int16>(stateTableHeader, success, (const le_int16*)(&stateTableHeader->stHeader),
+                                              0, LE_UNBOUNDED_ARRAY); // rest of the table as le_int16s
 }
 
 ContextualGlyphSubstitutionProcessor::~ContextualGlyphSubstitutionProcessor()
@@ -63,27 +68,26 @@
 
 ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
 {
-    const ContextualGlyphSubstitutionStateEntry *entry = &entryTable[index];
-    ByteOffset newState = SWAPW(entry->newStateOffset);
-    le_int16 flags = SWAPW(entry->flags);
-    WordOffset markOffset = SWAPW(entry->markOffset);
-    WordOffset currOffset = SWAPW(entry->currOffset);
+  LEErrorCode success = LE_NO_ERROR;
+  const ContextualGlyphSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
+  ByteOffset newState = SWAPW(entry->newStateOffset);
+  le_int16 flags = SWAPW(entry->flags);
+  WordOffset markOffset = SWAPW(entry->markOffset);
+  WordOffset currOffset = SWAPW(entry->currOffset);
 
-    if (markOffset != 0) {
-        const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + markOffset * 2);
-        LEGlyphID mGlyph = glyphStorage[markGlyph];
-        TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(mGlyph)]);
+  if (markOffset != 0 && LE_SUCCESS(success)) {
+    LEGlyphID mGlyph = glyphStorage[markGlyph];
+    TTGlyphID newGlyph = SWAPW(int16Table.getObject(markOffset + LE_GET_GLYPH(mGlyph), success)); // whew.
 
-         glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
-    }
+    glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
+  }
 
-    if (currOffset != 0) {
-        const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + currOffset * 2);
-        LEGlyphID thisGlyph = glyphStorage[currGlyph];
-        TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(thisGlyph)]);
+  if (currOffset != 0) {
+    LEGlyphID thisGlyph = glyphStorage[currGlyph];
+    TTGlyphID newGlyph = SWAPW(int16Table.getObject(currOffset + LE_GET_GLYPH(thisGlyph), success)); // whew.
 
-        glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
-    }
+    glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
+  }
 
     if (flags & cgsSetMark) {
         markGlyph = currGlyph;
--- a/src/share/native/sun/font/layout/ContextualGlyphSubstProc.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc.h	Mon Mar 04 12:29:30 2013 -0800
@@ -56,7 +56,7 @@
 
     virtual void endStateTable();
 
-    ContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
     virtual ~ContextualGlyphSubstitutionProcessor();
 
     /**
@@ -78,11 +78,11 @@
 
 protected:
     ByteOffset substitutionTableOffset;
-    const ContextualGlyphSubstitutionStateEntry *entryTable;
-
+    LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry> entryTable;
+    LEReferenceToArrayOf<le_int16> int16Table;
     le_int32 markGlyph;
 
-    const ContextualGlyphSubstitutionHeader *contextualGlyphSubstitutionHeader;
+    LEReferenceTo<ContextualGlyphSubstitutionHeader> contextualGlyphSubstitutionHeader;
 
 };
 
--- a/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -43,13 +43,14 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2)
 
-ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
-  : StateTableProcessor2(morphSubtableHeader)
+ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(
+                                  const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : StateTableProcessor2(morphSubtableHeader, success), contextualGlyphHeader(morphSubtableHeader, success)
 {
-    contextualGlyphHeader = (const ContextualGlyphHeader2 *) morphSubtableHeader;
+    if(LE_FAILURE(success)) return;
     le_uint32 perGlyphTableOffset = SWAPL(contextualGlyphHeader->perGlyphTableOffset);
-    perGlyphTable = ((le_uint32 *) ((char *)&stateTableHeader->stHeader + perGlyphTableOffset));
-    entryTable = (const ContextualGlyphStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
+    perGlyphTable = LEReferenceToArrayOf<le_uint32> (stHeader, success, perGlyphTableOffset, LE_UNBOUNDED_ARRAY);
+    entryTable = LEReferenceToArrayOf<ContextualGlyphStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
 }
 
 ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2()
@@ -61,25 +62,28 @@
     markGlyph = 0;
 }
 
-le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
+le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
+    EntryTableIndex2 index, LEErrorCode &success)
 {
-    const ContextualGlyphStateEntry2 *entry = &entryTable[index];
+    if(LE_FAILURE(success)) return 0;
+    const ContextualGlyphStateEntry2 *entry = entryTable.getAlias(index, success);
+    if(LE_FAILURE(success)) return 0;
     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]);
+        le_uint32 offset = SWAPL(perGlyphTable(markIndex, success));
         LEGlyphID mGlyph = glyphStorage[markGlyph];
-        TTGlyphID newGlyph = lookup(offset, mGlyph);
+        TTGlyphID newGlyph = lookup(offset, mGlyph, success);
         glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
     }
 
     if (currIndex != -1) {
-        le_uint32 offset = SWAPL(perGlyphTable[currIndex]);
+        le_uint32 offset = SWAPL(perGlyphTable(currIndex, success));
         LEGlyphID thisGlyph = glyphStorage[currGlyph];
-        TTGlyphID newGlyph = lookup(offset, thisGlyph);
+        TTGlyphID newGlyph = lookup(offset, thisGlyph, success);
         glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
     }
 
@@ -94,26 +98,30 @@
     return newState;
 }
 
-TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid)
+TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success)
 {
-    LookupTable *lookupTable = ((LookupTable *) ((char *)perGlyphTable + offset));
+    TTGlyphID newGlyph = 0xFFFF;
+    if(LE_FAILURE(success))  return newGlyph;
+    LEReferenceTo<LookupTable> lookupTable(perGlyphTable, success, offset);
+    if(LE_FAILURE(success))  return newGlyph;
     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;
+            LEReferenceTo<SimpleArrayLookupTable> lookupTable0(lookupTable, success);
+            LEReferenceToArrayOf<LookupValue> valueArray(lookupTable0, success, &lookupTable0->valueArray[0], LE_UNBOUNDED_ARRAY);
+            if(LE_FAILURE(success))  return newGlyph;
             TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
-            newGlyph = SWAPW(lookupTable0->valueArray[glyphCode]);
+            newGlyph = SWAPW(lookupTable0->valueArray(glyphCode, success));
 #endif
             break;
         }
         case ltfSegmentSingle: {
 #ifdef TEST_FORMAT
             // Disabled pending for design review
-            SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) lookupTable;
+            LEReferenceTo<SegmentSingleLookupTable> lookupTable2 = (SegmentSingleLookupTable *) lookupTable;
             const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid);
             if (segment != NULL) {
                 newGlyph = SWAPW(segment->value);
@@ -129,8 +137,8 @@
         {
 #ifdef TEST_FORMAT
             // Disabled pending for design review
-            SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) lookupTable;
-            const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
+            LEReferenceTo<SingleTableLookupTable> lookupTable6 = (SingleTableLookupTable *) lookupTable;
+            const LEReferenceTo<LookupSingle> segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
             if (segment != NULL) {
                 newGlyph = SWAPW(segment->value);
             }
@@ -138,12 +146,15 @@
             break;
         }
         case ltfTrimmedArray: {
-            TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) lookupTable;
+            LEReferenceTo<TrimmedArrayLookupTable> lookupTable8(lookupTable, success);
+            if (LE_FAILURE(success)) return newGlyph;
             TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph);
-            TTGlyphID lastGlyph  = firstGlyph + SWAPW(lookupTable8->glyphCount);
+            TTGlyphID glyphCount = SWAPW(lookupTable8->glyphCount);
+            TTGlyphID lastGlyph  = firstGlyph + glyphCount;
             TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
             if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) {
-                newGlyph = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]);
+              LEReferenceToArrayOf<LookupValue> valueArray(lookupTable8, success, &lookupTable8->valueArray[0], glyphCount);
+              newGlyph = SWAPW(valueArray(glyphCode - firstGlyph, success));
             }
         }
         default:
--- a/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -52,11 +52,11 @@
 public:
     virtual void beginStateTable();
 
-    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
 
     virtual void endStateTable();
 
-    ContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    ContextualGlyphSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
     virtual ~ContextualGlyphSubstitutionProcessor2();
 
     /**
@@ -75,16 +75,16 @@
 
 private:
     ContextualGlyphSubstitutionProcessor2();
-    TTGlyphID lookup(le_uint32 offset, LEGlyphID gid);
+    TTGlyphID lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success);
 
 protected:
-    const le_uint32* perGlyphTable;
-    const ContextualGlyphStateEntry2 *entryTable;
+    LEReferenceToArrayOf<le_uint32>           perGlyphTable;
+    LEReferenceToArrayOf<ContextualGlyphStateEntry2> entryTable;
 
     le_int16 perGlyphTableFormat;
     le_int32 markGlyph;
 
-    const ContextualGlyphHeader2 *contextualGlyphHeader;
+    LEReferenceTo<ContextualGlyphHeader2> contextualGlyphHeader;
 
 };
 
--- a/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -217,7 +217,7 @@
     }
 
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
 
     if (coverageIndex >= 0) {
         le_uint16 srSetCount = SWAPW(subRuleSetCount);
@@ -266,7 +266,7 @@
     }
 
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
 
     if (coverageIndex >= 0) {
         const ClassDefinitionTable *classDefinitionTable =
@@ -394,7 +394,7 @@
     }
 
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
 
     if (coverageIndex >= 0) {
         le_uint16 srSetCount = SWAPW(chainSubRuleSetCount);
@@ -465,7 +465,7 @@
     }
 
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
 
     if (coverageIndex >= 0) {
         const ClassDefinitionTable *backtrackClassDefinitionTable =
--- a/src/share/native/sun/font/layout/ContextualSubstSubtables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ContextualSubstSubtables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -43,6 +43,7 @@
 #include "GlyphSubstitutionTables.h"
 #include "GlyphIterator.h"
 #include "LookupProcessor.h"
+#include "LETableReference.h"
 
 U_NAMESPACE_BEGIN
 
@@ -88,6 +89,8 @@
 
     le_uint32  process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 };
+LE_VAR_ARRAY(ContextualSubstitutionFormat1Subtable, subRuleSetTableOffsetArray)
+
 
 struct SubRuleSetTable
 {
@@ -95,6 +98,7 @@
     Offset  subRuleTableOffsetArray[ANY_NUMBER];
 
 };
+LE_VAR_ARRAY(SubRuleSetTable, subRuleTableOffsetArray)
 
 // NOTE: Multiple variable size arrays!!
 struct SubRuleTable
@@ -104,6 +108,7 @@
     TTGlyphID inputGlyphArray[ANY_NUMBER];
   //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(SubRuleTable, inputGlyphArray)
 
 struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
 {
@@ -113,12 +118,16 @@
 
     le_uint32  process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 };
+LE_VAR_ARRAY(ContextualSubstitutionFormat2Subtable, subClassSetTableOffsetArray)
+
 
 struct SubClassSetTable
 {
     le_uint16  subClassRuleCount;
     Offset  subClassRuleTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(SubClassSetTable, subClassRuleTableOffsetArray)
+
 
 // NOTE: Multiple variable size arrays!!
 struct SubClassRuleTable
@@ -128,6 +137,8 @@
     le_uint16  classArray[ANY_NUMBER];
   //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(SubClassRuleTable, classArray)
+
 
 // NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause
 // it has an array of coverage tables instead of a single coverage table...
@@ -143,6 +154,7 @@
 
     le_uint32  process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 };
+LE_VAR_ARRAY(ContextualSubstitutionFormat3Subtable, coverageTableOffsetArray)
 
 struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase
 {
@@ -156,6 +168,8 @@
 
     le_uint32  process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 };
+LE_VAR_ARRAY(ChainingContextualSubstitutionFormat1Subtable, chainSubRuleSetTableOffsetArray)
+
 
 struct ChainSubRuleSetTable
 {
@@ -163,6 +177,7 @@
     Offset  chainSubRuleTableOffsetArray[ANY_NUMBER];
 
 };
+LE_VAR_ARRAY(ChainSubRuleSetTable, chainSubRuleTableOffsetArray)
 
 // NOTE: Multiple variable size arrays!!
 struct ChainSubRuleTable
@@ -176,6 +191,7 @@
   //le_uint16  substCount;
   //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(ChainSubRuleTable, backtrackGlyphArray)
 
 struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstitutionSubtable
 {
@@ -187,12 +203,15 @@
 
     le_uint32  process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 };
+LE_VAR_ARRAY(ChainingContextualSubstitutionFormat2Subtable, chainSubClassSetTableOffsetArray)
 
 struct ChainSubClassSetTable
 {
     le_uint16  chainSubClassRuleCount;
     Offset  chainSubClassRuleTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(ChainSubClassSetTable, chainSubClassRuleTableOffsetArray)
+
 
 // NOTE: Multiple variable size arrays!!
 struct ChainSubClassRuleTable
@@ -206,6 +225,7 @@
   //le_uint16  substCount;
   //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(ChainSubClassRuleTable, backtrackClassArray)
 
 // NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause
 // it has arrays of coverage tables instead of a single coverage table...
@@ -225,6 +245,8 @@
 
     le_uint32  process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 };
+LE_VAR_ARRAY(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray)
+
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/CoverageTables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/CoverageTables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -56,6 +56,8 @@
 
     le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
 };
+LE_VAR_ARRAY(CoverageFormat1Table, glyphArray)
+
 
 struct CoverageFormat2Table : CoverageTable
 {
@@ -64,6 +66,7 @@
 
     le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
 };
+LE_VAR_ARRAY(CoverageFormat2Table, rangeRecordArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -39,10 +39,10 @@
 
 U_NAMESPACE_BEGIN
 
-le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
+le_uint32 CursiveAttachmentSubtable::process(const LEReferenceTo<CursiveAttachmentSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
 {
     LEGlyphID glyphID       = glyphIterator->getCurrGlyphID();
-    le_int32  coverageIndex = getGlyphCoverage(glyphID);
+    le_int32  coverageIndex = getGlyphCoverage(base, glyphID, success);
     le_uint16 eeCount       = SWAPW(entryExitCount);
 
     if (coverageIndex < 0 || coverageIndex >= eeCount) {
@@ -51,7 +51,7 @@
     }
 
     LEPoint entryAnchor, exitAnchor;
-    Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor);
+    Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor); // TODO
     Offset exitOffset  = SWAPW(entryExitRecords[coverageIndex].exitAnchor);
 
     if (entryOffset != 0) {
--- a/src/share/native/sun/font/layout/CursiveAttachmentSubtables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/CursiveAttachmentSubtables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -57,8 +57,9 @@
     le_uint16 entryExitCount;
     EntryExitRecord entryExitRecords[ANY_NUMBER];
 
-    le_uint32  process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
+    le_uint32  process(const LEReferenceTo<CursiveAttachmentSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
 };
+LE_VAR_ARRAY(CursiveAttachmentSubtable, entryExitRecords)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/DeviceTables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/DeviceTables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -57,6 +57,7 @@
     static const le_uint16 fieldSignBits[];
     static const le_uint16 fieldBits[];
 };
+LE_VAR_ARRAY(DeviceTable, deltaValues)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/ExtensionSubtables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ExtensionSubtables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -47,6 +47,8 @@
 le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_uint16 lookupType,
                                       GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
 {
+    const LEReferenceTo<ExtensionSubtable> thisRef(lookupProcessor->getReference(), success); // create a reference to this
+
     if (LE_FAILURE(success)) {
         return 0;
     }
@@ -55,9 +57,11 @@
 
     if (elt != lookupType) {
         le_uint32 extOffset = READ_LONG(extensionOffset);
-        LookupSubtable *subtable = (LookupSubtable *) ((char *) this + extOffset);
+        LEReferenceTo<LookupSubtable> subtable(thisRef, success, extOffset);
 
-        return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success);
+        if(LE_SUCCESS(success)) {
+          return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success);
+        }
     }
 
     return 0;
--- a/src/share/native/sun/font/layout/Features.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/Features.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -38,19 +38,20 @@
 
 U_NAMESPACE_BEGIN
 
-const FeatureTable *FeatureListTable::getFeatureTable(le_uint16 featureIndex, LETag *featureTag) const
+LEReferenceTo<FeatureTable> FeatureListTable::getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const
 {
-    if (featureIndex >= SWAPW(featureCount)) {
-        return 0;
-    }
+  if (featureIndex >= SWAPW(featureCount) || LE_FAILURE(success)) {
+    return LEReferenceTo<FeatureTable>();
+  }
 
     Offset featureTableOffset = featureRecordArray[featureIndex].featureTableOffset;
 
     *featureTag = SWAPT(featureRecordArray[featureIndex].featureTag);
 
-    return (const FeatureTable *) ((char *) this + SWAPW(featureTableOffset));
+    return LEReferenceTo<FeatureTable>(base, success, SWAPW(featureTableOffset));
 }
 
+#if 0
 /*
  * Note: according to the OpenType Spec. v 1.4, the entries in the Feature
  * List Table are sorted alphabetically by feature tag; however, there seem
@@ -82,5 +83,6 @@
     return 0;
 #endif
 }
+#endif
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GDEFMarkFilter.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GDEFMarkFilter.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -36,9 +36,12 @@
 
 U_NAMESPACE_BEGIN
 
-GDEFMarkFilter::GDEFMarkFilter(const GlyphDefinitionTableHeader *gdefTable)
+GDEFMarkFilter::GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success)
+  : classDefTable(gdefTable->getGlyphClassDefinitionTable(gdefTable, success))
 {
-    classDefTable = gdefTable->getGlyphClassDefinitionTable();
+  if(!classDefTable.isValid()) {
+    success = LE_INTERNAL_ERROR;
+  }
 }
 
 GDEFMarkFilter::~GDEFMarkFilter()
--- a/src/share/native/sun/font/layout/GDEFMarkFilter.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GDEFMarkFilter.h	Mon Mar 04 12:29:30 2013 -0800
@@ -46,13 +46,13 @@
 class GDEFMarkFilter : public UMemory, public LEGlyphFilter
 {
 private:
-    const GlyphClassDefinitionTable *classDefTable;
+    const LEReferenceTo<GlyphClassDefinitionTable> classDefTable;
 
     GDEFMarkFilter(const GDEFMarkFilter &other); // forbid copying of this class
     GDEFMarkFilter &operator=(const GDEFMarkFilter &other); // forbid copying of this class
 
 public:
-    GDEFMarkFilter(const GlyphDefinitionTableHeader *gdefTable);
+    GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
     virtual ~GDEFMarkFilter();
 
     virtual le_bool accept(LEGlyphID glyph) const;
--- a/src/share/native/sun/font/layout/GXLayoutEngine.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GXLayoutEngine.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -41,9 +41,10 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine)
 
-GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable, LEErrorCode &success)
+  GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader> &morphTable, LEErrorCode &success)
     : LayoutEngine(fontInstance, scriptCode, languageCode, 0, success), fMorphTable(morphTable)
 {
+  fMorphTable.orphan();
     // nothing else to do?
 }
 
@@ -70,7 +71,7 @@
         return 0;
     }
 
-    fMorphTable->process(glyphStorage);
+    fMorphTable->process(fMorphTable, glyphStorage, success);
 
     return count;
 }
--- a/src/share/native/sun/font/layout/GXLayoutEngine.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GXLayoutEngine.h	Mon Mar 04 12:29:30 2013 -0800
@@ -74,7 +74,7 @@
      *
      * @internal
      */
-    GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable, LEErrorCode &success);
+    GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader> &morphTable, LEErrorCode &success);
 
     /**
      * The destructor, virtual for correct polymorphic invocation.
@@ -104,7 +104,7 @@
      *
      * @internal
      */
-    const MorphTableHeader *fMorphTable;
+    LEReferenceTo<MorphTableHeader> fMorphTable;
 
     /**
      * This method does GX layout using the font's 'mort' table. It converts the
--- a/src/share/native/sun/font/layout/GXLayoutEngine2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GXLayoutEngine2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -39,10 +39,10 @@
 
 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)
+GXLayoutEngine2::GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader2> &morphTable, le_int32 typoFlags, LEErrorCode &success)
+  : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMorphTable(morphTable)
 {
-    // nothing else to do?
+  // nothing else to do?
 }
 
 GXLayoutEngine2::~GXLayoutEngine2()
@@ -68,7 +68,7 @@
         return 0;
     }
 
-    fMorphTable->process(glyphStorage, fTypoFlags);
+    fMorphTable->process(fMorphTable, glyphStorage, fTypoFlags, success);
     return count;
 }
 
--- a/src/share/native/sun/font/layout/GXLayoutEngine2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GXLayoutEngine2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -73,7 +73,7 @@
      *
      * @internal
      */
-    GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader2 *morphTable, le_int32 typoFlags, LEErrorCode &success);
+    GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader2> &morphTable, le_int32 typoFlags, LEErrorCode &success);
 
     /**
      * The destructor, virtual for correct polymorphic invocation.
@@ -103,7 +103,7 @@
      *
      * @internal
      */
-    const MorphTableHeader2 *fMorphTable;
+    const LEReferenceTo<MorphTableHeader2> fMorphTable;
 
     /**
      * This method does GX layout using the font's 'mort' table. It converts the
--- a/src/share/native/sun/font/layout/GlyphDefinitionTables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphDefinitionTables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -36,24 +36,36 @@
 
 U_NAMESPACE_BEGIN
 
-const GlyphClassDefinitionTable *GlyphDefinitionTableHeader::getGlyphClassDefinitionTable() const
+const LEReferenceTo<GlyphClassDefinitionTable>
+GlyphDefinitionTableHeader::getGlyphClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                                                         LEErrorCode &success) const
 {
-    return (const GlyphClassDefinitionTable *) ((char *) this + SWAPW(glyphClassDefOffset));
+  if(LE_FAILURE(success)) return LEReferenceTo<GlyphClassDefinitionTable>();
+  return LEReferenceTo<GlyphClassDefinitionTable>(base, success, SWAPW(glyphClassDefOffset));
 }
 
-const AttachmentListTable *GlyphDefinitionTableHeader::getAttachmentListTable() const
+const LEReferenceTo<AttachmentListTable>
+GlyphDefinitionTableHeader::getAttachmentListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                                                         LEErrorCode &success) const
 {
-    return (const AttachmentListTable *) ((char *) this + SWAPW(attachListOffset));
+    if(LE_FAILURE(success)) return LEReferenceTo<AttachmentListTable>();
+    return LEReferenceTo<AttachmentListTable>(base, success, SWAPW(attachListOffset));
 }
 
-const LigatureCaretListTable *GlyphDefinitionTableHeader::getLigatureCaretListTable() const
+const LEReferenceTo<LigatureCaretListTable>
+GlyphDefinitionTableHeader::getLigatureCaretListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                                                         LEErrorCode &success) const
 {
-    return (const LigatureCaretListTable *) ((char *) this + SWAPW(ligCaretListOffset));
+    if(LE_FAILURE(success)) return LEReferenceTo<LigatureCaretListTable>();
+    return LEReferenceTo<LigatureCaretListTable>(base, success, SWAPW(ligCaretListOffset));
 }
 
-const MarkAttachClassDefinitionTable *GlyphDefinitionTableHeader::getMarkAttachClassDefinitionTable() const
+const LEReferenceTo<MarkAttachClassDefinitionTable>
+GlyphDefinitionTableHeader::getMarkAttachClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                                                         LEErrorCode &success) const
 {
-    return (const MarkAttachClassDefinitionTable *) ((char *) this + SWAPW(MarkAttachClassDefOffset));
+    if(LE_FAILURE(success)) return LEReferenceTo<MarkAttachClassDefinitionTable>();
+    return LEReferenceTo<MarkAttachClassDefinitionTable>(base, success, SWAPW(MarkAttachClassDefOffset));
 }
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GlyphDefinitionTables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphDefinitionTables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -60,12 +60,14 @@
     le_uint16  glyphCount;
     Offset  attachPointTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(AttachmentListTable, attachPointTableOffsetArray)
 
 struct AttachPointTable
 {
     le_uint16  pointCount;
     le_uint16  pointIndexArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(AttachPointTable, pointIndexArray)
 
 struct LigatureCaretListTable
 {
@@ -73,12 +75,14 @@
     le_uint16  ligGlyphCount;
     Offset  ligGlyphTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(LigatureCaretListTable, ligGlyphTableOffsetArray)
 
 struct LigatureGlyphTable
 {
     le_uint16  caretCount;
     Offset  caretValueTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(LigatureGlyphTable, caretValueTableOffsetArray)
 
 struct CaretValueTable
 {
@@ -111,10 +115,18 @@
     Offset  ligCaretListOffset;
     Offset  MarkAttachClassDefOffset;
 
-    const GlyphClassDefinitionTable *getGlyphClassDefinitionTable() const;
-    const AttachmentListTable *getAttachmentListTable()const ;
-    const LigatureCaretListTable *getLigatureCaretListTable() const;
-    const MarkAttachClassDefinitionTable *getMarkAttachClassDefinitionTable() const;
+    const LEReferenceTo<GlyphClassDefinitionTable>
+    getGlyphClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                                 LEErrorCode &success) const;
+    const LEReferenceTo<AttachmentListTable>
+    getAttachmentListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                           LEErrorCode &success)const ;
+    const LEReferenceTo<LigatureCaretListTable>
+    getLigatureCaretListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                              LEErrorCode &success) const;
+    const LEReferenceTo<MarkAttachClassDefinitionTable>
+    getMarkAttachClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                                      LEErrorCode &success) const;
 };
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GlyphIterator.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphIterator.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -41,18 +41,21 @@
 U_NAMESPACE_BEGIN
 
 GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
-                             FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader)
+                             FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader)
   : direction(1), position(-1), nextLimit(-1), prevLimit(-1),
     glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
     srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0),
-    glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL)
+    glyphClassDefinitionTable(), markAttachClassDefinitionTable()
 
 {
+  LEErrorCode success = LE_NO_ERROR; // TODO
     le_int32 glyphCount = glyphStorage.getGlyphCount();
 
-    if (theGlyphDefinitionTableHeader != NULL) {
-        glyphClassDefinitionTable = theGlyphDefinitionTableHeader->getGlyphClassDefinitionTable();
-        markAttachClassDefinitionTable = theGlyphDefinitionTableHeader->getMarkAttachClassDefinitionTable();
+    if (theGlyphDefinitionTableHeader.isValid()) {
+      glyphClassDefinitionTable = theGlyphDefinitionTableHeader
+        -> getGlyphClassDefinitionTable(theGlyphDefinitionTableHeader, success);
+      markAttachClassDefinitionTable = theGlyphDefinitionTableHeader
+        ->getMarkAttachClassDefinitionTable(theGlyphDefinitionTableHeader, success);
     }
 
     nextLimit = glyphCount;
@@ -380,6 +383,7 @@
 
 le_bool GlyphIterator::filterGlyph(le_uint32 index) const
 {
+    LEErrorCode success = LE_NO_ERROR;
     LEGlyphID glyphID = glyphStorage[index];
     le_int32 glyphClass = gcdNoGlyphClass;
 
@@ -387,8 +391,8 @@
         return TRUE;
     }
 
-    if (glyphClassDefinitionTable != NULL) {
-        glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphID);
+    if (glyphClassDefinitionTable.isValid()) {
+      glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success);
     }
 
     switch (glyphClass)
@@ -410,8 +414,9 @@
 
         le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
 
-        if ((markAttachType != 0) && (markAttachClassDefinitionTable != NULL)) {
-            return markAttachClassDefinitionTable->getGlyphClass(glyphID) != markAttachType;
+        if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) {
+          return markAttachClassDefinitionTable
+            -> getGlyphClass(markAttachClassDefinitionTable, glyphID, success) != markAttachType;
         }
 
         return FALSE;
@@ -461,6 +466,7 @@
     while (newPosition != nextLimit && delta > 0) {
         do {
             newPosition += direction;
+            //fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta);
         } while (newPosition != nextLimit && filterGlyph(newPosition));
 
         delta -= 1;
@@ -468,6 +474,7 @@
 
     position = newPosition;
 
+    //fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta);
     return position != nextLimit;
 }
 
@@ -483,6 +490,7 @@
     while (newPosition != prevLimit && delta > 0) {
         do {
             newPosition -= direction;
+            //fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta);
         } while (newPosition != prevLimit && filterGlyph(newPosition));
 
         delta -= 1;
@@ -490,6 +498,7 @@
 
     position = newPosition;
 
+    //fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta);
     return position != prevLimit;
 }
 
--- a/src/share/native/sun/font/layout/GlyphIterator.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphIterator.h	Mon Mar 04 12:29:30 2013 -0800
@@ -49,7 +49,7 @@
 class GlyphIterator : public UMemory {
 public:
     GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
-        FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader);
+                  FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader);
 
     GlyphIterator(GlyphIterator &that);
 
@@ -117,8 +117,8 @@
     FeatureMask featureMask;
     le_int32    glyphGroup;
 
-    const GlyphClassDefinitionTable *glyphClassDefinitionTable;
-    const MarkAttachClassDefinitionTable *markAttachClassDefinitionTable;
+    LEReferenceTo<GlyphClassDefinitionTable> glyphClassDefinitionTable;
+    LEReferenceTo<MarkAttachClassDefinitionTable> markAttachClassDefinitionTable;
 
     GlyphIterator &operator=(const GlyphIterator &other); // forbid copying of this class
 };
--- a/src/share/native/sun/font/layout/GlyphLookupTables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphLookupTables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -37,21 +37,22 @@
 
 U_NAMESPACE_BEGIN
 
-le_bool GlyphLookupTableHeader::coversScript(LETag scriptTag) const
+le_bool GlyphLookupTableHeader::coversScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const
 {
-    const ScriptListTable *scriptListTable = (const ScriptListTable *) ((char *)this + SWAPW(scriptListOffset));
+  LEReferenceTo<ScriptListTable> scriptListTable(base, success, SWAPW(scriptListOffset));
 
-    return scriptListOffset != 0 && scriptListTable->findScript(scriptTag) != NULL;
+  return (scriptListOffset != 0) && scriptListTable->findScript(scriptListTable, scriptTag, success) .isValid();
 }
 
-le_bool GlyphLookupTableHeader::coversScriptAndLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const
+le_bool GlyphLookupTableHeader::coversScriptAndLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const
 {
-    const ScriptListTable *scriptListTable = (const ScriptListTable *) ((char *)this + SWAPW(scriptListOffset));
-    const LangSysTable    *langSysTable    = scriptListTable->findLanguage(scriptTag, languageTag, exactMatch);
+  LEReferenceTo<ScriptListTable> scriptListTable(base, success, SWAPW(scriptListOffset));
+  LEReferenceTo<LangSysTable> langSysTable = scriptListTable->findLanguage(scriptListTable,
+                                    scriptTag, languageTag, success, exactMatch);
 
     // FIXME: could check featureListOffset, lookupListOffset, and lookup count...
     // Note: don't have to SWAPW langSysTable->featureCount to check for non-zero.
-    return langSysTable != NULL && langSysTable->featureCount != 0;
+  return LE_SUCCESS(success)&&langSysTable.isValid() && langSysTable->featureCount != 0;
 }
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GlyphLookupTables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphLookupTables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -49,8 +49,8 @@
     Offset  featureListOffset;
     Offset  lookupListOffset;
 
-    le_bool coversScript(LETag scriptTag) const;
-    le_bool coversScriptAndLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch = FALSE) const;
+  le_bool coversScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const;
+  le_bool coversScriptAndLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch = FALSE) const;
 };
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GlyphPositioningTables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphPositioningTables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -41,16 +41,16 @@
 
 U_NAMESPACE_BEGIN
 
-void GlyphPositioningTableHeader::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft,
+void GlyphPositioningTableHeader::process(const LEReferenceTo<GlyphPositioningTableHeader> &base, LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft,
                                           LETag scriptTag, LETag languageTag,
-                                          const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success,
+                                          const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, LEErrorCode &success,
                                           const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const
 {
     if (LE_FAILURE(success)) {
         return;
     }
 
-    GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success);
+    GlyphPositioningLookupProcessor processor(base, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success);
     if (LE_FAILURE(success)) {
         return;
     }
--- a/src/share/native/sun/font/layout/GlyphPositioningTables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphPositioningTables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -40,6 +40,7 @@
 #include "OpenTypeTables.h"
 #include "Lookups.h"
 #include "GlyphLookupTables.h"
+#include "LETableReference.h"
 
 U_NAMESPACE_BEGIN
 
@@ -51,9 +52,9 @@
 
 struct GlyphPositioningTableHeader : public GlyphLookupTableHeader
 {
-    void    process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
+  void    process(const LEReferenceTo<GlyphPositioningTableHeader> &base, LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
                 le_bool rightToLeft, LETag scriptTag, LETag languageTag,
-                const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success,
+                const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, LEErrorCode &success,
                 const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const;
 };
 
--- a/src/share/native/sun/font/layout/GlyphPosnLookupProc.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphPosnLookupProc.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -57,7 +57,7 @@
 typedef ChainingContextualSubstitutionSubtable ChainingContextualPositioningSubtable;
 
 GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor(
-        const GlyphPositioningTableHeader *glyphPositioningTableHeader,
+        const LEReferenceTo<GlyphPositioningTableHeader> &glyphPositioningTableHeader,
         LETag scriptTag,
         LETag languageTag,
         const FeatureMap *featureMap,
@@ -65,7 +65,7 @@
         le_bool featureOrder,
         LEErrorCode& success)
     : LookupProcessor(
-                      (char *) glyphPositioningTableHeader,
+                      glyphPositioningTableHeader,
                       SWAPW(glyphPositioningTableHeader->scriptListOffset),
                       SWAPW(glyphPositioningTableHeader->featureListOffset),
                       SWAPW(glyphPositioningTableHeader->lookupListOffset),
@@ -84,7 +84,7 @@
 {
 }
 
-le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType,
+le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType,
                                                        GlyphIterator *glyphIterator,
                                                        const LEFontInstance *fontInstance,
                                                        LEErrorCode& success) const
@@ -102,55 +102,55 @@
 
     case gpstSingle:
     {
-        const SinglePositioningSubtable *subtable = (const SinglePositioningSubtable *) lookupSubtable;
+      LEReferenceTo<SinglePositioningSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fontInstance);
+        delta = subtable->process(subtable, glyphIterator, fontInstance, success);
         break;
     }
 
     case gpstPair:
     {
-        const PairPositioningSubtable *subtable = (const PairPositioningSubtable *) lookupSubtable;
+        LEReferenceTo<PairPositioningSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fontInstance);
+        delta = subtable->process(subtable, glyphIterator, fontInstance, success);
         break;
     }
 
     case gpstCursive:
     {
-        const CursiveAttachmentSubtable *subtable = (const CursiveAttachmentSubtable *) lookupSubtable;
+        LEReferenceTo<CursiveAttachmentSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fontInstance);
+        delta = subtable->process(subtable, glyphIterator, fontInstance, success);
         break;
     }
 
     case gpstMarkToBase:
     {
-        const MarkToBasePositioningSubtable *subtable = (const MarkToBasePositioningSubtable *) lookupSubtable;
+        LEReferenceTo<MarkToBasePositioningSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fontInstance);
+        delta = subtable->process(subtable, glyphIterator, fontInstance, success);
         break;
     }
 
      case gpstMarkToLigature:
     {
-        const MarkToLigaturePositioningSubtable *subtable = (const MarkToLigaturePositioningSubtable *) lookupSubtable;
+        LEReferenceTo<MarkToLigaturePositioningSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fontInstance);
+        delta = subtable->process(subtable, glyphIterator, fontInstance, success);
         break;
     }
 
     case gpstMarkToMark:
     {
-        const MarkToMarkPositioningSubtable *subtable = (const MarkToMarkPositioningSubtable *) lookupSubtable;
+        LEReferenceTo<MarkToMarkPositioningSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fontInstance);
+        delta = subtable->process(subtable, glyphIterator, fontInstance, success);
         break;
     }
 
    case gpstContext:
     {
-        const ContextualPositioningSubtable *subtable = (const ContextualPositioningSubtable *) lookupSubtable;
+        LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success);
 
         delta = subtable->process(this, glyphIterator, fontInstance, success);
         break;
@@ -158,7 +158,7 @@
 
     case gpstChainedContext:
     {
-        const ChainingContextualPositioningSubtable *subtable = (const ChainingContextualPositioningSubtable *) lookupSubtable;
+        LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success);
 
         delta = subtable->process(this, glyphIterator, fontInstance, success);
         break;
@@ -166,7 +166,7 @@
 
     case gpstExtension:
     {
-        const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable;
+        LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
 
         delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
         break;
--- a/src/share/native/sun/font/layout/GlyphPosnLookupProc.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphPosnLookupProc.h	Mon Mar 04 12:29:30 2013 -0800
@@ -51,7 +51,7 @@
 class GlyphPositioningLookupProcessor : public LookupProcessor
 {
 public:
-    GlyphPositioningLookupProcessor(const GlyphPositioningTableHeader *glyphPositioningTableHeader,
+    GlyphPositioningLookupProcessor(const LEReferenceTo<GlyphPositioningTableHeader> &glyphPositioningTableHeader,
         LETag scriptTag,
         LETag languageTag,
         const FeatureMap *featureMap,
@@ -61,7 +61,7 @@
 
     virtual ~GlyphPositioningLookupProcessor();
 
-    virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
+    virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
         const LEFontInstance *fontInstance, LEErrorCode& success) const;
 
 protected:
--- a/src/share/native/sun/font/layout/GlyphSubstLookupProc.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphSubstLookupProc.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -51,7 +51,7 @@
 U_NAMESPACE_BEGIN
 
 GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor(
-        const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader,
+        const LEReferenceTo<GlyphSubstitutionTableHeader> &glyphSubstitutionTableHeader,
         LETag scriptTag,
         LETag languageTag,
         const LEGlyphFilter *filter,
@@ -60,7 +60,7 @@
         le_bool featureOrder,
         LEErrorCode& success)
     : LookupProcessor(
-                      (char *) glyphSubstitutionTableHeader,
+                      glyphSubstitutionTableHeader,
                       SWAPW(glyphSubstitutionTableHeader->scriptListOffset),
                       SWAPW(glyphSubstitutionTableHeader->featureListOffset),
                       SWAPW(glyphSubstitutionTableHeader->lookupListOffset),
@@ -73,7 +73,7 @@
 {
 }
 
-le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType,
+le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType,
                                                        GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
 {
     if (LE_FAILURE(success)) {
@@ -89,39 +89,39 @@
 
     case gsstSingle:
     {
-        const SingleSubstitutionSubtable *subtable = (const SingleSubstitutionSubtable *) lookupSubtable;
+        const LEReferenceTo<SingleSubstitutionSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fFilter);
+        delta = subtable->process(subtable, glyphIterator, success, fFilter);
         break;
     }
 
     case gsstMultiple:
     {
-        const MultipleSubstitutionSubtable *subtable = (const MultipleSubstitutionSubtable *) lookupSubtable;
+        const LEReferenceTo<MultipleSubstitutionSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, success, fFilter);
+        delta = subtable->process(subtable, glyphIterator, success, fFilter);
         break;
     }
 
     case gsstAlternate:
     {
-        const AlternateSubstitutionSubtable *subtable = (const AlternateSubstitutionSubtable *) lookupSubtable;
+        const LEReferenceTo<AlternateSubstitutionSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fFilter);
+        delta = subtable->process(subtable, glyphIterator, success, fFilter);
         break;
     }
 
     case gsstLigature:
     {
-        const LigatureSubstitutionSubtable *subtable = (const LigatureSubstitutionSubtable *) lookupSubtable;
+        const LEReferenceTo<LigatureSubstitutionSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fFilter);
+        delta = subtable->process(subtable, glyphIterator, success, fFilter);
         break;
     }
 
     case gsstContext:
     {
-        const ContextualSubstitutionSubtable *subtable = (const ContextualSubstitutionSubtable *) lookupSubtable;
+        const LEReferenceTo<ContextualSubstitutionSubtable> subtable(lookupSubtable, success);
 
         delta = subtable->process(this, glyphIterator, fontInstance, success);
         break;
@@ -129,7 +129,7 @@
 
     case gsstChainingContext:
     {
-        const ChainingContextualSubstitutionSubtable *subtable = (const ChainingContextualSubstitutionSubtable *) lookupSubtable;
+        const LEReferenceTo<ChainingContextualSubstitutionSubtable> subtable(lookupSubtable, success);
 
         delta = subtable->process(this, glyphIterator, fontInstance, success);
         break;
@@ -137,7 +137,7 @@
 
     case gsstExtension:
     {
-        const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable;
+        const LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
 
         delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
         break;
--- a/src/share/native/sun/font/layout/GlyphSubstLookupProc.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphSubstLookupProc.h	Mon Mar 04 12:29:30 2013 -0800
@@ -52,7 +52,7 @@
 class GlyphSubstitutionLookupProcessor : public LookupProcessor
 {
 public:
-    GlyphSubstitutionLookupProcessor(const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader,
+    GlyphSubstitutionLookupProcessor(const LEReferenceTo<GlyphSubstitutionTableHeader> &glyphSubstitutionTableHeader,
         LETag scriptTag,
         LETag languageTag,
         const LEGlyphFilter *filter,
@@ -63,7 +63,7 @@
 
     virtual ~GlyphSubstitutionLookupProcessor();
 
-    virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
+    virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
         const LEFontInstance *fontInstance, LEErrorCode& success) const;
 
 protected:
--- a/src/share/native/sun/font/layout/GlyphSubstitutionTables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphSubstitutionTables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -42,11 +42,12 @@
 
 U_NAMESPACE_BEGIN
 
-le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage,
+le_int32 GlyphSubstitutionTableHeader::process(const LEReferenceTo<GlyphSubstitutionTableHeader> &base,
+                                               LEGlyphStorage &glyphStorage,
                                                le_bool rightToLeft,
                                                LETag scriptTag,
                                                LETag languageTag,
-                                           const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
+                                               const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
                                                const LEGlyphFilter *filter,
                                                const FeatureMap *featureMap,
                                                le_int32 featureMapCount,
@@ -57,7 +58,7 @@
         return 0;
     }
 
-    GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder, success);
+    GlyphSubstitutionLookupProcessor processor(base, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder, success);
     return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL, success);
 }
 
--- a/src/share/native/sun/font/layout/GlyphSubstitutionTables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/GlyphSubstitutionTables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,11 +50,12 @@
 
 struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader
 {
-    le_int32    process(LEGlyphStorage &glyphStorage,
+  le_int32    process(const LEReferenceTo<GlyphSubstitutionTableHeader> &base,
+                      LEGlyphStorage &glyphStorage,
                         le_bool rightToLeft,
                         LETag scriptTag,
                         LETag languageTag,
-                        const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
+                        const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
                         const LEGlyphFilter *filter,
                         const FeatureMap *featureMap,
                         le_int32 featureMapCount,
--- a/src/share/native/sun/font/layout/HanLayoutEngine.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/HanLayoutEngine.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -64,7 +64,7 @@
 #define features (loclFeatureMask)
 
 HanOpenTypeLayoutEngine::HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                        le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
+                                                 le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
 {
     fFeatureMap      = featureMap;
--- a/src/share/native/sun/font/layout/HanLayoutEngine.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/HanLayoutEngine.h	Mon Mar 04 12:29:30 2013 -0800
@@ -73,7 +73,7 @@
      * @internal
      */
     HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                            le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTablem, LEErrorCode &success);
+                            le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTablem, LEErrorCode &success);
 
 
     /**
--- a/src/share/native/sun/font/layout/HangulLayoutEngine.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/HangulLayoutEngine.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -209,7 +209,7 @@
 }
 
 HangulOpenTypeLayoutEngine::HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 /*languageCode*/,
-                                       le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
+                                                       le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags, gsubTable, success)
 {
     fFeatureMap = featureMap;
--- a/src/share/native/sun/font/layout/HangulLayoutEngine.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/HangulLayoutEngine.h	Mon Mar 04 12:29:30 2013 -0800
@@ -79,7 +79,7 @@
      * @internal
      */
     HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                            le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
+                               le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
 
     /**
      * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/ICUFeatures.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ICUFeatures.h	Mon Mar 04 12:29:30 2013 -0800
@@ -54,16 +54,21 @@
     le_uint16   lookupCount;
     le_uint16   lookupListIndexArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(FeatureTable, lookupListIndexArray)
 
 struct FeatureListTable
 {
     le_uint16           featureCount;
     FeatureRecord       featureRecordArray[ANY_NUMBER];
 
-    const FeatureTable  *getFeatureTable(le_uint16 featureIndex, LETag *featureTag) const;
+  LEReferenceTo<FeatureTable>  getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const;
 
-    const FeatureTable *getFeatureTable(LETag featureTag) const;
+#if 0
+  const LEReferenceTo<FeatureTable>  getFeatureTable(const LETableReference &base, LETag featureTag, LEErrorCode &success) const;
+#endif
 };
 
+LE_VAR_ARRAY(FeatureListTable, featureRecordArray)
+
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/IndicLayoutEngine.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/IndicLayoutEngine.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -50,7 +50,7 @@
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine)
 
 IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                    le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
+                                                     le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success), fMPreFixups(NULL)
 {
         if ( version2 ) {
--- a/src/share/native/sun/font/layout/IndicLayoutEngine.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/IndicLayoutEngine.h	Mon Mar 04 12:29:30 2013 -0800
@@ -81,7 +81,7 @@
      * @internal
      */
     IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                            le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
+                            le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
 
     /**
      * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/IndicRearrangementProcessor.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -43,11 +43,14 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor)
 
-IndicRearrangementProcessor::IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader)
-  : StateTableProcessor(morphSubtableHeader)
+  IndicRearrangementProcessor::IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+  : StateTableProcessor(morphSubtableHeader, success),
+  indicRearrangementSubtableHeader(morphSubtableHeader, success),
+  entryTable(stateTableHeader, success, (const IndicRearrangementStateEntry*)(&stateTableHeader->stHeader),
+             entryTableOffset, LE_UNBOUNDED_ARRAY),
+  int16Table(stateTableHeader, success, (const le_int16*)entryTable.getAlias(), 0, LE_UNBOUNDED_ARRAY)
+
 {
-    indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader *) morphSubtableHeader;
-    entryTable = (const IndicRearrangementStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
 }
 
 IndicRearrangementProcessor::~IndicRearrangementProcessor()
@@ -62,7 +65,8 @@
 
 ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
 {
-    const IndicRearrangementStateEntry *entry = &entryTable[index];
+  LEErrorCode success = LE_NO_ERROR; // todo- make a param?
+  const IndicRearrangementStateEntry *entry = entryTable.getAlias(index,success);
     ByteOffset newState = SWAPW(entry->newStateOffset);
     IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
 
--- a/src/share/native/sun/font/layout/IndicRearrangementProcessor.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor.h	Mon Mar 04 12:29:30 2013 -0800
@@ -58,7 +58,7 @@
 
     void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const;
 
-    IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
     virtual ~IndicRearrangementProcessor();
 
     /**
@@ -79,8 +79,9 @@
     le_int32 firstGlyph;
     le_int32 lastGlyph;
 
-    const IndicRearrangementStateEntry *entryTable;
-    const IndicRearrangementSubtableHeader *indicRearrangementSubtableHeader;
+    LEReferenceTo<IndicRearrangementSubtableHeader> indicRearrangementSubtableHeader;
+    LEReferenceToArrayOf<IndicRearrangementStateEntry> entryTable;
+    LEReferenceToArrayOf<le_int16> int16Table;
 
 };
 
--- a/src/share/native/sun/font/layout/IndicRearrangementProcessor2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -43,11 +43,11 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)
 
-IndicRearrangementProcessor2::IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
-  : StateTableProcessor2(morphSubtableHeader)
+IndicRearrangementProcessor2::IndicRearrangementProcessor2(
+      const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : StateTableProcessor2(morphSubtableHeader, success), indicRearrangementSubtableHeader(morphSubtableHeader, success),
+  entryTable(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY)
 {
-    indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader2 *) morphSubtableHeader;
-    entryTable = (const IndicRearrangementStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
 }
 
 IndicRearrangementProcessor2::~IndicRearrangementProcessor2()
@@ -60,9 +60,11 @@
     lastGlyph = 0;
 }
 
-le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
+le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
+                                                          EntryTableIndex2 index, LEErrorCode &success)
 {
-    const IndicRearrangementStateEntry2 *entry = &entryTable[index];
+    const IndicRearrangementStateEntry2 *entry = entryTable.getAlias(index, success);
+    if (LE_FAILURE(success)) return 0; // TODO - what to return in bad state?
     le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state
     IndicRearrangementFlags  flags =  (IndicRearrangementFlags) SWAPW(entry->flags);
 
--- a/src/share/native/sun/font/layout/IndicRearrangementProcessor2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -52,13 +52,13 @@
 public:
     virtual void beginStateTable();
 
-    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
 
     virtual void endStateTable();
 
     void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const;
 
-    IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    IndicRearrangementProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
     virtual ~IndicRearrangementProcessor2();
 
     /**
@@ -79,8 +79,8 @@
     le_int32 firstGlyph;
     le_int32 lastGlyph;
 
-    const IndicRearrangementStateEntry2 *entryTable;
-    const IndicRearrangementSubtableHeader2 *indicRearrangementSubtableHeader;
+    LEReferenceToArrayOf<IndicRearrangementStateEntry2> entryTable;
+    LEReferenceTo<IndicRearrangementSubtableHeader2> indicRearrangementSubtableHeader;
 
 };
 
--- a/src/share/native/sun/font/layout/IndicReordering.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/IndicReordering.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -658,6 +658,11 @@
     MPreFixups *mpreFixups = NULL;
     const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode);
 
+    if(classTable==NULL) {
+      success = LE_MEMORY_ALLOCATION_ERROR;
+      return 0;
+    }
+
     if (classTable->scriptFlags & SF_MPRE_FIXUP) {
         mpreFixups = new MPreFixups(charCount);
         if (mpreFixups == NULL) {
--- a/src/share/native/sun/font/layout/KernTable.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/KernTable.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -92,16 +92,16 @@
  * TODO: support multiple subtables
  * TODO: respect header flags
  */
-KernTable::KernTable(const LEFontInstance* font_, const void* tableData)
-  : pairs(0), font(font_)
+KernTable::KernTable(const LETableReference &table, LEErrorCode &success)
+  : pairs(table, success), pairsSwapped(NULL), fTable(table)
 {
-  const KernTableHeader* header = (const KernTableHeader*)tableData;
-  if (header == 0) {
+  if(LE_FAILURE(success) || (fTable.isEmpty())) {
 #if DEBUG
     fprintf(stderr, "no kern data\n");
 #endif
     return;
   }
+  LEReferenceTo<KernTableHeader> header(fTable, success);
 
 #if DEBUG
   // dump first 32 bytes of header
@@ -115,12 +115,17 @@
   }
 #endif
 
-  if (header->version == 0 && SWAPW(header->nTables) > 0) {
-    const SubtableHeader* subhead = (const SubtableHeader*)((char*)tableData + KERN_TABLE_HEADER_SIZE);
-    if (subhead->version == 0) {
+  if(LE_FAILURE(success)) return;
+
+  if (!header.isEmpty() && header->version == 0 && SWAPW(header->nTables) > 0) {
+    LEReferenceTo<SubtableHeader> subhead(header, success, KERN_TABLE_HEADER_SIZE);
+
+    if (LE_SUCCESS(success) && !subhead.isEmpty() && subhead->version == 0) {
       coverage = SWAPW(subhead->coverage);
       if (coverage & COVERAGE_HORIZONTAL) { // only handle horizontal kerning
-        const Subtable_0* table = (const Subtable_0*)((char*)subhead + KERN_SUBTABLE_HEADER_SIZE);
+        LEReferenceTo<Subtable_0> table(subhead, success, KERN_SUBTABLE_HEADER_SIZE);
+
+        if(table.isEmpty() || LE_FAILURE(success)) return;
 
         nPairs        = SWAPW(table->nPairs);
 
@@ -134,17 +139,17 @@
         rangeShift    = (nPairs * KERN_PAIRINFO_SIZE) - searchRange;
 #endif
 
-        pairs = (PairInfo*)font->getKernPairs();
-        if (pairs == NULL) {
-            char *pairData = (char*)table + KERN_SUBTABLE_0_HEADER_SIZE;
-            char *pptr = pairData;
-            pairs =  (PairInfo*)(malloc(nPairs*sizeof(PairInfo)));
-            PairInfo *p = (PairInfo*)pairs;
-            for (int i = 0; i < nPairs; i++, pptr += KERN_PAIRINFO_SIZE, p++) {
-              memcpy(p, pptr, KERN_PAIRINFO_SIZE);
+        if(LE_SUCCESS(success) && nPairs>0) {
+          pairs.setToOffsetInParent(table, KERN_SUBTABLE_0_HEADER_SIZE, nPairs, success);
+        }
+        if (LE_SUCCESS(success) && pairs.isValid()) {
+            pairsSwapped =  (PairInfo*)(malloc(nPairs*sizeof(PairInfo)));
+            PairInfo *p = (PairInfo*)pairsSwapped;
+            for (int i = 0; LE_SUCCESS(success) && i < nPairs; i++, p++) {
+              memcpy(p, pairs.getAlias(i,success), KERN_PAIRINFO_SIZE);
               p->key = SWAPL(p->key);
             }
-            font->setKernPairs((void*)pairs);
+            fTable.getFont()->setKernPairs((void*)pairsSwapped); // store it
         }
 
 #if DEBUG
@@ -194,10 +199,12 @@
  * Process the glyph positions.  The positions array has two floats for each
  * glyph, plus a trailing pair to mark the end of the last glyph.
  */
-void KernTable::process(LEGlyphStorage& storage)
+void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
 {
-  if (pairs) {
-    LEErrorCode success = LE_NO_ERROR;
+  if(LE_FAILURE(success)) return;
+
+  if (pairsSwapped) {
+    success = LE_NO_ERROR;
 
     le_uint32 key = storage[0]; // no need to mask off high bits
     float adjust = 0;
@@ -209,7 +216,7 @@
       // so either I have to swap the element each time I examine it, or I have to swap
       // all the elements ahead of time and store them in the font
 
-      const PairInfo* p = pairs;
+      const PairInfo* p = pairsSwapped;
       const PairInfo* tp = (const PairInfo*)(p + (rangeShift/KERN_PAIRINFO_SIZE)); /* rangeshift is in original table bytes */
       if (key > tp->key) {
         p = tp;
@@ -225,7 +232,7 @@
         tp = (const PairInfo*)(p + (probe/KERN_PAIRINFO_SIZE));
         le_uint32 tkey = tp->key;
 #if DEBUG
-        fprintf(stdout, "   %.3d (%0.8x)\n", (tp - pairs), tkey);
+        fprintf(stdout, "   %.3d (%0.8x)\n", (tp - pairsSwapped), tkey);
 #endif
         if (tkey <= key) {
           if (tkey == key) {
@@ -240,10 +247,10 @@
             // device transform, or a faster way, such as moving the
             // entire kern table up to Java.
             LEPoint pt;
-            pt.fX = font->xUnitsToPoints(value);
+            pt.fX = fTable.getFont()->xUnitsToPoints(value);
             pt.fY = 0;
 
-            font->getKerningAdjustment(pt);
+            fTable.getFont()->getKerningAdjustment(pt);
             adjust += pt.fX;
             break;
           }
--- a/src/share/native/sun/font/layout/KernTable.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/KernTable.h	Mon Mar 04 12:29:30 2013 -0800
@@ -26,7 +26,7 @@
 /*
  *
  *
- * (C) Copyright IBM Corp. 2004-2005 - All Rights Reserved
+ * (C) Copyright IBM Corp. 2004-2013 - All Rights Reserved
  *
  */
 
@@ -38,6 +38,7 @@
 #endif
 
 #include "LETypes.h"
+#include "LETableReference.h"
 //#include "LEFontInstance.h"
 //#include "LEGlyphStorage.h"
 
@@ -56,19 +57,20 @@
  private:
   le_uint16 coverage;
   le_uint16 nPairs;
-  const PairInfo* pairs;
-  const LEFontInstance* font;
+  LEReferenceToArrayOf<PairInfo> pairs;
+  PairInfo  *pairsSwapped;
+  const LETableReference &fTable;
   le_uint16 searchRange;
   le_uint16 entrySelector;
   le_uint16 rangeShift;
 
  public:
-  KernTable(const LEFontInstance* font, const void* tableData);
+  KernTable(const LETableReference &table, LEErrorCode &success);
 
   /*
    * Process the glyph positions.
    */
-  void process(LEGlyphStorage& storage);
+  void process(LEGlyphStorage& storage, LEErrorCode &success);
 };
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/KhmerLayoutEngine.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/KhmerLayoutEngine.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -43,7 +43,7 @@
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(KhmerOpenTypeLayoutEngine)
 
 KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                    le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
+                                                     le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
 {
     fFeatureMap   = KhmerReordering::getFeatureMap(fFeatureMapCount);
--- a/src/share/native/sun/font/layout/KhmerLayoutEngine.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/KhmerLayoutEngine.h	Mon Mar 04 12:29:30 2013 -0800
@@ -83,7 +83,7 @@
      * @internal
      */
     KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                            le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
+                            le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
 
     /**
      * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/LEScripts.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LEScripts.h	Mon Mar 04 12:29:30 2013 -0800
@@ -258,10 +258,11 @@
  * @stable ICU 49
  */
 
-    khojScriptCode = 156,
-    tirhScriptCode = 157,
+    hluwScriptCode = 156, /* bump to match current ICU */
+    khojScriptCode = 157,
+    tirhScriptCode = 158,
 
-    scriptCodeCount = 158
+    scriptCodeCount = 159
 };
 
 U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/LETableReference.h	Mon Mar 04 12:29:30 2013 -0800
@@ -0,0 +1,497 @@
+/*
+ * 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++ -*-
+ *
+ * (C) Copyright IBM Corp. and others 2013 - All Rights Reserved
+ *
+ * Range checking
+ *
+ */
+
+#ifndef __LETABLEREFERENCE_H
+#define __LETABLEREFERENCE_H
+
+#include "LETypes.h"
+#include "LEFontInstance.h"
+
+
+#define kQuestionmarkTableTag  0x3F3F3F3FUL
+#define kTildeTableTag  0x7e7e7e7eUL
+#ifdef __cplusplus
+
+// internal - interface for range checking
+U_NAMESPACE_BEGIN
+
+#if LE_ASSERT_BAD_FONT
+class LETableReference; // fwd
+/**
+ *  defined in OpenTypeUtilities.cpp
+ * @internal
+ */
+U_INTERNAL void U_EXPORT2 _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len);
+
+#define LE_DEBUG_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
+#define LE_DEBUG_TR3(x,y,z) _debug_LETableReference(__FILE__, __LINE__, x, this, (const void*)y, (size_t)z);
+#if 0
+#define LE_TRACE_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
+#else
+#define LE_TRACE_TR(x)
+#endif
+
+#else
+#define LE_DEBUG_TR(x)
+#define LE_DEBUG_TR3(x,y,z)
+#define LE_TRACE_TR(x)
+#endif
+
+/**
+ * @internal
+ */
+class LETableReference {
+public:
+/**
+ * @internal
+ * Construct from a specific tag
+ */
+  LETableReference(const LEFontInstance* font, LETag tableTag, LEErrorCode &success) :
+    fFont(font), fTag(tableTag), fParent(NULL), fStart(NULL),fLength(LE_UINTPTR_MAX) {
+      loadTable(success);
+    LE_TRACE_TR("INFO: new table load")
+  }
+
+  LETableReference(const LETableReference &parent, LEErrorCode &success) : fFont(parent.fFont), fTag(parent.fTag), fParent(&parent), fStart(parent.fStart), fLength(parent.fLength) {
+    if(LE_FAILURE(success)) {
+      clear();
+    }
+    LE_TRACE_TR("INFO: new clone")
+  }
+
+   LETableReference(const le_uint8* data, size_t length = LE_UINTPTR_MAX) :
+    fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) {
+    LE_TRACE_TR("INFO: new raw")
+  }
+  LETableReference() :
+    fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(NULL), fLength(0) {
+    LE_TRACE_TR("INFO: new empty")
+  }
+
+  ~LETableReference() {
+    fTag=kTildeTableTag;
+    LE_TRACE_TR("INFO: new dtor")
+  }
+
+  /**
+   * @internal
+   * @param length  if LE_UINTPTR_MAX means "whole table"
+   * subset
+   */
+  LETableReference(const LETableReference &parent, size_t offset, size_t length,
+                   LEErrorCode &err) :
+    fFont(parent.fFont), fTag(parent.fTag), fParent(&parent),
+    fStart((parent.fStart)+offset), fLength(length) {
+    if(LE_SUCCESS(err)) {
+      if(isEmpty()) {
+        //err = LE_MISSING_FONT_TABLE_ERROR;
+        clear(); // it's just empty. Not an error.
+      } else if(offset >= fParent->fLength) {
+        LE_DEBUG_TR3("offset out of range: (%p) +%d", NULL, offset);
+        err = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+        clear();
+      } else {
+        if(fLength == LE_UINTPTR_MAX &&
+           fParent->fLength != LE_UINTPTR_MAX) {
+          fLength = (fParent->fLength) - offset; // decrement length as base address is incremented
+        }
+        if(fLength != LE_UINTPTR_MAX) {  // if we have bounds:
+          if(offset+fLength > fParent->fLength) {
+            LE_DEBUG_TR3("offset+fLength out of range: (%p) +%d", NULL, offset+fLength);
+            err = LE_INDEX_OUT_OF_BOUNDS_ERROR; // exceeded
+            clear();
+          }
+        }
+      }
+    } else {
+      clear();
+    }
+    LE_TRACE_TR("INFO: new subset")
+  }
+
+  const void* getAlias() const { return (const void*)fStart; }
+  const void* getAliasTODO() const { LE_DEBUG_TR("getAliasTODO()"); return (const void*)fStart; }
+  le_bool isEmpty() const { return fStart==NULL || fLength==0; }
+  le_bool isValid() const { return !isEmpty(); }
+  le_bool hasBounds() const { return fLength!=LE_UINTPTR_MAX; }
+  void clear() { fLength=0; fStart=NULL; }
+  size_t getLength() const { return fLength; }
+  const LEFontInstance* getFont() const { return fFont; }
+  LETag getTag() const { return fTag; }
+  const LETableReference* getParent() const { return fParent; }
+
+  void addOffset(size_t offset, LEErrorCode &success) {
+    if(hasBounds()) {
+      if(offset > fLength) {
+        LE_DEBUG_TR("addOffset off end");
+        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+        return;
+      } else {
+        fLength -= offset;
+      }
+    }
+    fStart += offset;
+  }
+
+  size_t ptrToOffset(const void *atPtr, LEErrorCode &success) const {
+    if(atPtr==NULL) return 0;
+    if(LE_FAILURE(success)) return LE_UINTPTR_MAX;
+    if((atPtr < fStart) ||
+       (hasBounds() && (atPtr > fStart+fLength))) {
+      LE_DEBUG_TR3("ptrToOffset args out of range: %p", atPtr, 0);
+      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+      return LE_UINTPTR_MAX;
+    }
+    return ((const le_uint8*)atPtr)-fStart;
+  }
+
+  /**
+   * Clamp down the length, for range checking.
+   */
+  size_t contractLength(size_t newLength) {
+    if(fLength!=LE_UINTPTR_MAX&&newLength>0&&newLength<=fLength) {
+      fLength = newLength;
+    }
+    return fLength;
+  }
+
+  /**
+   * Throw an error if offset+length off end
+   */
+public:
+  size_t verifyLength(size_t offset, size_t length, LEErrorCode &success) {
+    if(isValid()&&
+       LE_SUCCESS(success) &&
+       fLength!=LE_UINTPTR_MAX && length!=LE_UINTPTR_MAX && offset!=LE_UINTPTR_MAX &&
+       (offset+length)>fLength) {
+      LE_DEBUG_TR3("verifyLength failed (%p) %d",NULL, offset+length);
+      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+#if LE_ASSERT_BAD_FONT
+      fprintf(stderr, "offset=%lu, len=%lu, would be at %p, (%lu) off end. End at %p\n", offset,length, fStart+offset+length, (offset+length-fLength), (offset+length-fLength)+fStart);
+#endif
+    }
+    return fLength;
+  }
+
+  le_bool isSubsetOf(const LETableReference& base) const {
+    if(this == &base) return true;
+    if(fStart < base.fStart) return false;
+    if(base.hasBounds()) {
+      if(fStart >= base.fStart + base.fLength) return false;
+      if(hasBounds()) {
+        if(fStart + fLength > base.fStart + base.fLength) return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Change parent link to another
+   */
+  LETableReference &reparent(const LETableReference &base) {
+    fParent = &base;
+    return *this;
+  }
+
+  /**
+   * remove parent link. Factory functions should do this.
+   */
+  void orphan(void) {
+    fParent=NULL;
+  }
+
+protected:
+  const LEFontInstance* fFont;
+  LETag  fTag;
+  const LETableReference *fParent;
+  const le_uint8 *fStart; // keep as 8 bit internally, for pointer math
+  size_t fLength;
+
+  void loadTable(LEErrorCode &success) {
+    if(LE_SUCCESS(success)) {
+      fStart = (const le_uint8*)(fFont->getFontTable(fTag, fLength)); // note - a null table is not an error.
+    }
+  }
+
+  void setRaw(const void *data, size_t length = LE_UINTPTR_MAX) {
+    fFont = NULL;
+    fTag = kQuestionmarkTableTag;
+    fParent = NULL;
+    fStart = (const le_uint8*)data;
+    fLength = length;
+  }
+};
+
+
+template<class T>
+class LETableVarSizer {
+ public:
+  inline static size_t getSize();
+};
+
+// base definition- could override for adjustments
+template<class T> inline
+size_t LETableVarSizer<T>::getSize() {
+  return sizeof(T);
+}
+
+/**
+ * \def LE_VAR_ARRAY
+ * @param x Type (T)
+ * @param y some member that is of length ANY_NUMBER
+ * Call this after defining a class, for example:
+ *   LE_VAR_ARRAY(FeatureListTable,featureRecordArray)
+ * this is roughly equivalent to:
+ *   template<> inline size_t LETableVarSizer<FeatureListTable>::getSize() { return sizeof(FeatureListTable) - (sizeof(le_uint16)*ANY_NUMBER); }
+ * it's a specialization that informs the LETableReference subclasses to NOT include the variable array in the size.
+ * dereferencing NULL is valid here because we never actually dereference it, just inside sizeof.
+ */
+#define LE_VAR_ARRAY(x,y) template<> inline size_t LETableVarSizer<x>::getSize() { return sizeof(x) - (sizeof(((const x*)0)->y)); }
+
+/**
+ * Open a new entry based on an existing table
+ */
+
+/**
+ * \def LE_UNBOUNDED_ARRAY
+ * define an array with no *known* bound. Will trim to available size.
+ * @internal
+ */
+#define LE_UNBOUNDED_ARRAY LE_UINT32_MAX
+
+template<class T>
+class LEReferenceToArrayOf : public LETableReference {
+public:
+  LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, size_t offset, le_uint32 count)
+    : LETableReference(parent, offset, LE_UINTPTR_MAX, success), fCount(count) {
+    LE_TRACE_TR("INFO: new RTAO by offset")
+    if(LE_SUCCESS(success)) {
+      if(count == LE_UNBOUNDED_ARRAY) { // not a known length
+        count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
+      }
+      LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success);
+    }
+    if(LE_FAILURE(success)) {
+      fCount=0;
+      clear();
+    }
+  }
+
+  LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 count)
+    : LETableReference(parent, parent.ptrToOffset(array, success), LE_UINTPTR_MAX, success), fCount(count) {
+LE_TRACE_TR("INFO: new RTAO")
+    if(LE_SUCCESS(success)) {
+      if(count == LE_UNBOUNDED_ARRAY) { // not a known length
+        count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
+      }
+      LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success);
+    }
+    if(LE_FAILURE(success)) clear();
+  }
+ LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, size_t offset, le_uint32 count)
+   : LETableReference(parent, parent.ptrToOffset(array, success)+offset, LE_UINTPTR_MAX, success), fCount(count) {
+LE_TRACE_TR("INFO: new RTAO")
+    if(LE_SUCCESS(success)) {
+      if(count == LE_UNBOUNDED_ARRAY) { // not a known length
+        count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
+      }
+      LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success);
+    }
+    if(LE_FAILURE(success)) clear();
+  }
+
+ LEReferenceToArrayOf() :LETableReference(), fCount(0) {}
+
+  le_uint32 getCount() const { return fCount; }
+
+  using LETableReference::getAlias;
+
+  const T *getAlias(le_uint32 i, LEErrorCode &success) const {
+    if(LE_SUCCESS(success)&& i<getCount()) {
+      return  ((const T*)getAlias())+i;
+    } else {
+      if(LE_SUCCESS(success)) {
+        LE_DEBUG_TR("getAlias(subscript) out of range");
+        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+      }
+      return ((const T*)getAlias());  // return first item, so there's no crash
+    }
+  }
+
+  const T *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); return (const T*)fStart; }
+
+  const T& getObject(le_uint32 i, LEErrorCode &success) const {
+    return *getAlias(i,success);
+  }
+
+  const T& operator()(le_uint32 i, LEErrorCode &success) const {
+    return *getAlias(i,success);
+  }
+
+  size_t getOffsetFor(le_uint32 i, LEErrorCode &success) const {
+    if(LE_SUCCESS(success)&&i<getCount()) {
+      return LETableVarSizer<T>::getSize()*i;
+    } else {
+      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+    }
+    return 0;
+  }
+
+  LEReferenceToArrayOf<T> &reparent(const LETableReference &base) {
+    fParent = &base;
+    return *this;
+  }
+
+ LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) {
+    LE_TRACE_TR("INFO: null RTAO")
+  }
+
+  /**
+   * set this to point within our fParent, but based on 'base' as a subtable.
+   */
+  void setToOffsetInParent(const LETableReference& base, size_t offset, le_uint32 count, LEErrorCode &success) {
+LE_TRACE_TR("INFO: sTOIP")
+    if(LE_FAILURE(success)) return;
+    if(!fParent->isSubsetOf(base)) {  // Ensure that 'base' is containable within our parent.
+      clear();                        // otherwise, it's not a subtable of our parent.
+      LE_DEBUG_TR("setToOffsetInParents called on non subsets");
+      success = LE_ILLEGAL_ARGUMENT_ERROR; return;
+    }
+    size_t baseOffset = fParent->ptrToOffset(((const le_uint8*)base.getAlias())+offset, success);
+    if(LE_FAILURE(success)) return; // base was outside of parent's range
+    if(fParent->hasBounds()) {
+      if((baseOffset >= fParent->getLength()) || // start off end of parent
+         (baseOffset+(count*LETableVarSizer<T>::getSize()) >= fParent->getLength()) || // or off end of parent
+         count > LE_UINTPTR_MAX/LETableVarSizer<T>::getSize()) { // or more than would fit in memory
+        LE_DEBUG_TR("setToOffsetInParent called with bad length");
+        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+        clear();
+        return; // start would go off end of parent
+      }
+    }
+    fStart = (const le_uint8*)(fParent->getAlias()) + baseOffset;
+    //fLength = count*LETableVarSizer<T>::getSize(); - no- do not shrink fLength.
+    if(fParent->hasBounds()) {
+      fLength = (fParent->getLength() - (fStart-(const le_uint8*)fParent->getAlias())); // reduces fLength accordingly.
+    } else {
+      fLength = LE_UINTPTR_MAX; // unbounded
+    }
+    if((fStart < fParent->getAlias()) ||
+       (hasBounds()&&(fStart+fLength < fStart))) { // wrapped
+        LE_DEBUG_TR("setToOffsetInParent called with bad length");
+        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+        clear();
+        return; // start would go off end of parent
+    }
+    fCount = count;
+  }
+
+private:
+  le_uint32 fCount;
+};
+
+
+template<class T>
+class LEReferenceTo : public LETableReference {
+public:
+  /**
+   * open a sub reference.
+   * @param parent parent reference
+   * @param success error status
+   * @param atPtr location of reference - if NULL, will be at offset zero (i.e. downcast of parent). Otherwise must be a pointer within parent's bounds.
+   */
+  LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr)
+    : LETableReference(parent, parent.ptrToOffset(atPtr, success), LE_UINTPTR_MAX, success) {
+    verifyLength(parent.ptrToOffset(atPtr,success), LETableVarSizer<T>::getSize(), success);
+    if(LE_FAILURE(success)) clear();
+  }
+  /**
+   * ptr plus offset
+   */
+ LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr, size_t offset)
+    : LETableReference(parent, parent.ptrToOffset(atPtr, success)+offset, LE_UINTPTR_MAX, success) {
+    verifyLength(0, LETableVarSizer<T>::getSize(), success);
+    if(LE_FAILURE(success)) clear();
+  }
+  LEReferenceTo(const LETableReference &parent, LEErrorCode &success, size_t offset)
+    : LETableReference(parent, offset, LE_UINTPTR_MAX, success) {
+    verifyLength(0, LETableVarSizer<T>::getSize(), success);
+    if(LE_FAILURE(success)) clear();
+  }
+  LEReferenceTo(const LETableReference &parent, LEErrorCode &success)
+    : LETableReference(parent, 0, LE_UINTPTR_MAX, success) {
+    verifyLength(0, LETableVarSizer<T>::getSize(), success);
+    if(LE_FAILURE(success)) clear();
+  }
+ LEReferenceTo(const LEFontInstance *font, LETag tableTag, LEErrorCode &success)
+   : LETableReference(font, tableTag, success) {
+    verifyLength(0, LETableVarSizer<T>::getSize(), success);
+    if(LE_FAILURE(success)) clear();
+  }
+ LEReferenceTo(const le_uint8 *data, size_t length = LE_UINTPTR_MAX) : LETableReference(data, length) {}
+ LEReferenceTo(const T *data, size_t length = LE_UINTPTR_MAX) : LETableReference((const le_uint8*)data, length) {}
+  LEReferenceTo() : LETableReference(NULL) {}
+
+  LEReferenceTo<T>& operator=(const T* other) {
+    setRaw(other);
+    return *this;
+  }
+
+  LEReferenceTo<T> &reparent(const LETableReference &base) {
+    fParent = &base;
+    return *this;
+  }
+
+  /**
+   * roll forward by one <T> size.
+   * same as addOffset(LETableVarSizer<T>::getSize(),success)
+   */
+  void addObject(LEErrorCode &success) {
+    addOffset(LETableVarSizer<T>::getSize(), success);
+  }
+  void addObject(size_t count, LEErrorCode &success) {
+    addOffset(LETableVarSizer<T>::getSize()*count, success);
+  }
+
+  const T *operator->() const { return getAlias(); }
+  const T *getAlias() const { return (const T*)fStart; }
+  const T *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); return (const T*)fStart; }
+};
+
+
+U_NAMESPACE_END
+
+#endif
+
+#endif
--- a/src/share/native/sun/font/layout/LETypes.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LETypes.h	Mon Mar 04 12:29:30 2013 -0800
@@ -354,12 +354,15 @@
 /**
  * Max value representable by a uintptr
  */
+
+#ifndef UINT32_MAX
+#define LE_UINT32_MAX 0xFFFFFFFFU
+#else
+#define LE_UINT32_MAX UINT32_MAX
+#endif
+
 #ifndef UINTPTR_MAX
-#ifndef UINT32_MAX
-#define LE_UINTPTR_MAX 0xFFFFFFFFU
-#else
-#define LE_UINTPTR_MAX UINT32_MAX
-#endif
+#define LE_UINTPTR_MAX LE_UINT32_MAX
 #else
 #define LE_UINTPTR_MAX UINTPTR_MAX
 #endif
--- a/src/share/native/sun/font/layout/LayoutEngine.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LayoutEngine.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -147,21 +147,21 @@
 class CanonMarkFilter : public UMemory, public LEGlyphFilter
 {
 private:
-    const GlyphClassDefinitionTable *classDefTable;
+  const LEReferenceTo<GlyphClassDefinitionTable> classDefTable;
 
     CanonMarkFilter(const CanonMarkFilter &other); // forbid copying of this class
     CanonMarkFilter &operator=(const CanonMarkFilter &other); // forbid copying of this class
 
 public:
-    CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable);
+    CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
     virtual ~CanonMarkFilter();
 
     virtual le_bool accept(LEGlyphID glyph) const;
 };
 
-CanonMarkFilter::CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable)
+CanonMarkFilter::CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success)
+  : classDefTable(gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success))
 {
-    classDefTable = gdefTable->getMarkAttachClassDefinitionTable();
 }
 
 CanonMarkFilter::~CanonMarkFilter()
@@ -171,9 +171,10 @@
 
 le_bool CanonMarkFilter::accept(LEGlyphID glyph) const
 {
-    le_int32 glyphClass = classDefTable->getGlyphClass(glyph);
-
-    return glyphClass != 0;
+  LEErrorCode success = LE_NO_ERROR;
+  le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success);
+  if(LE_FAILURE(success)) return false;
+  return glyphClass != 0;
 }
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine)
@@ -262,20 +263,20 @@
       return count;
     }
 
-    const GlyphSubstitutionTableHeader *canonGSUBTable = (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
+    LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable((GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable);
     LETag scriptTag  = OpenTypeLayoutEngine::getScriptTag(fScriptCode);
     LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode);
     le_int32 i, dir = 1, out = 0, outCharCount = count;
 
-    if (canonGSUBTable->coversScript(scriptTag)) {
+    if (canonGSUBTable->coversScript(canonGSUBTable,scriptTag, success) || LE_SUCCESS(success)) {
         CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance);
         if (substitutionFilter == NULL) {
             success = LE_MEMORY_ALLOCATION_ERROR;
             return 0;
         }
 
-                const LEUnicode *inChars = &chars[offset];
-                LEUnicode *reordered = NULL;
+        const LEUnicode *inChars = &chars[offset];
+        LEUnicode *reordered = NULL;
         LEGlyphStorage fakeGlyphStorage;
 
         fakeGlyphStorage.allocateGlyphArray(count, rightToLeft, success);
@@ -285,20 +286,20 @@
             return 0;
         }
 
-                // This is the cheapest way to get mark reordering only for Hebrew.
-                // We could just do the mark reordering for all scripts, but most
-                // of them probably don't need it...
-                if (fScriptCode == hebrScriptCode) {
-                        reordered = LE_NEW_ARRAY(LEUnicode, count);
+        // This is the cheapest way to get mark reordering only for Hebrew.
+        // We could just do the mark reordering for all scripts, but most
+        // of them probably don't need it...
+        if (fScriptCode == hebrScriptCode) {
+          reordered = LE_NEW_ARRAY(LEUnicode, count);
 
-                        if (reordered == NULL) {
-                delete substitutionFilter;
-                                success = LE_MEMORY_ALLOCATION_ERROR;
-                                return 0;
-                        }
+          if (reordered == NULL) {
+            delete substitutionFilter;
+            success = LE_MEMORY_ALLOCATION_ERROR;
+            return 0;
+          }
 
-                        CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage);
-                        inChars = reordered;
+          CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage);
+          inChars = reordered;
                 }
 
         fakeGlyphStorage.allocateAuxData(success);
@@ -318,11 +319,11 @@
             fakeGlyphStorage.setAuxData(out, canonFeatures, success);
         }
 
-                if (reordered != NULL) {
-                        LE_DELETE_ARRAY(reordered);
-                }
+        if (reordered != NULL) {
+          LE_DELETE_ARRAY(reordered);
+        }
 
-        outCharCount = canonGSUBTable->process(fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);
+        outCharCount = canonGSUBTable->process(canonGSUBTable, fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, (const GlyphDefinitionTableHeader*)NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);
 
         if (LE_FAILURE(success)) {
             delete substitutionFilter;
@@ -423,16 +424,16 @@
         return;
     }
 
-    GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
-    CanonMarkFilter filter(gdefTable);
+    LEReferenceTo<GlyphDefinitionTableHeader> gdefTable((GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable,
+                                                        CanonShaping::glyphDefinitionTableLen);
+    CanonMarkFilter filter(gdefTable, success);
 
     adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
 
     if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
-      static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG;
-
-      KernTable kt(fFontInstance, getFontTable(kernTableTag));
-      kt.process(glyphStorage);
+      LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
+      KernTable kt(kernTable, success);
+      kt.process(glyphStorage, success);
     }
 
     // default is no adjustments
@@ -517,9 +518,9 @@
     glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success);
 }
 
-const void *LayoutEngine::getFontTable(LETag tableTag) const
+const void *LayoutEngine::getFontTable(LETag tableTag, size_t &length) const
 {
-    return fFontInstance->getFontTable(tableTag);
+  return fFontInstance->getFontTable(tableTag, length);
 }
 
 void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror,
@@ -566,7 +567,10 @@
 
 void LayoutEngine::reset()
 {
+  if(fGlyphStorage!=NULL) {
     fGlyphStorage->reset();
+    fGlyphStorage = NULL;
+  }
 }
 
 LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success)
@@ -585,19 +589,19 @@
         return NULL;
     }
 
-    const GlyphSubstitutionTableHeader *gsubTable = (const GlyphSubstitutionTableHeader *) fontInstance->getFontTable(gsubTableTag);
+    LEReferenceTo<GlyphSubstitutionTableHeader> gsubTable(fontInstance,gsubTableTag,success);
     LayoutEngine *result = NULL;
     LETag scriptTag   = 0x00000000;
     LETag languageTag = 0x00000000;
-        LETag v2ScriptTag = OpenTypeLayoutEngine::getV2ScriptTag(scriptCode);
+    LETag v2ScriptTag = OpenTypeLayoutEngine::getV2ScriptTag(scriptCode);
 
     // Right now, only invoke V2 processing for Devanagari.  TODO: Allow more V2 scripts as they are
     // properly tested.
 
-        if ( v2ScriptTag == dev2ScriptTag && gsubTable != NULL && gsubTable->coversScript( v2ScriptTag )) {
-                result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success);
-        }
-    else if (gsubTable != NULL && gsubTable->coversScript(scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode))) {
+    if ( v2ScriptTag == dev2ScriptTag && gsubTable.isValid() && gsubTable->coversScript(gsubTable, v2ScriptTag, success )) {
+      result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success);
+    }
+    else if (gsubTable.isValid() && gsubTable->coversScript(gsubTable, scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode), success)) {
         switch (scriptCode) {
         case bengScriptCode:
         case devaScriptCode:
@@ -633,10 +637,10 @@
             case janLanguageCode:
             case zhtLanguageCode:
             case zhsLanguageCode:
-                if (gsubTable->coversScriptAndLanguage(scriptTag, languageTag, TRUE)) {
+              if (gsubTable->coversScriptAndLanguage(gsubTable, scriptTag, languageTag, success, TRUE)) {
                     result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
                     break;
-                }
+              }
 
                 // note: falling through to default case.
             default:
@@ -663,9 +667,9 @@
         if (morxTable != NULL && SWAPL(morxTable->version)==0x00020000) {
             result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success);
         } else {
-            const MorphTableHeader *mortTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag);
-            if (mortTable != NULL && SWAPL(mortTable->version)==0x00010000) { // mort
-                result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, mortTable, success);
+          LEReferenceTo<MorphTableHeader> mortTable(fontInstance, mortTableTag, success);
+          if (LE_SUCCESS(success) && mortTable.isValid() && SWAPL(mortTable->version)==0x00010000) { // mort
+            result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, mortTable, success);
             } else {
                 switch (scriptCode) {
                     case bengScriptCode:
--- a/src/share/native/sun/font/layout/LayoutEngine.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LayoutEngine.h	Mon Mar 04 12:29:30 2013 -0800
@@ -280,12 +280,18 @@
      * some other way must override this method.
      *
      * @param tableTag - the four byte table tag.
+     * @param length - length to use
      *
      * @return the address of the table.
      *
      * @internal
      */
-    virtual const void *getFontTable(LETag tableTag) const;
+    virtual const void *getFontTable(LETag tableTag, size_t &length) const;
+
+    /**
+     * @deprecated
+     */
+    virtual const void *getFontTable(LETag tableTag) const { size_t ignored; return getFontTable(tableTag, ignored); }
 
     /**
      * This method does character to glyph mapping. The default implementation
--- a/src/share/native/sun/font/layout/LigatureSubstProc.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LigatureSubstProc.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -47,15 +47,15 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor)
 
-LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader)
-  : StateTableProcessor(morphSubtableHeader)
+  LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+: StateTableProcessor(morphSubtableHeader, success), ligatureSubstitutionHeader(morphSubtableHeader, success)
 {
-    ligatureSubstitutionHeader = (const LigatureSubstitutionHeader *) morphSubtableHeader;
+    if(LE_FAILURE(success)) return;
     ligatureActionTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureActionTableOffset);
     componentTableOffset = SWAPW(ligatureSubstitutionHeader->componentTableOffset);
     ligatureTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureTableOffset);
 
-    entryTable = (const LigatureSubstitutionStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
+    entryTable = LEReferenceToArrayOf<LigatureSubstitutionStateEntry>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
 }
 
 LigatureSubstitutionProcessor::~LigatureSubstitutionProcessor()
@@ -69,7 +69,9 @@
 
 ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
 {
-    const LigatureSubstitutionStateEntry *entry = &entryTable[index];
+  LEErrorCode success = LE_NO_ERROR;
+  const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
+
     ByteOffset newState = SWAPW(entry->newStateOffset);
     le_int16 flags = SWAPW(entry->flags);
 
@@ -88,7 +90,7 @@
     ByteOffset actionOffset = flags & lsfActionOffsetMask;
 
     if (actionOffset != 0) {
-        const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + actionOffset);
+      LEReferenceTo<LigatureActionEntry> ap(stHeader, success, actionOffset);
         LigatureActionEntry action;
         le_int32 offset, i = 0;
         le_int32 stack[nComponents];
@@ -97,7 +99,8 @@
         do {
             le_uint32 componentGlyph = componentStack[m--];
 
-            action = SWAPL(*ap++);
+            action = SWAPL(*ap.getAlias());
+            ap.addObject(success); // ap++
 
             if (m < 0) {
                 m = nComponents - 1;
@@ -105,37 +108,33 @@
 
             offset = action & lafComponentOffsetMask;
             if (offset != 0) {
-                const le_int16 *offsetTable = (const le_int16 *)((char *) &ligatureSubstitutionHeader->stHeader + 2 * SignExtend(offset, lafComponentOffsetMask));
-                const le_int16 *tableEnd = (const le_int16 *)((char *) &ligatureSubstitutionHeader + 1 * SWAPW(ligatureSubstitutionHeader->length));
+              LEReferenceToArrayOf<le_int16> offsetTable(stHeader, success, 2 * SignExtend(offset, lafComponentOffsetMask), LE_UNBOUNDED_ARRAY);
 
-                // Check if the font is internally consistent
-                if(tableEnd < (const le_int16*)&ligatureSubstitutionHeader  // stated end wrapped around?
-                   || offsetTable > tableEnd) { // offset past end of stated length?
+              if(LE_FAILURE(success)) {
                   currGlyph++;
                   LE_DEBUG_BAD_FONT("off end of ligature substitution header");
                   return newState; // get out! bad font
-                }
-
-                if(componentGlyph > glyphStorage.getGlyphCount()) {
-                  LE_DEBUG_BAD_FONT("preposterous componentGlyph");
-                  currGlyph++;
-                  return newState; // get out! bad font
-                }
-                i += SWAPW(offsetTable[LE_GET_GLYPH(glyphStorage[componentGlyph])]);
+              }
+              if(componentGlyph > glyphStorage.getGlyphCount()) {
+                LE_DEBUG_BAD_FONT("preposterous componentGlyph");
+                currGlyph++;
+                return newState; // get out! bad font
+              }
+              i += SWAPW(offsetTable.getObject(LE_GET_GLYPH(glyphStorage[componentGlyph]), success));
 
                 if (action & (lafLast | lafStore))  {
-                    const TTGlyphID *ligatureOffset = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + i);
-                    TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset);
+                  LEReferenceTo<TTGlyphID> ligatureOffset(stHeader, success, i);
+                  TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset.getAlias());
 
-                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
-                    if(mm==nComponents) {
-                      LE_DEBUG_BAD_FONT("exceeded nComponents");
-                      mm--; // don't overrun the stack.
-                    }
-                    stack[++mm] = componentGlyph;
-                    i = 0;
+                  glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
+                  if(mm==nComponents) {
+                    LE_DEBUG_BAD_FONT("exceeded nComponents");
+                    mm--; // don't overrun the stack.
+                  }
+                  stack[++mm] = componentGlyph;
+                  i = 0;
                 } else {
-                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
+                  glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
                 }
             }
 #if LE_ASSERT_BAD_FONT
@@ -146,11 +145,11 @@
         } while (!(action & lafLast)  && (m>=0) ); // stop if last bit is set, or if run out of items
 
         while (mm >= 0) {
-            if (++m >= nComponents) {
-                m = 0;
-            }
+          if (++m >= nComponents) {
+            m = 0;
+          }
 
-            componentStack[m] = stack[mm--];
+          componentStack[m] = stack[mm--];
         }
     }
 
--- a/src/share/native/sun/font/layout/LigatureSubstProc.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LigatureSubstProc.h	Mon Mar 04 12:29:30 2013 -0800
@@ -58,7 +58,7 @@
 
     virtual void endStateTable();
 
-    LigatureSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    LigatureSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
     virtual ~LigatureSubstitutionProcessor();
 
     /**
@@ -83,12 +83,12 @@
     ByteOffset componentTableOffset;
     ByteOffset ligatureTableOffset;
 
-    const LigatureSubstitutionStateEntry *entryTable;
+    LEReferenceToArrayOf<LigatureSubstitutionStateEntry> entryTable;
 
     le_int32 componentStack[nComponents];
     le_int16 m;
 
-    const LigatureSubstitutionHeader *ligatureSubstitutionHeader;
+    LEReferenceTo<LigatureSubstitutionHeader> ligatureSubstitutionHeader;
 
 };
 
--- a/src/share/native/sun/font/layout/LigatureSubstProc2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LigatureSubstProc2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -47,15 +47,18 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor2)
 
-LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
-  : StateTableProcessor2(morphSubtableHeader)
+LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : StateTableProcessor2(morphSubtableHeader, success),
+  ligActionOffset(0),
+  ligatureSubstitutionHeader(morphSubtableHeader, success), componentOffset(0), ligatureOffset(0), entryTable()
 {
-    ligatureSubstitutionHeader = (const LigatureSubstitutionHeader2 *) morphSubtableHeader;
+    if (LE_FAILURE(success)) return;
+
     ligActionOffset = SWAPL(ligatureSubstitutionHeader->ligActionOffset);
     componentOffset = SWAPL(ligatureSubstitutionHeader->componentOffset);
     ligatureOffset = SWAPL(ligatureSubstitutionHeader->ligatureOffset);
 
-    entryTable = (const LigatureSubstitutionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
+    entryTable = LEReferenceToArrayOf<LigatureSubstitutionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
 }
 
 LigatureSubstitutionProcessor2::~LigatureSubstitutionProcessor2()
@@ -67,9 +70,11 @@
     m = -1;
 }
 
-le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
+le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success)
 {
-    const LigatureSubstitutionStateEntry2 *entry = &entryTable[index];
+    const LigatureSubstitutionStateEntry2 *entry = entryTable.getAlias(index, success);
+    if(LE_FAILURE(success)) return 0;
+
     le_uint16 nextStateIndex = SWAPW(entry->nextStateIndex);
     le_uint16 flags = SWAPW(entry->entryFlags);
     le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex);
@@ -81,7 +86,7 @@
         componentStack[m] = currGlyph;
     } else if ( m == -1) {
         // bad font- skip this glyph.
-        LE_DEBUG_BAD_FONT("m==-1")
+        //LE_DEBUG_BAD_FONT("m==-1 (componentCount went negative)")
         currGlyph+= dir;
         return nextStateIndex;
     }
@@ -89,29 +94,25 @@
     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);
+        LEReferenceTo<LigatureActionEntry> ap(stHeader, success, ligActionOffset); // byte offset
+        ap.addObject(ligActionIndex - 1, success);  // index offset ( one before the actual start, because we will pre-increment)
+        LEReferenceToArrayOf<TTGlyphID> ligatureTable(stHeader, success, ligatureOffset, LE_UNBOUNDED_ARRAY);
         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);
-
-        const le_uint16 *tableEnd = (const le_uint16 *)((char *) &ligatureSubstitutionHeader + SWAPL(ligatureSubstitutionHeader->length));
-
-        // Check if the font is internally consistent
-        if(tableEnd < (const le_uint16*)&ligatureSubstitutionHeader  // stated end wrapped around?
-           || componentTable > tableEnd) { // offset past end of stated length?
+        LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY);
+        if(LE_FAILURE(success)) {
           currGlyph+= dir;
-          LE_DEBUG_BAD_FONT("ligatureSubstHeader off end of table")
             return nextStateIndex; // get out! bad font
         }
 
         do {
             le_uint32 componentGlyph = componentStack[m--]; // pop off
 
-            action = SWAPL(*ap++);
+            ap.addObject(success);
+            action = SWAPL(*ap.getAlias());
 
             if (m < 0) {
                 m = nComponents - 1;
@@ -124,10 +125,10 @@
                   currGlyph+= dir;
                   return nextStateIndex; // get out! bad font
                 }
-                i += SWAPW(componentTable[LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask))]);
+                i += SWAPW(componentTable(LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask)),success));
 
                 if (action & (lafLast | lafStore))  {
-                    TTGlyphID ligatureGlyph = SWAPW(ligatureTable[i]);
+                  TTGlyphID ligatureGlyph = SWAPW(ligatureTable(i,success));
                     glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
                     if(mm==nComponents) {
                       LE_DEBUG_BAD_FONT("exceeded nComponents");
--- a/src/share/native/sun/font/layout/LigatureSubstProc2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LigatureSubstProc2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -54,11 +54,12 @@
 public:
     virtual void beginStateTable();
 
-    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index);
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
+                                        EntryTableIndex2 index, LEErrorCode &success);
 
     virtual void endStateTable();
 
-    LigatureSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    LigatureSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
     virtual ~LigatureSubstitutionProcessor2();
 
     /**
@@ -83,12 +84,12 @@
     le_uint32 componentOffset;
     le_uint32 ligatureOffset;
 
-    const LigatureSubstitutionStateEntry2 *entryTable;
+    LEReferenceToArrayOf<LigatureSubstitutionStateEntry2> entryTable;
 
     le_int32 componentStack[nComponents];
     le_int16 m;
 
-    const LigatureSubstitutionHeader2 *ligatureSubstitutionHeader;
+    const LEReferenceTo<LigatureSubstitutionHeader2> ligatureSubstitutionHeader;
 
 };
 
--- a/src/share/native/sun/font/layout/LigatureSubstSubtables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LigatureSubstSubtables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -40,10 +40,10 @@
 
 U_NAMESPACE_BEGIN
 
-le_uint32 LigatureSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
+le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
 {
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
 
     if (coverageIndex >= 0) {
         Offset ligSetTableOffset = SWAPW(ligSetTableOffsetArray[coverageIndex]);
--- a/src/share/native/sun/font/layout/LigatureSubstSubtables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LigatureSubstSubtables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,6 +50,7 @@
     le_uint16 ligatureCount;
     Offset    ligatureTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(LigatureSetTable, ligatureTableOffsetArray)
 
 struct LigatureTable
 {
@@ -57,14 +58,16 @@
     le_uint16 compCount;
     TTGlyphID componentArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(LigatureTable, componentArray)
 
 struct LigatureSubstitutionSubtable : GlyphSubstitutionSubtable
 {
     le_uint16 ligSetCount;
     Offset    ligSetTableOffsetArray[ANY_NUMBER];
 
-    le_uint32  process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const;
+    le_uint32  process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
 };
+LE_VAR_ARRAY(LigatureSubstitutionSubtable, ligSetTableOffsetArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/LookupProcessor.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LookupProcessor.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -44,7 +44,7 @@
 
 U_NAMESPACE_BEGIN
 
-le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator,
+le_uint32 LookupProcessor::applyLookupTable(const LEReferenceTo<LookupTable> &lookupTable, GlyphIterator *glyphIterator,
                                          const LEFontInstance *fontInstance, LEErrorCode& success) const
 {
     if (LE_FAILURE(success)) {
@@ -57,7 +57,7 @@
     le_uint32 delta;
 
     for (le_uint16 subtable = 0; subtable < subtableCount; subtable += 1) {
-        const LookupSubtable *lookupSubtable = lookupTable->getLookupSubtable(subtable);
+      LEReferenceTo<LookupSubtable> lookupSubtable = lookupTable->getLookupSubtable(lookupTable, subtable, success);
 
         delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success);
 
@@ -72,7 +72,7 @@
 }
 
 le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
-                              le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
+                                  le_bool rightToLeft, const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
                               const LEFontInstance *fontInstance, LEErrorCode& success) const
 {
     if (LE_FAILURE(success)) {
@@ -89,13 +89,13 @@
                                 rightToLeft, 0, 0, glyphDefinitionTableHeader);
     le_int32 newGlyphCount = glyphCount;
 
-    for (le_uint16 order = 0; order < lookupOrderCount; order += 1) {
+    for (le_uint16 order = 0; order < lookupOrderCount && LE_SUCCESS(success); order += 1) {
         le_uint16 lookup = lookupOrderArray[order];
         FeatureMask selectMask = lookupSelectArray[lookup];
 
         if (selectMask != 0) {
-            const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup);
-            if (!lookupTable) {
+          const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success);
+          if (!lookupTable.isValid() ||LE_FAILURE(success) ) {
                 continue;
             }
             le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
@@ -103,7 +103,7 @@
             glyphIterator.reset(lookupFlags, selectMask);
 
             while (glyphIterator.findFeatureTag()) {
-                applyLookupTable(lookupTable, &glyphIterator, fontInstance, success);
+              applyLookupTable(lookupTable, &glyphIterator, fontInstance, success); // TODO
                 if (LE_FAILURE(success)) {
                     return 0;
                 }
@@ -123,8 +123,8 @@
         return 0;
     }
 
-    const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex);
-    if (lookupTable == NULL) {
+    const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookupTableIndex, success);
+    if (!lookupTable.isValid()) {
         success = LE_INTERNAL_ERROR;
         return 0;
     }
@@ -135,33 +135,35 @@
     return delta;
 }
 
-le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, FeatureMask featureMask, le_int32 order)
+le_int32 LookupProcessor::selectLookups(const LEReferenceTo<FeatureTable> &featureTable, FeatureMask featureMask, le_int32 order, LEErrorCode &success)
 {
-    le_uint16 lookupCount = featureTable? SWAPW(featureTable->lookupCount) : 0;
+  le_uint16 lookupCount = featureTable.isValid()? SWAPW(featureTable->lookupCount) : 0;
     le_int32  store = order;
 
-    for (le_uint16 lookup = 0; lookup < lookupCount; lookup += 1) {
-        le_uint16 lookupListIndex = SWAPW(featureTable->lookupListIndexArray[lookup]);
-        if (lookupListIndex >= lookupSelectCount) {
-            continue;
-        }
+    LEReferenceToArrayOf<le_uint16> lookupListIndexArray(featureTable, success, featureTable->lookupListIndexArray, lookupCount);
 
-        lookupSelectArray[lookupListIndex] |= featureMask;
-        lookupOrderArray[store++] = lookupListIndex;
+    for (le_uint16 lookup = 0; LE_SUCCESS(success) && lookup < lookupCount; lookup += 1) {
+      le_uint16 lookupListIndex = SWAPW(lookupListIndexArray.getObject(lookup,success));
+      if (lookupListIndex >= lookupSelectCount) {
+        continue;
+      }
+
+      lookupSelectArray[lookupListIndex] |= featureMask;
+      lookupOrderArray[store++] = lookupListIndex;
     }
 
     return store - order;
 }
 
-LookupProcessor::LookupProcessor(const char *baseAddress,
+LookupProcessor::LookupProcessor(const LETableReference &baseAddress,
         Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset,
         LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures,
         LEErrorCode& success)
-    : lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL), lookupSelectCount(0),
-      lookupOrderArray(NULL), lookupOrderCount(0)
+    : lookupListTable(), featureListTable(), lookupSelectArray(NULL), lookupSelectCount(0),
+      lookupOrderArray(NULL), lookupOrderCount(0), fReference(baseAddress)
 {
-    const ScriptListTable *scriptListTable = NULL;
-    const LangSysTable *langSysTable = NULL;
+  LEReferenceTo<ScriptListTable> scriptListTable;
+  LEReferenceTo<LangSysTable> langSysTable;
     le_uint16 featureCount = 0;
     le_uint16 lookupListCount = 0;
     le_uint16 requiredFeatureIndex;
@@ -171,29 +173,33 @@
     }
 
     if (scriptListOffset != 0) {
-        scriptListTable = (const ScriptListTable *) (baseAddress + scriptListOffset);
-        langSysTable = scriptListTable->findLanguage(scriptTag, languageTag);
+      scriptListTable = LEReferenceTo<ScriptListTable>(baseAddress, success, scriptListOffset);
+      langSysTable = scriptListTable->findLanguage(scriptListTable, scriptTag, languageTag, success);
 
-        if (langSysTable != 0) {
-            featureCount = SWAPW(langSysTable->featureCount);
-        }
+      if (langSysTable.isValid() && LE_SUCCESS(success)) {
+        featureCount = SWAPW(langSysTable->featureCount);
+      }
     }
 
     if (featureListOffset != 0) {
-        featureListTable = (const FeatureListTable *) (baseAddress + featureListOffset);
+      featureListTable = LEReferenceTo<FeatureListTable>(baseAddress, success, featureListOffset);
     }
 
     if (lookupListOffset != 0) {
-        lookupListTable = (const LookupListTable *) (baseAddress + lookupListOffset);
+      lookupListTable = LEReferenceTo<LookupListTable>(baseAddress,success, lookupListOffset);
+      if(LE_SUCCESS(success) && lookupListTable.isValid()) {
         lookupListCount = SWAPW(lookupListTable->lookupCount);
+      }
     }
 
-    if (langSysTable == NULL || featureListTable == NULL || lookupListTable == NULL ||
+    if (langSysTable.isEmpty() || featureListTable.isEmpty() || lookupListTable.isEmpty() ||
         featureCount == 0 || lookupListCount == 0) {
         return;
     }
 
-    requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
+    if(langSysTable.isValid()) {
+      requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
+    }
 
     lookupSelectArray = LE_NEW_ARRAY(FeatureMask, lookupListCount);
     if (lookupSelectArray == NULL) {
@@ -209,34 +215,38 @@
 
     le_int32 count, order = 0;
     le_uint32 featureReferences = 0;
-    const FeatureTable *featureTable = NULL;
+    LEReferenceTo<FeatureTable> featureTable;
     LETag featureTag;
 
-    const FeatureTable *requiredFeatureTable = NULL;
+    LEReferenceTo<FeatureTable> requiredFeatureTable;
     LETag requiredFeatureTag = 0x00000000U;
 
     // Count the total number of lookups referenced by all features. This will
     // be the maximum number of entries in the lookupOrderArray. We can't use
     // lookupListCount because some lookups might be referenced by more than
     // one feature.
-    for (le_uint32 feature = 0; feature < featureCount; feature += 1) {
-        le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
+    if(featureListTable.isValid() && LE_SUCCESS(success)) {
+      LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount);
 
-        featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
-        if (!featureTable) {
-             continue;
+      for (le_uint32 feature = 0; LE_SUCCESS(success)&&(feature < featureCount); feature += 1) {
+        le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature, success));
+
+        featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex,  &featureTag, success);
+        if (!featureTable.isValid() || LE_FAILURE(success)) {
+          continue;
         }
         featureReferences += SWAPW(featureTable->lookupCount);
+      }
     }
 
-    if (!featureTable) {
+    if (!featureTable.isValid() || LE_FAILURE(success)) {
         success = LE_INTERNAL_ERROR;
         return;
     }
 
     if (requiredFeatureIndex != 0xFFFF) {
-        requiredFeatureTable = featureListTable->getFeatureTable(requiredFeatureIndex, &requiredFeatureTag);
-        featureReferences += SWAPW(featureTable->lookupCount);
+      requiredFeatureTable = featureListTable->getFeatureTable(featureListTable, requiredFeatureIndex, &requiredFeatureTag, success);
+      featureReferences += SWAPW(featureTable->lookupCount);
     }
 
     lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences);
@@ -251,7 +261,7 @@
 
         // If this is the required feature, add its lookups
         if (requiredFeatureTag == fm.tag) {
-            count += selectLookups(requiredFeatureTable, fm.mask, order);
+          count += selectLookups(requiredFeatureTable, fm.mask, order, success);
         }
 
         if (orderFeatures) {
@@ -261,7 +271,8 @@
             }
 
             for (le_uint16 feature = 0; feature < featureCount; feature += 1) {
-                le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
+              LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount);
+              le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature,success));
 
                 // don't add the required feature to the list more than once...
                 // TODO: Do we need this check? (Spec. says required feature won't be in feature list...)
@@ -269,10 +280,10 @@
                     continue;
                 }
 
-                featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
+                featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success);
 
                 if (featureTag == fm.tag) {
-                    count += selectLookups(featureTable, fm.mask, order + count);
+                  count += selectLookups(featureTable, fm.mask, order + count, success);
                 }
             }
 
@@ -281,9 +292,10 @@
             }
 
             order += count;
-        } else {
-            for (le_uint16 feature = 0; feature < featureCount; feature += 1) {
-                le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
+        } else if(langSysTable.isValid()) {
+          LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount);
+          for (le_uint16 feature = 0; LE_SUCCESS(success)&& (feature < featureCount); feature += 1) {
+            le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature,success));
 
                 // don't add the required feature to the list more than once...
                 // NOTE: This check is commented out because the spec. says that
@@ -295,10 +307,10 @@
                 }
 #endif
 
-                featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
+                featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success);
 
                 if (featureTag == fm.tag) {
-                    order += selectLookups(featureTable, fm.mask, order);
+                  order += selectLookups(featureTable, fm.mask, order, success);
                 }
             }
         }
--- a/src/share/native/sun/font/layout/LookupProcessor.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LookupProcessor.h	Mon Mar 04 12:29:30 2013 -0800
@@ -41,6 +41,7 @@
 #include "LETypes.h"
 #include "LEFontInstance.h"
 #include "OpenTypeTables.h"
+#include "LETableReference.h"
 //#include "Lookups.h"
 //#include "Features.h"
 
@@ -59,19 +60,21 @@
 class LookupProcessor : public UMemory {
 public:
     le_int32 process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
-                 le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEFontInstance *fontInstance, LEErrorCode& success) const;
+                 le_bool rightToLeft, const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 
-    le_uint32 applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
+    le_uint32 applyLookupTable(const LEReferenceTo<LookupTable> &lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 
     le_uint32 applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 
-    virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 subtableType,
+    virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 subtableType,
         GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const = 0;
 
     virtual ~LookupProcessor();
 
+    const LETableReference &getReference() const { return fReference; }
+
 protected:
-     LookupProcessor(const char *baseAddress,
+    LookupProcessor(const LETableReference &baseAddress,
         Offset scriptListOffset,
         Offset featureListOffset,
         Offset lookupListOffset,
@@ -84,10 +87,10 @@
 
    LookupProcessor();
 
-    le_int32 selectLookups(const FeatureTable *featureTable, FeatureMask featureMask, le_int32 order);
+    le_int32 selectLookups(const LEReferenceTo<FeatureTable> &featureTable, FeatureMask featureMask, le_int32 order, LEErrorCode &success);
 
-    const LookupListTable   *lookupListTable;
-    const FeatureListTable  *featureListTable;
+    LEReferenceTo<LookupListTable>   lookupListTable;
+    LEReferenceTo<FeatureListTable>  featureListTable;
 
     FeatureMask            *lookupSelectArray;
     le_uint32              lookupSelectCount;
@@ -95,6 +98,8 @@
     le_uint16               *lookupOrderArray;
     le_uint32               lookupOrderCount;
 
+    LETableReference        fReference;
+
 private:
 
     LookupProcessor(const LookupProcessor &other); // forbid copying of this class
--- a/src/share/native/sun/font/layout/LookupTables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LookupTables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -49,22 +49,26 @@
     of the derived classes, and implement it in the others by casting
     the "this" pointer to the type that has the implementation.
 */
-const LookupSegment *BinarySearchLookupTable::lookupSegment(const LookupSegment *segments, LEGlyphID glyph) const
+const LookupSegment *BinarySearchLookupTable::lookupSegment(const LETableReference &base, const LookupSegment *segments, LEGlyphID glyph, LEErrorCode &success) const
 {
+
     le_int16  unity = SWAPW(unitSize);
     le_int16  probe = SWAPW(searchRange);
     le_int16  extra = SWAPW(rangeShift);
     TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
-    const LookupSegment *entry = segments;
-    const LookupSegment *trial = (const LookupSegment *) ((char *) entry + extra);
+    LEReferenceTo<LookupSegment> entry(base, success, segments);
+    LEReferenceTo<LookupSegment> trial(entry, success, extra);
+
+    if(LE_FAILURE(success)) return NULL;
 
     if (SWAPW(trial->lastGlyph) <= ttGlyph) {
         entry = trial;
     }
 
-    while (probe > unity) {
+    while (probe > unity && LE_SUCCESS(success)) {
         probe >>= 1;
-        trial = (const LookupSegment *) ((char *) entry + probe);
+        trial = entry; // copy
+        trial.addOffset(probe, success);
 
         if (SWAPW(trial->lastGlyph) <= ttGlyph) {
             entry = trial;
@@ -72,28 +76,29 @@
     }
 
     if (SWAPW(entry->firstGlyph) <= ttGlyph) {
-        return entry;
+      return entry.getAlias();
     }
 
     return NULL;
 }
 
-const LookupSingle *BinarySearchLookupTable::lookupSingle(const LookupSingle *entries, LEGlyphID glyph) const
+const LookupSingle *BinarySearchLookupTable::lookupSingle(const LETableReference &base, const LookupSingle *entries, LEGlyphID glyph, LEErrorCode &success) const
 {
     le_int16  unity = SWAPW(unitSize);
     le_int16  probe = SWAPW(searchRange);
     le_int16  extra = SWAPW(rangeShift);
     TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
-    const LookupSingle *entry = entries;
-    const LookupSingle *trial = (const LookupSingle *) ((char *) entry + extra);
+    LEReferenceTo<LookupSingle> entry(base, success, entries);
+    LEReferenceTo<LookupSingle> trial(entry, success, extra);
 
     if (SWAPW(trial->glyph) <= ttGlyph) {
         entry = trial;
     }
 
-    while (probe > unity) {
+    while (probe > unity && LE_SUCCESS(success)) {
         probe >>= 1;
-        trial = (const LookupSingle *) ((char *) entry + probe);
+        trial = entry;
+        trial.addOffset(probe, success);
 
         if (SWAPW(trial->glyph) <= ttGlyph) {
             entry = trial;
@@ -101,7 +106,7 @@
     }
 
     if (SWAPW(entry->glyph) == ttGlyph) {
-        return entry;
+      return entry.getAlias();
     }
 
     return NULL;
--- a/src/share/native/sun/font/layout/LookupTables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/LookupTables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -39,6 +39,7 @@
 
 #include "LETypes.h"
 #include "LayoutTables.h"
+#include "LETableReference.h"
 
 U_NAMESPACE_BEGIN
 
@@ -79,30 +80,34 @@
     le_int16 entrySelector;
     le_int16 rangeShift;
 
-    const LookupSegment *lookupSegment(const LookupSegment *segments, LEGlyphID glyph) const;
+    const LookupSegment *lookupSegment(const LETableReference &base, const LookupSegment *segments, LEGlyphID glyph, LEErrorCode &success) const;
 
-    const LookupSingle *lookupSingle(const LookupSingle *entries, LEGlyphID glyph) const;
+    const LookupSingle *lookupSingle(const LETableReference &base, const LookupSingle *entries, LEGlyphID glyph, LEErrorCode &success) const;
 };
 
 struct SimpleArrayLookupTable : LookupTable
 {
     LookupValue valueArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(SimpleArrayLookupTable, valueArray)
 
 struct SegmentSingleLookupTable : BinarySearchLookupTable
 {
     LookupSegment segments[ANY_NUMBER];
 };
+LE_VAR_ARRAY(SegmentSingleLookupTable, segments)
 
 struct SegmentArrayLookupTable : BinarySearchLookupTable
 {
     LookupSegment segments[ANY_NUMBER];
 };
+LE_VAR_ARRAY(SegmentArrayLookupTable, segments)
 
 struct SingleTableLookupTable : BinarySearchLookupTable
 {
     LookupSingle entries[ANY_NUMBER];
 };
+LE_VAR_ARRAY(SingleTableLookupTable, entries)
 
 struct TrimmedArrayLookupTable : LookupTable
 {
@@ -110,6 +115,7 @@
     TTGlyphID   glyphCount;
     LookupValue valueArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(TrimmedArrayLookupTable, valueArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/Lookups.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/Lookups.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -37,33 +37,35 @@
 
 U_NAMESPACE_BEGIN
 
-const LookupTable *LookupListTable::getLookupTable(le_uint16 lookupTableIndex) const
+const LEReferenceTo<LookupTable> LookupListTable::getLookupTable(const LEReferenceTo<LookupListTable> &base, le_uint16 lookupTableIndex, LEErrorCode &success) const
 {
-    if (lookupTableIndex >= SWAPW(lookupCount)) {
-        return 0;
-    }
+  LEReferenceToArrayOf<Offset> lookupTableOffsetArrayRef(base, success, (const Offset*)&lookupTableOffsetArray, SWAPW(lookupCount));
 
-    Offset lookupTableOffset = lookupTableOffsetArray[lookupTableIndex];
-
-    return (const LookupTable *) ((char *) this + SWAPW(lookupTableOffset));
+  if(LE_FAILURE(success) || lookupTableIndex>lookupTableOffsetArrayRef.getCount()) {
+    return LEReferenceTo<LookupTable>();
+  } else {
+    return LEReferenceTo<LookupTable>(base, success, SWAPW(lookupTableOffsetArrayRef.getObject(lookupTableIndex, success)));
+  }
 }
 
-const LookupSubtable *LookupTable::getLookupSubtable(le_uint16 subtableIndex) const
+const LEReferenceTo<LookupSubtable> LookupTable::getLookupSubtable(const LEReferenceTo<LookupTable> &base, le_uint16 subtableIndex, LEErrorCode &success) const
 {
-    if (subtableIndex >= SWAPW(subTableCount)) {
-        return 0;
-    }
+  LEReferenceToArrayOf<Offset> subTableOffsetArrayRef(base, success, (const Offset*)&subTableOffsetArray, SWAPW(subTableCount));
 
-    Offset subtableOffset = subTableOffsetArray[subtableIndex];
-
-    return (const LookupSubtable *) ((char *) this + SWAPW(subtableOffset));
+  if(LE_FAILURE(success) || subtableIndex>subTableOffsetArrayRef.getCount()) {
+    return LEReferenceTo<LookupSubtable>();
+  } else {
+    return LEReferenceTo<LookupSubtable>(base, success, SWAPW(subTableOffsetArrayRef.getObject(subtableIndex, success)));
+  }
 }
 
-le_int32 LookupSubtable::getGlyphCoverage(Offset tableOffset, LEGlyphID glyphID) const
+le_int32 LookupSubtable::getGlyphCoverage(const LEReferenceTo<LookupSubtable> &base, Offset tableOffset, LEGlyphID glyphID, LEErrorCode &success) const
 {
-    const CoverageTable *coverageTable = (const CoverageTable *) ((char *) this + SWAPW(tableOffset));
+  const LEReferenceTo<CoverageTable> coverageTable(base, success, SWAPW(tableOffset));
 
-    return coverageTable->getGlyphCoverage(glyphID);
+  if(LE_FAILURE(success)) return 0;
+
+  return coverageTable->getGlyphCoverage(glyphID);
 }
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/Lookups.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/Lookups.h	Mon Mar 04 12:29:30 2013 -0800
@@ -58,9 +58,14 @@
     le_uint16 subtableFormat;
     Offset    coverageTableOffset;
 
-    inline le_int32  getGlyphCoverage(LEGlyphID glyphID) const;
+  inline le_int32  getGlyphCoverage(const LEReferenceTo<LookupSubtable> &base, LEGlyphID glyphID, LEErrorCode &success) const;
 
-    le_int32  getGlyphCoverage(Offset tableOffset, LEGlyphID glyphID) const;
+  le_int32  getGlyphCoverage(const LEReferenceTo<LookupSubtable> &base, Offset tableOffset, LEGlyphID glyphID, LEErrorCode &success) const;
+
+  // convenience
+  inline le_int32  getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
+
+  inline le_int32  getGlyphCoverage(const LETableReference &base, Offset tableOffset, LEGlyphID glyphID, LEErrorCode &success) const;
 };
 
 struct LookupTable
@@ -70,20 +75,32 @@
     le_uint16       subTableCount;
     Offset          subTableOffsetArray[ANY_NUMBER];
 
-    const LookupSubtable  *getLookupSubtable(le_uint16 subtableIndex) const;
+  const LEReferenceTo<LookupSubtable> getLookupSubtable(const LEReferenceTo<LookupTable> &base, le_uint16 subtableIndex, LEErrorCode &success) const;
 };
+LE_VAR_ARRAY(LookupTable, subTableOffsetArray)
 
 struct LookupListTable
 {
     le_uint16   lookupCount;
     Offset      lookupTableOffsetArray[ANY_NUMBER];
 
-    const LookupTable *getLookupTable(le_uint16 lookupTableIndex) const;
+  const LEReferenceTo<LookupTable> getLookupTable(const LEReferenceTo<LookupListTable> &base, le_uint16 lookupTableIndex, LEErrorCode &success) const;
 };
+LE_VAR_ARRAY(LookupListTable, lookupTableOffsetArray)
 
-inline le_int32 LookupSubtable::getGlyphCoverage(LEGlyphID glyphID) const
+inline le_int32 LookupSubtable::getGlyphCoverage(const LEReferenceTo<LookupSubtable> &base, LEGlyphID glyphID, LEErrorCode &success) const
 {
-    return getGlyphCoverage(coverageTableOffset, glyphID);
+  return getGlyphCoverage(base, coverageTableOffset, glyphID, success);
+}
+
+inline le_int32  LookupSubtable::getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const {
+  LEReferenceTo<LookupSubtable> thisRef(base, success, this);
+  return getGlyphCoverage(thisRef, glyphID, success);
+}
+
+inline le_int32  LookupSubtable::getGlyphCoverage(const LETableReference &base, Offset tableOffset, LEGlyphID glyphID, LEErrorCode &success) const {
+  LEReferenceTo<LookupSubtable> thisRef(base, success, this);
+  return getGlyphCoverage(thisRef, tableOffset, glyphID, success);
 }
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/MarkArrays.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/MarkArrays.h	Mon Mar 04 12:29:30 2013 -0800
@@ -57,6 +57,7 @@
     le_int32 getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance,
         LEPoint &anchor) const;
 };
+LE_VAR_ARRAY(MarkArray, markRecordArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -51,10 +51,10 @@
     return 0xFFFF;
 }
 
-le_int32 MarkToBasePositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
+le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
 {
     LEGlyphID markGlyph = glyphIterator->getCurrGlyphID();
-    le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph);
+    le_int32 markCoverage = getGlyphCoverage(base, (LEGlyphID) markGlyph, success);
 
     if (markCoverage < 0) {
         // markGlyph isn't a covered mark glyph
@@ -75,7 +75,7 @@
     // FIXME: We probably don't want to find a base glyph before a previous ligature...
     GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/));
     LEGlyphID baseGlyph = findBaseGlyph(&baseIterator);
-    le_int32 baseCoverage = getBaseCoverage((LEGlyphID) baseGlyph);
+    le_int32 baseCoverage = getBaseCoverage(base, (LEGlyphID) baseGlyph, success);
     const BaseArray *baseArray = (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset));
     le_uint16 baseCount = SWAPW(baseArray->baseRecordCount);
 
--- a/src/share/native/sun/font/layout/MarkToBasePosnSubtables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/MarkToBasePosnSubtables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -48,7 +48,7 @@
 
 struct MarkToBasePositioningSubtable : AttachmentPositioningSubtable
 {
-    le_int32   process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
+  le_int32   process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
     LEGlyphID  findBaseGlyph(GlyphIterator *glyphIterator) const;
 };
 
@@ -56,12 +56,14 @@
 {
     Offset baseAnchorTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(BaseRecord, baseAnchorTableOffsetArray)
 
 struct BaseArray
 {
     le_int16 baseRecordCount;
     BaseRecord baseRecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(BaseArray, baseRecordArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -50,10 +50,10 @@
     return 0xFFFF;
 }
 
-le_int32 MarkToLigaturePositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
+le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
 {
     LEGlyphID markGlyph = glyphIterator->getCurrGlyphID();
-    le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph);
+    le_int32 markCoverage = getGlyphCoverage(base, (LEGlyphID) markGlyph, success);
 
     if (markCoverage < 0) {
         // markGlyph isn't a covered mark glyph
@@ -74,7 +74,7 @@
     // FIXME: we probably don't want to find a ligature before a previous base glyph...
     GlyphIterator ligatureIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/));
     LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator);
-    le_int32 ligatureCoverage = getBaseCoverage((LEGlyphID) ligatureGlyph);
+    le_int32 ligatureCoverage = getBaseCoverage(base, (LEGlyphID) ligatureGlyph, success);
     const LigatureArray *ligatureArray = (const LigatureArray *) ((char *) this + SWAPW(baseArrayOffset));
     le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount);
 
--- a/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -48,7 +48,7 @@
 
 struct MarkToLigaturePositioningSubtable : AttachmentPositioningSubtable
 {
-    le_int32   process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
+  le_int32   process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
     LEGlyphID  findLigatureGlyph(GlyphIterator *glyphIterator) const;
 };
 
@@ -56,18 +56,21 @@
 {
     Offset ligatureAnchorTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(ComponentRecord, ligatureAnchorTableOffsetArray)
 
 struct LigatureAttachTable
 {
     le_uint16 componentCount;
     ComponentRecord componentRecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(LigatureAttachTable, componentRecordArray)
 
 struct LigatureArray
 {
     le_uint16 ligatureCount;
     Offset ligatureAttachTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(LigatureArray, ligatureAttachTableOffsetArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -51,10 +51,10 @@
     return 0xFFFF;
 }
 
-le_int32 MarkToMarkPositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
+le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
 {
     LEGlyphID markGlyph = glyphIterator->getCurrGlyphID();
-    le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph);
+    le_int32 markCoverage = getGlyphCoverage(base, (LEGlyphID) markGlyph, success);
 
     if (markCoverage < 0) {
         // markGlyph isn't a covered mark glyph
@@ -74,7 +74,7 @@
 
     GlyphIterator mark2Iterator(*glyphIterator);
     LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator);
-    le_int32 mark2Coverage = getBaseCoverage((LEGlyphID) mark2Glyph);
+    le_int32 mark2Coverage = getBaseCoverage(base, (LEGlyphID) mark2Glyph, success);
     const Mark2Array *mark2Array = (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset));
     le_uint16 mark2Count = SWAPW(mark2Array->mark2RecordCount);
 
--- a/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -48,7 +48,7 @@
 
 struct MarkToMarkPositioningSubtable : AttachmentPositioningSubtable
 {
-    le_int32   process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
+  le_int32   process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
     LEGlyphID  findMark2Glyph(GlyphIterator *glyphIterator) const;
 };
 
@@ -56,12 +56,14 @@
 {
     Offset mark2AnchorTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(Mark2Record, mark2AnchorTableOffsetArray)
 
 struct Mark2Array
 {
     le_uint16 mark2RecordCount;
     Mark2Record mark2RecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(Mark2Array, mark2RecordArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/MorphTables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/MorphTables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -44,61 +44,61 @@
 
 U_NAMESPACE_BEGIN
 
-void MorphTableHeader::process(LEGlyphStorage &glyphStorage) const
+void MorphTableHeader::process(const LETableReference &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const
 {
-    const ChainHeader *chainHeader = chains;
-    le_uint32 chainCount = SWAPL(this->nChains);
+  le_uint32 chainCount = SWAPL(this->nChains);
+  LEReferenceTo<ChainHeader> chainHeader(base, success, chains); // moving header
+    LEReferenceToArrayOf<ChainHeader> chainHeaderArray(base, success, chains, chainCount);
     le_uint32 chain;
 
-    for (chain = 0; chain < chainCount; chain += 1) {
+    for (chain = 0; LE_SUCCESS(success) && (chain < chainCount); chain += 1) {
         FeatureFlags defaultFlags = SWAPL(chainHeader->defaultFlags);
         le_uint32 chainLength = SWAPL(chainHeader->chainLength);
         le_int16 nFeatureEntries = SWAPW(chainHeader->nFeatureEntries);
         le_int16 nSubtables = SWAPW(chainHeader->nSubtables);
-        const MorphSubtableHeader *subtableHeader =
-            (const MorphSubtableHeader *)&chainHeader->featureTable[nFeatureEntries];
+        LEReferenceTo<MorphSubtableHeader> subtableHeader =
+          LEReferenceTo<MorphSubtableHeader>(chainHeader,success, &(chainHeader->featureTable[nFeatureEntries]));
         le_int16 subtable;
 
-        for (subtable = 0; subtable < nSubtables; subtable += 1) {
+        for (subtable = 0; LE_SUCCESS(success) && (subtable < nSubtables); subtable += 1) {
             le_int16 length = SWAPW(subtableHeader->length);
             SubtableCoverage coverage = SWAPW(subtableHeader->coverage);
             FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
 
             // should check coverage more carefully...
-            if ((coverage & scfVertical) == 0 && (subtableFeatures & defaultFlags) != 0) {
-                subtableHeader->process(glyphStorage);
+            if ((coverage & scfVertical) == 0 && (subtableFeatures & defaultFlags) != 0  && LE_SUCCESS(success)) {
+              subtableHeader->process(subtableHeader, glyphStorage, success);
             }
 
-            subtableHeader = (const MorphSubtableHeader *) ((char *)subtableHeader + length);
+            subtableHeader.addOffset(length, success);
         }
-
-        chainHeader = (const ChainHeader *)((char *)chainHeader + chainLength);
+        chainHeader.addOffset(chainLength, success);
     }
 }
 
-void MorphSubtableHeader::process(LEGlyphStorage &glyphStorage) const
+void MorphSubtableHeader::process(const LEReferenceTo<MorphSubtableHeader> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const
 {
     SubtableProcessor *processor = NULL;
 
     switch (SWAPW(coverage) & scfTypeMask)
     {
     case mstIndicRearrangement:
-        processor = new IndicRearrangementProcessor(this);
+      processor = new IndicRearrangementProcessor(base, success);
         break;
 
     case mstContextualGlyphSubstitution:
-        processor = new ContextualGlyphSubstitutionProcessor(this);
+      processor = new ContextualGlyphSubstitutionProcessor(base, success);
         break;
 
     case mstLigatureSubstitution:
-        processor = new LigatureSubstitutionProcessor(this);
+      processor = new LigatureSubstitutionProcessor(base, success);
         break;
 
     case mstReservedUnused:
         break;
 
     case mstNonContextualGlyphSubstitution:
-        processor = NonContextualGlyphSubstitutionProcessor::createInstance(this);
+      processor = NonContextualGlyphSubstitutionProcessor::createInstance(base, success);
         break;
 
     /*
@@ -112,8 +112,10 @@
     }
 
     if (processor != NULL) {
-        processor->process(glyphStorage);
-        delete processor;
+      if(LE_SUCCESS(success)) {
+        processor->process(glyphStorage, success);
+      }
+      delete processor;
     }
 }
 
--- a/src/share/native/sun/font/layout/MorphTables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/MorphTables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -39,6 +39,7 @@
 
 #include "LETypes.h"
 #include "LayoutTables.h"
+#include "LETableReference.h"
 
 U_NAMESPACE_BEGIN
 
@@ -65,6 +66,7 @@
     le_int16           nSubtables;
     FeatureTableEntry   featureTable[ANY_NUMBER];
 };
+LE_VAR_ARRAY(ChainHeader, featureTable)
 
 struct MorphTableHeader
 {
@@ -72,8 +74,9 @@
     le_uint32   nChains;
     ChainHeader chains[ANY_NUMBER];
 
-    void process(LEGlyphStorage &glyphStorage) const;
+  void process(const LETableReference& base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const;
 };
+LE_VAR_ARRAY(MorphTableHeader, chains)
 
 typedef le_int16 SubtableCoverage;
 typedef le_uint32 SubtableCoverage2;
@@ -103,7 +106,7 @@
     SubtableCoverage    coverage;
     FeatureFlags        subtableFeatures;
 
-    void process(LEGlyphStorage &glyphStorage) const;
+  void process(const LEReferenceTo<MorphSubtableHeader> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const;
 };
 
 enum SubtableCoverageFlags2
@@ -121,7 +124,7 @@
     SubtableCoverage2    coverage;
     FeatureFlags        subtableFeatures;
 
-    void process(LEGlyphStorage &glyphStorage) const;
+    void process(const LEReferenceTo<MorphSubtableHeader2> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const;
 };
 
 struct ChainHeader2
@@ -132,6 +135,7 @@
     le_uint32           nSubtables;
     FeatureTableEntry   featureTable[ANY_NUMBER];
 };
+LE_VAR_ARRAY(ChainHeader2, featureTable)
 
 struct MorphTableHeader2
 {
@@ -139,8 +143,9 @@
     le_uint32   nChains;
     ChainHeader2 chains[ANY_NUMBER];
 
-    void process(LEGlyphStorage &glyphStorage, le_int32 typoFlags) const;
+    void process(const LEReferenceTo<MorphTableHeader2> &base, LEGlyphStorage &glyphStorage, le_int32 typoFlags, LEErrorCode &success) const;
 };
+LE_VAR_ARRAY(MorphTableHeader2, chains)
 
 /*
  * AAT Font Features
--- a/src/share/native/sun/font/layout/MorphTables2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/MorphTables2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -42,27 +42,40 @@
 
 U_NAMESPACE_BEGIN
 
-void MorphTableHeader2::process(LEGlyphStorage &glyphStorage, le_int32 typoFlags) const
+void MorphTableHeader2::process(const LEReferenceTo<MorphTableHeader2> &base, LEGlyphStorage &glyphStorage,
+                                le_int32 typoFlags, LEErrorCode &success) const
 {
-    const ChainHeader2 *chainHeader = chains;
-    le_uint32 chainCount = SWAPL(this->nChains);
-    le_uint32 chain;
+  if(LE_FAILURE(success)) return;
 
-    for (chain = 0; chain < chainCount; chain++) {
+  le_uint32 chainCount = SWAPL(this->nChains);
+  LEReferenceTo<ChainHeader2> chainHeader(base, success, &chains[0]);
+  /* chainHeader and subtableHeader are implemented as a moving pointer rather than an array dereference
+   * to (slightly) reduce code churn. However, must be careful to preincrement them the 2nd time through.
+   * We don't want to increment them at the end of the loop, as that would attempt to dereference
+   * out of range memory.
+   */
+  le_uint32 chain;
+
+  for (chain = 0; LE_SUCCESS(success) && (chain < chainCount); chain++) {
+        if (chain>0) {
+          le_uint32 chainLength = SWAPL(chainHeader->chainLength);
+          chainHeader.addOffset(chainLength, success); // Don't increment the first time
+        }
         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];
+        LEReferenceTo<MorphSubtableHeader2> subtableHeader(chainHeader,
+              success, (const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries]);
         le_uint32 subtable;
+        if(LE_FAILURE(success)) break; // malformed table
 
         if (typoFlags != 0) {
            le_uint32 featureEntry;
-
+           LEReferenceToArrayOf<FeatureTableEntry> featureTableRef(chainHeader, success, &chainHeader->featureTable[0], nFeatureEntries);
+           if(LE_FAILURE(success)) break;
             // Feature subtables
             for (featureEntry = 0; featureEntry < nFeatureEntries; featureEntry++) {
-                FeatureTableEntry featureTableEntry = chains->featureTable[featureEntry];
+                const FeatureTableEntry &featureTableEntry = featureTableRef(featureEntry, success);
                 le_int16 featureType = SWAPW(featureTableEntry.featureType);
                 le_int16 featureSetting = SWAPW(featureTableEntry.featureSetting);
                 le_uint32 enableFlags = SWAPL(featureTableEntry.enableFlags);
@@ -172,57 +185,63 @@
             }
         }
 
-        for (subtable = 0; subtable < nSubtables; subtable++) {
-            le_uint32 length = SWAPL(subtableHeader->length);
+        for (subtable = 0;  LE_SUCCESS(success) && subtable < nSubtables; subtable++) {
+            if(subtable>0)  {
+              le_uint32 length = SWAPL(subtableHeader->length);
+              subtableHeader.addOffset(length, success); // Don't addOffset for the last entry.
+            }
             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->process(subtableHeader, glyphStorage, success);
             }
-            subtableHeader = (const MorphSubtableHeader2 *) ((char *)subtableHeader + length);
         }
-        chainHeader = (const ChainHeader2 *)((char *)chainHeader + chainLength);
     }
 }
 
-void MorphSubtableHeader2::process(LEGlyphStorage &glyphStorage) const
+void MorphSubtableHeader2::process(const LEReferenceTo<MorphSubtableHeader2> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const
 {
     SubtableProcessor2 *processor = NULL;
 
     switch (SWAPL(coverage) & scfTypeMask2)
     {
     case mstIndicRearrangement:
-        processor = new IndicRearrangementProcessor2(this);
+        processor = new IndicRearrangementProcessor2(base, success);
         break;
 
     case mstContextualGlyphSubstitution:
-        processor = new ContextualGlyphSubstitutionProcessor2(this);
+        processor = new ContextualGlyphSubstitutionProcessor2(base, success);
         break;
 
     case mstLigatureSubstitution:
-        processor = new LigatureSubstitutionProcessor2(this);
+        processor = new LigatureSubstitutionProcessor2(base, success);
         break;
 
     case mstReservedUnused:
         break;
 
     case mstNonContextualGlyphSubstitution:
-        processor = NonContextualGlyphSubstitutionProcessor2::createInstance(this);
+        processor = NonContextualGlyphSubstitutionProcessor2::createInstance(base, success);
         break;
 
 
     case mstContextualGlyphInsertion:
-        processor = new ContextualGlyphInsertionProcessor2(this);
+        processor = new ContextualGlyphInsertionProcessor2(base, success);
         break;
 
     default:
-        break;
+        return;
+        break; /*NOTREACHED*/
     }
 
     if (processor != NULL) {
-        processor->process(glyphStorage);
+      processor->process(glyphStorage, success);
         delete processor;
+    } else {
+      if(LE_SUCCESS(success)) {
+        success = LE_MEMORY_ALLOCATION_ERROR; // because ptr is null and we didn't break out.
+      }
     }
 }
 
--- a/src/share/native/sun/font/layout/MultipleSubstSubtables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/MultipleSubstSubtables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -39,7 +39,7 @@
 
 U_NAMESPACE_BEGIN
 
-le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter) const
+le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter) const
 {
     if (LE_FAILURE(success)) {
         return 0;
@@ -58,7 +58,7 @@
         return 0;
     }
 
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
     le_uint16 seqCount = SWAPW(sequenceCount);
 
     if (coverageIndex >= 0 && coverageIndex < seqCount) {
--- a/src/share/native/sun/font/layout/MultipleSubstSubtables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/MultipleSubstSubtables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,14 +50,16 @@
     le_uint16 glyphCount;
     TTGlyphID substituteArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(SequenceTable, substituteArray)
 
 struct MultipleSubstitutionSubtable : GlyphSubstitutionSubtable
 {
     le_uint16 sequenceCount;
     Offset    sequenceTableOffsetArray[ANY_NUMBER];
 
-    le_uint32 process(GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter = NULL) const;
+    le_uint32 process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter = NULL) const;
 };
+LE_VAR_ARRAY(MultipleSubstitutionSubtable, sequenceTableOffsetArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/NonContextualGlyphSubstProc.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/NonContextualGlyphSubstProc.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -47,8 +47,8 @@
 {
 }
 
-NonContextualGlyphSubstitutionProcessor::NonContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader)
-    : SubtableProcessor(morphSubtableHeader)
+NonContextualGlyphSubstitutionProcessor::NonContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+  : SubtableProcessor(morphSubtableHeader, success)
 {
 }
 
@@ -56,26 +56,27 @@
 {
 }
 
-SubtableProcessor *NonContextualGlyphSubstitutionProcessor::createInstance(const MorphSubtableHeader *morphSubtableHeader)
+SubtableProcessor *NonContextualGlyphSubstitutionProcessor::createInstance(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
 {
-    const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader;
+  LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success);
 
-    switch (SWAPW(header->table.format))
-    {
+  if(LE_FAILURE(success)) return NULL;
+
+  switch (SWAPW(header->table.format)) {
     case ltfSimpleArray:
-        return new SimpleArrayProcessor(morphSubtableHeader);
+      return new SimpleArrayProcessor(morphSubtableHeader, success);
 
     case ltfSegmentSingle:
-        return new SegmentSingleProcessor(morphSubtableHeader);
+      return new SegmentSingleProcessor(morphSubtableHeader, success);
 
     case ltfSegmentArray:
-        return new SegmentArrayProcessor(morphSubtableHeader);
+      return new SegmentArrayProcessor(morphSubtableHeader, success);
 
     case ltfSingleTable:
-        return new SingleTableProcessor(morphSubtableHeader);
+      return new SingleTableProcessor(morphSubtableHeader, success);
 
     case ltfTrimmedArray:
-        return new TrimmedArrayProcessor(morphSubtableHeader);
+      return new TrimmedArrayProcessor(morphSubtableHeader, success);
 
     default:
         return NULL;
--- a/src/share/native/sun/font/layout/NonContextualGlyphSubstProc.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/NonContextualGlyphSubstProc.h	Mon Mar 04 12:29:30 2013 -0800
@@ -49,13 +49,13 @@
 class NonContextualGlyphSubstitutionProcessor : public SubtableProcessor
 {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage) = 0;
+  virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success) = 0;
 
-    static SubtableProcessor *createInstance(const MorphSubtableHeader *morphSubtableHeader);
+    static SubtableProcessor *createInstance(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
 
 protected:
     NonContextualGlyphSubstitutionProcessor();
-    NonContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    NonContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &status);
 
     virtual ~NonContextualGlyphSubstitutionProcessor();
 
--- a/src/share/native/sun/font/layout/NonContextualGlyphSubstProc2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/NonContextualGlyphSubstProc2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -47,8 +47,9 @@
 {
 }
 
-NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
-    : SubtableProcessor2(morphSubtableHeader)
+NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcessor2(
+     const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : SubtableProcessor2(morphSubtableHeader, success)
 {
 }
 
@@ -56,26 +57,28 @@
 {
 }
 
-SubtableProcessor2 *NonContextualGlyphSubstitutionProcessor2::createInstance(const MorphSubtableHeader2 *morphSubtableHeader)
+SubtableProcessor2 *NonContextualGlyphSubstitutionProcessor2::createInstance(
+      const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
 {
-    const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
+    const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success);
+    if(LE_FAILURE(success)) return NULL;
 
     switch (SWAPW(header->table.format))
     {
     case ltfSimpleArray:
-        return new SimpleArrayProcessor2(morphSubtableHeader);
+      return new SimpleArrayProcessor2(morphSubtableHeader, success);
 
     case ltfSegmentSingle:
-        return new SegmentSingleProcessor2(morphSubtableHeader);
+      return new SegmentSingleProcessor2(morphSubtableHeader, success);
 
     case ltfSegmentArray:
-        return new SegmentArrayProcessor2(morphSubtableHeader);
+      return new SegmentArrayProcessor2(morphSubtableHeader, success);
 
     case ltfSingleTable:
-        return new SingleTableProcessor2(morphSubtableHeader);
+      return new SingleTableProcessor2(morphSubtableHeader, success);
 
     case ltfTrimmedArray:
-        return new TrimmedArrayProcessor2(morphSubtableHeader);
+      return new TrimmedArrayProcessor2(morphSubtableHeader, success);
 
     default:
         return NULL;
--- a/src/share/native/sun/font/layout/NonContextualGlyphSubstProc2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/NonContextualGlyphSubstProc2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -49,13 +49,13 @@
 class NonContextualGlyphSubstitutionProcessor2 : public SubtableProcessor2
 {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage) = 0;
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success) = 0;
 
-    static SubtableProcessor2 *createInstance(const MorphSubtableHeader2 *morphSubtableHeader);
+    static SubtableProcessor2 *createInstance(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
 
 protected:
     NonContextualGlyphSubstitutionProcessor2();
-    NonContextualGlyphSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    NonContextualGlyphSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
 
     virtual ~NonContextualGlyphSubstitutionProcessor2();
 
--- a/src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -151,25 +151,21 @@
 static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
 
 OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                        le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
+                     le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
     : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureMask(minimalFeatures),
       fFeatureMap(featureMap), fFeatureMapCount(featureMapCount), fFeatureOrder(FALSE),
-      fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL)
+      fGSUBTable(gsubTable),
+      fGDEFTable(fontInstance, LE_GDEF_TABLE_TAG, success),
+      fGPOSTable(fontInstance, LE_GPOS_TABLE_TAG, success), fSubstitutionFilter(NULL)
 {
-    static const le_uint32 gdefTableTag = LE_GDEF_TABLE_TAG;
-    static const le_uint32 gposTableTag = LE_GPOS_TABLE_TAG;
-    const GlyphPositioningTableHeader *gposTable = (const GlyphPositioningTableHeader *) getFontTable(gposTableTag);
-
     applyTypoFlags();
 
     setScriptAndLanguageTags();
 
-    fGDEFTable = (const GlyphDefinitionTableHeader *) getFontTable(gdefTableTag);
-
 // JK patch, 2008-05-30 - see Sinhala bug report and LKLUG font
 //    if (gposTable != NULL && gposTable->coversScriptAndLanguage(fScriptTag, fLangSysTag)) {
-    if (gposTable != NULL && gposTable->coversScript(fScriptTag)) {
-        fGPOSTable = gposTable;
+    if (!fGPOSTable.isEmpty()&& !fGPOSTable->coversScript(fGPOSTable, fScriptTag, success)) {
+      fGPOSTable.clear(); // already loaded
     }
 }
 
@@ -252,7 +248,7 @@
 OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
                        le_int32 typoFlags, LEErrorCode &success)
     : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureOrder(FALSE),
-      fGSUBTable(NULL), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL)
+      fGSUBTable(), fGDEFTable(), fGPOSTable(), fSubstitutionFilter(NULL)
 {
   applyTypoFlags();
   setScriptAndLanguageTags();
@@ -375,13 +371,13 @@
         return 0;
     }
 
-    if (fGSUBTable != NULL) {
-        if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) {
-            count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter,
+    if (fGSUBTable.isValid()) {
+      if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fGSUBTable, fScriptTagV2, fLangSysTag, success)) {
+          count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter,
                                     fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
 
         } else {
-        count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter,
+          count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter,
                                     fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
     }
     }
@@ -402,13 +398,13 @@
         return 0;
     }
 
-    if (fGSUBTable != NULL) {
-        if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) {
-            count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter,
+    if (fGSUBTable.isValid()) {
+       if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fGSUBTable,fScriptTagV2,fLangSysTag,success)) {
+          count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter,
                                     fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
 
         } else {
-        count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter,
+          count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter,
                                     fFeatureMap, fFeatureMapCount, fFeatureOrder, success);
         }
     }
@@ -488,7 +484,7 @@
         return;
     }
 
-    if (fGPOSTable != NULL) {
+    if (!fGPOSTable.isEmpty()) {
         GlyphPositionAdjustments *adjustments = new GlyphPositionAdjustments(glyphCount);
         le_int32 i;
 
@@ -511,19 +507,20 @@
         }
 #endif
 
-        if (fGPOSTable != NULL) {
-            if (fScriptTagV2 != nullScriptTag && fGPOSTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) {
-                fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag, fGDEFTable, success, fFontInstance,
-                            fFeatureMap, fFeatureMapCount, fFeatureOrder);
+        if (!fGPOSTable.isEmpty()) {
+            if (fScriptTagV2 != nullScriptTag &&
+                fGPOSTable->coversScriptAndLanguage(fGPOSTable, fScriptTagV2,fLangSysTag,success)) {
+              fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag,
+                                  fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
 
             } else {
-                fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, success, fFontInstance,
-                                fFeatureMap, fFeatureMapCount, fFeatureOrder);
+              fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag,
+                                  fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
             }
-        } else if ( fTypoFlags & 0x1 ) {
-            static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG;
-            KernTable kt(fFontInstance, getFontTable(kernTableTag));
-            kt.process(glyphStorage);
+        } else if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
+          LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
+          KernTable kt(kernTable, success);
+          kt.process(glyphStorage, success);
         }
 
         float xAdjust = 0, yAdjust = 0;
--- a/src/share/native/sun/font/layout/OpenTypeLayoutEngine.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/OpenTypeLayoutEngine.h	Mon Mar 04 12:29:30 2013 -0800
@@ -35,6 +35,7 @@
 #include "LEGlyphFilter.h"
 #include "LEFontInstance.h"
 #include "LayoutEngine.h"
+#include "LETableReference.h"
 
 #include "GlyphSubstitutionTables.h"
 #include "GlyphDefinitionTables.h"
@@ -88,7 +89,7 @@
      * @internal
      */
     OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                            le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
+                            le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
 
     /**
      * This constructor is used when the font requires a "canned" GSUB table which can't be known
@@ -228,21 +229,21 @@
      *
      * @internal
      */
-    const GlyphSubstitutionTableHeader *fGSUBTable;
+    LEReferenceTo<GlyphSubstitutionTableHeader> fGSUBTable;
 
     /**
      * The address of the GDEF table.
      *
      * @internal
      */
-    const GlyphDefinitionTableHeader   *fGDEFTable;
+    LEReferenceTo<GlyphDefinitionTableHeader> fGDEFTable;
 
     /**
      * The address of the GPOS table.
      *
      * @internal
      */
-    const GlyphPositioningTableHeader  *fGPOSTable;
+    LEReferenceTo<GlyphPositioningTableHeader> fGPOSTable;
 
     /**
      * An optional filter used to inhibit substitutions
--- a/src/share/native/sun/font/layout/OpenTypeTables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/OpenTypeTables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -38,6 +38,7 @@
  */
 
 #include "LETypes.h"
+#include "LETableReference.h"
 
 U_NAMESPACE_BEGIN
 
@@ -50,7 +51,7 @@
 #define LE_GLYPH_GROUP_MASK 0x00000001UL
 typedef le_uint32 FeatureMask;
 
-#define SWAPT(atag) ((LETag) ((atag[0] << 24) + (atag[1] << 16) + (atag[2] << 8) + atag[3]))
+#define SWAPT(atag) ((LETag) (((atag[0]) << 24) + ((atag[1]) << 16) + ((atag[2]) << 8) + (atag[3])))
 
 struct TagAndOffsetRecord
 {
--- a/src/share/native/sun/font/layout/OpenTypeUtilities.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/OpenTypeUtilities.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -76,58 +76,74 @@
     return bit;
 }
 
-Offset OpenTypeUtilities::getTagOffset(LETag tag, const TagAndOffsetRecord *records, le_int32 recordCount)
+
+Offset OpenTypeUtilities::getTagOffset(LETag tag, const LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success)
 {
-    le_uint8 bit = highBit(recordCount);
-    le_int32 power = 1 << bit;
-    le_int32 extra = recordCount - power;
-    le_int32 probe = power;
-    le_int32 index = 0;
+  if(LE_FAILURE(success)) return 0;
 
-    if (SWAPT(records[extra].tag) <= tag) {
-        index = extra;
+  le_uint32 recordCount = records.getCount();
+  le_uint8 bit = highBit(recordCount);
+  le_int32 power = 1 << bit;
+  le_int32 extra = recordCount - power;
+  le_int32 probe = power;
+  le_int32 index = 0;
+
+  {
+    const ATag &aTag = records.getAlias(extra,success)->tag;
+    if (SWAPT(aTag) <= tag) {
+      index = extra;
     }
+  }
 
-    while (probe > (1 << 0)) {
-        probe >>= 1;
+  while (probe > (1 << 0) && LE_SUCCESS(success)) {
+    probe >>= 1;
 
-        if (SWAPT(records[index + probe].tag) <= tag) {
-            index += probe;
-        }
+    {
+      const ATag &aTag = records.getAlias(index+probe,success)->tag;
+      if (SWAPT(aTag) <= tag) {
+        index += probe;
+      }
     }
+  }
 
-    if (SWAPT(records[index].tag) == tag) {
-        return SWAPW(records[index].offset);
+  {
+    const ATag &aTag = records.getAlias(index,success)->tag;
+    if (SWAPT(aTag) == tag) {
+      return SWAPW(records.getAlias(index,success)->offset);
     }
+  }
 
-    return 0;
+  return 0;
 }
 
-le_int32 OpenTypeUtilities::getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount)
+le_int32 OpenTypeUtilities::getGlyphRangeIndex(TTGlyphID glyphID, const LEReferenceToArrayOf<GlyphRangeRecord> &records, LEErrorCode &success)
 {
+  if(LE_FAILURE(success)) return -1;
+
+    le_uint32 recordCount = records.getCount();
     le_uint8 bit = highBit(recordCount);
     le_int32 power = 1 << bit;
     le_int32 extra = recordCount - power;
     le_int32 probe = power;
     le_int32 range = 0;
 
-        if (recordCount == 0) {
-                return -1;
-        }
+    if (recordCount == 0) {
+      return -1;
+    }
 
-    if (SWAPW(records[extra].firstGlyph) <= glyphID) {
+    if (SWAPW(records(extra,success).firstGlyph) <= glyphID) {
         range = extra;
     }
 
-    while (probe > (1 << 0)) {
+    while (probe > (1 << 0) && LE_SUCCESS(success)) {
         probe >>= 1;
 
-        if (SWAPW(records[range + probe].firstGlyph) <= glyphID) {
+        if (SWAPW(records(range + probe,success).firstGlyph) <= glyphID) {
             range += probe;
         }
     }
 
-    if (SWAPW(records[range].firstGlyph) <= glyphID && SWAPW(records[range].lastGlyph) >= glyphID) {
+    if (SWAPW(records(range,success).firstGlyph) <= glyphID && SWAPW(records(range,success).lastGlyph) >= glyphID) {
         return range;
     }
 
@@ -199,6 +215,38 @@
     }
 }
 
+U_NAMESPACE_END
 
+#if LE_ASSERT_BAD_FONT
+#include <stdio.h>
 
-U_NAMESPACE_END
+static const char *letagToStr(LETag tag, char *str) {
+  str[0]= 0xFF & (tag>>24);
+  str[1]= 0xFF & (tag>>16);
+  str[2]= 0xFF & (tag>>8);
+  str[3]= 0xFF & (tag>>0);
+  str[4]= 0;
+  return str;
+}
+
+U_CAPI void U_EXPORT2 _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len) {
+  char tagbuf[5];
+
+  fprintf(stderr, "%s:%d: LETableReference@0x%p: ", f, l, what);
+  fprintf(stderr, msg, ptr, len);
+  fprintf(stderr, "\n");
+
+  for(int depth=0;depth<10&&(what!=NULL);depth++) {
+    for(int i=0;i<depth;i++) {
+      fprintf(stderr, " "); // indent
+    }
+    if(!what->isValid()) {
+      fprintf(stderr, "(invalid)");
+    }
+    fprintf(stderr, "@%p: tag (%s) font (0x%p), [0x%p+0x%lx]\n", what, letagToStr(what->getTag(), tagbuf), what->getFont(),
+            what->getAlias(), what->getLength());
+
+    what = what->getParent();
+  }
+}
+#endif
--- a/src/share/native/sun/font/layout/OpenTypeUtilities.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/OpenTypeUtilities.h	Mon Mar 04 12:29:30 2013 -0800
@@ -45,8 +45,17 @@
 class OpenTypeUtilities /* not : public UObject because all methods are static */ {
 public:
     static le_int8 highBit(le_int32 value);
-    static Offset getTagOffset(LETag tag, const TagAndOffsetRecord *records, le_int32 recordCount);
-    static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount);
+    static Offset getTagOffset(LETag tag, const LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success);
+    /**
+     * @deprecated TODO remove
+     */
+    static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount) {
+      LEErrorCode success = LE_NO_ERROR;
+      LETableReference recordRef0((const le_uint8*)records);
+      LEReferenceToArrayOf<GlyphRangeRecord> recordRef(recordRef0, success, (size_t)0, recordCount);
+      return getGlyphRangeIndex(glyphID, recordRef, success);
+    }
+    static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const LEReferenceToArrayOf<GlyphRangeRecord> &records, LEErrorCode &success);
     static le_int32 search(le_uint16 value, const le_uint16 array[], le_int32 count);
     static le_int32 search(le_uint32 value, const le_uint32 array[], le_int32 count);
     static void sort(le_uint16 *array, le_int32 count);
--- a/src/share/native/sun/font/layout/PairPositioningSubtables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/PairPositioningSubtables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -41,7 +41,7 @@
 
 U_NAMESPACE_BEGIN
 
-le_uint32 PairPositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
+le_uint32 PairPositioningSubtable::process(const LEReferenceTo<PairPositioningSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
 {
     switch(SWAPW(subtableFormat))
     {
@@ -50,27 +50,32 @@
 
     case 1:
     {
-        const PairPositioningFormat1Subtable *subtable = (const PairPositioningFormat1Subtable *) this;
+      const LEReferenceTo<PairPositioningFormat1Subtable> subtable(base, success, (const PairPositioningFormat1Subtable *) this);
 
-        return subtable->process(glyphIterator, fontInstance);
+      if(LE_SUCCESS(success))
+      return subtable->process(subtable, glyphIterator, fontInstance, success);
+      else
+        return 0;
     }
 
     case 2:
     {
-        const PairPositioningFormat2Subtable *subtable = (const PairPositioningFormat2Subtable *) this;
+      const LEReferenceTo<PairPositioningFormat2Subtable> subtable(base, success, (const PairPositioningFormat2Subtable *) this);
 
-        return subtable->process(glyphIterator, fontInstance);
+      if(LE_SUCCESS(success))
+      return subtable->process(subtable, glyphIterator, fontInstance, success);
+      else
+        return 0;
     }
-
     default:
-        return 0;
+      return 0;
     }
 }
 
-le_uint32 PairPositioningFormat1Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
+le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
 {
     LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(firstGlyph);
+    le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success);
     GlyphIterator tempIterator(*glyphIterator);
 
     if (coverageIndex >= 0 && glyphIterator->next()) {
@@ -110,10 +115,10 @@
     return 0;
 }
 
-le_uint32 PairPositioningFormat2Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
+le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositioningFormat2Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
 {
     LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(firstGlyph);
+    le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success);
     GlyphIterator tempIterator(*glyphIterator);
 
     if (coverageIndex >= 0 && glyphIterator->next()) {
--- a/src/share/native/sun/font/layout/PairPositioningSubtables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/PairPositioningSubtables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -59,13 +59,14 @@
     le_uint16       pairValueCount;
     PairValueRecord pairValueRecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(PairSetTable, pairValueRecordArray)
 
 struct PairPositioningSubtable : GlyphPositioningSubtable
 {
     ValueFormat valueFormat1;
     ValueFormat valueFormat2;
 
-    le_uint32  process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
+    le_uint32  process(const LEReferenceTo<PairPositioningSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
 };
 
 struct PairPositioningFormat1Subtable : PairPositioningSubtable
@@ -73,12 +74,13 @@
     le_uint16   pairSetCount;
     Offset      pairSetTableOffsetArray[ANY_NUMBER];
 
-    le_uint32  process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
+    le_uint32  process(const LEReferenceTo<PairPositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
 
 private:
     const PairValueRecord *findPairValueRecord(TTGlyphID glyphID, const PairValueRecord *records,
         le_uint16 recordCount, le_uint16 recordSize) const;
 };
+LE_VAR_ARRAY(PairPositioningFormat1Subtable, pairSetTableOffsetArray)
 
 // NOTE: ValueRecord has a variable size
 struct Class2Record
@@ -91,6 +93,7 @@
 {
     Class2Record class2RecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(Class1Record, class2RecordArray)
 
 struct PairPositioningFormat2Subtable : PairPositioningSubtable
 {
@@ -100,8 +103,9 @@
     le_uint16    class2Count;
     Class1Record class1RecordArray[ANY_NUMBER];
 
-    le_uint32  process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
+    le_uint32  process(const LEReferenceTo<PairPositioningFormat2Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
 };
+LE_VAR_ARRAY(PairPositioningFormat2Subtable, class1RecordArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/ScriptAndLanguage.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ScriptAndLanguage.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -38,29 +38,33 @@
 
 U_NAMESPACE_BEGIN
 
-const LangSysTable *ScriptTable::findLanguage(LETag languageTag, le_bool exactMatch) const
+LEReferenceTo<LangSysTable> ScriptTable::findLanguage(const LETableReference& base, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const
 {
     le_uint16 count = SWAPW(langSysCount);
     Offset langSysTableOffset = exactMatch? 0 : SWAPW(defaultLangSysTableOffset);
 
     if (count > 0) {
-        Offset foundOffset =
-            OpenTypeUtilities::getTagOffset(languageTag, langSysRecordArray, count);
+      LEReferenceToArrayOf<TagAndOffsetRecord> langSysRecords(base, success, langSysRecordArray, count);
+      Offset foundOffset =
+        OpenTypeUtilities::getTagOffset(languageTag, langSysRecords, success);
 
-        if (foundOffset != 0) {
-            langSysTableOffset = foundOffset;
-        }
+      if (foundOffset != 0 && LE_SUCCESS(success)) {
+        langSysTableOffset = foundOffset;
+      }
     }
 
     if (langSysTableOffset != 0) {
-        return (const LangSysTable *) ((char *)this + langSysTableOffset);
+      return LEReferenceTo<LangSysTable>(base, success, langSysTableOffset);
     }
 
-    return NULL;
+    return LEReferenceTo<LangSysTable>();
 }
 
-const ScriptTable *ScriptListTable::findScript(LETag scriptTag) const
+LEReferenceTo<ScriptTable> ScriptListTable::findScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const
 {
+    if (LE_FAILURE(success) ) {
+      return LEReferenceTo<ScriptTable>(); // get out
+    }
     /*
      * There are some fonts that have a large, bogus value for scriptCount. To try
      * and protect against this, we use the offset in the first scriptRecord,
@@ -74,38 +78,53 @@
      * to be unsorted.
      */
     le_uint16 count = SWAPW(scriptCount);
+
+    if (count == 0) {
+      return LEReferenceTo<ScriptTable>(); // no items, no search
+    }
+
+    // attempt to construct a ref with at least one element
+    LEReferenceToArrayOf<ScriptRecord> oneElementTable(base, success, &scriptRecordArray[0], 1);
+
+    if( LE_FAILURE(success) ) {
+      return LEReferenceTo<ScriptTable>(); // couldn't even read the first record - bad font.
+    }
+
     le_uint16 limit = ((SWAPW(scriptRecordArray[0].offset) - sizeof(ScriptListTable)) / sizeof(scriptRecordArray)) + ANY_NUMBER;
     Offset scriptTableOffset = 0;
 
+
     if (count > limit) {
         // the scriptCount value is bogus; do a linear search
         // because limit may still be too large.
-        for(le_int32 s = 0; s < limit; s += 1) {
-            if (SWAPT(scriptRecordArray[s].tag) == scriptTag) {
-                scriptTableOffset = SWAPW(scriptRecordArray[s].offset);
-                break;
-            }
+        LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], limit);
+        for(le_int32 s = 0; (s < limit)&&LE_SUCCESS(success); s += 1) {
+          if (SWAPT(scriptRecordArrayRef(s,success).tag) == scriptTag) {
+            scriptTableOffset = SWAPW(scriptRecordArrayRef(s,success).offset);
+            break;
+          }
         }
     } else {
-        scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArray, count);
+      LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], count);
+      scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success); // TODO
     }
 
     if (scriptTableOffset != 0) {
-        return (const ScriptTable *) ((char *)this + scriptTableOffset);
+      return LEReferenceTo<ScriptTable>(base, success, scriptTableOffset);
     }
 
-    return NULL;
+  return LEReferenceTo<ScriptTable>();
 }
 
-const LangSysTable *ScriptListTable::findLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const
+LEReferenceTo<LangSysTable>  ScriptListTable::findLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const
 {
-    const ScriptTable *scriptTable = findScript(scriptTag);
+  const LEReferenceTo<ScriptTable> scriptTable = findScript(base, scriptTag, success);
 
-    if (scriptTable == 0) {
-        return NULL;
-    }
+  if (scriptTable.isEmpty()) {
+    return LEReferenceTo<LangSysTable>();
+  }
 
-    return scriptTable->findLanguage(languageTag, exactMatch);
+  return scriptTable->findLanguage(scriptTable, languageTag, success, exactMatch).reparent(base);
 }
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/ScriptAndLanguage.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ScriptAndLanguage.h	Mon Mar 04 12:29:30 2013 -0800
@@ -51,6 +51,7 @@
     le_uint16 featureCount;
     le_uint16 featureIndexArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(LangSysTable, featureIndexArray)
 
 struct ScriptTable
 {
@@ -58,8 +59,9 @@
     le_uint16           langSysCount;
     LangSysRecord       langSysRecordArray[ANY_NUMBER];
 
-    const LangSysTable  *findLanguage(LETag languageTag, le_bool exactMatch = FALSE) const;
+  LEReferenceTo<LangSysTable>  findLanguage(const LETableReference &base, LETag languageTag, LEErrorCode &success, le_bool exactMatch = FALSE) const;
 };
+LE_VAR_ARRAY(ScriptTable, langSysRecordArray)
 
 typedef TagAndOffsetRecord ScriptRecord;
 
@@ -68,9 +70,10 @@
     le_uint16           scriptCount;
     ScriptRecord        scriptRecordArray[ANY_NUMBER];
 
-    const ScriptTable   *findScript(LETag scriptTag) const;
-    const LangSysTable  *findLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch = FALSE) const;
+  LEReferenceTo<ScriptTable>   findScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const;
+  LEReferenceTo<LangSysTable>  findLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch = FALSE) const;
 };
+LE_VAR_ARRAY(ScriptListTable, scriptRecordArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/SegmentArrayProcessor.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SegmentArrayProcessor.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -46,19 +46,18 @@
 {
 }
 
-SegmentArrayProcessor::SegmentArrayProcessor(const MorphSubtableHeader *morphSubtableHeader)
-  : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader)
+SegmentArrayProcessor::SegmentArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+  : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success)
 {
-    const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader;
-
-    segmentArrayLookupTable = (const SegmentArrayLookupTable *) &header->table;
+  LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success);
+  segmentArrayLookupTable = LEReferenceTo<SegmentArrayLookupTable>(morphSubtableHeader, success, (const SegmentArrayLookupTable*)&header->table);
 }
 
 SegmentArrayProcessor::~SegmentArrayProcessor()
 {
 }
 
-void SegmentArrayProcessor::process(LEGlyphStorage &glyphStorage)
+void SegmentArrayProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
     const LookupSegment *segments = segmentArrayLookupTable->segments;
     le_int32 glyphCount = glyphStorage.getGlyphCount();
@@ -66,17 +65,16 @@
 
     for (glyph = 0; glyph < glyphCount; glyph += 1) {
         LEGlyphID thisGlyph = glyphStorage[glyph];
-        const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segments, thisGlyph);
+        const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segmentArrayLookupTable, segments, thisGlyph, success);
 
         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);
+              LEReferenceToArrayOf<TTGlyphID> glyphArray(subtableHeader, success, offset, LE_UNBOUNDED_ARRAY);
+              TTGlyphID   newGlyph   = SWAPW(glyphArray(LE_GET_GLYPH(thisGlyph) - firstGlyph, success));
+              glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
             }
         }
     }
--- a/src/share/native/sun/font/layout/SegmentArrayProcessor.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SegmentArrayProcessor.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,9 +50,9 @@
 class SegmentArrayProcessor : public NonContextualGlyphSubstitutionProcessor
 {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage);
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
-    SegmentArrayProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    SegmentArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
 
     virtual ~SegmentArrayProcessor();
 
@@ -74,7 +74,7 @@
     SegmentArrayProcessor();
 
 protected:
-    const SegmentArrayLookupTable *segmentArrayLookupTable;
+    LEReferenceTo<SegmentArrayLookupTable> segmentArrayLookupTable;
 
 };
 
--- a/src/share/native/sun/font/layout/SegmentArrayProcessor2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SegmentArrayProcessor2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -46,19 +46,18 @@
 {
 }
 
-SegmentArrayProcessor2::SegmentArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
-  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader)
+SegmentArrayProcessor2::SegmentArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success)
 {
-    const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
-
-    segmentArrayLookupTable = (const SegmentArrayLookupTable *) &header->table;
+  const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success);
+  segmentArrayLookupTable = LEReferenceTo<SegmentArrayLookupTable>(morphSubtableHeader,  success, &header->table); // don't parent to 'header' as it is on the stack
 }
 
 SegmentArrayProcessor2::~SegmentArrayProcessor2()
 {
 }
 
-void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage)
+void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
     const LookupSegment *segments = segmentArrayLookupTable->segments;
     le_int32 glyphCount = glyphStorage.getGlyphCount();
@@ -66,14 +65,14 @@
 
     for (glyph = 0; glyph < glyphCount; glyph += 1) {
         LEGlyphID thisGlyph = glyphStorage[glyph];
-        const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segments, thisGlyph);
+        const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segmentArrayLookupTable, segments, thisGlyph, success);
 
         if (lookupSegment != NULL)  {
             TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph);
             le_int16  offset = SWAPW(lookupSegment->value);
 
             if (offset != 0) {
-                TTGlyphID  *glyphArray = (TTGlyphID *) ((char *) subtableHeader + offset);
+              TTGlyphID  *glyphArray = (TTGlyphID *) ((char *) subtableHeader.getAliasTODO() + offset);
                 TTGlyphID   newGlyph   = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]);
 
                 glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
--- a/src/share/native/sun/font/layout/SegmentArrayProcessor2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SegmentArrayProcessor2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,9 +50,9 @@
 class SegmentArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2
 {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage);
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
-    SegmentArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    SegmentArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
 
     virtual ~SegmentArrayProcessor2();
 
@@ -74,7 +74,7 @@
     SegmentArrayProcessor2();
 
 protected:
-    const SegmentArrayLookupTable *segmentArrayLookupTable;
+    LEReferenceTo<SegmentArrayLookupTable> segmentArrayLookupTable;
 
 };
 
--- a/src/share/native/sun/font/layout/SegmentSingleProcessor.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SegmentSingleProcessor.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -46,29 +46,28 @@
 {
 }
 
-SegmentSingleProcessor::SegmentSingleProcessor(const MorphSubtableHeader *morphSubtableHeader)
-  : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader)
+SegmentSingleProcessor::SegmentSingleProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+  : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success)
 {
-    const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader;
-
-    segmentSingleLookupTable = (const SegmentSingleLookupTable *) &header->table;
+  LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success);
+  segmentSingleLookupTable = LEReferenceTo<SegmentSingleLookupTable>(morphSubtableHeader, success, (const SegmentSingleLookupTable*)&header->table);
 }
 
 SegmentSingleProcessor::~SegmentSingleProcessor()
 {
 }
 
-void SegmentSingleProcessor::process(LEGlyphStorage &glyphStorage)
+void SegmentSingleProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
     const LookupSegment *segments = segmentSingleLookupTable->segments;
     le_int32 glyphCount = glyphStorage.getGlyphCount();
     le_int32 glyph;
 
-    for (glyph = 0; glyph < glyphCount; glyph += 1) {
+    for (glyph = 0; glyph < glyphCount && LE_SUCCESS(success); glyph += 1) {
         LEGlyphID thisGlyph = glyphStorage[glyph];
-        const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segments, thisGlyph);
+        const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segmentSingleLookupTable, segments, thisGlyph, success);
 
-        if (lookupSegment != NULL) {
+        if (lookupSegment != NULL && LE_SUCCESS(success)) {
             TTGlyphID   newGlyph  = (TTGlyphID) LE_GET_GLYPH(thisGlyph) + SWAPW(lookupSegment->value);
 
             glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
--- a/src/share/native/sun/font/layout/SegmentSingleProcessor.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SegmentSingleProcessor.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,9 +50,9 @@
 class SegmentSingleProcessor : public NonContextualGlyphSubstitutionProcessor
 {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage);
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
-    SegmentSingleProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    SegmentSingleProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
 
     virtual ~SegmentSingleProcessor();
 
@@ -74,7 +74,7 @@
     SegmentSingleProcessor();
 
 protected:
-    const SegmentSingleLookupTable *segmentSingleLookupTable;
+    LEReferenceTo<SegmentSingleLookupTable> segmentSingleLookupTable;
 
 };
 
--- a/src/share/native/sun/font/layout/SegmentSingleProcessor2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SegmentSingleProcessor2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -46,19 +46,19 @@
 {
 }
 
-SegmentSingleProcessor2::SegmentSingleProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
-  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader)
+SegmentSingleProcessor2::SegmentSingleProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success)
 {
-    const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
+  const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success);
 
-    segmentSingleLookupTable = (const SegmentSingleLookupTable *) &header->table;
+  segmentSingleLookupTable = LEReferenceTo<SegmentSingleLookupTable>(morphSubtableHeader, success, &header->table);
 }
 
 SegmentSingleProcessor2::~SegmentSingleProcessor2()
 {
 }
 
-void SegmentSingleProcessor2::process(LEGlyphStorage &glyphStorage)
+void SegmentSingleProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
     const LookupSegment *segments = segmentSingleLookupTable->segments;
     le_int32 glyphCount = glyphStorage.getGlyphCount();
@@ -66,9 +66,9 @@
 
     for (glyph = 0; glyph < glyphCount; glyph += 1) {
         LEGlyphID thisGlyph = glyphStorage[glyph];
-        const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segments, thisGlyph);
+        const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segmentSingleLookupTable, segments, thisGlyph, success);
 
-        if (lookupSegment != NULL) {
+        if (lookupSegment != NULL && LE_SUCCESS(success)) {
             TTGlyphID   newGlyph  = (TTGlyphID) LE_GET_GLYPH(thisGlyph) + SWAPW(lookupSegment->value);
 
             glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
--- a/src/share/native/sun/font/layout/SegmentSingleProcessor2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SegmentSingleProcessor2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,9 +50,9 @@
 class SegmentSingleProcessor2 : public NonContextualGlyphSubstitutionProcessor2
 {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage);
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
-    SegmentSingleProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    SegmentSingleProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
 
     virtual ~SegmentSingleProcessor2();
 
@@ -74,7 +74,7 @@
     SegmentSingleProcessor2();
 
 protected:
-    const SegmentSingleLookupTable *segmentSingleLookupTable;
+    LEReferenceTo<SegmentSingleLookupTable> segmentSingleLookupTable;
 
 };
 
--- a/src/share/native/sun/font/layout/ShapingTypeData.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ShapingTypeData.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -122,4 +122,6 @@
     0x00, 0x05, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x05, 0xFF, 0xF9, 0xFF, 0xFB, 0x00, 0x05
 };
 
+const size_t ArabicShaping::shapingTypeTableLen = sizeof(shapingTypeTable)/sizeof(shapingTypeTable[0]);
+
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/SimpleArrayProcessor.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SimpleArrayProcessor.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -46,29 +46,29 @@
 {
 }
 
-SimpleArrayProcessor::SimpleArrayProcessor(const MorphSubtableHeader *morphSubtableHeader)
-  : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader)
+SimpleArrayProcessor::SimpleArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+  : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success)
 {
-    const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader;
-
-    simpleArrayLookupTable = (const SimpleArrayLookupTable *) &header->table;
+  LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success);
+  simpleArrayLookupTable = LEReferenceTo<SimpleArrayLookupTable>(morphSubtableHeader, success, (const SimpleArrayLookupTable*)&header->table);
 }
 
 SimpleArrayProcessor::~SimpleArrayProcessor()
 {
 }
 
-void SimpleArrayProcessor::process(LEGlyphStorage &glyphStorage)
+void SimpleArrayProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
     le_int32 glyphCount = glyphStorage.getGlyphCount();
     le_int32 glyph;
 
-    for (glyph = 0; glyph < glyphCount; glyph += 1) {
+    LEReferenceToArrayOf<LookupValue> valueArray(simpleArrayLookupTable, success, (const LookupValue*)&simpleArrayLookupTable->valueArray, LE_UNBOUNDED_ARRAY);
+
+    for (glyph = 0; LE_SUCCESS(success) && (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);
+          TTGlyphID newGlyph = SWAPW(valueArray.getObject(LE_GET_GLYPH(thisGlyph),success));
+          glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
         }
     }
 }
--- a/src/share/native/sun/font/layout/SimpleArrayProcessor.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SimpleArrayProcessor.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,9 +50,9 @@
 class SimpleArrayProcessor : public NonContextualGlyphSubstitutionProcessor
 {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage);
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
-    SimpleArrayProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    SimpleArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
 
     virtual ~SimpleArrayProcessor();
 
@@ -74,7 +74,7 @@
     SimpleArrayProcessor();
 
 protected:
-    const SimpleArrayLookupTable *simpleArrayLookupTable;
+    LEReferenceTo<SimpleArrayLookupTable> simpleArrayLookupTable;
 
 };
 
--- a/src/share/native/sun/font/layout/SimpleArrayProcessor2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SimpleArrayProcessor2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -46,27 +46,29 @@
 {
 }
 
-SimpleArrayProcessor2::SimpleArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
-  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader)
+SimpleArrayProcessor2::SimpleArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success)
 {
-    const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
+  const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success);
 
-    simpleArrayLookupTable = (const SimpleArrayLookupTable *) &header->table;
+  simpleArrayLookupTable = LEReferenceTo<SimpleArrayLookupTable>(morphSubtableHeader, success, &header->table);
+  valueArray = LEReferenceToArrayOf<LookupValue>(morphSubtableHeader, success, &simpleArrayLookupTable->valueArray[0], LE_UNBOUNDED_ARRAY);
 }
 
 SimpleArrayProcessor2::~SimpleArrayProcessor2()
 {
 }
 
-void SimpleArrayProcessor2::process(LEGlyphStorage &glyphStorage)
+void SimpleArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
+    if (LE_FAILURE(success)) return;
     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)]);
+          TTGlyphID newGlyph = SWAPW(valueArray(LE_GET_GLYPH(thisGlyph),success));
 
             glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
         }
--- a/src/share/native/sun/font/layout/SimpleArrayProcessor2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SimpleArrayProcessor2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,9 +50,9 @@
 class SimpleArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2
 {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage);
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
-    SimpleArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    SimpleArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
 
     virtual ~SimpleArrayProcessor2();
 
@@ -74,7 +74,8 @@
     SimpleArrayProcessor2();
 
 protected:
-    const SimpleArrayLookupTable *simpleArrayLookupTable;
+    LEReferenceTo<SimpleArrayLookupTable> simpleArrayLookupTable;
+    LEReferenceToArrayOf<LookupValue> valueArray;
 
 };
 
--- a/src/share/native/sun/font/layout/SinglePositioningSubtables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SinglePositioningSubtables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -40,7 +40,7 @@
 
 U_NAMESPACE_BEGIN
 
-le_uint32 SinglePositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
+le_uint32 SinglePositioningSubtable::process(const LEReferenceTo<SinglePositioningSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
 {
     switch(SWAPW(subtableFormat))
     {
@@ -49,16 +49,16 @@
 
     case 1:
     {
-        const SinglePositioningFormat1Subtable *subtable = (const SinglePositioningFormat1Subtable *) this;
+      const LEReferenceTo<SinglePositioningFormat1Subtable> subtable(base, success, (const SinglePositioningFormat1Subtable *) this);
 
-        return subtable->process(glyphIterator, fontInstance);
+      return subtable->process(subtable, glyphIterator, fontInstance, success);
     }
 
     case 2:
     {
-        const SinglePositioningFormat2Subtable *subtable = (const SinglePositioningFormat2Subtable *) this;
+      const LEReferenceTo<SinglePositioningFormat2Subtable> subtable(base, success, (const SinglePositioningFormat2Subtable *) this);
 
-        return subtable->process(glyphIterator, fontInstance);
+      return subtable->process(subtable, glyphIterator, fontInstance, success);
     }
 
     default:
@@ -66,10 +66,10 @@
     }
 }
 
-le_uint32 SinglePositioningFormat1Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
+le_uint32 SinglePositioningFormat1Subtable::process(const LEReferenceTo<SinglePositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
 {
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
 
     if (coverageIndex >= 0) {
         valueRecord.adjustPosition(SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance);
@@ -80,10 +80,10 @@
     return 0;
 }
 
-le_uint32 SinglePositioningFormat2Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
+le_uint32 SinglePositioningFormat2Subtable::process(const LEReferenceTo<SinglePositioningFormat2Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
 {
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int16 coverageIndex = (le_int16) getGlyphCoverage(glyph);
+    le_int16 coverageIndex = (le_int16) getGlyphCoverage(base, glyph, success);
 
     if (coverageIndex >= 0) {
         valueRecordArray[0].adjustPosition(coverageIndex, SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance);
--- a/src/share/native/sun/font/layout/SinglePositioningSubtables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SinglePositioningSubtables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -48,7 +48,7 @@
 
 struct SinglePositioningSubtable : GlyphPositioningSubtable
 {
-    le_uint32  process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
+    le_uint32  process(const LEReferenceTo<SinglePositioningSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
 };
 
 struct SinglePositioningFormat1Subtable : SinglePositioningSubtable
@@ -56,7 +56,7 @@
     ValueFormat valueFormat;
     ValueRecord valueRecord;
 
-    le_uint32  process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
+    le_uint32  process(const LEReferenceTo<SinglePositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
 };
 
 struct SinglePositioningFormat2Subtable : SinglePositioningSubtable
@@ -65,8 +65,9 @@
     le_uint16   valueCount;
     ValueRecord valueRecordArray[ANY_NUMBER];
 
-    le_uint32  process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
+    le_uint32  process(const LEReferenceTo<SinglePositioningFormat2Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
 };
+LE_VAR_ARRAY(SinglePositioningFormat2Subtable, valueRecordArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/SingleSubstitutionSubtables.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SingleSubstitutionSubtables.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -39,7 +39,7 @@
 
 U_NAMESPACE_BEGIN
 
-le_uint32 SingleSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
+le_uint32 SingleSubstitutionSubtable::process(const LEReferenceTo<SingleSubstitutionSubtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
 {
     switch(SWAPW(subtableFormat))
     {
@@ -48,16 +48,16 @@
 
     case 1:
     {
-        const SingleSubstitutionFormat1Subtable *subtable = (const SingleSubstitutionFormat1Subtable *) this;
+      const LEReferenceTo<SingleSubstitutionFormat1Subtable> subtable(base, success, (const SingleSubstitutionFormat1Subtable *) this);
 
-        return subtable->process(glyphIterator, filter);
+      return subtable->process(subtable, glyphIterator, success, filter);
     }
 
     case 2:
     {
-        const SingleSubstitutionFormat2Subtable *subtable = (const SingleSubstitutionFormat2Subtable *) this;
+      const LEReferenceTo<SingleSubstitutionFormat2Subtable> subtable(base, success, (const SingleSubstitutionFormat2Subtable *) this);
 
-        return subtable->process(glyphIterator, filter);
+      return subtable->process(subtable, glyphIterator, success, filter);
     }
 
     default:
@@ -65,10 +65,10 @@
     }
 }
 
-le_uint32 SingleSubstitutionFormat1Subtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
+le_uint32 SingleSubstitutionFormat1Subtable::process(const LEReferenceTo<SingleSubstitutionFormat1Subtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
 {
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
 
     if (coverageIndex >= 0) {
         TTGlyphID substitute = ((TTGlyphID) LE_GET_GLYPH(glyph)) + SWAPW(deltaGlyphID);
@@ -83,10 +83,10 @@
     return 0;
 }
 
-le_uint32 SingleSubstitutionFormat2Subtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
+le_uint32 SingleSubstitutionFormat2Subtable::process(const LEReferenceTo<SingleSubstitutionFormat2Subtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
 {
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
 
     if (coverageIndex >= 0) {
         TTGlyphID substitute = SWAPW(substituteArray[coverageIndex]);
--- a/src/share/native/sun/font/layout/SingleSubstitutionSubtables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SingleSubstitutionSubtables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -47,14 +47,14 @@
 
 struct SingleSubstitutionSubtable : GlyphSubstitutionSubtable
 {
-    le_uint32  process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const;
+    le_uint32  process(const LEReferenceTo<SingleSubstitutionSubtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
 };
 
 struct SingleSubstitutionFormat1Subtable : SingleSubstitutionSubtable
 {
     le_int16   deltaGlyphID;
 
-    le_uint32  process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const;
+    le_uint32  process(const LEReferenceTo<SingleSubstitutionFormat1Subtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
 };
 
 struct SingleSubstitutionFormat2Subtable : SingleSubstitutionSubtable
@@ -62,8 +62,9 @@
     le_uint16  glyphCount;
     TTGlyphID  substituteArray[ANY_NUMBER];
 
-    le_uint32  process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const;
+    le_uint32  process(const LEReferenceTo<SingleSubstitutionFormat2Subtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
 };
+LE_VAR_ARRAY(SingleSubstitutionFormat2Subtable, substituteArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/SingleTableProcessor.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SingleTableProcessor.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -46,26 +46,25 @@
 {
 }
 
-SingleTableProcessor::SingleTableProcessor(const MorphSubtableHeader *moprhSubtableHeader)
-  : NonContextualGlyphSubstitutionProcessor(moprhSubtableHeader)
+SingleTableProcessor::SingleTableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+  : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success)
 {
-    const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) moprhSubtableHeader;
-
-    singleTableLookupTable = (const SingleTableLookupTable *) &header->table;
+  LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success);
+  singleTableLookupTable = LEReferenceTo<SingleTableLookupTable>(morphSubtableHeader, success, (const SingleTableLookupTable*)&header->table);
 }
 
 SingleTableProcessor::~SingleTableProcessor()
 {
 }
 
-void SingleTableProcessor::process(LEGlyphStorage &glyphStorage)
+void SingleTableProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
     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]);
+      const LookupSingle *lookupSingle = singleTableLookupTable->lookupSingle(singleTableLookupTable, entries, glyphStorage[glyph], success);
 
         if (lookupSingle != NULL) {
             glyphStorage[glyph] = SWAPW(lookupSingle->value);
--- a/src/share/native/sun/font/layout/SingleTableProcessor.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SingleTableProcessor.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,9 +50,9 @@
 class SingleTableProcessor : public NonContextualGlyphSubstitutionProcessor
 {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage);
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
-    SingleTableProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    SingleTableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
 
     virtual ~SingleTableProcessor();
 
@@ -74,7 +74,7 @@
     SingleTableProcessor();
 
 protected:
-    const SingleTableLookupTable *singleTableLookupTable;
+    LEReferenceTo<SingleTableLookupTable> singleTableLookupTable;
 
 };
 
--- a/src/share/native/sun/font/layout/SingleTableProcessor2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SingleTableProcessor2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -46,26 +46,27 @@
 {
 }
 
-SingleTableProcessor2::SingleTableProcessor2(const MorphSubtableHeader2 *moprhSubtableHeader)
-  : NonContextualGlyphSubstitutionProcessor2(moprhSubtableHeader)
+SingleTableProcessor2::SingleTableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success)
 {
-    const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) moprhSubtableHeader;
+  const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success);
 
-    singleTableLookupTable = (const SingleTableLookupTable *) &header->table;
+    singleTableLookupTable = LEReferenceTo<SingleTableLookupTable>(morphSubtableHeader, success, &header->table);
 }
 
 SingleTableProcessor2::~SingleTableProcessor2()
 {
 }
 
-void SingleTableProcessor2::process(LEGlyphStorage &glyphStorage)
+void SingleTableProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
+  if(LE_FAILURE(success)) return;
     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]);
+      const LookupSingle *lookupSingle = singleTableLookupTable->lookupSingle(singleTableLookupTable, entries, glyphStorage[glyph], success);
 
         if (lookupSingle != NULL) {
             glyphStorage[glyph] = SWAPW(lookupSingle->value);
--- a/src/share/native/sun/font/layout/SingleTableProcessor2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SingleTableProcessor2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,9 +50,9 @@
 class SingleTableProcessor2 : public NonContextualGlyphSubstitutionProcessor2
 {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage);
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
-    SingleTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    SingleTableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
 
     virtual ~SingleTableProcessor2();
 
@@ -74,7 +74,7 @@
     SingleTableProcessor2();
 
 protected:
-    const SingleTableLookupTable *singleTableLookupTable;
+    LEReferenceTo<SingleTableLookupTable> singleTableLookupTable;
 
 };
 
--- a/src/share/native/sun/font/layout/StateTableProcessor.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/StateTableProcessor.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -44,17 +44,18 @@
 {
 }
 
-StateTableProcessor::StateTableProcessor(const MorphSubtableHeader *morphSubtableHeader)
-  : SubtableProcessor(morphSubtableHeader)
+StateTableProcessor::StateTableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+  : SubtableProcessor(morphSubtableHeader, success), stateTableHeader(morphSubtableHeader, success),
+    stHeader(stateTableHeader, success, (const StateTableHeader*)&stateTableHeader->stHeader)
 {
-    stateTableHeader = (const MorphStateTableHeader *) morphSubtableHeader;
-
+  if(LE_FAILURE(success)) return;
     stateSize = SWAPW(stateTableHeader->stHeader.stateSize);
     classTableOffset = SWAPW(stateTableHeader->stHeader.classTableOffset);
     stateArrayOffset = SWAPW(stateTableHeader->stHeader.stateArrayOffset);
     entryTableOffset = SWAPW(stateTableHeader->stHeader.entryTableOffset);
 
-    classTable = (const ClassTable *) ((char *) &stateTableHeader->stHeader + classTableOffset);
+    classTable = LEReferenceTo<ClassTable>(stateTableHeader, success, ((char *) &stateTableHeader->stHeader + classTableOffset));
+  if(LE_FAILURE(success)) return;
     firstGlyph = SWAPW(classTable->firstGlyph);
     lastGlyph  = firstGlyph + SWAPW(classTable->nGlyphs);
 }
@@ -63,9 +64,9 @@
 {
 }
 
-void StateTableProcessor::process(LEGlyphStorage &glyphStorage)
+void StateTableProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
-
+    if (LE_FAILURE(success)) return;
     LE_STATE_PATIENCE_INIT();
 
     // Start at state 0
@@ -94,8 +95,8 @@
             }
         }
 
-        const EntryTableIndex *stateArray = (const EntryTableIndex *) ((char *) &stateTableHeader->stHeader + currentState);
-        EntryTableIndex entryTableIndex = stateArray[(le_uint8)classCode];
+        LEReferenceToArrayOf<EntryTableIndex> stateArray(stHeader, success, currentState, LE_UNBOUNDED_ARRAY);
+        EntryTableIndex entryTableIndex = stateArray.getObject((le_uint8)classCode, success);
         LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
         currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
         LE_STATE_PATIENCE_INCR(currGlyph);
--- a/src/share/native/sun/font/layout/StateTableProcessor.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/StateTableProcessor.h	Mon Mar 04 12:29:30 2013 -0800
@@ -49,7 +49,7 @@
 class StateTableProcessor : public SubtableProcessor
 {
 public:
-    void process(LEGlyphStorage &glyphStorage);
+    void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
     virtual void beginStateTable() = 0;
 
@@ -58,7 +58,7 @@
     virtual void endStateTable() = 0;
 
 protected:
-    StateTableProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    StateTableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
     virtual ~StateTableProcessor();
 
     StateTableProcessor();
@@ -68,11 +68,12 @@
     ByteOffset stateArrayOffset;
     ByteOffset entryTableOffset;
 
-    const ClassTable *classTable;
+    LEReferenceTo<ClassTable> classTable;
     TTGlyphID firstGlyph;
     TTGlyphID lastGlyph;
 
-    const MorphStateTableHeader *stateTableHeader;
+    LEReferenceTo<MorphStateTableHeader> stateTableHeader;
+    LEReferenceTo<StateTableHeader> stHeader; // for convenience
 
 private:
     StateTableProcessor(const StateTableProcessor &other); // forbid copying of this class
--- a/src/share/native/sun/font/layout/StateTableProcessor2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/StateTableProcessor2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -45,27 +45,33 @@
 {
 }
 
-StateTableProcessor2::StateTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
-  : SubtableProcessor2(morphSubtableHeader)
+StateTableProcessor2::StateTableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : SubtableProcessor2(morphSubtableHeader, success), stateTableHeader(morphSubtableHeader, success),
+    stHeader(stateTableHeader, success, (const StateTableHeader2*)&stateTableHeader->stHeader),
+    nClasses(0), classTableOffset(0), stateArrayOffset(0), entryTableOffset(0), classTable(), format(0),
+    stateArray()
 {
-    stateTableHeader = (const MorphStateTableHeader2 *) morphSubtableHeader;
-    nClasses = SWAPL(stateTableHeader->stHeader.nClasses);
-    classTableOffset = SWAPL(stateTableHeader->stHeader.classTableOffset);
-    stateArrayOffset = SWAPL(stateTableHeader->stHeader.stateArrayOffset);
-    entryTableOffset = SWAPL(stateTableHeader->stHeader.entryTableOffset);
+  if (LE_FAILURE(success)) {
+    return;
+  }
+  nClasses = SWAPL(stHeader->nClasses);
+  classTableOffset = SWAPL(stHeader->classTableOffset);
+  stateArrayOffset = SWAPL(stHeader->stateArrayOffset);
+  entryTableOffset = SWAPL(stHeader->entryTableOffset);
 
-    classTable = (LookupTable *) ((char *) &stateTableHeader->stHeader + classTableOffset);
-    format = SWAPW(classTable->format);
+  classTable = LEReferenceTo<LookupTable>(stHeader, success, classTableOffset);
+  format = SWAPW(classTable->format);
 
-    stateArray = (const EntryTableIndex2 *) ((char *) &stateTableHeader->stHeader + stateArrayOffset);
+  stateArray = LEReferenceToArrayOf<EntryTableIndex2>(stHeader, success, stateArrayOffset, LE_UNBOUNDED_ARRAY);
 }
 
 StateTableProcessor2::~StateTableProcessor2()
 {
 }
 
-void StateTableProcessor2::process(LEGlyphStorage &glyphStorage)
+void StateTableProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
+    if (LE_FAILURE(success)) return;
     // Start at state 0
     // XXX: How do we know when to start at state 1?
     le_uint16 currentState = 0;
@@ -85,9 +91,11 @@
     switch (format) {
         case ltfSimpleArray: {
 #ifdef TEST_FORMAT
-            SimpleArrayLookupTable *lookupTable0 = (SimpleArrayLookupTable *) classTable;
+          LEReferenceTo<SimpleArrayLookupTable> lookupTable0(classTable, success);
+          if(LE_FAILURE(success)) break;
             while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
-                if(LE_STATE_PATIENCE_DECR()) {
+                if (LE_FAILURE(success)) break;
+                if (LE_STATE_PATIENCE_DECR()) {
                   LE_DEBUG_BAD_FONT("patience exceeded - state table not moving")
                   break; // patience exceeded.
                 }
@@ -105,7 +113,7 @@
                         classCode = SWAPW(lookupTable0->valueArray[gid]);
                     }
                 }
-                EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
+                EntryTableIndex2 entryTableIndex = SWAPW(stateArray(classCode + currentState * nClasses, success));
                 LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
                 currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); // return a zero-based index instead of a byte offset
                 LE_STATE_PATIENCE_INCR(currGlyph);
@@ -114,10 +122,12 @@
             break;
         }
         case ltfSegmentSingle: {
-            SegmentSingleLookupTable *lookupTable2 = (SegmentSingleLookupTable *) classTable;
+          LEReferenceTo<SegmentSingleLookupTable> lookupTable2(classTable, success);
+          if(LE_FAILURE(success)) break;
             while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
-                if(LE_STATE_PATIENCE_DECR()) {
-                  LE_DEBUG_BAD_FONT("patience exceeded - state table not moving")
+                if (LE_FAILURE(success)) break;
+                if (LE_STATE_PATIENCE_DECR()) {
+                  LE_DEBUG_BAD_FONT("patience exceeded  - state table not moving")
                   break; // patience exceeded.
                 }
                 LookupValue classCode = classCodeOOB;
@@ -131,15 +141,16 @@
                     if (glyphCode == 0xFFFF) {
                         classCode = classCodeDEL;
                     } else {
-                        const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid);
-                        if (segment != NULL) {
+                      const LookupSegment *segment =
+                        lookupTable2->lookupSegment(lookupTable2, lookupTable2->segments, gid, success);
+                        if (segment != NULL && LE_SUCCESS(success)) {
                             classCode = SWAPW(segment->value);
                         }
                     }
                 }
-                EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
+                EntryTableIndex2 entryTableIndex = SWAPW(stateArray(classCode + currentState * nClasses,success));
                 LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
-                currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
+                currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success);
                 LE_STATE_PATIENCE_INCR(currGlyph);
             }
             break;
@@ -149,9 +160,10 @@
             break;
         }
         case ltfSingleTable: {
-            SingleTableLookupTable *lookupTable6 = (SingleTableLookupTable *) classTable;
+            LEReferenceTo<SingleTableLookupTable> lookupTable6(classTable, success);
             while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) {
-                if(LE_STATE_PATIENCE_DECR()) {
+                if (LE_FAILURE(success)) break;
+                if (LE_STATE_PATIENCE_DECR()) {
                   LE_DEBUG_BAD_FONT("patience exceeded - state table not moving")
                   break; // patience exceeded.
                 }
@@ -170,21 +182,22 @@
                     if (glyphCode == 0xFFFF) {
                         classCode = classCodeDEL;
                     } else {
-                        const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
+                      const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6, lookupTable6->entries, gid, success);
                         if (segment != NULL) {
                             classCode = SWAPW(segment->value);
                         }
                     }
                 }
-                EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
+                EntryTableIndex2 entryTableIndex = SWAPW(stateArray(classCode + currentState * nClasses, success));
                 LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
-                currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
+                currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success);
                 LE_STATE_PATIENCE_INCR(currGlyph);
             }
             break;
         }
         case ltfTrimmedArray: {
-            TrimmedArrayLookupTable *lookupTable8 = (TrimmedArrayLookupTable *) classTable;
+            LEReferenceTo<TrimmedArrayLookupTable> lookupTable8(classTable, success);
+            if (LE_FAILURE(success)) break;
             TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph);
             TTGlyphID lastGlyph  = firstGlyph + SWAPW(lookupTable8->glyphCount);
 
@@ -206,9 +219,9 @@
                         classCode = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]);
                     }
                 }
-                EntryTableIndex2 entryTableIndex = SWAPW(stateArray[classCode + currentState * nClasses]);
+                EntryTableIndex2 entryTableIndex = SWAPW(stateArray(classCode + currentState * nClasses, success));
                 LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
-                currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
+                currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success);
                 LE_STATE_PATIENCE_INCR(currGlyph);
             }
             break;
--- a/src/share/native/sun/font/layout/StateTableProcessor2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/StateTableProcessor2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,16 +50,16 @@
 class StateTableProcessor2 : public SubtableProcessor2
 {
 public:
-    void process(LEGlyphStorage &glyphStorage);
+    void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
     virtual void beginStateTable() = 0;
 
-    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index) = 0;
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success) = 0;
 
     virtual void endStateTable() = 0;
 
 protected:
-    StateTableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    StateTableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
     virtual ~StateTableProcessor2();
 
     StateTableProcessor2();
@@ -71,9 +71,10 @@
     le_uint32 stateArrayOffset;
     le_uint32 entryTableOffset;
 
-    const LookupTable *classTable;
-    const EntryTableIndex2 *stateArray;
-    const MorphStateTableHeader2 *stateTableHeader;
+    LEReferenceTo<LookupTable> classTable;
+    LEReferenceToArrayOf<EntryTableIndex2> stateArray;
+    LEReferenceTo<MorphStateTableHeader2> stateTableHeader;
+    LEReferenceTo<StateTableHeader2> stHeader; // for convenience
 
 private:
     StateTableProcessor2(const StateTableProcessor2 &other); // forbid copying of this class
--- a/src/share/native/sun/font/layout/StateTables.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/StateTables.h	Mon Mar 04 12:29:30 2013 -0800
@@ -111,6 +111,7 @@
     le_uint16 nGlyphs;
     ClassCode classArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(ClassTable, classArray)
 
 enum StateNumber
 {
--- a/src/share/native/sun/font/layout/SubtableProcessor.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SubtableProcessor.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -40,10 +40,10 @@
 {
 }
 
-SubtableProcessor::SubtableProcessor(const MorphSubtableHeader *morphSubtableHeader)
+SubtableProcessor::SubtableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+  : length(0), coverage(0), subtableFeatures(0L), subtableHeader(morphSubtableHeader)
 {
-    subtableHeader = morphSubtableHeader;
-
+  if(LE_FAILURE(success)) return;
     length = SWAPW(subtableHeader->length);
     coverage = SWAPW(subtableHeader->coverage);
     subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
--- a/src/share/native/sun/font/layout/SubtableProcessor.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SubtableProcessor.h	Mon Mar 04 12:29:30 2013 -0800
@@ -46,11 +46,11 @@
 
 class SubtableProcessor : public UMemory {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage) = 0;
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success) = 0;
     virtual ~SubtableProcessor();
 
 protected:
-    SubtableProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    SubtableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
 
     SubtableProcessor();
 
@@ -58,7 +58,7 @@
     SubtableCoverage coverage;
     FeatureFlags subtableFeatures;
 
-    const MorphSubtableHeader *subtableHeader;
+    const LEReferenceTo<MorphSubtableHeader> subtableHeader;
 
 private:
 
--- a/src/share/native/sun/font/layout/SubtableProcessor2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SubtableProcessor2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -40,13 +40,14 @@
 {
 }
 
-SubtableProcessor2::SubtableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
+SubtableProcessor2::SubtableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : subtableHeader(morphSubtableHeader, success), length(0), coverage(0), subtableFeatures(0L)
 {
-    subtableHeader = morphSubtableHeader;
+  if(LE_FAILURE(success)) return;
 
-    length = SWAPL(subtableHeader->length);
-    coverage = SWAPL(subtableHeader->coverage);
-    subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
+  length = SWAPL(subtableHeader->length);
+  coverage = SWAPL(subtableHeader->coverage);
+  subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
 }
 
 SubtableProcessor2::~SubtableProcessor2()
--- a/src/share/native/sun/font/layout/SubtableProcessor2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/SubtableProcessor2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -46,11 +46,11 @@
 
 class SubtableProcessor2 : public UMemory {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage) = 0;
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success) = 0;
     virtual ~SubtableProcessor2();
 
 protected:
-    SubtableProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    SubtableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
 
     SubtableProcessor2();
 
@@ -58,7 +58,7 @@
     SubtableCoverage2 coverage;
     FeatureFlags subtableFeatures;
 
-    const MorphSubtableHeader2 *subtableHeader;
+    const LEReferenceTo<MorphSubtableHeader2> subtableHeader;
 
 private:
 
--- a/src/share/native/sun/font/layout/ThaiLayoutEngine.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ThaiLayoutEngine.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -134,11 +134,10 @@
         return;
     }
 
-    if (fTypoFlags & 0x1) { /* kerning enabled */
-      static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG;
-
-      KernTable kt(fFontInstance, getFontTable(kernTableTag));
-      kt.process(glyphStorage);
+    if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
+      LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
+      KernTable kt(kernTable, success);
+      kt.process(glyphStorage, success);
     }
 
     // default is no adjustments
--- a/src/share/native/sun/font/layout/TibetanLayoutEngine.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/TibetanLayoutEngine.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -49,7 +49,7 @@
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TibetanOpenTypeLayoutEngine)
 
 TibetanOpenTypeLayoutEngine::TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                    le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
+                                                         le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
 {
     fFeatureMap   = TibetanReordering::getFeatureMap(fFeatureMapCount);
--- a/src/share/native/sun/font/layout/TibetanLayoutEngine.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/TibetanLayoutEngine.h	Mon Mar 04 12:29:30 2013 -0800
@@ -83,7 +83,7 @@
      * @internal
      */
     TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                            le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
+                            le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
 
     /**
      * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/TrimmedArrayProcessor.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/TrimmedArrayProcessor.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -46,22 +46,28 @@
 {
 }
 
-TrimmedArrayProcessor::TrimmedArrayProcessor(const MorphSubtableHeader *morphSubtableHeader)
-  : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader)
+TrimmedArrayProcessor::TrimmedArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+  : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success), firstGlyph(0), lastGlyph(0)
 {
-    const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader;
+  LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success);
 
-    trimmedArrayLookupTable = (const TrimmedArrayLookupTable *) &header->table;
-    firstGlyph = SWAPW(trimmedArrayLookupTable->firstGlyph);
-    lastGlyph = firstGlyph + SWAPW(trimmedArrayLookupTable->glyphCount);
+  if(LE_FAILURE(success)) return;
+
+  trimmedArrayLookupTable = LEReferenceTo<TrimmedArrayLookupTable>(morphSubtableHeader, success, (const TrimmedArrayLookupTable*)&header->table);
+
+  if(LE_FAILURE(success)) return;
+
+  firstGlyph = SWAPW(trimmedArrayLookupTable->firstGlyph);
+  lastGlyph = firstGlyph + SWAPW(trimmedArrayLookupTable->glyphCount);
 }
 
 TrimmedArrayProcessor::~TrimmedArrayProcessor()
 {
 }
 
-void TrimmedArrayProcessor::process(LEGlyphStorage &glyphStorage)
+void TrimmedArrayProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
+  if(LE_FAILURE(success)) return;
     le_int32 glyphCount = glyphStorage.getGlyphCount();
     le_int32 glyph;
 
--- a/src/share/native/sun/font/layout/TrimmedArrayProcessor.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/TrimmedArrayProcessor.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,9 +50,9 @@
 class TrimmedArrayProcessor : public NonContextualGlyphSubstitutionProcessor
 {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage);
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
-    TrimmedArrayProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    TrimmedArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
 
     virtual ~TrimmedArrayProcessor();
 
@@ -76,7 +76,7 @@
 protected:
     TTGlyphID firstGlyph;
     TTGlyphID lastGlyph;
-    const TrimmedArrayLookupTable *trimmedArrayLookupTable;
+    LEReferenceTo<TrimmedArrayLookupTable> trimmedArrayLookupTable;
 
 };
 
--- a/src/share/native/sun/font/layout/TrimmedArrayProcessor2.cpp	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/TrimmedArrayProcessor2.cpp	Mon Mar 04 12:29:30 2013 -0800
@@ -46,22 +46,24 @@
 {
 }
 
-TrimmedArrayProcessor2::TrimmedArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
-  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader)
+TrimmedArrayProcessor2::TrimmedArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success)
 {
-    const NonContextualGlyphSubstitutionHeader2 *header = (const NonContextualGlyphSubstitutionHeader2 *) morphSubtableHeader;
+    const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success);
 
-    trimmedArrayLookupTable = (const TrimmedArrayLookupTable *) &header->table;
+    trimmedArrayLookupTable = LEReferenceTo<TrimmedArrayLookupTable>(morphSubtableHeader, success, &header->table);
     firstGlyph = SWAPW(trimmedArrayLookupTable->firstGlyph);
     lastGlyph = firstGlyph + SWAPW(trimmedArrayLookupTable->glyphCount);
+    valueArray = LEReferenceToArrayOf<LookupValue>(morphSubtableHeader, success, &trimmedArrayLookupTable->valueArray[0], LE_UNBOUNDED_ARRAY);
 }
 
 TrimmedArrayProcessor2::~TrimmedArrayProcessor2()
 {
 }
 
-void TrimmedArrayProcessor2::process(LEGlyphStorage &glyphStorage)
+void TrimmedArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
+    if(LE_FAILURE(success)) return;
     le_int32 glyphCount = glyphStorage.getGlyphCount();
     le_int32 glyph;
 
@@ -70,7 +72,7 @@
         TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph);
 
         if ((ttGlyph > firstGlyph) && (ttGlyph < lastGlyph)) {
-            TTGlyphID newGlyph = SWAPW(trimmedArrayLookupTable->valueArray[ttGlyph - firstGlyph]);
+            TTGlyphID newGlyph = SWAPW(valueArray(ttGlyph - firstGlyph, success));
 
             glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
         }
--- a/src/share/native/sun/font/layout/TrimmedArrayProcessor2.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/TrimmedArrayProcessor2.h	Mon Mar 04 12:29:30 2013 -0800
@@ -50,9 +50,9 @@
 class TrimmedArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2
 {
 public:
-    virtual void process(LEGlyphStorage &glyphStorage);
+    virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
-    TrimmedArrayProcessor2(const MorphSubtableHeader2 *morphSubtableHeader);
+    TrimmedArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
 
     virtual ~TrimmedArrayProcessor2();
 
@@ -76,8 +76,8 @@
 protected:
     TTGlyphID firstGlyph;
     TTGlyphID lastGlyph;
-    const TrimmedArrayLookupTable *trimmedArrayLookupTable;
-
+    LEReferenceTo<TrimmedArrayLookupTable> trimmedArrayLookupTable;
+    LEReferenceToArrayOf<LookupValue> valueArray;
 };
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/ValueRecords.h	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/layout/ValueRecords.h	Mon Mar 04 12:29:30 2013 -0800
@@ -64,6 +64,7 @@
     static le_int16    getFieldCount(ValueFormat valueFormat);
     static le_int16    getFieldIndex(ValueFormat valueFormat, ValueRecordField field);
 };
+LE_VAR_ARRAY(ValueRecord, values)
 
 enum ValueRecordFields
 {
--- a/src/share/native/sun/font/sunFont.c	Fri Mar 01 21:35:49 2013 +0400
+++ b/src/share/native/sun/font/sunFont.c	Mon Mar 04 12:29:30 2013 -0800
@@ -320,22 +320,20 @@
 JNIEXPORT TTLayoutTableCache* newLayoutTableCache() {
   TTLayoutTableCache* ltc = calloc(1, sizeof(TTLayoutTableCache));
   if (ltc) {
-    ltc->gsub_len = -1;
-    ltc->gpos_len = -1;
-    ltc->gdef_len = -1;
-    ltc->mort_len = -1;
-    ltc->kern_len = -1;
+    int i;
+    for(i=0;i<LAYOUTCACHE_ENTRIES;i++) {
+      ltc->entries[i].len = -1;
+    }
   }
   return ltc;
 }
 
 JNIEXPORT void freeLayoutTableCache(TTLayoutTableCache* ltc) {
   if (ltc) {
-    if (ltc->gsub) free(ltc->gsub);
-    if (ltc->gpos) free(ltc->gpos);
-    if (ltc->gdef) free(ltc->gdef);
-    if (ltc->mort) free(ltc->mort);
-    if (ltc->kern) free(ltc->kern);
+    int i;
+    for(i=0;i<LAYOUTCACHE_ENTRIES;i++) {
+      if(ltc->entries[i].ptr) free (ltc->entries[i].ptr);
+    }
     if (ltc->kernPairs) free(ltc->kernPairs);
     free(ltc);
   }