jdk/src/share/native/sun/font/layout/LigatureSubstProc2.cpp
changeset 16891 91e99bed64ae
parent 16890 36b30720a997
child 22330 cafb826672bd
equal deleted inserted replaced
16890:36b30720a997 16891:91e99bed64ae
    45 #define SignBit(m) ((ExtendedComplement(m) >> 1) & (le_int32)(m))
    45 #define SignBit(m) ((ExtendedComplement(m) >> 1) & (le_int32)(m))
    46 #define SignExtend(v,m) (((v) & SignBit(m))? ((v) | ExtendedComplement(m)): (v))
    46 #define SignExtend(v,m) (((v) & SignBit(m))? ((v) | ExtendedComplement(m)): (v))
    47 
    47 
    48 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor2)
    48 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor2)
    49 
    49 
    50 LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
    50 LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
    51   : StateTableProcessor2(morphSubtableHeader)
    51   : StateTableProcessor2(morphSubtableHeader, success),
       
    52   ligActionOffset(0),
       
    53   ligatureSubstitutionHeader(morphSubtableHeader, success), componentOffset(0), ligatureOffset(0), entryTable()
    52 {
    54 {
    53     ligatureSubstitutionHeader = (const LigatureSubstitutionHeader2 *) morphSubtableHeader;
    55     if (LE_FAILURE(success)) return;
       
    56 
    54     ligActionOffset = SWAPL(ligatureSubstitutionHeader->ligActionOffset);
    57     ligActionOffset = SWAPL(ligatureSubstitutionHeader->ligActionOffset);
    55     componentOffset = SWAPL(ligatureSubstitutionHeader->componentOffset);
    58     componentOffset = SWAPL(ligatureSubstitutionHeader->componentOffset);
    56     ligatureOffset = SWAPL(ligatureSubstitutionHeader->ligatureOffset);
    59     ligatureOffset = SWAPL(ligatureSubstitutionHeader->ligatureOffset);
    57 
    60 
    58     entryTable = (const LigatureSubstitutionStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
    61     entryTable = LEReferenceToArrayOf<LigatureSubstitutionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
    59 }
    62 }
    60 
    63 
    61 LigatureSubstitutionProcessor2::~LigatureSubstitutionProcessor2()
    64 LigatureSubstitutionProcessor2::~LigatureSubstitutionProcessor2()
    62 {
    65 {
    63 }
    66 }
    65 void LigatureSubstitutionProcessor2::beginStateTable()
    68 void LigatureSubstitutionProcessor2::beginStateTable()
    66 {
    69 {
    67     m = -1;
    70     m = -1;
    68 }
    71 }
    69 
    72 
    70 le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index)
    73 le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success)
    71 {
    74 {
    72     const LigatureSubstitutionStateEntry2 *entry = &entryTable[index];
    75     const LigatureSubstitutionStateEntry2 *entry = entryTable.getAlias(index, success);
       
    76     if(LE_FAILURE(success)) return 0;
       
    77 
    73     le_uint16 nextStateIndex = SWAPW(entry->nextStateIndex);
    78     le_uint16 nextStateIndex = SWAPW(entry->nextStateIndex);
    74     le_uint16 flags = SWAPW(entry->entryFlags);
    79     le_uint16 flags = SWAPW(entry->entryFlags);
    75     le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex);
    80     le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex);
    76 
    81 
    77     if (flags & lsfSetComponent) {
    82     if (flags & lsfSetComponent) {
    79             m = 0;
    84             m = 0;
    80         }
    85         }
    81         componentStack[m] = currGlyph;
    86         componentStack[m] = currGlyph;
    82     } else if ( m == -1) {
    87     } else if ( m == -1) {
    83         // bad font- skip this glyph.
    88         // bad font- skip this glyph.
    84         LE_DEBUG_BAD_FONT("m==-1")
    89         //LE_DEBUG_BAD_FONT("m==-1 (componentCount went negative)")
    85         currGlyph+= dir;
    90         currGlyph+= dir;
    86         return nextStateIndex;
    91         return nextStateIndex;
    87     }
    92     }
    88 
    93 
    89     ByteOffset actionOffset = flags & lsfPerformAction;
    94     ByteOffset actionOffset = flags & lsfPerformAction;
    90 
    95 
    91     if (actionOffset != 0) {
    96     if (actionOffset != 0) {
    92         const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + ligActionOffset) + ligActionIndex;
    97         LEReferenceTo<LigatureActionEntry> ap(stHeader, success, ligActionOffset); // byte offset
    93         const TTGlyphID *ligatureTable = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + ligatureOffset);
    98         ap.addObject(ligActionIndex - 1, success);  // index offset ( one before the actual start, because we will pre-increment)
       
    99         LEReferenceToArrayOf<TTGlyphID> ligatureTable(stHeader, success, ligatureOffset, LE_UNBOUNDED_ARRAY);
    94         LigatureActionEntry action;
   100         LigatureActionEntry action;
    95         le_int32 offset, i = 0;
   101         le_int32 offset, i = 0;
    96         le_int32 stack[nComponents];
   102         le_int32 stack[nComponents];
    97         le_int16 mm = -1;
   103         le_int16 mm = -1;
    98 
   104 
    99         const le_uint16 *componentTable = (const le_uint16 *)((char *) &ligatureSubstitutionHeader->stHeader + componentOffset);
   105         LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY);
   100 
   106         if(LE_FAILURE(success)) {
   101         const le_uint16 *tableEnd = (const le_uint16 *)((char *) &ligatureSubstitutionHeader + SWAPL(ligatureSubstitutionHeader->length));
       
   102 
       
   103         // Check if the font is internally consistent
       
   104         if(tableEnd < (const le_uint16*)&ligatureSubstitutionHeader  // stated end wrapped around?
       
   105            || componentTable > tableEnd) { // offset past end of stated length?
       
   106           currGlyph+= dir;
   107           currGlyph+= dir;
   107           LE_DEBUG_BAD_FONT("ligatureSubstHeader off end of table")
       
   108             return nextStateIndex; // get out! bad font
   108             return nextStateIndex; // get out! bad font
   109         }
   109         }
   110 
   110 
   111         do {
   111         do {
   112             le_uint32 componentGlyph = componentStack[m--]; // pop off
   112             le_uint32 componentGlyph = componentStack[m--]; // pop off
   113 
   113 
   114             action = SWAPL(*ap++);
   114             ap.addObject(success);
       
   115             action = SWAPL(*ap.getAlias());
   115 
   116 
   116             if (m < 0) {
   117             if (m < 0) {
   117                 m = nComponents - 1;
   118                 m = nComponents - 1;
   118             }
   119             }
   119 
   120 
   122                 if(componentGlyph > glyphStorage.getGlyphCount()) {
   123                 if(componentGlyph > glyphStorage.getGlyphCount()) {
   123                   LE_DEBUG_BAD_FONT("preposterous componentGlyph");
   124                   LE_DEBUG_BAD_FONT("preposterous componentGlyph");
   124                   currGlyph+= dir;
   125                   currGlyph+= dir;
   125                   return nextStateIndex; // get out! bad font
   126                   return nextStateIndex; // get out! bad font
   126                 }
   127                 }
   127                 i += SWAPW(componentTable[LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask))]);
   128                 i += SWAPW(componentTable(LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask)),success));
   128 
   129 
   129                 if (action & (lafLast | lafStore))  {
   130                 if (action & (lafLast | lafStore))  {
   130                     TTGlyphID ligatureGlyph = SWAPW(ligatureTable[i]);
   131                   TTGlyphID ligatureGlyph = SWAPW(ligatureTable(i,success));
   131                     glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
   132                     glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
   132                     if(mm==nComponents) {
   133                     if(mm==nComponents) {
   133                       LE_DEBUG_BAD_FONT("exceeded nComponents");
   134                       LE_DEBUG_BAD_FONT("exceeded nComponents");
   134                       mm--; // don't overrun the stack.
   135                       mm--; // don't overrun the stack.
   135                     }
   136                     }