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

XMLRenderer.java 12KB

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