Ejemplo n.º 1
0
int16 ModOS2( CONST_TTFACC_FILEBUFFERINFO * pInputBufferInfo, TTFACC_FILEBUFFERINFO * pOutputBufferInfo, 
             uint16 usMinChr, 
             uint16 usMaxChr,
              CONST uint16 usFormat,
              uint32 *pulNewOutOffset)
{
/* read OS2 table, modify the max,min char field, and write out the
new table */

NEWOS2  Os2;
uint32   ulOffset;
BOOL bNewOS2 = FALSE;
uint16 usBytesWritten;
int16 errCode = NO_ERROR;

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

    if ((ulOffset = GetSmartOS2(pOutputBufferInfo,&Os2,&bNewOS2)) == 0L)
    {
        if ((errCode = CopyTableOver(pOutputBufferInfo, pInputBufferInfo, OS2_TAG, pulNewOutOffset)) != NO_ERROR)
        {
            if (errCode == ERR_FORMAT)
                return NO_ERROR;    /* not required */
            return errCode;
        }
        if ((ulOffset = GetSmartOS2(pOutputBufferInfo,&Os2,&bNewOS2)) == 0L)
            return ERR_GENERIC;
    }

    if (usMinChr != 0 || usMaxChr != 0) /* couldn't set in modcmap because of growth */
    {
        if (Os2.usFirstCharIndex < 0xF000)   /* lcp 5/26/97 don't want to change this if it is a Symbol font */
            Os2.usFirstCharIndex = usMinChr;
        Os2.usLastCharIndex  = usMaxChr;
        
        if( bNewOS2 )  /* write out the new one */
        {
            if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *) &Os2, SIZEOF_NEWOS2, NEWOS2_CONTROL, ulOffset, &usBytesWritten)) != NO_ERROR)
                return errCode;
        }
        else     /* write out the old one */
        {
            if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *) &Os2, SIZEOF_OS2, OS2_CONTROL, ulOffset, &usBytesWritten )) != NO_ERROR)
                return errCode;
        }
    }
    return errCode;
}
Ejemplo n.º 2
0
int16 ModPost( CONST_TTFACC_FILEBUFFERINFO * pInputBufferInfo, 
              TTFACC_FILEBUFFERINFO * pOutputBufferInfo,
              CONST uint16 usFormat,
              uint32 *pulNewOutOffset)
{
POST    Post;
int16 errCode = NO_ERROR;
uint16 usBytesWritten;
uint32 ulOffset;

    /* verify table needs to be modified */

    if (usFormat == TTFDELTA_DELTA) /* only formats for which this is not valid */
    {
        MarkTableForDeletion(pOutputBufferInfo, POST_TAG);
        return errCode;
    }
    if ((errCode = CopyTableOver(pOutputBufferInfo, pInputBufferInfo, POST_TAG, pulNewOutOffset)) != NO_ERROR)
    {
        if (errCode == ERR_FORMAT)
            return NO_ERROR;    /* not required */
        return errCode;
    }

    if ((ulOffset = GetPost( pOutputBufferInfo, &Post )) == 0L)
        return ERR_GENERIC;

    if ( Post.formatType != POST_FORMAT_3 )
    {
        /* Not POST format 3.0, so change it to 3.0 */
        Post.formatType = POST_FORMAT_3;
        if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *) &Post,SIZEOF_POST, POST_CONTROL, ulOffset, &usBytesWritten )) != NO_ERROR)
            return errCode;
        /* update the directory entry with new length */

        errCode = UpdateDirEntry( pOutputBufferInfo, POST_TAG, (uint32) usBytesWritten );
        *pulNewOutOffset = ulOffset + usBytesWritten;
    }
    return errCode;
}
Ejemplo n.º 3
0
int16 ModMaxP( CONST_TTFACC_FILEBUFFERINFO * pInputBufferInfo, 
              TTFACC_FILEBUFFERINFO * pOutputBufferInfo,
              uint32 *pulNewOutOffset)
{
MAXP MaxP;
uint32 ulOffset;
uint16 usnMaxComponents;
uint16 *pausComponents; 
int16 errCode;
uint16 usBytesWritten;

   /* get old maxp record */
    if ((ulOffset = GetMaxp( pOutputBufferInfo, &MaxP)) == 0L)
    { /* not copied over yet */
        if ((errCode = CopyTableOver(pOutputBufferInfo, pInputBufferInfo, MAXP_TAG, pulNewOutOffset)) != NO_ERROR)
            return ERR_MISSING_MAXP; /* required */

        if ((ulOffset = GetMaxp( pOutputBufferInfo, &MaxP)) == 0L)
            return ERR_GENERIC;
    }

   /* recompute maxp info */
    /* figure a conservative maximum total possible. 3x3 at minimum */
    usnMaxComponents = max(3,MaxP.maxComponentElements) * max(3,MaxP.maxComponentDepth);
    pausComponents = (uint16 *) Mem_Alloc(usnMaxComponents * sizeof(uint16));
    if (pausComponents == NULL)
        return ERR_MEM;

    errCode = ComputeMaxPStats( pOutputBufferInfo, &(MaxP.maxContours), &(MaxP.maxPoints), &(MaxP.maxCompositeContours),
                     &(MaxP.maxCompositePoints), &(MaxP.maxSizeOfInstructions),
                     &(MaxP.maxComponentElements), &(MaxP.maxComponentDepth), pausComponents, usnMaxComponents  );
   /* write out new maxp record with new maxp info */
    Mem_Free(pausComponents);

    if (errCode == NO_ERROR)
        errCode = WriteGeneric( pOutputBufferInfo, (uint8 *) &MaxP, SIZEOF_MAXP, MAXP_CONTROL, ulOffset, &usBytesWritten );

    return errCode;
}
Ejemplo n.º 4
0
 bool Write(TOffset Position, u64 const& rData)
 { return WriteGeneric(Position, rData); }
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
int16 ModLTSH(  CONST_TTFACC_FILEBUFFERINFO * pInputBufferInfo, TTFACC_FILEBUFFERINFO * pOutputBufferInfo, 
              CONST uint8 *puchKeepGlyphList, 
              CONST uint16 usGlyphListCount,
              CONST uint16 usDttfGlyphIndexCount,
              uint32 *pulNewOutOffset)
{
LTSH  Ltsh;
uint32 ulLtshOffset;
uint32 ulInOffset;
uint32 ulOutOffset;
uint16 i,j;
int16 errCode;
uint16 GlyphCount;
uint8 uchValue;
uint16 usBytesWritten;

   /* read ltsh table header */

  if ((errCode = CopyTableOver(pOutputBufferInfo, pInputBufferInfo, LTSH_TAG, pulNewOutOffset)) != NO_ERROR)
  {
    if (errCode == ERR_FORMAT)
        return NO_ERROR;    /* not required */
    return errCode;
  }
  ulLtshOffset = GetLTSH( pOutputBufferInfo, &Ltsh );
   if ( ulLtshOffset == 0 )
      return ERR_GENERIC;

   if (usDttfGlyphIndexCount)
   {
       ulOutOffset = ulLtshOffset + GetGenericSize( LTSH_CONTROL );
       ulInOffset = ulLtshOffset + GetGenericSize( LTSH_CONTROL );
       GlyphCount = min(Ltsh.numGlyphs, usGlyphListCount); /* don't want to process too many if file is buggy */

        for( i=0, j= 0; i < GlyphCount && j < usDttfGlyphIndexCount; i++)
        {
            if (puchKeepGlyphList[ i ]) /* need keep this one out */
            {
                if ((errCode = ReadByte( pOutputBufferInfo, (uint8 *) &uchValue, ulInOffset)) != NO_ERROR)
                    return errCode;

                if ((errCode = WriteByte( pOutputBufferInfo, (uint8) uchValue, ulOutOffset)) != NO_ERROR)
                    return errCode;
                ulOutOffset += sizeof(uint8);
                ++j;
            }
            ulInOffset += sizeof(uint8);
        }
        /* now we need to update the count for the LTSH table */
        Ltsh.numGlyphs = usDttfGlyphIndexCount;
        if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *)&Ltsh, SIZEOF_LTSH, LTSH_CONTROL, ulLtshOffset, &usBytesWritten )) != NO_ERROR)
            return errCode;
        if ((errCode = UpdateDirEntry( pOutputBufferInfo, LTSH_TAG, ulOutOffset - ulLtshOffset )) != NO_ERROR)
            return errCode;
   }
   else
   {

       ulOutOffset = ulLtshOffset + GetGenericSize( LTSH_CONTROL );
       GlyphCount = min(Ltsh.numGlyphs, usGlyphListCount); /* don't want to process too many if file is buggy */

        for( i=0; i < GlyphCount; i++)
        {
            if (!puchKeepGlyphList[ i ])    /* need to zero out */
            {
                if ((errCode = WriteByte( pOutputBufferInfo, (uint8) 0, ulOutOffset)) != NO_ERROR)
                    return errCode;
            }
            ulOutOffset += sizeof(uint8);
        }
   }
   *pulNewOutOffset = ulOutOffset;
    return NO_ERROR;
}
Ejemplo n.º 7
0
int16 ModHdmx( CONST_TTFACC_FILEBUFFERINFO * pInputBufferInfo, TTFACC_FILEBUFFERINFO * pOutputBufferInfo, 
              CONST uint8 *puchKeepGlyphList, 
              CONST uint16 usGlyphListCount,
              CONST uint16 usDttfGlyphIndexCount,
              uint32 *pulNewOutOffset)
{
HDMX Hdmx;
HDMX_DEVICE_REC DevRecord;
uint8 Width;
uint8 maxWidth;
uint16 i;
uint16 j,k;
uint32 ulHdmxOffset;
uint32 ulOffset;
uint32 ulDevOffset;
uint32 ulInOffset;
uint32 ulOutOffset;
uint32 ulInDevOffset;
uint32 ulOutDevOffset;
int16 errCode;
uint16 usBytesRead;
uint16 usBytesWritten;
uint32 ulOutSizeDeviceRecord;

    if ((errCode = CopyTableOver(pOutputBufferInfo, pInputBufferInfo, HDMX_TAG, pulNewOutOffset)) != NO_ERROR)
    {
        if (errCode == ERR_FORMAT)
            return NO_ERROR;    /* not required */
        return errCode;
    }

    ulHdmxOffset = GetHdmx(pOutputBufferInfo, &Hdmx);
    if ( !ulHdmxOffset )
        return ERR_GENERIC;

    ulOffset = ulHdmxOffset + GetGenericSize( HDMX_CONTROL );

    if (usDttfGlyphIndexCount) /* we want compact form */
    {
        ulInOffset = ulOutOffset = ulOffset;
        ulOutSizeDeviceRecord = RoundToLongWord(GetGenericSize(HDMX_DEVICE_REC_CONTROL) + (sizeof(uint8) * usDttfGlyphIndexCount));
        for( j = 0; j < Hdmx.numDeviceRecords; j++)
        {
            ulInDevOffset = ulInOffset;
            ulOutDevOffset = ulOutOffset;
            if ((errCode = ReadGeneric( pOutputBufferInfo, (uint8 *)&DevRecord, SIZEOF_HDMX_DEVICE_REC, HDMX_DEVICE_REC_CONTROL, ulInDevOffset, &usBytesRead )) != NO_ERROR)
                return errCode;
            ulInOffset += usBytesRead;
            ulOutOffset += usBytesRead;
            maxWidth = 0;

            for(i = 0, k= 0; i < usGlyphListCount && k < usDttfGlyphIndexCount; i++) /* process each glyph entry */
            {
                if (puchKeepGlyphList[ i ])
                {
                    if ((errCode = ReadByte( pOutputBufferInfo, &Width, ulInOffset)) != NO_ERROR)
                        return errCode;
                    maxWidth = max( maxWidth, Width );
                    if ((errCode = WriteByte( pOutputBufferInfo, Width, ulOutOffset)) != NO_ERROR)
                        return errCode;
                    ulOutOffset += sizeof(uint8);
                    ++k;
                }
                ulInOffset += sizeof(uint8);
            }
            if ((errCode = ZeroLongWordAlign(pOutputBufferInfo, ulOutOffset, &ulOutOffset)) != NO_ERROR)
                return errCode;
            DevRecord.maxWidth = maxWidth;
            if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *)&DevRecord, SIZEOF_HDMX_DEVICE_REC, HDMX_DEVICE_REC_CONTROL, ulOutDevOffset, &usBytesWritten )) != NO_ERROR)
                return errCode;
            ulInOffset = ulInDevOffset + Hdmx.sizeDeviceRecord;
            ulOutOffset = ulOutDevOffset + ulOutSizeDeviceRecord;
        }
        /* now need to update hdmx record */
        Hdmx.sizeDeviceRecord = ulOutSizeDeviceRecord;
        if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *)&Hdmx, SIZEOF_HDMX, HDMX_CONTROL, ulHdmxOffset, &usBytesWritten )) != NO_ERROR)
            return errCode;
        if ((errCode = UpdateDirEntry( pOutputBufferInfo, HDMX_TAG, ulOutOffset - ulHdmxOffset )) != NO_ERROR)
            return errCode;
        *pulNewOutOffset = ulOutOffset;
    }
    else
    {

    /*      if (GetHHea(pOutputBufferInfo, &Hhea) == 0L)
           return ERR_FORMAT;  */

        for( j = 0; j < Hdmx.numDeviceRecords; j++)
        {
            ulDevOffset = ulOffset;
            if ((errCode = ReadGeneric( pOutputBufferInfo, (uint8 *)&DevRecord, SIZEOF_HDMX_DEVICE_REC, HDMX_DEVICE_REC_CONTROL, ulDevOffset, &usBytesRead )) != NO_ERROR)
                return errCode;
            ulOffset += usBytesRead;
            maxWidth = 0;

            for(i = 0; i < usGlyphListCount; i++) /* process each glyph entry */
            {
                if (puchKeepGlyphList[ i ])
                {
                    if ((errCode = ReadByte( pOutputBufferInfo, &Width, ulOffset)) != NO_ERROR)
                        return errCode;
                    maxWidth = max( maxWidth, Width );
                }
                else /* if (i != Hhea.numLongMetrics-1) clear the value in the file, so the compressor can do its work, except for any dummy entries in the hmtx table */
                {
                    if ((errCode = WriteByte( pOutputBufferInfo, (uint8) 0, ulOffset)) != NO_ERROR)
                        return errCode;
                }
                ulOffset += sizeof(uint8);
            }
            if (DevRecord.maxWidth != maxWidth) /* it's changed, we need to write it out again */
            {
                DevRecord.maxWidth = maxWidth;
                if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *)&DevRecord, SIZEOF_HDMX_DEVICE_REC, HDMX_DEVICE_REC_CONTROL, ulDevOffset, &usBytesWritten )) != NO_ERROR)
                    return errCode;
            }
            ulOffset = ulDevOffset + Hdmx.sizeDeviceRecord;
        }
        *pulNewOutOffset = ulOffset;
    }

    return NO_ERROR;
}
Ejemplo n.º 8
0
int16 ModXmtxXhea( CONST_TTFACC_FILEBUFFERINFO * pInputBufferInfo,
                  TTFACC_FILEBUFFERINFO * pOutputBufferInfo, 
                  CONST uint8 *puchKeepGlyphList, 
                  CONST uint16 usGlyphListCount,
                  CONST uint16 usDttfGlyphIndexCount,
                  CONST uint16 usMaxGlyphIndexUsed,
                  BOOL isHmtx,
                  uint32 *pulNewOutOffset)
{                         

XHEA XHea;
uint16 i,j;
uint32 ulXmtxOffset;
uint32 ulXheaOffset;
uint32 ulCrntOffset;
LONGXMETRIC ZeroLongMetric;
LONGXMETRIC CurrLongMetric;
LONGXMETRIC *LongMetricsArray;
uint16 LongMetricSize;
int16 errCode;
uint16 usBytesRead;
uint16 usBytesWritten;
uint16 nNewLongMetrics;
uint32 ulBytesWritten;
const char * xmtx_tag;
const char * xhea_tag;

   /* determine number of long metrics in hmtx table */

    if (isHmtx)
    {
        xmtx_tag = HMTX_TAG;
        xhea_tag = HHEA_TAG;
        if ((ulXheaOffset = GetHHea( pOutputBufferInfo, (HHEA *) &XHea )) == 0L)
        { /* hasn't been copied yet */
            if ((errCode = CopyTableOver(pOutputBufferInfo, pInputBufferInfo, xhea_tag, pulNewOutOffset)) != NO_ERROR)
                return ERR_INVALID_HHEA;
            if ((ulXheaOffset = GetHHea( pOutputBufferInfo, (HHEA *) &XHea )) == 0L)
                return ERR_MISSING_HHEA;    /* required table */
        }
    }
    else
    {
        xmtx_tag = VMTX_TAG;
        xhea_tag = VHEA_TAG;
        ulXheaOffset = TTTableOffset( (TTFACC_FILEBUFFERINFO *)pInputBufferInfo, xhea_tag);
        ulXmtxOffset = TTTableOffset( (TTFACC_FILEBUFFERINFO *)pInputBufferInfo, xmtx_tag);
        if (ulXheaOffset != DIRECTORY_ERROR && ulXmtxOffset == DIRECTORY_ERROR)   /* this is bogus, get rid of the vhea table */
        {
            MarkTableForDeletion(pOutputBufferInfo, xhea_tag);  /* there is an entry in the output directory */
            return (NO_ERROR);
        } 

        if ((ulXheaOffset = GetVHea( pOutputBufferInfo, (VHEA *) &XHea )) == 0L)
        {
            if ((errCode = CopyTableOver(pOutputBufferInfo, pInputBufferInfo, xhea_tag, pulNewOutOffset)) != NO_ERROR)
            {
                if (errCode == ERR_FORMAT)
                    return NO_ERROR;    /* not required */
                else
                    return errCode;
            }
            if ((ulXheaOffset = GetVHea( pOutputBufferInfo, (VHEA *) &XHea )) == 0L)
                return ERR_MISSING_VHEA;    /* */
        }
    }


    if ((errCode = CopyTableOver(pOutputBufferInfo, pInputBufferInfo, xmtx_tag, pulNewOutOffset)) != NO_ERROR)
        return errCode;
    ulXmtxOffset = TTTableOffset( pOutputBufferInfo, xmtx_tag);

    if ((XHea.numLongMetrics == 0) || (XHea.numLongMetrics > usGlyphListCount))
        return ERR_INVALID_HHEA_OR_VHEA;        /* invalid values */
    
    if (ulXmtxOffset == DIRECTORY_ERROR )
        return ERR_MISSING_HMTX_OR_VMTX;        /* required table */
                                        
    ulCrntOffset = ulXmtxOffset;
    ZeroLongMetric.xsb = 0;
    ZeroLongMetric.advanceX = 0;
    LongMetricSize = GetGenericSize(LONGXMETRIC_CONTROL);

    if (usDttfGlyphIndexCount == 0)    /* not trying to make a compact table, just subsetting */
    {
    /* check to see if we will grow. We will grow with subsetting if our last good glyph index is beyond the current numLongMetrics */

        if ((XHea.numLongMetrics != usGlyphListCount) && /* if longmetrics is the same as number of glyphs, table won't be growing  */ 
            /* need for zero based to 1 base + 1 for the dummy 0 entry */
            (usMaxGlyphIndexUsed + 1 + 1 > XHea.numLongMetrics)) /* check if we may make the table grow */
            return (ERR_WOULD_GROW);
        nNewLongMetrics = min(usGlyphListCount, usMaxGlyphIndexUsed + 1 + 1);   /* + 1 again for dummy */
        /* process all the Long metrics (and perhaps some short when we won't be modifying the table */
        for (i = 0; i < nNewLongMetrics; ++i)
        {
            if (puchKeepGlyphList[i] == FALSE)/* else we don't want to keep this one, 0 metrics to write */
            {
                if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *)&ZeroLongMetric, SIZEOF_LONGXMETRIC, LONGXMETRIC_CONTROL, ulCrntOffset, &usBytesWritten)) != NO_ERROR)
                    return (errCode);
            }
            ulCrntOffset += LongMetricSize;
        }
        /* write out short metrics of 0 for the rest of them*/
        for (i = nNewLongMetrics; i < usGlyphListCount; ++i)
        {
            if ((errCode = WriteWord(pOutputBufferInfo, 0, ulCrntOffset)) != NO_ERROR)
                return errCode;
            ulCrntOffset += sizeof (uint16);
        }
        ulBytesWritten = ulCrntOffset - ulXmtxOffset;
    }
    else  /* we want to make a compact table */
    {
    /* now collapse the table if we are in Compact form for Subsetting and Delta fonts */
    /* we will use an interrum table for simplification */
        ulCrntOffset = ulXmtxOffset;
        LongMetricsArray = (LONGXMETRIC *)Mem_Alloc(sizeof(LONGXMETRIC) * usDttfGlyphIndexCount);
        if (LongMetricsArray == NULL)
            return ERR_MEM;
        nNewLongMetrics = 0;
        for (i = 0, j= 0; i < XHea.numLongMetrics && j < usDttfGlyphIndexCount && errCode == NO_ERROR; ++i)  /* need to read and copy up the values */
        {
            if (puchKeepGlyphList[i]) /* if we want to keep the glyph, or its the last special one */
            {
                if ((errCode = ReadGeneric( pOutputBufferInfo, (uint8 *)&CurrLongMetric, SIZEOF_LONGXMETRIC, LONGXMETRIC_CONTROL, ulCrntOffset, &usBytesRead)) != NO_ERROR)
                    break;
                LongMetricsArray[j] = CurrLongMetric;
                ++j;
                ++nNewLongMetrics;
            }
            else if (i == XHea.numLongMetrics-1) /* its that special dummy "last" one, need AW value */
            {
                if ((errCode = ReadGeneric( pOutputBufferInfo, (uint8 *)&CurrLongMetric, SIZEOF_LONGXMETRIC, LONGXMETRIC_CONTROL, ulCrntOffset, &usBytesRead)) != NO_ERROR)
                    break;
                ++nNewLongMetrics; /* we will need an extra one, but guarenteed to be <= XHea.numLongMetrics */
            }
            ulCrntOffset += LongMetricSize;
        }
        if (errCode != NO_ERROR)
        {
            Mem_Free(LongMetricsArray);
            return errCode;
        }
        for (; i < usGlyphListCount && j < usDttfGlyphIndexCount; ++i) /* copy the xsb from the long metrics */
        {
            if (puchKeepGlyphList[i])
            {
                if ((errCode = ReadWord( pOutputBufferInfo, (uint16 *)&(CurrLongMetric.xsb), ulCrntOffset)) != NO_ERROR)
                    break;
                LongMetricsArray[j] = CurrLongMetric;
                ++j;
            }
            ulCrntOffset += sizeof(uint16);
        }
        if (errCode != NO_ERROR)
        {
            Mem_Free(LongMetricsArray);
            return errCode;
        }

        if (j != usDttfGlyphIndexCount)
        {
            Mem_Free(LongMetricsArray);
            return ERR_GENERIC;
        }
        /* first write out the long metrics */
        errCode = WriteGenericRepeat(pOutputBufferInfo,(uint8 *)LongMetricsArray, LONGXMETRIC_CONTROL,
                ulXmtxOffset,&ulBytesWritten, nNewLongMetrics, SIZEOF_LONGXMETRIC);
        /* then write out the short metrics */
        if (errCode == NO_ERROR)
        {
            ulCrntOffset = ulXmtxOffset + ulBytesWritten;
            for (i = nNewLongMetrics; i < usDttfGlyphIndexCount; ++i)
            {
                if ((errCode = WriteWord( pOutputBufferInfo, LongMetricsArray[i].xsb, ulCrntOffset)) != NO_ERROR)
                    break;
                ulCrntOffset += sizeof(uint16);
            }
        }
    
        Mem_Free(LongMetricsArray);
        if (errCode != NO_ERROR)
            return errCode;
        ulBytesWritten = ulCrntOffset - ulXmtxOffset;
    }
  
        /* write out our new, shorter length... cleanup comes later */
    errCode = UpdateDirEntry( pOutputBufferInfo, xmtx_tag, ulBytesWritten );

    if (errCode == NO_ERROR && nNewLongMetrics != XHea.numLongMetrics) 
    {
        XHea.numLongMetrics = nNewLongMetrics;      /* leave these alone if the hmtx table will remain the same */
        if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *) &XHea, SIZEOF_XHEA, XHEA_CONTROL, ulXheaOffset, &usBytesWritten )) != NO_ERROR)
            return (errCode);
    }
    *pulNewOutOffset = ulCrntOffset;

    return errCode;
}
Ejemplo n.º 9
0
PRIVATE int16 AdjustKernFormat0(TTFACC_FILEBUFFERINFO * pOutputBufferInfo, 
                        CONST uint8 *puchKeepGlyphList, 
                        CONST uint16 usGlyphListCount, 
                        KERN_SUB_HEADER   KernSubHeader,
                        uint32 ulOffset,
                        uint16 usSubHeaderSize, /* size in file of usSubHeader */
                        uint16 * pusNewLength)
{
uint32 ulSourceOffset;
uint32 ulTargetOffset;
KERN_FORMAT_0 KernFormat0;
KERN_PAIR KernPair;
uint16 usKernFormat0Size;
uint16 i;
uint16 usUsedPairs;
uint16 usSearchRange;
uint16 usRangeShift;
uint16 usBytesRead;
uint16 usBytesWritten;
int16 errCode;
                         
    /* determine number of kern pairs */
    ulSourceOffset = ulOffset + usSubHeaderSize;
    if ((errCode = ReadGeneric( pOutputBufferInfo, (uint8 *)&KernFormat0, SIZEOF_KERN_FORMAT_0, KERN_FORMAT_0_CONTROL, ulSourceOffset, &usBytesRead )) != NO_ERROR)
        return errCode;
    usKernFormat0Size = usBytesRead;
    ulSourceOffset += usKernFormat0Size;
    ulTargetOffset = ulSourceOffset;

    /* wade through list of pairs, copying those that do not include a
    deleted glyph and ignoring those that do */

    usUsedPairs = 0;
    for ( i = 0; i < KernFormat0.nPairs; i++ )
    {
        if ((errCode = ReadGeneric( pOutputBufferInfo, (uint8 *) &KernPair, SIZEOF_KERN_PAIR, KERN_PAIR_CONTROL, ulSourceOffset, &usBytesRead )) != NO_ERROR)
        return errCode;

        if (( KernPair.left < usGlyphListCount && puchKeepGlyphList[KernPair.left] ) &&
            ( KernPair.right < usGlyphListCount && puchKeepGlyphList[KernPair.right] ))
        {
            if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *) &KernPair, SIZEOF_KERN_PAIR, KERN_PAIR_CONTROL, ulTargetOffset, &usBytesWritten)) != NO_ERROR)
                return errCode;
            ulTargetOffset += usBytesWritten;
            usUsedPairs++;
        }
        ulSourceOffset += usBytesRead;
    }

    /* calc and write out revised subtable header */
    if (usUsedPairs > 0)
    {
        *pusNewLength = (uint16) (ulTargetOffset - ulOffset);
        KernSubHeader.length = *pusNewLength ;
        if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *) &KernSubHeader, SIZEOF_KERN_SUB_HEADER, KERN_SUB_HEADER_CONTROL, ulOffset, &usBytesWritten )) != NO_ERROR)
            return errCode;

        /* calc and write out revised format 0 header */

        usSearchRange = (0x0001 << log2( usUsedPairs )) * GetGenericSize( KERN_PAIR_CONTROL );
        usRangeShift  = (usUsedPairs * GetGenericSize( KERN_PAIR_CONTROL )) - usSearchRange;
        KernFormat0.nPairs      = usUsedPairs;
        KernFormat0.searchRange =  usSearchRange;
        KernFormat0.entrySelector = log2( usUsedPairs );
        KernFormat0.rangeShift    = usRangeShift;
        if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *) &KernFormat0, SIZEOF_KERN_FORMAT_0, KERN_FORMAT_0_CONTROL, ulOffset + usBytesWritten, &usBytesWritten )) != NO_ERROR)
            return errCode;
    }
    else
        *pusNewLength = 0;
    return NO_ERROR;
}
Ejemplo n.º 10
0
void MD32spr::Write()
{
  size_t i = 0;
  csString vfspath;
  char* fileName = 0;
  char* mdlName = 0;

  if (outZipName)
  {
    if (outZipName.Length() > 0)
    {
      csArchive* zipFile = new csArchive (outZipName.GetData());

      if(!zipFile)
      {
        ReportError("Error creating output zip file.\n");
        return;
      }

      delete zipFile;
      fileName = new char[outZipName.Length() + 1];
      basename(outZipName.GetData(), fileName);
      vfspath.Format ("/tmp/%s_out/", fileName);

      if (!out->Mount(vfspath, outZipName.GetData()))
      {
        ReportError("Error mounting output zip file.\n");
        return;
      }
    }
  }

  if (!player && !weaponDir)
  {
    if (generic.GetSize ())
    {
      for (i = 0; i < generic.GetSize (); i++)
      {
        md3Model *mdl = generic.Get(i);
        mdlName = new char[strlen(mdl->GetFileName()) + 1];
        basename(mdl->GetFileName(), mdlName);
        csRef<iDocumentSystem> xml(csPtr <iDocumentSystem>
          (new csTinyDocumentSystem()));
        csRef <iDocument> doc = xml->CreateDocument();
        csRef <iDocumentNode> root = doc->CreateRoot();
        csRef <iDocumentNode> parent =
          root->CreateNodeBefore(CS_NODE_ELEMENT, 0);
        parent->SetValue("library");
	
        WriteGeneric(mdl, parent);
        csString outFile(vfspath);
        outFile += mdlName;
        doc->Write(out, outFile.GetData());
      }
    }
  }

  if (player) 
  {
    if (headModel) 
    {
      char *headName = new char[strlen(headModel->GetFileName()) + 1];
      csString tagFileName;
      basename(headModel->GetFileName(), headName);
      tagFileName.Format ("%s%s.tag", vfspath.GetData(), headName);
      WriteXMLTags(headModel, tagFileName);
      csRef < iDocumentSystem > xml(csPtr < iDocumentSystem >
				    (new csTinyDocumentSystem()));
      csRef < iDocument > doc = xml->CreateDocument();
      csRef < iDocumentNode > root = doc->CreateRoot();
      csRef < iDocumentNode > parent =
	root->CreateNodeBefore(CS_NODE_ELEMENT, 0);
      parent->SetValue("library");
      WriteGeneric(headModel, parent);
      csString outFile(vfspath);
      outFile += headName;
      doc->Write(out, outFile.GetData());
    }
    if (upperModel) {
      char *upperName = new char[strlen(headModel->GetFileName()) + 1];
      csString tagFileName;
      basename(upperModel->GetFileName(), upperName);
      tagFileName.Format ("%s%s.tag", vfspath.GetData(), upperName);
      WriteXMLTags(upperModel, tagFileName);
      csRef < iDocumentSystem > xml(csPtr < iDocumentSystem >
				    (new csTinyDocumentSystem()));
      csRef < iDocument > doc = xml->CreateDocument();
      csRef < iDocumentNode > root = doc->CreateRoot();
      csRef < iDocumentNode > parent =
	root->CreateNodeBefore(CS_NODE_ELEMENT, 0);
      parent->SetValue("library");

      WriteGeneric(upperModel, parent);
      csString outFile(vfspath);
      outFile += upperName;
      doc->Write(out, outFile.GetData());
    }
    if (lowerModel) {
      char *lowerName = new char[strlen(headModel->GetFileName()) + 1];
      csString tagFileName;
      basename(lowerModel->GetFileName(), lowerName);
      tagFileName.Format ("%s%s.tag", vfspath.GetData(), lowerName);
      WriteXMLTags(lowerModel, tagFileName);
      csRef < iDocumentSystem > xml(csPtr < iDocumentSystem >
				    (new csTinyDocumentSystem()));
      csRef < iDocument > doc = xml->CreateDocument();
      csRef < iDocumentNode > root = doc->CreateRoot();
      csRef < iDocumentNode > parent =
	root->CreateNodeBefore(CS_NODE_ELEMENT, 0);
      parent->SetValue("library");

      WriteGeneric(lowerModel, parent);
      csString outFile(vfspath);
      outFile += lowerName;
      doc->Write(out, outFile.GetData());
    }
    if (weaponDir)
    {
      for (i = 0; i < generic.GetSize (); i++)
      {
	md3Model *mdl = generic.Get(i);
	csRef < iDocumentSystem > xml(csPtr < iDocumentSystem >
				      (new csTinyDocumentSystem()));
	csRef < iDocument > doc = xml->CreateDocument();
	csRef < iDocumentNode > root = doc->CreateRoot();
	csRef < iDocumentNode > parent =
	  root->CreateNodeBefore(CS_NODE_ELEMENT, 0);
	parent->SetValue("library");

	WriteGeneric(mdl, parent);
	char *fileName = new char[mdl->fileName.Length() + 1];
	csString tagFileName;
	basename(mdl->fileName.GetData(), fileName);


	csString outFile(vfspath);
	outFile += weaponDir;
	outFile += "/";
	outFile += fileName;
	doc->Write(out, outFile.GetData());
	tagFileName.Format ("%s%s/%s.tag", vfspath.GetData(), weaponDir.GetData(), fileName);
	WriteXMLTags(mdl, tagFileName);
      }
    }
  }
  WriteTextures(mountPath.GetData(),vfspath);
  if(weaponDir) {
    csString weaponInPath(mountPath.GetData());
    csString weaponOutPath(vfspath);
    weaponInPath += weaponDir;
    weaponInPath += "/";
    weaponOutPath += weaponDir;
    weaponOutPath += "/";
    WriteTextures(weaponInPath.GetData(), weaponOutPath.GetData());
  }
}
Ejemplo n.º 11
0
PRIVATE int16 CopyOffsetDirectoryTables(CONST_TTFACC_FILEBUFFERINFO * pInputBufferInfo, 
                                       TTFACC_FILEBUFFERINFO * pOutputBufferInfo, 
                                       uint16 usFormat, 
                                       uint32 * pulNewOutOffset )
{
DIRECTORY *aDirectory;
DIRECTORY Directory;
OFFSET_TABLE OffsetTable;
DTTF_HEADER DttfHeader;
uint16 usnTables;
uint16 usnNewTables;
uint32 ulOffset;
uint32 ulDttfOffset;
uint16 usTableIdx;
uint16 usBytesRead;
uint16 usBytesWritten;
uint32 ulBytesWritten;
int16 errCode;

    ulDttfOffset = TTTableOffset( (TTFACC_FILEBUFFERINFO *)pInputBufferInfo, DTTF_TAG); /* check to see if one there already */
    if (ulDttfOffset != DIRECTORY_ERROR)
    {
        if ((errCode = ReadGeneric((TTFACC_FILEBUFFERINFO *) pInputBufferInfo, (uint8 *) &DttfHeader, SIZEOF_DTTF_HEADER, DTTF_HEADER_CONTROL, ulDttfOffset, &usBytesRead)) != NO_ERROR)
            return(errCode);
        if (DttfHeader.format != TTFDELTA_MERGE) /* only acceptable delta font at this time */
            return(ERR_INVALID_DELTA_FORMAT);
    }

    /* read offset table and determine number of existing tables */
    ulOffset = pInputBufferInfo->ulOffsetTableOffset;
    if ((errCode = ReadGeneric((TTFACC_FILEBUFFERINFO *) pInputBufferInfo, (uint8 *) &OffsetTable, SIZEOF_OFFSET_TABLE, OFFSET_TABLE_CONTROL, ulOffset, &usBytesRead)) != NO_ERROR)
        return(errCode);
    usnTables = OffsetTable.numTables;
    ulOffset += usBytesRead;
    /* Create a list of valid tables */

    aDirectory = (DIRECTORY *) Mem_Alloc((usnTables + (ulDttfOffset == 0)) * sizeof(DIRECTORY));    /* one extra for possible private table */
    if (aDirectory == NULL)
        return(ERR_MEM);
    

    /* sort directories by offset */

    for ( usTableIdx = usnNewTables = 0; usTableIdx < usnTables; usTableIdx++ )
    {
        errCode = ReadGeneric((TTFACC_FILEBUFFERINFO *)pInputBufferInfo, (uint8 *) &Directory, SIZEOF_DIRECTORY, DIRECTORY_CONTROL, ulOffset, &usBytesRead);
        ulOffset += usBytesRead;

        if (errCode != NO_ERROR)
        {
            Mem_Free(aDirectory);
            return errCode;
        }
        if (usFormat == TTFDELTA_DELTA) /* need to get rid of some of the tables */
        {
            switch(Directory.tag)/* only want to keep these */
            {
            /* tables sent each time */
            case HEAD_LONG_TAG:
            case MAXP_LONG_TAG:
            case HHEA_LONG_TAG:
            case VHEA_LONG_TAG:
                /* tables subsetted */
            case CMAP_LONG_TAG:
            case GLYF_LONG_TAG:
            case EBLC_LONG_TAG:
            case EBDT_LONG_TAG:
            case BLOC_LONG_TAG:
            case BDAT_LONG_TAG:
                /* tables compacted */
            case LTSH_LONG_TAG:
            case HMTX_LONG_TAG:
            case VMTX_LONG_TAG:
            case HDMX_LONG_TAG:
            case LOCA_LONG_TAG:
                /* private table - keep shell */
            case DTTF_LONG_TAG:
                break;
            default:  /* any others, just get rid of */
              continue; /* don't copy this over */
            }
        }

        /* empty out the entries */
        aDirectory[ usnNewTables ].length = 0;
        aDirectory[ usnNewTables ].offset = DIRECTORY_ERROR;
        aDirectory[ usnNewTables ].tag = Directory.tag; /* don't worry about the checksum */
        ++ usnNewTables;
    }
    /* add in dttf entry */
    if (ulDttfOffset == 0 && usFormat == TTFDELTA_SUBSET1 || usFormat == TTFDELTA_DELTA)
    {
        aDirectory[ usnNewTables].length = 0;
        aDirectory[ usnNewTables].offset = DIRECTORY_ERROR;
        aDirectory[ usnNewTables].tag = DTTF_LONG_TAG;
        ++usnNewTables;
        SortByTag( aDirectory, usnNewTables );    /* to insert the dttf table */
    }

    OffsetTable.numTables = usnNewTables; /* don't worry if other fields not ok, will be updated in compress tables */
    ulOffset = pOutputBufferInfo->ulOffsetTableOffset;
    errCode = WriteGeneric( pOutputBufferInfo, (uint8 *) &OffsetTable, SIZEOF_OFFSET_TABLE, OFFSET_TABLE_CONTROL, ulOffset, &usBytesWritten);
    /* write out the new directory info to the output buffer */
    ulOffset += usBytesWritten;
    if (errCode == NO_ERROR)
    {
        errCode = WriteGenericRepeat( pOutputBufferInfo, (uint8 *) aDirectory, DIRECTORY_CONTROL, ulOffset, &ulBytesWritten, usnNewTables, SIZEOF_DIRECTORY );
        if (errCode == NO_ERROR)
            *pulNewOutOffset = ulOffset+ulBytesWritten;  /* end of written to data */
    }
    Mem_Free(aDirectory);

    return(errCode);
}
Ejemplo n.º 12
0
PRIVATE int16 ModMacTrimmedCmap( TTFACC_FILEBUFFERINFO * pOutputBufferInfo, 
                               uint32 ulOffset, 
                               uint8 *puchKeepGlyphList, 
                               uint16 usGlyphCount )
{
uint16 i;
uint16 GlyphIndex;
CMAP_FORMAT6 CmapFormat6;
int16 errCode;
uint16 usBytesRead;
uint16 usBytesWritten;
uint16 usNewFirstCode= 0xFFFF;
uint16 usNewLastCode=0;  /* saved to calc NewEntryCount */
uint32 ulInGlyphOffset;  /* to point to a glyph value to read */
uint32 ulOutGlyphOffset;  /* to point to a glyph value to write */


    if ((errCode = ReadGeneric(pOutputBufferInfo, (uint8 *)&CmapFormat6, SIZEOF_CMAP_FORMAT6, CMAP_FORMAT6_CONTROL, ulOffset, &usBytesRead)) != NO_ERROR)
        return errCode; 
    ulInGlyphOffset = ulOutGlyphOffset = ulOffset + usBytesRead;
    /* first figure out where the start and end are */
    for ( i = 0; i < CmapFormat6.entryCount; i++ )
    {
        if ((errCode = ReadWord(pOutputBufferInfo, &GlyphIndex, ulInGlyphOffset)) != NO_ERROR)
            return errCode;
        if (GlyphIndex < usGlyphCount && puchKeepGlyphList[GlyphIndex] != 0) /* a glyph to be used */
        {
            if (usNewFirstCode == 0xFFFF)  /* default first code, set only if hasn't been set already */
                usNewFirstCode = CmapFormat6.firstCode + i;    /* may be zero */
            usNewLastCode = CmapFormat6.firstCode+i;
        }
        ulInGlyphOffset += sizeof(GlyphIndex);
    }
    if (usNewFirstCode == 0xFFFF) /* none were found */
    {
        CmapFormat6.firstCode = 0;
        CmapFormat6.entryCount = 0; 
    }
    else
    {
        /* now calculate the new table */
        CmapFormat6.firstCode = usNewFirstCode;
        CmapFormat6.entryCount = usNewLastCode - usNewFirstCode+1;
        
        ulInGlyphOffset = ulOutGlyphOffset + usNewFirstCode * sizeof(GlyphIndex); /* where to read the first code */
        for ( i = usNewFirstCode; i <= usNewLastCode; i++ )
        {
            if ((errCode = ReadWord(pOutputBufferInfo, &GlyphIndex, ulInGlyphOffset)) != NO_ERROR)
                return errCode;
            if (GlyphIndex >= usGlyphCount || puchKeepGlyphList[GlyphIndex] == 0) /* not a glyph to be used */
            {
                if ((errCode = WriteWord(pOutputBufferInfo, (uint16) 0, ulOutGlyphOffset)) != NO_ERROR)
                    return errCode;
            }
            else  /* write the glyph Index to the new location */
            {
                if ((errCode = WriteWord(pOutputBufferInfo, GlyphIndex, ulOutGlyphOffset)) != NO_ERROR)
                    return errCode;
            }
            ulInGlyphOffset += sizeof(GlyphIndex);
            ulOutGlyphOffset += sizeof(GlyphIndex);
        }
    }
    CmapFormat6.length = (uint16) (ulOutGlyphOffset - ulOffset);
    /* write out new cmap subtable header */
    if ((errCode = WriteGeneric(pOutputBufferInfo, (uint8 *)&CmapFormat6, SIZEOF_CMAP_FORMAT6, CMAP_FORMAT6_CONTROL, ulOffset, &usBytesWritten)) != NO_ERROR)
        return errCode; 

    return NO_ERROR;
}
Ejemplo n.º 13
0
PRIVATE int16 CompressCmapSubTables(TTFACC_FILEBUFFERINFO * pOutputBufferInfo,  /* ttfacc info */
                    CMAP_TABLELOC *pCmapTableLoc, /* array of CmapSubTable locators */
                    uint16 usSubTableCount, /* count of that array */
                    uint32 ulCmapOffset, /* offset to cmap table */
                    uint32 ulSubTableOffset, /* offset to beginning of Subtables */
                    uint32 ulCmapOldLength,    /* length of old cmap table - not to be exceeded */
                    uint32 *pulCmapNewLength)
{
IndexOffset *pIndexArray;  /* local array of structures to keep track of new offsets of sorted subtables */
CMAP_SUBHEADER_GEN CmapSubHeader;    
int16 errCode = NO_ERROR;
uint32 ulCurrentOffset;
uint32 ulLastOffset;
uint16 usIndex;
uint32 ulCmapTableLength = 0;
uint32 ulCmapSubTableDirOffset;
uint32 ulPadOffset;
uint16 i,j;
uint16 usBytesRead;
uint16 usPadBytes;

    pIndexArray = (IndexOffset *) Mem_Alloc(usSubTableCount * sizeof(*pIndexArray));
    if (pIndexArray == NULL)
        return ERR_MEM;
    
    /* sort them by old offsets, so we can move the blocks in order */
    SortCmapSubByOffset(pCmapTableLoc, usSubTableCount, pIndexArray); 

    ulCurrentOffset = ulSubTableOffset; /* end of the Cmap Directories */
    ulLastOffset = 0;
    for (i = 0; i < usSubTableCount; ++i)    /* process each subtable */
    {
        usIndex = pIndexArray[i].usIndex;
        /* check to see if this offset is the same as the last one copied. If so, ignore, as it has already been copied */
        if (i > 0 && pCmapTableLoc[usIndex].offset == ulLastOffset) /* we're pointing to some already copied data */
        {
            pIndexArray[i].ulNewOffset = pIndexArray[i-1].ulNewOffset;
            continue;
        }
        /* read the CmapSub Header */
         if ((errCode = ReadCmapLength(pOutputBufferInfo, &CmapSubHeader, ulCmapOffset + pCmapTableLoc[usIndex].offset, &usBytesRead)) != NO_ERROR)
            break;
        /* do we need to pad? */

        ulPadOffset = ulCurrentOffset;
        ulCurrentOffset = (ulPadOffset + 1) & ~1;      /* we may need to pad, but do it after we move data in case we would overwrite data */
        usPadBytes = (uint16) (ulCurrentOffset - ulPadOffset);

        if (ulCmapTableLength + usPadBytes + CmapSubHeader.length > ulCmapOldLength) /* if we are about to exceed the bounds */
        {
            errCode = ERR_WOULD_GROW;  /* can't do it. Bail and restore the old cmap table */
            break;
        }
        pIndexArray[i].ulNewOffset = ulCurrentOffset-ulCmapOffset;    /* calculate the new offset of the cmap subtable, and store in local structure */
        ulLastOffset = pCmapTableLoc[usIndex].offset;
        /* now copy the subtable to it's new locations */
        if ((errCode = CopyBlock(pOutputBufferInfo, ulCurrentOffset, ulCmapOffset + pCmapTableLoc[usIndex].offset,CmapSubHeader.length)) != NO_ERROR)
            break;
        for (j = 0; j < usPadBytes; ++j)
            WriteByte(pOutputBufferInfo,(uint8) 0, ulPadOffset+j);     /* now clear out those pad bytes */

        ulCurrentOffset += CmapSubHeader.length;
        ulCmapTableLength = ulCurrentOffset - ulCmapOffset;  /* to update the Font Directory values */
    } 
    if (errCode == NO_ERROR)
    {
        for (i = 0; i < usSubTableCount; ++i) /* now set the new offsets - retrieved from the local structure array */
            pCmapTableLoc[pIndexArray[i].usIndex].offset = pIndexArray[i].ulNewOffset;

        ulCmapSubTableDirOffset = ulCmapOffset + GetGenericSize( CMAP_HEADER_CONTROL );
        for (i = 0; i < usSubTableCount; ++i) /* now write the new offsets in their original order (Plat/encoding order) */
        {
              if ((errCode = WriteGeneric(pOutputBufferInfo, (uint8 *) &(pCmapTableLoc[i]), SIZEOF_CMAP_TABLELOC, CMAP_TABLELOC_CONTROL, ulCmapSubTableDirOffset, &usBytesRead)) != NO_ERROR)
                break; 
            ulCmapSubTableDirOffset += usBytesRead;  /* for next time around */
        }
    }
    Mem_Free(pIndexArray);
    if (errCode == NO_ERROR)
        /* now update the Directory Entry for the file */
        errCode = UpdateDirEntry(pOutputBufferInfo, CMAP_TAG, ulCmapTableLength);

    *pulCmapNewLength = ulCmapTableLength;

    return errCode;
}
Ejemplo n.º 14
0
int16 ModGlyfLocaAndHead( CONST_TTFACC_FILEBUFFERINFO * pInputBufferInfo, 
                         TTFACC_FILEBUFFERINFO * pOutputBufferInfo,
                         uint8 *puchKeepGlyphList, 
                         uint16 usGlyphCount,
                         uint32 *pCheckSumAdjustment,   /* this is returned to be saved with a subset1 or delta format font */
                         uint32 *pulNewOutOffset)
{

uint16 i;
uint16 usOffset;
uint16 usIdxToLocFmt;
uint16 usBytesWritten;
uint32 ulBytesWritten;
int16 errCode = NO_ERROR;
uint32 * aulLoca;
uint32 ulGlyphLength;
uint32 ulOutLoca;
uint32 ulGlyfOffset;
uint32 ulOutGlyfOffset;
uint32 ulOutGlyfDirectoryOffset;
uint32 ulHeadOffset;
uint32 ulOutLocaOffset;
uint32 ulOutLocaDirectoryOffset;
DIRECTORY LocaDirectory, GlyfDirectory;
HEAD Head;

/* allocate memory for and read loca table */

    aulLoca = (uint32 *)Mem_Alloc( (usGlyphCount + 1) * sizeof( uint32 ));
    if ( aulLoca == NULL )
        return ERR_MEM;

    if (GetLoca((TTFACC_FILEBUFFERINFO *)pInputBufferInfo, aulLoca, usGlyphCount + 1) == 0L)
    {
        Mem_Free(aulLoca);
        return ERR_INVALID_LOCA;
    }

    if ((ulHeadOffset = GetHead(pOutputBufferInfo, &Head)) == 0L)
    {
        /* copy over head table. will update below */
        if ((errCode = CopyTableOver(pOutputBufferInfo, pInputBufferInfo, HEAD_TAG, pulNewOutOffset))!=NO_ERROR)
        {
            Mem_Free(aulLoca);
            return errCode;
        }
        ulHeadOffset = GetHead(pOutputBufferInfo, &Head);
    }
    
    ulOutLoca     = 0L;
    ulGlyfOffset  = TTTableOffset( (TTFACC_FILEBUFFERINFO *)pInputBufferInfo, GLYF_TAG );
    if (ulGlyfOffset == DIRECTORY_ERROR) /* this should have been setup */
    {
        Mem_Free(aulLoca);
        return ERR_MISSING_GLYF; 
    }
    ulOutGlyfDirectoryOffset = GetTTDirectory( pOutputBufferInfo, GLYF_TAG, &GlyfDirectory); 
    /* make sure there is a directory entry */
    if (ulOutGlyfDirectoryOffset == DIRECTORY_ERROR) /* this should have been setup */
    {
        Mem_Free(aulLoca);
        return ERR_MISSING_GLYF; 
    }
    if (GlyfDirectory.offset == DIRECTORY_ERROR)
    {
        if ((errCode = ZeroLongWordAlign(pOutputBufferInfo, *pulNewOutOffset, pulNewOutOffset)) != NO_ERROR)
        {
            Mem_Free(aulLoca);
            return errCode;
        }
        GlyfDirectory.offset = *pulNewOutOffset;
    }

    ulOutGlyfOffset = GlyfDirectory.offset;

    /* go thru the glyf table, copying up the glyphs to be saved */
    for ( i = 0; i < usGlyphCount; i++ )
    {
        ulGlyphLength = 0L;
        if (puchKeepGlyphList[i])   /* we want to keep this one */
        {
            /* copy existing glyph data to new location */

            if ( aulLoca[ i ] < aulLoca[ i+1 ] )
                ulGlyphLength = aulLoca[ i+1 ] - aulLoca[ i ];

            if ( ulGlyphLength )
            {
                if ((errCode = CopyBlockOver( pOutputBufferInfo, pInputBufferInfo, ulOutGlyfOffset + ulOutLoca, 
                        ulGlyfOffset + aulLoca[ i ], ulGlyphLength )) != NO_ERROR)
                    break;
            }
        }
        assert((ulOutLoca & 1) != 1);
        aulLoca[ i ] = ulOutLoca;
        ulOutLoca += ulGlyphLength;
        if (ulOutLoca & 1)
        {       /* the glyph offset is on an odd-byte boundry. get ready for next time */
            if ((errCode = WriteByte( pOutputBufferInfo, 0, ulOutGlyfOffset + ulOutLoca)) != NO_ERROR)
                break;
            ++ulOutLoca;
        }
    }
    if (errCode == NO_ERROR)
    {
    /* The last loca entry is the end of the last glyph! */
        *pulNewOutOffset += ulOutLoca;
        aulLoca[ usGlyphCount ] = ulOutLoca;
        GlyfDirectory.length = ulOutLoca;
        errCode = WriteGeneric( pOutputBufferInfo, (uint8 *)&GlyfDirectory, SIZEOF_DIRECTORY, DIRECTORY_CONTROL, ulOutGlyfDirectoryOffset, &usBytesWritten );
    }

    if (errCode != NO_ERROR)
    {
        Mem_Free(aulLoca);
        return errCode;
    }

    /* write out the modified 'loca' table */
 
    ulOutLocaDirectoryOffset = GetTTDirectory( pOutputBufferInfo, LOCA_TAG, &LocaDirectory); 
    /* make sure there is a directory entry */
    if (ulOutLocaDirectoryOffset == DIRECTORY_ERROR) /* this should have been setup */
    {
        Mem_Free(aulLoca);
        return ERR_MISSING_LOCA;
    }

    if ((errCode = ZeroLongWordAlign(pOutputBufferInfo, *pulNewOutOffset, pulNewOutOffset)) != NO_ERROR)
    {
        Mem_Free(aulLoca);
        return errCode;
    }
    ulOutLocaOffset = LocaDirectory.offset = *pulNewOutOffset;  /* where to write the loca */

    /* Check to see what format to use */
    if (ulOutLoca <= 0x1FFFC)   /* maximum number stored here (0xFFFE * 2) Chosen as conservative value over 0xFFFF * 2 */
    {
        usIdxToLocFmt = SHORT_OFFSETS;
        for ( i = 0; i <= usGlyphCount; i++ )
        {
            assert((aulLoca[i] & 1) != 1);   /* can't have this, would be truncated */
            usOffset = (uint16) (aulLoca[ i ] / 2L);
            if ((errCode = WriteWord( pOutputBufferInfo,  usOffset, ulOutLocaOffset + i*sizeof(uint16) )) != NO_ERROR)
                break;
        }
        ulOutLoca = (uint32) (usGlyphCount+1) * sizeof(uint16);
    }
    else
    {
        usIdxToLocFmt = LONG_OFFSETS;
        errCode = WriteGenericRepeat(pOutputBufferInfo,  (uint8 *) aulLoca, LONG_CONTROL,ulOutLocaOffset,&ulBytesWritten,(uint16) (usGlyphCount+1), sizeof(uint32)); 
        ulOutLoca = ulBytesWritten;
    }

    if (errCode == NO_ERROR)
    {
        /* update the length, etc. for the loca table as well */

        LocaDirectory.length = ulOutLoca;
        *pulNewOutOffset += ulOutLoca;
        if ((errCode = WriteGeneric( pOutputBufferInfo, (uint8 *) &LocaDirectory, SIZEOF_DIRECTORY, DIRECTORY_CONTROL, ulOutLocaDirectoryOffset, &usBytesWritten )) == NO_ERROR)
        {
            *pCheckSumAdjustment = Head.checkSumAdjustment;/* for use by dttf table */
            Head.checkSumAdjustment = 0L;    /* needs to be 0 when setting the file checksum value */
            Head.indexToLocFormat = usIdxToLocFmt;
            errCode = WriteGeneric( pOutputBufferInfo, (uint8 *) &Head, SIZEOF_HEAD, HEAD_CONTROL, ulHeadOffset, &usBytesWritten);
        }
    }

    /* clean up */

    Mem_Free( aulLoca );
    return errCode;

}