📄 cmap.htm
字号:
element corresponding to firstCode appears.
<P>
Finally, if the value obtained from the subarray is not 0 (which
indicates the missing glyph), you should add idDelta to it in
order to get the glyphIndex. The value idDelta permits the same
subarray to be used for several different subheaders. The idDelta
arithmetic is modulo 65536.
<P><BR><H4>Format 4: Segment mapping to delta
values</H4>
<P>
This is the Microsoft standard character to
glyph index mapping table.
<P>
This format is used when the character codes for the characters
represented by a font fall into several contiguous ranges, possibly
with holes in some or all of the ranges (that is, some of the
codes in a range may not have a representation in the font). The
format-dependent data is divided into three parts, which must
occur in the following order:
<OL>
<LI>A four-word header gives parameters
for an optimized search of the segment list;
<LI>Four parallel arrays describe the segments (one segment
for each contiguous range of codes);
<LI>A variable-length array of glyph IDs (unsigned words).
</OL>
<TABLE BGCOLOR="F0F0F0" WIDTH=480>
<THEAD>
<TR>
<TH BGCOLOR="#C0C0C0">Type</TH>
<TH BGCOLOR="#C0C0C0">Name</TH><TH BGCOLOR="#C0C0C0">Description</TH></TR>
</THEAD><TBODY>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>format</TD>
<TD VALIGN=TOP>Format number is set to 4. </TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>length</TD>
<TD VALIGN=TOP>Length in bytes. </TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>version</TD>
<TD VALIGN=TOP>Version number (starts at 0).</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>segCountX2 </TD>
<TD VALIGN=TOP>2 x segCount.</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>searchRange </TD>
<TD VALIGN=TOP>2 x (2**floor(log2(segCount)))</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>entrySelector </TD>
<TD VALIGN=TOP>log2(searchRange/2)</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>rangeShift </TD>
<TD VALIGN=TOP>2 x segCount - searchRange</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>endCount[segCount]</TD>
<TD VALIGN=TOP>End characterCode for each segment,
<BR>
last =0xFFFF.</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>reservedPad</TD>
<TD VALIGN=TOP>Set to 0.</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>startCount[segCount]</TD>
<TD VALIGN=TOP>Start character code for each segment.</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>idDelta[segCount]</TD>
<TD VALIGN=TOP>Delta for all character codes in segment.</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>idRangeOffset[segCount]</TD>
<TD VALIGN=TOP>Offsets into glyphIdArray or 0</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>glyphIdArray[ ]</TD>
<TD VALIGN=TOP>Glyph index array (arbitrary length)</TD></TR>
</TABLE>
<P>
The number of segments is specified by segCount,
which is not explicitly in the header; however, all of the header
parameters are derived from it. The searchRange value is twice
the largest power of 2 that is less than or equal to segCount.
For example, if segCount=39, we have the following:
<TABLE WIDTH=480>
<TR>
<TD>segCountX2</TD><TD>78</TD></TR>
<TR>
<TD>searchRange</TD><TD>64</TD><TD>(2 * largest power of 2 <=39)</TD></TR>
<TR>
<TD>entrySelector</TD><TD>5</TD><TD>log<SUB>2</SUB> (32)</TD></TR>
<TR>
<TD>rangeShift</TD><TD>14</TD><TD>2 x 39 - 64</TD></TR>
</TABLE>
<P>
Each segment is described by a startCode and
endCode, along with an idDelta and an idRangeOffset, which are
used for mapping the character codes in the segment. The segments
are sorted in order of increasing endCode values, and the segment
values are specified in four parallel arrays. You search for the
first endCode that is greater than or equal to the character code
you want to map. If the corresponding startCode is less than or
equal to the character code, then you use the corresponding idDelta
and idRangeOffset to map the character code to a glyph index (otherwise,
the missingGlyph is returned). For the search to terminate, the
final endCode value must be 0xFFFF. This segment need not contain
any valid mappings. (It can just map the single character code
0xFFFF to missingGlyph). However, the segment must be present.
<P>
If the idRangeOffset value for the segment is not 0, the mapping
of character codes relies on glyphIdArray. The character code
offset from startCode is added to the idRangeOffset value. This
sum is used as an offset from the current location within idRangeOffset
itself to index out the correct glyphIdArray value. This obscure
indexing trick works because glyphIdArray immediately follows
idRangeOffset in the font file. The C expression that yields the
glyph index is:
<BR><TT>
*(idRangeOffset[i]/2 + (c - startCount[i]) + &idRangeOffset[i])
</TT>
<P>
The value <CITE>c</CITE> is the character code
in question, and <CITE>i</CITE> is the segment index in which <CITE>c</CITE>
appears. If the value obtained from the indexing operation is
not 0 (which indicates missingGlyph), idDelta[i] is added to it
to get the glyph index. The idDelta arithmetic is modulo 65536.
<P>
If the idRangeOffset is 0, the idDelta value is added directly
to the character code offset (i.e. <TT>idDelta[i]
+ c</TT>) to get the corresponding
glyph index. Again, the idDelta arithmetic is modulo 65536.
<P>
As an example, the variant part of the table to map characters
10-20, 30-90, and 480-153 onto a contiguous range of glyph indices
may look like this:
<P>
<TABLE width=480>
<tr>
<TD>segCountX2:</TD><TD>8</TD></TR>
<TR>
<TD>searchRange:</TD><TD>8</TD></TR>
<TR>
<TD>entrySelector:</TD><TD>4</TD></TR>
<TR>
<TD>rangeShift:</TD><TD>0</TD></TR>
<TR>
<TD>endCode:</TD><TD>20</TD><TD>90</TD><TD>153</TD><TD>0Xffff</TD></TR>
<TR>
<TD>reservedPad:</TD><TD>0</TD></TR>
<TR>
<TD>startCode:</TD><TD>10</TD><TD>30</TD><TD>480</TD><TD>0Xffff</TD></TR>
<TR>
<TD>idDelta:</TD><TD>-9</TD><TD>-18</TD><TD>-27</TD><TD>1</TD></TR>
<TR>
<TD>idRangeOffset:</TD><TD>0</TD><TD>0</TD><TD>0</TD><TD>0</TD></TR>
</TABLE>
<P>
This table performs the following mappings:<BR>
<P>10 -> 10 - 9 = 1<BR>
20 -> 20 - 9 = 11<BR>
30 -> 30 - 18 = 12<BR>
90 -> 90 - 18 = 72<BR>
...and so on.
<P>
Note that the delta values could be reworked
so as to reorder the segments.
<P><BR>
<P>
<BR> <BR><FONT SIZE=5>Format 6: Trimmed table mapping</FONT>
<TABLE BGCOLOR="#F0F0F0" WIDTH=480>
<THEAD>
<TR>
<TH BGCOLOR="#C0C0C0">Type</TH>
<TH BGCOLOR="#C0C0C0">Name</TH>
<TH BGCOLOR="#C0C0C0">Description</TH></TR>
</THEAD><TBODY>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>format</TD>
<TD VALIGN=TOP>Format number is set to 6.</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>length</TD>
<TD VALIGN=TOP>Length in bytes. </TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>version</TD>
<TD VALIGN=TOP>Version number (starts at 0)</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>firstCode</TD>
<TD VALIGN=TOP>First character code of subrange.</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>entryCount</TD>
<TD VALIGN=TOP>Number of character codes in subrange.</TD></TR>
<TR>
<TD VALIGN=TOP>USHORT</TD><TD VALIGN=TOP>glyphIdArray [entryCount]</TD>
<TD VALIGN=TOP>Array of glyph index values for character codes in the range.</TD></TR>
</TABLE>
<P>
The firstCode and entryCount values specify
a subrange (beginning at firstCode,length = entryCount) within
the range of possible character codes. Codes outside of this subrange
are mapped to glyph index 0. The offset of the code (from the
first code) within this subrange is used as index to the glyphIdArray,
which provides the glyph index value.
<br> <br>
<FONT FACE="Arial, Helvetica" SIZE=1>
Microsoft Typography Web Site <A HREF="/truetype/otspec/CPYRIGHT.htm">© 1996 Microsoft Corporation</A>
<BR>
Comments to the Microsoft Typography group: <A HREF="mailto:ttwsite@microsoft.com">ttwsite@microsoft.com</A>
<BR>
<A HREF="/truetype/default.htm">Home</a> | <a href="/truetype/creators.htm"> Information for Developers</a>
<BR>
Last updated 05 September 1996
</FONT>
</TD></TR>
</TABLE>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -