?? truetype.cpp
字號(hào):
//-----------------------------------------------------------------------------------//
// Windows Graphics Programming: Win32 GDI and DirectDraw //
// ISBN 0-13-086985-6 //
// //
// Written by Yuan, Feng www.fengyuan.com //
// Copyright (c) 2000 by Hewlett-Packard Company www.hp.com //
// Published by Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com //
// //
// FileName : truetype.cpp //
// Description: Truetype font decoding //
// Version : 1.00.000, May 31, 2000 //
//-----------------------------------------------------------------------------------//
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <assert.h>
#include <tchar.h>
#include <math.h>
#include "..\..\include\win.h"
#include "..\..\include\LogWindow.h"
#include "TrueType.h"
#include "resource.h"
const char tag_cmap[] = "cmap"; // character to glyph mapping
const char tag_glyf[] = "glyf"; // glyph data
const char tag_head[] = "head"; // font header
const char tag_hhea[] = "hhea"; // horizontal header
const char tag_hmtx[] = "hmtx"; // horizontal metrics
const char tag_loca[] = "loca"; // index to location
const char tag_maxp[] = "maxp"; // maximum profile
const char tag_name[] = "name"; // naming
const char tag_post[] = "post"; // PostScript
const char tag_ttcf[] = "ttcf"; // TrueType font collection
const char tag_kern[] = "kern"; // Kerning table
void KTrueType::Release(void)
{
if ( m_pFontData )
{
delete [] (BYTE *) m_pFontData;
m_pFontData = NULL;
}
}
const BYTE * KTrueType::GetTable(const char * tag) const
{
int no = GetTableNo();
for (int i=0; i<no; i++)
if ( memcmp(m_pFontData->entries[i].tag, tag, 4)==0 )
return GetTable(i);
return NULL;
}
const GlyphHeader * KTrueType::GetGlyph(int index) const
{
if ( (index<0) || (index>=m_nNumGlyphs) )
return NULL;
if ( m_pGlyphTable==NULL )
return NULL;
if ( m_pShortGlyphIndex )
return (const GlyphHeader *) ( m_pGlyphTable + reverse(m_pShortGlyphIndex[index]) * 2);
if ( m_pLongGlyphIndex )
return (const GlyphHeader *) ( m_pGlyphTable + reverse(m_pLongGlyphIndex[index]) );
return NULL;
}
///////////////////////////////////////////////////////
// h e a d T A B L E //
///////////////////////////////////////////////////////
typedef struct
{
Fixed Table; // version number 0x00010000 for version 1.0.
Fixed fontRevision; // Set by font manufacturer.
ULONG checkSumAdjustment; // To compute: set it to 0, sum the entire font as ULONG, then store 0xB1B0AFBA - sum.
ULONG magicNumber; // Set to 0x5F0F3CF5.
USHORT flags; // Bit 0 - baseline for font at y=0;
// Bit 1 - left sidebearing at x=0;
// Bit 2 - instructions may depend on point size;
// Bit 3 - force ppem to integer values for all internal scaler math; may use fractional ppem sizes if this bit is clear;
// Bit 4 - instructions may alter advance width (the advance widths might not scale linearly);
// Bits 5-10 - defined by Apple;
// Bit 11 - font compressed with Agfa MicroType Compression.
// Note: All other bits must be zero.
USHORT unitsPerEm; // Valid range is from 16 to 16384
longDT created; // International date (8-byte field).
longDT modified; // International date (8-byte field).
FWord xMin; // For all glyph bounding boxes.
FWord yMin; // For all glyph bounding boxes.
FWord xMax; // For all glyph bounding boxes.
FWord yMax; // For all glyph bounding boxes.
USHORT macStyle; // Bit 0 bold (if set to 1); Bit 1 italic (if set to 1)
// Bits 2-15 reserved (set to 0).
USHORT lowestRecPPEM; // Smallest readable size in pixels.
SHORT fontDirectionHint; // 0 Fully mixed directional glyphs;
// 1 Only strongly left to right;
// 2 Like 1 but also contains neutrals;
// -1 Only strongly right to left;
// -2 Like -1 but also contains neutrals.
SHORT indexToLocFormat; // 0 for short offsets, 1 for long.
SHORT glyphDataFormat; // 0 for current format.
} Table_head;
///////////////////////////////////////////////////////
// m a x p T A B L E //
///////////////////////////////////////////////////////
typedef struct
{
Fixed Version; // 0x00010000 for version 1.0.
USHORT numGlyphs; // The number of glyphs in the font.
USHORT maxPoints; // Maximum points in a non-composite glyph.
USHORT maxContours; // Maximum contours in a non-composite glyph.
USHORT maxCompositePoints; // Maximum points in a composite glyph.
USHORT maxCompositeContours; // Maximum contours in a composite glyph.
USHORT maxZones; // 1 if instructions do not use the twilight zone (Z0),
// or 2 if instructions do use Z0; should be set to 2 in most cases.
USHORT maxTwilightPoints; // Maximum points used in Z0.
USHORT maxStorage; // Number of Storage Area locations.
USHORT maxFunctionDefs; // Number of FDEFs.
USHORT maxInstructionDefs; // Number of IDEFs.
USHORT maxStackElements; // Maximum stack depth2.
USHORT maxSizeOfInstructions; // Maximum byte count for glyph instructions.
USHORT maxComponentElements; // Maximum number of components referenced at "top level" for any composite glyph.
USHORT maxComponentDepth; // Maximum levels of recursion; 1 for simple components.
} Table_maxp;
/////////////////////////////////////
// CMAP //
/////////////////////////////////////
typedef struct
{
USHORT Platform; // platform ID
USHORT EncodingID; // encoding ID
ULONG TableOffset; // offset to encoding table
} submap;
typedef struct
{
USHORT TableVersion; // table version 0
USHORT NumSubTable; // number of encoding tables
submap TableHead[1]; // heads for encoding tables
} Table_cmap;
typedef struct
{
USHORT format; // format: 0, 2, 4, 6
USHORT length; // size
USHORT version; // version
BYTE map[1]; // mapping data
} Table_Encode;
//////////////////////////////////////
// HHEA Horizontal Header
//////////////////////////////////////
typedef struct
{
Fixed version; // 0x00010000 for version 1.0.
FWord Ascender; // Typographic ascent.
FWord Descender; // Typographic descent.
FWord LineGap; // Typographic line gap.
FWord advanceWidthMax; // Maximum advance width value in 'hmtx' table.
FWord minLeftSideBearing; // Minimum left sidebearing value in 'hmtx' table.
FWord minRightSideBearing; // Minimum right sidebearing value; calculated as Min(aw - lsb - (xMax - xMin)).
FWord xMaxExtent; // Max(lsb + (xMax - xMin)).
SHORT caretSlopeRise; // Used to calculate the slope of the cursor (rise/run); 1 for vertical.
SHORT caretSlopeRun; // 0 for vertical.
SHORT reserved[5]; // set to 0
SHORT metricDataFormat; // 0 for current format.
USHORT numberOfHMetrics; // Number of hMetric entries in 'hmtx' table;
// must be equal to the CharStrings INDEX count in the 'CFF ' table.
} Table_HoriHeader;
//////////////////////////////////////
// KERN Kerning Table
//////////////////////////////////////
typedef struct
{
FWord leftglyph;
FWord rightglyph;
FWord move;
} KerningPair;
typedef struct
{
FWord Version;
FWord nSubTables;
FWord SubTableVersion;
FWord Bytesinsubtable;
FWord Coveragebits;
FWord Numberpairs;
FWord SearchRange;
FWord EntrySelector;
FWord RangeShift;
KerningPair KerningPair[1]; // variable size
} Table_Kerning;
////////////////////////////////////
typedef struct
{
USHORT version; // 0x0001
SHORT xAvgCharWidth; // weighted average width of a..z
USHORT usWeightClass; // FW_THIN..FW_BLACK
USHORT usWidthClass; // FWIDTH_ULTRA_CONDENSED..FWIDTH_ULTRA_EXPANDED
SHORT fsType; // embedding licensing rights
SHORT ySubscriptXSize;
SHORT ySubscriptYSize;
SHORT ySubscriptXOffset;
SHORT ySubscriptYOffset;
SHORT ySuperscriptXSize;
SHORT ySuperscriptYSize;
SHORT ySuperscriptXOffset;
SHORT ySuperscriptYOffset;
SHORT yStrikeoutSize; // strikeout stroke width in design units.
SHORT yStrikeoutPosition;
SHORT sFamilyClass; // IBM font class
PANOSE panose;
ULONG ulUnicodeRange1; // Bits 0-31 Unicode Character Range
ULONG ulUnicodeRange2; // Bits 32-63
ULONG ulUnicodeRange3; // Bits 64-95
ULONG ulUnicodeRange4; // Bits 96-127
CHAR achVendID[4]; // vendor ID
USHORT fsSelection; // ITALIC UNDERSCORE NEGATIVE OUTLINE STRIKEOUT BOLD REGULAR
USHORT usFirstCharIndex; // first UNICODE char
USHORT usLastCharIndex; // last UNICODE char
USHORT sTypoAscender; // typographic ascender
USHORT sTypoDescender; // typographic ascender
USHORT sTypoLineGap; // typographic line gap
USHORT usWinAscent; // ascender metric for Windows
USHORT usWinDescent; // descender metric for Windows
ULONG ulCodePageRange1; // Bits 0-31
ULONG ulCodePageRange2; // Bits 32-63
} Table_OS2;
/////////////////////////////////////
TableDirectory * GetTrueTypeFont(HDC hDC)
{
// read font size
DWORD FontSize = GetFontData(hDC, 0, 0, NULL, 0);
TableDirectory * pFont = (TableDirectory *) new BYTE[FontSize];
if ( pFont==NULL )
return NULL;
GetFontData(hDC, 0, 0, pFont, FontSize);
return pFont;
}
BOOL KTrueType::Load(LOGFONT & logfont)
{
HFONT hFont = CreateFontIndirect(& logfont);
HDC hDC = GetDC(NULL);
HGDIOBJ hOld = SelectObject(hDC, hFont);
Release();
// read font collection size
DWORD FCsize = GetFontData(hDC, * (DWORD *) tag_ttcf, 0, NULL, 0);
// read font size
m_nFontSize = GetFontData(hDC, NULL, 0, NULL, 0);
if ( (m_nFontSize==0) || (m_nFontSize==0xFFFFFFFF) )
return FALSE;
if ( (FCsize==0) || (FCsize==0xFFFFFFFF) ) // not a font collecton
m_nBias = 0;
else // is font collection, calculate bias
m_nBias = m_nFontSize - FCsize;
m_pFontData = (TableDirectory *) new BYTE[m_nFontSize];
GetFontData(hDC, NULL, 0, m_pFontData, m_nFontSize);
SelectObject(hDC, hOld);
ReleaseDC(NULL, hDC);
DeleteObject(hFont);
const Table_maxp * pmaxp = (const Table_maxp *) GetTable(tag_maxp);
if ( pmaxp )
m_nNumGlyphs = reverse(pmaxp->numGlyphs);
const Table_head * phead = (const Table_head *) GetTable(tag_head);
if ( phead->indexToLocFormat )
m_pLongGlyphIndex = (const DWORD *) GetTable(tag_loca);
else
m_pShortGlyphIndex = (const WORD *) GetTable(tag_loca);
m_pGlyphTable = GetTable(tag_glyf);
m_unitsPerEm = reverse(phead->unitsPerEm);
{
const Table_HoriHeader * phhea = (const Table_HoriHeader *) GetTable(tag_hhea);
m_Ascender = (short) reverse((WORD) phhea->Ascender);
m_Descender = (short) reverse((WORD) phhea->Descender);
m_LineGap = (short) reverse((WORD) phhea->LineGap);
m_numberOfHMetrics = (short) reverse((WORD) phhea->numberOfHMetrics);
SetHTMX(GetTable(tag_hmtx));
}
{
const Table_Kerning * pKern = (const Table_Kerning *) GetTable(tag_kern);
int i = 0;
}
return TRUE;
}
///////////////////////////////////////////////////////
// g l y p T A B L E //
///////////////////////////////////////////////////////
// Simple Glyph
// USHORT endPtsOfContours[n]; // Array of last points of each contour; n is the number of contours.
// USHORT instructionLength; // Total number of bytes for instructions.
// BYTE instructions[n]; // Array of instructions for each glyph; n is the number of instructions.
// BYTE flags[n]; // Array of flags for each coordinate in outline; n is the number of flags.
// BYTE or SHORT xCoordinates[ ] First coordinates relative to (0,0); others are relative to previous point.
// BYTE or SHORT yCoordinates[ ] First coordinates relative to (0,0); others are relative to previous point.
typedef enum
{
G_ONCURVE = 0x01, // on curve, off curve
G_REPEAT = 0x08, // next byte is flag repeat count
G_XMASK = 0x12,
G_XADDBYTE = 0x12, // X is positive byte
G_XSUBBYTE = 0x02, // X is negative byte
G_XSAME = 0x10, // X is same
G_XADDINT = 0x00, // X is signed word
G_YMASK = 0x24,
G_YADDBYTE = 0x24, // Y is positive byte
G_YSUBBYTE = 0x04, // Y is negative byte
G_YSAME = 0x20, // Y is same
G_YADDINT = 0x00, // Y is signed word
};
// Simple Glyph
// USHORT endPtsOfContours[n]; // Array of last points of each contour; n is the number of contours.
// USHORT instructionLength; // Total number of bytes for instructions.
// BYTE instructions[n]; // Array of instructions for each glyph; n is the number of instructions.
// BYTE flags[n]; // Array of flags for each coordinate in outline; n is the number of flags.
// BYTE or SHORT xCoordinates[ ] First coordinates relative to (0,0); others are relative to previous point.
// BYTE or SHORT yCoordinates[ ] First coordinates relative to (0,0); others are relative to previous point.
void Mark(HDC hDC, int x, int y, COLORREF cr)
{
SetPixel(hDC, x, y, cr);
SetPixel(hDC, x-2, y-1, cr);
SetPixel(hDC, x-2, y, cr);
SetPixel(hDC, x-2, y+1, cr);
SetPixel(hDC, x+2, y-1, cr);
SetPixel(hDC, x+2, y, cr);
SetPixel(hDC, x+2, y+1, cr);
SetPixel(hDC, x-1, y-2, cr);
SetPixel(hDC, x, y-2, cr);
SetPixel(hDC, x+1, y-2, cr);
SetPixel(hDC, x-1, y+2, cr);
SetPixel(hDC, x, y+2, cr);
SetPixel(hDC, x+1, y+2, cr);
}
// draw a 2nd degree Bezier curve segment
BOOL Bezier(HDC hDC, int & x0, int & y0, int x1, int y1, int x2, int y2)
{
// p0 p1 p2 -> p0 (p0+2p1)/3 (2p1+p2)/3, p2
POINT P[3] = { { (x0+2*x1)/3, (y0+2*y1)/3 }, { (2*x1+x2)/3, (2*y1+y2)/3 }, { x2, y2 } };
x0 = x2; y0 = y2;
return PolyBezierTo(hDC, P, 3);
}
class KScale
{
int _x;
int _y;
double _scale;
public:
KScale(int x, int y, double scale)
{
_x = x;
_y = y;
_scale = scale;
}
void Map(POINT & p)
{
p.x = (int) (_x + p.x * _scale);
p.y = (int) (_y - p.y * _scale);
}
void Line(HDC hDC, int x0, int y0, int x1, int y1)
{
MoveToEx(hDC, (int) (_x + x0 * _scale), (int) (_y - y0 * _scale), NULL);
LineTo (hDC, (int) (_x + x1 * _scale), (int) (_y - y1 * _scale));
}
};
class KCurve
{
typedef enum { MAX_POINTS = 1024 };
POINT m_Point[MAX_POINTS];
BYTE m_Flag [MAX_POINTS];
RECT m_bound;
int m_len;
int m_open;
public:
int m_glyphsize;
int m_instrsize;
int m_glyphindex;
int m_Ascender;
int m_Descender;
int m_LineGap;
int m_advancewidth;
int m_lsb;
typedef enum { FLAG_ON=1, FLAG_OPEN=2, FLAG_EXTRA=4 };
void SetBound(signed short x0, signed short y0, signed short x1, signed short y1)
{
m_bound.left = x0;
m_bound.top = y0;
m_bound.right = x1;
m_bound.bottom = y1;
}
void Reset(void)
{
m_len = 0;
m_open = 0;
}
void Append(int x, int y, BYTE flag)
{
m_Point[m_len].x = x;
m_Point[m_len].y = y;
if ( m_open==m_len )
flag |= FLAG_OPEN;
m_Flag[m_len] = flag;
assert(m_len<= MAX_POINTS);
m_len ++;
}
void Add(int x, int y, BYTE flag)
{
if ( m_len && ( (flag & FLAG_ON)==0 ) && ( (m_Flag[m_len-1] & FLAG_ON)==0 ) )
{
Append((m_Point[m_len-1].x+x)/2, (m_Point[m_len-1].y+y)/2, FLAG_ON | FLAG_EXTRA); // add a middle point
}
Append(x, y, flag);
}
void Close(void)
{
Append(m_Point[m_open].x, m_Point[m_open].y, FLAG_ON | FLAG_EXTRA);
m_open = m_len;
}
int GetLength(void) const
{
return m_len;
}
BOOL Draw(HDC hDC, int x, int y, double scale, int mark, int emsquare)
{
KScale sc(x, y, scale);
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -