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.

CustomFont.java 11KB

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