📄 fstextconstructor.java
字号:
*/
int spaceIndex = characterTable[(short)' '];
glyphTable[spaceIndex].shape = new FSShape();
glyphTable[spaceIndex].advance = 250;
}
private void decodeHEAD(FSCoder coder)
{
byte[] date = new byte[8];
coder.readFixedBits(32, 16); // table version
coder.readFixedBits(32, 16); // font version
coder.readWord(4, false); // checksum adjustment
coder.readWord(4, false); // magic number
coder.readBits(1, false); // baseline at y=0
coder.readBits(1, false); // side bearing at x=0;
coder.readBits(1, false); // instructions depend on point size
coder.readBits(1, false); // force ppem to integer values
coder.readBits(1, false); // instructions may alter advance
coder.readBits(11, false);
attributes[SCALE] = coder.readWord(2, false) / 1024; // units per em
if (attributes[SCALE] == 0)
attributes[SCALE] = 1;
coder.readBytes(date); // number of seconds since midnight, Jan 01 1904
coder.readBytes(date); // number of seconds since midnight, Jan 01 1904
coder.readWord(2, true); // xMin for all glyph bounding boxes
coder.readWord(2, true); // yMin for all glyph bounding boxes
coder.readWord(2, true); // xMax for all glyph bounding boxes
coder.readWord(2, true); // yMax for all glyph bounding boxes
/*
* Next two byte define font appearance on Macs, values are
* specified in the OS/2 table
*/
isBold = coder.readBits(1, false) != 0;
isItalic = coder.readBits(1, false) != 0;
coder.readBits(14, false); //
coder.readWord(2, false);// smallest readable size in pixels
coder.readWord(2, true); // font direction hint
attributes[GLYPH_OFFSET_SIZE] = coder.readWord(2, true);
coder.readWord(2, true); // glyph data format
}
private void decodeHHEA(FSCoder coder)
{
coder.readFixedBits(32, 16); // table version
ascent = coder.readWord(2, true);
descent = coder.readWord(2, true);
leading = coder.readWord(2, true);
coder.readWord(2, false); // maximum advance in the htmx table
coder.readWord(2, true); // minimum left side bearing in the htmx table
coder.readWord(2, true); // minimum right side bearing in the htmx table
coder.readWord(2, true); // maximum extent
coder.readWord(2, true); // caret slope rise
coder.readWord(2, true); // caret slope run
coder.readWord(2, true); // caret offset
coder.readWord(2, false); // reserved
coder.readWord(2, false); // reserved
coder.readWord(2, false); // reserved
coder.readWord(2, false); // reserved
coder.readWord(2, true); // metric data format
attributes[NUMBER_OF_METRICS] = coder.readWord(2, false);
}
private void decodeOS_2(FSCoder coder)
{
byte[] panose = new byte[10];
int[] unicodeRange = new int[4];
byte[] vendor = new byte[4];
int version = coder.readWord(2, false); // version
coder.readWord(2, true); // average character width
switch (coder.readWord(2, false)) // weight class
{
case FONT_WEIGHT_BOLD: isBold = true; break;
default: break;
}
coder.readWord(2, false); // width class
coder.readWord(2, false); // embedding licence
coder.readWord(2, true); // subscript x size
coder.readWord(2, true); // subscript y size
coder.readWord(2, true); // subscript x offset
coder.readWord(2, true); // subscript y offset
coder.readWord(2, true); // superscript x size
coder.readWord(2, true); // superscript y size
coder.readWord(2, true); // superscript x offset
coder.readWord(2, true); // superscript y offset
coder.readWord(2, true); // width of strikeout stroke
coder.readWord(2, true); // strikeout stroke position
coder.readWord(2, true); // font family class
coder.readBytes(panose);
for (int i=0; i<4; i++)
unicodeRange[i] = coder.readWord(4, false);
coder.readBytes(vendor); // font vendor identification
isItalic = coder.readBits(1, false) != 0;
coder.readBits(4, false);
isBold = coder.readBits(1, false) != 0;
coder.readBits(10, false);
coder.readWord(2, false); // first unicode character code
coder.readWord(2, false); // last unicode character code
ascent = coder.readWord(2, false);
descent = coder.readWord(2, false);
leading = coder.readWord(2, false);
coder.readWord(2, false); // ascent in Windows
coder.readWord(2, false); // descent in Windows
if (version > 0)
{
coder.readWord(4, false); // code page range
coder.readWord(4, false); // code page range
if (version > 1)
{
coder.readWord(2, true); // height
coder.readWord(2, true); // Capitals height
missingGlyph = coder.readWord(2, false);
coder.readWord(2, false); // break character
coder.readWord(2, false); // maximum context
}
}
}
private void decodeNAME(FSCoder coder)
{
int format = coder.readWord(2, false);
int numberOfNameRecords = coder.readWord(2, false);
int stringTable = coder.readWord(2, false);
for (int i=0; i<numberOfNameRecords; i++)
{
int platformId = coder.readWord(2, false);
int encodingId = coder.readWord(2, false);
int languageId = coder.readWord(2, false);
int nameId = coder.readWord(2, false);
int stringLength = coder.readWord(2, false);
int stringOffset = coder.readWord(2, false);
int current = coder.getPointer();
coder.setPointer((stringTable+stringOffset) << 3);
byte[] b = new byte[stringLength];
coder.readBytes(b);
String nameEncoding = "UTF-8";
if (platformId == 0) // Unicode
{
nameEncoding = "UTF-16";
}
else if (platformId == 1) // Macintosh
{
if (encodingId == 0 && languageId == 0)
nameEncoding = "ISO8859-1";
}
else if (platformId == 3) // Microsoft
{
switch (encodingId)
{
case 1: nameEncoding = "UTF-16"; break;
case 2: nameEncoding = "SJIS"; break;
case 4: nameEncoding = "Big5"; break;
}
}
try
{
if (nameId == 1)
name = new String(b, nameEncoding);
}
catch (UnsupportedEncodingException e)
{
name = new String(b);
}
coder.setPointer(current);
}
}
private void decodeMAXP(FSCoder coder)
{
float version = coder.readFixedBits(32, 16);
numberOfGlyphs = coder.readWord(2, false);
if (version == 1.0)
{
coder.readWord(2, false); // maximum number of points in a simple glyph
coder.readWord(2, false); // maximum number of contours in a simple glyph
coder.readWord(2, false); // maximum number of points in a composite glyph
coder.readWord(2, false); // maximum number of contours in a composite glyph
coder.readWord(2, false); // maximum number of zones
coder.readWord(2, false); // maximum number of point in Z0
coder.readWord(2, false); // number of storage area locations
coder.readWord(2, false); // maximum number of FDEFs
coder.readWord(2, false); // maximum number of IDEFs
coder.readWord(2, false); // maximum stack depth
coder.readWord(2, false); // maximum byte count for glyph instructions
coder.readWord(2, false); // maximum number of components for composite glyphs
coder.readWord(2, false); // maximum level of recursion
}
}
private void decodeHMTX(FSCoder coder)
{
int i = 0;
for (i=0; i<attributes[NUMBER_OF_METRICS]; i++)
{
glyphTable[i].advance = (coder.readWord(2, false) / attributes[SCALE]);
coder.readWord(2, true); // left side bearing
}
int advance = glyphTable[i-1].advance;
for (; i<numberOfGlyphs; i++)
glyphTable[i].advance = advance;
for (; i<numberOfGlyphs; i++)
coder.readWord(2, true);
}
private void decodeCMAP(FSCoder coder)
{
int tableStart = coder.getPointer();
int version = coder.readWord(2, false);
int numberOfTables = coder.readWord(2, false);
int platformId = 0;
int encodingId = 0;
int offset = 0;
int current = 0;
int format = 0;
int length = 0;
int language = 0;
int segmentCount = 0;
int[] startCount = null;
int[] endCount = null;
int[] delta = null;
int[] range = null;
int[] rangeAdr = null;
int i = 0;
int n = 0;
for (i=0; i<numberOfTables; i++)
{
platformId = coder.readWord(2, false);
encodingId = coder.readWord(2, false);
offset = coder.readWord(4, false) << 3;
current = coder.getPointer();
if (platformId == 0) // Unicode
{
encoding = FSText.Unicode;
}
else if (platformId == 1) // Macintosh
{
switch (encodingId)
{
case 1: encoding = FSText.SJIS; break;
default: encoding = FSText.ANSI; break;
}
}
else if (platformId == 3) // Microsoft
{
switch (encodingId)
{
case 1: encoding = FSText.Unicode; break;
case 2: encoding = FSText.SJIS; break;
default: encoding = FSText.ANSI; break;
}
}
coder.setPointer(tableStart+offset);
format = coder.readWord(2, false);
length = coder.readWord(2, false);
language = coder.readWord(2, false);
switch (format)
{
case 0:
for (n=0; n<256; n++)
characterTable[n] = (short)coder.readWord(1, false);
break;
case 4:
segmentCount = coder.readWord(2, false) / 2;
coder.readWord(2, false); // search range
coder.readWord(2, false); // entry selector
coder.readWord(2, false); // range shift
startCount = new int[segmentCount];
endCount = new int[segmentCount];
delta = new int[segmentCount];
range = new int[segmentCount];
rangeAdr = new int[segmentCount];
for (n=0; n<segmentCount; n++)
endCount[n] = coder.readWord(2, false);
coder.readWord(2, false); // reserved padding
for (n=0; n<segmentCount; n++)
startCount[n] = coder.readWord(2, false);
for (n=0; n<segmentCount; n++)
delta[n] = coder.readWord(2, true);
for (n=0; n<segmentCount; n++)
{
rangeAdr[n] = coder.getPointer() >> 3;
range[n] = coder.readWord(2, true);
}
int glyphIndex = 0;
int loca
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -