import java.util.BitSet;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.fop.util.CharUtilities;
/**
* usedGlyphs contains orginal, new glyph index (glyph index -> char selector)
*/
- private Map<Integer, Integer> usedGlyphs = new HashMap<Integer, Integer>();
+ private Map<Integer, Integer> usedGlyphs = new LinkedHashMap<Integer, Integer>();
/**
* usedGlyphsIndex contains new glyph, original index (char selector -> glyph index)
RENDERING_MODE("rendering", PCLRenderingMode.class),
TEXT_RENDERING("text-rendering", Boolean.class),
DISABLE_PJL("disable-pjl", Boolean.class),
+ OPTIMIZE_RESOURCES("optimize-resources", Boolean.class),
MODE_COLOR("color", Boolean.class);
private final String name;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.Map;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.xmlgraphics.io.TempResourceURIGenerator;
import org.apache.xmlgraphics.util.UnitConv;
import org.apache.fop.apps.FopFactoryConfig;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.Typeface;
import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
import org.apache.fop.render.java2d.Java2DUtil;
import org.apache.fop.render.pcl.PCLRendererConfig.PCLRendererConfigParser;
import org.apache.fop.render.pcl.extensions.PCLElementMapping;
+import org.apache.fop.render.pcl.fonts.PCLSoftFontManager;
/**
* {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
/** logging instance */
private static Log log = LogFactory.getLog(PCLDocumentHandler.class);
+ /** the temporary file in case of two-pass processing */
+ private URI tempURI;
+ private static final TempResourceURIGenerator TEMP_URI_GENERATOR = new TempResourceURIGenerator("pcl-optimize");
+
/** Utility class for handling all sorts of peripheral tasks around PCL generation. */
protected PCLRenderingUtil pclUtil;
public void startDocument() throws IFException {
super.startDocument();
try {
- this.gen = new PCLGenerator(this.outputStream, getResolution());
+ final OutputStream out;
+ if (pclUtil.isOptimizeResources()) {
+ tempURI = TEMP_URI_GENERATOR.generate();
+ out = new BufferedOutputStream(getUserAgent().getResourceResolver().getOutputStream(tempURI));
+ } else {
+ out = this.outputStream;
+ }
+
+ this.gen = new PCLGenerator(out, getResolution());
this.gen.setDitheringQuality(pclUtil.getDitheringQuality());
if (!pclUtil.isPJLDisabled()) {
if (!pclUtil.isPJLDisabled()) {
gen.universalEndOfLanguage();
}
+
+ if (pclUtil.isOptimizeResources()) {
+ IOUtils.closeQuietly(gen.getOutputStream());
+ rewritePCLFile();
+ }
} catch (IOException ioe) {
throw new IFException("I/O error in endDocument()", ioe);
}
super.endDocument();
}
+ private void rewritePCLFile() throws IOException {
+ InputStream in = new BufferedInputStream(getUserAgent().getResourceResolver().getResource(tempURI));
+ long offset = 0;
+ for (Map.Entry<PCLSoftFontManager, Map<Typeface, Long>> fontManagerMapEntry : gen.fontManagerMap.entrySet()) {
+ PCLSoftFontManager softFontManager = fontManagerMapEntry.getKey();
+ for (Map.Entry<Typeface, Long> fontEntry : fontManagerMapEntry.getValue().entrySet()) {
+ ByteArrayOutputStream fontData = softFontManager.makeSoftFont(fontEntry.getKey(), null);
+ long pos = fontEntry.getValue();
+ copy(in, pos - offset);
+ outputStream.write(fontData.toByteArray());
+ offset = pos;
+ }
+ }
+ copy(in, Long.MAX_VALUE);
+ this.outputStream.flush();
+ IOUtils.closeQuietly(in);
+ }
+
+ private void copy(InputStream is, long len) throws IOException {
+ while (len > 0) {
+ int bufsize = (int) Math.min(1024, len);
+ byte[] buf = new byte[bufsize];
+ if (is.read(buf) == -1) {
+ return;
+ }
+ outputStream.write(buf);
+ len -= bufsize;
+ }
+ }
+
/** {@inheritDoc} */
public void startPageSequence(String id) throws IFException {
//nop
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Locale;
+import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.commons.io.output.CountingOutputStream;
import org.apache.xmlgraphics.util.UnitConv;
+import org.apache.fop.fonts.Typeface;
+import org.apache.fop.render.pcl.fonts.PCLFontReader;
+import org.apache.fop.render.pcl.fonts.PCLSoftFontManager;
import org.apache.fop.util.bitmap.BitmapImageUtil;
import org.apache.fop.util.bitmap.DitherUtil;
private final DecimalFormat df2 = new DecimalFormat("0.##", symbols);
private final DecimalFormat df4 = new DecimalFormat("0.####", symbols);
- private final OutputStream out;
+ private final CountingOutputStream out;
+ protected Map<Typeface, PCLFontReader> fontReaderMap = new HashMap<Typeface, PCLFontReader>();
+ protected Map<PCLSoftFontManager, Map<Typeface, Long>> fontManagerMap
+ = new LinkedHashMap<PCLSoftFontManager, Map<Typeface, Long>>();
private boolean currentSourceTransparency = true;
private boolean currentPatternTransparency = true;
* @param out the OutputStream to write the PCL stream to
*/
public PCLGenerator(OutputStream out) {
- this.out = out;
+ this.out = new CountingOutputStream(out);
}
/**
this.maxBitmapResolution = maxResolution;
}
+ public void addFont(PCLSoftFontManager sfManager, Typeface font) {
+ if (!fontManagerMap.containsKey(sfManager)) {
+ fontManagerMap.put(sfManager, new LinkedHashMap<Typeface, Long>());
+ }
+ Map<Typeface, Long> fonts = fontManagerMap.get(sfManager);
+ if (!fonts.containsKey(font)) {
+ fonts.put(font, out.getByteCount());
+ }
+ }
+
/** @return the OutputStream that this generator writes to */
public OutputStream getOutputStream() {
return this.out;
private Stack<GraphicContext> graphicContextStack = new Stack<GraphicContext>();
private GraphicContext graphicContext = new GraphicContext();
-
- private PCLSoftFontManager sfManager = new PCLSoftFontManager();
+ private PCLSoftFontManager sfManager;
/**
* Main constructor.
} else {
// TrueType conversion to a soft font (PCL 5 Technical Reference - Chapter 11)
if (!drawAsBitmaps && isTrueType(tf)) {
- boolean madeSF = false;
- if (sfManager.getSoftFont(tf, text) == null) {
- madeSF = true;
- ByteArrayOutputStream baos = sfManager.makeSoftFont(tf);
+ if (sfManager == null) {
+ sfManager = new PCLSoftFontManager(gen.fontReaderMap);
+ }
+ if (getPCLUtil().isOptimizeResources() || sfManager.getSoftFont(tf, text) == null) {
+ for (char c : text.toCharArray()) {
+ tf.mapChar(c);
+ }
+ ByteArrayOutputStream baos = sfManager.makeSoftFont(tf, text);
if (baos != null) {
- gen.writeBytes(baos.toByteArray());
+ if (getPCLUtil().isOptimizeResources()) {
+ gen.addFont(sfManager, tf);
+ } else {
+ gen.writeBytes(baos.toByteArray());
+ }
}
}
String formattedSize = gen.formatDouble2(state.getFontSize() / 1000.0);
import static org.apache.fop.render.pcl.Java2DRendererOption.DISABLE_PJL;
import static org.apache.fop.render.pcl.Java2DRendererOption.MODE_COLOR;
+import static org.apache.fop.render.pcl.Java2DRendererOption.OPTIMIZE_RESOURCES;
import static org.apache.fop.render.pcl.Java2DRendererOption.RENDERING_MODE;
import static org.apache.fop.render.pcl.Java2DRendererOption.TEXT_RENDERING;
return getParam(MODE_COLOR, Boolean.class);
}
+ public Boolean isOptimizeResources() {
+ return getParam(OPTIMIZE_RESOURCES, Boolean.class);
+ }
+
private <T> T getParam(Java2DRendererOption option, Class<T> type) {
assert option.getType().equals(type);
return type.cast(params.get(option));
}
config.setParam(DISABLE_PJL,
cfg.getChild(DISABLE_PJL.getName()).getValueAsBoolean(false));
+ config.setParam(OPTIMIZE_RESOURCES,
+ cfg.getChild(OPTIMIZE_RESOURCES.getName()).getValueAsBoolean(false));
}
}
if (config.isColorEnabled() != null) {
pclUtil.setColorEnabled(config.isColorEnabled());
}
+ if (config.isOptimizeResources() != null) {
+ pclUtil.setOptimizeResources(config.isOptimizeResources());
+ }
}
@Override
private float ditheringQuality = 0.5f;
private boolean useColor;
+ private boolean optimizeResources;
/**
* Controls whether the generation of PJL commands gets disabled.
return transPoint;
}
+ public boolean isOptimizeResources() {
+ return optimizeResources;
+ }
+
+ public void setOptimizeResources(boolean b) {
+ optimizeResources = b;
+ }
+
}
import java.io.IOException;
import java.util.Arrays;
-public class PCLByteWriterUtil {
+public final class PCLByteWriterUtil {
- public byte[] padBytes(byte[] in, int length) {
+ private PCLByteWriterUtil() {
+ }
+
+ public static byte[] padBytes(byte[] in, int length) {
return padBytes(in, length, 0);
}
- public byte[] padBytes(byte[] in, int length, int value) {
+ public static byte[] padBytes(byte[] in, int length, int value) {
byte[] out = new byte[length];
for (int i = 0; i < length; i++) {
if (i < in.length) {
return out;
}
- public byte[] signedInt(int s) {
+ public static byte[] signedInt(int s) {
byte b1 = (byte) (s >> 8);
byte b2 = (byte) s;
return new byte[]{b1, b2};
}
- public byte signedByte(int s) {
+ public static byte signedByte(int s) {
return (byte) s;
}
- public byte[] unsignedLongInt(int s) {
+ public static byte[] unsignedLongInt(int s) {
return unsignedLongInt((long) s);
}
- public byte[] unsignedLongInt(long s) {
+ public static byte[] unsignedLongInt(long s) {
byte b1 = (byte) ((s >> 24) & 0xff);
byte b2 = (byte) ((s >> 16) & 0xff);
byte b3 = (byte) ((s >> 8) & 0xff);
return new byte[]{b1, b2, b3, b4};
}
- public byte[] unsignedInt(int s) {
+ public static byte[] unsignedInt(int s) {
byte b1 = (byte) ((s >> 8) & 0xff);
byte b2 = (byte) (s & 0xff);
return new byte[]{b1, b2};
}
- public int unsignedByte(int b) {
+ public static int unsignedByte(int b) {
return (byte) b & 0xFF;
}
- public int maxPower2(int value) {
+ public static int maxPower2(int value) {
int test = 2;
while (test < value) {
test *= 2;
return test;
}
- public int log(int x, int base) {
+ public static int log(int x, int base) {
return (int) (Math.log(x) / Math.log(base));
}
- public byte[] toByteArray(int[] s) {
+ public static byte[] toByteArray(int[] s) {
byte[] values = new byte[s.length];
for (int i = 0; i < s.length; i++) {
values[i] = (byte) s[i];
return values;
}
- public byte[] insertIntoArray(int index, byte[] insertTo, byte[] data) throws IOException {
+ public static byte[] insertIntoArray(int index, byte[] insertTo, byte[] data) throws IOException {
byte[] preBytes = Arrays.copyOf(insertTo, index);
byte[] postBytes = Arrays.copyOfRange(insertTo, index, insertTo.length);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
return baos.toByteArray();
}
- public byte[] updateDataAtLocation(byte[] data, byte[] update, int offset) {
+ public static byte[] updateDataAtLocation(byte[] data, byte[] update, int offset) {
int count = 0;
for (int i = offset; i < offset + update.length; i++) {
data[i] = update[count++];
* @param cmd the command (without the ESCAPE character)
* @throws IOException In case of an I/O error
*/
- public byte[] writeCommand(String cmd) throws IOException {
+ public static byte[] writeCommand(String cmd) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(27); // ESC
baos.write(cmd.getBytes("US-ASCII"));
private boolean hasContinuation;
private PCLCharacterFormat charFormat;
private PCLCharacterClass charClass;
- private PCLByteWriterUtil pclByteWriter;
private List<PCLCharacterDefinition> composites;
private boolean isComposite;
public PCLCharacterDefinition(int charCode, PCLCharacterFormat charFormat,
- PCLCharacterClass charClass, byte[] glyfData, PCLByteWriterUtil pclByteWriter,
- boolean isComposite) {
+ PCLCharacterClass charClass, byte[] glyfData, boolean isComposite) {
this.charCode = charCode;
this.charFormat = charFormat;
this.charClass = charClass;
this.glyfData = glyfData;
- this.pclByteWriter = pclByteWriter;
this.isComposite = isComposite;
// Glyph Data + (Descriptor Size) + (Character Data Size) + (Glyph ID) must
// be less than 32767 otherwise it will result in a continuation structure.
}
public byte[] getCharacterCommand() throws IOException {
- return pclByteWriter.writeCommand(String.format("*c%dE", (isComposite) ? 65535 : charCode));
+ return PCLByteWriterUtil.writeCommand(String.format("*c%dE", (isComposite) ? 65535 : charCode));
}
public byte[] getCharacterDefinitionCommand() throws IOException {
- return pclByteWriter.writeCommand(String.format("(s%dW", 10 + glyfData.length));
+ return PCLByteWriterUtil.writeCommand(String.format("(s%dW", 10 + glyfData.length));
}
public byte[] getData() throws IOException {
}
private void writeCharacterDescriptorHeader(int continuation, ByteArrayOutputStream baos) throws IOException {
- baos.write(pclByteWriter.unsignedByte(charFormat.getValue()));
+ baos.write(PCLByteWriterUtil.unsignedByte(charFormat.getValue()));
baos.write(continuation);
- baos.write(pclByteWriter.unsignedByte(2)); // Descriptor size (from this byte to character data)
- baos.write(pclByteWriter.unsignedByte(charClass.getValue()));
- baos.write(pclByteWriter.unsignedInt(glyfData.length + 4));
- baos.write(pclByteWriter.unsignedInt(charCode));
+ baos.write(PCLByteWriterUtil.unsignedByte(2)); // Descriptor size (from this byte to character data)
+ baos.write(PCLByteWriterUtil.unsignedByte(charClass.getValue()));
+ baos.write(PCLByteWriterUtil.unsignedInt(glyfData.length + 4));
+ baos.write(PCLByteWriterUtil.unsignedInt(charCode));
}
public void addCompositeGlyph(PCLCharacterDefinition composite) {
public abstract class PCLCharacterWriter {
protected PCLSoftFont font;
- protected PCLByteWriterUtil pclByteWriter;
protected OpenFont openFont;
protected FontFileReader fontReader;
this.font = font;
openFont = font.getOpenFont();
fontReader = font.getReader();
- pclByteWriter = new PCLByteWriterUtil();
}
public abstract byte[] writeCharacterDefinitions(String text) throws IOException;
public abstract class PCLFontReader {
protected Typeface typeface;
- protected PCLByteWriterUtil pclByteWriter;
protected CustomFont font;
- public PCLFontReader(Typeface font, PCLByteWriterUtil pclByteWriter) {
+ public PCLFontReader(Typeface font) {
this.typeface = font;
- this.pclByteWriter = pclByteWriter;
}
public void setFont(CustomFont mbFont) {
public abstract int getMasterUnderlineThickness() throws IOException;
public abstract int getFontScalingTechnology();
public abstract int getVariety();
+ public abstract Map<Integer, Integer> scanMtxCharacters() throws IOException;
/** Segmented Font Data **/
public abstract List<PCLFontSegment> getFontSegments(Map<Character, Integer> mappedGlyphs)
public final class PCLFontReaderFactory {
- private PCLByteWriterUtil pclByteWriter;
-
- private PCLFontReaderFactory(PCLByteWriterUtil pclByteWriter) {
- this.pclByteWriter = pclByteWriter;
- }
-
- public static PCLFontReaderFactory getInstance(PCLByteWriterUtil pclByteWriter) {
- return new PCLFontReaderFactory(pclByteWriter);
+ private PCLFontReaderFactory() {
}
- public PCLFontReader createInstance(Typeface font) throws IOException {
+ public static PCLFontReader createInstance(Typeface font) throws IOException {
if (font.getFontType() == FontType.TRUETYPE || isCIDType2(font)) {
- return new PCLTTFFontReader(font, pclByteWriter);
+ return new PCLTTFFontReader(font);
}
// else if (font instanceof MultiByteFont && ((MultiByteFont) font).isOTFFile()) {
// Placeholder for future Type 1 / OTF Soft font implementations e.g.
return null;
}
- private boolean isCIDType2(Typeface font) {
+ private static boolean isCIDType2(Typeface font) {
CustomFontMetricsMapper fontMetrics = (CustomFontMetricsMapper) font;
CustomFont customFont = (CustomFont) fontMetrics.getRealFont();
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.fop.render.java2d.CustomFontMetricsMapper;
public class PCLSoftFontManager {
- private ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ private Map<Typeface, PCLFontReader> fontReaderMap;
private PCLFontReader fontReader;
- private PCLByteWriterUtil pclByteWriter = new PCLByteWriterUtil();
private List<PCLSoftFont> fonts = new ArrayList<PCLSoftFont>();
- private PCLFontReaderFactory fontReaderFactory;
private static final int SOFT_FONT_SIZE = 255;
- public ByteArrayOutputStream makeSoftFont(Typeface font) throws IOException {
+ public PCLSoftFontManager(Map<Typeface, PCLFontReader> fontReaderMap) {
+ this.fontReaderMap = fontReaderMap;
+ }
+
+ public ByteArrayOutputStream makeSoftFont(Typeface font, String text) throws IOException {
List<Map<Character, Integer>> mappedGlyphs = mapFontGlyphs(font);
- if (fontReaderFactory == null) {
- fontReaderFactory = PCLFontReaderFactory.getInstance(pclByteWriter);
+ if (!fontReaderMap.containsKey(font)) {
+ fontReaderMap.put(font, PCLFontReaderFactory.createInstance(font));
}
- fontReader = fontReaderFactory.createInstance(font);
- initialize();
+ fontReader = fontReaderMap.get(font);
if (mappedGlyphs.isEmpty()) {
mappedGlyphs.add(new HashMap<Character, Integer>());
}
if (fontReader != null) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PCLSoftFont softFont = null;
for (Map<Character, Integer> glyphSet : mappedGlyphs) {
- PCLSoftFont softFont = new PCLSoftFont(fonts.size() + 1, font,
- mappedGlyphs.get(0).size() != 0);
+ softFont = getSoftFont(font, text, mappedGlyphs, softFont);
softFont.setMappedChars(glyphSet);
- assignFontID();
- writeFontHeader(softFont.getMappedChars());
+ writeFontID(softFont.getFontID(), baos);
+ writeFontHeader(softFont.getMappedChars(), baos);
softFont.setCharacterOffsets(fontReader.getCharacterOffsets());
softFont.setOpenFont(fontReader.getFontFile());
softFont.setReader(fontReader.getFontFileReader());
- fonts.add(softFont);
+ softFont.setMtxCharIndexes(fontReader.scanMtxCharacters());
}
return baos;
} else {
}
}
+ private PCLSoftFont getSoftFont(Typeface font, String text, List<Map<Character, Integer>> mappedGlyphs,
+ PCLSoftFont last) {
+ if (text == null) {
+ Iterator<PCLSoftFont> fontIterator = fonts.iterator();
+ while (fontIterator.hasNext()) {
+ PCLSoftFont sftFont = fontIterator.next();
+ if (sftFont.getTypeface().equals(font)) {
+ fontIterator.remove();
+ return sftFont;
+ }
+ }
+ }
+ for (PCLSoftFont sftFont : fonts) {
+ if (sftFont.getTypeface().equals(font) && sftFont != last
+ && (sftFont.getCharCount() + countNonMatches(sftFont, text)) < SOFT_FONT_SIZE) {
+ return sftFont;
+ }
+ }
+ PCLSoftFont f = new PCLSoftFont(fonts.size() + 1, font, mappedGlyphs.get(0).size() != 0);
+ fonts.add(f);
+ return f;
+ }
+
private List<Map<Character, Integer>> mapFontGlyphs(Typeface tf) {
List<Map<Character, Integer>> mappedGlyphs = new ArrayList<Map<Character, Integer>>();
if (tf instanceof CustomFontMetricsMapper) {
return mappedGlyphs;
}
- private void initialize() {
- baos.reset();
- }
-
- private void assignFontID() throws IOException {
- baos.write(assignFontID(fonts.size() + 1));
+ private void writeFontID(int fontID, OutputStream os) throws IOException {
+ os.write(assignFontID(fontID));
}
public byte[] assignFontID(int fontID) throws IOException {
- return pclByteWriter.writeCommand(String.format("*c%dD", fontID));
+ return PCLByteWriterUtil.writeCommand(String.format("*c%dD", fontID));
}
- private void writeFontHeader(Map<Character, Integer> mappedGlyphs) throws IOException {
+ private void writeFontHeader(Map<Character, Integer> mappedGlyphs, OutputStream os) throws IOException {
ByteArrayOutputStream header = new ByteArrayOutputStream();
- header.write(pclByteWriter.unsignedInt(fontReader.getDescriptorSize()));
- header.write(pclByteWriter.unsignedByte(fontReader.getHeaderFormat()));
- header.write(pclByteWriter.unsignedByte(fontReader.getFontType()));
- header.write(pclByteWriter.unsignedByte(fontReader.getStyleMSB()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getDescriptorSize()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getHeaderFormat()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getFontType()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getStyleMSB()));
header.write(0); // Reserved
- header.write(pclByteWriter.unsignedInt(fontReader.getBaselinePosition()));
- header.write(pclByteWriter.unsignedInt(fontReader.getCellWidth()));
- header.write(pclByteWriter.unsignedInt(fontReader.getCellHeight()));
- header.write(pclByteWriter.unsignedByte(fontReader.getOrientation()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getBaselinePosition()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getCellWidth()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getCellHeight()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getOrientation()));
header.write(fontReader.getSpacing());
- header.write(pclByteWriter.unsignedInt(fontReader.getSymbolSet()));
- header.write(pclByteWriter.unsignedInt(fontReader.getPitch()));
- header.write(pclByteWriter.unsignedInt(fontReader.getHeight()));
- header.write(pclByteWriter.unsignedInt(fontReader.getXHeight()));
- header.write(pclByteWriter.signedByte(fontReader.getWidthType()));
- header.write(pclByteWriter.unsignedByte(fontReader.getStyleLSB()));
- header.write(pclByteWriter.signedByte(fontReader.getStrokeWeight()));
- header.write(pclByteWriter.unsignedByte(fontReader.getTypefaceLSB()));
- header.write(pclByteWriter.unsignedByte(fontReader.getTypefaceMSB()));
- header.write(pclByteWriter.unsignedByte(fontReader.getSerifStyle()));
- header.write(pclByteWriter.unsignedByte(fontReader.getQuality()));
- header.write(pclByteWriter.signedByte(fontReader.getPlacement()));
- header.write(pclByteWriter.signedByte(fontReader.getUnderlinePosition()));
- header.write(pclByteWriter.unsignedByte(fontReader.getUnderlineThickness()));
- header.write(pclByteWriter.unsignedInt(fontReader.getTextHeight()));
- header.write(pclByteWriter.unsignedInt(fontReader.getTextWidth()));
- header.write(pclByteWriter.unsignedInt(fontReader.getFirstCode()));
- header.write(pclByteWriter.unsignedInt(fontReader.getLastCode()));
- header.write(pclByteWriter.unsignedByte(fontReader.getPitchExtended()));
- header.write(pclByteWriter.unsignedByte(fontReader.getHeightExtended()));
- header.write(pclByteWriter.unsignedInt(fontReader.getCapHeight()));
- header.write(pclByteWriter.unsignedLongInt(fontReader.getFontNumber()));
- header.write(pclByteWriter.padBytes(fontReader.getFontName().getBytes("US-ASCII"), 16, 32));
- header.write(pclByteWriter.unsignedInt(fontReader.getScaleFactor()));
- header.write(pclByteWriter.signedInt(fontReader.getMasterUnderlinePosition()));
- header.write(pclByteWriter.unsignedInt(fontReader.getMasterUnderlineThickness()));
- header.write(pclByteWriter.unsignedByte(fontReader.getFontScalingTechnology()));
- header.write(pclByteWriter.unsignedByte(fontReader.getVariety()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getSymbolSet()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getPitch()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getHeight()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getXHeight()));
+ header.write(PCLByteWriterUtil.signedByte(fontReader.getWidthType()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getStyleLSB()));
+ header.write(PCLByteWriterUtil.signedByte(fontReader.getStrokeWeight()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getTypefaceLSB()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getTypefaceMSB()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getSerifStyle()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getQuality()));
+ header.write(PCLByteWriterUtil.signedByte(fontReader.getPlacement()));
+ header.write(PCLByteWriterUtil.signedByte(fontReader.getUnderlinePosition()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getUnderlineThickness()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getTextHeight()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getTextWidth()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getFirstCode()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getLastCode()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getPitchExtended()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getHeightExtended()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getCapHeight()));
+ header.write(PCLByteWriterUtil.unsignedLongInt(fontReader.getFontNumber()));
+ header.write(PCLByteWriterUtil.padBytes(fontReader.getFontName().getBytes("US-ASCII"), 16, 32));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getScaleFactor()));
+ header.write(PCLByteWriterUtil.signedInt(fontReader.getMasterUnderlinePosition()));
+ header.write(PCLByteWriterUtil.unsignedInt(fontReader.getMasterUnderlineThickness()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getFontScalingTechnology()));
+ header.write(PCLByteWriterUtil.unsignedByte(fontReader.getVariety()));
writeSegmentedFontData(header, mappedGlyphs);
- baos.write(getFontHeaderCommand(header.size()));
- baos.write(header.toByteArray());
+ os.write(getFontHeaderCommand(header.size()));
+ os.write(header.toByteArray());
}
private void writeSegmentedFontData(ByteArrayOutputStream header,
}
private byte[] getFontHeaderCommand(int headerSize) throws IOException {
- return pclByteWriter.writeCommand(String.format(")s%dW", headerSize));
+ return PCLByteWriterUtil.writeCommand(String.format(")s%dW", headerSize));
}
private void writeFontSegment(ByteArrayOutputStream header, PCLFontSegment segment) throws IOException {
- header.write(pclByteWriter.unsignedInt(segment.getIdentifier().getValue()));
- header.write(pclByteWriter.unsignedInt(segment.getData().length));
+ header.write(PCLByteWriterUtil.unsignedInt(segment.getIdentifier().getValue()));
+ header.write(PCLByteWriterUtil.unsignedInt(segment.getData().length));
header.write(segment.getData());
}
public PCLTTFCharacterWriter(PCLSoftFont softFont) throws IOException {
super(softFont);
- softFont.setMtxCharIndexes(scanMtxCharacters());
}
@Override
baos.write(pclChar.getData());
}
- private Map<Integer, Integer> scanMtxCharacters() throws IOException {
- Map<Integer, Integer> charMtxOffsets = new HashMap<Integer, Integer>();
- List<OFMtxEntry> mtx = openFont.getMtx();
- OFTableName glyfTag = OFTableName.GLYF;
- if (openFont.seekTab(fontReader, glyfTag, 0)) {
- for (int i = 1; i < mtx.size(); i++) {
- OFMtxEntry entry = mtx.get(i);
- int charCode = 0;
- if (entry.getUnicodeIndex().size() > 0) {
- charCode = (Integer) entry.getUnicodeIndex().get(0);
- } else {
- charCode = entry.getIndex();
- }
- charMtxOffsets.put(charCode, i);
- }
- }
- return charMtxOffsets;
- }
-
private PCLCharacterDefinition getCharacterDefinition(int unicode) throws IOException {
if (mtx == null) {
mtx = openFont.getMtx();
PCLCharacterDefinition newChar = new PCLCharacterDefinition(
font.getCharCode((char) unicode),
PCLCharacterFormat.TrueType,
- PCLCharacterClass.TrueType, glyphData, pclByteWriter, false);
+ PCLCharacterClass.TrueType, glyphData, false);
// Handle composite character definitions
GlyfTable glyfTable = new GlyfTable(fontReader, mtx.toArray(new OFMtxEntry[mtx.size()]),
byte[] compositeData = getGlyphData(compositeIndex);
newChar.addCompositeGlyph(new PCLCharacterDefinition(compositeIndex,
PCLCharacterFormat.TrueType,
- PCLCharacterClass.TrueType, compositeData, pclByteWriter, true));
+ PCLCharacterClass.TrueType, compositeData, true));
}
}
private PCLTTFOS2FontTable os2Table;
private PCLTTFPOSTFontTable postTable;
private PCLTTFTableFactory ttfTableFactory;
+ private Map<Integer, int[]> charOffsets;
+ private Map<Integer, Integer> charMtxOffsets;
private static final int HMTX_RESTRICT_SIZE = 50000;
private int scaleFactor = -1;
private PCLSymbolSet symbolSet = PCLSymbolSet.Bound_Generic;
- public PCLTTFFontReader(Typeface font, PCLByteWriterUtil pclByteWriter) throws IOException {
- super(font, pclByteWriter);
+ public PCLTTFFontReader(Typeface font) throws IOException {
+ super(font);
loadFont();
}
throws IOException {
List<PCLFontSegment> fontSegments = new ArrayList<PCLFontSegment>();
fontSegments.add(new PCLFontSegment(SegmentID.CC, getCharacterComplement()));
- fontSegments.add(new PCLFontSegment(SegmentID.PA, pclByteWriter.toByteArray(os2Table.getPanose())));
+ fontSegments.add(new PCLFontSegment(SegmentID.PA, PCLByteWriterUtil.toByteArray(os2Table.getPanose())));
fontSegments.add(new PCLFontSegment(SegmentID.GT, getGlobalTrueTypeData(mappedGlyphs)));
fontSegments.add(new PCLFontSegment(SegmentID.CP, ttfFont.getCopyrightNotice().getBytes("US-ASCII")));
fontSegments.add(new PCLFontSegment(SegmentID.NULL, new byte[0]));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
List<TableOffset> tableOffsets = new ArrayList<TableOffset>();
// Version
- baos.write(pclByteWriter.unsignedInt(1)); // Major
- baos.write(pclByteWriter.unsignedInt(0)); // Minor
+ baos.write(PCLByteWriterUtil.unsignedInt(1)); // Major
+ baos.write(PCLByteWriterUtil.unsignedInt(0)); // Minor
int numTables = 5; // head, hhea, hmtx, maxp and gdir
// Optional Hint Tables
OFDirTabEntry headTable = ttfFont.getDirectoryEntry(OFTableName.CVT);
if (prepTable != null) {
numTables++;
}
- baos.write(pclByteWriter.unsignedInt(numTables)); // numTables
- int maxPowerNumTables = pclByteWriter.maxPower2(numTables);
+ baos.write(PCLByteWriterUtil.unsignedInt(numTables)); // numTables
+ int maxPowerNumTables = PCLByteWriterUtil.maxPower2(numTables);
int searchRange = maxPowerNumTables * 16;
- baos.write(pclByteWriter.unsignedInt(searchRange));
- baos.write(pclByteWriter.unsignedInt(pclByteWriter.log(maxPowerNumTables, 2))); // Entry Selector
- baos.write(pclByteWriter.unsignedInt(numTables * 16 - searchRange)); // Range shift
+ baos.write(PCLByteWriterUtil.unsignedInt(searchRange));
+ baos.write(PCLByteWriterUtil.unsignedInt(PCLByteWriterUtil.log(maxPowerNumTables, 2))); // Entry Selector
+ baos.write(PCLByteWriterUtil.unsignedInt(numTables * 16 - searchRange)); // Range shift
// Add default data tables
writeTrueTypeTable(baos, OFTableName.HEAD, tableOffsets);
OFDirTabEntry tabEntry = ttfFont.getDirectoryEntry(table);
if (tabEntry != null) {
baos.write(tabEntry.getTag());
- baos.write(pclByteWriter.unsignedLongInt(tabEntry.getChecksum()));
+ baos.write(PCLByteWriterUtil.unsignedLongInt(tabEntry.getChecksum()));
TableOffset newTableOffset = new TableOffset(tabEntry.getOffset(),
tabEntry.getLength(), baos.size());
tableOffsets.add(newTableOffset);
- baos.write(pclByteWriter.unsignedLongInt(0)); // Offset to be set later
- baos.write(pclByteWriter.unsignedLongInt(tabEntry.getLength()));
+ baos.write(PCLByteWriterUtil.unsignedLongInt(0)); // Offset to be set later
+ baos.write(PCLByteWriterUtil.unsignedLongInt(tabEntry.getLength()));
}
}
private void writeGDIR(ByteArrayOutputStream baos) throws UnsupportedEncodingException, IOException {
baos.write("gdir".getBytes("ISO-8859-1"));
- baos.write(pclByteWriter.unsignedLongInt(0)); // Checksum
- baos.write(pclByteWriter.unsignedLongInt(0)); // Offset
- baos.write(pclByteWriter.unsignedLongInt(0)); // Length
+ baos.write(PCLByteWriterUtil.unsignedLongInt(0)); // Checksum
+ baos.write(PCLByteWriterUtil.unsignedLongInt(0)); // Offset
+ baos.write(PCLByteWriterUtil.unsignedLongInt(0)); // Length
}
private ByteArrayOutputStream copyTables(List<TableOffset> tableOffsets,
throws IOException {
Map<Integer, byte[]> offsetValues = new HashMap<Integer, byte[]>();
for (TableOffset tableOffset : tableOffsets) {
- offsetValues.put(tableOffset.getNewOffset(), pclByteWriter.unsignedLongInt(baos.size()));
+ offsetValues.put(tableOffset.getNewOffset(), PCLByteWriterUtil.unsignedLongInt(baos.size()));
if (tableOffset.getOriginOffset() == -1) { // Update the offset in the table directory
baos.write(hmtxTable);
} else {
throws IOException {
byte[] softFont = baos.toByteArray();
for (int offset : offsets.keySet()) {
- pclByteWriter.updateDataAtLocation(softFont, offsets.get(offset), offset);
+ PCLByteWriterUtil.updateDataAtLocation(softFont, offsets.get(offset), offset);
}
baos = new ByteArrayOutputStream();
baos.write(softFont);
@Override
public Map<Integer, int[]> getCharacterOffsets() throws IOException {
- List<OFMtxEntry> mtx = ttfFont.getMtx();
- OFTableName glyfTag = OFTableName.GLYF;
- Map<Integer, int[]> charOffsets = new HashMap<Integer, int[]>();
- OFDirTabEntry tabEntry = ttfFont.getDirectoryEntry(glyfTag);
- if (ttfFont.seekTab(reader, glyfTag, 0)) {
- for (int i = 1; i < mtx.size(); i++) {
- OFMtxEntry entry = mtx.get(i);
- OFMtxEntry nextEntry;
- int nextOffset = 0;
- int charCode = 0;
- if (entry.getUnicodeIndex().size() > 0) {
- charCode = (Integer) entry.getUnicodeIndex().get(0);
- } else {
- charCode = entry.getIndex();
+ if (charOffsets == null) {
+ List<OFMtxEntry> mtx = ttfFont.getMtx();
+ OFTableName glyfTag = OFTableName.GLYF;
+ charOffsets = new HashMap<Integer, int[]>();
+ OFDirTabEntry tabEntry = ttfFont.getDirectoryEntry(glyfTag);
+ if (ttfFont.seekTab(reader, glyfTag, 0)) {
+ for (int i = 1; i < mtx.size(); i++) {
+ OFMtxEntry entry = mtx.get(i);
+ OFMtxEntry nextEntry;
+ int nextOffset = 0;
+ int charCode = 0;
+ if (entry.getUnicodeIndex().size() > 0) {
+ charCode = (Integer) entry.getUnicodeIndex().get(0);
+ } else {
+ charCode = entry.getIndex();
+ }
+
+ if (i < mtx.size() - 1) {
+ nextEntry = mtx.get(i + 1);
+ nextOffset = (int) nextEntry.getOffset();
+ } else {
+ nextOffset = (int) ttfFont.getLastGlyfLocation();
+ }
+ int glyphOffset = (int) entry.getOffset();
+ int glyphLength = nextOffset - glyphOffset;
+
+ charOffsets.put(charCode, new int[]{(int) tabEntry.getOffset() + glyphOffset, glyphLength});
}
-
- if (i < mtx.size() - 1) {
- nextEntry = mtx.get(i + 1);
- nextOffset = (int) nextEntry.getOffset();
- } else {
- nextOffset = (int) ttfFont.getLastGlyfLocation();
- }
- int glyphOffset = (int) entry.getOffset();
- int glyphLength = nextOffset - glyphOffset;
-
- charOffsets.put(charCode, new int[]{(int) tabEntry.getOffset() + glyphOffset, glyphLength});
}
}
return charOffsets;
if (tabEntry != null) {
baos.write(tabEntry.getTag());
// Override the original checksum for the subset version
- baos.write(pclByteWriter.unsignedLongInt(getCheckSum(hmtxTable, 0, hmtxTable.length)));
+ baos.write(PCLByteWriterUtil.unsignedLongInt(getCheckSum(hmtxTable, 0, hmtxTable.length)));
TableOffset newTableOffset = new TableOffset(-1, hmtxTable.length, baos.size());
tableOffsets.add(newTableOffset);
- baos.write(pclByteWriter.unsignedLongInt(0)); // Offset to be set later
- baos.write(pclByteWriter.unsignedLongInt(hmtxTable.length));
+ baos.write(PCLByteWriterUtil.unsignedLongInt(0)); // Offset to be set later
+ baos.write(PCLByteWriterUtil.unsignedLongInt(hmtxTable.length));
}
}
out[offset] = b1;
out[offset + 1] = b2;
}
+
+ public Map<Integer, Integer> scanMtxCharacters() throws IOException {
+ if (charMtxOffsets == null) {
+ charMtxOffsets = new HashMap<Integer, Integer>();
+ List<OFMtxEntry> mtx = ttfFont.getMtx();
+ OFTableName glyfTag = OFTableName.GLYF;
+ if (ttfFont.seekTab(reader, glyfTag, 0)) {
+ for (int i = 1; i < mtx.size(); i++) {
+ OFMtxEntry entry = mtx.get(i);
+ int charCode = 0;
+ if (entry.getUnicodeIndex().size() > 0) {
+ charCode = (Integer) entry.getUnicodeIndex().get(0);
+ } else {
+ charCode = entry.getIndex();
+ }
+ charMtxOffsets.put(charCode, i);
+ }
+ }
+ }
+ return charMtxOffsets;
+ }
}
import java.awt.Color;
import java.awt.Dimension;
+import java.awt.FontFormatException;
import java.awt.Rectangle;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
import javax.xml.transform.stream.StreamResult;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FopFactory;
+import org.apache.fop.fonts.EmbeddingMode;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontType;
+import org.apache.fop.fonts.MultiByteFont;
import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFException;
+import org.apache.fop.render.java2d.CustomFontMetricsMapper;
import junit.framework.Assert;
Assert.assertTrue(output.toString().contains("*v255a0b0c0I\u001B*v0S\u001B*c0.01h0.01V\u001B*c0P"));
}
+ @Test
+ public void testTruetype() throws IFException, IOException, FontFormatException, URISyntaxException {
+ String optimizeResources = getPCL(true).toString();
+ String notOptimizeResources = getPCL(false).toString();
+ Assert.assertTrue(notOptimizeResources.contains("DejaVu"));
+ Assert.assertFalse(optimizeResources.contains("DejaVu"));
+ Assert.assertEquals(optimizeResources.length(), 935);
+ }
+
+ private ByteArrayOutputStream getPCL(boolean optimizeResources)
+ throws IFException, URISyntaxException, IOException, FontFormatException {
+ Rectangle size = new Rectangle(1, 1);
+ PCLPageDefinition pclPageDef = new PCLPageDefinition("", 0, new Dimension(), size, true);
+ PCLDocumentHandler documentHandler = new PCLDocumentHandler(new IFContext(ua));
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ documentHandler.setResult(new StreamResult(output));
+ documentHandler.startDocument();
+ PCLPainter pclPainter = new PCLPainter(documentHandler, pclPageDef);
+ pclPainter.getPCLUtil().setOptimizeResources(optimizeResources);
+ FontInfo fi = new FontInfo();
+ fi.addFontProperties("", "", "", 0);
+ MultiByteFont mbf = new MultiByteFont(ua.getResourceResolver(), EmbeddingMode.AUTO);
+ mbf.setEmbedURI(new URI("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"));
+ mbf.setFontType(FontType.TRUETYPE);
+ fi.addMetrics("", new CustomFontMetricsMapper(mbf));
+ documentHandler.setFontInfo(fi);
+ pclPainter.setFont("", "", 0, "", 0, Color.BLACK);
+ pclPainter.drawText(0, 0, 0, 0, null, "test");
+ return output;
+ }
+
}
public class MockPCLTTFFontReader extends PCLTTFFontReader {
- public MockPCLTTFFontReader(Typeface font, PCLByteWriterUtil pclByteWriter) throws IOException {
- super(font, pclByteWriter);
+ public MockPCLTTFFontReader(Typeface font) throws IOException {
+ super(font);
}
@Override
import java.io.IOException;
-import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
public class PCLByteWriterUtilTestCase {
- private PCLByteWriterUtil byteWriter;
-
- @Before
- public void setUp() {
- byteWriter = new PCLByteWriterUtil();
- }
@Test
public void testWriteMethods() throws IOException {
- byte[] output = byteWriter.writeCommand("(s4X");
+ byte[] output = PCLByteWriterUtil.writeCommand("(s4X");
// 27 = PCL escape character with rest in ASCII format
byte[] command = {27, 40, 115, 52, 88};
assertArrayEquals(command, output);
- byte[] resultB = byteWriter.unsignedLongInt(102494);
+ byte[] resultB = PCLByteWriterUtil.unsignedLongInt(102494);
byte[] compareB = {0, 1, -112, 94};
assertArrayEquals(compareB, resultB);
- byte[] resultC = byteWriter.unsignedInt(1024);
+ byte[] resultC = PCLByteWriterUtil.unsignedInt(1024);
byte[] compareC = {4, 0};
assertArrayEquals(compareC, resultC);
}
public void testUtilMethods() throws IOException {
byte[] anArray = {1, 2, 3, 4, 5, 9, 10};
byte[] insertArray = {6, 7, 8};
- byte[] result = byteWriter.insertIntoArray(5, anArray, insertArray);
+ byte[] result = PCLByteWriterUtil.insertIntoArray(5, anArray, insertArray);
byte[] compareA = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
assertArrayEquals(compareA, result);
byte[] reverse = {10, 9, 8, 7, 6};
- byteWriter.updateDataAtLocation(compareA, reverse, 5);
+ PCLByteWriterUtil.updateDataAtLocation(compareA, reverse, 5);
byte[] compareB = {1, 2, 3, 4, 5, 10, 9, 8, 7, 6};
assertArrayEquals(compareB, compareA);
byte[] anArrayC = {1, 2, 3, 4, 5};
- byte[] resultC = byteWriter.padBytes(anArrayC, 10);
+ byte[] resultC = PCLByteWriterUtil.padBytes(anArrayC, 10);
byte[] compareC = {1, 2, 3, 4, 5, 0, 0, 0, 0, 0};
assertArrayEquals(compareC, resultC);
- byte[] resultD = byteWriter.padBytes(anArrayC, 10, 1);
+ byte[] resultD = PCLByteWriterUtil.padBytes(anArrayC, 10, 1);
byte[] compareD = {1, 2, 3, 4, 5, 1, 1, 1, 1, 1};
assertArrayEquals(compareD, resultD);
}
// Have to mock the input stream twice otherwise get a Stream is closed exception
when(((CustomFont) customFont.getRealFont()).getInputStream()).thenReturn(
new FileInputStream(new File(TEST_FONT_TTF)));
- PCLFontReaderFactory fontReaderFactory = PCLFontReaderFactory.getInstance(null);
- assertTrue(fontReaderFactory.createInstance(customFont) instanceof PCLTTFFontReader);
+ assertTrue(PCLFontReaderFactory.createInstance(customFont) instanceof PCLTTFFontReader);
}
}
import java.util.List;
import java.util.Map;
-import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
public class PCLTTFFontReaderTestCase {
private CustomFontMetricsMapper customFont = mock(CustomFontMetricsMapper.class);
- private PCLByteWriterUtil byteWriter;
private static final String TEST_FONT_A = "./test/resources/fonts/ttf/DejaVuLGCSerif.ttf";
- @Before
- public void setUp() {
- byteWriter = new PCLByteWriterUtil();
- }
-
@Test
public void verifyFontAData() throws Exception {
CustomFont sbFont = mock(CustomFont.class);
when(font.getGIDFromChar('e')).thenReturn(101);
when(font.getGIDFromChar('l')).thenReturn(108);
when(font.getGIDFromChar('o')).thenReturn(111);
- PCLTTFFontReader reader = new MockPCLTTFFontReader(customFont, byteWriter);
+ PCLTTFFontReader reader = new MockPCLTTFFontReader(customFont);
reader.setFont(font);
verifyFontData(reader);
validateOffsets(reader);
public void verifyCharacterDefinition() throws Exception {
CustomFont sbFont = mock(CustomFont.class);
when(customFont.getRealFont()).thenReturn(sbFont);
+ when(sbFont.getInputStream()).thenReturn(new FileInputStream(TEST_FONT_A));
softFont = new PCLSoftFont(1, customFont, false);
TTFFile openFont = new TTFFile();
FontFileReader reader = new FontFileReader(new FileInputStream(new File(TEST_FONT_A)));
openFont.readFont(reader, header);
softFont.setOpenFont(openFont);
softFont.setReader(reader);
+ softFont.setMtxCharIndexes(new PCLTTFFontReader(customFont).scanMtxCharacters());
characterWriter = new PCLTTFCharacterWriter(softFont);
byte[] charDefinition = characterWriter.writeCharacterDefinitions("f");
- PCLByteWriterUtil pclByteWriter = new PCLByteWriterUtil();
// Character command
- byte[] command = pclByteWriter.writeCommand(String.format("*c%dE", 32));
+ byte[] command = PCLByteWriterUtil.writeCommand(String.format("*c%dE", 32));
assertArrayEquals(getBytes(charDefinition, 0, 6), command);
// Character definition command
- byte[] charDefCommand = pclByteWriter.writeCommand(String.format("(s%dW", 210));
+ byte[] charDefCommand = PCLByteWriterUtil.writeCommand(String.format("(s%dW", 210));
assertArrayEquals(getBytes(charDefinition, 6, 7), charDefCommand);
}