aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2009-03-22 11:54:39 +0000
committerJeremias Maerki <jeremias@apache.org>2009-03-22 11:54:39 +0000
commit43ecaa845e9042fda99f8b5e91834e8d4b2c1689 (patch)
tree1b88529949d0e68e40eee848b4fc83256e2ac518
parent085000aa2a34f78a73b6ed23112d6ad16e707ec2 (diff)
downloadxmlgraphics-fop-43ecaa845e9042fda99f8b5e91834e8d4b2c1689.tar.gz
xmlgraphics-fop-43ecaa845e9042fda99f8b5e91834e8d4b2c1689.zip
Added a command-line tool to list all configured fonts (org.apache.fop.tools.fontlist.FontListMain).
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@757172 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/documentation/content/xdocs/trunk/fonts.xml8
-rw-r--r--src/java/org/apache/fop/tools/fontlist/FontListGenerator.java115
-rw-r--r--src/java/org/apache/fop/tools/fontlist/FontListMain.java305
-rw-r--r--src/java/org/apache/fop/tools/fontlist/FontListSerializer.java142
-rw-r--r--src/java/org/apache/fop/tools/fontlist/FontSpec.java103
-rw-r--r--src/java/org/apache/fop/tools/fontlist/fonts2fo.xsl200
-rw-r--r--status.xml4
7 files changed, 877 insertions, 0 deletions
diff --git a/src/documentation/content/xdocs/trunk/fonts.xml b/src/documentation/content/xdocs/trunk/fonts.xml
index 261e6faf3..9fa34552b 100644
--- a/src/documentation/content/xdocs/trunk/fonts.xml
+++ b/src/documentation/content/xdocs/trunk/fonts.xml
@@ -545,5 +545,13 @@
</ul>
<p>Character-by-Character is NOT yet supported!</p>
</section>
+ <section id="font-list">
+ <title>Font List Command-Line Tool</title>
+ <p>
+ FOP contains a small command-line tool that lets you generate a list of all configured
+ fonts. Its class name is: <code>org.apache.fop.tools.fontlist.FontListMain</code>.
+ Run it with the "-?" parameter to get help for the various options.
+ </p>
+ </section>
</body>
</document>
diff --git a/src/java/org/apache/fop/tools/fontlist/FontListGenerator.java b/src/java/org/apache/fop/tools/fontlist/FontListGenerator.java
new file mode 100644
index 000000000..ce44eee19
--- /dev/null
+++ b/src/java/org/apache/fop/tools/fontlist/FontListGenerator.java
@@ -0,0 +1,115 @@
+/*
+ * 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.tools.fontlist;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.fonts.FontEventListener;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontMetrics;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+
+/**
+ * Generates a list of available fonts.
+ */
+public class FontListGenerator {
+
+ /**
+ * List all fonts configured for a particular output format (identified by MIME type).
+ * The sorted map returned looks like this:
+ * <code>SortedMap&lt;String/font-family, List&lt;{@link FontSpec}&gt;&gt;</code>
+ * @param fopFactory the FOP factory (already configured)
+ * @param mime the MIME type identified the selected output format
+ * @param listener a font event listener to catch any font-related errors while listing fonts
+ * @return the map of font families
+ * @throws FOPException if an error occurs setting up the fonts
+ */
+ public SortedMap listFonts(FopFactory fopFactory, String mime, FontEventListener listener)
+ throws FOPException {
+ FontInfo fontInfo = setupFonts(fopFactory, mime, listener);
+ SortedMap fontFamilies = buildFamilyMap(fontInfo);
+ return fontFamilies;
+ }
+
+ private FontInfo setupFonts(FopFactory fopFactory, String mime, FontEventListener listener)
+ throws FOPException {
+ FOUserAgent userAgent = fopFactory.newFOUserAgent();
+
+ //The document handler is only instantiated to get access to its configurator!
+ IFDocumentHandler documentHandler
+ = fopFactory.getRendererFactory().createDocumentHandler(userAgent, mime);
+ IFDocumentHandlerConfigurator configurator = documentHandler.getConfigurator();
+
+ FontInfo fontInfo = new FontInfo();
+ configurator.setupFontInfo(documentHandler, fontInfo);
+ return fontInfo;
+ }
+
+ private SortedMap buildFamilyMap(FontInfo fontInfo) {
+ Map fonts = fontInfo.getFonts();
+ Set keyBag = new java.util.HashSet(fonts.keySet());
+
+ Map keys = new java.util.HashMap();
+ SortedMap fontFamilies = new java.util.TreeMap();
+ //SortedMap<String/font-family, List<FontSpec>>
+
+ Iterator iter = fontInfo.getFontTriplets().entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry entry = (Map.Entry)iter.next();
+ FontTriplet triplet = (FontTriplet)entry.getKey();
+ String key = (String)entry.getValue();
+ FontSpec container;
+ if (keyBag.contains(key)) {
+ keyBag.remove(key);
+
+ FontMetrics metrics = (FontMetrics)fonts.get(key);
+
+ container = new FontSpec(key, metrics);
+ container.addFamilyNames(metrics.getFamilyNames());
+ keys.put(key, container);
+ String firstFamilyName = (String)container.getFamilyNames().first();
+ List containers = (List)fontFamilies.get(firstFamilyName);
+ if (containers == null) {
+ containers = new java.util.ArrayList();
+ fontFamilies.put(firstFamilyName, containers);
+ }
+ containers.add(container);
+ Collections.sort(containers);
+
+ } else {
+ container = (FontSpec)keys.get(key);
+ }
+ container.addTriplet(triplet);
+ }
+
+ return fontFamilies;
+ }
+
+}
diff --git a/src/java/org/apache/fop/tools/fontlist/FontListMain.java b/src/java/org/apache/fop/tools/fontlist/FontListMain.java
new file mode 100644
index 000000000..d31da92c2
--- /dev/null
+++ b/src/java/org/apache/fop/tools/fontlist/FontListMain.java
@@ -0,0 +1,305 @@
+/*
+ * 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.tools.fontlist;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+
+import org.apache.fop.Version;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.Fop;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.fonts.FontEventListener;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.util.GenerationHelperContentHandler;
+
+/**
+ * Command-line application to list available fonts and to optionally produce sample pages
+ * with those fonts.
+ */
+public final class FontListMain {
+
+ private static final int GENERATE_CONSOLE = 0;
+ private static final int GENERATE_XML = 1;
+ private static final int GENERATE_FO = 2;
+ private static final int GENERATE_RENDERED = 3;
+
+ private FopFactory fopFactory = FopFactory.newInstance();
+
+ private File configFile;
+ private File outputFile;
+ private String configMime = MimeConstants.MIME_PDF;
+ private String outputMime;
+ private int mode = GENERATE_CONSOLE;
+ private String singleFamilyFilter;
+
+ private FontListMain() throws SAXException, IOException {
+ }
+
+ private void prepare() throws SAXException, IOException {
+ if (this.configFile != null) {
+ fopFactory.setUserConfig(this.configFile);
+ }
+ }
+
+ private ContentHandler getFOPContentHandler(OutputStream out) throws FOPException {
+ Fop fop = fopFactory.newFop(this.outputMime, out);
+ return fop.getDefaultHandler();
+ }
+
+ private void generateXML(SortedMap fontFamilies, File outFile, String singleFamily)
+ throws TransformerConfigurationException, SAXException, IOException {
+ SAXTransformerFactory tFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
+ TransformerHandler handler;
+ if (this.mode == GENERATE_XML) {
+ handler = tFactory.newTransformerHandler();
+ } else {
+ URL url = getClass().getResource("fonts2fo.xsl");
+ if (url == null) {
+ throw new FileNotFoundException("Did not find resource: fonts2fo.xsl");
+ }
+ handler = tFactory.newTransformerHandler(new StreamSource(url.toExternalForm()));
+ }
+
+ if (singleFamily != null) {
+ Transformer transformer = handler.getTransformer();
+ transformer.setParameter("single-family", singleFamily);
+ }
+
+ OutputStream out = new java.io.FileOutputStream(outFile);
+ out = new java.io.BufferedOutputStream(out);
+ if (this.mode == GENERATE_RENDERED) {
+ handler.setResult(new SAXResult(getFOPContentHandler(out)));
+ } else {
+ handler.setResult(new StreamResult(out));
+ }
+ try {
+ GenerationHelperContentHandler helper = new GenerationHelperContentHandler(
+ handler, null);
+ FontListSerializer serializer = new FontListSerializer();
+ serializer.generateSAX(fontFamilies, singleFamily, helper);
+ } finally {
+ IOUtils.closeQuietly(out);
+ }
+ }
+
+ private void generate() throws Exception {
+ prepare();
+
+ FontEventListener listener = new FontEventListener() {
+
+ public void fontLoadingErrorAtAutoDetection(Object source,
+ String fontURL, Exception e) {
+ System.err.println("Could not load " + fontURL
+ + " (" + e.getLocalizedMessage() + ")");
+ }
+
+ public void fontSubstituted(Object source,
+ FontTriplet requested, FontTriplet effective) {
+ //ignore
+ }
+
+ public void glyphNotAvailable(Object source, char ch, String fontName) {
+ //ignore
+ }
+
+ };
+
+ FontListGenerator listGenerator = new FontListGenerator();
+ SortedMap fontFamilies = listGenerator.listFonts(fopFactory, configMime, listener);
+
+ if (this.mode == GENERATE_CONSOLE) {
+ writeToConsole(fontFamilies);
+ } else {
+ writeOutput(fontFamilies);
+ }
+ }
+
+ private void writeToConsole(SortedMap fontFamilies)
+ throws TransformerConfigurationException, SAXException, IOException {
+ Iterator iter = fontFamilies.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry entry = (Map.Entry)iter.next();
+ String firstFamilyName = (String)entry.getKey();
+ System.out.println(firstFamilyName + ":");
+ List list = (List)entry.getValue();
+ Iterator fonts = list.iterator();
+ while (fonts.hasNext()) {
+ FontSpec f = (FontSpec)fonts.next();
+ System.out.println(" " + f.getKey() + " " + f.getFamilyNames());
+ Iterator triplets = f.getTriplets().iterator();
+ while (triplets.hasNext()) {
+ FontTriplet triplet = (FontTriplet)triplets.next();
+ System.out.println(" " + triplet.toString());
+ }
+ }
+ }
+ }
+
+ private void writeOutput(SortedMap fontFamilies)
+ throws TransformerConfigurationException, SAXException, IOException {
+ if (this.outputFile.isDirectory()) {
+ System.out.println("Creating one file for each family...");
+ Iterator iter = fontFamilies.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry entry = (Map.Entry)iter.next();
+ String familyName = (String)entry.getKey();
+ System.out.println("Creating output file for " + familyName + "...");
+ String filename;
+ switch(this.mode) {
+ case GENERATE_RENDERED:
+ filename = familyName + ".pdf";
+ break;
+ case GENERATE_FO:
+ filename = familyName + ".fo";
+ break;
+ case GENERATE_XML:
+ filename = familyName + ".xml";
+ break;
+ default:
+ throw new IllegalStateException("Unsupported mode");
+ }
+ File outFile = new File(this.outputFile, filename);
+ generateXML(fontFamilies, outFile, familyName);
+ }
+ } else {
+ System.out.println("Creating output file...");
+ generateXML(fontFamilies, this.outputFile, this.singleFamilyFilter);
+ }
+ System.out.println(this.outputFile + " written.");
+ }
+
+ private static void printVersion() {
+ System.out.println("Apache FOP " + Version.getVersion()
+ + " - http://xmlgraphics.apache.org/fop/\n");
+ }
+
+ private static void printHelp() {
+ printVersion();
+
+ String className = FontListMain.class.getName();
+ PrintStream out = System.out;
+ out.println("USAGE");
+ out.println(" java [vmargs] " + className
+ + " [-c <config-file>] [-f <mime>] [[output-dir|output-file] [font-family]]");
+ out.println();
+ out.println("PARAMETERS");
+ out.println(" config-file: an optional FOP configuration file");
+ out.println(" mime: The MIME type of the output format for which to");
+ out.println(" create the font list (defaults to application/pdf)");
+ out.println(" output-dir: Creates one sample PDF per font-family");
+ out.println(" output-file: writes the list as file (valid file extensions: xml, fo, pdf)");
+ out.println(" font-family: filters to a single font family");
+ out.println();
+ out.println("EXAMPLE");
+ out.println(" java [vmargs] " + className
+ + " -c userconfig.xml all-fonts.pdf");
+ out.println(" --> this generates a single PDF containing a sample");
+ out.println(" of all configured fonts.");
+ out.println(" java [vmargs] " + className
+ + " -c userconfig.xml");
+ out.println(" --> this prints all configured fonts to the console.");
+ out.println();
+ }
+
+ private void parseArguments(String[] args) {
+ if (args.length > 0) {
+ int idx = 0;
+ if ("--help".equals(args[idx]) || "-?".equals(args[idx]) || "-h".equals(args[idx])) {
+ printHelp();
+ System.exit(0);
+ }
+ if (idx < args.length - 1 && "-c".equals(args[idx])) {
+ String filename = args[idx + 1];
+ this.configFile = new File(filename);
+ idx += 2;
+ }
+ if (idx < args.length - 1 && "-f".equals(args[idx])) {
+ this.configMime = args[idx + 1];
+ idx += 2;
+ }
+ if (idx < args.length) {
+ String name = args[idx];
+ this.outputFile = new File(name);
+ if (this.outputFile.isDirectory()) {
+ this.mode = GENERATE_RENDERED;
+ this.outputMime = MimeConstants.MIME_PDF;
+ } else if (FilenameUtils.getExtension(name).equalsIgnoreCase("pdf")) {
+ this.mode = GENERATE_RENDERED;
+ this.outputMime = MimeConstants.MIME_PDF;
+ } else if (FilenameUtils.getExtension(name).equalsIgnoreCase("fo")) {
+ this.mode = GENERATE_FO;
+ } else if (FilenameUtils.getExtension(name).equalsIgnoreCase("xml")) {
+ this.mode = GENERATE_XML;
+ } else {
+ throw new IllegalArgumentException(
+ "Operating mode for the output file cannot be determined"
+ + " or is unsupported: " + name);
+ }
+ idx++;
+ }
+ if (idx < args.length) {
+ this.singleFamilyFilter = args[idx];
+ }
+ } else {
+ System.out.println("use --help or -? for usage information.");
+ }
+ }
+
+ /**
+ * The command-line interface.
+ * @param args the command-line arguments
+ */
+ public static void main(String[] args) {
+ try {
+ FontListMain app = new FontListMain();
+ app.parseArguments(args);
+ app.generate();
+ } catch (Throwable t) {
+ printHelp();
+ t.printStackTrace();
+ System.exit(-1);
+ }
+ }
+
+}
diff --git a/src/java/org/apache/fop/tools/fontlist/FontListSerializer.java b/src/java/org/apache/fop/tools/fontlist/FontListSerializer.java
new file mode 100644
index 000000000..eab3caa56
--- /dev/null
+++ b/src/java/org/apache/fop/tools/fontlist/FontListSerializer.java
@@ -0,0 +1,142 @@
+/*
+ * 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.tools.fontlist;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.regex.Pattern;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.util.GenerationHelperContentHandler;
+
+/**
+ * Turns the font list into SAX events.
+ */
+public class FontListSerializer {
+
+ private static final String FONTS = "fonts";
+ private static final String FAMILY = "family";
+ private static final String FONT = "font";
+ private static final String TRIPLETS = "triplets";
+ private static final String TRIPLET = "triplet";
+
+ private static final String NAME = "name";
+ private static final String STRIPPED_NAME = "stripped-name";
+ private static final String TYPE = "type";
+ private static final String KEY = "key";
+ private static final String STYLE = "style";
+ private static final String WEIGHT = "weight";
+
+ private static final String CDATA = "CDATA";
+
+ /**
+ * Generates SAX events from the font damily map.
+ * @param fontFamilies the font families
+ * @param handler the target SAX handler
+ * @throws SAXException if an XML-related exception occurs
+ */
+ public void generateSAX(SortedMap fontFamilies,
+ GenerationHelperContentHandler handler) throws SAXException {
+ generateSAX(fontFamilies, null, handler);
+ }
+
+ /**
+ * Generates SAX events from the font damily map.
+ * @param fontFamilies the font families
+ * @param singleFamily if not null, the output will be filtered so only this single font family
+ * will be used
+ * @param handler the target SAX handler
+ * @throws SAXException if an XML-related exception occurs
+ */
+ public void generateSAX(SortedMap fontFamilies, String singleFamily,
+ GenerationHelperContentHandler handler) throws SAXException {
+ handler.startDocument();
+ AttributesImpl atts = new AttributesImpl();
+ handler.startElement(FONTS, atts);
+
+ Iterator iter = fontFamilies.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry entry = (Map.Entry)iter.next();
+ String familyName = (String)entry.getKey();
+ if (singleFamily != null && familyName != singleFamily) {
+ continue;
+ }
+ atts.clear();
+ atts.addAttribute(null, NAME, NAME, CDATA, familyName);
+ atts.addAttribute(null, STRIPPED_NAME, STRIPPED_NAME, CDATA,
+ stripQuotes(familyName));
+ handler.startElement(FAMILY, atts);
+
+ List containers = (List)entry.getValue();
+ generateXMLForFontContainers(handler, containers);
+ handler.endElement(FAMILY);
+ }
+
+ handler.endElement(FONTS);
+ handler.endDocument();
+ }
+
+ private final Pattern quotePattern = Pattern.compile("'");
+
+ private String stripQuotes(String name) {
+ return quotePattern.matcher(name).replaceAll("");
+ }
+
+ private void generateXMLForFontContainers(GenerationHelperContentHandler handler,
+ List containers) throws SAXException {
+ AttributesImpl atts = new AttributesImpl();
+ Iterator fontIter = containers.iterator();
+ while (fontIter.hasNext()) {
+ FontSpec cont = (FontSpec)fontIter.next();
+ atts.clear();
+ atts.addAttribute(null, KEY, KEY, CDATA, cont.getKey());
+ atts.addAttribute(null, TYPE, TYPE, CDATA,
+ cont.getFontMetrics().getFontType().getName());
+ handler.startElement(FONT, atts);
+ generateXMLForTriplets(handler, cont.getTriplets());
+ handler.endElement(FONT);
+ }
+ }
+
+ private void generateXMLForTriplets(GenerationHelperContentHandler handler, Collection triplets)
+ throws SAXException {
+ AttributesImpl atts = new AttributesImpl();
+ atts.clear();
+ handler.startElement(TRIPLETS, atts);
+ Iterator iter = triplets.iterator();
+ while (iter.hasNext()) {
+ FontTriplet triplet = (FontTriplet)iter.next();
+ atts.clear();
+ atts.addAttribute(null, NAME, NAME, CDATA, triplet.getName());
+ atts.addAttribute(null, STYLE, STYLE, CDATA, triplet.getStyle());
+ atts.addAttribute(null, WEIGHT, WEIGHT, CDATA,
+ Integer.toString(triplet.getWeight()));
+ handler.element(TRIPLET, atts);
+ }
+ handler.endElement(TRIPLETS);
+ }
+
+}
diff --git a/src/java/org/apache/fop/tools/fontlist/FontSpec.java b/src/java/org/apache/fop/tools/fontlist/FontSpec.java
new file mode 100644
index 000000000..ce5c7a6c7
--- /dev/null
+++ b/src/java/org/apache/fop/tools/fontlist/FontSpec.java
@@ -0,0 +1,103 @@
+/*
+ * 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.tools.fontlist;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.SortedSet;
+
+import org.apache.fop.fonts.FontMetrics;
+import org.apache.fop.fonts.FontTriplet;
+
+/**
+ * Represents a font with information on how it can be used from XSL-FO.
+ */
+public class FontSpec implements Comparable {
+
+ private String key;
+ private FontMetrics metrics;
+ private SortedSet familyNames = new java.util.TreeSet();
+ private Collection triplets = new java.util.TreeSet();
+
+ /**
+ * Creates a new font spec.
+ * @param key the internal font key
+ * @param metrics the font metrics
+ */
+ public FontSpec(String key, FontMetrics metrics) {
+ this.key = key;
+ this.metrics = metrics;
+ }
+
+ /**
+ * Adds font family names.
+ * @param names the names
+ */
+ public void addFamilyNames(Collection names) {
+ this.familyNames.addAll(names);
+ }
+
+ /**
+ * Adds a font triplet.
+ * @param triplet the font triplet
+ */
+ public void addTriplet(FontTriplet triplet) {
+ this.triplets.add(triplet);
+ }
+
+ /**
+ * Returns the font family names.
+ * @return the font family names
+ */
+ public SortedSet getFamilyNames() {
+ return Collections.unmodifiableSortedSet(this.familyNames);
+ }
+
+ /**
+ * Returns the font triplets.
+ * @return the font triplets
+ */
+ public Collection getTriplets() {
+ return Collections.unmodifiableCollection(this.triplets);
+ }
+
+ /**
+ * Returns the internal font key.
+ * @return the internal font key
+ */
+ public String getKey() {
+ return this.key;
+ }
+
+ /**
+ * Returns the font metrics.
+ * @return the font metrics
+ */
+ public FontMetrics getFontMetrics() {
+ return this.metrics;
+ }
+
+ /** {@inheritDoc} */
+ public int compareTo(Object o) {
+ FontSpec other = (FontSpec)o;
+ return metrics.getFullName().compareTo(other.metrics.getFullName());
+ }
+
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/tools/fontlist/fonts2fo.xsl b/src/java/org/apache/fop/tools/fontlist/fonts2fo.xsl
new file mode 100644
index 000000000..5c2b59e8e
--- /dev/null
+++ b/src/java/org/apache/fop/tools/fontlist/fonts2fo.xsl
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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$ -->
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ xmlns:svg="http://www.w3.org/2000/svg">
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:param name="single-family" select="''"/>
+
+ <xsl:template match="fonts">
+ <fo:root font-family="sans-serif" font-size="10pt">
+ <!-- defines the layout master -->
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm"
+ margin="1.5cm">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <!-- starts actual layout -->
+ <xsl:choose>
+ <xsl:when test="string-length($single-family) &gt; 0">
+ <xsl:apply-templates select="family[@name = $single-family]"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="bookmarks"/>
+ <xsl:call-template name="toc"/>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </fo:root>
+ </xsl:template>
+
+ <xsl:template name="bookmarks">
+ <fo:bookmark-tree>
+ <fo:bookmark internal-destination="toc">
+ <fo:bookmark-title>Table of Contents</fo:bookmark-title>
+ </fo:bookmark>
+ <xsl:apply-templates mode="bookmark"/>
+ </fo:bookmark-tree>
+ </xsl:template>
+
+ <xsl:template name="toc">
+ <fo:page-sequence master-reference="A4" id="toc">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>
+ <fo:block font-size="14pt" font-weight="bold" space-after="1em">FOP Font List</fo:block>
+ <fo:block space-after="0.5em">The number of font families: <xsl:value-of select="count(family)"/></fo:block>
+ </fo:block>
+ <xsl:if test="count(family) > 0">
+ <fo:list-block provisional-distance-between-starts="1.6em"
+ provisional-label-separation="0.5em">
+ <xsl:apply-templates mode="toc"/>
+ </fo:list-block>
+ </xsl:if>
+ </fo:flow>
+ </fo:page-sequence>
+ </xsl:template>
+
+ <xsl:template match="family" mode="bookmark">
+ <fo:bookmark internal-destination="{generate-id()}">
+ <fo:bookmark-title>
+ <xsl:value-of select="@name"/>
+ </fo:bookmark-title>
+ </fo:bookmark>
+ </xsl:template>
+
+ <xsl:template match="family" mode="toc">
+ <fo:list-item>
+ <fo:list-item-label start-indent="2mm" end-indent="label-end()">
+ <fo:block hyphenation-character="&#x2212;" font-family="Symbol">&#x2022;</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+ <fo:basic-link internal-destination="{generate-id()}">
+ <xsl:value-of select="@name"/>
+ </fo:basic-link>
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </xsl:template>
+
+ <xsl:template match="family">
+ <fo:page-sequence master-reference="A4" id="{generate-id()}">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>
+ <fo:block font-size="14pt" font-weight="bold" space-after="0.5em" border-bottom="solid 0.5mm">
+ <xsl:value-of select="@name"/>
+ </fo:block>
+ <fo:block>
+ <fo:block font-weight="bold">Fonts:</fo:block>
+ <xsl:apply-templates/>
+ </fo:block>
+ </fo:block>
+ <xsl:call-template name="weight-sample">
+ <xsl:with-param name="font-family" select="@stripped-name"/>
+ </xsl:call-template>
+ </fo:flow>
+ </fo:page-sequence>
+ </xsl:template>
+
+ <xsl:template name="weight-sample">
+ <xsl:param name="font-family" select="'sans-serif'"/>
+ <fo:block border="solid 0.25mm" start-indent="0.25mm" end-indent="0.25mm"
+ space-before="0.5em"
+ keep-together.within-column="always">
+ <fo:block font-size="8pt"
+ background-color="black" color="white"
+ padding="0mm 1mm" start-indent="1.25mm" end-indent="1.25mm">
+ Weight Sample: font-family="<xsl:value-of select="$font-family"/>" font-weight="100..900"</fo:block>
+ <fo:block padding="1mm 1mm" start-indent="1.25mm" end-indent="1.25mm">
+ <xsl:attribute name="font-family">
+ <xsl:value-of select="$font-family"/>
+ </xsl:attribute>
+ <fo:block font-weight="100">100: The quick brown fox jumps over the lazy dog</fo:block>
+ <fo:block font-weight="200">200: The quick brown fox jumps over the lazy dog</fo:block>
+ <fo:block font-weight="300">300: The quick brown fox jumps over the lazy dog</fo:block>
+ <fo:block font-weight="400">400: The quick brown fox jumps over the lazy dog</fo:block>
+ <fo:block font-weight="500">500: The quick brown fox jumps over the lazy dog</fo:block>
+ <fo:block font-weight="600">600: The quick brown fox jumps over the lazy dog</fo:block>
+ <fo:block font-weight="700">700: The quick brown fox jumps over the lazy dog</fo:block>
+ <fo:block font-weight="800">800: The quick brown fox jumps over the lazy dog</fo:block>
+ <fo:block font-weight="900">900: The quick brown fox jumps over the lazy dog</fo:block>
+ <fo:block>
+ <fo:instream-foreign-object>
+ <svg xmlns="http://www.w3.org/2000/svg" width="16cm" height="108pt">
+ <g font-family="sans-serif" font-weight="bold" font-size="80pt"
+ transform="translate(30, 100) rotate(-15)">
+ <text fill="lightgray">SVG</text>
+ </g>
+ <g font-size="10pt">
+ <xsl:attribute name="font-family">
+ '<xsl:value-of select="$font-family"/>'
+ </xsl:attribute>
+ <text x="0" y="10">
+ <tspan x="0" dy="0" font-weight="100">100: The quick brown fox jumps over the lazy dog</tspan>
+ <tspan x="0" dy="12" font-weight="200">200: The quick brown fox jumps over the lazy dog</tspan>
+ <tspan x="0" dy="12" font-weight="300">300: The quick brown fox jumps over the lazy dog</tspan>
+ <tspan x="0" dy="12" font-weight="400">400: The quick brown fox jumps over the lazy dog</tspan>
+ <tspan x="0" dy="12" font-weight="500">500: The quick brown fox jumps over the lazy dog</tspan>
+ <tspan x="0" dy="12" font-weight="600">600: The quick brown fox jumps over the lazy dog</tspan>
+ <tspan x="0" dy="12" font-weight="700">700: The quick brown fox jumps over the lazy dog</tspan>
+ <tspan x="0" dy="12" font-weight="800">800: The quick brown fox jumps over the lazy dog</tspan>
+ <tspan x="0" dy="12" font-weight="900">900: The quick brown fox jumps over the lazy dog</tspan>
+ </text>
+ </g>
+ </svg>
+ </fo:instream-foreign-object>
+ </fo:block>
+ </fo:block>
+ </fo:block>
+ </xsl:template>
+
+ <xsl:template match="font">
+ <fo:block>Internal key: <xsl:value-of select="@key"/></fo:block>
+ <fo:block border="solid 0.25mm" start-indent="0.25mm" end-indent="0.25mm">
+ <fo:block font-size="8pt"
+ background-color="black" color="white"
+ padding="0mm 1mm" start-indent="1.25mm" end-indent="1.25mm">
+ Sample:</fo:block>
+ <fo:block font-family="{triplets/triplet[1]/@name}"
+ font-style="{triplets/triplet[1]/@style}"
+ font-weight="{triplets/triplet[1]/@weight}"
+ font-size="14pt" padding="1mm" start-indent="1.25mm" end-indent="1.25mm">
+ The quick brown fox jumps over the lazy dog.
+ </fo:block>
+ </fo:block>
+ <fo:block start-indent="5mm">
+ <fo:block>Accessible by:</fo:block>
+ <fo:block start-indent="10mm">
+ <xsl:apply-templates select="triplets/triplet"/>
+ </fo:block>
+ </fo:block>
+ </xsl:template>
+
+ <xsl:template match="triplet">
+ <fo:block color="gray">
+ font-family=<fo:inline color="black">"<xsl:value-of select="@name"/>"</fo:inline>
+ font-style=<fo:inline color="black"><xsl:value-of select="@style"/>"</fo:inline>
+ font-weight=<fo:inline color="black"><xsl:value-of select="@weight"/>"</fo:inline>
+ </fo:block>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/status.xml b/status.xml
index 825824410..5c28c8005 100644
--- a/status.xml
+++ b/status.xml
@@ -58,6 +58,10 @@
documents. Example: the fix of marks layering will be such a case when it's done.
-->
<release version="FOP Trunk" date="TBD">
+ <action context="Fonts" dev="JM" type="add">
+ Added a command-line tool to list all configured fonts
+ (org.apache.fop.tools.fontlist.FontListMain).
+ </action>
<action context="Code" dev="AD" type="add" fixes-bug="46828" due-to="Dario Laera">
Added the possibility to use CachedRenderPagesModel, to conserve memory in case
of large documents with a lot of cross-references (area tree will be serialized to