浏览代码

FOP-2608: Allow more than 256 glyphs for CFF to Type1

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1745490 13f79535-47bb-0310-9956-ffa450edef68
pull/3/head
Simon Steiner 8 年前
父节点
当前提交
16e07aaae8

+ 39
- 2
fop-core/src/main/java/org/apache/fop/fonts/CFFToType1Font.java 查看文件

import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.fontbox.cff.CFFFont; import org.apache.fontbox.cff.CFFFont;
} }


public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
return null;
}

public List<InputStream> getInputStreams() throws IOException {
InputStream cff = super.getInputStream(); InputStream cff = super.getInputStream();
return convertOTFToType1(cff); return convertOTFToType1(cff);
} }


private InputStream convertOTFToType1(InputStream in) throws IOException {
private List<InputStream> convertOTFToType1(InputStream in) throws IOException {
CFFFont f = new CFFParser().parse(IOUtils.toByteArray(in)).get(0); CFFFont f = new CFFParser().parse(IOUtils.toByteArray(in)).get(0);
if (!(f instanceof CFFType1Font)) { if (!(f instanceof CFFType1Font)) {
throw new IOException(getEmbedFileURI() + ": only OTF CFF Type1 font can be converted to Type1"); throw new IOException(getEmbedFileURI() + ": only OTF CFF Type1 font can be converted to Type1");
} }
byte[] t1 = new Type1FontFormatter(cidSet.getGlyphs(), eventListener).format((CFFType1Font) f);
List<InputStream> fonts = new ArrayList<InputStream>();
Map<Integer, Integer> glyphs = cidSet.getGlyphs();
int i = 0;
for (Map<Integer, Integer> x : splitGlyphs(glyphs)) {
String iStr = "." + i;
fonts.add(convertOTFToType1(x, f, iStr));
i++;
}
return fonts;
}

private List<Map<Integer, Integer>> splitGlyphs(Map<Integer, Integer> glyphs) {
List<Map<Integer, Integer>> allGlyphs = new ArrayList<Map<Integer, Integer>>();
for (Map.Entry<Integer, Integer> x : glyphs.entrySet()) {
int k = x.getKey();
int v = x.getValue();
int pot = v / 256;
v = v % 256;
while (allGlyphs.size() < pot + 1) {
Map<Integer, Integer> glyphsPerFont = new HashMap<Integer, Integer>();
glyphsPerFont.put(0, 0);
allGlyphs.add(glyphsPerFont);
}
allGlyphs.get(pot).put(k, v);
}
return allGlyphs;
}

private InputStream convertOTFToType1(Map<Integer, Integer> glyphs, CFFFont f, String i) throws IOException {
byte[] t1 = new Type1FontFormatter(glyphs).format((CFFType1Font) f, i);
PFBData pfb = new PFBParser().parsePFB(new ByteArrayInputStream(t1)); PFBData pfb = new PFBParser().parsePFB(new ByteArrayInputStream(t1));
ByteArrayOutputStream s1 = new ByteArrayOutputStream(); ByteArrayOutputStream s1 = new ByteArrayOutputStream();
s1.write(pfb.getHeaderSegment()); s1.write(pfb.getHeaderSegment());

+ 0
- 4
fop-core/src/main/java/org/apache/fop/fonts/FontEventAdapter.java 查看文件

getEventProducer().fontDirectoryNotFound(source, dir); getEventProducer().fontDirectoryNotFound(source, dir);
} }


public void fontType1MaxGlyphs(Object source, String fontName) {
getEventProducer().fontType1MaxGlyphs(source, fontName);
}

