📄 convertglyph.cpp
字号:
// Yep, count it.
nGlyphs++;
}
}
}
return nGlyphs;
} /* end of function GetFontFormat4CharCount */
BOOL GetTTUnicodeCoverage (
HDC hdc, // DC with TT font
LPCMAP4 pBuffer, // Properly allocated buffer
DWORD cbSize, // Size of properly allocated buffer
DWORD *pcbNeeded // size of buffer needed
)
/*
if cbSize is to small or zero, or if pBuffer is NULL the function
will fail and return the required buffer size in *pcbNeeded.
if another error occurs, the function will fail and *pcbNeeded will
be zero.
When the function succeeds, *pcbNeeded contains the number of bytes
copied to pBuffer.
*/
{
USHORT nEncodings; // # of encoding in the TT font
CMAPENCODING Encoding; // The current encoding
DWORD dwResult;
DWORD i,
iUnicode; // The Unicode encoding
CMAP4 Format4; // Unicode subtable format
LPCMAP4 pFormat4Subtable; // Working buffer for subtable
// Get the number of subtables in the CMAP table from the CMAP header
// The # of subtables is the second USHORT in the CMAP table, per the TT Spec.
dwResult = GetFontData ( hdc, dwCmapName, sizeof(USHORT), &nEncodings, sizeof(USHORT) );
nEncodings = SWAPWORD(nEncodings);
if ( dwResult != sizeof(USHORT) )
{
// Something is wrong, we probably got GDI_ERROR back
// Probably this means that the Device Context does not have
// a TrueType font selected into it.
return FALSE;
}
// Get the encodings and look for a Unicode Encoding
iUnicode = nEncodings;
for (i=0; i < nEncodings; i++)
{
// Get the encoding entry for each encoding
if (!GetFontEncoding ( hdc, &Encoding, i ))
{
*pcbNeeded = 0;
return FALSE;
}
// Take note of the Unicode encoding.
//
// A Unicode encoding per the TrueType specification has a
// Platform Id of 3 and a Platform specific encoding id of 1
// Note that Symbol fonts are supposed to have a Platform Id of 3
// and a specific id of 0. If the TrueType spec. suggestions were
// followed then the Symbol font's Format 4 encoding could also
// be considered Unicode because the mapping would be in the
// Private Use Area of Unicode. We assume this here and allow
// Symbol fonts to be interpreted. If they do not contain a
// Format 4, we bail later. If they do not have a Unicode
// character mapping, we'll get wrong results.
// Code could infer from the coverage whether 3-0 fonts are
// Unicode or not by examining the segments for placement within
// the Private Use Area Subrange.
if (Encoding.PlatformId == 3 &&
(Encoding.EncodingId == 1 || Encoding.EncodingId == 0) )
{
iUnicode = i; // Set the index to the Unicode encoding
}
}
// index out of range means failure to find a Unicode mapping
if (iUnicode >= nEncodings)
{
// No Unicode encoding found.
*pcbNeeded = 0;
return FALSE;
}
// Get the header entries(first 7 USHORTs) for the Unicode encoding.
if ( !GetFontFormat4Header ( hdc, &Format4, Encoding.Offset ) )
{
*pcbNeeded = 0;
return FALSE;
}
// Check to see if we retrieved a Format 4 table
if ( Format4.format != 4 )
{
// Bad, subtable is not format 4, bail.
// This could happen if the font is corrupt
// It could also happen if there is a new font format we
// don't understand.
*pcbNeeded = 0;
return FALSE;
}
// Figure buffer size and tell caller if buffer to small
*pcbNeeded = Format4.length;
if (*pcbNeeded > cbSize || pBuffer == NULL)
{
// Either test indicates caller needs to know
// the buffer size and the parameters are not setup
// to continue.
return FALSE;
}
// allocate a full working buffer
pFormat4Subtable = (LPCMAP4)malloc ( Format4.length );
if ( pFormat4Subtable == NULL)
{
// Bad things happening if we can't allocate memory
*pcbNeeded = 0;
return FALSE;
}
// get the entire subtable
if (!GetFontFormat4Subtable ( hdc, pFormat4Subtable, Encoding.Offset ))
{
// Bad things happening if we can't allocate memory
*pcbNeeded = 0;
return FALSE;
}
// Copy the retrieved table into the buffer
CopyMemory( pBuffer,
pFormat4Subtable,
pFormat4Subtable->length );
free ( pFormat4Subtable );
return TRUE;
} /* end of function GetTTUnicodeCoverage */
BOOL FindFormat4Segment (
LPCMAP4 pTable, // a valid Format4 subtable buffer
USHORT ch, // Unicode character to search for
USHORT *piSeg // out: index of segment containing ch
)
/*
if the Unicode character ch is not contained in one of the
segments the function returns FALSE.
if the Unicode character ch is found in a segment, the index
of the segment is placed in*piSeg and the function returns
TRUE.
*/
{
USHORT i,
segCount = pTable->segCountX2/2;
USHORT *pendCount = GetEndCountArray((LPBYTE) pTable);
USHORT *pstartCount = GetStartCountArray((LPBYTE) pTable);
// Find segment that could contain the Unicode character code
for (i=0; i < segCount && pendCount[i] < ch; i++);
// We looked in them all, ch not there
if (i >= segCount)
return FALSE;
// character code not within the range of the segment
if (pstartCount[i] > ch)
return FALSE;
// this segment contains the character code
*piSeg = i;
return TRUE;
} /* end of function FindFormat4Segment */
USHORT GetTTUnicodeCharCount (
HDC hdc
)
/*
Returns the number of Unicode character glyphs that
are in the TrueType font that is selected into the hdc.
*/
{
LPCMAP4 pUnicodeCMapTable;
USHORT cChar;
DWORD dwSize;
// Get the Unicode CMAP table from the TT font
GetTTUnicodeCoverage( hdc, NULL, 0, &dwSize );
pUnicodeCMapTable = (LPCMAP4)malloc( dwSize );
if (!GetTTUnicodeCoverage( hdc, pUnicodeCMapTable, dwSize, &dwSize ))
{
// possibly no Unicode cmap, not a TT font selected,...
free( pUnicodeCMapTable );
return 0;
}
cChar = GetFontFormat4CharCount( pUnicodeCMapTable );
free( pUnicodeCMapTable );
return cChar;
} /* end of function GetTTUnicodeCharCount */
USHORT GetTTUnicodeGlyphIndex (
HDC hdc, // DC with a TrueType font selected
USHORT ch // Unicode character to convert to Index
)
/*
When the TrueType font contains a glyph for ch, the
function returns the glyph index for that character.
If an error occurs, or there is no glyph for ch, the
function will return the missing glyph index of zero.
*/
{
LPCMAP4 pUnicodeCMapTable;
DWORD dwSize;
USHORT iSegment;
USHORT *idRangeOffset;
USHORT *idDelta;
USHORT *startCount;
USHORT GlyphIndex = 0; // Initialize to missing glyph
// How big a buffer do we need for Unicode CMAP?
GetTTUnicodeCoverage( hdc, NULL, 0, &dwSize );
pUnicodeCMapTable = (LPCMAP4)malloc( dwSize );
if (!GetTTUnicodeCoverage( hdc, pUnicodeCMapTable, dwSize, &dwSize ))
{
// Either no Unicode cmap, or some other error occurred
// like font in DC is not TT.
free( pUnicodeCMapTable );
return 0; // return missing glyph on error
}
// Find the cmap segment that has the character code.
if (!FindFormat4Segment( pUnicodeCMapTable, ch, &iSegment ))
{
free( pUnicodeCMapTable );
return 0; // ch not in cmap, return missing glyph
}
// Get pointers to the cmap data
idRangeOffset = GetIdRangeOffsetArray( (LPBYTE) pUnicodeCMapTable );
idDelta = GetIdDeltaArray( (LPBYTE) pUnicodeCMapTable );
startCount = GetStartCountArray( (LPBYTE) pUnicodeCMapTable );
// Per TT spec, if the RangeOffset is zero,
if ( idRangeOffset[iSegment] == 0)
{
// calculate the glyph index directly
GlyphIndex = (idDelta[iSegment] + ch) % 65536;
}
else
{
// otherwise, use the glyph id array to get the index
USHORT idResult; //Intermediate id calc.
idResult = *(
idRangeOffset[iSegment]/2 +
(ch - startCount[iSegment]) +
&idRangeOffset[iSegment]
); // indexing equation from TT spec
if (idResult)
// Per TT spec, nonzero means there is a glyph
GlyphIndex = (idDelta[iSegment] + idResult) % 65536;
else
// otherwise, return the missing glyph
GlyphIndex = 0;
}
free( pUnicodeCMapTable );
return GlyphIndex;
} /* end of function GetTTUnicodeGlyphIndex */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -