Madhukar_KR

Hi,

This is regarding the CreateFontPackage API which is implemented in the FontSub.dll as part of Windows GDI which we would like to use for Font subsetting:

I got the details about this from the URL below:

http://windowssdk.msdn.microsoft.com/library/default.asp url=/library/en-us/gdi/t2embed_CreateFontPackage.asp

1. I tried out using this API but the API is returning an error code of 1009 for which I was not able to get the error message string. The API documentation gives a list of error codes @ http://windowssdk.msdn.microsoft.com/library/default.asp url=/library/en-us/gdi/t2embed_FontPackageErrorMessages.asp such as ERR_NO_GLYPHS.

2. Where are the error codes defined The error code definitons could not be found in FontSub.h which is in the Windows SDK Nov CTP include folder.

3. I wrote the output buffer contents to a .ttf file, but the output TTF file from this API seems to be corrupt as it does not open as a valid font file.

4. Is there any other way through which I can implement Font subsetting

Below is the piece of code which I have tried out:

I am building this code through VS2005 in a Windows Forms Application:

FILE* Httf = fopen("C:\\Windows\\Fonts\\COUR.TTF","rb");

fseek(Httf,0,SEEK_END);

DWORD len = ftell(Httf);

fread(puchSrcBuffer,sizeof(puchSrcBuffer),len,Httf);

unsigned long ulSrcBufferSize; /* size of input TTF or TTC buffer data */

ulSrcBufferSize = sizeof(puchSrcBuffer);

unsigned char ** ppuchFontPackageBuffer; /* output package buffer */

unsigned long * pulFontPackageBufferSize; /* output package buffer size */

unsigned long * pulBytesWritten; /* output package buffer data length */

 

unsigned short usFlag = TTFCFP_FLAGS_SUBSET; /* subset, compress, or both, TTF or TTC, Chars or Glyphs */

unsigned short usTTCIndex = NULL; /* TTC Index, only used if TTC bit set */

unsigned short usSubsetFormat = TTFCFP_SUBSET; /* Old Subset, Subset or Delta */

unsigned short usSubsetLanguage = 0; /* Language in Name table to keep */

unsigned short usSubsetPlatform = TTFCFP_UNICODE_PLATFORMID; /* if ListType is Character, Platform of cmap to use for glyph list */

unsigned short usSubsetEncoding = TTFCFP_DONT_CARE; /* if ListType is Character, Encoding of cmap to use for glyph list */

unsigned short *pusSubsetKeepList; /* List of Characters or Glyphs to keep */

pusSubsetKeepList = new unsigned short [10];

pusSubsetKeepList[0] = 48;

pusSubsetKeepList[1] = 49;

pusSubsetKeepList[2] = 50;

pusSubsetKeepList[3] = 51;

pusSubsetKeepList[4] = 71;

pusSubsetKeepList[5] = NULL;

INT iListCount = 0,i=0;

while(pusSubsetKeepList[i++] != NULL)

{

iListCount++;

}

unsigned short usSubsetListCount = iListCount; /* number of elements in list */

CFP_ALLOCPROC lpfnAllocate = fnAllocate; /* call back function to allocate temp buffers and output buffers */

CFP_REALLOCPROC lpfnReAllocate = fnReAllocate; /* call back function to reallocate temp and output buffers */

CFP_FREEPROC lpfnFree = fnFree; /* call back function to free buffer allocated with lpfnAllocate and lpfnReAllocate */

void * lpvReserved = NULL;

//Load the Font subset dll

HMODULE hFS = NULL;

hFS = LoadLibrary(L"C:\\WINDOWS\\system32\\FontSub.dll");

typedef short (*CREATEFONTPACKAGE)(const unsigned char *,const unsigned long ,unsigned char ** ,

const unsigned long *,unsigned long *,const unsigned short ,const unsigned short,

const unsigned short,const unsigned short,const unsigned short,const unsigned short,

const unsigned short*,const unsigned short,CFP_ALLOCPROC,CFP_REALLOCPROC,CFP_FREEPROC,

LPVOID);

if(hFS != NULL)