/** {@inheritDoc} */ /** {@inheritDoc} */
public void svgTextStrokedAsShapes(Object source, String fontFamily) { public void svgTextStrokedAsShapes(Object source, String fontFamily) {
getEventProducer().svgTextStrokedAsShapes(source, fontFamily); getEventProducer().svgTextStrokedAsShapes(source, fontFamily);

+ 0
- 2
fop-core/src/main/java/org/apache/fop/fonts/FontEventListener.java 查看文件

* @param fontFamily the family name of the font that is being stroked * @param fontFamily the family name of the font that is being stroked
*/ */
void svgTextStrokedAsShapes(Object source, String fontFamily); void svgTextStrokedAsShapes(Object source, String fontFamily);

void fontType1MaxGlyphs(Object source, String fontName);
} }

+ 0
- 7
fop-core/src/main/java/org/apache/fop/fonts/FontEventProducer.java 查看文件

*/ */
void svgTextStrokedAsShapes(Object source, String fontFamily); void svgTextStrokedAsShapes(Object source, String fontFamily);


/**
* A method to warn the user that the font has too many glyphs
* @param source
* @param fontName
* @event.severity ERROR
*/
void fontType1MaxGlyphs(Object source, String fontName);
} }

+ 1
- 1
fop-core/src/main/java/org/apache/fop/fonts/truetype/OFFontLoader.java 查看文件

multiFont = new CFFToType1Font(resourceResolver, embeddingMode); multiFont = new CFFToType1Font(resourceResolver, embeddingMode);
} else { } else {
multiFont = new MultiByteFont(resourceResolver, embeddingMode); multiFont = new MultiByteFont(resourceResolver, embeddingMode);
multiFont.setIsOTFFile(otf instanceof OTFFile);
} }
multiFont.setIsOTFFile(otf instanceof OTFFile);
returnFont = multiFont; returnFont = multiFont;
multiFont.setTTCName(ttcFontName); multiFont.setTTCName(ttcFontName);
} else { } else {

+ 53
- 38
fop-core/src/main/java/org/apache/fop/render/ps/PSFontUtils.java 查看文件

import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.xmlgraphics.ps.dsc.ResourceTracker; import org.apache.xmlgraphics.ps.dsc.ResourceTracker;


import org.apache.fop.fonts.Base14Font; import org.apache.fop.fonts.Base14Font;
import org.apache.fop.fonts.CFFToType1Font;
import org.apache.fop.fonts.CIDFontType; import org.apache.fop.fonts.CIDFontType;
import org.apache.fop.fonts.CIDSet; import org.apache.fop.fonts.CIDSet;
import org.apache.fop.fonts.CMapSegment; import org.apache.fop.fonts.CMapSegment;
Map fontResources = new HashMap(); Map fontResources = new HashMap();
for (String key : fonts.keySet()) { for (String key : fonts.keySet()) {
Typeface tf = getTypeFace(fontInfo, fonts, key); Typeface tf = getTypeFace(fontInfo, fonts, key);
PSResource fontRes = new PSResource(PSResource.TYPE_FONT, tf.getEmbedFontName());
PSFontResource fontResource = embedFont(gen, tf, fontRes, eventProducer);
PSFontResource fontResource = embedFont(gen, tf, eventProducer);
fontResources.put(key, fontResource); fontResources.put(key, fontResource);


if (tf instanceof SingleByteFont) { if (tf instanceof SingleByteFont) {
return tf; return tf;
} }


private static PSFontResource embedFont(PSGenerator gen, Typeface tf, PSResource fontRes,
PSEventProducer eventProducer) throws IOException {
private static PSFontResource embedFont(PSGenerator gen, Typeface tf, PSEventProducer eventProducer)
throws IOException {
boolean embeddedFont = false; boolean embeddedFont = false;
FontType fontType = tf.getFontType(); FontType fontType = tf.getFontType();
PSFontResource fontResource = null; PSFontResource fontResource = null;
PSResource fontRes = new PSResource(PSResource.TYPE_FONT, tf.getEmbedFontName());
if (!(fontType == FontType.TYPE1 || fontType == FontType.TRUETYPE if (!(fontType == FontType.TYPE1 || fontType == FontType.TRUETYPE
|| fontType == FontType.TYPE0) || !(tf instanceof CustomFont)) { || fontType == FontType.TYPE0) || !(tf instanceof CustomFont)) {
gen.writeDSCComment(DSCConstants.INCLUDE_RESOURCE, fontRes); gen.writeDSCComment(DSCConstants.INCLUDE_RESOURCE, fontRes);
} }
CustomFont cf = (CustomFont)tf; CustomFont cf = (CustomFont)tf;
if (isEmbeddable(cf)) { if (isEmbeddable(cf)) {
InputStream in = getInputStreamOnFont(gen, cf);
if (in != null) {
if (fontType == FontType.TYPE0) {
if (((MultiByteFont)tf).isOTFFile()) {
checkPostScriptLevel3(gen, eventProducer, "OpenType CFF");
embedType2CFF(gen, (MultiByteFont) tf, in);
} else {
if (gen.embedIdentityH()) {
checkPostScriptLevel3(gen, eventProducer, "TrueType");
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) {
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 * First CID-keyed font to be embedded; add
* %%IncludeResource: comment for ProcSet CIDInit. * %%IncludeResource: comment for ProcSet CIDInit.
*/ */
gen.includeProcsetCIDInitResource();
gen.includeProcsetCIDInitResource();
}
PSResource cidFontResource;
cidFontResource = embedType2CIDFont(gen,
(MultiByteFont) tf, in);
fontResource = PSFontResource.createFontResource(fontRes,
gen.getProcsetCIDInitResource(), gen.getIdentityHCMapResource(),
cidFontResource);
} }
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++;
} }
gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, fontRes);
if (fontType == FontType.TYPE1) {
embedType1Font(gen, (CustomFont) tf, in);
fontResource = PSFontResource.createFontResource(fontRes);
} else if (fontType == FontType.TRUETYPE) {
embedTrueTypeFont(gen, (SingleByteFont) tf, in);
fontResource = PSFontResource.createFontResource(fontRes);
} else {
composeType0Font(gen, (MultiByteFont) tf, in);
}
gen.writeDSCComment(DSCConstants.END_RESOURCE);
gen.getResourceTracker().registerSuppliedResource(fontRes);
embeddedFont = true;
} else { } else {
gen.commentln("%WARNING: Could not embed font: " + cf.getEmbedFontName()); gen.commentln("%WARNING: Could not embed font: " + cf.getEmbedFontName());
log.warn("Font " + cf.getEmbedFontName() + " is marked as supplied in the" log.warn("Font " + cf.getEmbedFontName() + " is marked as supplied in the"
if (!embeddedFont) { if (!embeddedFont) {
gen.writeDSCComment(DSCConstants.INCLUDE_RESOURCE, fontRes); gen.writeDSCComment(DSCConstants.INCLUDE_RESOURCE, fontRes);
fontResource = PSFontResource.createFontResource(fontRes); fontResource = PSFontResource.createFontResource(fontRes);
return fontResource;
} }
return fontResource; return fontResource;
} }
return 0; return 0;
} }


private static void composeType0Font(PSGenerator gen, MultiByteFont font,
InputStream fontStream) throws IOException {
private static void composeType0Font(PSGenerator gen, MultiByteFont font) throws IOException {
String psName = font.getEmbedFontName(); String psName = font.getEmbedFontName();
gen.write("/"); gen.write("/");
gen.write(psName); gen.write(psName);
return font.isEmbeddable(); return font.isEmbeddable();
} }


private static InputStream getInputStreamOnFont(PSGenerator gen, CustomFont font)
private static List<InputStream> getInputStreamOnFont(PSGenerator gen, CustomFont font)
throws IOException { throws IOException {
if (isEmbeddable(font)) { if (isEmbeddable(font)) {
List<InputStream> fonts = new ArrayList<InputStream>();
InputStream in = font.getInputStream(); InputStream in = font.getInputStream();
if (in == null) { if (in == null) {
if (font instanceof CFFToType1Font) {
return ((CFFToType1Font) font).getInputStreams();
}
return null; return null;
} }
//Make sure the InputStream is decorated with a BufferedInputStream //Make sure the InputStream is decorated with a BufferedInputStream
if (!(in instanceof java.io.BufferedInputStream)) { if (!(in instanceof java.io.BufferedInputStream)) {
in = new java.io.BufferedInputStream(in); in = new java.io.BufferedInputStream(in);
} }
return in;
fonts.add(in);
return fonts;
} else { } else {
return null; return null;
} }

+ 5
- 9
fop-core/src/main/java/org/apache/fop/render/ps/PSPainter.java 查看文件

import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.xmlgraphics.ps.PSGenerator;
import org.apache.xmlgraphics.ps.PSResource; import org.apache.xmlgraphics.ps.PSResource;


import org.apache.fop.fonts.CFFToType1Font;
import org.apache.fop.fonts.EmbeddingMode; import org.apache.fop.fonts.EmbeddingMode;
import org.apache.fop.fonts.Font; import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontTriplet; import org.apache.fop.fonts.FontTriplet;
true); true);
start = i; start = i;
} }
generator.writeln("/" + res.getName() + "." + encoding + " "
+ generator.formatDouble(sizeMillipoints / 1000f) + " F");
generator.useFont("/" + res.getName() + "." + encoding, sizeMillipoints / 1000f);
curEncoding = encoding; curEncoding = encoding;
} }
} }
int lineStart = 0; int lineStart = 0;
StringBuffer accText = new StringBuffer(initialSize); StringBuffer accText = new StringBuffer(initialSize);
StringBuffer sb = new StringBuffer(initialSize); StringBuffer sb = new StringBuffer(initialSize);
boolean isOTF = multiByte && ((MultiByteFont)tf).isOTFFile() || tf instanceof CFFToType1Font;
boolean isOTF = multiByte && ((MultiByteFont)tf).isOTFFile();
for (int i = start; i < end; i++) { for (int i = start; i < end; i++) {
char orgChar = text.charAt(i); char orgChar = text.charAt(i);
char ch; char ch;
private void useFont(String key, int size, boolean otf) throws IOException { private void useFont(String key, int size, boolean otf) throws IOException {
PSFontResource res = getDocumentHandler().getPSResourceForFontKey(key); PSFontResource res = getDocumentHandler().getPSResourceForFontKey(key);
PSGenerator generator = getGenerator(); PSGenerator generator = getGenerator();
String name = "/" + res.getName();
if (otf) { if (otf) {
String name = "/" + res.getName() + ".0";
generator.getCurrentState().useFont(name, size);
generator.writeln(name + ' ' + generator.formatDouble(size / 1000f) + " F");
} else {
generator.useFont("/" + res.getName(), size / 1000f);
name += ".0";
} }
generator.useFont(name, size / 1000f);
res.notifyResourceUsageOnPage(generator.getResourceTracker()); res.notifyResourceUsageOnPage(generator.getResourceTracker());
} }
} }

+ 9
- 15
fop-core/src/main/java/org/apache/fop/render/ps/Type1FontFormatter.java 查看文件

import org.apache.fontbox.cff.DataOutput; import org.apache.fontbox.cff.DataOutput;
import org.apache.fontbox.cff.Type1FontUtil; import org.apache.fontbox.cff.Type1FontUtil;


import org.apache.fop.fonts.FontEventListener;

/** /**
* This class represents a formatter for a given Type1 font. * This class represents a formatter for a given Type1 font.
* author Villu Ruusmann * author Villu Ruusmann
*/ */
public final class Type1FontFormatter { public final class Type1FontFormatter {
private Map<Integer, Integer> gids; private Map<Integer, Integer> gids;
private FontEventListener eventListener;


public Type1FontFormatter(Map<Integer, Integer> gids, FontEventListener eventListener) {
public Type1FontFormatter(Map<Integer, Integer> gids) {
this.gids = gids; this.gids = gids;
this.eventListener = eventListener;
} }


/** /**
* Read and convert a given CFFFont. * Read and convert a given CFFFont.
* @param font the given CFFFont * @param font the given CFFFont
* @param i
* @return the Type1 font * @return the Type1 font
* @throws IOException if an error occurs during reading the given font * @throws IOException if an error occurs during reading the given font
*/ */
public byte[] format(CFFType1Font font) throws IOException {
public byte[] format(CFFType1Font font, String i) throws IOException {
DataOutput output = new DataOutput(); DataOutput output = new DataOutput();
printFont(font, output);
printFont(font, output, i);
return output.getBytes(); return output.getBytes();
} }


private void printFont(CFFType1Font font, DataOutput output)
private void printFont(CFFType1Font font, DataOutput output, String iStr)
throws IOException { throws IOException {
output.println("%!FontType1-1.0 " + font.getName() + " "
output.println("%!FontType1-1.0 " + font.getName() + iStr + " "
+ font.getTopDict().get("version")); + font.getTopDict().get("version"));


printFontDictionary(font, output);
printFontDictionary(font, output, iStr);


for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
output.println("cleartomark"); output.println("cleartomark");
} }


private void printFontDictionary(CFFType1Font font, DataOutput output)
private void printFontDictionary(CFFType1Font font, DataOutput output, String iStr)
throws IOException { throws IOException {
output.println("10 dict begin"); output.println("10 dict begin");
output.println("/FontInfo 10 dict dup begin"); output.println("/FontInfo 10 dict dup begin");
output.println("/UnderlineThickness " output.println("/UnderlineThickness "
+ font.getTopDict().get("UnderlineThickness") + " def"); + font.getTopDict().get("UnderlineThickness") + " def");
output.println("end readonly def"); output.println("end readonly def");
output.println("/FontName /" + font.getName() + " def");
output.println("/FontName /" + font.getName() + iStr + " def");
output.println("/PaintType " + font.getTopDict().get("PaintType") + " def"); output.println("/PaintType " + font.getTopDict().get("PaintType") + " def");
output.println("/FontType 1 def"); output.println("/FontType 1 def");
NumberFormat matrixFormat = new DecimalFormat("0.########", new DecimalFormatSymbols(Locale.US)); NumberFormat matrixFormat = new DecimalFormat("0.########", new DecimalFormatSymbols(Locale.US));
sb.append(String.format("dup %d /%s put", gid.getValue(), name)).append('\n'); sb.append(String.format("dup %d /%s put", gid.getValue(), name)).append('\n');
max = Math.max(max, gid.getValue()); max = Math.max(max, gid.getValue());
} }
if (max > 255) {
eventListener.fontType1MaxGlyphs(this, font.getName());
}
output.println("/Encoding " + (max + 1) + " array"); output.println("/Encoding " + (max + 1) + " array");
output.println("0 1 " + max + " {1 index exch /.notdef put} for"); output.println("0 1 " + max + " {1 index exch /.notdef put} for");
output.print(sb.toString()); output.print(sb.toString());

+ 0
- 4
fop-core/src/main/java/org/apache/fop/tools/fontlist/FontListMain.java 查看文件

public void svgTextStrokedAsShapes(Object source, String fontFamily) { public void svgTextStrokedAsShapes(Object source, String fontFamily) {
// ignore // ignore
} }

public void fontType1MaxGlyphs(Object source, String fontName) {
//ignore
}
}; };


