You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FontManagerConfigurator.java 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.fonts;
  19. import java.net.URI;
  20. import java.net.URISyntaxException;
  21. import java.util.List;
  22. import java.util.regex.Pattern;
  23. import org.apache.commons.logging.Log;
  24. import org.apache.commons.logging.LogFactory;
  25. import org.apache.xmlgraphics.io.ResourceResolver;
  26. import org.apache.fop.apps.FOPException;
  27. import org.apache.fop.apps.io.InternalResourceResolver;
  28. import org.apache.fop.apps.io.ResourceResolverFactory;
  29. import org.apache.fop.configuration.Configuration;
  30. import org.apache.fop.configuration.ConfigurationException;
  31. import org.apache.fop.fonts.substitute.FontSubstitutions;
  32. import org.apache.fop.fonts.substitute.FontSubstitutionsConfigurator;
  33. import org.apache.fop.util.LogUtil;
  34. /**
  35. * Configurator of the FontManager
  36. */
  37. public class FontManagerConfigurator {
  38. /** logger instance */
  39. private static Log log = LogFactory.getLog(FontManagerConfigurator.class);
  40. private final Configuration cfg;
  41. private final URI baseURI;
  42. private final URI fallbackURI;
  43. private final ResourceResolver resourceResolver;
  44. /**
  45. * Main constructor
  46. * @param cfg the font manager configuration object
  47. * @param baseURI the URI against which to resolve relative URIs
  48. * @param fallbackURI the URI to use as a fallback if font-base is unspecified
  49. * @param resourceResolver the resource resolver
  50. */
  51. public FontManagerConfigurator(Configuration cfg, URI baseURI, URI fallbackURI,
  52. ResourceResolver resourceResolver) {
  53. this.cfg = cfg;
  54. this.baseURI = baseURI;
  55. this.fallbackURI = fallbackURI;
  56. this.resourceResolver = resourceResolver;
  57. }
  58. /**
  59. * Initializes font settings from the user configuration
  60. * @param fontManager a font manager
  61. * @param strict true if strict checking of the configuration is enabled
  62. * @throws FOPException if an exception occurs while processing the configuration
  63. */
  64. public void configure(FontManager fontManager, boolean strict) throws FOPException {
  65. if (cfg.getChild("font-base", false) != null) {
  66. try {
  67. URI fontBase = InternalResourceResolver.getBaseURI(cfg.getChild("font-base")
  68. .getValue(null));
  69. fontManager.setResourceResolver(ResourceResolverFactory.createInternalResourceResolver(
  70. baseURI.resolve(fontBase), resourceResolver));
  71. } catch (URISyntaxException use) {
  72. LogUtil.handleException(log, use, true);
  73. }
  74. } else {
  75. fontManager.setResourceResolver(ResourceResolverFactory.createInternalResourceResolver(
  76. fallbackURI, resourceResolver));
  77. }
  78. // caching (fonts)
  79. if (cfg.getChild("use-cache", false) != null) {
  80. try {
  81. if (!cfg.getChild("use-cache").getValueAsBoolean()) {
  82. fontManager.disableFontCache();
  83. } else {
  84. if (cfg.getChild("cache-file", false) != null) {
  85. fontManager.setCacheFile(URI.create(cfg.getChild("cache-file").getValue()));
  86. }
  87. }
  88. } catch (ConfigurationException mfue) {
  89. LogUtil.handleException(log, mfue, true);
  90. }
  91. }
  92. // [GA] permit configuration control over base14 kerning; without this,
  93. // there is no way for a user to enable base14 kerning other than by
  94. // programmatic API;
  95. if (cfg.getChild("base14-kerning", false) != null) {
  96. try {
  97. fontManager
  98. .setBase14KerningEnabled(cfg.getChild("base14-kerning").getValueAsBoolean());
  99. } catch (ConfigurationException e) {
  100. LogUtil.handleException(log, e, true);
  101. }
  102. }
  103. // global font configuration
  104. Configuration fontsCfg = cfg.getChild("fonts", false);
  105. if (fontsCfg != null) {
  106. // font substitution
  107. Configuration substitutionsCfg = fontsCfg.getChild("substitutions", false);
  108. if (substitutionsCfg != null) {
  109. FontSubstitutions substitutions = new FontSubstitutions();
  110. new FontSubstitutionsConfigurator(substitutionsCfg).configure(substitutions);
  111. fontManager.setFontSubstitutions(substitutions);
  112. }
  113. // referenced fonts (fonts which are not to be embedded)
  114. Configuration referencedFontsCfg = fontsCfg.getChild("referenced-fonts", false);
  115. if (referencedFontsCfg != null) {
  116. FontTriplet.Matcher matcher = createFontsMatcher(
  117. referencedFontsCfg, strict);
  118. fontManager.setReferencedFontsMatcher(matcher);
  119. }
  120. }
  121. }
  122. /**
  123. * Creates a font triplet matcher from a configuration object.
  124. * @param cfg the configuration object
  125. * @param strict true for strict configuraton error handling
  126. * @return the font matcher
  127. * @throws FOPException if an error occurs while building the matcher
  128. */
  129. public static FontTriplet.Matcher createFontsMatcher(
  130. Configuration cfg, boolean strict) throws FOPException {
  131. List<FontTriplet.Matcher> matcherList = new java.util.ArrayList<FontTriplet.Matcher>();
  132. Configuration[] matches = cfg.getChildren("match");
  133. for (Configuration matche : matches) {
  134. try {
  135. matcherList.add(new FontFamilyRegExFontTripletMatcher(
  136. matche.getAttribute("font-family")));
  137. } catch (ConfigurationException ce) {
  138. LogUtil.handleException(log, ce, strict);
  139. continue;
  140. }
  141. }
  142. FontTriplet.Matcher orMatcher = new OrFontTripletMatcher(
  143. matcherList.toArray(new FontTriplet.Matcher[matcherList.size()]));
  144. return orMatcher;
  145. }
  146. /**
  147. * Creates a font triplet matcher from a configuration object.
  148. * @param fontFamilies the list of font families
  149. * @param strict true for strict configuraton error handling
  150. * @return the font matcher
  151. * @throws FOPException if an error occurs while building the matcher
  152. */
  153. public static FontTriplet.Matcher createFontsMatcher(
  154. List<String> fontFamilies, boolean strict) throws FOPException {
  155. List<FontTriplet.Matcher> matcherList = new java.util.ArrayList<FontTriplet.Matcher>();
  156. for (String fontFamily : fontFamilies) {
  157. matcherList.add(new FontFamilyRegExFontTripletMatcher(fontFamily));
  158. }
  159. FontTriplet.Matcher orMatcher = new OrFontTripletMatcher(
  160. matcherList.toArray(new FontTriplet.Matcher[matcherList.size()]));
  161. return orMatcher;
  162. }
  163. private static class OrFontTripletMatcher implements FontTriplet.Matcher {
  164. private final FontTriplet.Matcher[] matchers;
  165. public OrFontTripletMatcher(FontTriplet.Matcher[] matchers) {
  166. this.matchers = matchers;
  167. }
  168. /** {@inheritDoc} */
  169. public boolean matches(FontTriplet triplet) {
  170. for (FontTriplet.Matcher matcher : matchers) {
  171. if (matcher.matches(triplet)) {
  172. return true;
  173. }
  174. }
  175. return false;
  176. }
  177. }
  178. private static class FontFamilyRegExFontTripletMatcher implements FontTriplet.Matcher {
  179. private final Pattern regex;
  180. public FontFamilyRegExFontTripletMatcher(String regex) {
  181. this.regex = Pattern.compile(regex);
  182. }
  183. /** {@inheritDoc} */
  184. public boolean matches(FontTriplet triplet) {
  185. return regex.matcher(triplet.getName()).matches();
  186. }
  187. }
  188. }