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.

AFPRendererConfigurator.java 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  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.render.afp;
  19. import java.io.File;
  20. import java.util.List;
  21. import org.apache.avalon.framework.configuration.Configuration;
  22. import org.apache.avalon.framework.configuration.ConfigurationException;
  23. import org.apache.fop.afp.AFPResourceLevel;
  24. import org.apache.fop.afp.AFPResourceLevelDefaults;
  25. import org.apache.fop.afp.fonts.AFPFontCollection;
  26. import org.apache.fop.afp.fonts.AFPFontInfo;
  27. import org.apache.fop.afp.fonts.CharacterSet;
  28. import org.apache.fop.afp.fonts.FopCharacterSet;
  29. import org.apache.fop.afp.fonts.OutlineFont;
  30. import org.apache.fop.afp.fonts.RasterFont;
  31. import org.apache.fop.apps.FOPException;
  32. import org.apache.fop.apps.FOUserAgent;
  33. import org.apache.fop.fonts.FontCollection;
  34. import org.apache.fop.fonts.FontInfo;
  35. import org.apache.fop.fonts.FontManager;
  36. import org.apache.fop.fonts.FontTriplet;
  37. import org.apache.fop.fonts.FontUtil;
  38. import org.apache.fop.fonts.Typeface;
  39. import org.apache.fop.render.PrintRendererConfigurator;
  40. import org.apache.fop.render.Renderer;
  41. import org.apache.fop.render.intermediate.IFDocumentHandler;
  42. import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
  43. import org.apache.fop.util.LogUtil;
  44. /**
  45. * AFP Renderer configurator
  46. */
  47. public class AFPRendererConfigurator extends PrintRendererConfigurator
  48. implements IFDocumentHandlerConfigurator {
  49. /**
  50. * Default constructor
  51. *
  52. * @param userAgent user agent
  53. */
  54. public AFPRendererConfigurator(FOUserAgent userAgent) {
  55. super(userAgent);
  56. }
  57. private AFPFontInfo buildFont(Configuration fontCfg, String fontPath)
  58. throws ConfigurationException {
  59. Configuration[] triple = fontCfg.getChildren("font-triplet");
  60. List/*<FontTriplet>*/ tripletList = new java.util.ArrayList/*<FontTriplet>*/();
  61. if (triple.length == 0) {
  62. log.error("Mandatory font configuration element '<font-triplet...' is missing");
  63. return null;
  64. }
  65. for (int j = 0; j < triple.length; j++) {
  66. int weight = FontUtil.parseCSS2FontWeight(triple[j].getAttribute("weight"));
  67. FontTriplet triplet = new FontTriplet(triple[j].getAttribute("name"),
  68. triple[j].getAttribute("style"),
  69. weight);
  70. tripletList.add(triplet);
  71. }
  72. //build the fonts
  73. Configuration afpFontCfg = fontCfg.getChild("afp-font");
  74. if (afpFontCfg == null) {
  75. log.error("Mandatory font configuration element '<afp-font...' is missing");
  76. return null;
  77. }
  78. String path = afpFontCfg.getAttribute("path", fontPath);
  79. String type = afpFontCfg.getAttribute("type");
  80. if (type == null) {
  81. log.error("Mandatory afp-font configuration attribute 'type=' is missing");
  82. return null;
  83. }
  84. String codepage = afpFontCfg.getAttribute("codepage");
  85. if (codepage == null) {
  86. log.error("Mandatory afp-font configuration attribute 'code=' is missing");
  87. return null;
  88. }
  89. String encoding = afpFontCfg.getAttribute("encoding");
  90. if (encoding == null) {
  91. log.error("Mandatory afp-font configuration attribute 'encoding=' is missing");
  92. return null;
  93. }
  94. if ("raster".equalsIgnoreCase(type)) {
  95. String name = afpFontCfg.getAttribute("name", "Unknown");
  96. // Create a new font object
  97. RasterFont font = new RasterFont(name);
  98. Configuration[] rasters = afpFontCfg.getChildren("afp-raster-font");
  99. if (rasters.length == 0) {
  100. log.error(
  101. "Mandatory font configuration elements '<afp-raster-font...' are missing");
  102. return null;
  103. }
  104. for (int j = 0; j < rasters.length; j++) {
  105. Configuration rasterCfg = rasters[j];
  106. String characterset = rasterCfg.getAttribute("characterset");
  107. if (characterset == null) {
  108. log.error(
  109. "Mandatory afp-raster-font configuration attribute 'characterset=' is missing");
  110. return null;
  111. }
  112. int size = rasterCfg.getAttributeAsInteger("size");
  113. String base14 = rasterCfg.getAttribute("base14-font", null);
  114. if (base14 != null) {
  115. try {
  116. Class clazz = Class.forName("org.apache.fop.fonts.base14."
  117. + base14);
  118. try {
  119. Typeface tf = (Typeface)clazz.newInstance();
  120. font.addCharacterSet(size, new FopCharacterSet(
  121. codepage, encoding, characterset, tf));
  122. } catch (Exception ie) {
  123. String msg = "The base 14 font class " + clazz.getName()
  124. + " could not be instantiated";
  125. log.error(msg);
  126. }
  127. } catch (ClassNotFoundException cnfe) {
  128. String msg = "The base 14 font class for " + characterset
  129. + " could not be found";
  130. log.error(msg);
  131. }
  132. } else {
  133. font.addCharacterSet(size, new CharacterSet(
  134. codepage, encoding, characterset, path));
  135. }
  136. }
  137. return new AFPFontInfo(font, tripletList);
  138. } else if ("outline".equalsIgnoreCase(type)) {
  139. String characterset = afpFontCfg.getAttribute("characterset");
  140. if (characterset == null) {
  141. log.error("Mandatory afp-font configuration attribute 'characterset=' is missing");
  142. return null;
  143. }
  144. String name = afpFontCfg.getAttribute("name", characterset);
  145. CharacterSet characterSet = null;
  146. String base14 = afpFontCfg.getAttribute("base14-font", null);
  147. if (base14 != null) {
  148. try {
  149. Class clazz = Class.forName("org.apache.fop.fonts.base14."
  150. + base14);
  151. try {
  152. Typeface tf = (Typeface)clazz.newInstance();
  153. characterSet = new FopCharacterSet(
  154. codepage, encoding, characterset, tf);
  155. } catch (Exception ie) {
  156. String msg = "The base 14 font class " + clazz.getName()
  157. + " could not be instantiated";
  158. log.error(msg);
  159. }
  160. } catch (ClassNotFoundException cnfe) {
  161. String msg = "The base 14 font class for " + characterset
  162. + " could not be found";
  163. log.error(msg);
  164. }
  165. } else {
  166. characterSet = new CharacterSet(codepage, encoding, characterset, path);
  167. }
  168. // Create a new font object
  169. OutlineFont font = new OutlineFont(name, characterSet);
  170. return new AFPFontInfo(font, tripletList);
  171. } else {
  172. log.error("No or incorrect type attribute");
  173. }
  174. return null;
  175. }
  176. /**
  177. * Builds a list of AFPFontInfo objects for use with the setup() method.
  178. *
  179. * @param cfg Configuration object
  180. * @return List the newly created list of fonts
  181. * @throws ConfigurationException if something's wrong with the config data
  182. */
  183. private List/*<AFPFontInfo>*/ buildFontListFromConfiguration(Configuration cfg)
  184. throws ConfigurationException {
  185. List/*<AFPFontInfo>*/ fontList = new java.util.ArrayList();
  186. Configuration[] font = cfg.getChild("fonts").getChildren("font");
  187. final String fontPath = null;
  188. for (int i = 0; i < font.length; i++) {
  189. AFPFontInfo afi = buildFont(font[i], fontPath);
  190. if (afi != null) {
  191. if (log.isDebugEnabled()) {
  192. log.debug("Adding font " + afi.getAFPFont().getFontName());
  193. List/*<FontTriplet>*/ fontTriplets = afi.getFontTriplets();
  194. for (int j = 0; j < fontTriplets.size(); ++j) {
  195. FontTriplet triplet = (FontTriplet) fontTriplets.get(j);
  196. log.debug(" Font triplet "
  197. + triplet.getName() + ", "
  198. + triplet.getStyle() + ", "
  199. + triplet.getWeight());
  200. }
  201. }
  202. fontList.add(afi);
  203. }
  204. }
  205. return fontList;
  206. }
  207. /** images are converted to grayscale bitmapped IOCA */
  208. private static final String IMAGES_MODE_GRAYSCALE = "b+w";
  209. /** images are converted to color bitmapped IOCA */
  210. private static final String IMAGES_MODE_COLOR = "color";
  211. /**
  212. * Configure the AFP renderer.
  213. *
  214. * @param renderer AFP renderer
  215. * @throws FOPException fop exception
  216. * @see org.apache.fop.render.PrintRendererConfigurator#configure(Renderer)
  217. */
  218. public void configure(Renderer renderer) throws FOPException {
  219. Configuration cfg = super.getRendererConfig(renderer);
  220. if (cfg != null) {
  221. AFPRenderer afpRenderer = (AFPRenderer)renderer;
  222. try {
  223. List/*<AFPFontInfo>*/ fontList = buildFontListFromConfiguration(cfg);
  224. afpRenderer.setFontList(fontList);
  225. } catch (ConfigurationException e) {
  226. LogUtil.handleException(log, e,
  227. userAgent.getFactory().validateUserConfigStrictly());
  228. }
  229. configure(afpRenderer, cfg);
  230. }
  231. }
  232. private void configure(AFPCustomizable customizable, Configuration cfg) throws FOPException {
  233. // image information
  234. Configuration imagesCfg = cfg.getChild("images");
  235. // default to grayscale images
  236. String imagesMode = imagesCfg.getAttribute("mode", IMAGES_MODE_GRAYSCALE);
  237. if (IMAGES_MODE_COLOR.equals(imagesMode)) {
  238. customizable.setColorImages(true);
  239. } else {
  240. customizable.setColorImages(false);
  241. // default to 8 bits per pixel
  242. int bitsPerPixel = imagesCfg.getAttributeAsInteger("bits-per-pixel", 8);
  243. customizable.setBitsPerPixel(bitsPerPixel);
  244. }
  245. // native image support
  246. boolean nativeImageSupport = imagesCfg.getAttributeAsBoolean("native", false);
  247. customizable.setNativeImagesSupported(nativeImageSupport);
  248. // renderer resolution
  249. Configuration rendererResolutionCfg = cfg.getChild("renderer-resolution", false);
  250. if (rendererResolutionCfg != null) {
  251. customizable.setResolution(rendererResolutionCfg.getValueAsInteger(240));
  252. }
  253. // a default external resource group file setting
  254. Configuration resourceGroupFileCfg
  255. = cfg.getChild("resource-group-file", false);
  256. if (resourceGroupFileCfg != null) {
  257. String resourceGroupDest = null;
  258. try {
  259. resourceGroupDest = resourceGroupFileCfg.getValue();
  260. } catch (ConfigurationException e) {
  261. LogUtil.handleException(log, e,
  262. userAgent.getFactory().validateUserConfigStrictly());
  263. }
  264. File resourceGroupFile = new File(resourceGroupDest);
  265. if (resourceGroupFile.canWrite()) {
  266. customizable.setDefaultResourceGroupFilePath(resourceGroupDest);
  267. } else {
  268. log.warn("Unable to write to default external resource group file '"
  269. + resourceGroupDest + "'");
  270. }
  271. }
  272. Configuration defaultResourceLevelCfg = cfg.getChild("default-resource-levels", false);
  273. if (defaultResourceLevelCfg != null) {
  274. AFPResourceLevelDefaults defaults = new AFPResourceLevelDefaults();
  275. String[] types = defaultResourceLevelCfg.getAttributeNames();
  276. for (int i = 0, c = types.length; i < c; i++) {
  277. String type = types[i];
  278. try {
  279. String level = defaultResourceLevelCfg.getAttribute(type);
  280. defaults.setDefaultResourceLevel(type, AFPResourceLevel.valueOf(level));
  281. } catch (IllegalArgumentException iae) {
  282. LogUtil.handleException(log, iae,
  283. userAgent.getFactory().validateUserConfigStrictly());
  284. } catch (ConfigurationException e) {
  285. LogUtil.handleException(log, e,
  286. userAgent.getFactory().validateUserConfigStrictly());
  287. }
  288. }
  289. customizable.setResourceLevelDefaults(defaults);
  290. }
  291. }
  292. /** {@inheritDoc} */
  293. public void configure(IFDocumentHandler documentHandler) throws FOPException {
  294. Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
  295. if (cfg != null) {
  296. AFPDocumentHandler afpDocumentHandler = (AFPDocumentHandler)documentHandler;
  297. configure(afpDocumentHandler, cfg);
  298. }
  299. }
  300. /** {@inheritDoc} */
  301. public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo)
  302. throws FOPException {
  303. FontManager fontManager = userAgent.getFactory().getFontManager();
  304. List fontCollections = new java.util.ArrayList();
  305. Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
  306. if (cfg != null) {
  307. try {
  308. List fontList = buildFontListFromConfiguration(cfg);
  309. fontCollections.add(new AFPFontCollection(
  310. userAgent.getEventBroadcaster(), fontList));
  311. } catch (ConfigurationException e) {
  312. LogUtil.handleException(log, e,
  313. userAgent.getFactory().validateUserConfigStrictly());
  314. }
  315. }
  316. fontManager.setup(fontInfo,
  317. (FontCollection[])fontCollections.toArray(
  318. new FontCollection[fontCollections.size()]));
  319. documentHandler.setFontInfo(fontInfo);
  320. }
  321. }