001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: $ */
019:
020: package org.apache.fop.apps;
021:
022: import java.awt.color.ColorSpace;
023: import java.io.File;
024: import java.io.IOException;
025: import java.io.OutputStream;
026: import java.net.MalformedURLException;
027: import java.net.URL;
028: import java.util.Collection;
029: import java.util.Collections;
030: import java.util.Set;
031:
032: import javax.xml.transform.Source;
033: import javax.xml.transform.TransformerException;
034: import javax.xml.transform.URIResolver;
035:
036: import org.xml.sax.SAXException;
037:
038: import org.apache.avalon.framework.configuration.Configuration;
039:
040: import org.apache.commons.logging.Log;
041: import org.apache.commons.logging.LogFactory;
042:
043: import org.apache.fop.fo.ElementMapping;
044: import org.apache.fop.fo.ElementMappingRegistry;
045: import org.apache.fop.fonts.FontCache;
046: import org.apache.fop.hyphenation.HyphenationTreeResolver;
047: import org.apache.fop.image.ImageFactory;
048: import org.apache.fop.layoutmgr.LayoutManagerMaker;
049: import org.apache.fop.render.RendererFactory;
050: import org.apache.fop.render.XMLHandlerRegistry;
051: import org.apache.fop.util.ColorSpaceCache;
052: import org.apache.fop.util.ContentHandlerFactoryRegistry;
053:
054: /**
055: * Factory class which instantiates new Fop and FOUserAgent instances. This
056: * class also holds environmental information and configuration used by FOP.
057: * Information that may potentially be different for each rendering run can be
058: * found and managed in the FOUserAgent.
059: */
060: public class FopFactory {
061:
062: /** logger instance */
063: private static Log log = LogFactory.getLog(FopFactory.class);
064:
065: /** Factory for Renderers and FOEventHandlers */
066: private RendererFactory rendererFactory;
067:
068: /** Registry for XML handlers */
069: private XMLHandlerRegistry xmlHandlers;
070:
071: /** The registry for ElementMapping instances */
072: private ElementMappingRegistry elementMappingRegistry;
073:
074: /** The registry for ContentHandlerFactory instance */
075: private ContentHandlerFactoryRegistry contentHandlerFactoryRegistry = new ContentHandlerFactoryRegistry();
076:
077: /** The resolver for user-supplied hyphenation patterns */
078: private HyphenationTreeResolver hyphResolver = null;
079:
080: private ColorSpaceCache colorSpaceCache = null;
081:
082: /** Image factory for creating fop image objects */
083: private ImageFactory imageFactory;
084:
085: /** Configuration layer used to configure fop */
086: private FopFactoryConfigurator config = null;
087:
088: /**
089: * The base URL for all URL resolutions, especially for
090: * external-graphics.
091: */
092: private String base = null;
093:
094: /** The base URL for all font URL resolutions. */
095: private String fontBase = null;
096:
097: /** The base URL for all hyphen URL resolutions. */
098: private String hyphenBase = null;
099:
100: /**
101: * FOP has the ability, for some FO's, to continue processing even if the
102: * input XSL violates that FO's content model. This is the default
103: * behavior for FOP. However, this flag, if set, provides the user the
104: * ability for FOP to halt on all content model violations if desired.
105: */
106: private boolean strictFOValidation = FopFactoryConfigurator.DEFAULT_STRICT_FO_VALIDATION;
107:
108: /**
109: * FOP will validate the contents of the user configuration strictly
110: * (e.g. base-urls and font urls/paths).
111: */
112: private boolean strictUserConfigValidation = FopFactoryConfigurator.DEFAULT_STRICT_USERCONFIG_VALIDATION;
113:
114: /** Font cache to speed up auto-font configuration (null if disabled) */
115: private FontCache fontCache = null;
116:
117: /** Allows enabling kerning on the base 14 fonts, default is false */
118: private boolean enableBase14Kerning = false;
119:
120: /** Source resolution in dpi */
121: private float sourceResolution = FopFactoryConfigurator.DEFAULT_SOURCE_RESOLUTION;
122:
123: /** Target resolution in dpi */
124: private float targetResolution = FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
125:
126: /** Page height */
127: private String pageHeight = FopFactoryConfigurator.DEFAULT_PAGE_HEIGHT;
128:
129: /** Page width */
130: private String pageWidth = FopFactoryConfigurator.DEFAULT_PAGE_WIDTH;
131:
132: /** @see #setBreakIndentInheritanceOnReferenceAreaBoundary(boolean) */
133: private boolean breakIndentInheritanceOnReferenceAreaBoundary = FopFactoryConfigurator.DEFAULT_BREAK_INDENT_INHERITANCE;
134:
135: /** Optional overriding LayoutManagerMaker */
136: private LayoutManagerMaker lmMakerOverride = null;
137:
138: private Set ignoredNamespaces;
139:
140: private FOURIResolver foURIResolver;
141:
142: /**
143: * Main constructor.
144: */
145: protected FopFactory() {
146: this .config = new FopFactoryConfigurator(this );
147: this .elementMappingRegistry = new ElementMappingRegistry(this );
148: this .foURIResolver = new FOURIResolver(
149: validateUserConfigStrictly());
150: this .colorSpaceCache = new ColorSpaceCache(foURIResolver);
151: this .imageFactory = new ImageFactory();
152: this .rendererFactory = new RendererFactory();
153: this .xmlHandlers = new XMLHandlerRegistry();
154: this .ignoredNamespaces = new java.util.HashSet();
155: setUseCache(FopFactoryConfigurator.DEFAULT_USE_CACHE);
156: }
157:
158: /**
159: * Returns a new FopFactory instance.
160: * @return the requested FopFactory instance.
161: */
162: public static FopFactory newInstance() {
163: return new FopFactory();
164: }
165:
166: /**
167: * Returns a new FOUserAgent instance. Use the FOUserAgent to configure special values that
168: * are particular to a rendering run. Don't reuse instances over multiple rendering runs but
169: * instead create a new one each time and reuse the FopFactory.
170: * @return the newly created FOUserAgent instance initialized with default values
171: * @throws FOPException
172: */
173: public FOUserAgent newFOUserAgent() {
174: FOUserAgent userAgent = new FOUserAgent(this );
175: return userAgent;
176: }
177:
178: /**
179: * Returns a new {@link Fop} instance. FOP will be configured with a default user agent
180: * instance.
181: * <p>
182: * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
183: * use the constants defined in {@link MimeConstants}.
184: * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
185: * @return the new Fop instance
186: * @throws FOPException when the constructor fails
187: */
188: public Fop newFop(String outputFormat) throws FOPException {
189: return new Fop(outputFormat, newFOUserAgent());
190: }
191:
192: /**
193: * Returns a new {@link Fop} instance. Use this factory method if you want to configure this
194: * very rendering run, i.e. if you want to set some metadata like the title and author of the
195: * document you want to render. In that case, create a new {@link FOUserAgent}
196: * instance using {@link #newFOUserAgent()}.
197: * <p>
198: * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
199: * use the constants defined in {@link MimeConstants}.
200: * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
201: * @param userAgent the user agent that will be used to control the rendering run
202: * @return the new Fop instance
203: * @throws FOPException when the constructor fails
204: */
205: public Fop newFop(String outputFormat, FOUserAgent userAgent)
206: throws FOPException {
207: if (userAgent == null) {
208: throw new NullPointerException(
209: "The userAgent parameter must not be null!");
210: }
211: return new Fop(outputFormat, userAgent);
212: }
213:
214: /**
215: * Returns a new {@link Fop} instance. FOP will be configured with a default user agent
216: * instance. Use this factory method if your output type requires an output stream.
217: * <p>
218: * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
219: * use the constants defined in {@link MimeConstants}.
220: * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
221: * @param stream the output stream
222: * @return the new Fop instance
223: * @throws FOPException when the constructor fails
224: */
225: public Fop newFop(String outputFormat, OutputStream stream)
226: throws FOPException {
227: return new Fop(outputFormat, newFOUserAgent(), stream);
228: }
229:
230: /**
231: * Returns a new {@link Fop} instance. Use this factory method if your output type
232: * requires an output stream and you want to configure this very rendering run,
233: * i.e. if you want to set some metadata like the title and author of the document
234: * you want to render. In that case, create a new {@link FOUserAgent} instance
235: * using {@link #newFOUserAgent()}.
236: * <p>
237: * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
238: * use the constants defined in {@link MimeConstants}.
239: * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
240: * @param userAgent the user agent that will be used to control the rendering run
241: * @param stream the output stream
242: * @return the new Fop instance
243: * @throws FOPException when the constructor fails
244: */
245: public Fop newFop(String outputFormat, FOUserAgent userAgent,
246: OutputStream stream) throws FOPException {
247: if (userAgent == null) {
248: throw new NullPointerException(
249: "The userAgent parameter must not be null!");
250: }
251: return new Fop(outputFormat, userAgent, stream);
252: }
253:
254: /**
255: * Returns a new {@link Fop} instance. Use this factory method if you want to supply your
256: * own {@link org.apache.fop.render.Renderer Renderer} or
257: * {@link org.apache.fop.fo.FOEventHandler FOEventHandler}
258: * instance instead of the default ones created internally by FOP.
259: * @param userAgent the user agent that will be used to control the rendering run
260: * @return the new Fop instance
261: * @throws FOPException when the constructor fails
262: */
263: public Fop newFop(FOUserAgent userAgent) throws FOPException {
264: if (userAgent.getRendererOverride() == null
265: && userAgent.getFOEventHandlerOverride() == null) {
266: throw new IllegalStateException(
267: "Either the overriding renderer or the overriding"
268: + " FOEventHandler must be set when this factory method is used!");
269: }
270: return newFop(null, userAgent);
271: }
272:
273: /** @return the RendererFactory */
274: public RendererFactory getRendererFactory() {
275: return this .rendererFactory;
276: }
277:
278: /** @return the XML handler registry */
279: public XMLHandlerRegistry getXMLHandlerRegistry() {
280: return this .xmlHandlers;
281: }
282:
283: /** @return the element mapping registry */
284: public ElementMappingRegistry getElementMappingRegistry() {
285: return this .elementMappingRegistry;
286: }
287:
288: /** @return the content handler factory registry */
289: public ContentHandlerFactoryRegistry getContentHandlerFactoryRegistry() {
290: return this .contentHandlerFactoryRegistry;
291: }
292:
293: /** @return the image factory */
294: public ImageFactory getImageFactory() {
295: return this .imageFactory;
296: }
297:
298: /**
299: * Add the element mapping with the given class name.
300: * @param elementMapping the class name representing the element mapping.
301: */
302: public void addElementMapping(ElementMapping elementMapping) {
303: this .elementMappingRegistry.addElementMapping(elementMapping);
304: }
305:
306: /**
307: * Sets an explicit LayoutManagerMaker instance which overrides the one
308: * defined by the AreaTreeHandler.
309: * @param lmMaker the LayoutManagerMaker instance
310: */
311: public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
312: this .lmMakerOverride = lmMaker;
313: }
314:
315: /**
316: * Returns the overriding LayoutManagerMaker instance, if any.
317: * @return the overriding LayoutManagerMaker or null
318: */
319: public LayoutManagerMaker getLayoutManagerMakerOverride() {
320: return this .lmMakerOverride;
321: }
322:
323: /**
324: * cleans the base url
325: * @param base
326: * @return
327: * @throws MalformedURLException
328: * @throws URISyntaxException
329: */
330: private String checkBaseURL(String base)
331: throws MalformedURLException {
332: if (!base.endsWith("/")) {
333: // The behavior described by RFC 3986 regarding resolution of relative
334: // references may be misleading for normal users:
335: // file://path/to/resources + myResource.res -> file://path/to/myResource.res
336: // file://path/to/resources/ + myResource.res -> file://path/to/resources/myResource.res
337: // We assume that even when the ending slash is missing, users have the second
338: // example in mind
339: base += "/";
340: }
341: File dir = new File(base);
342: try {
343: base = (dir.isDirectory() ? dir.toURL() : new URL(base))
344: .toExternalForm();
345: } catch (MalformedURLException mfue) {
346: if (strictUserConfigValidation) {
347: throw mfue;
348: }
349: log.error(mfue.getMessage());
350: }
351: return base;
352: }
353:
354: /**
355: * Sets the base URL.
356: * @param base base URL
357: * @throws MalformedURLException
358: * @throws URISyntaxException
359: */
360: public void setBaseURL(String base) throws MalformedURLException {
361: this .base = checkBaseURL(base);
362: }
363:
364: /**
365: * Returns the base URL.
366: * @return the base URL
367: */
368: public String getBaseURL() {
369: return this .base;
370: }
371:
372: /**
373: * Sets the font base URL.
374: * @param fontBase font base URL
375: * @throws MalformedURLException
376: * @throws URISyntaxException
377: */
378: public void setFontBaseURL(String fontBase)
379: throws MalformedURLException {
380: this .fontBase = checkBaseURL(fontBase);
381: }
382:
383: /** @return the font base URL */
384: public String getFontBaseURL() {
385: return this .fontBase;
386: }
387:
388: /** @return the hyphen base URL */
389: public String getHyphenBaseURL() {
390: return this .hyphenBase;
391: }
392:
393: /**
394: * Sets the hyphen base URL.
395: * @param hyphenBase hythen base URL
396: * @throws MalformedURLException
397: * @throws URISyntaxException
398: * */
399: public void setHyphenBaseURL(final String hyphenBase)
400: throws MalformedURLException {
401: if (hyphenBase != null) {
402: setHyphenationTreeResolver(new HyphenationTreeResolver() {
403: public Source resolve(String href) {
404: return resolveURI(href, hyphenBase);
405: }
406: });
407: }
408: this .hyphenBase = checkBaseURL(hyphenBase);
409: }
410:
411: /**
412: * Sets the URI Resolver. It is used for resolving factory-level URIs like hyphenation
413: * patterns and as backup for URI resolution performed during a rendering run.
414: * @param resolver the new URI resolver
415: */
416: public void setURIResolver(URIResolver uriResolver) {
417: foURIResolver.setCustomURIResolver(uriResolver);
418: }
419:
420: /**
421: * Returns the URI Resolver.
422: * @return the URI Resolver
423: */
424: public URIResolver getURIResolver() {
425: return foURIResolver;
426: }
427:
428: /** @return the HyphenationTreeResolver for resolving user-supplied hyphenation patterns. */
429: public HyphenationTreeResolver getHyphenationTreeResolver() {
430: return this .hyphResolver;
431: }
432:
433: /**
434: * sets the HyphenationTreeResolver
435: * @param hyphResolver
436: */
437: public void setHyphenationTreeResolver(
438: HyphenationTreeResolver hyphResolver) {
439: this .hyphResolver = hyphResolver;
440: }
441:
442: /**
443: * Activates strict XSL content model validation for FOP
444: * Default is false (FOP will continue processing where it can)
445: * @param validateStrictly true to turn on strict validation
446: */
447: public void setStrictValidation(boolean validateStrictly) {
448: this .strictFOValidation = validateStrictly;
449: }
450:
451: /**
452: * Returns whether FOP is strictly validating input XSL
453: * @return true of strict validation turned on, false otherwise
454: */
455: public boolean validateStrictly() {
456: return strictFOValidation;
457: }
458:
459: /**
460: * @return true if the indent inheritance should be broken when crossing reference area
461: * boundaries (for more info, see the javadoc for the relative member variable)
462: */
463: public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
464: return breakIndentInheritanceOnReferenceAreaBoundary;
465: }
466:
467: /**
468: * Controls whether to enable a feature that breaks indent inheritance when crossing
469: * reference area boundaries.
470: * <p>
471: * This flag controls whether FOP will enable special code that breaks property
472: * inheritance for start-indent and end-indent when the evaluation of the inherited
473: * value would cross a reference area. This is described under
474: * http://wiki.apache.org/xmlgraphics-fop/IndentInheritance as is intended to
475: * improve interoperability with commercial FO implementations and to produce
476: * results that are more in line with the expectation of unexperienced FO users.
477: * Note: Enabling this features violates the XSL specification!
478: * @param value true to enable the feature
479: */
480: public void setBreakIndentInheritanceOnReferenceAreaBoundary(
481: boolean value) {
482: this .breakIndentInheritanceOnReferenceAreaBoundary = value;
483: }
484:
485: /** @return true if kerning on base 14 fonts is enabled */
486: public boolean isBase14KerningEnabled() {
487: return this .enableBase14Kerning;
488: }
489:
490: /**
491: * Controls whether kerning is activated on base 14 fonts.
492: * @param value true if kerning should be activated
493: */
494: public void setBase14KerningEnabled(boolean value) {
495: this .enableBase14Kerning = value;
496: }
497:
498: /** @return the resolution for resolution-dependant input */
499: public float getSourceResolution() {
500: return this .sourceResolution;
501: }
502:
503: /**
504: * Returns the conversion factor from pixel units to millimeters. This
505: * depends on the desired source resolution.
506: * @return float conversion factor
507: * @see #getSourceResolution()
508: */
509: public float getSourcePixelUnitToMillimeter() {
510: return 25.4f / getSourceResolution();
511: }
512:
513: /**
514: * Sets the source resolution in dpi. This value is used to interpret the pixel size
515: * of source documents like SVG images and bitmap images without resolution information.
516: * @param dpi resolution in dpi
517: */
518: public void setSourceResolution(float dpi) {
519: this .sourceResolution = dpi;
520: if (log.isDebugEnabled()) {
521: log.debug("source-resolution set to: " + sourceResolution
522: + "dpi (px2mm=" + getSourcePixelUnitToMillimeter()
523: + ")");
524: }
525: }
526:
527: /** @return the resolution for resolution-dependant output */
528: public float getTargetResolution() {
529: return this .targetResolution;
530: }
531:
532: /**
533: * Returns the conversion factor from pixel units to millimeters. This
534: * depends on the desired target resolution.
535: * @return float conversion factor
536: * @see #getTargetResolution()
537: */
538: public float getTargetPixelUnitToMillimeter() {
539: return 25.4f / this .targetResolution;
540: }
541:
542: /**
543: * Sets the source resolution in dpi. This value is used to interpret the pixel size
544: * of source documents like SVG images and bitmap images without resolution information.
545: * @param dpi resolution in dpi
546: */
547: public void setTargetResolution(float dpi) {
548: this .targetResolution = dpi;
549: }
550:
551: /**
552: * Sets the source resolution in dpi. This value is used to interpret the pixel size
553: * of source documents like SVG images and bitmap images without resolution information.
554: * @param dpi resolution in dpi
555: */
556: public void setSourceResolution(int dpi) {
557: setSourceResolution((float) dpi);
558: }
559:
560: /**
561: * Gets the default page-height to use as fallback,
562: * in case page-height="auto"
563: *
564: * @return the page-height, as a String
565: */
566: public String getPageHeight() {
567: return this .pageHeight;
568: }
569:
570: /**
571: * Sets the page-height to use as fallback, in case
572: * page-height="auto"
573: *
574: * @param pageHeight page-height as a String
575: */
576: public void setPageHeight(String pageHeight) {
577: this .pageHeight = pageHeight;
578: if (log.isDebugEnabled()) {
579: log.debug("Default page-height set to: " + pageHeight);
580: }
581: }
582:
583: /**
584: * Gets the default page-width to use as fallback,
585: * in case page-width="auto"
586: *
587: * @return the page-width, as a String
588: */
589: public String getPageWidth() {
590: return this .pageWidth;
591: }
592:
593: /**
594: * Sets the page-width to use as fallback, in case
595: * page-width="auto"
596: *
597: * @param pageWidth page-width as a String
598: */
599: public void setPageWidth(String pageWidth) {
600: this .pageWidth = pageWidth;
601: if (log.isDebugEnabled()) {
602: log.debug("Default page-width set to: " + pageWidth);
603: }
604: }
605:
606: /**
607: * Adds a namespace to the set of ignored namespaces.
608: * If FOP encounters a namespace which it cannot handle, it issues a warning except if this
609: * namespace is in the ignored set.
610: * @param namespaceURI the namespace URI
611: */
612: public void ignoreNamespace(String namespaceURI) {
613: this .ignoredNamespaces.add(namespaceURI);
614: }
615:
616: /**
617: * Adds a collection of namespaces to the set of ignored namespaces.
618: * If FOP encounters a namespace which it cannot handle, it issues a warning except if this
619: * namespace is in the ignored set.
620: * @param namespaceURIs the namespace URIs
621: */
622: public void ignoreNamespaces(Collection namespaceURIs) {
623: this .ignoredNamespaces.addAll(namespaceURIs);
624: }
625:
626: /**
627: * Indicates whether a namespace URI is on the ignored list.
628: * @param namespaceURI the namespace URI
629: * @return true if the namespace is ignored by FOP
630: */
631: public boolean isNamespaceIgnored(String namespaceURI) {
632: return this .ignoredNamespaces.contains(namespaceURI);
633: }
634:
635: /** @return the set of namespaces that are ignored by FOP */
636: public Set getIgnoredNamespace() {
637: return Collections.unmodifiableSet(this .ignoredNamespaces);
638: }
639:
640: //------------------------------------------- Configuration stuff
641:
642: /**
643: * Set the user configuration.
644: * @param userConfigFile the configuration file
645: * @throws IOException if an I/O error occurs
646: * @throws SAXException if a parsing error occurs
647: */
648: public void setUserConfig(File userConfigFile) throws SAXException,
649: IOException {
650: config.setUserConfig(userConfigFile);
651: }
652:
653: /**
654: * Set the user configuration from an URI.
655: * @param uri the URI to the configuration file
656: * @throws IOException if an I/O error occurs
657: * @throws SAXException if a parsing error occurs
658: */
659: public void setUserConfig(String uri) throws SAXException,
660: IOException {
661: config.setUserConfig(uri);
662: }
663:
664: /**
665: * Set the user configuration.
666: * @param userConfig configuration
667: * @throws FOPException if a configuration problem occurs
668: */
669: public void setUserConfig(Configuration userConfig)
670: throws FOPException {
671: config.setUserConfig(userConfig);
672: }
673:
674: /**
675: * Get the user configuration.
676: * @return the user configuration
677: */
678: public Configuration getUserConfig() {
679: return config.getUserConfig();
680: }
681:
682: /**
683: * Is the user configuration to be validated?
684: * @param strictUserConfigValidation strict user config validation
685: */
686: public void setStrictUserConfigValidation(
687: boolean strictUserConfigValidation) {
688: this .strictUserConfigValidation = strictUserConfigValidation;
689: this .foURIResolver
690: .setThrowExceptions(strictUserConfigValidation);
691: }
692:
693: /**
694: * Is the user configuration to be validated?
695: * @return if the user configuration should be validated
696: */
697: public boolean validateUserConfigStrictly() {
698: return this .strictUserConfigValidation;
699: }
700:
701: //------------------------------------------- Cache related stuff
702:
703: /**
704: * Whether or not to cache results of font triplet detection/auto-config
705: * @param useCache use cache or not
706: */
707: public void setUseCache(boolean useCache) {
708: if (useCache) {
709: this .fontCache = FontCache.load();
710: if (this .fontCache == null) {
711: this .fontCache = new FontCache();
712: }
713: } else {
714: this .fontCache = null;
715: }
716: }
717:
718: /**
719: * Cache results of font triplet detection/auto-config?
720: * @return whether this factory is uses the cache
721: */
722: public boolean useCache() {
723: return (this .fontCache != null);
724: }
725:
726: public FontCache getFontCache() {
727: return this .fontCache;
728: }
729:
730: /**
731: * Attempts to resolve the given URI.
732: * Will use the configured resolver and if not successful fall back
733: * to the default resolver.
734: * @param href URI to access
735: * @param baseUri the base URI to resolve against
736: * @return A {@link javax.xml.transform.Source} object, or null if the URI
737: * cannot be resolved.
738: * @see org.apache.fop.apps.FOURIResolver
739: */
740: public Source resolveURI(String href, String baseUri) {
741: Source source = null;
742: try {
743: source = foURIResolver.resolve(href, baseUri);
744: } catch (TransformerException e) {
745: log.error("Attempt to resolve URI '" + href + "' failed: ",
746: e);
747: }
748: return source;
749: }
750:
751: /**
752: * Create (if needed) and return an ICC ColorSpace instance.
753: *
754: * The ICC profile source is taken from the src attribute of the color-profile FO element.
755: * If the ICC ColorSpace is not yet in the cache a new one is created and stored in the cache.
756: *
757: * The FOP URI resolver is used to try and locate the ICC file.
758: * If that fails null is returned.
759: *
760: * @param baseUri a base URI to resolve relative URIs
761: * @param iccProfileSrc ICC Profile source to return a ColorSpace for
762: * @return ICC ColorSpace object or null if ColorSpace could not be created
763: */
764: public ColorSpace getColorSpace(String baseUri, String iccProfileSrc) {
765: return colorSpaceCache.get(baseUri, iccProfileSrc);
766: }
767: }
|