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.

LazyFont.java 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /*
  2. * Copyright 1999-2006 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /* $Id$ */
  17. package org.apache.fop.fonts;
  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. import java.net.URL;
  21. import java.util.Map;
  22. import javax.xml.transform.Source;
  23. import javax.xml.transform.stream.StreamSource;
  24. import org.apache.commons.logging.Log;
  25. import org.apache.commons.logging.LogFactory;
  26. import org.apache.fop.apps.FOPException;
  27. import org.xml.sax.InputSource;
  28. /**
  29. * This class is used to defer the loading of a font until it is really used.
  30. */
  31. public class LazyFont extends Typeface implements FontDescriptor {
  32. private static Log log = LogFactory.getLog(LazyFont.class);
  33. private String metricsFileName = null;
  34. private String fontEmbedPath = null;
  35. private boolean useKerning = false;
  36. private boolean isMetricsLoaded = false;
  37. private Typeface realFont = null;
  38. private FontDescriptor realFontDescriptor = null;
  39. private FontResolver resolver = null;
  40. /**
  41. * Main constructor
  42. * @param fontEmbedPath path to embeddable file (may be null)
  43. * @param metricsFileName path to the metrics XML file
  44. * @param useKerning True, if kerning should be enabled
  45. * @param resolver the font resolver to handle font URIs
  46. */
  47. public LazyFont(String fontEmbedPath, String metricsFileName
  48. , boolean useKerning, FontResolver resolver) {
  49. this.metricsFileName = metricsFileName;
  50. this.fontEmbedPath = fontEmbedPath;
  51. this.useKerning = useKerning;
  52. this.resolver = resolver;
  53. }
  54. private void load(boolean fail) {
  55. if (!isMetricsLoaded) {
  56. try {
  57. /**@todo Possible thread problem here */
  58. FontReader reader = null;
  59. if (resolver != null) {
  60. Source source = resolver.resolve(metricsFileName);
  61. if (source == null) {
  62. String err = "Cannot load font: failed to create Source from metrics file "
  63. + metricsFileName;
  64. if (fail) {
  65. throw new RuntimeException(err);
  66. } else {
  67. log.error(err);
  68. }
  69. return;
  70. }
  71. InputStream in = null;
  72. if (source instanceof StreamSource) {
  73. in = ((StreamSource) source).getInputStream();
  74. }
  75. if (in == null && source.getSystemId() != null) {
  76. in = new java.net.URL(source.getSystemId()).openStream();
  77. }
  78. if (in == null) {
  79. String err = "Cannot load font: failed to create InputStream from"
  80. + " Source for metrics file " + metricsFileName;
  81. if (fail) {
  82. throw new RuntimeException(err);
  83. } else {
  84. log.error(err);
  85. }
  86. return;
  87. }
  88. InputSource src = new InputSource(in);
  89. src.setSystemId(source.getSystemId());
  90. reader = new FontReader(src);
  91. } else {
  92. reader
  93. = new FontReader(new InputSource(new URL(metricsFileName).openStream()));
  94. }
  95. reader.setKerningEnabled(useKerning);
  96. reader.setFontEmbedPath(fontEmbedPath);
  97. reader.setResolver(resolver);
  98. realFont = reader.getFont();
  99. if (realFont instanceof FontDescriptor) {
  100. realFontDescriptor = (FontDescriptor) realFont;
  101. }
  102. // log.debug("Metrics " + metricsFileName + " loaded.");
  103. } catch (FOPException fopex) {
  104. log.error("Failed to read font metrics file " + metricsFileName, fopex);
  105. if (fail) {
  106. throw new RuntimeException(fopex.getMessage());
  107. }
  108. } catch (IOException ioex) {
  109. log.error("Failed to read font metrics file " + metricsFileName, ioex);
  110. if (fail) {
  111. throw new RuntimeException(ioex.getMessage());
  112. }
  113. }
  114. isMetricsLoaded = true;
  115. }
  116. }
  117. /**
  118. * Gets the real font.
  119. * @return the real font
  120. */
  121. public Typeface getRealFont() {
  122. load(false);
  123. return realFont;
  124. }
  125. // ---- Font ----
  126. /**
  127. * @see org.apache.fop.fonts.Typeface#getEncoding()
  128. */
  129. public String getEncoding() {
  130. load(true);
  131. return realFont.getEncoding();
  132. }
  133. /**
  134. * @see org.apache.fop.fonts.Typeface#mapChar(char)
  135. */
  136. public char mapChar(char c) {
  137. load(true);
  138. return realFont.mapChar(c);
  139. }
  140. /**
  141. * @see org.apache.fop.fonts.Typeface#hasChar(char)
  142. */
  143. public boolean hasChar(char c) {
  144. load(true);
  145. return realFont.hasChar(c);
  146. }
  147. /**
  148. * @see org.apache.fop.fonts.Typeface#isMultiByte()
  149. */
  150. public boolean isMultiByte() {
  151. load(true);
  152. return realFont.isMultiByte();
  153. }
  154. // ---- FontMetrics interface ----
  155. /**
  156. * @see org.apache.fop.fonts.FontMetrics#getFontName()
  157. */
  158. public String getFontName() {
  159. load(true);
  160. return realFont.getFontName();
  161. }
  162. /**
  163. * @see org.apache.fop.fonts.FontMetrics#getAscender(int)
  164. */
  165. public int getAscender(int size) {
  166. load(true);
  167. return realFont.getAscender(size);
  168. }
  169. /**
  170. * @see org.apache.fop.fonts.FontMetrics#getCapHeight(int)
  171. */
  172. public int getCapHeight(int size) {
  173. load(true);
  174. return realFont.getCapHeight(size);
  175. }
  176. /**
  177. * @see org.apache.fop.fonts.FontMetrics#getDescender(int)
  178. */
  179. public int getDescender(int size) {
  180. load(true);
  181. return realFont.getDescender(size);
  182. }
  183. /**
  184. * @see org.apache.fop.fonts.FontMetrics#getXHeight(int)
  185. */
  186. public int getXHeight(int size) {
  187. load(true);
  188. return realFont.getXHeight(size);
  189. }
  190. /**
  191. * @see org.apache.fop.fonts.FontMetrics#getWidth(int, int)
  192. */
  193. public int getWidth(int i, int size) {
  194. load(true);
  195. return realFont.getWidth(i, size);
  196. }
  197. /**
  198. * @see org.apache.fop.fonts.FontMetrics#getWidths()
  199. */
  200. public int[] getWidths() {
  201. load(true);
  202. return realFont.getWidths();
  203. }
  204. /**
  205. * @see org.apache.fop.fonts.FontMetrics#hasKerningInfo()
  206. */
  207. public boolean hasKerningInfo() {
  208. load(true);
  209. return realFont.hasKerningInfo();
  210. }
  211. /**
  212. * @see org.apache.fop.fonts.FontMetrics#getKerningInfo()
  213. */
  214. public Map getKerningInfo() {
  215. load(true);
  216. return realFont.getKerningInfo();
  217. }
  218. // ---- FontDescriptor interface ----
  219. /**
  220. * @see org.apache.fop.fonts.FontDescriptor#getCapHeight()
  221. */
  222. public int getCapHeight() {
  223. load(true);
  224. return realFontDescriptor.getCapHeight();
  225. }
  226. /**
  227. * @see org.apache.fop.fonts.FontDescriptor#getDescender()
  228. */
  229. public int getDescender() {
  230. load(true);
  231. return realFontDescriptor.getDescender();
  232. }
  233. /**
  234. * @see org.apache.fop.fonts.FontDescriptor#getAscender()
  235. */
  236. public int getAscender() {
  237. load(true);
  238. return realFontDescriptor.getAscender();
  239. }
  240. /**
  241. * @see org.apache.fop.fonts.FontDescriptor#getFlags()
  242. */
  243. public int getFlags() {
  244. load(true);
  245. return realFontDescriptor.getFlags();
  246. }
  247. /**
  248. * @see org.apache.fop.fonts.FontDescriptor#getFontBBox()
  249. */
  250. public int[] getFontBBox() {
  251. load(true);
  252. return realFontDescriptor.getFontBBox();
  253. }
  254. /**
  255. * @see org.apache.fop.fonts.FontDescriptor#getItalicAngle()
  256. */
  257. public int getItalicAngle() {
  258. load(true);
  259. return realFontDescriptor.getItalicAngle();
  260. }
  261. /**
  262. * @see org.apache.fop.fonts.FontDescriptor#getStemV()
  263. */
  264. public int getStemV() {
  265. load(true);
  266. return realFontDescriptor.getStemV();
  267. }
  268. /**
  269. * @see org.apache.fop.fonts.FontDescriptor#getFontType()
  270. */
  271. public FontType getFontType() {
  272. load(true);
  273. return realFontDescriptor.getFontType();
  274. }
  275. /**
  276. * @see org.apache.fop.fonts.FontDescriptor#isEmbeddable()
  277. */
  278. public boolean isEmbeddable() {
  279. load(true);
  280. return realFontDescriptor.isEmbeddable();
  281. }
  282. }