📄 convertglyph.cpp
字号:
#include <windows.h>
#pragma pack(1) // for byte alignment
// We need byte alignment to be structure compatible with the
// contents of a TrueType font file
// Macros to swap from Big Endian to Little Endian
#define SWAPWORD(x) MAKEWORD( HIBYTE(x), LOBYTE(x) )
#define SWAPLONG(x) MAKELONG( SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)) )
typedef struct _CMap4 // From the TrueType Spec. revision 1.66
{
USHORT format; // Format number is set to 4.
USHORT length; // Length in bytes.
USHORT version; // Version number (starts at 0).
USHORT segCountX2; // 2 x segCount.
USHORT searchRange; // 2 x (2**floor(log2(segCount)))
USHORT entrySelector; // log2(searchRange/2)
USHORT rangeShift; // 2 x segCount - searchRange
USHORT Arrays[1]; // Placeholder symbol for address of arrays following
} CMAP4, *LPCMAP4;
/* CMAP table Data
From the TrueType Spec revision 1.66
USHORT Table Version #
USHORT Number of encoding tables
*/
#define CMAPHEADERSIZE (sizeof(USHORT)*2)
/* ENCODING entry Data aka CMAPENCODING
From the TrueType Spec revision 1.66
USHORT Platform Id
USHORT Platform Specific Encoding Id
ULONG Byte Offset from beginning of table
*/
#define ENCODINGSIZE (sizeof(USHORT)*2 + sizeof(ULONG))
typedef struct _CMapEncoding
{
USHORT PlatformId;
USHORT EncodingId;
ULONG Offset;
} CMAPENCODING;
// Macro to pack a TrueType table name into a DWORD
#define MAKETABLENAME(ch1, ch2, ch3, ch4) ( (((DWORD)(ch4)) << 24) | (((DWORD)(ch3)) << 16) | (((DWORD)(ch2)) << 8) | ((DWORD)(ch1)))
/* public functions */
USHORT GetTTUnicodeGlyphIndex(HDC hdc, USHORT ch);
USHORT GetTTUnicodeCharCount(HDC hdc);
// DWORD packed four letter table name for each GetFontData()
// function call when working with the CMAP TrueType table
DWORD dwCmapName = MAKETABLENAME( 'c','m','a','p' );
USHORT *GetEndCountArray(LPBYTE pBuff)
{
return (USHORT *)(pBuff + 7 * sizeof(USHORT)); // Per TT spec
}
USHORT *GetStartCountArray(LPBYTE pBuff)
{
DWORD segCount = ((LPCMAP4)pBuff)->segCountX2/2;
return (USHORT *)( pBuff +
8 * sizeof(USHORT) + // 7 header + 1 reserved USHORT
segCount*sizeof(USHORT) ); // Per TT spec
}
USHORT *GetIdDeltaArray(LPBYTE pBuff)
{
DWORD segCount = ((LPCMAP4)pBuff)->segCountX2/2;
return (USHORT *)( pBuff +
8 * sizeof(USHORT) + // 7 header + 1 reserved USHORT
segCount * 2 * sizeof(USHORT) ); // Per TT spec
}
USHORT *GetIdRangeOffsetArray(LPBYTE pBuff)
{
DWORD segCount = ((LPCMAP4)pBuff)->segCountX2/2;
return (USHORT *)( pBuff +
8 * sizeof(USHORT) + // 7 header + 1 reserved USHORT
segCount * 3 * sizeof(USHORT) ); // Per TT spec
}
void SwapArrays( LPCMAP4 pFormat4 )
{
DWORD segCount = pFormat4->segCountX2/2; // Per TT Spec
DWORD i;
USHORT *pGlyphId,
*pEndOfBuffer,
*pstartCount = GetStartCountArray( (LPBYTE)pFormat4 ),
*pidDelta = GetIdDeltaArray( (LPBYTE)pFormat4 ),
*pidRangeOffset = GetIdRangeOffsetArray( (LPBYTE)pFormat4 ),
*pendCount = GetEndCountArray( (LPBYTE)pFormat4 );
// Swap the array elements for Intel.
for (i=0; i < segCount; i++)
{
pendCount[i] = SWAPWORD(pendCount[i]);
pstartCount[i] = SWAPWORD(pstartCount[i]);
pidDelta[i] = SWAPWORD(pidDelta[i]);
pidRangeOffset[i] = SWAPWORD(pidRangeOffset[i]);
}
// Swap the Glyph Id array
pGlyphId = pidRangeOffset + segCount; // Per TT spec
pEndOfBuffer = (USHORT*)((LPBYTE)pFormat4 + pFormat4->length);
for (;pGlyphId < pEndOfBuffer; pGlyphId++)
{
*pGlyphId = SWAPWORD(*pGlyphId);
}
} /* end of function SwapArrays */
BOOL GetFontEncoding (
HDC hdc,
CMAPENCODING * pEncoding,
int iEncoding
)
/*
Note for this function to work correctly, structures must
have byte alignment.
*/
{
DWORD dwResult;
BOOL fSuccess = TRUE;
// Get the structure data from the TrueType font
dwResult = GetFontData (
hdc,
dwCmapName,
CMAPHEADERSIZE + ENCODINGSIZE*iEncoding,
pEncoding,
sizeof(CMAPENCODING) );
fSuccess = (dwResult == sizeof(CMAPENCODING));
// swap the Platform Id for Intel
pEncoding->PlatformId = SWAPWORD(pEncoding->PlatformId);
// swap the Specific Id for Intel
pEncoding->EncodingId = SWAPWORD(pEncoding->EncodingId);
// swap the subtable offset for Intel
pEncoding->Offset = SWAPLONG(pEncoding->Offset);
return fSuccess;
} /* end of function GetFontEncoding */
BOOL GetFontFormat4Header (
HDC hdc,
LPCMAP4 pFormat4,
DWORD dwOffset
)
/*
Note for this function to work correctly, structures must
have byte alignment.
*/
{
BOOL fSuccess = TRUE;
DWORD dwResult;
int i;
USHORT *pField;
// Loop and Alias a writeable pointer to the field of interest
pField = (USHORT *)pFormat4;
for (i=0; i < 7; i++)
{
// Get the field from the subtable
dwResult = GetFontData (
hdc,
dwCmapName,
dwOffset + sizeof(USHORT)*i,
pField,
sizeof(USHORT) );
// swap it to make it right for Intel.
*pField = SWAPWORD(*pField);
// move on to the next
pField++;
// accumulate our success
fSuccess = (dwResult == sizeof(USHORT)) && fSuccess;
}
return fSuccess;
} /* end of function GetFontFormat4Header */
BOOL GetFontFormat4Subtable (
HDC hdc, // DC with TrueType font
LPCMAP4 pFormat4Subtable, // destination buffer
DWORD dwOffset // Offset within font
)
{
DWORD dwResult;
USHORT length;
// Retrieve the header values in swapped order
if (!GetFontFormat4Header ( hdc,
pFormat4Subtable,
dwOffset ))
{
return FALSE;
}
// Get the rest of the table
length = pFormat4Subtable->length - (7 * sizeof(USHORT));
dwResult = GetFontData( hdc,
dwCmapName,
dwOffset + 7 * sizeof(USHORT), // pos of arrays
(LPBYTE)pFormat4Subtable->Arrays, // destination
length );
if ( dwResult != length)
{
// We really shouldn't ever get here
return FALSE;
}
// Swamp the arrays
SwapArrays( pFormat4Subtable );
return TRUE;
}
USHORT GetFontFormat4CharCount (
LPCMAP4 pFormat4 // pointer to a valid Format4 subtable
)
{
USHORT i,
*pendCount = GetEndCountArray((LPBYTE) pFormat4),
*pstartCount = GetStartCountArray((LPBYTE) pFormat4),
*idRangeOffset = GetIdRangeOffsetArray( (LPBYTE) pFormat4 );
// Count the # of glyphs
USHORT nGlyphs = 0;
if ( pFormat4 == NULL )
return 0;
// by adding up the coverage of each segment
for (i=0; i < (pFormat4->segCountX2/2); i++)
{
if ( idRangeOffset[i] == 0)
{
// if per the TT spec, the idRangeOffset element is zero,
// all of the characters in this segment exist.
nGlyphs += pendCount[i] - pstartCount[i] +1;
}
else
{
// otherwise we have to test for glyph existence for
// each character in the segment.
USHORT idResult; //Intermediate id calc.
USHORT ch;
for (ch = pstartCount[i]; ch <= pendCount[i]; ch++)
{
// determine if a glyph exists
idResult = *(
idRangeOffset[i]/2 +
(ch - pstartCount[i]) +
&idRangeOffset[i]
); // indexing equation from TT spec
if (idResult != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -