Esempio n. 1
0
PRIVATE int16 CopyForgottenTables( CONST_TTFACC_FILEBUFFERINFO * pInputBufferInfo, 
                                 TTFACC_FILEBUFFERINFO * pOutputBufferInfo, 
                                 uint32 * pulNewOutOffset )
{
DIRECTORY *aDirectory;
OFFSET_TABLE OffsetTable;
uint16 usnTables;
uint16 usTableIdx;
uint16 usBytesRead;
uint32 ulBytesRead;
uint32 ulOffset;
int16 errCode;
char szTag[5];

    /* read offset table and determine number of existing tables */
    ulOffset = pOutputBufferInfo->ulOffsetTableOffset;
    if ((errCode = ReadGeneric( pOutputBufferInfo, (uint8 *) &OffsetTable, SIZEOF_OFFSET_TABLE, OFFSET_TABLE_CONTROL, ulOffset, &usBytesRead)) != NO_ERROR)
        return(ERR_MEM);
    ulOffset += usBytesRead;

    usnTables = OffsetTable.numTables;
    /* Create a list of valid tables */

    aDirectory = (DIRECTORY *) Mem_Alloc((usnTables) * sizeof(DIRECTORY));
    if (aDirectory == NULL)
        return(ERR_MEM);

    errCode = ReadGenericRepeat( pOutputBufferInfo, (uint8 *) aDirectory, DIRECTORY_CONTROL, ulOffset, &ulBytesRead, usnTables, SIZEOF_DIRECTORY );

    if (errCode != NO_ERROR)
    {
        Mem_Free(aDirectory);
        return errCode;
    }
    /* sort directories by offset */

    SortByOffset( aDirectory, usnTables );  /* will sort all the zero offsets to the beginning */
    
    for ( usTableIdx = 0; usTableIdx < usnTables; usTableIdx++ )
    {
        /* copy the forgotten table from the input file to the output file */
        if (aDirectory[ usTableIdx ].length == 0 &&
            aDirectory[ usTableIdx ].offset == DIRECTORY_ERROR)
        {
            if (aDirectory[ usTableIdx ].tag != DELETETABLETAG) /* it hasn't been marked for deletion */
            {
            /* Copy the table contents over, and update the directory */
                ConvertLongTagToString(aDirectory[ usTableIdx ].tag, szTag);
                if ((errCode = CopyTableOver( pOutputBufferInfo, pInputBufferInfo, szTag, pulNewOutOffset )) != NO_ERROR)
                    break;
            }
        }
        else
            break; /* we're done with all the forgotten tables */
    }

    Mem_Free(aDirectory);

    return(errCode);
}
Esempio n. 2
0
static int16 UpdateKeepWithCoverage(TTFACC_FILEBUFFERINFO * pInputBufferInfo, uint8 * pabKeepGlyphs, uint16 usnGlyphs, uint16 fKeepFlag, uint32 ulBaseOffset, uint32 ulCoverageOffset, uint16 *pArray, uint16 usLookupType, uint16 usSubstFormat)
{
    uint32 ulOffset;
    uint16 usCoverageFormat;
    GSUBCOVERAGEFORMAT1    Coverage1;
    GSUBCOVERAGEFORMAT2    Coverage2;
    uint16 usCount;    /* number of array elements in coverage table */
    uint16 usGlyphCount; /* number of glyphs processed in Coverage Table */
    uint16 usGlyphID;
    uint16 *pGlyphIDArray = NULL;
    GSUBRANGERECORD *pRangeRecordArray = NULL;
    uint16 i, j, k, l;
    uint16 usBytesRead;
    uint32 ulBytesRead;
    int16 errCode = NO_ERROR;

    if ((ulCoverageOffset == 0) || (pArray == NULL))
        return NO_ERROR;
    ulOffset = ulBaseOffset + ulCoverageOffset;
    if ((errCode = ReadWord( pInputBufferInfo, &usCoverageFormat, ulOffset)) != NO_ERROR)
        return errCode;
    /* OK, read in the actual Coverage Table */
    switch (usCoverageFormat)
    {
    case 1:
        if ((errCode = ReadGeneric( pInputBufferInfo,  (uint8 *)&Coverage1, SIZEOF_GSUBCOVERAGEFORMAT1, GSUBCOVERAGEFORMAT1_CONTROL, ulOffset, &usBytesRead) )!= NO_ERROR)
            return errCode;
        ulOffset += usBytesRead;
        usCount = Coverage1.GlyphCount;
        pGlyphIDArray = (uint16 *)Mem_Alloc(usCount * sizeof(uint16));
        if (pGlyphIDArray == NULL)
            return ERR_MEM;
        if ((errCode = ReadGenericRepeat( pInputBufferInfo, (uint8 *)pGlyphIDArray, WORD_CONTROL, ulOffset, &ulBytesRead, usCount, sizeof(uint16)) )!= NO_ERROR)
        {
            Mem_Free(pGlyphIDArray);
            return errCode;
        }
        break;
    case 2:
        if ((errCode = ReadGeneric( pInputBufferInfo,  (uint8 *)&Coverage2, SIZEOF_GSUBCOVERAGEFORMAT2, GSUBCOVERAGEFORMAT2_CONTROL, ulOffset, &usBytesRead) )!= NO_ERROR)
            return errCode;
        ulOffset += usBytesRead;
        usCount = Coverage2.CoverageRangeCount;
        pRangeRecordArray = (GSUBRANGERECORD *)Mem_Alloc(usCount * SIZEOF_GSUBRANGERECORD);
        if (pRangeRecordArray == NULL)
            return ERR_MEM;
        if ((errCode = ReadGenericRepeat( pInputBufferInfo, (uint8 *) pRangeRecordArray,  GSUBRANGERECORD_CONTROL, ulOffset, &ulBytesRead, usCount, SIZEOF_GSUBRANGERECORD) )!= NO_ERROR)
        {
            Mem_Free(pRangeRecordArray);
            return errCode;
        }
        break;
    default:
        return ERR_INVALID_TTO;
    }

    for (i = 0, j = 0, usGlyphCount = 0; i < usCount && errCode == NO_ERROR; ++usGlyphCount) /* while the entire Coverage Table has not been processed */
    {
        /* First, get a glyph Code from coverage table */
        if (usCoverageFormat == 1)
        {
            usGlyphID = pGlyphIDArray[i];
            ++i;
        }
        else
        {
            usGlyphID = (uint16) (pRangeRecordArray[i].RangeStart + j);
            if (usGlyphID < pRangeRecordArray[i].RangeEnd)
                ++j;
            else  /* go to next range */
            {
                ++i;
                j = 0;
            }
        }

        /* Next, see if it exists, and deal with corresponding Substitute data */
        if (usGlyphID >= usnGlyphs || pabKeepGlyphs[usGlyphID] != fKeepFlag)
            continue;

        /* now read in the actual Subtitute Glyph Data and process */
        switch (usLookupType)
        {
        case GSUBSingleLookupType:
            if (usSubstFormat == 1)
            {
                if ((usGlyphID + (int16) *pArray) < usnGlyphs && pabKeepGlyphs[usGlyphID + (int16) *pArray] == 0)
                    pabKeepGlyphs[usGlyphID + (int16) *pArray] = (uint8)(fKeepFlag + 1);
            }
            else
            {
                if (pArray[usGlyphCount] < usnGlyphs && pabKeepGlyphs[pArray[usGlyphCount]] == 0)
                    pabKeepGlyphs[pArray[usGlyphCount]] = (uint8)(fKeepFlag + 1);
            }
            break;
        case GSUBMultipleLookupType:
        {
            uint16 usSequenceGlyphCount;
            uint16 *pausGlyphID = NULL;

            if (pArray[usGlyphCount] == 0)
                break;
            ulOffset = ulBaseOffset + pArray[usGlyphCount];
            if ((errCode = ReadWord( pInputBufferInfo, &usSequenceGlyphCount, ulOffset ) )!= NO_ERROR)
                break;
            ulOffset += sizeof(uint16);
            pausGlyphID = (uint16 *)Mem_Alloc(usSequenceGlyphCount * sizeof(uint16));
            if (pausGlyphID == NULL)
            {
                errCode = ERR_MEM;
                break;
            }
            errCode = ReadGenericRepeat( pInputBufferInfo, (uint8 *)pausGlyphID, WORD_CONTROL, ulOffset, &ulBytesRead, usSequenceGlyphCount, sizeof(uint16));
            if (errCode == NO_ERROR)
            {
                for (k = 0; k < usSequenceGlyphCount; ++k)
                {
                    if (pausGlyphID[k] < usnGlyphs && pabKeepGlyphs[pausGlyphID[k]] == 0)
                        pabKeepGlyphs[pausGlyphID[k]] = (uint8)(fKeepFlag + 1);
                }
            }
            Mem_Free (pausGlyphID);
            break;
        }
        case GSUBAlternateLookupType:
        {
            uint16 usAlternateGlyphCount;
            uint16 *pausGlyphID = NULL;

            if (pArray[usGlyphCount] == 0)
                break;
            ulOffset = ulBaseOffset + pArray[usGlyphCount];
            if ((errCode = ReadWord( pInputBufferInfo, &usAlternateGlyphCount, ulOffset ) )!= NO_ERROR)
                break;
            ulOffset += sizeof(uint16);
            pausGlyphID = (uint16 *)Mem_Alloc(usAlternateGlyphCount * sizeof(uint16));
            if (pausGlyphID == NULL)
            {
                errCode = ERR_MEM;
                break;
            }
            if ((errCode = ReadGenericRepeat( pInputBufferInfo, (uint8 *)pausGlyphID, WORD_CONTROL, ulOffset, &ulBytesRead, usAlternateGlyphCount, sizeof(uint16)) )== NO_ERROR)
            {
                for (k = 0; k < usAlternateGlyphCount; ++k)
                {
                    if (pausGlyphID[k] < usnGlyphs && pabKeepGlyphs[pausGlyphID[k]] == 0)
                        pabKeepGlyphs[pausGlyphID[k]] = (uint8)(fKeepFlag + 1);
                }
            }
            Mem_Free (pausGlyphID);
            break;
        }
        case GSUBLigatureLookupType:
        {
            uint16 usLigatureCompCount;
            uint16 usLigatureCount;
            uint16 *pausCompGlyphID = NULL; /* glyph IDs components of ligature */
            uint16 usLigatureGlyphID;   /* actual glyph to substitute for ligatures */
            uint16 *pausLigatureOffsetArray = NULL;
            GSUBLIGATURE GSUBLigature;

            if (pArray[usGlyphCount] == 0)
                break;
            ulOffset = ulBaseOffset + pArray[usGlyphCount];
            if ((errCode = ReadWord( pInputBufferInfo, &usLigatureCount, ulOffset ) )!= NO_ERROR)
                break;
            ulOffset += sizeof(uint16);
            pausLigatureOffsetArray = (uint16 *)Mem_Alloc(usLigatureCount * sizeof(uint16));
            if (pausLigatureOffsetArray == NULL)
            {
                errCode = ERR_MEM;
                break;
            }
            if ((errCode = ReadGenericRepeat( pInputBufferInfo,  (uint8 *)pausLigatureOffsetArray, WORD_CONTROL, ulOffset, &ulBytesRead, usLigatureCount, sizeof(uint16)) ) == NO_ERROR)
            {
                for (l = 0; l < usLigatureCount; ++l)
                {
                    if (pausLigatureOffsetArray[l] == 0)
                        continue;
                    ulOffset = ulBaseOffset + (pArray)[usGlyphCount] + pausLigatureOffsetArray[l];
                    if ((errCode = ReadGeneric( pInputBufferInfo,  (uint8 *)&GSUBLigature, SIZEOF_GSUBLIGATURE, GSUBLIGATURE_CONTROL, ulOffset, &usBytesRead) )!= NO_ERROR)
                    {
                        Mem_Free (pausLigatureOffsetArray);
                        Mem_Free(pGlyphIDArray);
                        Mem_Free(pRangeRecordArray);
                        return errCode;
                    }
                    ulOffset += usBytesRead;
                    usLigatureCompCount = GSUBLigature.LigatureCompCount;
                    usLigatureGlyphID = GSUBLigature.GlyphID;
                    if (usLigatureGlyphID >= usnGlyphs || pabKeepGlyphs[usLigatureGlyphID] != 0)
                        continue;  /* already in list, go to next ligature */
                    pausCompGlyphID = (uint16 *)Mem_Alloc((usLigatureCompCount - 1) * sizeof(uint16));
                    if (pausCompGlyphID == NULL)
                    {
                        Mem_Free (pausLigatureOffsetArray);
                        Mem_Free(pGlyphIDArray);
                        Mem_Free(pRangeRecordArray);
                        return ERR_MEM;
                    }
                    if ((errCode = ReadGenericRepeat( pInputBufferInfo, (uint8 *)pausCompGlyphID, WORD_CONTROL, ulOffset, &ulBytesRead, (uint16) (usLigatureCompCount - 1) , sizeof(uint16)) )!= NO_ERROR)
                    {
                        Mem_Free (pausCompGlyphID);
                        Mem_Free (pausLigatureOffsetArray);
                        Mem_Free(pGlyphIDArray);
                        Mem_Free(pRangeRecordArray);
                        return errCode;
                    }
                    for (k = 0; k < usLigatureCompCount - 1; ++k)
                    {
                        if (pausCompGlyphID[k] >= usnGlyphs || pabKeepGlyphs[pausCompGlyphID[k]] == 0)
                            break; /* if one of the components is not in list, don't worry about ligature */
                    }
                    if (k == (usLigatureCompCount - 1) && pabKeepGlyphs[usLigatureGlyphID] == 0) /* got to the end of the component list */
                        pabKeepGlyphs[usLigatureGlyphID] = (uint8)(fKeepFlag+1);
                    Mem_Free(pausCompGlyphID);
                }
            }
            Mem_Free (pausLigatureOffsetArray);
            break;
        }
        }

    }
    Mem_Free(pGlyphIDArray);
    Mem_Free(pRangeRecordArray);
    return errCode;
}
Esempio n. 3
0
int16 TTOAutoMap( TTFACC_FILEBUFFERINFO * pInputBufferInfo,   /* ttfacc info */
                  uint8 * pabKeepGlyphs, /* binary list of glyphs to keep - to be updated here */
                  uint16 usnGlyphs,    /* number of glyphs in list */
                  uint16 fKeepFlag) /* flag index (really contains a number) of what to set in the pabKeepGlyph list */
{
    GSUBHEADER GSUBHeader;
    GSUBLOOKUPLIST GSUBLookupList, *pGSUBLookupList = NULL;
    JSTFHEADER JSTFHeader;
    JSTFSCRIPTRECORD *ScriptRecordArray;
    JSTFSCRIPT JSTFScript;
    JSTFEXTENDERGLYPH JSTFExtenderGlyph;
    uint16 *GlyphIDArray;
    BASEHEADER BASEHeader;
    BASEAXIS BASEAxis;
    BASESCRIPTLIST BASEScriptList;
    BASESCRIPTRECORD BASEScriptRecord;
    BASESCRIPT BASEScript;
    BASEVALUES BASEValues;
    BASELANGSYSRECORD BASELangSysRecord;
    uint16 BASECoordOffset;
    uint16 AxisOffset;
    uint32 ulHeaderOffset;
    uint32 ulCurrentOffset;
    uint32 ulLangSysOffset;
    uint16 usMaxLookupCount;
    uint32 ulOffset;
    uint16 i, j, k;
    uint16 usBytesRead;
    uint32 ulBytesRead;
    int16 errCode = NO_ERROR;


    /* Process GSUB Table */
    while (1)  /* so we can break out on null offsets */
    {
        ulHeaderOffset = TTTableOffset( pInputBufferInfo, GSUB_TAG );

        if (ulHeaderOffset == 0)
            break;

        if ((errCode = ReadGeneric( pInputBufferInfo,   (uint8 *)&GSUBHeader, SIZEOF_GSUBHEADER, GSUBHEADER_CONTROL, ulHeaderOffset, &usBytesRead ) )!= NO_ERROR)
            return errCode;

        /* now read the max number of lookups, for allocation of the lookup list */

        if (GSUBHeader.LookupListOffset == 0)
            break;
        if ((errCode = ReadGeneric( pInputBufferInfo,   (uint8 *)&GSUBLookupList, SIZEOF_GSUBLOOKUPLIST, GSUBLOOKUPLIST_CONTROL, ulHeaderOffset + GSUBHeader.LookupListOffset, &usBytesRead) )!= NO_ERROR)
            return errCode;
        usMaxLookupCount = GSUBLookupList.LookupCount;

        if (usMaxLookupCount == 0)
            break;

        while (1) /* so we can break out and clean up on error */
            /* Now look at lookup table, and add to list from Context lookups */
        {
            GSUBLOOKUP GSUBLookup;
            uint16 *SubstTableOffsetArray = NULL;

            ulOffset = ulHeaderOffset + GSUBHeader.LookupListOffset;
            pGSUBLookupList = (GSUBLOOKUPLIST *)Mem_Alloc(SIZEOF_GSUBLOOKUPLIST + usMaxLookupCount * sizeof(uint16));
            if (pGSUBLookupList == NULL)
            {
                errCode = ERR_MEM;
                break;
            }
            /* read the first part */
            if ((errCode = ReadGeneric( pInputBufferInfo,   (uint8 *) pGSUBLookupList, SIZEOF_GSUBLOOKUPLIST, GSUBLOOKUPLIST_CONTROL, ulOffset, &usBytesRead) )!= NO_ERROR)
                break;
            /* now read the array */
            if ((errCode = ReadGenericRepeat( pInputBufferInfo,  (uint8 *) ((uint8 *)pGSUBLookupList + SIZEOF_GSUBLOOKUPLIST), WORD_CONTROL, ulOffset + usBytesRead, &ulBytesRead, usMaxLookupCount, sizeof(uint16)) )!= NO_ERROR)
                break;

            /* now make sure all the referenced glyphs are in the keep table */

            for (i = 0; i < usMaxLookupCount; ++i)
            {
                uint16 usSubTableCount;

                if (pGSUBLookupList->LookupTableOffsetArray[i] == 0)
                    continue;
                ulOffset = ulHeaderOffset +
                           GSUBHeader.LookupListOffset +
                           pGSUBLookupList->LookupTableOffsetArray[i];
                if ((errCode = ReadGeneric( pInputBufferInfo,  (uint8 *)&GSUBLookup, SIZEOF_GSUBLOOKUP, GSUBLOOKUP_CONTROL, ulOffset, &usBytesRead) )!= NO_ERROR)
                    break;
                if (GSUBLookup.LookupType == GSUBContextLookupType)  /* not looking for context lookups */
                    continue;
                usSubTableCount = GSUBLookup.SubTableCount;
                SubstTableOffsetArray = (uint16 *)Mem_Alloc(sizeof(uint16) * usSubTableCount);
                if (SubstTableOffsetArray == NULL)
                {
                    errCode = ERR_MEM;
                    break;
                }
                if ((errCode = ReadGenericRepeat( pInputBufferInfo, (uint8 *) SubstTableOffsetArray, WORD_CONTROL, ulOffset + usBytesRead, &ulBytesRead, usSubTableCount, sizeof(uint16)) )!= NO_ERROR)
                    break;

                for (j = 0; j < usSubTableCount; ++j)
                {
                    uint16 Format;

                    if (SubstTableOffsetArray[j] == 0)
                        continue;
                    ulOffset = ulHeaderOffset +
                               GSUBHeader.LookupListOffset +
                               pGSUBLookupList->LookupTableOffsetArray[i] +
                               SubstTableOffsetArray[j];
                    if ((errCode = ReadWord( pInputBufferInfo, &Format, ulOffset) )!= NO_ERROR)
                        break;
                    switch(GSUBLookup.LookupType)
                    {
                    case GSUBSingleLookupType:
                    {
                        switch    (Format)
                        {
                        case 1:
                        {
                            GSUBSINGLESUBSTFORMAT1 GSUBSubstTable;

                            if ((errCode = ReadGeneric( pInputBufferInfo,  (uint8 *)&GSUBSubstTable, SIZEOF_GSUBSINGLESUBSTFORMAT1, GSUBSINGLESUBSTFORMAT1_CONTROL, ulOffset, &usBytesRead) )== NO_ERROR)
                                errCode = UpdateKeepWithCoverage( pInputBufferInfo, pabKeepGlyphs, usnGlyphs, fKeepFlag, ulOffset, GSUBSubstTable.CoverageOffset , (uint16 *) &(GSUBSubstTable.DeltaGlyphID), GSUBLookup.LookupType, Format);
                            break;
                        }
                        case 2:
                        {
                            GSUBSINGLESUBSTFORMAT2 GSUBSubstTable;
                            uint16 usGlyphCount;
                            uint16 *pGlyphIDArray = NULL;

                            if ((errCode = ReadGeneric( pInputBufferInfo,  (uint8 *)&GSUBSubstTable, SIZEOF_GSUBSINGLESUBSTFORMAT2, GSUBSINGLESUBSTFORMAT2_CONTROL, ulOffset, &usBytesRead) )!= NO_ERROR)
                                break;
                            usGlyphCount = GSUBSubstTable.GlyphCount;
                            pGlyphIDArray = (uint16 *)Mem_Alloc(sizeof(uint16) * usGlyphCount);
                            if (pGlyphIDArray == NULL)
                            {
                                errCode = ERR_MEM;
                                break;
                            }
                            if ((errCode = ReadGenericRepeat( pInputBufferInfo,  (uint8 *)pGlyphIDArray, WORD_CONTROL, ulOffset + usBytesRead, &ulBytesRead, usGlyphCount, sizeof(uint16)) )== NO_ERROR)
                                errCode = UpdateKeepWithCoverage( pInputBufferInfo, pabKeepGlyphs, usnGlyphs, fKeepFlag, ulOffset, GSUBSubstTable.CoverageOffset , pGlyphIDArray, GSUBLookup.LookupType, Format);
                            Mem_Free(pGlyphIDArray);
                            break;
                        }

                        default:
                            errCode = ERR_INVALID_GSUB;
                            break;
                        }
                        break;
                    }
                    case GSUBMultipleLookupType:
                    {
                        GSUBMULTIPLESUBSTFORMAT1 GSUBSubstTable;
                        uint16 usCount;
                        uint16 *pOffsetArray = NULL;

                        if (Format != 1)
                            break;
                        if ((errCode = ReadGeneric( pInputBufferInfo,  (uint8 *)&GSUBSubstTable, SIZEOF_GSUBMULTIPLESUBSTFORMAT1, GSUBMULTIPLESUBSTFORMAT1_CONTROL, ulOffset, &usBytesRead) )!= NO_ERROR)
                            break;
                        usCount = GSUBSubstTable.SequenceCount;
                        pOffsetArray = (uint16 *)Mem_Alloc(sizeof(uint16) * usCount);
                        if (pOffsetArray == NULL)
                        {
                            errCode = ERR_MEM;
                            break;
                        }
                        if ((errCode = ReadGenericRepeat( pInputBufferInfo,  (uint8 *)pOffsetArray, WORD_CONTROL, ulOffset + usBytesRead, &ulBytesRead, usCount, sizeof(uint16)) )== NO_ERROR)
                            errCode = UpdateKeepWithCoverage( pInputBufferInfo, pabKeepGlyphs, usnGlyphs, fKeepFlag, ulOffset, GSUBSubstTable.CoverageOffset , pOffsetArray, GSUBLookup.LookupType, Format);
                        Mem_Free(pOffsetArray);
                        break;
                    }
                    case GSUBAlternateLookupType:
                    {
                        GSUBALTERNATESUBSTFORMAT1 GSUBSubstTable;
                        uint16 usCount;
                        uint16 *pOffsetArray = NULL;

                        if (Format != 1)
                            break;
                        if ((errCode = ReadGeneric( pInputBufferInfo,  (uint8 *)&GSUBSubstTable, SIZEOF_GSUBALTERNATESUBSTFORMAT1, GSUBALTERNATESUBSTFORMAT1_CONTROL, ulOffset, &usBytesRead) )!= NO_ERROR)
                            break;
                        usCount = GSUBSubstTable.AlternateSetCount;
                        pOffsetArray = (uint16 *)Mem_Alloc(sizeof(uint16) * usCount);
                        if (pOffsetArray == NULL)
                        {
                            errCode = ERR_MEM;
                            break;
                        }
                        if ((errCode = ReadGenericRepeat( pInputBufferInfo,  (uint8 *)pOffsetArray, WORD_CONTROL, ulOffset + usBytesRead, &ulBytesRead, usCount, sizeof(uint16)) )== NO_ERROR)
                            errCode = UpdateKeepWithCoverage( pInputBufferInfo, pabKeepGlyphs, usnGlyphs, fKeepFlag, ulOffset, GSUBSubstTable.CoverageOffset , pOffsetArray, GSUBLookup.LookupType, Format);
                        Mem_Free(pOffsetArray);
                        break;
                    }
                    case GSUBLigatureLookupType:
                    {
                        GSUBLIGATURESUBSTFORMAT1 GSUBSubstTable;
                        uint16 usCount;
                        uint16 *pOffsetArray = NULL;

                        if (Format != 1)
                            break;
                        if ((errCode = ReadGeneric( pInputBufferInfo,  (uint8 *)&GSUBSubstTable, SIZEOF_GSUBLIGATURESUBSTFORMAT1, GSUBLIGATURESUBSTFORMAT1_CONTROL, ulOffset, &usBytesRead) )!= NO_ERROR)
                            break;
                        usCount = GSUBSubstTable.LigatureSetCount;
                        pOffsetArray = (uint16 *)Mem_Alloc(sizeof(uint16) * usCount);
                        if (pOffsetArray == NULL)
                        {
                            errCode = ERR_MEM;
                            break;
                        }
                        if ((errCode = ReadGenericRepeat( pInputBufferInfo,  (uint8 *)pOffsetArray, WORD_CONTROL, ulOffset + usBytesRead, &ulBytesRead, usCount, sizeof(uint16)) )== NO_ERROR)
                            errCode = UpdateKeepWithCoverage( pInputBufferInfo, pabKeepGlyphs, usnGlyphs, fKeepFlag, ulOffset, GSUBSubstTable.CoverageOffset , pOffsetArray, GSUBLookup.LookupType, Format);
                        Mem_Free(pOffsetArray);
                        break;
                    }
                    default:
                        break;
                    }
                    if (errCode != NO_ERROR)
                        break;

                }
                Mem_Free(SubstTableOffsetArray);
                if (errCode != NO_ERROR)
                    break;
            }
            break; /* artificial while for error conditions */
        }
        Mem_Free(pGSUBLookupList);
        break;
    }

    if (errCode != NO_ERROR)
        return errCode;
    /* Process JSTF Table */
    while (1) /* so we can break out on NULL offsets */
    {
        ulHeaderOffset = TTTableOffset( pInputBufferInfo, JSTF_TAG );

        if (ulHeaderOffset == 0)
            break;

        if ((errCode = ReadGeneric( pInputBufferInfo,   (uint8 *)&JSTFHeader, SIZEOF_JSTFHEADER, JSTFHEADER_CONTROL, ulHeaderOffset, &usBytesRead ) )!= NO_ERROR)
            break;
        ScriptRecordArray = (JSTFSCRIPTRECORD *)Mem_Alloc(SIZEOF_JSTFSCRIPTRECORD * JSTFHeader.ScriptCount);
        if (ScriptRecordArray == NULL)
        {
            errCode = ERR_MEM;
            break;
        }

        ulOffset = ulHeaderOffset;
        if ((errCode = ReadGenericRepeat( pInputBufferInfo, (uint8 *)ScriptRecordArray, JSTFSCRIPTRECORD_CONTROL, ulOffset + usBytesRead, & ulBytesRead, JSTFHeader.ScriptCount, SIZEOF_JSTFSCRIPTRECORD ) )!= NO_ERROR)
            break;

        for (i = 0 ; i < JSTFHeader.ScriptCount; ++i)
        {
            if (ScriptRecordArray[i].JstfScriptOffset == 0)
                continue;
            ulOffset = ulHeaderOffset + ScriptRecordArray[i].JstfScriptOffset;
            if ((errCode = ReadGeneric( pInputBufferInfo,  (uint8 *)&JSTFScript, SIZEOF_JSTFSCRIPT, JSTFSCRIPT_CONTROL, ulOffset, &usBytesRead) )!= NO_ERROR)
                break;
            if (JSTFScript.ExtenderGlyphOffset == 0)
                continue;
            ulOffset = ulOffset = ulHeaderOffset + ScriptRecordArray[i].JstfScriptOffset + JSTFScript.ExtenderGlyphOffset;

            if ((errCode = ReadGeneric( pInputBufferInfo,  (uint8 *)&JSTFExtenderGlyph, SIZEOF_JSTFEXTENDERGLYPH, JSTFEXTENDERGLYPH_CONTROL, ulOffset, &usBytesRead) )!= NO_ERROR)
                break;

            GlyphIDArray = (uint16 *)Mem_Alloc((sizeof(uint16) * JSTFExtenderGlyph.ExtenderGlyphCount));
            if (GlyphIDArray == NULL)
            {
                errCode = ERR_MEM;
                break;
            }
            if ((errCode = ReadGenericRepeat( pInputBufferInfo, (uint8 *)GlyphIDArray, WORD_CONTROL, ulOffset + usBytesRead, &ulBytesRead, JSTFExtenderGlyph.ExtenderGlyphCount, sizeof(uint16)) )== NO_ERROR)
            {
                for (j = 0; j < JSTFExtenderGlyph.ExtenderGlyphCount; ++j)
                {
                    if (GlyphIDArray[j] < usnGlyphs && pabKeepGlyphs[GlyphIDArray[j]] == 0)
                        pabKeepGlyphs[GlyphIDArray[j]] =  (uint8)(fKeepFlag + 1);
                }
            }
            Mem_Free(GlyphIDArray);
            if (errCode != NO_ERROR)
                break;
        }
        Mem_Free(ScriptRecordArray);
        break;
    }
    if (errCode != NO_ERROR)
        return errCode;
    /* Process BASE Table */
    while (1)
    {
        ulHeaderOffset = TTTableOffset( pInputBufferInfo, BASE_TAG );

        if (ulHeaderOffset == 0)
            break;

        if ((errCode = ReadGeneric( pInputBufferInfo,   (uint8 *)&BASEHeader, SIZEOF_BASEHEADER, BASEHEADER_CONTROL, ulHeaderOffset, &usBytesRead ) )!= NO_ERROR)
            break;

        AxisOffset = BASEHeader.HorizAxisOffset;
        for (i = 0; i < 2; ++i, AxisOffset = BASEHeader.VertAxisOffset)  /* process the 2 axis */
        {
            if (AxisOffset == 0)
                continue;
            ulOffset = ulHeaderOffset + AxisOffset;
            if ((errCode = ReadGeneric( pInputBufferInfo,   (uint8 *)&BASEAxis, SIZEOF_BASEAXIS, BASEAXIS_CONTROL, ulOffset, &usBytesRead ) )!= NO_ERROR)
                break;
            if (BASEAxis.BaseScriptListOffset == 0)
                continue;
            ulOffset = ulHeaderOffset + AxisOffset + BASEAxis.BaseScriptListOffset;
            if ((errCode = ReadGeneric( pInputBufferInfo,   (uint8 *)&BASEScriptList, SIZEOF_BASESCRIPTLIST, BASESCRIPTLIST_CONTROL, ulOffset, &usBytesRead ) )!= NO_ERROR)
                break;
            ulCurrentOffset = ulOffset + usBytesRead;
            for (j = 0; j < BASEScriptList.BaseScriptCount; ++j)
            {
                uint32 ulLocalOffset;

                if ((errCode = ReadGeneric( pInputBufferInfo,   (uint8 *)&BASEScriptRecord, SIZEOF_BASESCRIPTRECORD, BASESCRIPTRECORD_CONTROL, ulCurrentOffset, &usBytesRead ) )!= NO_ERROR)
                    break;
                ulCurrentOffset += usBytesRead;
                if (BASEScriptRecord.BaseScriptOffset == 0)
                    continue;

                if ((errCode = ReadGeneric( pInputBufferInfo,   (uint8 *)&BASEScript, SIZEOF_BASESCRIPT, BASESCRIPT_CONTROL, ulOffset + BASEScriptRecord.BaseScriptOffset, &usBytesRead ) )!= NO_ERROR)
                    break;

                ulLangSysOffset = ulOffset + BASEScriptRecord.BaseScriptOffset + usBytesRead;

                /* PROCESS BaseValuesOffset */
                if (BASEScript.BaseValuesOffset    != 0)
                {
                    ulLocalOffset = ulOffset + BASEScriptRecord.BaseScriptOffset + BASEScript.BaseValuesOffset ;

                    if ((errCode = ReadGeneric( pInputBufferInfo,   (uint8 *)&BASEValues, SIZEOF_BASEVALUES, BASEVALUES_CONTROL, ulLocalOffset, &usBytesRead ) )!= NO_ERROR)
                        break;
                    ulLocalOffset += usBytesRead;
                    for (k = 0; k < BASEValues.BaseCoordCount; ++k)
                    {
                        if ((errCode = ReadWord( pInputBufferInfo,  &BASECoordOffset, ulLocalOffset ) )!= NO_ERROR)
                            break;
                        ulLocalOffset += sizeof(uint16);
                        if ((errCode = ProcessBaseCoord( pInputBufferInfo, ulOffset + BASEScriptRecord.BaseScriptOffset + BASEScript.BaseValuesOffset + BASECoordOffset, pabKeepGlyphs, usnGlyphs, fKeepFlag))!= NO_ERROR)
                            break;
                    }
                    if (errCode != NO_ERROR)
                        break;
                }
                /* Process MinMaxOffset */
                if (BASEScript.MinMaxOffset != 0)
                {
                    ulLocalOffset = ulOffset + BASEScriptRecord.BaseScriptOffset + BASEScript.MinMaxOffset ;
                    if ((errCode = ProcessMinMax( pInputBufferInfo, ulLocalOffset, pabKeepGlyphs, usnGlyphs, fKeepFlag))!= NO_ERROR)
                        break;
                }
                /* Process BaseLangSysRecordArray */
                for (k = 0; k < BASEScript.BaseLangSysCount; ++k)
                {
                    if ((errCode = ReadGeneric( pInputBufferInfo,  (uint8 *)&BASELangSysRecord, SIZEOF_BASELANGSYSRECORD, BASELANGSYSRECORD_CONTROL, ulLangSysOffset, &usBytesRead ) )!= NO_ERROR)
                        break;
                    ulLangSysOffset += usBytesRead;
                    if (BASELangSysRecord.MinMaxOffset != 0)
                        if ((errCode = ProcessMinMax( pInputBufferInfo, ulOffset + BASEScriptRecord.BaseScriptOffset + BASELangSysRecord.MinMaxOffset, pabKeepGlyphs, usnGlyphs, fKeepFlag))!= NO_ERROR)
                            break;
                }
                if (errCode != NO_ERROR)
                    break;
            }
            if (errCode != NO_ERROR)
                break;
        }
        break;
    }
    return errCode;

}
Esempio n. 4
0
int16 ModVDMX(CONST_TTFACC_FILEBUFFERINFO * pInputBufferInfo, 
              TTFACC_FILEBUFFERINFO * pOutputBufferInfo,
              CONST uint16 usFormat,
              uint32 *pulNewOutOffset)
{
VDMX Vdmx;
uint32 ulSrcOffset; /* offset to Src VDMX table */
uint32 ulSrcLength; /* length of Src VDMX table */
uint32 ulDestOffset; /* offset to Dest VDMX table */
uint32 ulDestLength; /* length of Dest VDMX table */
uint32 ulSrcOffsetRatios;   /* absolute offset to Ratios in Src file */
uint32 ulSrcOffsetOffsets;  /* absolute offset to Offsets in Src file */
uint32 ulSrcOffsetGroups;   /* absolute offset to Groups in Src file */
uint32 ulDestOffsetRatios;  /* absolute offset to Ratios in Dest file */
uint32 ulDestOffsetOffsets; /* absolute offset to Offsets in Dest file */
uint32 ulDestOffsetGroups;  /* absolute offset to Groups in Dest file */
uint16 usCurrGroupSrcOffset; /* relative offset from beginning of VDMX table */
uint16 usCurrGroupDestOffset; /* relative offset from beginning of VDMX table */
uint32 ulCurrGroupDestOffset=0; /* relative offset from beginning of VDMX table - long value */
uint16 usGroupDestOffset; /* relative offset from beginning of VDMX table, local copy for writing */
uint16 ----cRatioIndex,usDestRatioIndex;
uint16 i;
uint16 usBytesRead;
uint16 usBytesWritten;
uint32 ulBytesRead;
int16 errCode=NO_ERROR;
VDMXRatio *SrcRatioArray=NULL;
int8 *KeepSrcRatioArray = NULL;   /* parallel array to SrcRatioArray */
VDMXGroup GroupHeader;
uint8 * pGroupBuffer=NULL;
uint32 ulGroupBufferLength; /* total length of the Group Buffer (from source file) */
uint32 ulGroupLength; /* length of individual group to be read */
uint16 usGroupCount = 0; 
uint16 usKeepRatioCount = 0;
uint16 usRatioSize;
uint16 xRatio, yRatio; /* for reducing the ratios */
int16 Found1to1; 
GROUPOFFSETRECORDKEEPER keeper; 
TTFACC_FILEBUFFERINFO * pUnCONSTInputBufferInfo;

    if (usFormat == TTFDELTA_DELTA)  /* only formats for which this is not valid */
    {
        MarkTableForDeletion(pOutputBufferInfo, VDMX_TAG);
        return errCode;
    }

    pUnCONSTInputBufferInfo = (TTFACC_FILEBUFFERINFO *) pInputBufferInfo; /* used for Read functions ONLY. Not for Write */
/* get input buffer information */
    ulSrcOffset = TTTableOffset( pUnCONSTInputBufferInfo, VDMX_TAG );
    if ( ulSrcOffset == 0L )
        return NO_ERROR;
    ulSrcLength = TTTableLength( pUnCONSTInputBufferInfo, VDMX_TAG );
    if ( ulSrcLength == 0L )
    {
        MarkTableForDeletion(pOutputBufferInfo, VDMX_TAG);
        return NO_ERROR;
    }
    /* get output buffer information */
    if ((errCode = ZeroLongWordAlign(pOutputBufferInfo, *pulNewOutOffset, &ulDestOffset)) != NO_ERROR)
        return errCode;

    if ((errCode = ReadGeneric( pUnCONSTInputBufferInfo, (uint8 *) &Vdmx, SIZEOF_VDMX, VDMX_CONTROL, ulSrcOffset, &usBytesRead )) != NO_ERROR)
        return errCode;
    if (Vdmx.numRatios == 0)
    {
        MarkTableForDeletion(pOutputBufferInfo, VDMX_TAG);
        return NO_ERROR;
    }


    ulSrcOffsetRatios = ulSrcOffset + usBytesRead;
    ulSrcOffsetOffsets = ulSrcOffsetRatios + GetGenericSize(VDMXRATIO_CONTROL) * Vdmx.numRatios;
    ulSrcOffsetGroups = ulSrcOffsetOffsets + sizeof(uint16) * Vdmx.numRatios;
    memset(&keeper, 0, sizeof(keeper));

    SrcRatioArray = (VDMXRatio *)Mem_Alloc(Vdmx.numRatios * sizeof(VDMXRatio));
    if (SrcRatioArray == NULL)
        errCode = ERR_MEM;
    else
    {
        KeepSrcRatioArray = (int8 *)Mem_Alloc(Vdmx.numRatios * sizeof(int8));
        if (KeepSrcRatioArray == NULL)
            errCode = ERR_MEM;
        else
            errCode = ReadGenericRepeat(pUnCONSTInputBufferInfo, (uint8 *) SrcRatioArray, VDMXRATIO_CONTROL, ulSrcOffsetRatios, &ulBytesRead, Vdmx.numRatios, SIZEOF_VDMXRATIO );
    }

    while (errCode == NO_ERROR)     /* while is so we can break out. Only go once through */
    {
        Found1to1 = FALSE;
        for (i = 0; i < Vdmx.numRatios ; ++i)    /* keep all 1:1 aspect ratios */
        {
            KeepSrcRatioArray[i] = 1; /* assume we'll keep it */
            xRatio = SrcRatioArray[i].xRatio;
            yRatio = SrcRatioArray[i].yStartRatio;
            ReduceRatio(&xRatio,&yRatio);
            if (xRatio == yRatio)
            {
                if (SrcRatioArray[i].xRatio == 0)   /* anything after 0:0 is ignored */
                {
                    if (!Found1to1) /* need to keep this one */
                        ++usKeepRatioCount;
                    break;
                }
                if (Found1to1)  /* already have one */
                    KeepSrcRatioArray[i] = 0;  /* don't keep this one */
                else
                {
                    Found1to1 = TRUE;
                    ++usKeepRatioCount;
                }
            }
            else if (xRatio == EGA_X_RATIO && yRatio == EGA_Y_RATIO)
                KeepSrcRatioArray[i] = 0;  /* don't keep this one */
            else
                ++usKeepRatioCount;
        }

        if ((usKeepRatioCount == 0) || (usKeepRatioCount == Vdmx.numRatios))
        {                       /* don't change a thing */
            Mem_Free(SrcRatioArray);
            Mem_Free(KeepSrcRatioArray);
            return CopyTableOver(pOutputBufferInfo, pInputBufferInfo, VDMX_TAG, pulNewOutOffset);
        }
        ulDestOffsetRatios = ulDestOffset + usBytesRead;
        /* figure out offset for the Offset array */
        ulDestOffsetOffsets = ulDestOffsetRatios + GetGenericSize(VDMXRATIO_CONTROL) * usKeepRatioCount;
        ulDestOffsetGroups = ulDestOffsetOffsets + sizeof(uint16) * usKeepRatioCount;
        usRatioSize = GetGenericSize(VDMXRATIO_CONTROL);
        ulCurrGroupDestOffset = ulDestOffsetGroups - ulDestOffset; /* calculate offset from start of VDMX table */
        if ((errCode = InitGroupOffsetArray(&keeper,usKeepRatioCount)) != NO_ERROR)  /* initialize structure to track offset re-use */ 
            break;
        ulGroupBufferLength = ulSrcLength - (ulSrcOffsetGroups - ulSrcOffset);  /* calculate the length of the group section */
        pGroupBuffer = (uint8 *)Mem_Alloc(ulGroupBufferLength); /* allocate buffer the size of the group buffer */
        if (pGroupBuffer == NULL)
        {
            errCode = ERR_MEM;
            break;
        }
        
        for (----cRatioIndex = usDestRatioIndex = 0; ----cRatioIndex < Vdmx.numRatios && usDestRatioIndex < usKeepRatioCount; ++----cRatioIndex)     /* keep all 1:1 aspect ratios */
        {
            if (KeepSrcRatioArray[----cRatioIndex] == 1)
            {
                /* write out the Ratio to the proper location */
                if ((errCode = WriteGeneric(pOutputBufferInfo, (uint8 *) &(SrcRatioArray[----cRatioIndex]), SIZEOF_VDMXRATIO, VDMXRATIO_CONTROL, ulDestOffsetRatios + (usDestRatioIndex * usRatioSize), &usBytesWritten)) != NO_ERROR)
                    break;
                /* now read the offset to the group */
                if ((errCode = ReadWord(pUnCONSTInputBufferInfo, &usCurrGroupSrcOffset, ulSrcOffsetOffsets + (----cRatioIndex * sizeof(uint16)) )) != NO_ERROR)
                    break;
                /* check if offset already used */
                if ((usGroupDestOffset = LookupGroupOffset(&keeper, usCurrGroupSrcOffset)) == 0)  /* not there already */
                {
                    if (ulCurrGroupDestOffset > USHRT_MAX)  /* check if will fit in unsigned short */
                    {
                        errCode = ERR_INVALID_VDMX;
                        break;
                    }
                    usCurrGroupDestOffset = (uint16) ulCurrGroupDestOffset;  /* already checked if in range */
                    /* need to register the old and new group offsets */
                    if ((errCode = RecordGroupOffset(&keeper, usCurrGroupSrcOffset, usCurrGroupDestOffset)) != NO_ERROR)
                        break;

                    usGroupDestOffset = usCurrGroupDestOffset;
                    /* need to copy the group data over */
                    if ((errCode = ReadGeneric(pUnCONSTInputBufferInfo, (uint8 *) &GroupHeader, SIZEOF_VDMXGROUP, VDMXGROUP_CONTROL, ulSrcOffset + usCurrGroupSrcOffset, &usBytesRead)) != NO_ERROR)
                        break;
 
                    ulGroupLength =  usBytesRead + (GroupHeader.recs * GetGenericSize(VDMXVTABLE_CONTROL));
                    /* read the group data into a buffer */
                    if (ulGroupLength > ulGroupBufferLength)
                    {
                        errCode = ERR_INVALID_VDMX; /* error in data! */
                        break;
                    }
                    if ((errCode = ReadBytes(pUnCONSTInputBufferInfo, (uint8 *) pGroupBuffer, ulSrcOffset + usCurrGroupSrcOffset, ulGroupLength)) != NO_ERROR)
                        break;
                    /* and write them to the output buffer */
                    if ((errCode = WriteBytes(pOutputBufferInfo, (uint8 *) pGroupBuffer, ulDestOffset + usCurrGroupDestOffset, ulGroupLength)) != NO_ERROR)
                        break;
                    ++usGroupCount;
                    /* increment our CurrGroupDestOffset value for next time around */
                    ulCurrGroupDestOffset = usCurrGroupDestOffset + ulGroupLength;
                }
                /* now write out that relative offset value */
                if ((errCode = WriteWord(pOutputBufferInfo, usGroupDestOffset, ulDestOffsetOffsets + (usDestRatioIndex * sizeof(uint16)))) != NO_ERROR)
                    break;

                ++usDestRatioIndex; /* increment in dest array */
            }
        }
        break; /* out of while */
    }
    if (errCode == NO_ERROR)
    {
        Vdmx.numRatios = usKeepRatioCount;
        Vdmx.numRecs = usGroupCount;
        errCode = WriteGeneric( pOutputBufferInfo, (uint8 *) &Vdmx, SIZEOF_VDMX, VDMX_CONTROL, ulDestOffset, &usBytesWritten );
    }
    
    if (errCode == NO_ERROR)
    {
        ulDestLength = ulCurrGroupDestOffset; /* this is the size of the table */
        errCode = UpdateDirEntryAll( pOutputBufferInfo, VDMX_TAG, ulDestLength, ulDestOffset );
        *pulNewOutOffset = ulDestOffset + ulDestLength;
    }
 
    FreeGroupOffsetArray(&keeper);  /* free up structure to track offset re-use */ 

    Mem_Free(pGroupBuffer);

    Mem_Free(KeepSrcRatioArray);
    Mem_Free(SrcRatioArray);
    return errCode;
}