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 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  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.IOException;
  20. import java.io.InputStream;
  21. import java.net.URL;
  22. import java.util.Map;
  23. import javax.xml.transform.Source;
  24. import javax.xml.transform.stream.StreamSource;
  25. import org.apache.commons.logging.Log;
  26. import org.apache.commons.logging.LogFactory;
  27. import org.apache.fop.apps.FOPException;
  28. import org.xml.sax.InputSource;
  29. /**
  30. * This class is used to defer the loading of a font until it is really used.
  31. */
  32. public class LazyFont extends Typeface implements FontDescriptor {
  33. private static Log log = LogFactory.getLog(LazyFont.class);
  34. private String metricsFileName = null;
  35. private String fontEmbedPath = null;
  36. private boolean useKerning = false;
  37. private boolean isMetricsLoaded = false;
  38. private Typeface realFont = null;
  39. private FontDescriptor realFontDescriptor = null;
  40. private FontResolver resolver = null;
  41. /**
  42. * Main constructor
  43. * @param fontEmbedPath path to embeddable file (may be null)
  44. * @param metricsFileName path to the metrics XML file
  45. * @param useKerning True, if kerning should be enabled
  46. * @param resolver the font resolver to handle font URIs
  47. */
  48. public LazyFont(EmbedFontInfo fontInfo, FontResolver resolver) {
  49. this.metricsFileName = fontInfo.getMetricsFile();
  50. this.fontEmbedPath = fontInfo.getEmbedFile();
  51. this.useKerning = fontInfo.getKerning();
  52. this.resolver = resolver;
  53. }
  54. /**
  55. * String representation of LazyFont
  56. */
  57. public String toString() {
  58. return ( "metrics-url=" + metricsFileName + ", embed-url=" + fontEmbedPath + ", kerning=" + useKerning );
  59. }
  60. private void load(boolean fail) {
  61. if (!isMetricsLoaded) {
  62. try {
  63. if (metricsFileName != null) {
  64. /**@todo Possible thread problem here */
  65. FontReader reader = null;
  66. if (resolver != null) {
  67. Source source = resolver.resolve(metricsFileName);
  68. if (source == null) {
  69. String err = "Cannot load font: failed to create Source from metrics file "
  70. + metricsFileName;
  71. if (fail) {
  72. throw new RuntimeException(err);
  73. } else {
  74. log.error(err);
  75. }
  76. return;
  77. }
  78. InputStream in = null;
  79. if (source instanceof StreamSource) {
  80. in = ((StreamSource) source).getInputStream();
  81. }
  82. if (in == null && source.getSystemId() != null) {
  83. in = new java.net.URL(source.getSystemId()).openStream();
  84. }
  85. if (in == null) {
  86. String err = "Cannot load font: failed to create InputStream from"
  87. + " Source for metrics file " + metricsFileName;
  88. if (fail) {
  89. throw new RuntimeException(err);
  90. } else {
  91. log.error(err);
  92. }
  93. return;
  94. }
  95. InputSource src = new InputSource(in);
  96. src.setSystemId(source.getSystemId());
  97. reader = new FontReader(src);
  98. } else {
  99. reader
  100. = new FontReader(new InputSource(new URL(metricsFileName).openStream()));
  101. }
  102. reader.setKerningEnabled(useKerning);
  103. reader.setFontEmbedPath(fontEmbedPath);
  104. reader.setResolver(resolver);
  105. realFont = reader.getFont();
  106. } else {
  107. if (fontEmbedPath == null) {
  108. throw new RuntimeException("Cannot load font. No font URIs available.");
  109. }
  110. realFont = FontLoader.loadFont(fontEmbedPath, resolver);
  111. }
  112. if (realFont instanceof FontDescriptor) {
  113. realFontDescriptor = (FontDescriptor) realFont;
  114. }
  115. } catch (FOPException fopex) {
  116. log.error("Failed to read font metrics file " + metricsFileName, fopex);
  117. if (fail) {
  118. throw new RuntimeException(fopex.getMessage());
  119. }
  120. } catch (IOException ioex) {
  121. log.error("Failed to read font metrics file " + metricsFileName, ioex);
  122. if (fail) {
  123. throw new RuntimeException(ioex.getMessage());
  124. }
  125. }
  126. isMetricsLoaded = true;
  127. }
  128. }
  129. /**
  130. * Gets the real font.
  131. * @return the real font
  132. */
  133. public Typeface getRealFont() {
  134. load(false);
  135. return realFont;
  136. }
  137. // ---- Font ----
  138. /**
  139. * @see org.apache.fop.fonts.Typeface#getEncoding()
  140. */
  141. public String getEncoding() {
  142. load(true);
  143. return realFont.getEncoding();
  144. }
  145. /**
  146. * @see org.apache.fop.fonts.Typeface#mapChar(char)
  147. */
  148. public char mapChar(char c) {
  149. load(true);
  150. return realFont.mapChar(c);
  151. }
  152. /**
  153. * @see org.apache.fop.fonts.Typeface#hasChar(char)
  154. */
  155. public boolean hasChar(char c) {
  156. load(true);
  157. return realFont.hasChar(c);
  158. }
  159. /**
  160. * @see org.apache.fop.fonts.Typeface#isMultiByte()
  161. */
  162. public boolean isMultiByte() {
  163. load(true);
  164. return realFont.isMultiByte();
  165. }
  166. // ---- FontMetrics interface ----
  167. /**
  168. * @see org.apache.fop.fonts.FontMetrics#getFontName()
  169. */
  170. public String getFontName() {
  171. load(true);
  172. return realFont.getFontName();
  173. }
  174. /**
  175. * @see org.apache.fop.fonts.FontMetrics#getMaxAscent(int)
  176. */
  177. public int getMaxAscent(int size) {
  178. load(true);
  179. return realFont.getMaxAscent(size);
  180. }
  181. /**
  182. * @see org.apache.fop.fonts.FontMetrics#getAscender(int)
  183. */
  184. public int getAscender(int size) {
  185. load(true);
  186. return realFont.getAscender(size);
  187. }
  188. /**
  189. * @see org.apache.fop.fonts.FontMetrics#getCapHeight(int)
  190. */
  191. public int getCapHeight(int size) {
  192. load(true);
  193. return realFont.getCapHeight(size);
  194. }
  195. /**
  196. * @see org.apache.fop.fonts.FontMetrics#getDescender(int)
  197. */
  198. public int getDescender(int size) {
  199. load(true);
  200. return realFont.getDescender(size);
  201. }
  202. /**
  203. * @see org.apache.fop.fonts.FontMetrics#getXHeight(int)
  204. */
  205. public int getXHeight(int size) {
  206. load(true);
  207. return realFont.getXHeight(size);
  208. }
  209. /**
  210. * @see org.apache.fop.fonts.FontMetrics#getWidth(int, int)
  211. */
  212. public int getWidth(int i, int size) {
  213. load(true);
  214. return realFont.getWidth(i, size);
  215. }
  216. /**
  217. * @see org.apache.fop.fonts.FontMetrics#getWidths()
  218. */
  219. public int[] getWidths() {
  220. load(true);
  221. return realFont.getWidths();
  222. }
  223. /**
  224. * @see org.apache.fop.fonts.FontMetrics#hasKerningInfo()
  225. */
  226. public boolean hasKerningInfo() {
  227. load(true);
  228. return realFont.hasKerningInfo();
  229. }
  230. /**
  231. * @see org.apache.fop.fonts.FontMetrics#getKerningInfo()
  232. */
  233. public Map getKerningInfo() {
  234. load(true);
  235. return realFont.getKerningInfo();
  236. }
  237. // ---- FontDescriptor interface ----
  238. /**
  239. * @see org.apache.fop.fonts.FontDescriptor#getCapHeight()
  240. */
  241. public int getCapHeight() {
  242. load(true);
  243. return realFontDescriptor.getCapHeight();
  244. }
  245. /**
  246. * @see org.apache.fop.fonts.FontDescriptor#getDescender()
  247. */
  248. public int getDescender() {
  249. load(true);
  250. return realFontDescriptor.getDescender();
  251. }
  252. /**
  253. * @see org.apache.fop.fonts.FontDescriptor#getAscender()
  254. */
  255. public int getAscender() {
  256. load(true);
  257. return realFontDescriptor.getAscender();
  258. }
  259. /**
  260. * @see org.apache.fop.fonts.FontDescriptor#getFlags()
  261. */
  262. public int getFlags() {
  263. load(true);
  264. return realFontDescriptor.getFlags();
  265. }
  266. /**
  267. * @see org.apache.fop.fonts.FontDescriptor#getFontBBox()
  268. */
  269. public int[] getFontBBox() {
  270. load(true);
  271. return realFontDescriptor.getFontBBox();
  272. }
  273. /**
  274. * @see org.apache.fop.fonts.FontDescriptor#getItalicAngle()
  275. */
  276. public int getItalicAngle() {
  277. load(true);
  278. return realFontDescriptor.getItalicAngle();
  279. }
  280. /**
  281. * @see org.apache.fop.fonts.FontDescriptor#getStemV()
  282. */
  283. public int getStemV() {
  284. load(true);
  285. return realFontDescriptor.getStemV();
  286. }
  287. /**
  288. * @see org.apache.fop.fonts.FontDescriptor#getFontType()
  289. */
  290. public FontType getFontType() {
  291. load(true);
  292. return realFontDescriptor.getFontType();
  293. }
  294. /**
  295. * @see org.apache.fop.fonts.FontDescriptor#isEmbeddable()
  296. */
  297. public boolean isEmbeddable() {
  298. load(true);
  299. return realFontDescriptor.isEmbeddable();
  300. }
  301. }