FontListGenerator listGenerator = new FontListGenerator(); FontListGenerator listGenerator = new FontListGenerator();

+ 0
- 1
fop-core/src/main/resources/org/apache/fop/fonts/FontEventProducer.xml 查看文件

<message key="glyphNotAvailable">Glyph "{ch}" (0x{ch,hex}[, {ch,glyph-name}]) not available in font "{fontName}".</message> <message key="glyphNotAvailable">Glyph "{ch}" (0x{ch,hex}[, {ch,glyph-name}]) not available in font "{fontName}".</message>
<message key="fontDirectoryNotFound">The font directory {dir} could not be found.</message> <message key="fontDirectoryNotFound">The font directory {dir} could not be found.</message>
<message key="svgTextStrokedAsShapes">The SVG text for font {fontFamily} will be stroked as shapes.</message> <message key="svgTextStrokedAsShapes">The SVG text for font {fontFamily} will be stroked as shapes.</message>
<message key="fontType1MaxGlyphs">Font "{fontName}" encoding has more than 256 glyphs may cause wrong output, enable font subsetting or disable 'embed-as-type1'.</message>
</catalogue> </catalogue>

+ 4
- 3
fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFToType1TestCase.java 查看文件



import org.apache.fop.apps.io.InternalResourceResolver; import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.fonts.CFFToType1Font;
import org.apache.fop.fonts.CustomFont; import org.apache.fop.fonts.CustomFont;
import org.apache.fop.fonts.EmbeddingMode; import org.apache.fop.fonts.EmbeddingMode;
import org.apache.fop.fonts.EncodingMode; import org.apache.fop.fonts.EncodingMode;
@Test @Test
public void testFont() throws IOException { public void testFont() throws IOException {
Type1Font t1 = getFont("test/resources/fonts/otf/SourceSansProBold.otf"); Type1Font t1 = getFont("test/resources/fonts/otf/SourceSansProBold.otf");
Assert.assertEquals(t1.getFontName(), "SourceSansPro-Bold");
Assert.assertEquals(t1.getFontName(), "SourceSansPro-Bold.0");
Assert.assertEquals(t1.getCharStringsDict().keySet().toString(), "[.notdef, d]"); Assert.assertEquals(t1.getCharStringsDict().keySet().toString(), "[.notdef, d]");
t1 = getFont("test/resources/fonts/otf/AlexBrushRegular.otf"); t1 = getFont("test/resources/fonts/otf/AlexBrushRegular.otf");
Assert.assertEquals(t1.getFontName(), "AlexBrush-Regular");
Assert.assertEquals(t1.getFontName(), "AlexBrush-Regular.0");
} }


