关于TrueType字体结构的文章
来源:互联网 发布:淘宝百度网盘会员 编辑:程序博客网 时间:2024/05/21 09:52
http://www.zhaozi.cn/e/DoPrint/?classid=94&id=45
typedef sturct{char tag[4];ULONG checkSum;ULONG offset;ULONG length;}TableEntry;typedef struct{Fixed sfntversion; //0x10000 for version 1.0USHORT numTables;USHORT searchRange;USHORT entrySelector;USHORT rangeShift;TableEntry entries[1];//variable number of TableEntry}TableDirectory;
head 字体头 字体的全局信息
cmap 字符代码到图元的映射 把字符代码映射为图元索引
glyf 图元数据 图元轮廓定义以及网格调整指令
maxp 最大需求表 字体中所需内存分配情况的汇总数据
mmtx 水平规格 图元水平规格
loca 位置表索引 把元索引转换为图元的位置
name 命名表 版权说明、字体名、字体族名、风格名等等
hmtx 水平布局 字体水平布局星系:上高、下高、行间距、最大前进宽度、最小左支撑、最小右支撑
kerm 字距调整表 字距调整对的数组
post PostScript信息 所有图元的PostScript FontInfo目录项和PostScript名
PCLT PCL 5数据 HP PCL 5Printer Language 的字体信息:字体数、宽度、x高度、风格、记号集等等
OS/2 OS/2和Windows特有的规格 TrueType字体所需的规格集
DWORD GetFontData(HDC hDC,DWORD dwTable ,DWORD dwOffset, LPVOID lpbBuffer ,DWORD cbData);
TableDirctory * GetTrueTypeFont (HDC hDC ,DWORD &nFontSize){//query font sizenFontSize=GetFontData(hDC,0,0,NULL,0);TableDirectory * pFont =(TableDirectory *)new BYTE(nFontSize);if (pFont==NULL)return NULL;GetFontData(hDC,0,0,pFont,nFontSize);return pFont;}
1.字体头
typedef sturct{Fixed Table;//x00010000 ro version 1.0Fixed fontRevision;//Set by font manufacturer.ULONG checkSumAdjustment;ULONG magicNumer; //Set to 0x5f0f3cf5USHORT flags;USHORT unitsPerEm; //Valid range is from 16 to 16384longDT 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 xMax; //For all glyph bounding boxes.USHORT macStyle;USHORT lowestRecPPEM; //Smallest readable size in pixels.SHORT fontDirctionHint;SHORT indexToLocFormat; //0 for short offsets ,1 for long.SHORT glyphDataFormat; //0 for current format.}Table_head;
最大需求表
typedef struct{Fixed Version;//0x00010000 for version 1.0.USHORT numGlypha; //Number of glyphs in the font .USHORT maxPoints; //Max points in noncomposite glyph .RSHORT maxContours; //Max contours in noncomposite glyph.USHORT maxCompositePoints;//Max points in a composite glyph.USHORT maxCompositeContours; //Max contours in a composite glyph.USHORT maxZones;// 1 if not use the twilight zone [Z0],//or 2 if so use Z0;2 in most cases.USHORT max TwilightPoints ;/ Maximum points used in Z0.USHORT maxStorage; //Number of storage area locations.USHORT maxFunctionDefs; //Number of FDEFs.USHORT maxStackElements; //Number of depth.USHORT maxSizeOfInstructions; //Max byte count for glyph inst.USHORT maxComponentElements; //Max number top components refernced.USHORT maxComponentDepth; //Max levels of recursion.}Table_maxp;
下面是cmap表的结构。
typedef struct
{
USHORT Platform; //platform ID
USHORT EncodingID; //encoding ID
ULONG TableOffset ;//offset to encoding table
typedef struct {
WCHAR wcLow;
USHORT cGlyphs;
}
typedef struct
{
DWORD cbThis; //sizeof (GLYPHSET)+sizeof(WCRANGE)+(cRanges-1)
DWORD flAccel;
DWORD cGlyphsSupported;
DWORD cRanges;
WCRANGE ranges[1]; //ranges[cRanges]
}GLYPHSET;
DWORD GetFontUnicodeRanges(HDC hDC,LPGLYPHSET lpgs);
DWORD GetGlyphIndices(HDC hDC,LPCTSTR lpstr,int c ,LPWORD pgi,DWORD fl);
下面是用于查询上下文中当前字体GLYPHSET结构的一个简单函数。
GLYPHSET *QueryUnicodeRanges(HDC hDC){//query for sizeDWORD size=GetFontUnicodeRanges(hDC,NULL);if (size==0) return NULL;GLYPHSET *pGlyphSet=(GLYPHSET *)new BYTE(size);//get real datapGlyphSet->cbThis=size;size=GetFontUnicodeRanges(hDC,pGlyphSet);return pGlyphSet;}
2.位置索引
位置索引表中保存了n+1个图元数据表的索引,其中n是保存在最大需求表中的图元数量。最后一个额外的偏移量并不指向一个新图元,而是指向最后一个图元的偏移量和当前图元的偏移量和当前图元的偏移量间的差值得到图元的长度。
3.图元数据
typedef struct{WORD numberOfContours; //contor number,negative if compositeFWord xMin; //Minimum x for coordinate data.FWord yMin; //Minimum y for coordinate data.FWord xMax; //Maximum x for coordinate data.FWord yMax; //Maximum y for coordinate data.}GlyphHeader;
USHORT endPtsOfContours[n]; //n=number of contoursUSHORT instructionlength;BYTE instruction[i]; //i = instruction lengthBYTE flags[]; //variable sizeBYTE xCoordinates[]; //variable sizeBYTE yCoordinates[]; //variable size
我们提到棕em-square被限制为最大为16384个网格,因此通常情况下需要各两个字节来表示x坐标和y坐标。为了节省空间,图元中保存的是相对坐标。第一个点的坐标是相对(0,0)记录的,所有随后的点记录者是和上一个点的坐标差值。有些差值可以用一个字节表示,有些差值为0,另外一些差值则无法用耽搁字节表示。标志数组保存了每个坐标的编码信息以及其他一些信息。下面是标志中各个位的含义的总结:
typedef enum{G_ONCURVE = 0x01, // on curve ,off curveG_REPEAT =0x08, //next byte is flag repeat countG_XMASK =0x12,G_XADDBYTE =0x12, //X is positive byteG_XSUBBYTE =0x12, //X is negative byteG_XSAME =0x10, //X is sameG_XADDINT =0x00, //X is signed wordG_YMASK =0x24,G_YADDBYTE =0x24, //Y is positive byteG_YSUBBYTE =0x04, //Y is negative byteG_YSAME =0x20 , //Y is sameG_YADDINT =0x00, //Y is signed word};
int KTrueType::DecodeGlyph(int index, KCurve & curve, XFORM * xm) const{const GlyphHeader * pHeader = GetGlyph(index);if ( pHeader==NULL ){// assert(false);return 0;}int nContour = (short) reverse(pHeader->numberOfContours);if ( nContour<0 ){return DecodeCompositeGlyph(pHeader+1, curve); // after the header}if ( nContour==0 )return 0;curve.SetBound(reverse((WORD)pHeader->xMin), reverse((WORD)pHeader->yMin),reverse((WORD)pHeader->xMax), reverse((WORD)pHeader->yMax));const USHORT * pEndPoint = (const USHORT *) (pHeader+1);int nPoints = reverse(pEndPoint[nContour-1]) + 1; // endpoint of last contour + 1int nInst = reverse(pEndPoint[nContour]); // instructon lengthcurve.m_glyphindex = index;curve.m_glyphsize = (int) GetGlyph(index+1) - (int) GetGlyph(index);curve.m_Ascender = m_Ascender;curve.m_Descender = m_Descender;curve.m_LineGap = m_LineGap;GetMetrics(index, curve.m_advancewidth, curve.m_lsb);if ( curve.m_glyphsize==0 )return 0;curve.m_instrsize = nInst;const BYTE * pFlag = (const BYTE *) & pEndPoint[nContour] + 2 + nInst; // first byte in flagconst BYTE * pX = pFlag;int xlen = 0;for (int i=0; i<nPoints; i++, pX++){int unit = 0;switch ( pX[0] & G_XMASK ){case G_XADDBYTE:case G_XSUBBYTE:unit = 1;break;case G_XADDINT:unit = 2;}if ( pX[0] & G_REPEAT ){xlen += unit * (pX[1]+1);i += pX[1];pX ++;}elsexlen += unit;}const BYTE * pY = pX + xlen;int x = 0;}
int KTrueType::DecodeCompositeGlyph(const void * pGlyph, KCurve & curve) const{KDataStream str(pGlyph);unsigned flags;int len = 0;do{flags = str.GetWord();unsigned glyphIndex = str.GetWord();// Argument1 and argument2 can be either x and y offsets to be added to the glyph or two point numbers.// In the latter case, the first point number indicates the point that is to be matched to the new glyph.// The second number indicates the new glyph's "matched" point. Once a glyph is added, its point numbers// begin directly after the last glyphs (endpoint of first glyph + 1).// When arguments 1 and 2 are an x and a y offset instead of points and the bit ROUND_XY_TO_GRID is set to 1,// the values are rounded to those of the closest grid lines before they are added to the glyph.// X and Y offsets are described in FUnits.signed short argument1;signed short argument2;if ( flags & ARG_1_AND_2_ARE_WORDS ){argument1 = str.GetWord(); // (SHORT or FWord) argument1;argument2 = str.GetWord(); // (SHORT or FWord) argument2;}else{argument1 = (signed char) str.GetByte();argument2 = (signed char) str.GetByte();}signed short xscale, yscale, scale01, scale10;xscale = 1;yscale = 1;scale01 = 0;scale10 = 0;if ( flags & WE_HAVE_A_SCALE ){xscale = str.GetWord();yscale = xscale; // Format 2.14}else if ( flags & WE_HAVE_AN_X_AND_Y_SCALE ){xscale = str.GetWord();yscale = str.GetWord();}else if ( flags & WE_HAVE_A_TWO_BY_TWO ){xscale = str.GetWord();scale01 = str.GetWord();scale10 = str.GetWord();yscale = str.GetWord();}if ( flags & ARGS_ARE_XY_VALUES ){XFORM xm;xm.eDx = (float) argument1;xm.eDy = (float) argument2;xm.eM11 = xscale / (float) 16384.0;xm.eM12 = scale01 / (float) 16384.0;xm.eM21 = scale10 / (float) 16384.0;xm.eM22 = yscale / (float) 16384.0;len += DecodeGlyph(glyphIndex, curve, & xm);}elseassert(false);}while ( flags & MORE_COMPONENTS );if ( flags & WE_HAVE_INSTRUCTIONS ){unsigned numInstr = str.GetWord();for (unsigned i=0; i<numInstr; i++)str.GetByte();}// The purpose of USE_MY_METRICS is to force the lsb and rsb to take on a desired value.// For example, an i-circumflex (Unicode 00ef) is often composed of the circumflex and a dotless-i.// In order to force the composite to have the same metrics as the dotless-i,// set USE_MY_METRICS for the dotless-i component of the composite. Without this bit,// the rsb and lsb would be calculated from the HMTX entry for the composite (or would need to be// explicitly set with TrueType instructions).// Note that the behavior of the USE_MY_METRICS operation is undefined for rotated composite components.return len;}
//draw a 2nd-degree Bezier curve segmentBOOL Bezier2(HDC hDC,int & x0,int & y0, int x1, int y1, int x2 ,int y2){// p0 p1 p2 - > p0 (p0 + 2p1)/3 (2p1+p2)/3, p2POINT 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);}
对于用三个控制点(p0,p1,p2)定义的二阶Bezier曲线,相应的三阶Bezier曲线的控制点为(p0,(p0+2*p1)/3,(2*p1+p2)/3,p2)。
4.图元指令
控制图元中关键位置的尺寸
保持对称性和衬线等 重要的图元设计细节。
- 关于TrueType字体结构的文章
- 关于TrueType字体结构的文章
- 关于TrueType字体结构的文章
- 关于TrueType字体
- 有关TrueType字体的
- 关于制作TrueType字体(1)
- TrueType字体的后缀名解释
- TrueType字体
- 获得TrueType字体文件 的相关信息
- TrueType和Bitmap字体的区别
- 获取truetype字体数据
- TrueType字体文件
- TrueType字体文件解析
- 获取TrueType字体信息
- FreeType2的简单使用:平台无关的TrueType字体显示。
- FreeType2的简单使用:平台无关的TrueType字体显示。
- 在Debian下安装windows的中文TrueType字体
- mapx 创建使用truetype字体的符号样式。
- 实践 windows2003 IIS + PHP + MS SQL
- 跟着示例学Oozie
- Caused by: java.lang.NullPointerException
- java 定时器 quartz的使用
- 驱动技巧:解决安装驱动缺少.NET Framework 4.5的问题
- 关于TrueType字体结构的文章
- Java Map遍历方式的选择
- Java客户端与服务器端的超简易通讯4
- IOS高级开发~开机启动&无限后台运行&监听进程
- web工程的路径兼容问题
- 10个帮程序员和站长减压放松的良心网站!
- 如何处理图片
- 设计模式(Design Patterns)
- 细说Android事件传递机制(dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent)