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.

FontManager.java 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  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.io.File;
  20. import java.net.MalformedURLException;
  21. import java.util.Iterator;
  22. import java.util.List;
  23. import javax.xml.transform.Source;
  24. import javax.xml.transform.stream.StreamSource;
  25. import org.apache.fop.apps.FOPException;
  26. import org.apache.fop.fonts.FontTriplet.Matcher;
  27. import org.apache.fop.fonts.substitute.FontSubstitutions;
  28. // TODO: Refactor fonts package so major font activities (autodetection etc)
  29. // are all centrally managed and delegated from this class
  30. /**
  31. * The manager of fonts. The class holds a reference to the font cache and information about
  32. * font substitution, referenced fonts and similar.
  33. */
  34. public class FontManager {
  35. /** Use cache (record previously detected font triplet info) */
  36. public static final boolean DEFAULT_USE_CACHE = true;
  37. /** The base URL for all font URL resolutions. */
  38. private String fontBase = null;
  39. /** Font cache to speed up auto-font configuration (null if disabled) */
  40. private FontCache fontCache = null;
  41. /** Font substitutions */
  42. private FontSubstitutions fontSubstitutions = null;
  43. /** Allows enabling kerning on the base 14 fonts, default is false */
  44. private boolean enableBase14Kerning = false;
  45. /** FontTriplet matcher for fonts that shall be referenced rather than embedded. */
  46. private FontTriplet.Matcher referencedFontsMatcher;
  47. /** Enables/disables the use of font caching */
  48. private boolean useCache = DEFAULT_USE_CACHE;
  49. /** Provides a font cache file path **/
  50. private File cacheFile;
  51. /**
  52. * Main constructor
  53. */
  54. public FontManager() {
  55. }
  56. /**
  57. * Sets the font base URL.
  58. * @param fontBase font base URL
  59. * @throws MalformedURLException if there's a problem with a URL
  60. */
  61. public void setFontBaseURL(String fontBase) throws MalformedURLException {
  62. this.fontBase = fontBase;
  63. }
  64. /**
  65. * Returns the font base URL.
  66. * @return the font base URL (or null if none was set)
  67. */
  68. public String getFontBaseURL() {
  69. return this.fontBase;
  70. }
  71. /** @return true if kerning on base 14 fonts is enabled */
  72. public boolean isBase14KerningEnabled() {
  73. return this.enableBase14Kerning;
  74. }
  75. /**
  76. * Controls whether kerning is activated on base 14 fonts.
  77. * @param value true if kerning should be activated
  78. */
  79. public void setBase14KerningEnabled(boolean value) {
  80. this.enableBase14Kerning = value;
  81. }
  82. /**
  83. * Sets the font substitutions
  84. * @param substitutions font substitutions
  85. */
  86. public void setFontSubstitutions(FontSubstitutions substitutions) {
  87. this.fontSubstitutions = substitutions;
  88. }
  89. /**
  90. * Returns the font substitution catalog
  91. * @return the font substitution catalog
  92. */
  93. protected FontSubstitutions getFontSubstitutions() {
  94. if (fontSubstitutions == null) {
  95. this.fontSubstitutions = new FontSubstitutions();
  96. }
  97. return fontSubstitutions;
  98. }
  99. /**
  100. * Sets the font cache file
  101. * @param cacheFile the font cache file
  102. */
  103. public void setCacheFile(File cacheFile) {
  104. this.cacheFile = cacheFile;
  105. }
  106. /**
  107. * Returns the font cache file
  108. * @return the font cache file
  109. */
  110. public File getCacheFile() {
  111. if (cacheFile != null) {
  112. return this.cacheFile;
  113. }
  114. return FontCache.getDefaultCacheFile(false);
  115. }
  116. /**
  117. * Whether or not to cache results of font triplet detection/auto-config
  118. * @param useCache use cache or not
  119. */
  120. public void setUseCache(boolean useCache) {
  121. this.useCache = useCache;
  122. if (!useCache) {
  123. this.fontCache = null;
  124. }
  125. }
  126. /**
  127. * Cache results of font triplet detection/auto-config?
  128. * @return true if this font manager uses the cache
  129. */
  130. public boolean useCache() {
  131. return useCache;
  132. }
  133. /**
  134. * Returns the font cache instance used by this font manager.
  135. * @return the font cache
  136. */
  137. public FontCache getFontCache() {
  138. if (fontCache == null) {
  139. if (useCache) {
  140. if (cacheFile != null) {
  141. fontCache = FontCache.loadFrom(cacheFile);
  142. } else {
  143. fontCache = FontCache.load();
  144. }
  145. if (fontCache == null) {
  146. fontCache = new FontCache();
  147. }
  148. }
  149. }
  150. return fontCache;
  151. }
  152. /**
  153. * Saves the FontCache as necessary
  154. *
  155. * @throws FOPException fop exception
  156. */
  157. public void saveCache() throws FOPException {
  158. if (useCache) {
  159. if (fontCache != null && fontCache.hasChanged()) {
  160. if (cacheFile != null) {
  161. fontCache.saveTo(cacheFile);
  162. } else {
  163. fontCache.save();
  164. }
  165. }
  166. }
  167. }
  168. /**
  169. * Deletes the current FontCache file
  170. * @return Returns true if the font cache file was successfully deleted.
  171. */
  172. public boolean deleteCache() {
  173. boolean deleted = false;
  174. if (useCache) {
  175. if (cacheFile != null) {
  176. deleted = cacheFile.delete();
  177. } else {
  178. deleted = FontCache.getDefaultCacheFile(true).delete();
  179. }
  180. }
  181. return deleted;
  182. }
  183. /**
  184. * Sets up the fonts on a given FontInfo object. The fonts to setup are defined by an
  185. * array of {@link FontCollection} objects.
  186. * @param fontInfo the FontInfo object to set up
  187. * @param fontCollections the array of font collections/sources
  188. */
  189. public void setup(FontInfo fontInfo, FontCollection[] fontCollections) {
  190. int startNum = 1;
  191. for (int i = 0, c = fontCollections.length; i < c; i++) {
  192. startNum = fontCollections[i].setup(startNum, fontInfo);
  193. }
  194. // Make any defined substitutions in the font info
  195. getFontSubstitutions().adjustFontInfo(fontInfo);
  196. }
  197. /** @return a new FontResolver to be used by the font subsystem */
  198. public static FontResolver createMinimalFontResolver() {
  199. return new FontResolver() {
  200. /** {@inheritDoc} */
  201. public Source resolve(String href) {
  202. //Minimal functionality here
  203. return new StreamSource(href);
  204. }
  205. };
  206. }
  207. /**
  208. * Sets the {@link FontTriplet.Matcher} that can be used to identify the fonts that shall
  209. * be referenced rather than embedded.
  210. * @param matcher the font triplet matcher
  211. */
  212. public void setReferencedFontsMatcher(FontTriplet.Matcher matcher) {
  213. this.referencedFontsMatcher = matcher;
  214. }
  215. /**
  216. * Gets the {@link FontTriplet.Matcher} that can be used to identify the fonts that shall
  217. * be referenced rather than embedded.
  218. * @return the font triplet matcher (or null if none is set)
  219. */
  220. public Matcher getReferencedFontsMatcher() {
  221. return this.referencedFontsMatcher;
  222. }
  223. /**
  224. * Updates the referenced font list using the FontManager's referenced fonts matcher
  225. * ({@link #getReferencedFontsMatcher()}).
  226. * @param fontInfoList a font info list
  227. */
  228. public void updateReferencedFonts(List fontInfoList) {
  229. Matcher matcher = getReferencedFontsMatcher();
  230. updateReferencedFonts(fontInfoList, matcher);
  231. }
  232. /**
  233. * Updates the referenced font list.
  234. * @param fontInfoList a font info list
  235. * @param matcher the font triplet matcher to use
  236. */
  237. public void updateReferencedFonts(List fontInfoList, Matcher matcher) {
  238. if (matcher == null) {
  239. return; //No referenced fonts
  240. }
  241. Iterator iter = fontInfoList.iterator();
  242. while (iter.hasNext()) {
  243. EmbedFontInfo fontInfo = (EmbedFontInfo)iter.next();
  244. Iterator triplets = fontInfo.getFontTriplets().iterator();
  245. while (triplets.hasNext()) {
  246. FontTriplet triplet = (FontTriplet)triplets.next();
  247. if (matcher.matches(triplet)) {
  248. fontInfo.setEmbedded(false);
  249. break;
  250. }
  251. }
  252. }
  253. }
  254. }