private Type1Font getFont(String s) throws IOException { private Type1Font getFont(String s) throws IOException {
CustomFont realFont = FontLoader.loadFont(new FontUris(new File(s).toURI(), null), null, true, CustomFont realFont = FontLoader.loadFont(new FontUris(new File(s).toURI(), null), null, true,
EmbeddingMode.SUBSET, EncodingMode.AUTO, true, true, rr, true); EmbeddingMode.SUBSET, EncodingMode.AUTO, true, true, rr, true);
realFont.mapChar('d'); realFont.mapChar('d');
InputStream is = realFont.getInputStream();
InputStream is = ((CFFToType1Font)realFont).getInputStreams().get(0);
return Type1Font.createWithPFB(is); return Type1Font.createWithPFB(is);
} }
} }

+ 0
- 1
fop-core/src/test/java/org/apache/fop/render/ps/PSPainterTestCase.java 查看文件

+ "/OTFFont.0 0.01 F\n" + "/OTFFont.0 0.01 F\n"
+ "1 0 0 -1 0 0 Tm\n" + "1 0 0 -1 0 0 Tm\n"
+ "<FFFFFFFFFF> t\n" + "<FFFFFFFFFF> t\n"
+ "/OTFFont.0 0.01 F\n"
+ "1 0 0 -1 0 0 Tm\n" + "1 0 0 -1 0 0 Tm\n"
+ "<FFFFFFFFFF> t\n" + "<FFFFFFFFFF> t\n"
+ "/TTFFont 0.01 F\n" + "/TTFFont 0.01 F\n"

正在加载...
取消
保存