mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-31 08:06:39 +00:00
gnujpdf:
- adding custom ttf font - print transparent text - set raw transformation matrix
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
build.xml.data.CRC32=fb275268
|
||||
build.xml.script.CRC32=7438dbfb
|
||||
build.xml.stylesheet.CRC32=8064a381@1.74.2.48
|
||||
build.xml.stylesheet.CRC32=f85dc8f2@1.95.0.48
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=fb275268
|
||||
nbproject/build-impl.xml.script.CRC32=1ec9d904
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.2.48
|
||||
nbproject/build-impl.xml.script.CRC32=c29906ba
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=f89f7d21@1.95.0.48
|
||||
|
||||
@@ -19,8 +19,12 @@ build.test.results.dir=${build.dir}/test/results
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.modulepath=\
|
||||
${run.modulepath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
debug.test.modulepath=\
|
||||
${run.test.modulepath}
|
||||
# Files in build.classes.dir which should be excluded from distribution jar
|
||||
dist.archive.excludes=
|
||||
# This directory is removed when the project is cleaned:
|
||||
@@ -35,6 +39,8 @@ javac.classpath=
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.modulepath=
|
||||
javac.processormodulepath=
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=1.7
|
||||
@@ -42,6 +48,8 @@ javac.target=1.7
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.modulepath=\
|
||||
${javac.modulepath}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
@@ -67,9 +75,13 @@ run.classpath=\
|
||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||
run.jvmargs=
|
||||
run.modulepath=\
|
||||
${javac.modulepath}
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
run.test.modulepath=\
|
||||
${javac.test.modulepath}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
||||
|
||||
@@ -20,10 +20,20 @@
|
||||
*/
|
||||
package gnu.jpdf;
|
||||
|
||||
import java.awt.FontFormatException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* <p>This class is the base of the PDF generator. A PDFDocument class is
|
||||
@@ -249,7 +259,87 @@ public class PDFDocument implements Serializable
|
||||
add(ft);
|
||||
fonts.addElement(ft);
|
||||
return ft;
|
||||
}
|
||||
}
|
||||
|
||||
public PDFFont getEmbeddedFont(String font, int style, File file) throws FileNotFoundException, IOException {
|
||||
for (PDFFont ft : fonts) {
|
||||
if (ft.equals("/TrueType", font, style)) {
|
||||
return ft;
|
||||
}
|
||||
}
|
||||
PDFStream fontFile2 = new PDFStream() {
|
||||
@Override
|
||||
public void write(OutputStream os) throws IOException {
|
||||
writeStart(os);
|
||||
os.write("/Length1 ".getBytes());
|
||||
os.write(Integer.toString(buf.size()).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
writeStream(os);
|
||||
}
|
||||
|
||||
};
|
||||
fontFile2.setDeflate(true);
|
||||
OutputStream ff2Os = fontFile2.getOutputStream();
|
||||
InputStream is = new FileInputStream(file);
|
||||
byte buf[] = new byte[1024];
|
||||
int cnt = 0;
|
||||
while ((cnt = is.read(buf)) > 0) {
|
||||
ff2Os.write(buf, 0, cnt);
|
||||
}
|
||||
is.close();
|
||||
//ff2Os.write("AHOJ".getBytes());
|
||||
|
||||
add(fontFile2);
|
||||
|
||||
// the font wasn't found, so create it
|
||||
fontid++;
|
||||
TtfParser par = new TtfParser();
|
||||
try {
|
||||
par.loadFromTTF(file, 1024);
|
||||
} catch (FontFormatException ex) {
|
||||
Logger.getLogger(PDFDocument.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
PDFFontDescriptor fontDescriptor = new PDFFontDescriptor(font, par.getAscent(), par.getDescent(), par.getCapHeight(), 80/*?*/, "" + fontFile2.getSerialID() + " 0 R");
|
||||
add(fontDescriptor);
|
||||
|
||||
final List<Integer> widthsList = new ArrayList<>();
|
||||
|
||||
List<Integer> glyphAdvances = par.getAdvanceWidths();
|
||||
Map<Integer, Integer> cmap = par.getCmap();
|
||||
for (int i = 32; i <= 255; i++) {
|
||||
if (cmap.containsKey(i)) {
|
||||
widthsList.add(glyphAdvances.get(cmap.get(i)));
|
||||
} else {
|
||||
widthsList.add(0);
|
||||
}
|
||||
}
|
||||
|
||||
PDFObject widthStream = new PDFObject(null) {
|
||||
@Override
|
||||
public void write(OutputStream os) throws IOException {
|
||||
os.write(Integer.toString(objser).getBytes());
|
||||
os.write(" 0 obj\n".getBytes());
|
||||
os.write("[ ".getBytes());
|
||||
for (int i = 0; i < widthsList.size(); i++) {
|
||||
if (i > 0) {
|
||||
os.write(" ".getBytes());
|
||||
}
|
||||
os.write(("" + widthsList.get(i)).getBytes());
|
||||
}
|
||||
os.write(" ]\n".getBytes());
|
||||
os.write("endobj\n".getBytes());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
add(widthStream);
|
||||
|
||||
|
||||
PDFFont ft = new PDFEmbeddedFont("/F" + fontid, font, style, "" + fontDescriptor.getSerialID() + " 0 R", widthStream.getSerialID() + " 0 R", 32, 255);
|
||||
add(ft);
|
||||
fonts.addElement(ft);
|
||||
return ft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a unique name to a PDFImage
|
||||
|
||||
78
libsrc/gnujpdf/src/gnu/jpdf/PDFEmbeddedFont.java
Normal file
78
libsrc/gnujpdf/src/gnu/jpdf/PDFEmbeddedFont.java
Normal file
@@ -0,0 +1,78 @@
|
||||
package gnu.jpdf;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class PDFEmbeddedFont extends PDFFont {
|
||||
|
||||
private final String descriptor;
|
||||
private String name;
|
||||
private String font;
|
||||
private String type;
|
||||
private final String widths;
|
||||
private final int firstChar;
|
||||
private final int lastChar;
|
||||
|
||||
public PDFEmbeddedFont(String name, String font, int style, String descriptor, String widths, int firstChar, int lastChar) {
|
||||
super(name, "/TrueType", font, style);
|
||||
this.descriptor = descriptor;
|
||||
this.name = name;
|
||||
this.font = font;
|
||||
this.type = "/TrueType";
|
||||
this.widths = widths;
|
||||
this.firstChar = firstChar;
|
||||
this.lastChar = lastChar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(OutputStream os) throws IOException {
|
||||
// Write the object header
|
||||
writeStart(os);
|
||||
|
||||
// now the objects body
|
||||
os.write("/Subtype ".getBytes());
|
||||
os.write(type.getBytes());
|
||||
os.write("\n/Name ".getBytes());
|
||||
os.write(name.getBytes());
|
||||
os.write("\n/BaseFont ".getBytes());
|
||||
os.write(font.getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
//os.write("/Encoding /WinAnsiEncoding\n".getBytes());
|
||||
|
||||
os.write(("/FirstChar " + firstChar + "\n").getBytes());
|
||||
os.write(("/LastChar " + lastChar + "\n").getBytes());
|
||||
os.write(("/Widths " + widths + "\n").getBytes());
|
||||
/*int cnt = 300;
|
||||
|
||||
os.write(("/FirstChar 0\n").getBytes());
|
||||
os.write(("/LastChar " + (cnt - 1) + "\n").getBytes());
|
||||
|
||||
os.write(("/Widths [").getBytes());
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
os.write((" " + i).getBytes());
|
||||
}
|
||||
os.write(("]\n").getBytes());
|
||||
*/
|
||||
//os.write("/Widths [500 583 587 796]".getBytes());
|
||||
|
||||
os.write("/FontDescriptor ".getBytes());
|
||||
os.write(descriptor.getBytes());
|
||||
os.write("\n".getBytes());
|
||||
|
||||
/*os.write("/ToUnicode ".getBytes());
|
||||
os.write(toUnicode.getBytes());
|
||||
os.write("\n".getBytes());*/
|
||||
// finish off with its footer
|
||||
writeEnd(os);
|
||||
}
|
||||
|
||||
}
|
||||
48
libsrc/gnujpdf/src/gnu/jpdf/PDFFontDescriptor.java
Normal file
48
libsrc/gnujpdf/src/gnu/jpdf/PDFFontDescriptor.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package gnu.jpdf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class PDFFontDescriptor extends PDFObject implements Serializable {
|
||||
|
||||
private final String fontName;
|
||||
private final int ascent;
|
||||
private final int descent;
|
||||
private final int capheight;
|
||||
private final int stemv;
|
||||
private final String fontFile2;
|
||||
|
||||
public PDFFontDescriptor(String fontName, int ascent, int descent, int capheight, int stemv, String fontFile2) {
|
||||
super("/FontDescriptor");
|
||||
this.fontName = fontName;
|
||||
this.ascent = ascent;
|
||||
this.descent = descent;
|
||||
this.capheight = capheight;
|
||||
this.stemv = stemv;
|
||||
this.fontFile2 = fontFile2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(OutputStream os) throws IOException {
|
||||
writeStart(os);
|
||||
os.write("/FontName ".getBytes());
|
||||
os.write(fontName.getBytes());
|
||||
os.write("\n".getBytes());
|
||||
os.write("/Flags 4\n".getBytes());
|
||||
os.write("/FontBBox [0 -16 725 863]\n".getBytes());
|
||||
os.write("/ItalicAngle 0\n".getBytes());
|
||||
os.write(("/Ascent " + ascent + "\n").getBytes());
|
||||
os.write(("/Descent " + descent + "\n").getBytes());
|
||||
os.write(("/CapHeight " + capheight + "\n").getBytes());
|
||||
os.write(("/StemV " + stemv + "\n").getBytes());
|
||||
//os.write("/MissingWidth 0\n".getBytes());
|
||||
os.write(("/FontFile2 " + fontFile2 + "\n").getBytes());
|
||||
writeEnd(os);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -50,6 +50,9 @@ public class PDFImage extends PDFStream implements ImageObserver, Serializable
|
||||
*/
|
||||
|
||||
|
||||
// Dimensions of the object.
|
||||
private int objwidth;
|
||||
private int objheight;
|
||||
|
||||
// Dimensions of the image.
|
||||
private int width;
|
||||
@@ -74,7 +77,7 @@ public class PDFImage extends PDFStream implements ImageObserver, Serializable
|
||||
*/
|
||||
public PDFImage(Image img) {
|
||||
this();
|
||||
setImage(img,img.getWidth(this), img.getHeight(this), this);
|
||||
setImage(img, 0, 0, img.getWidth(this), img.getHeight(this), this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,9 +90,11 @@ public class PDFImage extends PDFStream implements ImageObserver, Serializable
|
||||
* @param h an <code>int</code> value
|
||||
* @param obs an <code>ImageObserver</code> value
|
||||
*/
|
||||
public PDFImage(Image img,ImageObserver obs) {
|
||||
public PDFImage(Image img,int x,int y,int w,int h,ImageObserver obs) {
|
||||
this();
|
||||
setImage(img, img.getWidth(this), img.getHeight(this), obs);
|
||||
objwidth = w;
|
||||
objheight = h;
|
||||
setImage(img, x, y, img.getWidth(this), img.getHeight(this), obs);
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +159,7 @@ public class PDFImage extends PDFStream implements ImageObserver, Serializable
|
||||
* @param h an <code>int</code> value
|
||||
* @param obs an <code>ImageObserver</code> value
|
||||
*/
|
||||
public void setImage(Image img,int w,int h,ImageObserver obs) {
|
||||
public void setImage(Image img,int x,int y,int w,int h,ImageObserver obs) {
|
||||
this.img = img;
|
||||
width = w;
|
||||
height = h;
|
||||
@@ -400,6 +405,5 @@ public class PDFImage extends PDFStream implements ImageObserver, Serializable
|
||||
//}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // end class PDFImage
|
||||
|
||||
@@ -235,9 +235,11 @@ public class PDFOutline extends PDFObject implements Serializable
|
||||
// the number of outlines in this document
|
||||
if(parent==null) {
|
||||
// were the top level node, so all are open by default
|
||||
os.write("/Count ".getBytes());
|
||||
os.write(Integer.toString(outlines.size()).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
if (outlines.size() > 0) {
|
||||
os.write("/Count ".getBytes());
|
||||
os.write(Integer.toString(outlines.size()).getBytes());
|
||||
os.write("\n".getBytes());
|
||||
}
|
||||
} else {
|
||||
// were a decendent, so by default we are closed. Find out how many
|
||||
// entries are below us
|
||||
|
||||
@@ -22,6 +22,7 @@ package gnu.jpdf;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.print.PageFormat;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
@@ -217,6 +218,30 @@ public class PDFPage extends PDFObject implements Serializable
|
||||
return f;
|
||||
}
|
||||
|
||||
public PDFFont getEmbeddedFont(String font, int style, File file) throws IOException {
|
||||
// Search the fonts on this page, and return one that matches this
|
||||
// font.
|
||||
// This keeps the number of font definitions down to one per font/style
|
||||
for (PDFFont ft : fonts) {
|
||||
if (ft.equals("/TrueType", font, style)) {
|
||||
return ft;
|
||||
}
|
||||
}
|
||||
|
||||
// Ok, the font isn't in the page, so create one.
|
||||
// We need a procset if we are using fonts, so create it (if not
|
||||
// already created, and add to our resources
|
||||
if (fonts.size() == 0) {
|
||||
addProcset();
|
||||
procset.add("/Text");
|
||||
}
|
||||
|
||||
// finally create and return the font
|
||||
PDFFont f = pdfDocument.getEmbeddedFont(font, style, file);
|
||||
fonts.addElement(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the page's PageFormat.
|
||||
* @return PageFormat describing the page size in device units (72dpi)
|
||||
|
||||
278
libsrc/gnujpdf/src/gnu/jpdf/TtfParser.java
Normal file
278
libsrc/gnujpdf/src/gnu/jpdf/TtfParser.java
Normal file
@@ -0,0 +1,278 @@
|
||||
package gnu.jpdf;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TtfParser {
|
||||
|
||||
private int size = -1;
|
||||
|
||||
|
||||
private long headOffset = -1;
|
||||
|
||||
private long os2Offset = -1;
|
||||
private long hheaOffset = -1;
|
||||
private long hmtxOffset = -1;
|
||||
private long cmapOffset = -1;
|
||||
|
||||
private Font font;
|
||||
|
||||
private int ascent;
|
||||
private int descent;
|
||||
private int capHeight;
|
||||
|
||||
private float scale;
|
||||
private int numOfHMetrics;
|
||||
|
||||
private List<Integer> advanceWidths = new ArrayList<>();
|
||||
private Map<Integer, Integer> cmap = new TreeMap<>();
|
||||
|
||||
private int firstChar = -1;
|
||||
private int lastChar = -1;
|
||||
|
||||
public void loadFromTTF(File file, int size) throws IOException, FontFormatException {
|
||||
font = Font.createFont(Font.TRUETYPE_FONT, file);
|
||||
RandomAccessFile input = new RandomAccessFile(file, "r");
|
||||
this.size = size;
|
||||
if (input == null) {
|
||||
throw new IllegalArgumentException("input cannot be null.");
|
||||
}
|
||||
readTableDirectory(input);
|
||||
if (headOffset == -1) {
|
||||
throw new IOException("HEAD table not found.");
|
||||
}
|
||||
readHEAD(input);
|
||||
readOS2(input);
|
||||
readHHEA(input);
|
||||
readHMTX(input);
|
||||
readCMAP(input);
|
||||
|
||||
input.close();
|
||||
}
|
||||
|
||||
public int getFirstChar() {
|
||||
return firstChar;
|
||||
}
|
||||
|
||||
public int getLastChar() {
|
||||
return lastChar;
|
||||
}
|
||||
|
||||
|
||||
public List<Integer> getAdvanceWidths() {
|
||||
return advanceWidths;
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> getCmap() {
|
||||
return cmap;
|
||||
}
|
||||
|
||||
private void readTableDirectory(RandomAccessFile input) throws IOException {
|
||||
skip(input, 4);
|
||||
int tableCount = readUnsignedShort(input);
|
||||
skip(input, 6);
|
||||
|
||||
byte[] tagBytes = new byte[4];
|
||||
long prevOffset = 0;
|
||||
for (int i = 0; i < tableCount; i++) {
|
||||
tagBytes[0] = readByte(input);
|
||||
tagBytes[1] = readByte(input);
|
||||
tagBytes[2] = readByte(input);
|
||||
tagBytes[3] = readByte(input);
|
||||
skip(input, 4);
|
||||
long offset = readUnsignedLong(input);
|
||||
long length = readUnsignedLong(input);
|
||||
prevOffset = offset;
|
||||
String tag = new String(tagBytes, "ISO-8859-1");
|
||||
//System.err.println("tag " + tag + ", length: " + length);
|
||||
if (tag.equals("head")) {
|
||||
headOffset = offset;
|
||||
}
|
||||
if (tag.equals("OS/2")) {
|
||||
os2Offset = offset;
|
||||
}
|
||||
if (tag.equals("hhea")) {
|
||||
hheaOffset = offset;
|
||||
}
|
||||
if (tag.equals("hmtx")) {
|
||||
hmtxOffset = offset;
|
||||
}
|
||||
if (tag.equals("cmap")) {
|
||||
cmapOffset = offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readCMAP(RandomAccessFile input) throws IOException {
|
||||
seek(input, cmapOffset);
|
||||
int version = readUnsignedShort(input);
|
||||
int numberSubtables = readUnsignedShort(input);
|
||||
|
||||
for (int i = 0; i < numberSubtables; i++) {
|
||||
int platFormId = readUnsignedShort(input);
|
||||
int platFormSpecificId = readUnsignedShort(input);
|
||||
long offset = readUnsignedLong(input);
|
||||
seek(input, cmapOffset + offset);
|
||||
|
||||
int format = readUnsignedShort(input);
|
||||
switch (format) {
|
||||
case 4:
|
||||
int length = readUnsignedShort(input);
|
||||
int languageCode = readUnsignedShort(input);
|
||||
int segCountX2 = readUnsignedShort(input);
|
||||
int segCount = segCountX2 / 2;
|
||||
int searchRange = readUnsignedShort(input);
|
||||
int entrySelector = readUnsignedShort(input);
|
||||
int rangeShift = readUnsignedShort(input);
|
||||
|
||||
List<Integer> endCodes = new ArrayList<>();
|
||||
List<Integer> startCodes = new ArrayList<>();
|
||||
List<Integer> idDeltas = new ArrayList<>();
|
||||
List<Integer> idRangeOffsets = new ArrayList<>();
|
||||
|
||||
|
||||
for (int j = 0; j < segCount; j++) {
|
||||
int endCode = readUnsignedShort(input);
|
||||
endCodes.add(endCode);
|
||||
}
|
||||
readUnsignedShort(input);//pad
|
||||
for (int j = 0; j < segCount; j++) {
|
||||
int startCode = readUnsignedShort(input);
|
||||
startCodes.add(startCode);
|
||||
}
|
||||
for (int j = 0; j < segCount; j++) {
|
||||
int idDelta = readShort(input);
|
||||
idDeltas.add(idDelta);
|
||||
}
|
||||
for (int j = 0; j < segCount; j++) {
|
||||
int idRangeOffset = readUnsignedShort(input);
|
||||
idRangeOffsets.add(idRangeOffset);
|
||||
}
|
||||
|
||||
List<Integer> glyphIndices = new ArrayList<>();
|
||||
long startA = input.getFilePointer();
|
||||
;
|
||||
long a = startA;
|
||||
for (; a < cmapOffset + offset + length; a += 2) {
|
||||
int glyphIndex = readUnsignedShort(input);
|
||||
glyphIndices.add(glyphIndex);
|
||||
}
|
||||
|
||||
for (int j = 0; j < segCount; j++) {
|
||||
for (int k = startCodes.get(j); k <= endCodes.get(j); k++) {
|
||||
if (k == 65535) {
|
||||
continue;
|
||||
}
|
||||
if (idRangeOffsets.get(j) == 0) {
|
||||
int glyph = (idDeltas.get(j) + k) % 65536;
|
||||
cmap.put(k, glyph);
|
||||
|
||||
} else {
|
||||
int glyphIndex = (idRangeOffsets.get(j) - 2 * (segCount - j)) / 2 + (k - startCodes.get(j));
|
||||
int glyph = glyphIndices.get(glyphIndex);
|
||||
cmap.put(k, glyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
//System.err.println("format=" + format);
|
||||
}
|
||||
|
||||
private void readHMTX(RandomAccessFile input) throws IOException {
|
||||
seek(input, hmtxOffset);
|
||||
for (int i = 0; i < numOfHMetrics; i++) {
|
||||
int advanceWidth = readUnsignedShort(input);
|
||||
advanceWidths.add((int) (scale * advanceWidth));
|
||||
int leftSideBearing = readUnsignedShort(input);
|
||||
}
|
||||
}
|
||||
|
||||
private void readHHEA(RandomAccessFile input) throws IOException {
|
||||
|
||||
seek(input, hheaOffset + 4);
|
||||
ascent = (int) (scale * readShort(input));
|
||||
descent = (int) (scale * readShort(input));
|
||||
capHeight = ascent;
|
||||
seek(input, hheaOffset + 34);
|
||||
numOfHMetrics = readUnsignedShort(input);
|
||||
}
|
||||
private void readHEAD(RandomAccessFile input) throws IOException {
|
||||
seek(input, headOffset + 2 * 4 + 2 * 4 + 2);
|
||||
int unitsPerEm = readUnsignedShort(input);
|
||||
scale = (float) size / (float) unitsPerEm;
|
||||
}
|
||||
|
||||
private void readOS2(RandomAccessFile input) throws IOException {
|
||||
seek(input, os2Offset + 68);
|
||||
//ascent = readShort(input);
|
||||
//descent = readShort(input);
|
||||
seek(input, os2Offset + 88);
|
||||
//capHeight = readShort(input);
|
||||
}
|
||||
|
||||
public int getAscent() {
|
||||
return ascent;
|
||||
}
|
||||
|
||||
public int getDescent() {
|
||||
return descent;
|
||||
}
|
||||
|
||||
public int getCapHeight() {
|
||||
return capHeight;
|
||||
}
|
||||
|
||||
|
||||
private int readUnsignedByte(RandomAccessFile input) throws IOException {
|
||||
int b = input.read();
|
||||
if (b == -1) {
|
||||
throw new EOFException("Unexpected end of file.");
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
private byte readByte(RandomAccessFile input) throws IOException {
|
||||
return (byte) readUnsignedByte(input);
|
||||
}
|
||||
|
||||
private int readUnsignedShort(RandomAccessFile input) throws IOException {
|
||||
return (readUnsignedByte(input) << 8) + readUnsignedByte(input);
|
||||
}
|
||||
|
||||
private short readShort(RandomAccessFile input) throws IOException {
|
||||
return (short) readUnsignedShort(input);
|
||||
}
|
||||
|
||||
private long readUnsignedLong(RandomAccessFile input) throws IOException {
|
||||
long value = readUnsignedByte(input);
|
||||
value = (value << 8) + readUnsignedByte(input);
|
||||
value = (value << 8) + readUnsignedByte(input);
|
||||
value = (value << 8) + readUnsignedByte(input);
|
||||
return value;
|
||||
}
|
||||
|
||||
private void skip(RandomAccessFile input, long skip) throws IOException {
|
||||
input.seek(input.getFilePointer() + skip);
|
||||
}
|
||||
|
||||
private void seek(RandomAccessFile input, long position) throws IOException {
|
||||
//skip(input, position - bytePosition);
|
||||
input.seek(position);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user