ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
{
  LEErrorCode success = LE_NO_ERROR;
  const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);

    ByteOffset newState = SWAPW(entry->newStateOffset);
    le_int16 flags = SWAPW(entry->flags);

    if (flags & lsfSetComponent) {
        if (++m >= nComponents) {
            m = 0;
        }

        componentStack[m] = currGlyph;
    } else if ( m == -1) {
        // bad font- skip this glyph.
        currGlyph++;
        return newState;
    }

    ByteOffset actionOffset = flags & lsfActionOffsetMask;

    if (actionOffset != 0) {
      LEReferenceTo<LigatureActionEntry> ap(stHeader, success, actionOffset);
        LigatureActionEntry action;
        le_int32 offset, i = 0;
        le_int32 stack[nComponents];
        le_int16 mm = -1;

        do {
            le_uint32 componentGlyph = componentStack[m--];

            action = SWAPL(*ap.getAlias());
            ap.addObject(success); // ap++

            if (m < 0) {
                m = nComponents - 1;
            }

            offset = action & lafComponentOffsetMask;
            if (offset != 0) {
              LEReferenceToArrayOf<le_int16> offsetTable(stHeader, success, 2 * SignExtend(offset, lafComponentOffsetMask), LE_UNBOUNDED_ARRAY);

              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.getObject(LE_GET_GLYPH(glyphStorage[componentGlyph]), success));

                if (action & (lafLast | lafStore))  {
                  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;
                } else {
                  glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
                }
            }
#if LE_ASSERT_BAD_FONT
            if(m<0) {
              LE_DEBUG_BAD_FONT("m<0")
            }
#endif
        } 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;
          }

          componentStack[m] = stack[mm--];
        }
    }
Exemplo n.º 2
0
le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success)
{
    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);

    if (flags & lsfSetComponent) {
        if (++m >= nComponents) {
            m = 0;
        }
        componentStack[m] = currGlyph;
    } else if ( m == -1) {
        // bad font- skip this glyph.
        //LE_DEBUG_BAD_FONT("m==-1 (componentCount went negative)")
        currGlyph+= dir;
        return nextStateIndex;
    }

    ByteOffset actionOffset = flags & lsfPerformAction;

    if (actionOffset != 0) {
        LEReferenceTo<LigatureActionEntry> ap(stHeader, success, ligActionOffset); // byte offset
        if (LE_FAILURE(success)) {
            currGlyph+= dir;
            return nextStateIndex;
        }
        ap.addObject(ligActionIndex, success);
        LEReferenceToArrayOf<TTGlyphID> ligatureTable(stHeader, success, ligatureOffset, LE_UNBOUNDED_ARRAY);
        LigatureActionEntry action;
        le_int32 offset, i = 0, j = 0;
        le_int32 stack[nComponents];
        le_int16 mm = -1;

        LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY);
        if(LE_FAILURE(success)) {
            currGlyph+= dir;
            return nextStateIndex; // get out! bad font
        }

        do {
            le_uint32 componentGlyph = componentStack[m--]; // pop off

            if (j++ > 0) {
                ap.addObject(success);
            }
            if (LE_FAILURE(success)) {
                currGlyph+= dir;
                return nextStateIndex;
            }

            action = SWAPL(*ap.getAlias());

            if (m < 0) {
                m = nComponents - 1;
            }

            offset = action & lafComponentOffsetMask;
            if (offset != 0) {
                if(componentGlyph >= glyphStorage.getGlyphCount()) {
                  LE_DEBUG_BAD_FONT("preposterous componentGlyph");
                  currGlyph+= dir;
                  return nextStateIndex; // get out! bad font
                }
                i += SWAPW(componentTable(LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask)),success));
                if (LE_FAILURE(success)) {
                    currGlyph+= dir;
                    return nextStateIndex;
                }

                if (action & (lafLast | lafStore))  {
                  TTGlyphID ligatureGlyph = SWAPW(ligatureTable(i,success));
                  if (LE_FAILURE(success)) {
                      currGlyph+= dir;
                      return nextStateIndex;
                  }
                    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);
                }
            }
#if LE_ASSERT_BAD_FONT
            if(m<0) {
              LE_DEBUG_BAD_FONT("m<0")
            }
#endif
        } while (LE_SUCCESS(success) && !(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items

        while (mm >= 0) {
            if (++m >= nComponents) {
                m = 0;
            }

            componentStack[m] = stack[mm--];
        }
    }