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.

FontInfoFinder.java 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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.autodetect;
  19. import java.io.File;
  20. import java.net.MalformedURLException;
  21. import java.util.List;
  22. import org.apache.commons.logging.Log;
  23. import org.apache.commons.logging.LogFactory;
  24. import org.apache.fop.fonts.CachedFontInfo;
  25. import org.apache.fop.fonts.CustomFont;
  26. import org.apache.fop.fonts.EmbedFontInfo;
  27. import org.apache.fop.fonts.Font;
  28. import org.apache.fop.fonts.FontCache;
  29. import org.apache.fop.fonts.FontLoader;
  30. import org.apache.fop.fonts.FontResolver;
  31. import org.apache.fop.fonts.FontTriplet;
  32. /**
  33. * Attempts to determine correct FontInfo
  34. */
  35. public class FontInfoFinder {
  36. /** logging instance */
  37. private Log log = LogFactory.getLog(FontInfoFinder.class);
  38. /** font constituent names which identify a font as being of "italic" style */
  39. private static final String[] ITALIC_WORDS = {"italic", "oblique"};
  40. /** font constituent names which identify a font as being of "bold" weight */
  41. private static final String[] BOLD_WORDS = {"bold", "black", "heavy", "ultra", "super"};
  42. /**
  43. * Attempts to determine FontTriplet from a given CustomFont.
  44. * It seems to be fairly accurate but will probably require some tweaking over time
  45. *
  46. * @param customFont CustomFont
  47. * @return newly created font triplet
  48. */
  49. private FontTriplet tripletFromFont(CustomFont customFont) {
  50. // default style and weight triplet vales (fallback)
  51. String name = customFont.getStrippedFontName();
  52. String subName = customFont.getFontSubName();
  53. String searchName = name.toLowerCase();
  54. if (subName != null) {
  55. searchName += subName.toLowerCase();
  56. }
  57. // style
  58. String style = Font.STYLE_NORMAL;
  59. if (customFont.getItalicAngle() > 0) {
  60. style = Font.STYLE_ITALIC;
  61. } else {
  62. for (int i = 0; i < ITALIC_WORDS.length; i++) {
  63. if (searchName.indexOf(ITALIC_WORDS[i]) != -1) {
  64. style = Font.STYLE_ITALIC;
  65. break;
  66. }
  67. }
  68. }
  69. // weight
  70. int weight = Font.WEIGHT_NORMAL;
  71. for (int i = 0; i < BOLD_WORDS.length; i++) {
  72. if (searchName.indexOf(BOLD_WORDS[i]) != -1) {
  73. weight = Font.WEIGHT_BOLD;
  74. break;
  75. }
  76. }
  77. return new FontTriplet(name, style, weight);
  78. }
  79. /**
  80. * Attempts to determine FontInfo from a given custom font
  81. * @param fontFile the font file
  82. * @param customFont the custom font
  83. * @param fontCache font cache (may be null)
  84. * @return
  85. */
  86. private EmbedFontInfo fontInfoFromCustomFont(
  87. File fontFile, CustomFont customFont, FontCache fontCache) {
  88. FontTriplet fontTriplet = tripletFromFont(customFont);
  89. List fontTripletList = new java.util.ArrayList();
  90. fontTripletList.add(fontTriplet);
  91. String embedUrl;
  92. try {
  93. embedUrl = fontFile.toURL().toExternalForm();
  94. } catch (MalformedURLException e) {
  95. embedUrl = fontFile.getAbsolutePath();
  96. }
  97. EmbedFontInfo fontInfo = new EmbedFontInfo(null, customFont.isKerningEnabled(),
  98. fontTripletList, embedUrl);
  99. if (fontCache != null) {
  100. fontCache.addFont(fontInfo);
  101. }
  102. return fontInfo;
  103. }
  104. /**
  105. * Attempts to determine EmbedFontInfo from a given font file.
  106. *
  107. * @param fontFile font file
  108. * @param resolver font resolver used to resolve font
  109. * @param fontCache font cache (may be null)
  110. * @return newly created embed font info
  111. */
  112. public EmbedFontInfo find(File fontFile, FontResolver resolver, FontCache fontCache) {
  113. String embedUrl = null;
  114. try {
  115. embedUrl = fontFile.toURL().toExternalForm();
  116. } catch (MalformedURLException mfue) {
  117. // should never happen
  118. log.error("Failed to convert '" + fontFile + "' to URL: " + mfue.getMessage() );
  119. }
  120. long fileLastModified = -1;
  121. if (fontCache != null) {
  122. fileLastModified = fontFile.lastModified();
  123. // firstly try and fetch it from cache before loading/parsing the font file
  124. if (fontCache.containsFont(embedUrl)) {
  125. CachedFontInfo fontInfo = fontCache.getFont(embedUrl);
  126. if (fontInfo.lastModified() == fileLastModified) {
  127. return fontInfo;
  128. } else {
  129. // out of date cache item
  130. fontCache.removeFont(embedUrl);
  131. }
  132. // is this a previously failed parsed font?
  133. } else if (fontCache.isFailedFont(embedUrl, fileLastModified)) {
  134. if (log.isDebugEnabled()) {
  135. log.debug("Skipping font file that failed to load previously: " + embedUrl);
  136. }
  137. return null;
  138. }
  139. }
  140. // try to determine triplet information from font file
  141. CustomFont customFont = null;
  142. try {
  143. customFont = FontLoader.loadFont(fontFile, resolver);
  144. } catch (Exception e) {
  145. //TODO Too verbose (it's an error but we don't care if some fonts can't be loaded)
  146. if (log.isErrorEnabled()) {
  147. log.error("Unable to load font file: " + embedUrl + ". Reason: " + e.getMessage());
  148. }
  149. if (fontCache != null) {
  150. fontCache.registerFailedFont(embedUrl, fileLastModified);
  151. }
  152. return null;
  153. }
  154. return fontInfoFromCustomFont(fontFile, customFont, fontCache);
  155. }
  156. }