Categories:
Audio (13)
Biotech (29)
Bytecode (36)
Database (77)
Framework (7)
Game (7)
General (507)
Graphics (53)
I/O (35)
IDE (2)
JAR Tools (101)
JavaBeans (21)
JDBC (121)
JDK (426)
JSP (20)
Logging (108)
Mail (58)
Messaging (8)
Network (84)
PDF (97)
Report (7)
Scripting (84)
Security (32)
Server (121)
Servlet (26)
SOAP (24)
Testing (54)
Web (15)
XML (309)
Collections:
Other Resources:
What Is fop.jar in fop-2.7-bin.zip
What Is fop.jar? I got it from the fop-2.7-bin.zip.
✍: FYIcenter.com
fop.jar in fop-2.7-bin.zip is the JAR file for FOP 2.7, which is a print formatter driven by XSL formatting objects (XSL-FO). You can obtain fop.jar from the build folder of the fop-2.7-bin.zip file.
Below is the information about the fop.jar (2.2) file:
JAR File Size and Download Location:
JAR name: fop.jar, fop-2.7.jar Target JDK version: 1.7 File name: fop.jar File size: 4442817 bytes Release date: 20-Jan-2022 Download: Apache FOP Website
Java source code files for fop.jar:
⏎ org/apache/fop/render/ps/PSFontUtils.java
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: PSFontUtils.java 1812122 2017-10-13 12:12:52Z ssteiner $ */ package org.apache.fop.render.ps; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.fontbox.cff.CFFStandardString; import org.apache.xmlgraphics.fonts.Glyphs; import org.apache.xmlgraphics.java2d.GeneralGraphics2DImagePainter; import org.apache.xmlgraphics.ps.DSCConstants; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.PSResource; import org.apache.xmlgraphics.ps.dsc.ResourceTracker; import org.apache.fop.fonts.Base14Font; import org.apache.fop.fonts.CFFToType1Font; import org.apache.fop.fonts.CIDFontType; import org.apache.fop.fonts.CIDSet; import org.apache.fop.fonts.CMapSegment; import org.apache.fop.fonts.CustomFont; import org.apache.fop.fonts.EmbeddingMode; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontTriplet; import org.apache.fop.fonts.FontType; import org.apache.fop.fonts.LazyFont; import org.apache.fop.fonts.MultiByteFont; import org.apache.fop.fonts.SingleByteEncoding; import org.apache.fop.fonts.SingleByteFont; import org.apache.fop.fonts.Typeface; import org.apache.fop.fonts.cff.CFFDataReader; import org.apache.fop.fonts.cff.CFFDataReader.DICTEntry; import org.apache.fop.fonts.truetype.FontFileReader; import org.apache.fop.fonts.truetype.OFFontLoader; import org.apache.fop.fonts.truetype.OTFFile; import org.apache.fop.fonts.truetype.OTFSubSetFile; import org.apache.fop.fonts.truetype.OpenFont.PostScriptVersion; import org.apache.fop.fonts.truetype.TTFFile; import org.apache.fop.fonts.truetype.TTFOutputStream; import org.apache.fop.fonts.truetype.TTFSubSetFile; import org.apache.fop.fonts.type1.Type1SubsetFile; import org.apache.fop.render.ps.fonts.PSTTFOutputStream; import org.apache.fop.util.HexEncoder; /** * Utility code for font handling in PostScript. */ // @SuppressFBWarnings("NM_SAME_SIMPLE_NAME_AS_SUPERCLASS") public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { /** logging instance */ protected static final Log log = LogFactory.getLog(PSFontUtils.class); /** * Generates the PostScript code for the font dictionary. This method should only be * used if no "resource optimization" is performed, i.e. when the fonts are not embedded * in a second pass. * @param gen PostScript generator to use for output * @param fontInfo available fonts * @return a Map of PSResource instances representing all defined fonts (key: font key) * @throws IOException in case of an I/O problem */ public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo) throws IOException { return writeFontDict(gen, fontInfo, null); } /** * Generates the PostScript code for the font dictionary. This method should only be * used if no "resource optimization" is performed, i.e. when the fonts are not embedded * in a second pass. * @param gen PostScript generator to use for output * @param fontInfo available fonts * @param eventProducer to report events * @return a Map of PSResource instances representing all defined fonts (key: font key) * @throws IOException in case of an I/O problem */ public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, PSEventProducer eventProducer) throws IOException { return writeFontDict(gen, fontInfo, fontInfo.getFonts(), true, eventProducer); } /** * Generates the PostScript code for the font dictionary. This method assumes all used * fonts and characters are known, i.e. when PostScript is generated with resource * optimization turned on. * @param gen PostScript generator to use for output * @param fontInfo available fonts * @param fonts the set of fonts to work with * @param eventProducer the event producer * @return a Map of PSResource instances representing all defined fonts (key: font key) * @throws IOException in case of an I/O problem */ public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map<String, Typeface> fonts, PSEventProducer eventProducer) throws IOException { return writeFontDict(gen, fontInfo, fonts, false, eventProducer); } /** * Generates the PostScript code for the font dictionary. * @param gen PostScript generator to use for output * @param fontInfo available fonts * @param fonts the set of fonts to work with * @param encodeAllCharacters true if all characters shall be encoded using additional, * generated encodings. * @return a Map of PSResource instances representing all defined fonts (key: font key) * @throws IOException in case of an I/O problem */ private static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map<String, Typeface> fonts, boolean encodeAllCharacters, PSEventProducer eventProducer) throws IOException { gen.commentln("%FOPBeginFontDict"); Map fontResources = new HashMap(); for (String key : fonts.keySet()) { Typeface tf = getTypeFace(fontInfo, fonts, key); PSFontResource fontResource = embedFont(gen, tf, eventProducer); fontResources.put(key, fontResource); if (tf instanceof SingleByteFont) { SingleByteFont sbf = (SingleByteFont)tf; if (encodeAllCharacters) { sbf.encodeAllUnencodedCharacters(); } for (int i = 0, c = sbf.getAdditionalEncodingCount(); i < c; i++) { SingleByteEncoding encoding = sbf.getAdditionalEncoding(i); defineEncoding(gen, encoding); String postFix = "_" + (i + 1); PSResource derivedFontRes; if (tf.getFontType() == FontType.TRUETYPE && sbf.getTrueTypePostScriptVersion() != PostScriptVersion.V2) { derivedFontRes = defineDerivedTrueTypeFont(gen, eventProducer, tf.getEmbedFontName(), tf.getEmbedFontName() + postFix, encoding, sbf.getCMap()); } else { derivedFontRes = defineDerivedFont(gen, tf.getEmbedFontName(), tf.getEmbedFontName() + postFix, encoding.getName()); } fontResources.put(key + postFix, PSFontResource.createFontResource(derivedFontRes)); } } } gen.commentln("%FOPEndFontDict"); reencodeFonts(gen, fonts); return fontResources; } private static void reencodeFonts(PSGenerator gen, Map<String, Typeface> fonts) throws IOException { ResourceTracker tracker = gen.getResourceTracker(); if (!tracker.isResourceSupplied(WINANSI_ENCODING_RESOURCE)) { //Only out Base 14 fonts still use that for (Typeface tf : fonts.values()) { if (tf instanceof LazyFont) { tf = ((LazyFont)tf).getRealFont(); if (tf instanceof SingleByteFont && ((SingleByteFont) tf).getEncoding().getName().equals("custom")) { defineEncoding(gen, ((SingleByteFont) tf).getEncoding()); } } } defineWinAnsiEncoding(gen); } gen.commentln("%FOPBeginFontReencode"); //Rewrite font encodings for (Map.Entry<String, Typeface> e : fonts.entrySet()) { String key = e.getKey(); Typeface tf = e.getValue(); if (tf instanceof LazyFont) { tf = ((LazyFont)tf).getRealFont(); if (tf == null) { continue; } } if (null == tf.getEncodingName()) { //ignore (ZapfDingbats and Symbol used to run through here, kept for safety reasons) } else if ("SymbolEncoding".equals(tf.getEncodingName())) { //ignore (no encoding redefinition) } else if ("ZapfDingbatsEncoding".equals(tf.getEncodingName())) { //ignore (no encoding redefinition) } else { if (tf instanceof Base14Font) { //Our Base 14 fonts don't use the default encoding redefineFontEncoding(gen, tf.getEmbedFontName(), tf.getEncodingName()); } else if (tf instanceof SingleByteFont) { SingleByteFont sbf = (SingleByteFont)tf; if (!sbf.isUsingNativeEncoding()) { //Font has been configured to use an encoding other than the default one redefineFontEncoding(gen, tf.getEmbedFontName(), tf.getEncodingName()); } } } } gen.commentln("%FOPEndFontReencode"); } private static Typeface getTypeFace(FontInfo fontInfo, Map<String, Typeface> fonts, String key) { Typeface tf = fonts.get(key); if (tf instanceof LazyFont) { tf = ((LazyFont)tf).getRealFont(); } if (tf == null) { //This is to avoid an NPE if a malconfigured font is in the configuration but not //used in the document. If it were used, we wouldn't get this far. String fallbackKey = fontInfo.getInternalFontKey(Font.DEFAULT_FONT); tf = fonts.get(fallbackKey); } return tf; } private static PSFontResource embedFont(PSGenerator gen, Typeface tf, PSEventProducer eventProducer) throws IOException { boolean embeddedFont = false; FontType fontType = tf.getFontType(); PSFontResource fontResource = null; PSResource fontRes = new PSResource(PSResource.TYPE_FONT, tf.getEmbedFontName()); if (!(fontType == FontType.TYPE1 || fontType == FontType.TRUETYPE || fontType == FontType.TYPE0 || fontType == FontType.TYPE1C) || !(tf instanceof CustomFont)) { gen.writeDSCComment(DSCConstants.INCLUDE_RESOURCE, fontRes); fontResource = PSFontResource.createFontResource(fontRes); return fontResource; } CustomFont cf = (CustomFont)tf; if (isEmbeddable(cf)) { List<InputStream> ins = getInputStreamOnFont(gen, cf); if (ins != null) { int i = 0; for (InputStream in : ins) { if (i > 0) { fontRes = new PSResource(PSResource.TYPE_FONT, tf.getEmbedFontName() + "." + i); } if (fontType == FontType.TYPE0 || fontType == FontType.TYPE1C) { if (((MultiByteFont) tf).isOTFFile()) { checkPostScriptLevel3(gen, eventProducer, "OpenType CFF"); embedType2CFF(gen, (MultiByteFont) tf, in); } else { if (gen.embedIdentityH()) { checkPostScriptLevel3(gen, eventProducer, "TrueType"); /* * First CID-keyed font to be embedded; add * %%IncludeResource: comment for ProcSet CIDInit. */ gen.includeProcsetCIDInitResource(); } PSResource cidFontResource; cidFontResource = embedType2CIDFont(gen, (MultiByteFont) tf, in); fontResource = PSFontResource.createFontResource(fontRes, gen.getProcsetCIDInitResource(), gen.getIdentityHCMapResource(), cidFontResource); } } gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, fontRes); if (fontType == FontType.TYPE1) { embedType1Font(gen, (CustomFont) tf, in); if (fontResource == null) { fontResource = PSFontResource.createFontResource(fontRes); } } else if (fontType == FontType.TRUETYPE) { embedTrueTypeFont(gen, (SingleByteFont) tf, in); fontResource = PSFontResource.createFontResource(fontRes); } else if (!((MultiByteFont) tf).isOTFFile()) { composeType0Font(gen, (MultiByteFont) tf); } gen.writeDSCComment(DSCConstants.END_RESOURCE); gen.getResourceTracker().registerSuppliedResource(fontRes); embeddedFont = true; i++; } } else { gen.commentln("%WARNING: Could not embed font: " + cf.getEmbedFontName()); log.warn("Font " + cf.getEmbedFontName() + " is marked as supplied in the" + " PostScript file but could not be embedded!"); } } if (!embeddedFont) { gen.writeDSCComment(DSCConstants.INCLUDE_RESOURCE, fontRes); fontResource = PSFontResource.createFontResource(fontRes); } return fontResource; } private static void checkPostScriptLevel3(PSGenerator gen, PSEventProducer eventProducer, String fontType) { if (gen.getPSLevel() < 3) { if (eventProducer != null) { eventProducer.postscriptLevel3Needed(gen); } else { throw new IllegalStateException("PostScript Level 3 is" + " required to use " + fontType + " fonts," + " configured level is " + gen.getPSLevel()); } } } private static void embedType1Font(PSGenerator gen, CustomFont font, InputStream fontStream) throws IOException { if (font.getEmbeddingMode() == EmbeddingMode.AUTO) { font.setEmbeddingMode(EmbeddingMode.FULL); } byte[] fullFont = IOUtils.toByteArray(fontStream); fontStream = new ByteArrayInputStream(fullFont); boolean embed = true; if (font.getEmbeddingMode() == EmbeddingMode.SUBSET) { Type1SubsetFile subset = new Type1SubsetFile(); byte[] byteSubset = subset.createSubset(fontStream, (SingleByteFont) font); fontStream = new ByteArrayInputStream(byteSubset); } embedType1Font(gen, fontStream); if (font.getEmbeddingMode() == EmbeddingMode.SUBSET) { writeEncoding(gen, (SingleByteFont) font); } } private static void writeEncoding(PSGenerator gen, SingleByteFont font) throws IOException { String psName = font.getEmbedFontName(); gen.writeln("/" + psName + ".0.enc [ "); int lengthCount = 0; int charCount = 1; int encodingCount = 0; StringBuilder line = new StringBuilder(); int lastGid = 0; Set<Integer> keySet = font.getUsedGlyphNames().keySet(); for (int gid : keySet) { for (int i = lastGid; i < gid - 1; i++) { line.append("/.notdef "); lengthCount++; if (lengthCount == 8) { gen.writeln(line.toString()); line = new StringBuilder(); lengthCount = 0; } } lastGid = gid; line.append(font.getUsedGlyphNames().get(gid) + " "); lengthCount++; charCount++; if (lengthCount == 8) { gen.writeln(line.toString()); line = new StringBuilder(); lengthCount = 0; } if (charCount > 256) { encodingCount++; charCount = 1; gen.writeln(line.toString()); line = new StringBuilder(); lengthCount = 0; gen.writeln("] def"); gen.writeln(String.format("/%s.%d %s.%d.enc /%s RE", psName, encodingCount - 1, psName, encodingCount - 1, psName)); gen.writeln("/" + psName + "." + encodingCount + ".enc [ "); } } gen.writeln(line.toString()); gen.writeln("] def"); gen.writeln(String.format("/%s.%d %s.%d.enc /%s RE", psName, encodingCount, psName, encodingCount, psName)); } private static void embedTrueTypeFont(PSGenerator gen, SingleByteFont font, InputStream fontStream) throws IOException { /* See Adobe Technical Note #5012, "The Type 42 Font Format Specification" */ gen.commentln("%!PS-TrueTypeFont-65536-65536-1"); // TODO TrueType & font versions gen.writeln("11 dict begin"); if (font.getEmbeddingMode() == EmbeddingMode.AUTO) { font.setEmbeddingMode(EmbeddingMode.SUBSET); } FontFileReader reader = new FontFileReader(fontStream); TTFFile ttfFile = new TTFFile(); ttfFile.readFont(reader, font.getFullName()); createType42DictionaryEntries(gen, font, font.getCMap(), ttfFile); gen.writeln("FontName currentdict end definefont pop"); } private static void createType42DictionaryEntries(PSGenerator gen, CustomFont font, CMapSegment[] cmap, TTFFile ttfFile) throws IOException { gen.write("/FontName /"); gen.write(font.getEmbedFontName()); gen.writeln(" def"); gen.writeln("/PaintType 0 def"); gen.writeln("/FontMatrix [1 0 0 1 0 0] def"); writeFontBBox(gen, font); gen.writeln("/FontType 42 def"); gen.writeln("/Encoding 256 array"); gen.writeln("0 1 255{1 index exch/.notdef put}for"); boolean buildCharStrings; Set<String> glyphNames = new HashSet<String>(); if (font.getFontType() == FontType.TYPE0 && font.getEmbeddingMode() != EmbeddingMode.FULL) { //"/Encoding" is required but ignored for CID fonts //so we keep it minimal to save space buildCharStrings = false; } else { buildCharStrings = true; for (int i = 0; i < Glyphs.WINANSI_ENCODING.length; i++) { gen.write("dup "); gen.write(i); gen.write(" /"); String glyphName = Glyphs.charToGlyphName(Glyphs.WINANSI_ENCODING[i]); if (glyphName.equals("")) { gen.write(Glyphs.NOTDEF); } else { gen.write(glyphName); glyphNames.add(glyphName); } gen.writeln(" put"); } } gen.writeln("readonly def"); TTFOutputStream ttfOut = new PSTTFOutputStream(gen); ttfFile.stream(ttfOut); buildCharStrings(gen, buildCharStrings, cmap, glyphNames, font); } private static void buildCharStrings(PSGenerator gen, boolean buildCharStrings, CMapSegment[] cmap, Set<String> glyphNames, CustomFont font) throws IOException { gen.write("/CharStrings "); if (!buildCharStrings) { gen.write(1); } else if (font.getEmbeddingMode() != EmbeddingMode.FULL) { int charCount = 1; //1 for .notdef for (CMapSegment segment : cmap) { charCount += segment.getUnicodeEnd() - segment.getUnicodeStart() + 1; } gen.write(charCount); } else { gen.write(font.getCMap().length); } gen.writeln(" dict dup begin"); gen.write("/"); gen.write(Glyphs.NOTDEF); gen.writeln(" 0 def"); // .notdef always has to be at index 0 if (!buildCharStrings) { // If we're not building the full CharStrings we can end here gen.writeln("end readonly def"); return; } if (font.getEmbeddingMode() != EmbeddingMode.FULL) { //Only performed in singly-byte mode, ignored for CID fonts for (CMapSegment segment : cmap) { int glyphIndex = segment.getGlyphStartIndex(); for (int ch = segment.getUnicodeStart(); ch <= segment.getUnicodeEnd(); ch++) { char ch16 = (char)ch; //TODO Handle Unicode characters beyond 16bit String glyphName = Glyphs.charToGlyphName(ch16); if ("".equals(glyphName)) { glyphName = "u" + Integer.toHexString(ch).toUpperCase(Locale.ENGLISH); } writeGlyphDefs(gen, glyphName, glyphIndex); glyphIndex++; } } } else { for (String name : glyphNames) { writeGlyphDefs(gen, name, getGlyphIndex(Glyphs.getUnicodeSequenceForGlyphName(name).charAt(0), font.getCMap())); } } gen.writeln("end readonly def"); } private static void writeGlyphDefs(PSGenerator gen, String glyphName, int glyphIndex) throws IOException { gen.write("/"); gen.write(glyphName); gen.write(" "); gen.write(glyphIndex); gen.writeln(" def"); } private static int getGlyphIndex(char c, CMapSegment[] cmap) { for (CMapSegment segment : cmap) { if (segment.getUnicodeStart() <= c && c <= segment.getUnicodeEnd()) { return segment.getGlyphStartIndex() + c - segment.getUnicodeStart(); } } return 0; } private static void composeType0Font(PSGenerator gen, MultiByteFont font) throws IOException { String psName = font.getEmbedFontName(); gen.write("/"); gen.write(psName); gen.write(" /Identity-H [/"); gen.write(psName); gen.writeln("] composefont pop"); } private static void embedType2CFF(PSGenerator gen, MultiByteFont font, InputStream fontStream) throws IOException { FontFileReader reader = new FontFileReader(fontStream); String psName; CFFDataReader cffReader = new CFFDataReader(reader); if (cffReader.getFDSelect() != null) { throw new UnsupportedOperationException("CID-Keyed OTF CFF fonts are not supported" + " for PostScript output."); } byte[] bytes; if (font.getEmbeddingMode() == EmbeddingMode.FULL) { font.setFontName(new String(cffReader.getNameIndex().getValue(0))); psName = font.getEmbedFontName(); Map<String, DICTEntry> topDICT = cffReader.getTopDictEntries(); int charsetOffset = topDICT.get("charset").getOperands().get(0).intValue(); for (int gid = 0; gid < cffReader.getCharStringIndex().getNumObjects(); gid++) { int sid = cffReader.getSIDFromGID(charsetOffset, gid); //Check whether the SID falls into the standard string set if (sid < 391) { font.mapUsedGlyphName(gid, CFFStandardString.getName(sid)); } else { int index = sid - 391; if (index < cffReader.getStringIndex().getNumObjects()) { font.mapUsedGlyphName(gid, new String(cffReader.getStringIndex().getValue(index))); } else { font.mapUsedGlyphName(gid, ".notdef"); } } } bytes = OTFFile.getCFFData(reader); } else { psName = font.getEmbedFontName(); OTFSubSetFile otfFile = new OTFSubSetFile(); otfFile.readFont(reader, psName, font); bytes = otfFile.getFontSubset(); } gen.writeln("%!PS-Adobe-3.0 Resource-FontSet"); gen.writeln("%%DocumentNeedResources:ProcSet(FontSetInit)"); gen.writeln("%%Title:(FontSet/" + psName + ")"); gen.writeln("%%Version: 1.000"); gen.writeln("%%EndComments"); gen.writeln("%%IncludeResource:ProcSet(FontSetInit)"); gen.writeln("%%BeginResource: FontSet (" + psName + ")"); gen.writeln("/FontSetInit /ProcSet findresource begin"); //Next line + 1 String fontDeclaration = "/" + psName + " " + bytes.length + " StartData"; gen.writeln("%%BeginData: " + (fontDeclaration.length() + 1 + bytes.length) + " Binary Bytes"); gen.writeln(fontDeclaration); gen.writeByteArr(bytes); gen.writeln("%%EndData"); gen.writeln("%%EndResource"); gen.writeln("/" + psName + ".0.enc [ "); int lengthCount = 0; int charCount = 1; int encodingCount = 0; String line = ""; for (int gid : font.getUsedGlyphNames().keySet()) { line += "/" + font.getUsedGlyphNames().get(gid) + " "; lengthCount++; charCount++; if (lengthCount == 8) { gen.writeln(line); line = ""; lengthCount = 0; } if (charCount > 256) { encodingCount++; charCount = 1; gen.writeln(line); line = ""; lengthCount = 0; gen.writeln("] def"); gen.writeln(String.format("/%s.%d %s.%d.enc /%s RE", psName, encodingCount - 1, psName, encodingCount - 1, psName)); gen.writeln("/" + psName + "." + encodingCount + ".enc [ "); } } gen.writeln(line); gen.writeln("] def"); gen.writeln(String.format("/%s.%d %s.%d.enc /%s RE", psName, encodingCount, psName, encodingCount, psName)); } private static PSResource embedType2CIDFont(PSGenerator gen, MultiByteFont font, InputStream fontStream) throws IOException { assert font.getCIDType() == CIDFontType.CIDTYPE2; String psName = font.getEmbedFontName(); gen.write("%%BeginResource: CIDFont "); gen.writeln(psName); gen.write("%%Title: ("); gen.write(psName); gen.writeln(" Adobe Identity 0)"); gen.writeln("%%Version: 1"); // TODO use font revision? gen.writeln("/CIDInit /ProcSet findresource begin"); gen.writeln("20 dict begin"); gen.write("/CIDFontName /"); gen.write(psName); gen.writeln(" def"); gen.writeln("/CIDFontVersion 1 def"); // TODO same as %%Version above gen.write("/CIDFontType "); gen.write(font.getCIDType().getValue()); gen.writeln(" def"); gen.writeln("/CIDSystemInfo 3 dict dup begin"); gen.writeln(" /Registry (Adobe) def"); gen.writeln(" /Ordering (Identity) def"); gen.writeln(" /Supplement 0 def"); gen.writeln("end def"); // TODO UIDBase (and UIDOffset in CMap) necessary if PostScript Level 1 & 2 // interpreters are to be supported // (Level 1: with composite font extensions; Level 2: those that do not offer // native mode support for CID-keyed fonts) // TODO XUID (optional but strongly recommended) // TODO /FontInfo gen.write("/CIDCount "); CIDSet cidSet = font.getCIDSet(); int numberOfGlyphs = cidSet.getNumberOfGlyphs(); gen.write(numberOfGlyphs); gen.writeln(" def"); gen.writeln("/GDBytes 2 def"); // TODO always 2? gen.writeln("/CIDMap [<"); int colCount = 0; int lineCount = 1; int nextBitSet = 0; int previousBitSet = 0; for (int cid = 0; cid < numberOfGlyphs; cid++) { if (colCount++ == 20) { gen.newLine(); colCount = 1; if (lineCount++ == 800) { gen.writeln("> <"); lineCount = 1; } } String gid; if (font.getEmbeddingMode() != EmbeddingMode.FULL) { gid = HexEncoder.encode(cid, 4); } else { previousBitSet = nextBitSet; nextBitSet = cidSet.getGlyphIndices().nextSetBit(nextBitSet); while (previousBitSet++ < nextBitSet) { // if there are gaps in the indices we pad them with zeros gen.write("0000"); cid++; if (colCount++ == 20) { gen.newLine(); colCount = 1; if (lineCount++ == 800) { gen.writeln("> <"); lineCount = 1; } } } gid = HexEncoder.encode(nextBitSet, 4); nextBitSet++; } gen.write(gid); } gen.writeln(">] def"); FontFileReader reader = new FontFileReader(fontStream); String header = OFFontLoader.readHeader(reader); TTFFile ttfFile; if (font.getEmbeddingMode() != EmbeddingMode.FULL) { ttfFile = new TTFSubSetFile(); //Change the TTFFile to have the abstract method for TTFSubSetFile ((TTFSubSetFile)ttfFile).readFont(reader, font.getTTCName(), header, font.getUsedGlyphs()); } else { ttfFile = new TTFFile(); ttfFile.readFont(reader, font.getTTCName()); } createType42DictionaryEntries(gen, font, new CMapSegment[0], ttfFile); gen.writeln("CIDFontName currentdict end /CIDFont defineresource pop"); gen.writeln("end"); gen.writeln("%%EndResource"); PSResource cidFontResource = new PSResource(PSResource.TYPE_CIDFONT, psName); gen.getResourceTracker().registerSuppliedResource(cidFontResource); return cidFontResource; } private static void writeFontBBox(PSGenerator gen, CustomFont font) throws IOException { int[] bbox = font.getFontBBox(); gen.write("/FontBBox["); for (int i = 0; i < 4; i++) { gen.write(" "); gen.write(bbox[i]); } gen.writeln(" ] def"); } private static boolean isEmbeddable(CustomFont font) { return font.isEmbeddable(); } private static List<InputStream> getInputStreamOnFont(PSGenerator gen, CustomFont font) throws IOException { if (isEmbeddable(font)) { List<InputStream> fonts = new ArrayList<InputStream>(); InputStream in = font.getInputStream(); if (in == null) { if (font instanceof CFFToType1Font) { return ((CFFToType1Font) font).getInputStreams(); } return null; } //Make sure the InputStream is decorated with a BufferedInputStream if (!(in instanceof java.io.BufferedInputStream)) { in = new java.io.BufferedInputStream(in); } fonts.add(in); return fonts; } else { return null; } } /** * Determines the set of fonts that will be supplied with the PS file and registers them * with the resource tracker. All the fonts that are being processed are returned as a Map. * @param resTracker the resource tracker * @param fontInfo available fonts * @param fonts the set of fonts to work with * @return a Map of PSResource instances representing all defined fonts (key: font key) */ public static Map determineSuppliedFonts(ResourceTracker resTracker, FontInfo fontInfo, Map<String, Typeface> fonts) { Map fontResources = new java.util.HashMap(); for (String key : fonts.keySet()) { Typeface tf = getTypeFace(fontInfo, fonts, key); PSResource fontRes = new PSResource("font", tf.getEmbedFontName()); fontResources.put(key, fontRes); FontType fontType = tf.getFontType(); if (fontType == FontType.TYPE1 || fontType == FontType.TRUETYPE || fontType == FontType.TYPE0) { if (tf instanceof CustomFont) { CustomFont cf = (CustomFont)tf; if (isEmbeddable(cf)) { if (fontType == FontType.TYPE0) { resTracker.registerSuppliedResource( new PSResource(PSResource.TYPE_CIDFONT, tf.getEmbedFontName())); resTracker.registerSuppliedResource( new PSResource(PSResource.TYPE_CMAP, "Identity-H")); } resTracker.registerSuppliedResource(fontRes); } if (tf instanceof SingleByteFont) { SingleByteFont sbf = (SingleByteFont)tf; for (int i = 0, c = sbf.getAdditionalEncodingCount(); i < c; i++) { SingleByteEncoding encoding = sbf.getAdditionalEncoding(i); PSResource encodingRes = new PSResource( PSResource.TYPE_ENCODING, encoding.getName()); resTracker.registerSuppliedResource(encodingRes); PSResource derivedFontRes = new PSResource( PSResource.TYPE_FONT, tf.getEmbedFontName() + "_" + (i + 1)); resTracker.registerSuppliedResource(derivedFontRes); } } } } } return fontResources; } /** * Defines the single-byte encoding for use in PostScript files. * @param gen the PostScript generator * @param encoding the single-byte encoding * @return the PSResource instance that represents the encoding * @throws IOException In case of an I/O problem */ public static PSResource defineEncoding(PSGenerator gen, SingleByteEncoding encoding) throws IOException { PSResource res = new PSResource(PSResource.TYPE_ENCODING, encoding.getName()); gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, res); gen.writeln("/" + encoding.getName() + " ["); String[] charNames = encoding.getCharNameMap(); for (int i = 0; i < 256; i++) { if (i > 0) { if ((i % 5) == 0) { gen.newLine(); } else { gen.write(" "); } } String glyphname = null; if (i < charNames.length) { glyphname = charNames[i]; } if (glyphname == null || "".equals(glyphname)) { glyphname = Glyphs.NOTDEF; } gen.write("/"); gen.write(glyphname); } gen.newLine(); gen.writeln("] def"); gen.writeDSCComment(DSCConstants.END_RESOURCE); gen.getResourceTracker().registerSuppliedResource(res); return res; } /** * Derives a new font based on an existing font with a given encoding. The encoding must * have been registered before. * @param gen the PostScript generator * @param baseFontName the font name of the font to derive from * @param fontName the font name of the new font to be define * @param encoding the new encoding (must be predefined in the PS file) * @return the PSResource representing the derived font * @throws IOException In case of an I/O problem */ public static PSResource defineDerivedFont( PSGenerator gen, String baseFontName, String fontName, String encoding) throws IOException { PSResource res = new PSResource(PSResource.TYPE_FONT, fontName); gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, res); gen.commentln("%XGCDependencies: font " + baseFontName); gen.commentln("%XGC+ encoding " + encoding); gen.writeln("/" + baseFontName + " findfont"); gen.writeln("dup length dict begin"); gen.writeln(" {1 index /FID ne {def} {pop pop} ifelse} forall"); gen.writeln(" /Encoding " + encoding + " def"); gen.writeln(" currentdict"); gen.writeln("end"); gen.writeln("/" + fontName + " exch definefont pop"); gen.writeDSCComment(DSCConstants.END_RESOURCE); gen.getResourceTracker().registerSuppliedResource(res); return res; } private static PSResource defineDerivedTrueTypeFont(PSGenerator gen, PSEventProducer eventProducer, String baseFontName, String fontName, SingleByteEncoding encoding, CMapSegment[] cmap) throws IOException { checkPostScriptLevel3(gen, eventProducer, "TrueType"); PSResource res = new PSResource(PSResource.TYPE_FONT, fontName); gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, res); gen.commentln("%XGCDependencies: font " + baseFontName); gen.commentln("%XGC+ encoding " + encoding.getName()); gen.writeln("/" + baseFontName + " findfont"); gen.writeln("dup length dict begin"); gen.writeln(" {1 index /FID ne {def} {pop pop} ifelse} forall"); gen.writeln(" /Encoding " + encoding.getName() + " def"); gen.writeln(" /CharStrings 256 dict dup begin"); String[] charNameMap = encoding.getCharNameMap(); char[] unicodeCharMap = encoding.getUnicodeCharMap(); assert charNameMap.length == unicodeCharMap.length; for (int i = 0; i < charNameMap.length; i++) { String glyphName = charNameMap[i]; gen.write(" /"); gen.write(glyphName); gen.write(" "); if (glyphName.equals(".notdef")) { gen.write(0); } else { gen.write(getGlyphIndex(unicodeCharMap[i], cmap)); } gen.writeln(" def"); } gen.writeln(" end readonly def"); gen.writeln(" currentdict"); gen.writeln("end"); gen.writeln("/" + fontName + " exch definefont pop"); gen.writeDSCComment(DSCConstants.END_RESOURCE); gen.getResourceTracker().registerSuppliedResource(res); return res; } public static void addFallbackFonts(FontInfo fontInfo, GeneralGraphics2DImagePainter painter) throws IOException { for (Map.Entry<FontTriplet, String> x : fontInfo.getFontTriplets().entrySet()) { String name = x.getKey().getName(); Typeface typeface = fontInfo.getFonts().get(x.getValue()); painter.addFallbackFont(name, typeface); } } }
⏎ org/apache/fop/render/ps/PSFontUtils.java
Or download all of them as a single archive file:
File name: fop-2.7-src.zip File size: 3401312 bytes Release date: 2022-01-20 Download
⇒ "fop" Command in fop-2.7-bin.zip
2016-07-07, 34547👍, 0💬
Popular Posts:
What is ojdbc.jar - JDBC Driver for Oracle? ojdbc.jar is a JDBC driver from Oracle that provides dat...
How to display types defined in an XML Schema file with the xs\QueryXS.java provided in the Apache X...
Java Architecture for XML Binding (JAXB) is a Java API that allows Java developers to map Java class...
JDK 11 jdk.internal.vm.ci.jmod is the JMOD file for JDK 11 Internal VM CI module. JDK 11 Internal VM...
What is the dom\GetElementsByTagName .javaprovided in the Apache Xerces package? I have Apache Xerce...