private String fontName = null;
private String embedFileName = null;
- private String embedResourceName = null;
+ protected String embedResourceName = null;
private FontResolver resolver = null;
private int capHeight = 0;
--- /dev/null
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements. See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/* $Id$ */\r
+\r
+package org.apache.fop.fonts;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+\r
+import javax.xml.transform.Source;\r
+import javax.xml.transform.stream.StreamSource;\r
+\r
+import org.apache.commons.io.IOUtils;\r
+import org.apache.fop.fonts.truetype.TTFFontLoader;\r
+import org.apache.fop.fonts.type1.Type1FontLoader;\r
+\r
+/**\r
+ * Base class for font loaders.\r
+ */\r
+public abstract class FontLoader {\r
+\r
+ /**\r
+ * Loads a custom font from a URI. In the case of Type 1 fonts, the PFB file must be specified.\r
+ * @param fontFileURI the URI to the font\r
+ * @param resolver the font resolver to use when resolving URIs\r
+ * @return the newly loaded font\r
+ * @throws IOException In case of an I/O error\r
+ */\r
+ public static CustomFont loadFont(String fontFileURI, FontResolver resolver)\r
+ throws IOException {\r
+ FontLoader loader;\r
+ fontFileURI = fontFileURI.trim();\r
+ String name = fontFileURI.toLowerCase();\r
+ String effURI;\r
+ boolean type1 = false;\r
+ if (name.endsWith(".pfb")) {\r
+ type1 = true;\r
+ effURI = name.substring(0, fontFileURI.length() - 4) + ".pfm";\r
+ } else {\r
+ effURI = fontFileURI;\r
+ }\r
+ \r
+ InputStream in = openFontFile(resolver, effURI);\r
+ try {\r
+ if (type1) {\r
+ loader = new Type1FontLoader(fontFileURI, in, resolver);\r
+ } else {\r
+ loader = new TTFFontLoader(fontFileURI, in, resolver);\r
+ }\r
+ return loader.getFont();\r
+ } finally {\r
+ IOUtils.closeQuietly(in);\r
+ }\r
+ }\r
+\r
+ private static InputStream openFontFile(FontResolver resolver, String uri) \r
+ throws IOException, MalformedURLException {\r
+ InputStream in = null;\r
+ if (resolver != null) {\r
+ Source source = resolver.resolve(uri);\r
+ if (source == null) {\r
+ String err = "Cannot load font: failed to create Source for font file " \r
+ + uri; \r
+ throw new IOException(err);\r
+ }\r
+ if (source instanceof StreamSource) {\r
+ in = ((StreamSource) source).getInputStream();\r
+ }\r
+ if (in == null && source.getSystemId() != null) {\r
+ in = new java.net.URL(source.getSystemId()).openStream();\r
+ }\r
+ if (in == null) {\r
+ String err = "Cannot load font: failed to create InputStream from"\r
+ + " Source for font file " + uri; \r
+ throw new IOException(err);\r
+ }\r
+ } else {\r
+ in = new URL(uri).openStream();\r
+ }\r
+ return in;\r
+ }\r
+ \r
+ /**\r
+ * @return the font loaded by this loader\r
+ */\r
+ public abstract CustomFont getFont();\r
+\r
+ \r
+}\r
EmbedFontInfo configFontInfo = (EmbedFontInfo) fontInfoList.get(i);
String metricsFile = configFontInfo.getMetricsFile();
- if (metricsFile != null) {
- internalName = "F" + num;
- num++;
- /*
- reader = new FontReader(metricsFile);
- reader.useKerning(configFontInfo.getKerning());
- reader.setFontEmbedPath(configFontInfo.getEmbedFile());
- fontInfo.addMetrics(internalName, reader.getFont());
- */
- LazyFont font = new LazyFont(configFontInfo.getEmbedFile(),
- metricsFile,
- configFontInfo.getKerning(),
- resolver);
- fontInfo.addMetrics(internalName, font);
+ internalName = "F" + num;
+ num++;
+ /*
+ reader = new FontReader(metricsFile);
+ reader.useKerning(configFontInfo.getKerning());
+ reader.setFontEmbedPath(configFontInfo.getEmbedFile());
+ fontInfo.addMetrics(internalName, reader.getFont());
+ */
+ LazyFont font = new LazyFont(configFontInfo.getEmbedFile(),
+ metricsFile,
+ configFontInfo.getKerning(),
+ resolver);
+ fontInfo.addMetrics(internalName, font);
- List triplets = configFontInfo.getFontTriplets();
- for (int c = 0; c < triplets.size(); c++) {
- FontTriplet triplet = (FontTriplet) triplets.get(c);
+ List triplets = configFontInfo.getFontTriplets();
+ for (int c = 0; c < triplets.size(); c++) {
+ FontTriplet triplet = (FontTriplet) triplets.get(c);
- if (log.isDebugEnabled()) {
- log.debug("Registering: " + triplet + " under " + internalName);
- }
- fontInfo.addFontProperties(internalName, triplet);
+ if (log.isDebugEnabled()) {
+ log.debug("Registering: " + triplet + " under " + internalName);
}
+ fontInfo.addFontProperties(internalName, triplet);
}
}
}
}
EmbedFontInfo efi;
- efi = new EmbedFontInfo(font[i].getAttribute("metrics-url"),
+ efi = new EmbedFontInfo(font[i].getAttribute("metrics-url", null),
font[i].getAttributeAsBoolean("kerning", false),
tripleList, font[i].getAttribute("embed-url", null));
private void load(boolean fail) {
if (!isMetricsLoaded) {
try {
- /**@todo Possible thread problem here */
- FontReader reader = null;
- if (resolver != null) {
- Source source = resolver.resolve(metricsFileName);
- if (source == null) {
- String err = "Cannot load font: failed to create Source from metrics file "
- + metricsFileName;
- if (fail) {
- throw new RuntimeException(err);
- } else {
- log.error(err);
+ if (metricsFileName != null) {
+ /**@todo Possible thread problem here */
+ FontReader reader = null;
+ if (resolver != null) {
+ Source source = resolver.resolve(metricsFileName);
+ if (source == null) {
+ String err = "Cannot load font: failed to create Source from metrics file "
+ + metricsFileName;
+ if (fail) {
+ throw new RuntimeException(err);
+ } else {
+ log.error(err);
+ }
+ return;
}
- return;
- }
- InputStream in = null;
- if (source instanceof StreamSource) {
- in = ((StreamSource) source).getInputStream();
- }
- if (in == null && source.getSystemId() != null) {
- in = new java.net.URL(source.getSystemId()).openStream();
- }
- if (in == null) {
- String err = "Cannot load font: failed to create InputStream from"
- + " Source for metrics file " + metricsFileName;
- if (fail) {
- throw new RuntimeException(err);
- } else {
- log.error(err);
+ InputStream in = null;
+ if (source instanceof StreamSource) {
+ in = ((StreamSource) source).getInputStream();
}
- return;
+ if (in == null && source.getSystemId() != null) {
+ in = new java.net.URL(source.getSystemId()).openStream();
+ }
+ if (in == null) {
+ String err = "Cannot load font: failed to create InputStream from"
+ + " Source for metrics file " + metricsFileName;
+ if (fail) {
+ throw new RuntimeException(err);
+ } else {
+ log.error(err);
+ }
+ return;
+ }
+ InputSource src = new InputSource(in);
+ src.setSystemId(source.getSystemId());
+ reader = new FontReader(src);
+ } else {
+ reader
+ = new FontReader(new InputSource(new URL(metricsFileName).openStream()));
}
- InputSource src = new InputSource(in);
- src.setSystemId(source.getSystemId());
- reader = new FontReader(src);
+ reader.setKerningEnabled(useKerning);
+ reader.setFontEmbedPath(fontEmbedPath);
+ reader.setResolver(resolver);
+ realFont = reader.getFont();
} else {
- reader
- = new FontReader(new InputSource(new URL(metricsFileName).openStream()));
+ if (fontEmbedPath == null) {
+ throw new RuntimeException("Cannot load font. No font URIs available.");
+ }
+ realFont = FontLoader.loadFont(fontEmbedPath, resolver);
}
- reader.setKerningEnabled(useKerning);
- reader.setFontEmbedPath(fontEmbedPath);
- reader.setResolver(resolver);
- realFont = reader.getFont();
if (realFont instanceof FontDescriptor) {
realFontDescriptor = (FontDescriptor) realFont;
}
- // log.debug("Metrics " + metricsFileName + " loaded.");
} catch (FOPException fopex) {
log.error("Failed to read font metrics file " + metricsFileName, fopex);
if (fail) {
private String ttcName = null;
private String encoding = "Identity-H";
- private String embedResourceName = null;
-
private int defaultWidth = 0;
private CIDFontType cidType = CIDFontType.CIDTYPE2;
--- /dev/null
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements. See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/* $Id$ */\r
+\r
+package org.apache.fop.fonts.truetype;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.apache.fop.fonts.BFEntry;\r
+import org.apache.fop.fonts.CIDFontType;\r
+import org.apache.fop.fonts.CustomFont;\r
+import org.apache.fop.fonts.FontLoader;\r
+import org.apache.fop.fonts.FontResolver;\r
+import org.apache.fop.fonts.MultiByteFont;\r
+\r
+/**\r
+ * Loads a font into memory directly from the original font file.\r
+ */\r
+public class TTFFontLoader extends FontLoader {\r
+\r
+ private String fontFileURI;\r
+ private TTFFile ttf;\r
+ private MultiByteFont multiFont;\r
+ private CustomFont returnFont;\r
+ private FontResolver resolver;\r
+ \r
+ public TTFFontLoader(String fontFileURI, InputStream in, FontResolver resolver) \r
+ throws IOException {\r
+ this.fontFileURI = fontFileURI;\r
+ this.resolver = resolver;\r
+\r
+ this.ttf = new TTFFile();\r
+ FontFileReader reader = new FontFileReader(in);\r
+ boolean supported = ttf.readFont(reader, null);\r
+ if (!supported) {\r
+ throw new IOException("Could not load TrueType font: " + fontFileURI);\r
+ }\r
+ multiFont = new MultiByteFont();\r
+ multiFont.setResolver(this.resolver);\r
+ returnFont = multiFont;\r
+ read(); \r
+ }\r
+ \r
+ private void read() throws IOException {\r
+ returnFont.setFontName(ttf.getFamilyName());\r
+ //multiFont.setTTCName(ttcName)\r
+ returnFont.setCapHeight(ttf.getCapHeight());\r
+ returnFont.setXHeight(ttf.getXHeight());\r
+ returnFont.setAscender(ttf.getLowerCaseAscent());\r
+ returnFont.setDescender(ttf.getLowerCaseDescent());\r
+ returnFont.setFontBBox(ttf.getFontBBox());\r
+ //returnFont.setFirstChar(ttf.getFirstChar();)\r
+ returnFont.setFlags(ttf.getFlags());\r
+ returnFont.setStemV(Integer.parseInt(ttf.getStemV())); //not used for TTF\r
+ returnFont.setItalicAngle(Integer.parseInt(ttf.getItalicAngle()));\r
+ returnFont.setMissingWidth(0);\r
+ multiFont.setCIDType(CIDFontType.CIDTYPE2);\r
+ int[] wx = ttf.getWidths();\r
+ multiFont.setWidthArray(wx);\r
+ List entries = ttf.getCMaps();\r
+ BFEntry[] bfentries = new BFEntry[entries.size()];\r
+ int pos = 0;\r
+ Iterator iter = ttf.getCMaps().listIterator();\r
+ while (iter.hasNext()) {\r
+ TTFCmapEntry ce = (TTFCmapEntry)iter.next();\r
+ bfentries[pos] = new BFEntry(ce.getUnicodeStart(), ce.getUnicodeEnd(),\r
+ ce.getGlyphStartIndex());\r
+ pos++;\r
+ }\r
+ multiFont.setBFEntries(bfentries);\r
+ copyKerning(ttf, true);\r
+ multiFont.setEmbedFileName(this.fontFileURI);\r
+ \r
+ }\r
+ \r
+ private void copyKerning(TTFFile ttf, boolean isCid) {\r
+ \r
+ // Get kerning\r
+ Iterator iter;\r
+ if (isCid) {\r
+ iter = ttf.getKerning().keySet().iterator();\r
+ } else {\r
+ iter = ttf.getAnsiKerning().keySet().iterator();\r
+ }\r
+\r
+ while (iter.hasNext()) {\r
+ Integer kpx1 = (Integer)iter.next();\r
+\r
+ Map h2;\r
+ if (isCid) {\r
+ h2 = (Map)ttf.getKerning().get(kpx1);\r
+ } else {\r
+ h2 = (Map)ttf.getAnsiKerning().get(kpx1);\r
+ }\r
+\r
+ returnFont.putKerningEntry(kpx1, h2);\r
+ }\r
+ }\r
+ \r
+ \r
+ /** @see org.apache.fop.fonts.FontLoader#getFont() */\r
+ public CustomFont getFont() {\r
+ return this.returnFont;\r
+ }\r
+ \r
+}\r
--- /dev/null
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements. See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/* $Id$ */\r
+\r
+package org.apache.fop.fonts.type1;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+\r
+import org.apache.fop.fonts.CustomFont;\r
+import org.apache.fop.fonts.FontLoader;\r
+import org.apache.fop.fonts.FontResolver;\r
+import org.apache.fop.fonts.FontType;\r
+import org.apache.fop.fonts.SingleByteFont;\r
+\r
+/**\r
+ * Loads a Type 1 font into memory directly from the original font file.\r
+ */\r
+public class Type1FontLoader extends FontLoader {\r
+\r
+ private String fontFileURI;\r
+ private PFMFile pfm;\r
+ private SingleByteFont singleFont;\r
+ private CustomFont returnFont;\r
+ private FontResolver resolver;\r
+ \r
+ /**\r
+ * Constructs a new Type 1 font loader.\r
+ * @param fontFileURI the URI to the PFB file of a Type 1 font\r
+ * @param in the InputStream reading the PFM file of a Type 1 font\r
+ * @param resolver the font resolver used to resolve URIs\r
+ * @throws IOException In case of an I/O error\r
+ */\r
+ public Type1FontLoader(String fontFileURI, InputStream in, FontResolver resolver) \r
+ throws IOException {\r
+ this.fontFileURI = fontFileURI;\r
+ this.resolver = resolver;\r
+\r
+ pfm = new PFMFile();\r
+ pfm.load(in);\r
+ singleFont = new SingleByteFont();\r
+ singleFont.setFontType(FontType.TYPE1);\r
+ singleFont.setResolver(this.resolver);\r
+ returnFont = singleFont;\r
+ read(); \r
+ }\r
+ \r
+ private void read() throws IOException {\r
+ returnFont.setFontName(pfm.getPostscriptName());\r
+ returnFont.setCapHeight(pfm.getCapHeight());\r
+ returnFont.setXHeight(pfm.getXHeight());\r
+ returnFont.setAscender(pfm.getLowerCaseAscent());\r
+ returnFont.setDescender(pfm.getLowerCaseDescent());\r
+ returnFont.setFontBBox(pfm.getFontBBox());\r
+ returnFont.setFirstChar(pfm.getFirstChar());\r
+ returnFont.setLastChar(pfm.getFirstChar());\r
+ returnFont.setFlags(pfm.getFlags());\r
+ returnFont.setStemV(pfm.getStemV());\r
+ returnFont.setItalicAngle(pfm.getItalicAngle());\r
+ returnFont.setMissingWidth(0);\r
+ for (short i = pfm.getFirstChar(); i <= pfm.getLastChar(); i++) {\r
+ singleFont.setWidth(i, pfm.getCharWidth(i));\r
+ }\r
+ singleFont.setEmbedFileName(this.fontFileURI);\r
+ \r
+ }\r
+ \r
+ /** @see org.apache.fop.fonts.FontLoader#getFont() */\r
+ public CustomFont getFont() {\r
+ return this.returnFont;\r
+ }\r
+ \r
+}\r
<changes>
<release version="FOP Trunk">
+ <action context="Code" dev="JM" type="add">
+ Added initial support for loading fonts without a pre-created XML font metric
+ file.
+ </action>
<action context="Code" dev="JM" type="add" fixes-bug="40729" due-to="Peter Coppens">
Support for the rgb-icc() function and for a proprietary cmyk() function (for device CMYK
colors only through the PDF renderer so far).