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.

XMLRenderer.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*
  2. * $Id$
  3. * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
  4. * For details on use and redistribution please refer to the
  5. * LICENSE file included with these sources.
  6. */
  7. package org.apache.fop.render.xml;
  8. // FOP
  9. import org.apache.fop.svg.*;
  10. import org.apache.fop.render.Renderer;
  11. import org.apache.fop.render.AbstractRenderer;
  12. import org.apache.fop.render.RendererContext;
  13. import org.apache.fop.render.XMLHandler;
  14. import org.apache.fop.image.ImageArea;
  15. import org.apache.fop.area.*;
  16. import org.apache.fop.area.inline.*;
  17. import org.apache.fop.pdf.*;
  18. import org.apache.fop.fo.properties.LeaderPattern;
  19. import org.apache.fop.fo.FOUserAgent;
  20. import org.apache.fop.layout.FontInfo;
  21. import org.apache.fop.apps.FOPException;
  22. import org.apache.log.Logger;
  23. // Java
  24. import java.io.IOException;
  25. import java.io.PrintWriter;
  26. import java.io.OutputStream;
  27. import java.util.Enumeration;
  28. import java.util.HashMap;
  29. import java.util.List;
  30. import java.awt.geom.Rectangle2D;
  31. import org.w3c.dom.Document;
  32. /**
  33. * Renderer that renders areas to XML for debugging purposes.
  34. * This creates an xml that contains the information of the area
  35. * tree. It does not output any state or derived information.
  36. * The output can be used to build a new area tree (@see AreaTreeBuilder)
  37. * which can be rendered to any renderer.
  38. */
  39. public class XMLRenderer extends AbstractRenderer {
  40. public static final String mimeType = "text/xml";
  41. boolean startedSequence = false;
  42. RendererContext context;
  43. public void setProducer(String producer) {
  44. }
  45. /**
  46. * indentation to use for pretty-printing the XML
  47. */
  48. protected int indent = 0;
  49. /**
  50. * the application producing the XML
  51. */
  52. protected String producer;
  53. /**
  54. * the writer used to output the XML
  55. */
  56. protected PrintWriter writer;
  57. /**
  58. * options
  59. */
  60. private boolean consistentOutput = false;
  61. public XMLRenderer() {
  62. context = new RendererContext(mimeType);
  63. }
  64. public void setUserAgent(FOUserAgent agent) {
  65. super.setUserAgent(agent);
  66. //userAgent.addExtensionHandler();
  67. XMLHandler handler = new XMLXMLHandler();
  68. userAgent.setDefaultXMLHandler(mimeType, handler);
  69. String svg = "http://www.w3.org/2000/svg";
  70. userAgent.addXMLHandler(mimeType, svg, handler);
  71. }
  72. /**
  73. * write out spaces to make indent
  74. */
  75. protected void writeIndent() {
  76. StringBuffer s = new StringBuffer();
  77. for (int i = 0; i < this.indent; i++) {
  78. s = s.append(" ");
  79. }
  80. this.writer.write(s.toString());
  81. }
  82. /**
  83. * write out an element
  84. *
  85. * @param element the full text of the element including tags
  86. */
  87. protected void writeElement(String element) {
  88. writeIndent();
  89. this.writer.write(element + "\n");
  90. }
  91. /**
  92. * write out an empty-element-tag
  93. *
  94. * @param tag the text of the tag
  95. */
  96. protected void writeEmptyElementTag(String tag) {
  97. writeIndent();
  98. this.writer.write(tag + "\n");
  99. }
  100. /**
  101. * write out an end tag
  102. *
  103. * @param tag the text of the tag
  104. */
  105. protected void writeEndTag(String tag) {
  106. this.indent--;
  107. writeIndent();
  108. this.writer.write(tag + "\n");
  109. }
  110. /**
  111. * write out a start tag
  112. *
  113. * @param tag the text of the tag
  114. */
  115. protected void writeStartTag(String tag) {
  116. writeIndent();
  117. this.writer.write(tag + "\n");
  118. this.indent++;
  119. }
  120. /**
  121. * set up the font info
  122. *
  123. * @param fontInfo the font info object to set up
  124. */
  125. public void setupFontInfo(FontInfo fontInfo) {
  126. /* use PDF's font setup to get PDF metrics */
  127. org.apache.fop.render.pdf.FontSetup.setup(fontInfo);
  128. }
  129. private boolean isCoarseXml() {
  130. return ((Boolean) options.get("fineDetail")).booleanValue();
  131. }
  132. /**
  133. */
  134. public void startRenderer(OutputStream outputStream)
  135. throws IOException {
  136. log.debug("rendering areas to XML");
  137. this.writer = new PrintWriter(outputStream);
  138. this.writer.write( "<?xml version=\"1.0\"?>\n<!-- produced by " +
  139. this.producer + " -->\n");
  140. writeStartTag("<areaTree>");
  141. }
  142. /**
  143. */
  144. public void stopRenderer() throws IOException {
  145. writeEndTag("</pageSequence>");
  146. writeEndTag("</areaTree>");
  147. this.writer.flush();
  148. log.debug("written out XML");
  149. }
  150. public void renderPage(PageViewport page) throws IOException,
  151. FOPException {
  152. writeStartTag("<pageViewport bounds=\"" +
  153. createString(page.getViewArea()) + "\">");
  154. writeStartTag("<page>");
  155. super.renderPage(page);
  156. writeEndTag("</page>");
  157. writeEndTag("</pageViewport>");
  158. }
  159. private String createString(Rectangle2D rect) {
  160. return "" + (int) rect.getX() + " " + (int) rect.getY() + " " +
  161. (int) rect.getWidth() + " " + (int) rect.getHeight();
  162. }
  163. public void startPageSequence(Title seqTitle) {
  164. if (startedSequence) {
  165. writeEndTag("</pageSequence>");
  166. }
  167. startedSequence = true;
  168. writeStartTag("<pageSequence>");
  169. if (seqTitle != null) {
  170. writeStartTag("<title>");
  171. List children = seqTitle.getInlineAreas();
  172. for (int count = 0; count < children.size(); count++) {
  173. InlineArea inline = (InlineArea) children.get(count);
  174. inline.render(this);
  175. }
  176. writeEndTag("</title>");
  177. }
  178. }
  179. protected void renderRegionViewport(RegionViewport port) {
  180. if (port != null) {
  181. writeStartTag("<regionViewport rect=\"" +
  182. createString(port.getViewArea()) + "\">");
  183. Region region = port.getRegion();
  184. if (region.getRegionClass() == Region.BEFORE) {
  185. writeStartTag("<regionBefore>");
  186. renderRegion(region);
  187. writeEndTag("</regionBefore>");
  188. } else if (region.getRegionClass() == Region.START) {
  189. writeStartTag("<regionStart>");
  190. renderRegion(region);
  191. writeEndTag("</regionStart>");
  192. } else if (region.getRegionClass() == Region.BODY) {
  193. writeStartTag("<regionBody>");
  194. renderBodyRegion((BodyRegion) region);
  195. writeEndTag("</regionBody>");
  196. } else if (region.getRegionClass() == Region.END) {
  197. writeStartTag("<regionEnd>");
  198. renderRegion(region);
  199. writeEndTag("</regionEnd>");
  200. } else if (region.getRegionClass() == Region.AFTER) {
  201. writeStartTag("<regionAfter>");
  202. renderRegion(region);
  203. writeEndTag("</regionAfter>");
  204. }
  205. writeEndTag("</regionViewport>");
  206. }
  207. }
  208. protected void renderBeforeFloat(BeforeFloat bf) {
  209. writeStartTag("<beforeFloat>");
  210. super.renderBeforeFloat(bf);
  211. writeEndTag("</beforeFloat>");
  212. }
  213. protected void renderFootnote(Footnote footnote) {
  214. writeStartTag("<footnote>");
  215. super.renderFootnote(footnote);
  216. writeEndTag("</footnote>");
  217. }
  218. protected void renderMainReference(MainReference mr) {
  219. writeStartTag("<mainReference columnGap=\"" +
  220. mr.getColumnGap() + "\" width=\"" + mr.getWidth() + "\">");
  221. Span span = null;
  222. List spans = mr.getSpans();
  223. for (int count = 0; count < spans.size(); count++) {
  224. span = (Span) spans.get(count);
  225. writeStartTag("<span>");
  226. for (int c = 0; c < span.getColumnCount(); c++) {
  227. Flow flow = (Flow) span.getFlow(c);
  228. renderFlow(flow);
  229. }
  230. writeEndTag("</span>");
  231. }
  232. writeEndTag("</mainReference>");
  233. }
  234. // the normal flow reference area contains stacked blocks
  235. protected void renderFlow(Flow flow) {
  236. writeStartTag("<flow>");
  237. super.renderFlow(flow);
  238. writeEndTag("</flow>");
  239. }
  240. protected void renderBlock(Block block) {
  241. String prop = "";
  242. List list = block.getPropertyList();
  243. if (list != null) {
  244. prop = " props=\"" + getPropString(list) + "\"";
  245. }
  246. writeStartTag("<block" + prop + ">");
  247. super.renderBlock(block);
  248. writeEndTag("</block>");
  249. }
  250. protected void renderLineArea(LineArea line) {
  251. String prop = "";
  252. List list = line.getPropertyList();
  253. if (list != null) {
  254. prop = " props=\"" + getPropString(list) + "\"";
  255. }
  256. writeStartTag("<lineArea height=\"" + line.getHeight() + "\"" +
  257. prop + ">");
  258. super.renderLineArea(line);
  259. writeEndTag("</lineArea>");
  260. }
  261. public void renderViewport(Viewport viewport) {
  262. writeStartTag("<viewport>");
  263. super.renderViewport(viewport);
  264. writeEndTag("</viewport>");
  265. }
  266. public void renderImage(Image image) {
  267. writeElement("<image url=\"" + image.getURL() + "\"/>");
  268. }
  269. public void renderContainer(Container cont) {
  270. writeStartTag("<container>");
  271. super.renderContainer(cont);
  272. writeEndTag("</container>");
  273. }
  274. public void renderForeignObject(ForeignObject fo) {
  275. writeStartTag("<foreignObject>");
  276. Document doc = fo.getDocument();
  277. String ns = fo.getNameSpace();
  278. context.setProperty(XMLXMLHandler.WRITER, writer);
  279. userAgent.renderXML(context, doc, ns);
  280. writeEndTag("</foreignObject>");
  281. }
  282. public void renderCharacter(org.apache.fop.area.inline.Character ch) {
  283. String prop = "";
  284. List list = ch.getPropertyList();
  285. if (list != null) {
  286. prop = " props=\"" + getPropString(list) + "\"";
  287. }
  288. writeElement("<char" + prop + ">" + ch.getChar() + "</char>");
  289. }
  290. public void renderInlineSpace(Space space) {
  291. writeElement("<space width=\"" + space.getWidth() + "\"/>");
  292. }
  293. public void renderLeader(Leader area) {
  294. String style = "solid";
  295. switch (area.getRuleStyle()) {
  296. case Leader.DOTTED:
  297. style = "dotted";
  298. break;
  299. case Leader.DASHED:
  300. style = "dashed";
  301. break;
  302. case Leader.SOLID:
  303. break;
  304. case Leader.DOUBLE:
  305. style = "double";
  306. break;
  307. case Leader.GROOVE:
  308. style = "groove";
  309. break;
  310. case Leader.RIDGE:
  311. style = "ridge";
  312. break;
  313. }
  314. writeElement("<leader width=\"" + area.getWidth() + "\" ruleStyle=\"" + style +
  315. "\" ruleThickness=\"" + area.getRuleThickness() + "\"/>");
  316. super.renderLeader(area);
  317. }
  318. protected String getPropString(List list) {
  319. String str = "";
  320. for (int count = 0; count < list.size(); count++) {
  321. Property prop = (Property) list.get(count);
  322. switch (prop.propType) {
  323. case Property.INTERNAL_LINK:
  324. str += "internal-link:" + prop.data;
  325. break;
  326. case Property.EXTERNAL_LINK:
  327. str += "external-link:" + prop.data;
  328. break;
  329. case Property.FONT_FAMILY:
  330. str += "font-family:" + prop.data;
  331. break;
  332. case Property.FONT_SIZE:
  333. str += "font-size:" + prop.data;
  334. break;
  335. case Property.FONT_WEIGHT:
  336. str += "font-weight:" + prop.data;
  337. break;
  338. case Property.FONT_STYLE:
  339. str += "font-style:" + prop.data;
  340. break;
  341. case Property.COLOR:
  342. str += "color:" + prop.data;
  343. break;
  344. case Property.BACKGROUND:
  345. str += "background:" + prop.data;
  346. break;
  347. case Property.UNDERLINE:
  348. str += "underline:" + prop.data;
  349. break;
  350. case Property.OVERLINE:
  351. str += "overline:" + prop.data;
  352. break;
  353. case Property.LINETHROUGH:
  354. str += "linethrough:" + prop.data;
  355. break;
  356. case Property.OFFSET:
  357. str += "offset:" + prop.data;
  358. break;
  359. case Property.SHADOW:
  360. str += "shadow:" + prop.data;
  361. break;
  362. default:
  363. break;
  364. }
  365. str += ";";
  366. }
  367. return str;
  368. }
  369. }