aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2006-11-13 16:28:13 +0000
committerJeremias Maerki <jeremias@apache.org>2006-11-13 16:28:13 +0000
commit652b3cbc5586d794a41bee4d2c824539e18b3cfc (patch)
treeb1f28123ec5b116e8ee68934af49680dd8c35d1d
parentd6f78f8cc3de4b43e36dff19fef56778149ca96d (diff)
downloadxmlgraphics-fop-652b3cbc5586d794a41bee4d2c824539e18b3cfc.tar.gz
xmlgraphics-fop-652b3cbc5586d794a41bee4d2c824539e18b3cfc.zip
Added initial support for loading fonts without a pre-created XML font metrics file.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@474387 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/fop/fonts/CustomFont.java2
-rw-r--r--src/java/org/apache/fop/fonts/FontLoader.java106
-rw-r--r--src/java/org/apache/fop/fonts/FontSetup.java42
-rw-r--r--src/java/org/apache/fop/fonts/LazyFont.java82
-rw-r--r--src/java/org/apache/fop/fonts/MultiByteFont.java2
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java125
-rw-r--r--src/java/org/apache/fop/fonts/type1/Type1FontLoader.java88
-rw-r--r--status.xml4
8 files changed, 388 insertions, 63 deletions
diff --git a/src/java/org/apache/fop/fonts/CustomFont.java b/src/java/org/apache/fop/fonts/CustomFont.java
index 8f21a449d..5d7221c13 100644
--- a/src/java/org/apache/fop/fonts/CustomFont.java
+++ b/src/java/org/apache/fop/fonts/CustomFont.java
@@ -31,7 +31,7 @@ public abstract class CustomFont extends Typeface
private String fontName = null;
private String embedFileName = null;
- private String embedResourceName = null;
+ protected String embedResourceName = null;
private FontResolver resolver = null;
private int capHeight = 0;
diff --git a/src/java/org/apache/fop/fonts/FontLoader.java b/src/java/org/apache/fop/fonts/FontLoader.java
new file mode 100644
index 000000000..4377f9fab
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/FontLoader.java
@@ -0,0 +1,106 @@
+/*
+ * 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$ */
+
+package org.apache.fop.fonts;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.fop.fonts.truetype.TTFFontLoader;
+import org.apache.fop.fonts.type1.Type1FontLoader;
+
+/**
+ * Base class for font loaders.
+ */
+public abstract class FontLoader {
+
+ /**
+ * Loads a custom font from a URI. In the case of Type 1 fonts, the PFB file must be specified.
+ * @param fontFileURI the URI to the font
+ * @param resolver the font resolver to use when resolving URIs
+ * @return the newly loaded font
+ * @throws IOException In case of an I/O error
+ */
+ public static CustomFont loadFont(String fontFileURI, FontResolver resolver)
+ throws IOException {
+ FontLoader loader;
+ fontFileURI = fontFileURI.trim();
+ String name = fontFileURI.toLowerCase();
+ String effURI;
+ boolean type1 = false;
+ if (name.endsWith(".pfb")) {
+ type1 = true;
+ effURI = name.substring(0, fontFileURI.length() - 4) + ".pfm";
+ } else {
+ effURI = fontFileURI;
+ }
+
+ InputStream in = openFontFile(resolver, effURI);
+ try {
+ if (type1) {
+ loader = new Type1FontLoader(fontFileURI, in, resolver);
+ } else {
+ loader = new TTFFontLoader(fontFileURI, in, resolver);
+ }
+ return loader.getFont();
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ private static InputStream openFontFile(FontResolver resolver, String uri)
+ throws IOException, MalformedURLException {
+ InputStream in = null;
+ if (resolver != null) {
+ Source source = resolver.resolve(uri);
+ if (source == null) {
+ String err = "Cannot load font: failed to create Source for font file "
+ + uri;
+ throw new IOException(err);
+ }
+ 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 font file " + uri;
+ throw new IOException(err);
+ }
+ } else {
+ in = new URL(uri).openStream();
+ }
+ return in;
+ }
+
+ /**
+ * @return the font loaded by this loader
+ */
+ public abstract CustomFont getFont();
+
+
+}
diff --git a/src/java/org/apache/fop/fonts/FontSetup.java b/src/java/org/apache/fop/fonts/FontSetup.java
index 4c9e3b768..3362ce334 100644
--- a/src/java/org/apache/fop/fonts/FontSetup.java
+++ b/src/java/org/apache/fop/fonts/FontSetup.java
@@ -209,30 +209,28 @@ public class FontSetup {
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);
}
}
}
@@ -270,7 +268,7 @@ public class FontSetup {
}
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));
diff --git a/src/java/org/apache/fop/fonts/LazyFont.java b/src/java/org/apache/fop/fonts/LazyFont.java
index 4d0b57cee..658c0cf1e 100644
--- a/src/java/org/apache/fop/fonts/LazyFont.java
+++ b/src/java/org/apache/fop/fonts/LazyFont.java
@@ -65,52 +65,58 @@ public class LazyFont extends Typeface implements FontDescriptor {
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) {
diff --git a/src/java/org/apache/fop/fonts/MultiByteFont.java b/src/java/org/apache/fop/fonts/MultiByteFont.java
index bcb295741..2dd3846ed 100644
--- a/src/java/org/apache/fop/fonts/MultiByteFont.java
+++ b/src/java/org/apache/fop/fonts/MultiByteFont.java
@@ -33,8 +33,6 @@ public class MultiByteFont extends CIDFont {
private String ttcName = null;
private String encoding = "Identity-H";
- private String embedResourceName = null;
-
private int defaultWidth = 0;
private CIDFontType cidType = CIDFontType.CIDTYPE2;
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java b/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
new file mode 100644
index 000000000..53be6a8d0
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
@@ -0,0 +1,125 @@
+/*
+ * 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$ */
+
+package org.apache.fop.fonts.truetype;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.fop.fonts.BFEntry;
+import org.apache.fop.fonts.CIDFontType;
+import org.apache.fop.fonts.CustomFont;
+import org.apache.fop.fonts.FontLoader;
+import org.apache.fop.fonts.FontResolver;
+import org.apache.fop.fonts.MultiByteFont;
+
+/**
+ * Loads a font into memory directly from the original font file.
+ */
+public class TTFFontLoader extends FontLoader {
+
+ private String fontFileURI;
+ private TTFFile ttf;
+ private MultiByteFont multiFont;
+ private CustomFont returnFont;
+ private FontResolver resolver;
+
+ public TTFFontLoader(String fontFileURI, InputStream in, FontResolver resolver)
+ throws IOException {
+ this.fontFileURI = fontFileURI;
+ this.resolver = resolver;
+
+ this.ttf = new TTFFile();
+ FontFileReader reader = new FontFileReader(in);
+ boolean supported = ttf.readFont(reader, null);
+ if (!supported) {
+ throw new IOException("Could not load TrueType font: " + fontFileURI);
+ }
+ multiFont = new MultiByteFont();
+ multiFont.setResolver(this.resolver);
+ returnFont = multiFont;
+ read();
+ }
+
+ private void read() throws IOException {
+ returnFont.setFontName(ttf.getFamilyName());
+ //multiFont.setTTCName(ttcName)
+ returnFont.setCapHeight(ttf.getCapHeight());
+ returnFont.setXHeight(ttf.getXHeight());
+ returnFont.setAscender(ttf.getLowerCaseAscent());
+ returnFont.setDescender(ttf.getLowerCaseDescent());
+ returnFont.setFontBBox(ttf.getFontBBox());
+ //returnFont.setFirstChar(ttf.getFirstChar();)
+ returnFont.setFlags(ttf.getFlags());
+ returnFont.setStemV(Integer.parseInt(ttf.getStemV())); //not used for TTF
+ returnFont.setItalicAngle(Integer.parseInt(ttf.getItalicAngle()));
+ returnFont.setMissingWidth(0);
+ multiFont.setCIDType(CIDFontType.CIDTYPE2);
+ int[] wx = ttf.getWidths();
+ multiFont.setWidthArray(wx);
+ List entries = ttf.getCMaps();
+ BFEntry[] bfentries = new BFEntry[entries.size()];
+ int pos = 0;
+ Iterator iter = ttf.getCMaps().listIterator();
+ while (iter.hasNext()) {
+ TTFCmapEntry ce = (TTFCmapEntry)iter.next();
+ bfentries[pos] = new BFEntry(ce.getUnicodeStart(), ce.getUnicodeEnd(),
+ ce.getGlyphStartIndex());
+ pos++;
+ }
+ multiFont.setBFEntries(bfentries);
+ copyKerning(ttf, true);
+ multiFont.setEmbedFileName(this.fontFileURI);
+
+ }
+
+ private void copyKerning(TTFFile ttf, boolean isCid) {
+
+ // Get kerning
+ Iterator iter;
+ if (isCid) {
+ iter = ttf.getKerning().keySet().iterator();
+ } else {
+ iter = ttf.getAnsiKerning().keySet().iterator();
+ }
+
+ while (iter.hasNext()) {
+ Integer kpx1 = (Integer)iter.next();
+
+ Map h2;
+ if (isCid) {
+ h2 = (Map)ttf.getKerning().get(kpx1);
+ } else {
+ h2 = (Map)ttf.getAnsiKerning().get(kpx1);
+ }
+
+ returnFont.putKerningEntry(kpx1, h2);
+ }
+ }
+
+
+ /** @see org.apache.fop.fonts.FontLoader#getFont() */
+ public CustomFont getFont() {
+ return this.returnFont;
+ }
+
+}
diff --git a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
new file mode 100644
index 000000000..ef0d45767
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
@@ -0,0 +1,88 @@
+/*
+ * 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$ */
+
+package org.apache.fop.fonts.type1;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.fop.fonts.CustomFont;
+import org.apache.fop.fonts.FontLoader;
+import org.apache.fop.fonts.FontResolver;
+import org.apache.fop.fonts.FontType;
+import org.apache.fop.fonts.SingleByteFont;
+
+/**
+ * Loads a Type 1 font into memory directly from the original font file.
+ */
+public class Type1FontLoader extends FontLoader {
+
+ private String fontFileURI;
+ private PFMFile pfm;
+ private SingleByteFont singleFont;
+ private CustomFont returnFont;
+ private FontResolver resolver;
+
+ /**
+ * Constructs a new Type 1 font loader.
+ * @param fontFileURI the URI to the PFB file of a Type 1 font
+ * @param in the InputStream reading the PFM file of a Type 1 font
+ * @param resolver the font resolver used to resolve URIs
+ * @throws IOException In case of an I/O error
+ */
+ public Type1FontLoader(String fontFileURI, InputStream in, FontResolver resolver)
+ throws IOException {
+ this.fontFileURI = fontFileURI;
+ this.resolver = resolver;
+
+ pfm = new PFMFile();
+ pfm.load(in);
+ singleFont = new SingleByteFont();
+ singleFont.setFontType(FontType.TYPE1);
+ singleFont.setResolver(this.resolver);
+ returnFont = singleFont;
+ read();
+ }
+
+ private void read() throws IOException {
+ returnFont.setFontName(pfm.getPostscriptName());
+ returnFont.setCapHeight(pfm.getCapHeight());
+ returnFont.setXHeight(pfm.getXHeight());
+ returnFont.setAscender(pfm.getLowerCaseAscent());
+ returnFont.setDescender(pfm.getLowerCaseDescent());
+ returnFont.setFontBBox(pfm.getFontBBox());
+ returnFont.setFirstChar(pfm.getFirstChar());
+ returnFont.setLastChar(pfm.getFirstChar());
+ returnFont.setFlags(pfm.getFlags());
+ returnFont.setStemV(pfm.getStemV());
+ returnFont.setItalicAngle(pfm.getItalicAngle());
+ returnFont.setMissingWidth(0);
+ for (short i = pfm.getFirstChar(); i <= pfm.getLastChar(); i++) {
+ singleFont.setWidth(i, pfm.getCharWidth(i));
+ }
+ singleFont.setEmbedFileName(this.fontFileURI);
+
+ }
+
+ /** @see org.apache.fop.fonts.FontLoader#getFont() */
+ public CustomFont getFont() {
+ return this.returnFont;
+ }
+
+}
diff --git a/status.xml b/status.xml
index 5a3bcc431..e931f104e 100644
--- a/status.xml
+++ b/status.xml
@@ -28,6 +28,10 @@
<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).