您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

CustomFont.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  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.util.Collections;
  21. import java.util.Map;
  22. import java.util.Set;
  23. import javax.xml.transform.Source;
  24. /**
  25. * Abstract base class for custom fonts loaded from files, for example.
  26. */
  27. public abstract class CustomFont extends Typeface
  28. implements FontDescriptor, MutableFont {
  29. private String fontName = null;
  30. private String fullName = null;
  31. private Set familyNames = null; //Set<String>
  32. private String fontSubName = null;
  33. private String embedFileName = null;
  34. private String embedResourceName = null;
  35. private FontResolver resolver = null;
  36. private int capHeight = 0;
  37. private int xHeight = 0;
  38. private int ascender = 0;
  39. private int descender = 0;
  40. private int[] fontBBox = {0, 0, 0, 0};
  41. private int flags = 4;
  42. private int weight = 0; //0 means unknown weight
  43. private int stemV = 0;
  44. private int italicAngle = 0;
  45. private int missingWidth = 0;
  46. private FontType fontType = FontType.TYPE1;
  47. private int firstChar = 0;
  48. private int lastChar = 255;
  49. private Map kerning;
  50. private boolean useKerning = true;
  51. /** {@inheritDoc} */
  52. public String getFontName() {
  53. return fontName;
  54. }
  55. /** {@inheritDoc} */
  56. public String getEmbedFontName() {
  57. return getFontName();
  58. }
  59. /** {@inheritDoc} */
  60. public String getFullName() {
  61. return fullName;
  62. }
  63. /**
  64. * Returns the font family names.
  65. * @return the font family names (a Set of Strings)
  66. */
  67. public Set getFamilyNames() {
  68. return Collections.unmodifiableSet(this.familyNames);
  69. }
  70. /**
  71. * Returns the font family name stripped of whitespace.
  72. * @return the stripped font family
  73. * @see FontUtil#stripWhiteSpace(String)
  74. */
  75. public String getStrippedFontName() {
  76. return FontUtil.stripWhiteSpace(getFontName());
  77. }
  78. /**
  79. * Returns font's subfamily name.
  80. * @return the font's subfamily name
  81. */
  82. public String getFontSubName() {
  83. return fontSubName;
  84. }
  85. /**
  86. * Returns an URI representing an embeddable font file. The URI will often
  87. * be a filename or an URL.
  88. * @return URI to an embeddable font file or null if not available.
  89. */
  90. public String getEmbedFileName() {
  91. return embedFileName;
  92. }
  93. /**
  94. * Returns a Source representing an embeddable font file.
  95. * @return Source for an embeddable font file
  96. * @throws IOException if embedFileName is not null but Source is not found
  97. */
  98. public Source getEmbedFileSource() throws IOException {
  99. Source result = null;
  100. if (resolver != null && embedFileName != null) {
  101. result = resolver.resolve(embedFileName);
  102. if (result == null) {
  103. throw new IOException("Unable to resolve Source '"
  104. + embedFileName + "' for embedded font");
  105. }
  106. }
  107. return result;
  108. }
  109. /**
  110. * Returns the lookup name to an embeddable font file available as a
  111. * resource.
  112. * (todo) Remove this method, this should be done using a resource: URI.
  113. * @return the lookup name
  114. */
  115. public String getEmbedResourceName() {
  116. return embedResourceName;
  117. }
  118. /**
  119. * {@inheritDoc}
  120. */
  121. public int getAscender() {
  122. return ascender;
  123. }
  124. /**
  125. * {@inheritDoc}
  126. */
  127. public int getDescender() {
  128. return descender;
  129. }
  130. /**
  131. * {@inheritDoc}
  132. */
  133. public int getCapHeight() {
  134. return capHeight;
  135. }
  136. /**
  137. * {@inheritDoc}
  138. */
  139. public int getAscender(int size) {
  140. return size * ascender;
  141. }
  142. /**
  143. * {@inheritDoc}
  144. */
  145. public int getDescender(int size) {
  146. return size * descender;
  147. }
  148. /**
  149. * {@inheritDoc}
  150. */
  151. public int getCapHeight(int size) {
  152. return size * capHeight;
  153. }
  154. /**
  155. * {@inheritDoc}
  156. */
  157. public int getXHeight(int size) {
  158. return size * xHeight;
  159. }
  160. /**
  161. * {@inheritDoc}
  162. */
  163. public int[] getFontBBox() {
  164. return fontBBox;
  165. }
  166. /** {@inheritDoc} */
  167. public int getFlags() {
  168. return flags;
  169. }
  170. /** {@inheritDoc} */
  171. public boolean isSymbolicFont() {
  172. return ((getFlags() & 4) != 0) || "ZapfDingbatsEncoding".equals(getEncodingName());
  173. //Note: The check for ZapfDingbats is necessary as the PFM does not reliably indicate
  174. //if a font is symbolic.
  175. }
  176. /**
  177. * Returns the font weight (100, 200...800, 900). This value may be different from the
  178. * one that was actually used to register the font.
  179. * @return the font weight (or 0 if the font weight is unknown)
  180. */
  181. public int getWeight() {
  182. return this.weight;
  183. }
  184. /**
  185. * {@inheritDoc}
  186. */
  187. public int getStemV() {
  188. return stemV;
  189. }
  190. /**
  191. * {@inheritDoc}
  192. */
  193. public int getItalicAngle() {
  194. return italicAngle;
  195. }
  196. /**
  197. * Returns the width to be used when no width is available.
  198. * @return a character width
  199. */
  200. public int getMissingWidth() {
  201. return missingWidth;
  202. }
  203. /**
  204. * {@inheritDoc}
  205. */
  206. public FontType getFontType() {
  207. return fontType;
  208. }
  209. /**
  210. * Returns the index of the first character defined in this font.
  211. * @return the index of the first character
  212. */
  213. public int getFirstChar() {
  214. return firstChar;
  215. }
  216. /**
  217. * Returns the index of the last character defined in this font.
  218. * @return the index of the last character
  219. */
  220. public int getLastChar() {
  221. return lastChar;
  222. }
  223. /**
  224. * Used to determine if kerning is enabled.
  225. * @return True if kerning is enabled.
  226. */
  227. public boolean isKerningEnabled() {
  228. return useKerning;
  229. }
  230. /**
  231. * {@inheritDoc}
  232. */
  233. public final boolean hasKerningInfo() {
  234. return (isKerningEnabled() && (kerning != null) && !kerning.isEmpty());
  235. }
  236. /**
  237. * {@inheritDoc}
  238. */
  239. public final Map getKerningInfo() {
  240. if (hasKerningInfo()) {
  241. return kerning;
  242. } else {
  243. return java.util.Collections.EMPTY_MAP;
  244. }
  245. }
  246. /* ---- MutableFont interface ---- */
  247. /** {@inheritDoc} */
  248. public void setFontName(String name) {
  249. this.fontName = name;
  250. }
  251. /** {@inheritDoc} */
  252. public void setFullName(String name) {
  253. this.fullName = name;
  254. }
  255. /** {@inheritDoc} */
  256. public void setFamilyNames(Set names) {
  257. this.familyNames = new java.util.HashSet(names);
  258. }
  259. /**
  260. * Sets the font's subfamily name.
  261. * @param subFamilyName the subfamily name of the font
  262. */
  263. public void setFontSubFamilyName(String subFamilyName) {
  264. this.fontSubName = subFamilyName;
  265. }
  266. /**
  267. * {@inheritDoc}
  268. */
  269. public void setEmbedFileName(String path) {
  270. this.embedFileName = path;
  271. }
  272. /**
  273. * {@inheritDoc}
  274. */
  275. public void setEmbedResourceName(String name) {
  276. this.embedResourceName = name;
  277. }
  278. /**
  279. * {@inheritDoc}
  280. */
  281. public void setCapHeight(int capHeight) {
  282. this.capHeight = capHeight;
  283. }
  284. /**
  285. * Returns the XHeight value of the font.
  286. * @param xHeight the XHeight value
  287. */
  288. public void setXHeight(int xHeight) {
  289. this.xHeight = xHeight;
  290. }
  291. /**
  292. * {@inheritDoc}
  293. */
  294. public void setAscender(int ascender) {
  295. this.ascender = ascender;
  296. }
  297. /**
  298. * {@inheritDoc}
  299. */
  300. public void setDescender(int descender) {
  301. this.descender = descender;
  302. }
  303. /**
  304. * {@inheritDoc}
  305. */
  306. public void setFontBBox(int[] bbox) {
  307. this.fontBBox = bbox;
  308. }
  309. /**
  310. * {@inheritDoc}
  311. */
  312. public void setFlags(int flags) {
  313. this.flags = flags;
  314. }
  315. /**
  316. * Sets the font weight. Valid values are 100, 200...800, 900.
  317. * @param weight the font weight
  318. */
  319. public void setWeight(int weight) {
  320. weight = (weight / 100) * 100;
  321. weight = Math.max(100, weight);
  322. weight = Math.min(900, weight);
  323. this.weight = weight;
  324. }
  325. /**
  326. * {@inheritDoc}
  327. */
  328. public void setStemV(int stemV) {
  329. this.stemV = stemV;
  330. }
  331. /**
  332. * {@inheritDoc}
  333. */
  334. public void setItalicAngle(int italicAngle) {
  335. this.italicAngle = italicAngle;
  336. }
  337. /**
  338. * {@inheritDoc}
  339. */
  340. public void setMissingWidth(int width) {
  341. this.missingWidth = width;
  342. }
  343. /**
  344. * {@inheritDoc}
  345. */
  346. public void setFontType(FontType fontType) {
  347. this.fontType = fontType;
  348. }
  349. /**
  350. * {@inheritDoc}
  351. */
  352. public void setFirstChar(int index) {
  353. this.firstChar = index;
  354. }
  355. /**
  356. * {@inheritDoc}
  357. */
  358. public void setLastChar(int index) {
  359. this.lastChar = index;
  360. }
  361. /**
  362. * {@inheritDoc}
  363. */
  364. public void setKerningEnabled(boolean enabled) {
  365. this.useKerning = enabled;
  366. }
  367. /**
  368. * Sets the font resolver. Needed for URI resolution.
  369. * @param resolver the font resolver
  370. */
  371. public void setResolver(FontResolver resolver) {
  372. this.resolver = resolver;
  373. }
  374. /** {@inheritDoc} */
  375. public void putKerningEntry(Integer key, Map value) {
  376. if (kerning == null) {
  377. kerning = new java.util.HashMap();
  378. }
  379. this.kerning.put(key, value);
  380. }
  381. /**
  382. * Replaces the existing kerning map with a new one.
  383. * @param kerningMap the kerning map (Map<Integer, Map<Integer, Integer>, the integers are
  384. * character codes)
  385. */
  386. public void replaceKerningMap(Map kerningMap) {
  387. if (kerningMap == null) {
  388. this.kerning = Collections.EMPTY_MAP;
  389. } else {
  390. this.kerning = kerningMap;
  391. }
  392. }
  393. }