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.

FontInfo.java 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  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.util.Collection;
  20. import java.util.Collections;
  21. import java.util.Iterator;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.Set;
  25. import org.apache.commons.logging.Log;
  26. import org.apache.commons.logging.LogFactory;
  27. /**
  28. * The FontInfo holds font information for the layout and rendering of a fo document.
  29. * This stores the list of available fonts that are setup by
  30. * the renderer. The font name can be retrieved for the
  31. * family style and weight.
  32. * <br>
  33. * Currently font supported font-variant small-caps is not
  34. * implemented.
  35. */
  36. public class FontInfo {
  37. /** logging instance */
  38. protected static Log log = LogFactory.getLog(FontInfo.class);
  39. /** Map containing fonts that have been used */
  40. private Map/*<String,FontMetrics>*/ usedFonts = null; //(String = font key)
  41. /** look up a font-triplet to find a font-name */
  42. private Map/*<FontTriplet,String>*/ triplets = null; //(String = font key)
  43. /** look up a font-triplet to find its priority
  44. * (only used inside addFontProperties()) */
  45. private Map/*<FontTriplet,Integer>*/ tripletPriorities = null; //Map<FontTriplet,Integer>
  46. /** look up a font-name to get a font (that implements FontMetrics at least) */
  47. private Map/*<String,FontMetrics>*/ fonts = null; //(String = font key)
  48. /**
  49. * a collection of missing fonts; used to make sure the user gets
  50. * a warning for a missing font only once (not every time the font is used)
  51. */
  52. private Set/*<FontTriplet>*/ loggedFontKeys = null;
  53. /** Cache for Font instances. */
  54. private Map/*<FontTriplet, Map>*/ fontInstanceCache = null;
  55. /** Event listener for font events */
  56. private FontEventListener eventListener = null;
  57. /**
  58. * Main constructor
  59. */
  60. public FontInfo() {
  61. this.triplets = new java.util.HashMap/*<FontTriplet, String>*/();
  62. this.tripletPriorities = new java.util.HashMap/*<FontTriplet, Integer>*/();
  63. this.fonts = new java.util.HashMap/*<String, FontMetrics>*/();
  64. this.usedFonts = new java.util.HashMap/*<String,FontMetrics>*/();
  65. }
  66. /**
  67. * Sets the font event listener that can be used to receive events about particular events
  68. * in this class.
  69. * @param listener the font event listener
  70. */
  71. public void setEventListener(FontEventListener listener) {
  72. this.eventListener = listener;
  73. }
  74. /**
  75. * Checks if the font setup is valid (At least the ultimate fallback font
  76. * must be registered.)
  77. * @return True if valid
  78. */
  79. public boolean isSetupValid() {
  80. //We're only called when font setup is done:
  81. tripletPriorities = null; // candidate for garbage collection
  82. return triplets.containsKey(Font.DEFAULT_FONT);
  83. }
  84. /**
  85. * Adds a new font triplet.
  86. * @param name internal key
  87. * @param family font family name
  88. * @param style font style (normal, italic, oblique...)
  89. * @param weight font weight
  90. */
  91. public void addFontProperties(String name, String family, String style, int weight) {
  92. addFontProperties(name, createFontKey(family, style, weight));
  93. }
  94. /**
  95. * Adds a series of new font triplets given an array of font family names.
  96. * @param name internal key
  97. * @param families an array of font family names
  98. * @param style font style (normal, italic, oblique...)
  99. * @param weight font weight
  100. */
  101. public void addFontProperties(String name, String[] families, String style, int weight) {
  102. for (int i = 0; i < families.length; i++) {
  103. addFontProperties(name, families[i], style, weight);
  104. }
  105. }
  106. /**
  107. * Adds a new font triplet.
  108. * @param internalFontKey internal font key
  109. * @param triplet the font triplet to associate with the internal key
  110. */
  111. public void addFontProperties(String internalFontKey, FontTriplet triplet) {
  112. /*
  113. * add the given family, style and weight as a lookup for the font
  114. * with the given name
  115. */
  116. if (log.isDebugEnabled()) {
  117. log.debug("Registering: " + triplet + " under " + internalFontKey);
  118. }
  119. String oldName = (String)triplets.get(triplet);
  120. int newPriority = triplet.getPriority();
  121. if (oldName != null) {
  122. int oldPriority = ((Integer)tripletPriorities.get(triplet)).intValue();
  123. if (oldPriority < newPriority) {
  124. logDuplicateFont(triplet, false, oldName, oldPriority,
  125. internalFontKey, newPriority);
  126. return;
  127. } else {
  128. logDuplicateFont(triplet, true, oldName, oldPriority,
  129. internalFontKey, newPriority);
  130. }
  131. }
  132. this.triplets.put(triplet, internalFontKey);
  133. this.tripletPriorities.put(triplet, new Integer(newPriority));
  134. }
  135. /**
  136. * Log warning about duplicate font triplets.
  137. *
  138. * @param triplet the duplicate font triplet
  139. * @param replacing true iff the new font will replace the old one
  140. * @param oldKey the old internal font name
  141. * @param oldPriority the priority of the existing font mapping
  142. * @param newKey the new internal font name
  143. * @param newPriority the priority of the duplicate font mapping
  144. */
  145. private void logDuplicateFont(FontTriplet triplet, boolean replacing,
  146. String oldKey, int oldPriority,
  147. String newKey, int newPriority) {
  148. if (log.isDebugEnabled()) {
  149. log.debug(triplet
  150. + (replacing ? ": Replacing " : ": Not replacing ")
  151. + ((FontMetrics)fonts.get(triplets.get(triplet))).getFullName()
  152. + " (priority=" + oldPriority + ") by "
  153. + ((FontMetrics)fonts.get(newKey)).getFullName()
  154. + " (priority=" + newPriority + ")");
  155. }
  156. }
  157. /**
  158. * Adds font metrics for a specific font.
  159. * @param internalFontKey internal key
  160. * @param metrics metrics to register
  161. */
  162. public void addMetrics(String internalFontKey, FontMetrics metrics) {
  163. // add the given metrics as a font with the given name
  164. if (metrics instanceof Typeface) {
  165. ((Typeface)metrics).setEventListener(this.eventListener);
  166. }
  167. this.fonts.put(internalFontKey, metrics);
  168. }
  169. /**
  170. * Lookup a font.
  171. * <br>
  172. * Locate the font name for a given family, style and weight.
  173. * The font name can then be used as a key as it is unique for
  174. * the associated document.
  175. * This also adds the font to the list of used fonts.
  176. * @param family font family
  177. * @param style font style
  178. * @param weight font weight
  179. * @param substitutable true if the font may be substituted with the
  180. * default font if not found
  181. * @return internal font triplet key
  182. */
  183. private FontTriplet fontLookup(String family, String style,
  184. int weight, boolean substitutable) {
  185. if (log.isTraceEnabled()) {
  186. log.trace("Font lookup: " + family + " " + style + " " + weight
  187. + (substitutable ? " substitutable" : ""));
  188. }
  189. FontTriplet startKey = createFontKey(family, style, weight);
  190. FontTriplet fontTriplet = startKey;
  191. // first try given parameters
  192. String internalFontKey = getInternalFontKey(fontTriplet);
  193. if (internalFontKey == null) {
  194. fontTriplet = fuzzyFontLookup(family, style, weight, startKey, substitutable);
  195. }
  196. if (fontTriplet != null) {
  197. if (fontTriplet != startKey) {
  198. notifyFontReplacement(startKey, fontTriplet);
  199. }
  200. return fontTriplet;
  201. } else {
  202. return null;
  203. }
  204. }
  205. private FontTriplet fuzzyFontLookup(String family, String style,
  206. int weight, FontTriplet startKey, boolean substitutable) {
  207. FontTriplet key;
  208. String internalFontKey = null;
  209. if (!family.equals(startKey.getName())) {
  210. key = createFontKey(family, style, weight);
  211. internalFontKey = getInternalFontKey(key);
  212. if (internalFontKey != null) {
  213. return key;
  214. }
  215. }
  216. // adjust weight, favouring normal or bold
  217. key = findAdjustWeight(family, style, weight);
  218. if (key != null) {
  219. internalFontKey = getInternalFontKey(key);
  220. }
  221. // return null if not found and not substitutable
  222. if (!substitutable && internalFontKey == null) {
  223. return null;
  224. }
  225. // only if the font may be substituted
  226. // fallback 1: try the same font-family and weight with default style
  227. if (internalFontKey == null && style != Font.STYLE_NORMAL) {
  228. key = createFontKey(family, Font.STYLE_NORMAL, weight);
  229. internalFontKey = getInternalFontKey(key);
  230. }
  231. if (internalFontKey == null && weight != Font.WEIGHT_NORMAL) {
  232. int diffWeight = (Font.WEIGHT_NORMAL - weight) / 100;
  233. int direction = diffWeight > 0 ? 1 : -1;
  234. int tryWeight = weight;
  235. while (tryWeight != Font.WEIGHT_NORMAL) {
  236. tryWeight += 100 * direction;
  237. key = createFontKey(family, style, weight);
  238. internalFontKey = getInternalFontKey(key);
  239. if (internalFontKey == null) {
  240. key = createFontKey(family, Font.STYLE_NORMAL, weight);
  241. internalFontKey = getInternalFontKey(key);
  242. }
  243. if (internalFontKey != null) {
  244. break;
  245. }
  246. }
  247. }
  248. // fallback 2: try the same font-family with default style and weight
  249. /* obsolete: replaced by the loop above
  250. if (internalFontKey == null) {
  251. key = createFontKey(family, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
  252. internalFontKey = getInternalFontKey(key);
  253. }*/
  254. // fallback 3: try any family with original style/weight
  255. if (internalFontKey == null) {
  256. return fuzzyFontLookup("any", style, weight, startKey, false);
  257. }
  258. // last resort: use default
  259. if (key == null && internalFontKey == null) {
  260. key = Font.DEFAULT_FONT;
  261. internalFontKey = getInternalFontKey(key);
  262. }
  263. if (internalFontKey != null) {
  264. return key;
  265. } else {
  266. return null;
  267. }
  268. }
  269. /**
  270. * Tells this class that the font with the given internal name has been used.
  271. * @param internalName the internal font name (F1, F2 etc.)
  272. */
  273. public void useFont(String internalName) {
  274. usedFonts.put(internalName, fonts.get(internalName));
  275. }
  276. private Map/*<FontTriplet,Map<Integer,Font>>*/ getFontInstanceCache() {
  277. if (fontInstanceCache == null) {
  278. fontInstanceCache = new java.util.HashMap/*<FontTriplet, Map<Integer,Font>>*/();
  279. }
  280. return fontInstanceCache;
  281. }
  282. /**
  283. * Retrieves a (possibly cached) Font instance based on a FontTriplet and a font size.
  284. *
  285. * @param triplet the font triplet designating the requested font
  286. * @param fontSize the font size
  287. * @return the requested Font instance
  288. */
  289. public Font getFontInstance(FontTriplet triplet, int fontSize) {
  290. Map/*<Integer,Font>*/ sizes
  291. = (Map/*<Integer,Font>*/)getFontInstanceCache().get(triplet);
  292. if (sizes == null) {
  293. sizes = new java.util.HashMap/*<Integer,Font>*/();
  294. getFontInstanceCache().put(triplet, sizes);
  295. }
  296. Integer size = new Integer(fontSize);
  297. Font font = (Font)sizes.get(size);
  298. if (font == null) {
  299. String fontKey = getInternalFontKey(triplet);
  300. useFont(fontKey);
  301. FontMetrics metrics = getMetricsFor(fontKey);
  302. font = new Font(fontKey, triplet, metrics, fontSize);
  303. sizes.put(size, font);
  304. }
  305. return font;
  306. }
  307. private List/*<FontTriplet>*/ getTripletsForName(String fontName) {
  308. List/*<FontTriplet>*/ matchedTriplets = new java.util.ArrayList/*<FontTriplet>*/();
  309. Iterator it = triplets.keySet().iterator();
  310. while (it.hasNext()) {
  311. FontTriplet triplet = (FontTriplet)it.next();
  312. String tripletName = triplet.getName();
  313. if (tripletName.toLowerCase().equals(fontName.toLowerCase())) {
  314. matchedTriplets.add(triplet);
  315. }
  316. }
  317. return matchedTriplets;
  318. }
  319. /**
  320. * Returns a suitable internal font given an AWT Font instance.
  321. *
  322. * @param awtFont the AWT font
  323. * @return a best matching internal Font
  324. */
  325. public Font getFontInstanceForAWTFont(java.awt.Font awtFont) {
  326. String awtFontName = awtFont.getName();
  327. String awtFontFamily = awtFont.getFamily();
  328. String awtFontStyle = awtFont.isItalic() ? Font.STYLE_ITALIC : Font.STYLE_NORMAL;
  329. int awtFontWeight = awtFont.isBold() ? Font.WEIGHT_BOLD : Font.WEIGHT_NORMAL;
  330. FontTriplet matchedTriplet = null;
  331. List/*<FontTriplet>*/ triplets = getTripletsForName(awtFontName);
  332. if (!triplets.isEmpty()) {
  333. Iterator it = triplets.iterator();
  334. while (it.hasNext()) {
  335. FontTriplet triplet = (FontTriplet)it.next();
  336. boolean styleMatched = triplet.getStyle().equals(awtFontStyle);
  337. boolean weightMatched = triplet.getWeight() == awtFontWeight;
  338. if (styleMatched && weightMatched) {
  339. matchedTriplet = triplet;
  340. break;
  341. }
  342. }
  343. }
  344. // not matched on font name so do a lookup using family
  345. if (matchedTriplet == null) {
  346. if (awtFontFamily.equals("sanserif")) {
  347. awtFontFamily = "sans-serif";
  348. }
  349. matchedTriplet = fontLookup(awtFontFamily, awtFontStyle, awtFontWeight);
  350. }
  351. float awtFontSize = awtFont.getSize2D();
  352. return getFontInstance(matchedTriplet, (int)(awtFontSize * 1000 + 0.5));
  353. }
  354. /**
  355. * Lookup a font.
  356. * <br>
  357. * Locate the font name for a given family, style and weight.
  358. * The font name can then be used as a key as it is unique for
  359. * the associated document.
  360. * This also adds the font to the list of used fonts.
  361. * @param family font family
  362. * @param style font style
  363. * @param weight font weight
  364. * @return the font triplet of the font chosen
  365. */
  366. public FontTriplet fontLookup(String family, String style,
  367. int weight) {
  368. return fontLookup(family, style, weight, true);
  369. }
  370. private List/*<FontTriplet>*/ fontLookup(String[] families, String style,
  371. int weight, boolean substitutable) {
  372. List/*<FontTriplet>*/ matchingTriplets = new java.util.ArrayList/*<FontTriplet>*/();
  373. FontTriplet triplet = null;
  374. for (int i = 0; i < families.length; i++) {
  375. triplet = fontLookup(families[i], style, weight, substitutable);
  376. if (triplet != null) {
  377. matchingTriplets.add(triplet);
  378. }
  379. }
  380. return matchingTriplets;
  381. }
  382. /**
  383. * Looks up a set of fonts.
  384. * <br>
  385. * Locate the font name(s) for the given families, style and weight.
  386. * The font name(s) can then be used as a key as they are unique for
  387. * the associated document.
  388. * This also adds the fonts to the list of used fonts.
  389. * @param families font families (priority list)
  390. * @param style font style
  391. * @param weight font weight
  392. * @return the set of font triplets of all supported and chosen font-families
  393. * in the specified style and weight.
  394. */
  395. public FontTriplet[] fontLookup(String[] families, String style,
  396. int weight) {
  397. if (families.length == 0) {
  398. throw new IllegalArgumentException("Specify at least one font family");
  399. }
  400. // try matching without substitutions
  401. List/*<FontTriplet>*/ matchedTriplets = fontLookup(families, style, weight, false);
  402. // if there are no matching font triplets found try with substitutions
  403. if (matchedTriplets.size() == 0) {
  404. matchedTriplets = fontLookup(families, style, weight, true);
  405. }
  406. // no matching font triplets found!
  407. if (matchedTriplets.size() == 0) {
  408. StringBuffer sb = new StringBuffer();
  409. for (int i = 0, c = families.length; i < c; i++) {
  410. if (i > 0) {
  411. sb.append(", ");
  412. }
  413. sb.append(families[i]);
  414. }
  415. throw new IllegalStateException(
  416. "fontLookup must return an array with at least one "
  417. + "FontTriplet on the last call. Lookup: " + sb.toString());
  418. }
  419. FontTriplet[] fontTriplets = new FontTriplet[matchedTriplets.size()];
  420. matchedTriplets.toArray(fontTriplets);
  421. // found some matching fonts so return them
  422. return fontTriplets;
  423. }
  424. private Set/*<FontTriplet>*/ getLoggedFontKeys() {
  425. if (loggedFontKeys == null) {
  426. loggedFontKeys = new java.util.HashSet/*<FontTriplet>*/();
  427. }
  428. return loggedFontKeys;
  429. }
  430. private void notifyFontReplacement(FontTriplet replacedKey, FontTriplet newKey) {
  431. if (!getLoggedFontKeys().contains(replacedKey)) {
  432. getLoggedFontKeys().add(replacedKey);
  433. if (this.eventListener != null) {
  434. this.eventListener.fontSubstituted(this, replacedKey, newKey);
  435. } else {
  436. log.warn("Font '" + replacedKey + "' not found. "
  437. + "Substituting with '" + newKey + "'.");
  438. }
  439. }
  440. }
  441. /**
  442. * Find a font with a given family and style by trying
  443. * different font weights according to the spec.
  444. * @param family font family
  445. * @param style font style
  446. * @param weight font weight
  447. * @return internal key
  448. */
  449. public FontTriplet findAdjustWeight(String family, String style,
  450. int weight) {
  451. FontTriplet key = null;
  452. String f = null;
  453. int newWeight = weight;
  454. if (newWeight <= 400) {
  455. while (f == null && newWeight > 100) {
  456. newWeight -= 100;
  457. key = createFontKey(family, style, newWeight);
  458. f = getInternalFontKey(key);
  459. }
  460. newWeight = weight;
  461. while (f == null && newWeight < 400) {
  462. newWeight += 100;
  463. key = createFontKey(family, style, newWeight);
  464. f = getInternalFontKey(key);
  465. }
  466. } else if (newWeight == 500) {
  467. key = createFontKey(family, style, 400);
  468. f = getInternalFontKey(key);
  469. } else if (newWeight > 500) {
  470. while (f == null && newWeight < 1000) {
  471. newWeight += 100;
  472. key = createFontKey(family, style, newWeight);
  473. f = getInternalFontKey(key);
  474. }
  475. newWeight = weight;
  476. while (f == null && newWeight > 400) {
  477. newWeight -= 100;
  478. key = createFontKey(family, style, newWeight);
  479. f = getInternalFontKey(key);
  480. }
  481. }
  482. if (f == null && weight != 400) {
  483. key = createFontKey(family, style, 400);
  484. f = getInternalFontKey(key);
  485. }
  486. if (f != null) {
  487. return key;
  488. } else {
  489. return null;
  490. }
  491. }
  492. /**
  493. * Determines if a particular font is available.
  494. * @param family font family
  495. * @param style font style
  496. * @param weight font weight
  497. * @return True if available
  498. */
  499. public boolean hasFont(String family, String style, int weight) {
  500. FontTriplet key = createFontKey(family, style, weight);
  501. return this.triplets.containsKey(key);
  502. }
  503. /**
  504. * Returns the internal font key (F1, F2, F3 etc.) for a given triplet.
  505. * @param triplet the font triplet
  506. * @return the associated internal key or null, if not found
  507. */
  508. public String getInternalFontKey(FontTriplet triplet) {
  509. return (String)triplets.get(triplet);
  510. }
  511. /**
  512. * Creates a key from the given strings.
  513. * @param family font family
  514. * @param style font style
  515. * @param weight font weight
  516. * @return internal key
  517. */
  518. public static FontTriplet createFontKey(String family, String style,
  519. int weight) {
  520. return new FontTriplet(family, style, weight);
  521. }
  522. /**
  523. * Gets a Map of all registered fonts.
  524. * @return a read-only Map with font key/FontMetrics pairs
  525. */
  526. public Map/*<String,FontMetrics>*/ getFonts() {
  527. return java.util.Collections.unmodifiableMap(this.fonts);
  528. }
  529. /**
  530. * Gets a Map of all registered font triplets.
  531. * @return a Map with FontTriplet/font key pairs
  532. */
  533. public Map/*<FontTriplet,String>*/ getFontTriplets() {
  534. return this.triplets;
  535. }
  536. /**
  537. * This is used by the renderers to retrieve all the
  538. * fonts used in the document.
  539. * This is for embedded font or creating a list of used fonts.
  540. * @return a read-only Map with font key/FontMetrics pairs
  541. */
  542. public Map/*<String,FontMetrics>*/ getUsedFonts() {
  543. return this.usedFonts;
  544. }
  545. /**
  546. * Returns the FontMetrics for a particular font
  547. * @param fontName internal key
  548. * @return font metrics
  549. */
  550. public FontMetrics getMetricsFor(String fontName) {
  551. FontMetrics metrics = (FontMetrics)fonts.get(fontName);
  552. usedFonts.put(fontName, metrics);
  553. return metrics;
  554. }
  555. /**
  556. * Returns all font triplet matching the given font name.
  557. * @param fontName The font name we are looking for
  558. * @return A list of matching font triplets
  559. */
  560. public List/*<FontTriplet>*/ getTripletsFor(String fontName) {
  561. List/*<FontTriplet>*/ foundTriplets = new java.util.ArrayList();
  562. for (Iterator iter = triplets.entrySet().iterator(); iter.hasNext();) {
  563. Map.Entry tripletEntry = (Map.Entry) iter.next();
  564. if (fontName.equals((tripletEntry.getValue()))) {
  565. foundTriplets.add(tripletEntry.getKey());
  566. }
  567. }
  568. return foundTriplets;
  569. }
  570. /**
  571. * Returns the first triplet matching the given font name.
  572. * As there may be multiple triplets matching the font name
  573. * the result set is sorted first to guarantee consistent results.
  574. * @param fontName The font name we are looking for
  575. * @return The first triplet for the given font name
  576. */
  577. public FontTriplet getTripletFor(String fontName) {
  578. List/*<FontTriplet>*/ foundTriplets = getTripletsFor(fontName);
  579. if (foundTriplets.size() > 0) {
  580. Collections.sort(foundTriplets);
  581. return (FontTriplet)foundTriplets.get(0);
  582. }
  583. return null;
  584. }
  585. /**
  586. * Returns the font style for a particular font.
  587. * There may be multiple font styles matching this font. Only the first
  588. * found is returned. Searching is done on a sorted list to guarantee consistent
  589. * results.
  590. * @param fontName internal key
  591. * @return font style
  592. */
  593. public String getFontStyleFor(String fontName) {
  594. FontTriplet triplet = getTripletFor(fontName);
  595. if (triplet != null) {
  596. return triplet.getStyle();
  597. } else {
  598. return "";
  599. }
  600. }
  601. /**
  602. * Returns the font weight for a particular font.
  603. * There may be multiple font weights matching this font. Only the first
  604. * found is returned. Searching is done on a sorted list to guarantee consistent
  605. * results.
  606. * @param fontName internal key
  607. * @return font weight
  608. */
  609. public int getFontWeightFor(String fontName) {
  610. FontTriplet triplet = getTripletFor(fontName);
  611. if (triplet != null) {
  612. return triplet.getWeight();
  613. } else {
  614. return 0;
  615. }
  616. }
  617. /**
  618. * Diagnostic method for logging all registered fonts to System.out.
  619. */
  620. public void dumpAllTripletsToSystemOut() {
  621. System.out.print(toString());
  622. }
  623. /**
  624. * {@inheritDoc}
  625. */
  626. public String toString() {
  627. Collection entries = new java.util.TreeSet();
  628. Iterator iter = this.triplets.keySet().iterator();
  629. while (iter.hasNext()) {
  630. FontTriplet triplet = (FontTriplet)iter.next();
  631. String key = getInternalFontKey(triplet);
  632. FontMetrics metrics = getMetricsFor(key);
  633. entries.add(triplet.toString() + " -> " + key + " -> " + metrics.getFontName() + "\n");
  634. }
  635. StringBuffer stringBuffer = new StringBuffer();
  636. for (iter = entries.iterator(); iter.hasNext();) {
  637. stringBuffer.append(iter.next());
  638. }
  639. return stringBuffer.toString();
  640. }
  641. }