{

//Get the Address of the exported fn

CREATEFONTPACKAGE lpDllEntryPoint = (CREATEFONTPACKAGE)GetProcAddress(hFS,"CreateFontPackage");

//#ifdef a 0

//Invoke the fn

short sRet = 1;

sRet = (short)(*lpDllEntryPoint)(

puchSrcBuffer, /* input TTF or TTC buffer */

ulSrcBufferSize, /* size of input TTF or TTC buffer data */

ppuchFontPackageBuffer, /* output package buffer */

pulFontPackageBufferSize, /* output package buffer size */

pulBytesWritten, /* output package buffer data length */

usFlag, /* subset, compress, or both, TTF or TTC, Chars or Glyphs */

usTTCIndex, /* TTC Index, only used if TTC bit set */

usSubsetFormat, /* Old Subset, Subset or Delta */

usSubsetLanguage, /* Language in Name table to keep */

usSubsetPlatform, /* if ListType is Character, Platform of cmap to use for glyph list */

usSubsetEncoding, /* if ListType is Character, Encoding of cmap to use for glyph list */

pusSubsetKeepList, /* List of Characters or Glyphs to keep */

usSubsetListCount, /* number of elements in list */

(CFP_ALLOCPROC)lpfnAllocate, /* call back function to allocate temp buffers and output buffers */

(CFP_REALLOCPROC) lpfnReAllocate, /* call back function to reallocate temp and output buffers */

(CFP_FREEPROC) lpfnFree, /* call back function to free buffer allocated with lpfnAllocate and lpfnReAllocate */

NULL);

DWORD Errno = GetLastError();

//Write the buffer contents to a file

FILE *ttfFile = NULL;

ttfFile = fopen("E:\\VSSamples\\Metro-Print\\Containers\\Arialsub.ttf","w+");

fwrite((void*)&ppuchFontPackageBuffer,sizeof(ppuchFontPackageBuffer),500,ttfFile);

fclose(ttfFile);

Best Regards,

Madhukar KR

 

  

 

 




Re: XML Paper Specification (XPS) Query regarding CreateFontPackage API used for Font Subsetting

Madhukar_KR

Some corrections in the Code above: Thanks to xpsInfo & Windows team (Clif & Sergey Malkin) for pointing them out.. Just posting this here for everyone's reference:

But the API still seems to be failing giving 1009 as the error code & also noticed that the callback functions are not getting called, resulting in Invalid/Incomplete data being present in the output font package buffer.

FILE* Httf = fopen("C:\\Windows\\Fonts\\COUR.TTF","rb");

fseek(Httf,0,SEEK_END);

DWORD len = ftell(Httf);

//Seeking back to the beginning of the file

int s = fseek(Httf,0,SEEK_SET);

fread(puchSrcBuffer,sizeof(puchSrcBuffer),len,Httf);

unsigned long ulSrcBufferSize; /* size of input TTF or TTC buffer data */

ulSrcBufferSize = sizeof(puchSrcBuffer);

unsigned char * ppuchFontPackageBuffer = NULL; /* output package buffer */

unsigned long pulFontPackageBufferSize =0; /*= new unsigned long[dwTTFileSize];*/ /* output package buffer size */

unsigned long pulBytesWritten=0; /*= new unsigned long[dwTTFileSize];*/ /* output package buffer data length */

unsigned short usFlag = TTFCFP_FLAGS_SUBSET; /* subset, compress, or both, TTF or TTC, Chars or Glyphs */

unsigned short usTTCIndex = NULL; /* TTC Index, only used if TTC bit set */

unsigned short usSubsetFormat = TTFCFP_SUBSET; /* Old Subset, Subset or Delta */

unsigned short usSubsetLanguage = 0; /* Language in Name table to keep */

unsigned short usSubsetPlatform = TTFCFP_UNICODE_PLATFORMID; /* if ListType is Character, Platform of cmap to use for glyph list */

unsigned short usSubsetEncoding = TTFCFP_DONT_CARE; /* if ListType is Character, Encoding of cmap to use for glyph list */

unsigned short *pusSubsetKeepList; /* List of Characters or Glyphs to keep */

pusSubsetKeepList = new unsigned short [10];

pusSubsetKeepList[0] = 48;

pusSubsetKeepList[1] = 49;

pusSubsetKeepList[2] = 50;

pusSubsetKeepList[3] = 51;

pusSubsetKeepList[4] = 71;

pusSubsetKeepList[5] = NULL;

INT iListCount = 0,i=0;

while(pusSubsetKeepList[i++] != NULL)

{

iListCount++;

}

unsigned short usSubsetListCount = iListCount; /* number of elements in list */

CFP_ALLOCPROC lpfnAllocate = (CFP_ALLOCPROC)fnAllocate; /* call back function to allocate temp buffers and output buffers */

CFP_REALLOCPROC lpfnReAllocate = (CFP_REALLOCPROC)fnReAllocate; /* call back function to reallocate temp and output buffers */

CFP_FREEPROC lpfnFree = (CFP_FREEPROC)fnFree; /* call back function to free buffer allocated with lpfnAllocate and lpfnReAllocate */

void * lpvReserved = NULL;

//Load the Font subset dll

HMODULE hFS = NULL;

hFS = LoadLibrary(L"C:\\WINDOWS\\system32\\FontSub.dll");

typedef short (*CREATEFONTPACKAGE)(const unsigned char *,const unsigned long ,unsigned char ** ,

const unsigned long *,unsigned long *,const unsigned short ,const unsigned short,

const unsigned short,const unsigned short,const unsigned short,const unsigned short,

const unsigned short*,const unsigned short,CFP_ALLOCPROC,CFP_REALLOCPROC,CFP_FREEPROC,

LPVOID);

if(hFS != NULL)

{

//Get the Address of the exported fn

CREATEFONTPACKAGE lpDllEntryPoint = (CREATEFONTPACKAGE)GetProcAddress(hFS,"CreateFontPackage");

//#ifdef a 0

//Invoke the fn

short sRet = 1; void *mem=NULL;

sRet = (short)(*lpDllEntryPoint)(

puchSrcBuffer, /* input TTF or TTC buffer */

ulSrcBufferSize, /* size of input TTF or TTC buffer data */

&ppuchFontPackageBuffer, /* output package buffer */

&pulFontPackageBufferSize, /* output package buffer size */

&pulBytesWritten, /* output package buffer data length */

usFlag, /* subset, compress, or both, TTF or TTC, Chars or Glyphs */

usTTCIndex, /* TTC Index, only used if TTC bit set */

usSubsetFormat, /* Old Subset, Subset or Delta */

usSubsetLanguage, /* Language in Name table to keep */

usSubsetPlatform, /* if ListType is Character, Platform of cmap to use for glyph list */

usSubsetEncoding, /* if ListType is Character, Encoding of cmap to use for glyph list */

pusSubsetKeepList, /* List of Characters or Glyphs to keep */

usSubsetListCount, /* number of elements in list */

(CFP_ALLOCPROC)lpfnAllocate, /* call back function to allocate temp buffers and output buffers */

(CFP_REALLOCPROC)lpfnReAllocate, /* call back function to reallocate temp and output buffers */

(CFP_FREEPROC)lpfnFree, /* call back function to free buffer allocated with lpfnAllocate and lpfnReAllocate */

NULL);

Regards,

Madhukar KR






Re: XML Paper Specification (XPS) Query regarding CreateFontPackage API used for Font Subsetting

Feng Yuan

The main issue seems to be the following line:

fread(puchSrcBuffer, sizeof(puchSrcBuffer), len, Httf);

it should have been:

fread(puchSrcBuffer, 1, len, Httf);

Here is the code which I have tested:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "fontsub.h"

typedef unsigned long (__cdecl * CREATEFONTPACKAGE)(
    CONST unsigned char * puchSrcBuffer, /* input TTF or TTC buffer */
    CONST unsigned long ulSrcBufferSize, /* size of input TTF or TTC buffer data */
    unsigned char ** ppuchFontPackageBuffer, /* output package buffer */
    unsigned long * pulFontPackageBufferSize, /* output package buffer size */
    unsigned long * pulBytesWritten,  /* output package buffer data length */
    CONST unsigned short usFlag, /* subset, compress, or both, TTF or TTC, Chars or Glyphs */
    CONST unsigned short usTTCIndex, /* TTC Index, only used if TTC bit set */
    CONST unsigned short usSubsetFormat, /* Old Subset, Subset or Delta */
    CONST unsigned short usSubsetLanguage, /* Language in Name table to keep */
    CONST unsigned short usSubsetPlatform, /* if ListType is Character, Platform of cmap to use for glyph list */
    CONST unsigned short usSubsetEncoding, /* if ListType is Character, Encoding of cmap to use for glyph list */
    CONST unsigned short *pusSubsetKeepList, /* List of Characters or Glyphs to keep */
    CONST unsigned short usSubsetListCount,  /* number of elements in list */
    CFP_ALLOCPROC lpfnAllocate,   /* call back function to allocate temp buffers and output buffers */
    CFP_REALLOCPROC lpfnReAllocate,   /* call back function to reallocate temp and output buffers */
    CFP_FREEPROC lpfnFree,  /* call back function to free buffer allocated with lpfnAllocate and lpfnReAllocate */
    void * lpvReserved);


int Subset(const char * fontFile, const unsigned short * keepList, unsigned short count)
{
    BYTE * pBuffer = NULL;
    DWORD  nLength = 0;

    {
        FILE * Httf = fopen(fontFile, "rb");

        if (Httf == NULL)
        {
            return -1;
        }

        fseek(Httf, 0, SEEK_END);

        nLength = ftell(Httf);

        // Seeking back to the beginning of the file

        fseek(Httf, 0, SEEK_SET);

        pBuffer = new BYTE[nLength];

        if (pBuffer == NULL)
        {
            fclose(Httf);

            return -2;
        }

        fread(pBuffer, 1, nLength, Httf);
   
        fclose(Httf);
    }

    //Load the Font subset dll

    HMODULE hFS = LoadLibrary("C:\\WINDOWS\\system32\\FontSub.dll");

    int result = 0;

    if (hFS == NULL)
    {
        result = -3;
    }
    else
    {
        //Get the Address of the exported fn

        CREATEFONTPACKAGE lpDllEntryPoint = (CREATEFONTPACKAGE) GetProcAddress(hFS, "CreateFontPackage");

        if (lpDllEntryPoint == NULL)
        {
            result = -4;
        }
        else
        {
            unsigned char * puchFontPackageBuffer   = NULL;
            unsigned long   ulFontPackageBufferSize = 0; 
            unsigned long   ulBytesWritten          = 0; 
       
            DWORD ret;
       
            ret = (*lpDllEntryPoint)(
                        pBuffer,     /* input TTF or TTC buffer */
                        nLength,     /* size of input TTF or TTC buffer data */
                        &puchFontPackageBuffer,     /* output package buffer */
                        &ulFontPackageBufferSize, /* output package buffer size */
                        &ulBytesWritten,   /* output package buffer data length */
                        TTFCFP_FLAGS_SUBSET,  /* subset, compress, or both, TTF or TTC, Chars or Glyphs */
                        0,       /* TTC Index, only used if TTC bit set */
                        TTFCFP_SUBSET,    /* Old Subset, Subset or Delta */
                        0,       /* Language in Name table to keep */
                        TTFCFP_UNICODE_PLATFORMID,  /* if ListType is Character, Platform of cmap to use for glyph list */
                        TTFCFP_DONT_CARE,   /* if ListType is Character, Encoding of cmap to use for glyph list */
                        keepList,     /* List of Characters or Glyphs to keep */
                        count,      /* number of elements in list */
                        malloc,      /* call back function to allocate temp buffers and output buffers */
                        realloc,     /* call back function to reallocate temp and output buffers */
                        free,      /* call back function to free buffer allocated with lpfnAllocate and lpfnReAllocate */
                        NULL);

            if (puchFontPackageBuffer != NULL)
            {
                printf("Subset: '%s' %d glyphs, original size: %d bytes -> subset size: %d bytes\r\n",
                    fontFile, count, nLength, ulBytesWritten);

                free(puchFontPackageBuffer);
            }
            else
            {
                result = -5;
            }
        }

    }

    delete [] pBuffer;

    return result;
}


int _tmain(int argc, _TCHAR* argv[])
{
    unsigned short  usSubsetKeepList[5] = { 48, 49, 50, 51, 71 };
               
    return Subset("C:\\Windows\\Fonts\\COUR.TTF", usSubsetKeepList, 5);
}

 Result:

Subset: 'C:\Windows\Fonts\COUR.TTF' 5 glyphs, original size: 303296 bytes -> subset size: 34432 bytes

 

 






Re: XML Paper Specification (XPS) Query regarding CreateFontPackage API used for Font Subsetting

Madhukar_KR

Hi Feng Yuan,

The problem is resolved. CreateFontPackage did create a working subset font after making the fread() & fwrite() calls appropriately.

Thanks a lot for the help.

Regards,

Madhukar KR







Re: XML Paper Specification (XPS) Query regarding CreateFontPackage API used for Font Subsetting

Mippy2

Error 1006 returns when CreateFontPackage is called about TTC data.
Should I take care about TTC data
I am setting "TTFCFP_FLAGS_TTC | TTFCFP_FLAGS_SUBSET" to usFlag.





Re: XML Paper Specification (XPS) Query regarding CreateFontPackage API used for Font Subsetting

Mippy2

I set "TTFCFP_MS_PLATFORMID" to "usSubsetPlatform".
Then, it made it to good.