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.

AWTRenderer.java 34KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  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.awt;
  8. /*
  9. * originally contributed by
  10. * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com,
  11. * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com,
  12. * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com
  13. */
  14. import org.apache.fop.layout.*;
  15. import org.apache.fop.layout.inline.*;
  16. import org.apache.fop.datatypes.*;
  17. import org.apache.fop.image.*;
  18. import org.apache.fop.svg.*;
  19. import org.apache.fop.render.pdf.*;
  20. import org.apache.fop.viewer.*;
  21. import org.apache.fop.apps.*;
  22. import org.w3c.dom.svg.*;
  23. import org.w3c.dom.Document;
  24. import org.w3c.dom.Element;
  25. import org.apache.batik.bridge.*;
  26. import org.apache.batik.swing.svg.*;
  27. import org.apache.batik.swing.gvt.*;
  28. import org.apache.batik.gvt.*;
  29. import org.apache.batik.gvt.renderer.*;
  30. import org.apache.batik.gvt.filter.*;
  31. import org.apache.batik.gvt.event.*;
  32. import java.awt.*;
  33. import java.awt.Image;
  34. import java.awt.image.*;
  35. import java.awt.geom.*;
  36. import java.awt.font.*;
  37. import java.util.*;
  38. import java.net.URL;
  39. import java.net.MalformedURLException;
  40. import java.io.*;
  41. import java.beans.*;
  42. import javax.swing.*;
  43. import java.awt.print.*;
  44. import java.awt.image.BufferedImage;
  45. import java.text.*;
  46. import org.apache.fop.render.AbstractRenderer;
  47. /**
  48. Modified by Mark Lillywhite mark-fop@inomial.com. Did lots of
  49. cleaning up and made the class implement the new Renderer
  50. interface. This class could also do with a general audit,
  51. and I suspect it's not swing-thread-safe either.
  52. */
  53. public class AWTRenderer extends AbstractRenderer implements Printable, Pageable {
  54. protected int pageWidth = 0;
  55. protected int pageHeight = 0;
  56. protected double scaleFactor = 100.0;
  57. protected int pageNumber = 0;
  58. protected Vector pageList = new Vector();
  59. protected ProgressListener progressListener = null;
  60. protected Translator res = null;
  61. protected Hashtable fontNames = new Hashtable();
  62. protected Hashtable fontStyles = new Hashtable();
  63. protected Color saveColor = null;
  64. protected IDReferences idReferences = null;
  65. /**
  66. * Image Object and Graphics Object. The Graphics Object is the Graphics
  67. * object that is contained withing the Image Object.
  68. */
  69. private BufferedImage pageImage = null;
  70. private Graphics2D graphics = null;
  71. /**
  72. * The current (internal) font name
  73. */
  74. protected String currentFontName;
  75. /**
  76. * The current font size in millipoints
  77. */
  78. protected int currentFontSize;
  79. /**
  80. * The current colour's red, green and blue component
  81. */
  82. protected float currentRed = 0;
  83. protected float currentGreen = 0;
  84. protected float currentBlue = 0;
  85. /**
  86. * The parent component, used to set up the font.
  87. * This is needed as FontSetup needs a live AWT component
  88. * in order to generate valid font measures.
  89. */
  90. protected Component parent;
  91. /**
  92. * The current vertical position in millipoints from bottom
  93. */
  94. protected int currentYPosition = 0;
  95. /**
  96. * The current horizontal position in millipoints from left
  97. */
  98. protected int currentXPosition = 0;
  99. /**
  100. * The horizontal position of the current area container
  101. */
  102. private int currentAreaContainerXPosition = 0;
  103. /**
  104. * options
  105. */
  106. protected Hashtable options;
  107. /**
  108. * set up renderer options
  109. */
  110. public void setOptions(Hashtable options) {
  111. this.options = options;
  112. }
  113. public AWTRenderer(Translator aRes) {
  114. res = aRes;
  115. }
  116. /**
  117. * Sets parent component which is used to set up the font.
  118. * This is needed as FontSetup needs a live AWT component
  119. * in order to generate valid font measures.
  120. * @param parent the live AWT component reference
  121. */
  122. public void setComponent(Component parent) {
  123. this.parent = parent;
  124. }
  125. public int getPageNumber() {
  126. return pageNumber;
  127. }
  128. public void setPageNumber(int aValue) {
  129. pageNumber = aValue;
  130. }
  131. public void setScaleFactor(double newScaleFactor) {
  132. scaleFactor = newScaleFactor;
  133. }
  134. public double getScaleFactor() {
  135. return scaleFactor;
  136. }
  137. public BufferedImage getLastRenderedPage() {
  138. return pageImage;
  139. }
  140. /**
  141. * add a line to the current stream
  142. *
  143. * @param x1 the start x location in millipoints
  144. * @param y1 the start y location in millipoints
  145. * @param x2 the end x location in millipoints
  146. * @param y2 the end y location in millipoints
  147. * @param th the thickness in millipoints
  148. * @param r the red component
  149. * @param g the green component
  150. * @param b the blue component
  151. */
  152. // corrected 7/13/01 aml,rlc to properly handle thickness
  153. //
  154. protected void addLine(int x1, int y1, int x2, int y2, int th, float r,
  155. float g, float b) {
  156. graphics.setColor(new Color(r, g, b));
  157. int x = x1;
  158. int y = y1;
  159. int height, width;
  160. if (x1 == x2) // vertical line
  161. {
  162. height = y2 - y1;
  163. if (height > 0) // y coordinates are reversed between fo and AWT
  164. {
  165. height = -height;
  166. y = y2;
  167. }
  168. width = th;
  169. if (width < 0) {
  170. width = -width;
  171. x -= width;
  172. }
  173. } else // horizontal line
  174. {
  175. width = x2 - x1;
  176. if (width < 0) {
  177. width = -width;
  178. x = x2;
  179. }
  180. height = th;
  181. if (height > 0) // y coordinates are reversed between fo and AWT
  182. {
  183. height = -height;
  184. y -= height;
  185. }
  186. }
  187. addRect(x, y, width, height, false);
  188. // // graphics.setColor(Color.red);
  189. // graphics.drawLine((int)(x1 / 1000f),
  190. // pageHeight - (int)(y1 / 1000f), (int)(x2 / 1000f),
  191. // pageHeight - (int)(y2 / 1000f));
  192. }
  193. /**
  194. * draw a rectangle
  195. *
  196. * @param x the x position of left edge in millipoints
  197. * @param y the y position of top edge in millipoints
  198. * @param w the width in millipoints
  199. * @param h the height in millipoints
  200. * @param r the red component
  201. * @param g the green component
  202. * @param b the blue component
  203. */
  204. // changed by aml/rlc to use helper function that
  205. // corrects for integer roundoff, and to remove 3D effect
  206. protected void addRect(int x, int y, int w, int h, float r, float g,
  207. float b) {
  208. graphics.setColor(new Color(r, g, b));
  209. // graphics.setColor(Color.green);
  210. addRect(x, y, w, h, true);
  211. }
  212. /**
  213. * draw a filled rectangle
  214. *
  215. * @param x the x position of left edge in millipoints
  216. * @param y the y position of top edge in millipoints
  217. * @param w the width in millipoints
  218. * @param h the height in millipoints
  219. * @param r the red component of edges
  220. * @param g the green component of edges
  221. * @param b the blue component of edges
  222. * @param fr the red component of the fill
  223. * @param fg the green component of the fill
  224. * @param fb the blue component of the fill
  225. */
  226. // changed by aml/rlc to use helper function that
  227. // corrects for integer roundoff
  228. protected void addRect(int x, int y, int w, int h, float r, float g,
  229. float b, float fr, float fg, float fb) {
  230. graphics.setColor(new Color(r, g, b));
  231. addRect(x, y, w, h, true);
  232. graphics.setColor(new Color(fr, fg, fb));
  233. addRect(x, y, w, h, false);
  234. }
  235. /**
  236. * draw a filled rectangle in the current color
  237. *
  238. * @param x the x position of left edge in millipoints
  239. * @param y the y position of top edge in millipoints
  240. * @param w the width in millipoints
  241. * @param h the height in millipoints
  242. * @param drawAsOutline true for draw, false for fill
  243. */
  244. // helper function by aml/rlc to correct integer roundoff problems
  245. //
  246. protected void addRect(int x, int y, int w, int h,
  247. boolean drawAsOutline) {
  248. int startx = (x + 500) / 1000;
  249. int starty = pageHeight - ((y + 500) / 1000);
  250. int endx = (x + w + 500) / 1000;
  251. int endy = pageHeight - ((y + h + 500) / 1000);
  252. if (drawAsOutline)
  253. graphics.drawRect(startx, starty, endx - startx, endy - starty);
  254. else
  255. graphics.fillRect(startx, starty, endx - startx, endy - starty);
  256. }
  257. /**
  258. * To configure before print.
  259. *
  260. * Choose pages
  261. * Zoom factor
  262. * Page format / Landscape or Portrait
  263. */
  264. public void transform(Graphics2D g2d, double zoomPercent, double angle) {
  265. AffineTransform at = g2d.getTransform();
  266. at.rotate(angle);
  267. at.scale(zoomPercent / 100.0, zoomPercent / 100.0);
  268. g2d.setTransform(at);
  269. }
  270. protected void drawFrame() {
  271. int width = pageWidth;
  272. int height = pageHeight;
  273. graphics.setColor(Color.white);
  274. graphics.fillRect(0, 0, width, height);
  275. graphics.setColor(Color.black);
  276. graphics.drawRect(-1, -1, width + 2, height + 2);
  277. graphics.drawLine(width + 2, 0, width + 2, height + 2);
  278. graphics.drawLine(width + 3, 1, width + 3, height + 3);
  279. graphics.drawLine(0, height + 2, width + 2, height + 2);
  280. graphics.drawLine(1, height + 3, width + 3, height + 3);
  281. }
  282. /**
  283. * Retrieve the number of pages in this document.
  284. *
  285. * @return the number of pages
  286. */
  287. public int getPageCount() {
  288. return pageList.size();
  289. }
  290. public void removePage(int page) {
  291. pageList.removeElementAt(page);
  292. }
  293. public void render(int aPageNumber) {
  294. if(aPageNumber >= pageList.size())
  295. return;
  296. try {
  297. render((Page) pageList.elementAt(aPageNumber));
  298. } catch(IOException e) {
  299. e.printStackTrace();
  300. // This exception can't occur because we are not dealing with
  301. // any files
  302. }
  303. }
  304. public void render(Page page, OutputStream stream)
  305. throws IOException {
  306. pageList.addElement(page);
  307. }
  308. public void render(Page page)
  309. throws IOException {
  310. idReferences = page.getIDReferences();
  311. pageWidth = (int)((float)page.getWidth() / 1000f + .5);
  312. pageHeight = (int)((float)page.getHeight() / 1000f + .5);
  313. pageImage =
  314. new BufferedImage((int)((pageWidth * (int)scaleFactor) / 100),
  315. (int)((pageHeight * (int)scaleFactor) / 100),
  316. BufferedImage.TYPE_INT_RGB);
  317. graphics = pageImage.createGraphics();
  318. transform(graphics, scaleFactor, 0);
  319. drawFrame();
  320. renderPage(page);
  321. }
  322. public void renderPage(Page page) {
  323. BodyAreaContainer body;
  324. AreaContainer before, after;
  325. body = page.getBody();
  326. before = page.getBefore();
  327. after = page.getAfter();
  328. this.currentFontName = "";
  329. this.currentFontSize = 0;
  330. renderBodyAreaContainer(body);
  331. if (before != null) {
  332. renderAreaContainer(before);
  333. }
  334. if (after != null) {
  335. renderAreaContainer(after);
  336. }
  337. // SG: Wollen wir Links abbilden?
  338. /*
  339. * if (page.hasLinks()) {
  340. * ....
  341. * }
  342. */
  343. }
  344. public void renderAreaContainer(AreaContainer area) {
  345. int saveY = this.currentYPosition;
  346. int saveX = this.currentAreaContainerXPosition;
  347. if (area.getPosition()
  348. == org.apache.fop.fo.properties.Position.ABSOLUTE) {
  349. // Y position is computed assuming positive Y axis, adjust
  350. // for negative postscript one
  351. this.currentYPosition = area.getYPosition()
  352. - 2 * area.getPaddingTop()
  353. - 2 * area.getBorderTopWidth();
  354. this.currentAreaContainerXPosition = area.getXPosition();
  355. } else if (area.getPosition()
  356. == org.apache.fop.fo.properties.Position.RELATIVE) {
  357. this.currentYPosition -= area.getYPosition();
  358. this.currentAreaContainerXPosition += area.getXPosition();
  359. } else if (area.getPosition()
  360. == org.apache.fop.fo.properties.Position.STATIC) {
  361. this.currentYPosition -= area.getPaddingTop()
  362. + area.getBorderTopWidth();
  363. this.currentAreaContainerXPosition += area.getPaddingLeft()
  364. + area.getBorderLeftWidth();
  365. }
  366. doFrame(area);
  367. Enumeration e = area.getChildren().elements();
  368. while (e.hasMoreElements()) {
  369. org.apache.fop.layout.Box b =
  370. (org.apache.fop.layout.Box)e.nextElement();
  371. b.render(this);
  372. }
  373. if (area.getPosition()
  374. != org.apache.fop.fo.properties.Position.STATIC) {
  375. this.currentYPosition = saveY;
  376. this.currentAreaContainerXPosition = saveX;
  377. } else {
  378. this.currentYPosition -= area.getHeight();
  379. }
  380. }
  381. // empty for now
  382. public void renderBodyAreaContainer(BodyAreaContainer area) {
  383. renderAreaContainer(area.getBeforeFloatReferenceArea());
  384. renderAreaContainer(area.getFootnoteReferenceArea());
  385. // main reference area
  386. Enumeration e = area.getMainReferenceArea().getChildren().elements();
  387. while (e.hasMoreElements()) {
  388. org.apache.fop.layout.Box b =
  389. (org.apache.fop.layout.Box)e.nextElement();
  390. b.render(this); // span areas
  391. }
  392. }
  393. // empty for now
  394. public void renderSpanArea(SpanArea area) {
  395. Enumeration e = area.getChildren().elements();
  396. while (e.hasMoreElements()) {
  397. org.apache.fop.layout.Box b =
  398. (org.apache.fop.layout.Box)e.nextElement();
  399. b.render(this); // column areas
  400. }
  401. }
  402. private void doFrame(org.apache.fop.layout.Area area) {
  403. int w, h;
  404. int rx = this.currentAreaContainerXPosition;
  405. w = area.getContentWidth();
  406. if (area instanceof BlockArea) {
  407. rx += ((BlockArea)area).getStartIndent();
  408. }
  409. h = area.getContentHeight();
  410. int ry = this.currentYPosition;
  411. ColorType bg = area.getBackgroundColor();
  412. rx = rx - area.getPaddingLeft();
  413. ry = ry + area.getPaddingTop();
  414. w = w + area.getPaddingLeft() + area.getPaddingRight();
  415. h = h + area.getPaddingTop() + area.getPaddingBottom();
  416. // I'm not sure I should have to check for bg being null
  417. // but I do
  418. if ((bg != null) && (bg.alpha() == 0)) {
  419. this.addRect(rx, ry, w, -h, bg.red(), bg.green(), bg.blue(),
  420. bg.red(), bg.green(), bg.blue());
  421. }
  422. rx = rx - area.getBorderLeftWidth();
  423. ry = ry + area.getBorderTopWidth();
  424. w = w + area.getBorderLeftWidth() + area.getBorderRightWidth();
  425. h = h + area.getBorderTopWidth() + area.getBorderBottomWidth();
  426. BorderAndPadding bp = area.getBorderAndPadding();
  427. ColorType borderColor;
  428. if (area.getBorderTopWidth() != 0) {
  429. borderColor = bp.getBorderColor(BorderAndPadding.TOP);
  430. // addLine(rx, ry, rx + w, ry, area.getBorderTopWidth(), // corrected aml/rlc
  431. addLine(rx, ry, rx + w, ry, -area.getBorderTopWidth(),
  432. borderColor.red(), borderColor.green(),
  433. borderColor.blue());
  434. }
  435. if (area.getBorderLeftWidth() != 0) {
  436. borderColor = bp.getBorderColor(BorderAndPadding.LEFT);
  437. addLine(rx, ry, rx, ry - h, area.getBorderLeftWidth(),
  438. borderColor.red(), borderColor.green(),
  439. borderColor.blue());
  440. }
  441. if (area.getBorderRightWidth() != 0) {
  442. borderColor = bp.getBorderColor(BorderAndPadding.RIGHT);
  443. addLine(rx + w, ry, rx + w, ry - h,
  444. // area.getBorderRightWidth(), borderColor.red(), // corrected aml/rlc
  445. -area.getBorderRightWidth(), borderColor.red(),
  446. borderColor.green(),
  447. borderColor.blue());
  448. }
  449. if (area.getBorderBottomWidth() != 0) {
  450. borderColor = bp.getBorderColor(BorderAndPadding.BOTTOM);
  451. addLine(rx, ry - h, rx + w, ry - h, area.getBorderBottomWidth(),
  452. borderColor.red(), borderColor.green(),
  453. borderColor.blue());
  454. }
  455. }
  456. protected Rectangle2D getBounds(org.apache.fop.layout.Area a) {
  457. return new Rectangle2D.Double(currentAreaContainerXPosition,
  458. currentYPosition,
  459. a.getAllocationWidth(), a.getHeight());
  460. }
  461. /*
  462. * public void renderBlockArea(BlockArea area) {
  463. * doFrame(area);
  464. * Enumeration e = area.getChildren().elements();
  465. * while (e.hasMoreElements()) {
  466. * org.apache.fop.layout.Box b =
  467. * (org.apache.fop.layout.Box) e.nextElement();
  468. * b.render(this);
  469. * }
  470. * }
  471. */
  472. public void renderBlockArea(BlockArea area) {
  473. this.currentYPosition -= (area.getPaddingTop()
  474. + area.getBorderTopWidth());
  475. doFrame(area);
  476. Enumeration e = area.getChildren().elements();
  477. while (e.hasMoreElements()) {
  478. org.apache.fop.layout.Box b =
  479. (org.apache.fop.layout.Box)e.nextElement();
  480. b.render(this);
  481. }
  482. this.currentYPosition -= (area.getPaddingBottom()
  483. + area.getBorderBottomWidth());
  484. }
  485. public void setupFontInfo(FontInfo fontInfo) {
  486. // create a temp Image to test font metrics on
  487. BufferedImage fontImage =
  488. new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
  489. FontSetup.setup(fontInfo, fontImage.createGraphics());
  490. }
  491. public void renderDisplaySpace(DisplaySpace space) {
  492. int d = space.getSize();
  493. this.currentYPosition -= d;
  494. }
  495. // correct integer roundoff (aml/rlc)
  496. public void renderImageArea(ImageArea area) {
  497. int x = currentAreaContainerXPosition + area.getXOffset();
  498. int y = currentYPosition;
  499. int w = area.getContentWidth();
  500. int h = area.getHeight();
  501. FopImage img = area.getImage();
  502. if (img == null) {
  503. log.error("Error while loading image : area.getImage() is null");
  504. // correct integer roundoff
  505. // graphics.drawRect(x / 1000, pageHeight - y / 1000,
  506. // w / 1000, h / 1000);
  507. addRect(x, y, w, h, true); // use helper function
  508. java.awt.Font f = graphics.getFont();
  509. java.awt.Font smallFont = new java.awt.Font(f.getFontName(),
  510. f.getStyle(), 8);
  511. graphics.setFont(smallFont);
  512. // correct integer roundoff // aml/rlc
  513. // graphics.drawString("area.getImage() is null", x / 1000,
  514. // pageHeight - y / 1000);
  515. graphics.drawString("area.getImage() is null", (x + 500) / 1000,
  516. pageHeight - (y + 500) / 1000);
  517. graphics.setFont(f);
  518. } else {
  519. if (img instanceof SVGImage) {
  520. try {
  521. SVGDocument svg = ((SVGImage)img).getSVGDocument();
  522. renderSVGDocument(svg, (int)x, (int)y);
  523. } catch (FopImageException e) {}
  524. } else {
  525. String urlString = img.getURL();
  526. try {
  527. URL url = new URL(urlString);
  528. ImageIcon icon = new ImageIcon(url);
  529. Image image = icon.getImage();
  530. // correct integer roundoff aml/rlc
  531. // graphics.drawImage(image, x / 1000,
  532. // pageHeight - y / 1000, w / 1000, h / 1000,
  533. // null);
  534. int startx = (x + 500) / 1000;
  535. int starty = pageHeight - ((y + 500) / 1000);
  536. int endx = (x + w + 500) / 1000;
  537. int endy = pageHeight - ((y + h + 500) / 1000);
  538. // reverse start and end y because h is positive
  539. graphics.drawImage(image, startx, starty, endx - startx,
  540. starty - endy, null);
  541. } catch (MalformedURLException mue) {
  542. // cannot normally occur because, if URL is wrong, constructing FopImage
  543. // will already have failed earlier on
  544. }
  545. }
  546. }
  547. currentYPosition -= h;
  548. }
  549. public void renderWordArea(WordArea area) {
  550. char ch;
  551. StringBuffer pdf = new StringBuffer();
  552. String name = area.getFontState().getFontName();
  553. int size = area.getFontState().getFontSize();
  554. boolean underlined = area.getUnderlined();
  555. float red = area.getRed();
  556. float green = area.getGreen();
  557. float blue = area.getBlue();
  558. FontMetricsMapper mapper;
  559. try {
  560. mapper =
  561. (FontMetricsMapper)area.getFontState().getFontInfo().getMetricsFor(name);
  562. } catch (FOPException iox) {
  563. mapper = new FontMetricsMapper("MonoSpaced", java.awt.Font.PLAIN,
  564. graphics);
  565. }
  566. if ((!name.equals(this.currentFontName))
  567. || (size != this.currentFontSize)) {
  568. this.currentFontName = name;
  569. this.currentFontSize = size;
  570. }
  571. if ((red != this.currentRed) || (green != this.currentGreen)
  572. || (blue != this.currentBlue)) {
  573. this.currentRed = red;
  574. this.currentGreen = green;
  575. this.currentBlue = blue;
  576. }
  577. int rx = this.currentXPosition;
  578. int bl = this.currentYPosition;
  579. String s; // = area.getText();
  580. if (area.getPageNumberID()
  581. != null) { // this text is a page number, so resolve it
  582. s = idReferences.getPageNumber(area.getPageNumberID());
  583. if (s == null) {
  584. s = "";
  585. }
  586. } else {
  587. s = area.getText();
  588. }
  589. Color oldColor = graphics.getColor();
  590. java.awt.Font oldFont = graphics.getFont();
  591. java.awt.Font f = mapper.getFont(size);
  592. if (saveColor != null) {
  593. if (saveColor.getRed() != red || saveColor.getGreen() != green
  594. || saveColor.getBlue() != blue) {
  595. saveColor = new Color(red, green, blue);
  596. }
  597. } else {
  598. saveColor = new Color(red, green, blue);
  599. }
  600. graphics.setColor(saveColor);
  601. AttributedString ats = new AttributedString(s);
  602. ats.addAttribute(TextAttribute.FONT, f);
  603. if (underlined) {
  604. ats.addAttribute(TextAttribute.UNDERLINE,
  605. TextAttribute.UNDERLINE_ON);
  606. }
  607. AttributedCharacterIterator iter = ats.getIterator();
  608. // correct integer roundoff
  609. // graphics.drawString(iter, rx / 1000f,
  610. // (int)(pageHeight - bl / 1000f));
  611. graphics.drawString(iter, (rx + 500) / 1000,
  612. (int)(pageHeight - (bl + 500) / 1000));
  613. graphics.setColor(oldColor);
  614. this.currentXPosition += area.getContentWidth();
  615. }
  616. public void renderInlineSpace(InlineSpace space) {
  617. this.currentXPosition += space.getSize();
  618. }
  619. public void renderLineArea(LineArea area) {
  620. int rx = this.currentAreaContainerXPosition + area.getStartIndent();
  621. int ry = this.currentYPosition;
  622. int w = area.getContentWidth();
  623. int h = area.getHeight();
  624. this.currentYPosition -= area.getPlacementOffset();
  625. this.currentXPosition = rx;
  626. int bl = this.currentYPosition;
  627. Enumeration e = area.getChildren().elements();
  628. while (e.hasMoreElements()) {
  629. org.apache.fop.layout.Box b =
  630. (org.apache.fop.layout.Box)e.nextElement();
  631. if (b instanceof InlineArea) {
  632. InlineArea ia = (InlineArea)b;
  633. this.currentYPosition = ry - ia.getYOffset();
  634. } else {
  635. this.currentYPosition = ry - area.getPlacementOffset();
  636. }
  637. b.render(this);
  638. }
  639. this.currentYPosition = ry - h;
  640. }
  641. /**
  642. * render leader area into AWT
  643. *
  644. * @param area area to render
  645. */
  646. // call to addRect corrected by aml/rlc
  647. public void renderLeaderArea(LeaderArea area) {
  648. int rx = this.currentXPosition;
  649. int ry = this.currentYPosition;
  650. int w = area.getLeaderLength();
  651. int h = area.getHeight();
  652. int th = area.getRuleThickness();
  653. int st = area.getRuleStyle(); // not used at the moment
  654. float r = area.getRed();
  655. float g = area.getGreen();
  656. float b = area.getBlue();
  657. Color oldColor = graphics.getColor();
  658. graphics.setColor(new Color(r, g, b));
  659. // use helper function to correct integer roundoff - aml/rlc
  660. // graphics.fillRect((int)(rx / 1000f),
  661. // (int)(pageHeight - ry / 1000f), (int)(w / 1000f),
  662. // (int)(th / 1000f));
  663. addRect(rx, ry, w, -th, false); // NB addRect expects negative height
  664. graphics.setColor(oldColor);
  665. this.currentXPosition += area.getContentWidth();
  666. }
  667. public void renderSVGArea(SVGArea area) {
  668. int x = this.currentXPosition;
  669. int y = this.currentYPosition;
  670. int w = area.getContentWidth();
  671. int h = area.getHeight();
  672. Document doc = area.getSVGDocument();
  673. renderSVGDocument(doc, x, y);
  674. this.currentXPosition += area.getContentWidth();
  675. }
  676. protected void renderSVGDocument(Document doc, int x, int y) {
  677. UserAgent userAgent = new MUserAgent(new AffineTransform());
  678. GVTBuilder builder = new GVTBuilder();
  679. GraphicsNodeRenderContext rc = getRenderContext();
  680. BridgeContext ctx = new BridgeContext(userAgent, rc);
  681. GraphicsNode root;
  682. // correct integer roundoff aml/rlc
  683. // graphics.translate(x / 1000f, pageHeight - y / 1000f);
  684. graphics.translate((x + 500) / 1000, pageHeight - (y + 500) / 1000);
  685. graphics.setRenderingHints(rc.getRenderingHints());
  686. try {
  687. root = builder.build(ctx, doc);
  688. root.paint(graphics, rc);
  689. } catch (Exception e) {
  690. e.printStackTrace();
  691. }
  692. // correct integer roundoff aml/rlc
  693. // graphics.translate(-x / 1000f, y / 1000f - pageHeight);
  694. graphics.translate(-(x + 500) / 1000, (y + 500) / 1000 - pageHeight);
  695. }
  696. public GraphicsNodeRenderContext getRenderContext() {
  697. GraphicsNodeRenderContext nodeRenderContext = null;
  698. if (nodeRenderContext == null) {
  699. RenderingHints hints = new RenderingHints(null);
  700. hints.put(RenderingHints.KEY_ANTIALIASING,
  701. RenderingHints.VALUE_ANTIALIAS_ON);
  702. hints.put(RenderingHints.KEY_INTERPOLATION,
  703. RenderingHints.VALUE_INTERPOLATION_BILINEAR);
  704. FontRenderContext fontRenderContext =
  705. new FontRenderContext(new AffineTransform(), true, true);
  706. TextPainter textPainter = new StrokingTextPainter();
  707. GraphicsNodeRableFactory gnrFactory =
  708. new ConcreteGraphicsNodeRableFactory();
  709. nodeRenderContext =
  710. new GraphicsNodeRenderContext(new AffineTransform(), null,
  711. hints, fontRenderContext,
  712. textPainter, gnrFactory);
  713. }
  714. return nodeRenderContext;
  715. }
  716. public void setProducer(String producer) {
  717. // defined in Renderer Interface
  718. }
  719. public int print(Graphics g, PageFormat pageFormat,
  720. int pageIndex) throws PrinterException {
  721. if (pageIndex >= pageList.size())
  722. return NO_SUCH_PAGE;
  723. Graphics2D oldGraphics = graphics;
  724. int oldPageNumber = pageNumber;
  725. graphics = (Graphics2D)g;
  726. Page aPage = (Page)pageList.elementAt(pageIndex);
  727. renderPage(aPage);
  728. graphics = oldGraphics;
  729. return PAGE_EXISTS;
  730. }
  731. public int getNumberOfPages() {
  732. return pageList.size();
  733. }
  734. public PageFormat getPageFormat(int pageIndex)
  735. throws IndexOutOfBoundsException {
  736. if (pageIndex >= pageList.size())
  737. return null;
  738. Page page = (Page)pageList.elementAt(pageIndex);
  739. PageFormat pageFormat = new PageFormat();
  740. Paper paper = new Paper();
  741. double width = page.getWidth();
  742. double height = page.getHeight();
  743. // if the width is greater than the height assume lanscape mode
  744. // and swap the width and height values in the paper format
  745. if (width > height) {
  746. paper.setImageableArea(0, 0, height / 1000d, width / 1000d);
  747. paper.setSize(height / 1000d, width / 1000d);
  748. pageFormat.setOrientation(PageFormat.LANDSCAPE);
  749. } else {
  750. paper.setImageableArea(0, 0, width / 1000d, height / 1000d);
  751. paper.setSize(width / 1000d, height / 1000d);
  752. pageFormat.setOrientation(PageFormat.PORTRAIT);
  753. }
  754. pageFormat.setPaper(paper);
  755. return pageFormat;
  756. }
  757. public Printable getPrintable(int pageIndex)
  758. throws IndexOutOfBoundsException {
  759. return this;
  760. }
  761. public void setProgressListener(ProgressListener l) {
  762. progressListener = l;
  763. }
  764. public static Color colorType2Color(ColorType ct) {
  765. if (ct == null) {
  766. return null;
  767. }
  768. return new Color(ct.red(), ct.green(), ct.blue());
  769. }
  770. /**
  771. * Draws an image.
  772. * TODO: protect other image formats (JIMI)
  773. */
  774. /*
  775. * public void renderImage(String href, float x, float y, float width,
  776. * float height, Vector transform) {
  777. * // What is with transformations?
  778. * try {
  779. * URL url = new URL(href);
  780. * ImageIcon imageIcon = new ImageIcon(url);
  781. * AffineTransform fullTransform = new AffineTransform();
  782. * AffineTransform aTransform;
  783. * transform = (transform == null) ? new Vector() : transform;
  784. * for (int i = 0; i < transform.size(); i++) {
  785. * org.w3c.dom.svg.SVGTransform t =
  786. * (org.w3c.dom.svg.SVGTransform)
  787. * transform.elementAt(i);
  788. * SVGMatrix matrix = t.getMatrix();
  789. * aTransform = new AffineTransform(matrix.getA(),
  790. * matrix.getB(), matrix.getC(), matrix.getD(),
  791. * matrix.getE(), matrix.getF());
  792. * fullTransform.concatenate(aTransform);
  793. * }
  794. * BufferedImage bi = new BufferedImage((int) width, (int) height,
  795. * BufferedImage.TYPE_INT_RGB);
  796. * Graphics2D g2d = bi.createGraphics();
  797. * BufferedImageOp bop = new AffineTransformOp(fullTransform,
  798. * AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
  799. * g2d.drawImage(imageIcon.getImage(), 0, 0, (int) width,
  800. * (int) height, imageIcon.getImageObserver());
  801. * graphics.drawImage(bi, bop, (int) x, (int) y);
  802. * } catch (Exception ex) {
  803. * log.error("AWTRenderer: renderImage(): " +
  804. * ex.getMessage(), ex);
  805. * }
  806. * }
  807. */
  808. public void renderForeignObjectArea(ForeignObjectArea area) {
  809. area.getObject().render(this);
  810. }
  811. protected class MUserAgent implements UserAgent {
  812. AffineTransform currentTransform = null;
  813. /**
  814. * Creates a new SVGUserAgent.
  815. */
  816. protected MUserAgent(AffineTransform at) {
  817. currentTransform = at;
  818. }
  819. /**
  820. * Displays an error message.
  821. */
  822. public void displayError(String message) {
  823. System.err.println(message);
  824. }
  825. /**
  826. * Displays an error resulting from the specified Exception.
  827. */
  828. public void displayError(Exception ex) {
  829. ex.printStackTrace(System.err);
  830. }
  831. /**
  832. * Displays a message in the User Agent interface.
  833. * The given message is typically displayed in a status bar.
  834. */
  835. public void displayMessage(String message) {
  836. System.out.println(message);
  837. }
  838. /**
  839. * Returns a customized the pixel to mm factor.
  840. */
  841. public float getPixelToMM() {
  842. // this is set to 72dpi as the values in fo are 72dpi
  843. return 0.35277777777777777778f; // 72 dpi
  844. // return 0.26458333333333333333333333333333f; // 96dpi
  845. }
  846. /**
  847. * Returns the language settings.
  848. */
  849. public String getLanguages() {
  850. return "en"; // userLanguages;
  851. }
  852. /**
  853. * Returns the user stylesheet uri.
  854. * @return null if no user style sheet was specified.
  855. */
  856. public String getUserStyleSheetURI() {
  857. return null; // userStyleSheetURI;
  858. }
  859. /**
  860. * Returns the class name of the XML parser.
  861. */
  862. public String getXMLParserClassName() {
  863. return Driver.getParserClassName();
  864. }
  865. /**
  866. * Opens a link in a new component.
  867. * @param doc The current document.
  868. * @param uri The document URI.
  869. */
  870. public void openLink(SVGAElement elt) {
  871. // application.openLink(uri);
  872. }
  873. public Point getClientAreaLocationOnScreen() {
  874. return new Point(0, 0);
  875. }
  876. public void setSVGCursor(java.awt.Cursor cursor) {}
  877. public AffineTransform getTransform() {
  878. return currentTransform;
  879. }
  880. public Dimension2D getViewportSize() {
  881. return new Dimension(100, 100);
  882. }
  883. public EventDispatcher getEventDispatcher() {
  884. return null;
  885. }
  886. public boolean supportExtension(String str) {
  887. return false;
  888. }
  889. public boolean hasFeature(String str) {
  890. return false;
  891. }
  892. public void registerExtension(BridgeExtension be) {}
  893. public void handleElement(Element elt, Object data) {}
  894. }
  895. public void startRenderer(OutputStream outputStream)
  896. throws IOException {}
  897. public void stopRenderer(OutputStream outputStream)
  898. throws IOException {
  899. render(0);
  900. }
  901. }