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.

TXTRenderer.java 59KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735
  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 com.eastpoint.chrysalis;
  8. package org.apache.fop.render.txt;
  9. // FOP
  10. import org.apache.fop.render.PrintRenderer;
  11. import org.apache.fop.render.pcl.*;
  12. import org.apache.fop.apps.FOPException;
  13. import org.apache.fop.fo.properties.*;
  14. import org.apache.fop.image.FopImage;
  15. import org.apache.fop.image.FopImageException;
  16. import org.apache.fop.layout.*;
  17. import org.apache.fop.layout.inline.*;
  18. import org.apache.fop.datatypes.*;
  19. import org.apache.fop.pdf.PDFPathPaint;
  20. import org.apache.fop.pdf.PDFColor;
  21. import org.apache.fop.image.*;
  22. import org.apache.fop.svg.SVGArea;
  23. import org.w3c.dom.svg.SVGSVGElement;
  24. import org.w3c.dom.svg.SVGDocument;
  25. // Java
  26. import java.io.IOException;
  27. import java.io.OutputStream;
  28. import java.util.ArrayList;
  29. /**
  30. * Renderer that renders areas to plain text.
  31. *
  32. * @author unascribed
  33. * @author <a href="mailto:mark-fop@inomial.com">Mark Lillywhite</a> (to use
  34. * the new Renderer interface)
  35. */
  36. public class TXTRenderer extends PrintRenderer {
  37. /**
  38. * the current stream to add Text commands to
  39. */
  40. TXTStream currentStream;
  41. public static final String encodingOptionName = "txt.encoding";
  42. private int pageHeight = 7920;
  43. // These variables control the virtual paggination functionality.
  44. public int curdiv = 0;
  45. private int divisions = -1;
  46. private int paperheight = -1; // Paper height in decipoints?
  47. public int orientation =
  48. -1; // -1=default/unknown, 0=portrait, 1=landscape.
  49. public int topmargin = -1; // Top margin in decipoints?
  50. public int leftmargin = -1; // Left margin in decipoints?
  51. private int fullmargin = 0;
  52. final boolean debug = false;
  53. // Variables for rendering text.
  54. StringBuffer charData[];
  55. StringBuffer decoData[];
  56. public float textCPI = 16.67f;
  57. public float textLPI = 8;
  58. int maxX = (int)(8.5f * textCPI + 1);
  59. int maxY = (int)(11f * textLPI + 1);
  60. float xFactor;
  61. float yFactor;
  62. public String lineEnding =
  63. "\r\n"; // Every line except the last line on a page (which will end with pageEnding) will be terminated with this string.
  64. public String pageEnding =
  65. "\f"; // Every page except the last one will end with this string.
  66. public boolean suppressGraphics =
  67. false; // If true then graphics/decorations will not be rendered - text only.
  68. boolean firstPage = false;
  69. /**
  70. * options
  71. */
  72. protected java.util.HashMap options;
  73. public TXTRenderer() {}
  74. /**
  75. * set up renderer options
  76. */
  77. public void setOptions(java.util.HashMap options) {
  78. this.options = options;
  79. }
  80. /**
  81. * set the TXT document's producer
  82. *
  83. * @param producer string indicating application producing PDF
  84. */
  85. public void setProducer(String producer) {}
  86. void addStr(int row, int col, String str, boolean ischar) {
  87. if (debug)
  88. System.out.println("TXTRenderer.addStr(" + row + ", " + col
  89. + ", \"" + str + "\", " + ischar + ")");
  90. if (suppressGraphics &&!ischar)
  91. return;
  92. StringBuffer sb;
  93. if (row < 0)
  94. row = 0;
  95. if (ischar)
  96. sb = charData[row];
  97. else
  98. sb = decoData[row];
  99. if (sb == null)
  100. sb = new StringBuffer();
  101. if ((col + str.length()) > maxX)
  102. col = maxX - str.length();
  103. if (col < 0) {
  104. col = 0;
  105. if (str.length() > maxX)
  106. str = str.substring(0, maxX);
  107. }
  108. // Pad to col
  109. for (int countr = sb.length(); countr < col; countr++)
  110. sb.append(' ');
  111. if (debug)
  112. System.out.println("TXTRenderer.addStr() sb.length()="
  113. + sb.length());
  114. for (int countr = col; countr < (col + str.length()); countr++) {
  115. if (countr >= sb.length())
  116. sb.append(str.charAt(countr - col));
  117. else {
  118. if (debug)
  119. System.out.println("TXTRenderer.addStr() sb.length()="
  120. + sb.length() + " countr=" + countr);
  121. sb.setCharAt(countr, str.charAt(countr - col));
  122. }
  123. }
  124. if (ischar)
  125. charData[row] = sb;
  126. else
  127. decoData[row] = sb;
  128. }
  129. /**
  130. * add a line to the current stream
  131. *
  132. * @param x1 the start x location in millipoints
  133. * @param y1 the start y location in millipoints
  134. * @param x2 the end x location in millipoints
  135. * @param y2 the end y location in millipoints
  136. * @param th the thickness in millipoints
  137. * @param stroke the line color
  138. */
  139. protected void addLine(int x1, int y1, int x2, int y2, int th,
  140. PDFPathPaint stroke) {
  141. if (x1 == x2) {
  142. addRect(x1, y1, th, y2 - y1 + 1, stroke, stroke);
  143. } else if (y1 == y2) {
  144. addRect(x1, y1, x2 - x1 + 1, th, stroke, stroke);
  145. }
  146. }
  147. /**
  148. * add a line to the current stream
  149. *
  150. * @param x1 the start x location in millipoints
  151. * @param y1 the start y location in millipoints
  152. * @param x2 the end x location in millipoints
  153. * @param y2 the end y location in millipoints
  154. * @param th the thickness in millipoints
  155. * @param rs the rule style
  156. * @param stroke the line color
  157. */
  158. protected void addLine(int x1, int y1, int x2, int y2, int th, int rs,
  159. PDFPathPaint stroke) {
  160. PDFColor lstroke = null;
  161. if (rs == org.apache.fop.fo.properties.RuleStyle.DOTTED)
  162. lstroke = new PDFColor(0.7f, 0.7f, 0.7f);
  163. else
  164. lstroke = (PDFColor)stroke;
  165. if (x1 == x2) {
  166. addRect(x1, y1, th, y2 - y1 + 1, lstroke, lstroke);
  167. } else if (y1 == y2) {
  168. addRect(x1, y1, x2 - x1 + 1, th, lstroke, lstroke);
  169. }
  170. }
  171. protected void addLine(float x1, float y1, float x2, float y2,
  172. PDFColor sc, float sw) {
  173. /*
  174. * SVG - Not yet implemented
  175. * if ( debug )
  176. * System.out.println("TXTRenderer.addLine(" + x1 + ", " + y1 + ", " + x2 + ", " + y2 + ", " + sc + ", " + sw + ")");
  177. * if ( x1 == x2 )
  178. * {
  179. * addRect(x1 - sw/2, y1, sw, y2 - y1 + 1, 0, 0, sc, null, 0);
  180. * }
  181. * else if ( y1 == y2 || (Math.abs(y1 - y2) <= 0.24) ) // 72/300=0.24
  182. * {
  183. * addRect(x1, y1 - sw/2, x2 - x1 + 1, sw, 0, 0, sc, null, 0);
  184. * }
  185. * else if ( sc != null )
  186. * {
  187. * // Convert dimensions to characters.
  188. * //float cfact = 300f / 72f; // 300 dpi, 1pt=1/72in
  189. * int ix1 = (int)(x1 * xFactor);
  190. * int iy1 = (int)(y1 * yFactor);
  191. * int ix2 = (int)(x2 * xFactor);
  192. * int iy2 = (int)(y2 * yFactor);
  193. * int isw = (int)(sw * xFactor);
  194. * int origix;
  195. * // Normalize
  196. * if ( iy1 > iy2 )
  197. * {
  198. * int tmp = ix1;
  199. * ix1 = ix2;
  200. * ix2 = tmp;
  201. * tmp = iy1;
  202. * iy1 = iy2;
  203. * iy2 = tmp;
  204. * }
  205. * if ( ix1 > ix2 )
  206. * {
  207. * origix = ix2;
  208. * ix1 -=ix2;
  209. * ix2 = 0;
  210. * }
  211. * else
  212. * {
  213. * origix = ix1;
  214. * ix2 -= ix1;
  215. * ix1 = 0;
  216. * }
  217. * // Convert line width to a pixel run length.
  218. * //System.out.println("TXTRenderer.addLine(" + ix1 + ", " + iy1 + ", " + ix2 + ", " + iy2 + ", " + isw + ")");
  219. * int runlen = (int)Math.sqrt(Math.pow(isw, 2) * (1 + Math.pow((ix1 - ix2) / (iy1 - iy2), 2)));
  220. * if ( runlen < 1 )
  221. * runlen = 1;
  222. * StringBuffer rlbuff = new StringBuffer();
  223. * for ( int countr = 0 ; countr < runlen ; countr++ )
  224. * rlbuff.append('*');
  225. * String rlstr = rlbuff.toString();
  226. * //System.out.println("TXTRenderer.addLine: runlen = " + runlen);
  227. * // Draw the line.
  228. * int d, dx, dy;
  229. * int Aincr, Bincr;
  230. * int xincr = 1;
  231. * int x, y;
  232. * dx = Math.abs(ix2 - ix1);
  233. * dy = iy2 - iy1;
  234. * if ( dx > dy )
  235. * {
  236. * xincr = dx / dy;
  237. * // Move to starting position.
  238. * //currentStream.add("\033*p" + origix + "x" + iy1 + "Y");
  239. * x = ix1 - runlen / 2;
  240. * iy2 += (isw / 2);
  241. * // Start raster graphics
  242. * //currentStream.add("\033*t300R\033*r" + dx + "s1A\033*b1M");
  243. * }
  244. * else
  245. * {
  246. * // Move to starting position.
  247. * //currentStream.add("\033*p" + (origix - runlen / 2) + "x" + iy1 + "Y");
  248. * x = ix1;
  249. * // Start raster graphics
  250. * //currentStream.add("\033*t300R\033*r1A\033*b1M");
  251. * }
  252. * if ( ix1 > ix2 )
  253. * xincr *= -1;
  254. * d = 2 * dx - dy;
  255. * Aincr = 2 * (dx - dy);
  256. * Bincr = 2 * dx;
  257. * y = iy1;
  258. * xferLineBytes(x, runlen, null, -1);
  259. *
  260. * for ( y = iy1 + 1 ; y <= iy2 ; y++ )
  261. * {
  262. * if ( d >= 0 )
  263. * {
  264. * x += xincr;
  265. * d += Aincr;
  266. * }
  267. * else
  268. * d += Bincr;
  269. * xferLineBytes(x, runlen, null, -1);
  270. * }
  271. * // End raster graphics
  272. * //currentStream.add("\033*rB");
  273. * // Return to regular print mode.
  274. * //currentStream.add("\033*v0t0n0O");
  275. * }
  276. */
  277. }
  278. private void xferLineBytes(int startpos, int bitcount, ArrayList save,
  279. int start2) {
  280. /*
  281. * Not yet implemented
  282. * //System.out.println("TXTRenderer.xferLineBytes(" + startpos + ", " + bitcount + ")");
  283. * int curbitpos = 0;
  284. * if ( start2 > 0 && start2 <= (startpos + bitcount) )
  285. * {
  286. * bitcount += (start2 - startpos);
  287. * start2 = 0;
  288. * }
  289. * char bytes[] = new char[((start2>startpos?start2:startpos) + bitcount) / 4 + 2];
  290. * int dlen = 0;
  291. * byte dbyte = 0;
  292. * int bytepos = 0;
  293. * do
  294. * {
  295. * int bits2set;
  296. * if ( startpos < 0 )
  297. * {
  298. * bits2set = bitcount + startpos;
  299. * startpos = 0;
  300. * }
  301. * else
  302. * bits2set = bitcount;
  303. * byte bittype = 0;
  304. * do
  305. * {
  306. * if ( bytepos > 0 )
  307. * {
  308. * int inc = startpos - curbitpos;
  309. * if ( (inc) >= (8 - bytepos) )
  310. * {
  311. * curbitpos += (8 - bytepos);
  312. * bytepos = 0;
  313. * bytes[dlen++] = (char)0;
  314. * bytes[dlen++] = (char)dbyte;
  315. * dbyte = 0;
  316. * }
  317. * else
  318. * {
  319. * bytepos += inc;
  320. * dbyte = (byte)(dbyte ^ (byte)(Math.pow(2, 8 - bytepos) - 1));
  321. * curbitpos += inc;
  322. * }
  323. * }
  324. * // Set runs of whole bytes.
  325. * int setbytes = (startpos - curbitpos) / 8;
  326. * if ( setbytes > 0 )
  327. * {
  328. * curbitpos += setbytes * 8;
  329. * while ( setbytes > 0 )
  330. * {
  331. * if ( setbytes > 256 )
  332. * {
  333. * bytes[dlen++] = 0xFF;
  334. * setbytes -= 256;
  335. * }
  336. * else
  337. * {
  338. * bytes[dlen++] = (char)((setbytes - 1) & 0xFF);
  339. * setbytes = 0;
  340. * }
  341. * bytes[dlen++] = (char)bittype;
  342. * }
  343. * }
  344. * // move to position in the first byte.
  345. * if ( curbitpos < startpos )
  346. * {
  347. * if ( bytepos == 0 )
  348. * dbyte = bittype;
  349. * bytepos += startpos - curbitpos;
  350. * dbyte = (byte)(dbyte ^ (byte)(Math.pow(2, 8 - bytepos) - 1));
  351. * curbitpos += bytepos;
  352. * startpos += bits2set;
  353. * }
  354. * else
  355. * {
  356. * startpos += bits2set;
  357. * }
  358. * if ( bittype == 0 )
  359. * bittype = (byte)0xFF;
  360. * else
  361. * bittype = 7;
  362. * } while ( bittype != 7 );
  363. * if ( start2 > 0 )
  364. * {
  365. * startpos = start2;
  366. * start2 = -1;
  367. * }
  368. * else
  369. * startpos = -1;
  370. * } while ( startpos >= 0 );
  371. * if ( bytepos > 0 )
  372. * {
  373. * bytes[dlen++] = (char)0;
  374. * bytes[dlen++] = (char)dbyte;
  375. * }
  376. * if ( save == null )
  377. * {
  378. * //currentStream.add("\033*b" + dlen + "W");
  379. * //currentStream.add(new String(bytes, 0, dlen));
  380. * }
  381. * else
  382. * {
  383. * String line = "\033*b" + dlen + "W" + new String(bytes, 0, dlen);
  384. * //currentStream.add(line);
  385. * save.add(line);
  386. * }
  387. */
  388. }
  389. /**
  390. * add a rectangle to the current stream
  391. *
  392. * @param x the x position of left edge in millipoints
  393. * @param y the y position of top edge in millipoints
  394. * @param w the width in millipoints
  395. * @param h the height in millipoints
  396. * @param stroke the stroke color/gradient
  397. */
  398. protected void addRect(int x, int y, int w, int h, PDFPathPaint stroke) {
  399. if (h < 0)
  400. h *= -1;
  401. if (h < 720 || w < 720) {
  402. if (w < 720)
  403. w = 720;
  404. if (h < 720)
  405. h = 720;
  406. addRect(x, y, w, h, stroke, stroke);
  407. } else {
  408. addRect(x, y, w, 720, stroke, stroke);
  409. addRect(x, y, 720, h, stroke, stroke);
  410. addRect(x + w - 720, y, 720, h, stroke, stroke);
  411. addRect(x, y - h + 720, w, 720, stroke, stroke);
  412. }
  413. }
  414. /**
  415. * add a filled rectangle to the current stream
  416. *
  417. * @param x the x position of left edge in millipoints
  418. * @param y the y position of top edge in millipoints
  419. * @param w the width in millipoints
  420. * @param h the height in millipoints
  421. * @param fill the fill color/gradient
  422. * @param stroke the stroke color/gradient
  423. */
  424. protected void addRect(int x, int y, int w, int h, PDFPathPaint stroke,
  425. PDFPathPaint fill) {
  426. // System.out.println("TXTRenderer.addRect(" + x + ", " + y + ", " + w + ", " + h + ", " + r + ", " + g + ", " + b + ", " + fr + ", " + fg + ", " + fb + ")");
  427. if ((w == 0) || (h == 0))
  428. return;
  429. if (h < 0)
  430. h *= -1;
  431. int row = (int)((pageHeight - (y / 100)) * 100 * yFactor);
  432. int col = (int)(x * xFactor);
  433. PDFColor sc = (PDFColor)stroke;
  434. PDFColor fc = (PDFColor)fill;
  435. sc.setColorSpace(ColorSpace.DEVICE_RGB);
  436. fc.setColorSpace(ColorSpace.DEVICE_RGB);
  437. int lineshade =
  438. (int)(100
  439. - ((0.3f * sc.red() + 0.59f * sc.green() + 0.11f * sc.blue())
  440. * 100f));
  441. int fillshade =
  442. (int)(100
  443. - ((0.3f * fc.red() + 0.59f * fc.green() + 0.11f * fc.blue())
  444. * 100f));
  445. if (debug)
  446. System.out.println("TXTRenderer.addRect(" + x + ", " + y + ", "
  447. + w + ", " + h + ", " + stroke + ", " + fill
  448. + ") fillshade=" + fillshade);
  449. char fillchar = ' ';
  450. if (fillshade >= 75)
  451. fillchar = '#';
  452. else if (fillshade >= 50)
  453. fillchar = '*';
  454. else if (fillshade >= 25)
  455. fillchar = ':';
  456. if (fillchar != ' ') {
  457. StringBuffer linefill = new StringBuffer();
  458. int sw = (int)(w * xFactor);
  459. int sh = (int)(h * yFactor);
  460. if (sw == 0 || sh == 0) {
  461. if (fillshade >= 50) {
  462. if (h > w)
  463. fillchar = '|';
  464. else
  465. fillchar = '-';
  466. } else {
  467. if (h > w)
  468. fillchar = ':';
  469. else
  470. fillchar = '.';
  471. }
  472. }
  473. if (sw == 0)
  474. linefill.append(fillchar);
  475. else
  476. for (int countr = 0; countr < sw; countr++)
  477. linefill.append(fillchar);
  478. if (sh == 0)
  479. addStr(row, col, linefill.toString(), false);
  480. else
  481. for (int countr = 0; countr < sh; countr++)
  482. addStr(row + countr, col, linefill.toString(), false);
  483. }
  484. if (lineshade >= 25) {
  485. char vlinechar = '|';
  486. char hlinechar = '-';
  487. if (lineshade < 50) {
  488. vlinechar = ':';
  489. hlinechar = '.';
  490. }
  491. StringBuffer linefill = new StringBuffer();
  492. int sw = (int)(w * xFactor);
  493. for (int countr = 0; countr < sw; countr++)
  494. linefill.append(hlinechar);
  495. int sh = (int)(h * yFactor);
  496. if (w > h) {
  497. for (int countr = 1; countr < (sh - 1); countr++) {
  498. addStr(row + countr, col, String.valueOf(vlinechar),
  499. false);
  500. addStr(row + countr, col + sw, String.valueOf(vlinechar),
  501. false);
  502. }
  503. addStr(row, col, linefill.toString(), false);
  504. addStr(row + sh, col, linefill.toString(), false);
  505. } else {
  506. addStr(row, col, linefill.toString(), false);
  507. addStr(row + sh, col, linefill.toString(), false);
  508. for (int countr = 1; countr < (sh - 1); countr++) {
  509. addStr(row + countr, col, String.valueOf(vlinechar),
  510. false);
  511. addStr(row + countr, col + sw, String.valueOf(vlinechar),
  512. false);
  513. }
  514. }
  515. }
  516. }
  517. /**
  518. * add a filled rectangle to the current stream
  519. *
  520. * @param x the x position of left edge in millipoints
  521. * @param y the y position of top edge in millipoints
  522. * @param w the width in millipoints
  523. * @param h the height in millipoints
  524. * @param r the red component of edges
  525. * @param g the green component of edges
  526. * @param b the blue component of edges
  527. * @param fr the red component of the fill
  528. * @param fg the green component of the fill
  529. * @param fb the blue component of the fill
  530. */
  531. protected void addRect(float x, float y, float w, float h, float rx,
  532. float ry, PDFColor fc, PDFColor sc, float sw) {
  533. /*
  534. * SVG - Not yet implemented
  535. * if ( debug )
  536. * System.out.println("TXTRenderer.addRect(" + x + ", " + y + ", " + w + ", " + h + ", " + rx + ", " + ry + ", " + fc + ", " + sc + ", " + sw + ")");
  537. * float sr = 1;
  538. * float sg = 1;
  539. * float sb = 1;
  540. * float fr = 1;
  541. * float fg = 1;
  542. * float fb = 1;
  543. * if ( sc != null && sw > 0 )
  544. * {
  545. * sr = (float)sc.red();
  546. * sg = (float)sc.green();
  547. * sb = (float)sc.blue();
  548. * }
  549. * if ( fc != null )
  550. * {
  551. * fr = (float)fc.red();
  552. * fg = (float)fc.green();
  553. * fb = (float)fc.blue();
  554. * }
  555. * addRect((int)(x * 1000), (int)(pageHeight * 100 - y * 1000), (int)(w * 1000), (int)(h * 1000), sr, sg, sb, fr, fg, fb);
  556. * fc = null;
  557. * sc = null;
  558. * if ( rx == 0 || ry == 0 )
  559. * {
  560. * if ( fc != null )
  561. * {
  562. * int fillshade = (int)(100 - ((0.3f * fc.red() + 0.59f * fc.green() + 0.11f * fc.blue()) * 100f));
  563. * currentStream.add("\033*v0n1O\033&a" + (x * 10) + "h" + ((y * 10)) + "V"
  564. * + "\033*c" + (w * 10) + "h" + (h * 10) + "v" + fillshade + "g2P\033*v0n0O");
  565. * }
  566. * if ( sc != null && sw > 0 )
  567. * {
  568. * String lend = "v" + String.valueOf((int)(100 - ((0.3f * sc.red() + 0.59f * sc.green() + 0.11f * sc.blue()) * 100f))) + "g2P";
  569. * currentStream.add("\033*v0n1O");
  570. * currentStream.add("\033&a" + ((x - sw/2) * 10) + "h" + (((y - sw/2)) * 10) + "V"
  571. * + "\033*c" + ((w + sw) * 10) + "h" + ((sw) * 10) + lend);
  572. * currentStream.add("\033&a" + ((x - sw/2) * 10) + "h" + (((y - sw/2)) * 10) + "V"
  573. * + "\033*c" + ((sw) * 10) + "h" + ((h + sw) * 10) + lend);
  574. * currentStream.add("\033&a" + ((x + w - sw/2) * 10) + "h" + (((y - sw/2)) * 10) + "V"
  575. * + "\033*c" + ((sw) * 10) + "h" + ((h + sw) * 10) + lend);
  576. * currentStream.add("\033&a" + ((x - sw/2) * 10) + "h" + (((y + h - sw/2)) * 10) + "V"
  577. * + "\033*c" + ((w + sw) * 10) + "h" + ((sw) * 10) + lend);
  578. * currentStream.add("\033*v0n0O");
  579. * }
  580. * }
  581. * else
  582. * {
  583. * // Convert dimensions to pixels.
  584. * float cfact = 300f / 72f; // 300 dpi, 1pt=1/72in
  585. * int ix = (int)(x * cfact);
  586. * int iy = (int)(y * cfact);
  587. * int iw = (int)(w * cfact);
  588. * int ih = (int)(h * cfact);
  589. * int irx = (int)(rx * cfact);
  590. * int iry = (int)(ry * cfact);
  591. * int isw = (int)(sw * cfact);
  592. * int longwidth = 0;
  593. * int pass = 0;
  594. * PDFColor thecolor = null;
  595. * do
  596. * {
  597. * if ( pass == 0 && fc != null )
  598. * {
  599. * thecolor = fc;
  600. * }
  601. * else if ( pass == 1 && sc != null )
  602. * {
  603. * int iswdiv2 = isw / 2;
  604. * thecolor = sc;
  605. * ix -= iswdiv2;
  606. * iy -= iswdiv2;
  607. * irx += iswdiv2;
  608. * iry += iswdiv2;
  609. * iw += isw;
  610. * ih += isw;
  611. * longwidth = (int)(isw * 1.414);
  612. * }
  613. * else
  614. * thecolor = null;
  615. * if ( thecolor != null )
  616. * {
  617. * int tx = 0;
  618. * int ty = iry;
  619. * long a = irx;
  620. * long b = iry;
  621. * long Asquared = (long)Math.pow(a, 2);
  622. * long TwoAsquared = 2 * Asquared;
  623. * long Bsquared = (long)Math.pow(b, 2);
  624. * long TwoBsquared = 2 * Bsquared;
  625. * long d = Bsquared - Asquared * b + Asquared / 4;
  626. * long dx = 0;
  627. * long dy = TwoAsquared * b;
  628. * int rectlen = iw - 2 * irx;
  629. * ArrayList bottomlines = new ArrayList();
  630. * int x0 = tx;
  631. * // Set Transparency modes and select shading.
  632. * currentStream.add("\033*v0n1O\033*c" + (int)(100 - ((0.3f * thecolor.red() + 0.59f * thecolor.green() + 0.11f * thecolor.blue()) * 100f)) + "G\033*v2T");
  633. * // Move to starting position.
  634. * currentStream.add("\033*p" + ix + "x" + iy + "Y");
  635. * // Start raster graphics
  636. * currentStream.add("\033*t300R\033*r" + iw + "s1A\033*b1M");
  637. * while ( dx < dy )
  638. * {
  639. * if ( d > 0 )
  640. * {
  641. * if ( pass == 0 || ty > (iry - isw) )
  642. * xferLineBytes(irx - x0, rectlen + 2 * x0, bottomlines, -1);
  643. * else
  644. * xferLineBytes(irx - x0, longwidth, bottomlines, iw - irx + x0 - longwidth);
  645. * x0 = tx + 1;
  646. * ty--;
  647. * dy -= TwoAsquared;
  648. * d -= dy;
  649. * }
  650. * tx++;
  651. * dx += TwoBsquared;
  652. * d += Bsquared + dx;
  653. * }
  654. * d += (3 * (Asquared - Bsquared) / 2 - (dx + dy)) / 2;
  655. * while ( ty > 0 )
  656. * {
  657. * if ( pass == 0 || ty >= (iry - isw) )
  658. * xferLineBytes(irx - tx, rectlen + 2 * tx, bottomlines, -1);
  659. * else
  660. * xferLineBytes(irx - tx, isw, bottomlines, iw - irx + tx - isw);
  661. *
  662. * if ( d < 0 )
  663. * {
  664. * tx++;
  665. * dx += TwoBsquared;
  666. * d += dx;
  667. * }
  668. * ty--;
  669. * dy -= TwoAsquared;
  670. * d += Asquared - dy;
  671. * }
  672. * // Draw the middle part of the rectangle
  673. * int midlen = ih - 2 * iry;
  674. * if ( midlen > 0 )
  675. * {
  676. * if ( pass == 0 )
  677. * xferLineBytes(0, iw, null, -1);
  678. * else
  679. * xferLineBytes(0, isw, null, iw - isw);
  680. * currentStream.add("\033*b3M");
  681. * for ( int countr = midlen - 1 ; countr > 0 ; countr-- )
  682. * currentStream.add("\033*b0W");
  683. * currentStream.add("\033*b1M");
  684. * }
  685. * // Draw the bottom.
  686. * for ( int countr = bottomlines.size() - 1 ; countr >= 0 ; countr-- )
  687. * currentStream.add((String)bottomlines.get(countr));
  688. * // End raster graphics
  689. * currentStream.add("\033*rB");
  690. * // Return to regular print mode.
  691. * currentStream.add("\033*v0t0n0O");
  692. * }
  693. * pass++;
  694. * } while ( pass < 2 );
  695. * }
  696. */
  697. }
  698. // Add a polyline or polygon. Does not support fills yet!!!
  699. protected void addPolyline(ArrayList points, int posx, int posy,
  700. PDFColor fc, PDFColor sc, float sw,
  701. boolean close) {}
  702. /**
  703. * Renders an image, scaling it to the given width and height.
  704. * If the scaled width and height is the same intrinsic size
  705. * of the image, the image is not scaled.
  706. *
  707. * @param x the x position of left edge in millipoints
  708. * @param y the y position of top edge in millipoints
  709. * @param w the width in millipoints
  710. * @param h the height in millipoints
  711. * @param image the image to be rendered
  712. * @param fs the font state to use when rendering text
  713. * in non-bitmapped images.
  714. */
  715. protected void drawImageScaled(int x, int y, int w, int h,
  716. FopImage image,
  717. FontState fs) {
  718. // XXX: implement this
  719. }
  720. /**
  721. * Renders an image, clipping it as specified.
  722. *
  723. * @param x the x position of left edge in millipoints.
  724. * @param y the y position of top edge in millipoints.
  725. * @param clipX the left edge of the clip in millipoints
  726. * @param clipY the top edge of the clip in millipoints
  727. * @param clipW the clip width in millipoints
  728. * @param clipH the clip height in millipoints
  729. * @param fill the image to be rendered
  730. * @param fs the font state to use when rendering text
  731. * in non-bitmapped images.
  732. */
  733. protected void drawImageClipped(int x, int y,
  734. int clipX, int clipY,
  735. int clipW, int clipH,
  736. FopImage image,
  737. FontState fs) {
  738. // XXX: implement this
  739. }
  740. boolean printBMP(FopImage img, int x, int y, int w,
  741. int h) throws FopImageException {
  742. if (debug)
  743. System.out.println("TXTRenderer.printBMP(" + img + ", " + x
  744. + ", " + y + ", " + w + ", " + h + ")");
  745. addRect(x, y, w, h, new PDFColor(1f, 1f, 1f),
  746. new PDFColor(0f, 0f, 0f));
  747. int nameh = (int)(h * yFactor / 2);
  748. if (nameh > 0) {
  749. int namew = (int)(w * xFactor);
  750. if (namew > 4) {
  751. String iname = img.getURL();
  752. if (iname.length() >= namew)
  753. addStr((int)((pageHeight - (y / 100)) * 100 * yFactor)
  754. + nameh, (int)(x * xFactor),
  755. iname.substring(iname.length() - namew),
  756. true);
  757. else
  758. addStr((int)((pageHeight - (y / 100)) * 100 * yFactor)
  759. + nameh, (int)(x * xFactor
  760. + (namew - iname.length())
  761. / 2), iname, true);
  762. }
  763. }
  764. return (true);
  765. }
  766. /**
  767. * render image area to PCL
  768. *
  769. * @param area the image area to render
  770. */
  771. public void renderImageArea(ImageArea area) {
  772. int x = this.currentAreaContainerXPosition + area.getXOffset();
  773. int y = this.currentYPosition;
  774. int w = area.getContentWidth();
  775. int h = area.getHeight();
  776. this.currentYPosition -= h;
  777. FopImage img = area.getImage();
  778. try {
  779. printBMP(img, x, y, w, h);
  780. } catch (FopImageException e) {
  781. // e.printStackTrace(System.out);
  782. log.error("TXTRenderer.renderImageArea() printing BMP ("
  783. + e.toString() + ").", e);
  784. }
  785. }
  786. public void renderImage(FontState fontState, String href, float x,
  787. float y, float width, float height) {
  788. try {
  789. if (href.indexOf(":") == -1)
  790. href = "file:" + href;
  791. FopImage img = FopImageFactory.Make(href);
  792. if (img != null) {
  793. if (img instanceof SVGImage) {
  794. SVGSVGElement svg =
  795. ((SVGImage)img).getSVGDocument().getRootElement();
  796. renderSVG(fontState, svg, (int)x * 1000, (int)y * 1000);
  797. } else {
  798. printBMP(img, (int)x, (int)y, (int)width, (int)height);
  799. }
  800. }
  801. } catch (Exception e) {
  802. log.error("could not add image to SVG: " + href, e);
  803. }
  804. }
  805. /**
  806. * render a foreign object area
  807. */
  808. public void renderForeignObjectArea(ForeignObjectArea area) {
  809. // if necessary need to scale and align the content
  810. this.currentXPosition = this.currentXPosition + area.getXOffset();
  811. this.currentYPosition = this.currentYPosition;
  812. switch (area.getAlign()) {
  813. case TextAlign.START:
  814. break;
  815. case TextAlign.END:
  816. break;
  817. case TextAlign.CENTER:
  818. case TextAlign.JUSTIFY:
  819. break;
  820. }
  821. switch (area.getVerticalAlign()) {
  822. case VerticalAlign.BASELINE:
  823. break;
  824. case VerticalAlign.MIDDLE:
  825. break;
  826. case VerticalAlign.SUB:
  827. break;
  828. case VerticalAlign.SUPER:
  829. break;
  830. case VerticalAlign.TEXT_TOP:
  831. break;
  832. case VerticalAlign.TEXT_BOTTOM:
  833. break;
  834. case VerticalAlign.TOP:
  835. break;
  836. case VerticalAlign.BOTTOM:
  837. break;
  838. }
  839. // in general the content will not be text
  840. // align and scale
  841. switch (area.scalingMethod()) {
  842. case Scaling.UNIFORM:
  843. break;
  844. case Scaling.NON_UNIFORM:
  845. break;
  846. }
  847. // if the overflow is auto (default), scroll or visible
  848. // then the contents should not be clipped, since this
  849. // is considered a printing medium.
  850. switch (area.getOverflow()) {
  851. case Overflow.VISIBLE:
  852. case Overflow.SCROLL:
  853. case Overflow.AUTO:
  854. break;
  855. case Overflow.HIDDEN:
  856. break;
  857. }
  858. area.getObject().render(this);
  859. this.currentXPosition += area.getEffectiveWidth();
  860. // this.currentYPosition -= area.getEffectiveHeight();
  861. }
  862. void renderSVG(FontState fontState, SVGSVGElement svg, int x, int y) {
  863. /*
  864. * SVG - Not yet implemented
  865. * NodeList nl = svg.getChildNodes();
  866. * for(int count = 0; count < nl.getLength(); count++) {
  867. * Node n = nl.item(count);
  868. * if(n instanceof SVGElement) {
  869. * renderElement(fontState, (SVGElement)n, x, y);
  870. * }
  871. * }
  872. */
  873. }
  874. /**
  875. * render SVG area to Text
  876. *
  877. * @param area the SVG area to render
  878. */
  879. public void renderSVGArea(SVGArea area) {
  880. if (debug)
  881. System.out.println("TXTRenderer.renderSVGArea(" + area + ")");
  882. int x = this.currentAreaContainerXPosition;
  883. int y = this.currentYPosition;
  884. SVGSVGElement svg =
  885. ((SVGDocument)area.getSVGDocument()).getRootElement();
  886. int w = (int)(svg.getWidth().getBaseVal().getValue() * 1000);
  887. int h = (int)(svg.getHeight().getBaseVal().getValue() * 1000);
  888. // currentStream.add("ET\n");
  889. /*
  890. * Clip to the svg area.
  891. * Note: To have the svg overlay (under) a text area then use
  892. * an fo:block-container
  893. */
  894. // currentStream.add("q\n");
  895. // currentStream.add(x / 1000f + " " + y / 1000f + " m\n");
  896. // currentStream.add((x + w) / 1000f + " " + y / 1000f + " l\n");
  897. // currentStream.add((x + w) / 1000f + " " + (y - h) / 1000f + " l\n");
  898. // currentStream.add(x / 1000f + " " + (y - h) / 1000f + " l\n");
  899. // currentStream.add("h\n");
  900. // currentStream.add("W\n");
  901. // currentStream.add("n\n");
  902. // transform so that the coordinates (0,0) is from the top left
  903. // and positive is down and to the right
  904. // currentStream.add(1 + " " + 0 + " " + 0 + " " + (-1) + " " + x / 1000f + " " + y / 1000f + " cm\n");
  905. // TODO - translate and clip to viewbox
  906. renderSVG(area.getFontState(), svg, x, y);
  907. // Enumeration e = area.getChildren().elements();
  908. // while (e.hasMoreElements()) {
  909. // Object o = e.nextElement();
  910. // if(o instanceof GraphicImpl) {
  911. // renderElement(area, (GraphicImpl)o, x, y);
  912. // }
  913. // }
  914. // currentStream.add("Q\n");
  915. // currentStream.add("BT\n");
  916. // this.currentYPosition -= h;
  917. }
  918. /*
  919. * SVG - Not yet implemented
  920. * public void renderElement(FontState fontState, SVGElement area, int posx, int posy)
  921. * {
  922. * if ( debug )
  923. * System.out.println("TXTRenderer.renderElement(" + fontState + ", " + area + ", " + posx + ", " + posy + ")");
  924. * int x = posx;
  925. * int y = posy;
  926. * CSSStyleDeclaration style = null;
  927. * if ( area instanceof SVGStylable )
  928. * style = ((SVGStylable)area).getStyle();
  929. * PDFColor fillColour = null;
  930. * PDFColor strokeColour = null;
  931. * float strokeWidth = 0;
  932. * //currentStream.add("q\n");
  933. * //if( area instanceof SVGTransformable )
  934. * //{
  935. * // SVGTransformable tf = (SVGTransformable)area;
  936. * // SVGAnimatedTransformList trans = tf.getTransform();
  937. * // SVGRect bbox = tf.getBBox();
  938. * // if(trans != null) {
  939. * // applyTransform(trans, bbox);
  940. * // }
  941. * //}
  942. * if(style != null)
  943. * {
  944. * CSSValue sp = style.getPropertyCSSValue("fill");
  945. * if(sp != null)
  946. * {
  947. * if( sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE )
  948. * {
  949. * if( ((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_RGBCOLOR )
  950. * {
  951. * RGBColor col = ((CSSPrimitiveValue)sp).getRGBColorValue();
  952. * CSSPrimitiveValue val;
  953. * val = col.getRed();
  954. * float red = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
  955. * val = col.getGreen();
  956. * float green = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
  957. * val = col.getBlue();
  958. * float blue = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
  959. * fillColour = new PDFColor(red, green, blue);
  960. * }
  961. * }
  962. * //if(sp instanceof ColorType)
  963. * //{
  964. * // ColorType ct = (ColorType)sp;
  965. * // fillColour = new PDFColor(ct.red(), ct.green(), ct.blue());
  966. * //}
  967. * }
  968. * else
  969. * fillColour = new PDFColor(0, 0, 0);
  970. * sp = style.getPropertyCSSValue("stroke");
  971. * if(sp != null)
  972. * {
  973. * if( sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE )
  974. * {
  975. * if( ((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_RGBCOLOR )
  976. * {
  977. * RGBColor col = ((CSSPrimitiveValue)sp).getRGBColorValue();
  978. * CSSPrimitiveValue val;
  979. * val = col.getRed();
  980. * float red = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
  981. * val = col.getGreen();
  982. * float green = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
  983. * val = col.getBlue();
  984. * float blue = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
  985. * strokeColour = new PDFColor(red, green, blue);
  986. * }
  987. * }
  988. * //if(sp instanceof ColorType)
  989. * //{
  990. * // ColorType ct = (ColorType)sp;
  991. * // strokeColour = new PDFColor(ct.red(), ct.green(), ct.blue());
  992. * //}
  993. * }
  994. * sp = style.getPropertyCSSValue("stroke-width");
  995. * if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE)
  996. * {
  997. * strokeWidth = ((CSSPrimitiveValue)sp).getFloatValue(CSSPrimitiveValue.CSS_PT);
  998. * //PDFNumber pdfNumber = new PDFNumber();
  999. * //currentStream.add(pdfNumber.doubleOut(width) + " w\n");
  1000. * //strokeWidth = ((SVGLengthImpl)sp).getValue();
  1001. * }
  1002. * else
  1003. * strokeWidth = 1;
  1004. * }
  1005. * if (area instanceof SVGRectElement)
  1006. * {
  1007. * SVGRectElement rg = (SVGRectElement)area;
  1008. * float rectx = rg.getX().getBaseVal().getValue() + posx / 1000;
  1009. * float recty = ((pageHeight / 10) - posy/1000) + rg.getY().getBaseVal().getValue();
  1010. * float rx = rg.getRx().getBaseVal().getValue();
  1011. * float ry = rg.getRy().getBaseVal().getValue();
  1012. * float rw = rg.getWidth().getBaseVal().getValue();
  1013. * float rh = rg.getHeight().getBaseVal().getValue();
  1014. * addRect(rectx, recty, rw, rh, rx, ry, fillColour, strokeColour, strokeWidth);
  1015. * }
  1016. * else if (area instanceof SVGLineElement)
  1017. * {
  1018. * SVGLineElement lg = (SVGLineElement)area;
  1019. * float x1 = lg.getX1().getBaseVal().getValue() + posx / 1000;
  1020. * float y1 = ((pageHeight / 10) - posy/1000) + lg.getY1().getBaseVal().getValue();
  1021. * float x2 = lg.getX2().getBaseVal().getValue() + posx / 1000;
  1022. * float y2 = ((pageHeight / 10) - posy/1000) + lg.getY2().getBaseVal().getValue();
  1023. * addLine(x1,y1,x2,y2, strokeColour, strokeWidth);
  1024. * }
  1025. * else if (area instanceof SVGTextElementImpl)
  1026. * {
  1027. * //currentStream.add("BT\n");
  1028. * renderText(fontState, (SVGTextElementImpl)area, posx / 1000f, ((float)(pageHeight / 10) - posy/1000f));
  1029. * //currentStream.add("ET\n");
  1030. * }
  1031. * else if (area instanceof SVGCircleElement)
  1032. * {
  1033. * SVGCircleElement cg = (SVGCircleElement)area;
  1034. * float cx = cg.getCx().getBaseVal().getValue() + posx / 1000;
  1035. * float cy = ((pageHeight / 10) - posy/1000) + cg.getCy().getBaseVal().getValue();
  1036. * float r = cg.getR().getBaseVal().getValue();
  1037. * //addCircle(cx,cy,r, di);
  1038. * addRect(cx - r, cy - r, 2 * r, 2 * r, r, r, fillColour, strokeColour, strokeWidth);
  1039. * }
  1040. * else if (area instanceof SVGEllipseElement)
  1041. * {
  1042. * SVGEllipseElement cg = (SVGEllipseElement)area;
  1043. * float cx = cg.getCx().getBaseVal().getValue() + posx / 1000;
  1044. * float cy = ((pageHeight / 10) - posy/1000) + cg.getCy().getBaseVal().getValue();
  1045. * float rx = cg.getRx().getBaseVal().getValue();
  1046. * float ry = cg.getRy().getBaseVal().getValue();
  1047. * //addEllipse(cx,cy,rx,ry, di);
  1048. * addRect(cx - rx, cy - ry, 2 * rx, 2 * ry, rx, ry, fillColour, strokeColour, strokeWidth);
  1049. * }
  1050. * else if (area instanceof SVGPathElementImpl)
  1051. * {
  1052. * //addPath(((SVGPathElementImpl)area).pathElements, posx, posy, di);
  1053. * }
  1054. * else if (area instanceof SVGPolylineElementImpl)
  1055. * {
  1056. * addPolyline(((SVGPolylineElementImpl)area).points, posx, posy, fillColour, strokeColour, strokeWidth, false);
  1057. * }
  1058. * else if (area instanceof SVGPolygonElementImpl)
  1059. * {
  1060. * addPolyline(((SVGPolylineElementImpl)area).points, posx, posy, fillColour, strokeColour, strokeWidth, true);
  1061. * }
  1062. * else if (area instanceof SVGGElementImpl)
  1063. * {
  1064. * renderGArea(fontState, (SVGGElementImpl)area, x, y);
  1065. * }
  1066. * else if(area instanceof SVGUseElementImpl)
  1067. * {
  1068. * SVGUseElementImpl ug = (SVGUseElementImpl)area;
  1069. * String ref = ug.link;
  1070. * ref = ref.substring(1, ref.length());
  1071. * SVGElement graph = null;
  1072. * //GraphicImpl graph = null;
  1073. * //graph = area.locateDef(ref);
  1074. * if(graph != null) {
  1075. * // probably not the best way to do this, should be able
  1076. * // to render without the style being set.
  1077. * //GraphicImpl parent = graph.getGraphicParent();
  1078. * //graph.setParent(area);
  1079. * // need to clip (if necessary) to the use area
  1080. * // the style of the linked element is as if is was
  1081. * // a direct descendant of the use element.
  1082. * renderElement(fontState, graph, posx, posy);
  1083. * //graph.setParent(parent);
  1084. * }
  1085. * }
  1086. * else if (area instanceof SVGImageElementImpl)
  1087. * {
  1088. * SVGImageElementImpl ig = (SVGImageElementImpl)area;
  1089. * renderImage(fontState, ig.link, ig.x, ig.y, ig.width, ig.height);
  1090. * }
  1091. * else if (area instanceof SVGSVGElement)
  1092. * {
  1093. * // the x and y pos will be wrong!
  1094. * renderSVG(fontState, (SVGSVGElement)area, x, y);
  1095. * }
  1096. * else if (area instanceof SVGAElement)
  1097. * {
  1098. * SVGAElement ael = (SVGAElement)area;
  1099. * org.w3c.dom.NodeList nl = ael.getChildNodes();
  1100. * for ( int count = 0 ; count < nl.getLength() ; count++ )
  1101. * {
  1102. * org.w3c.dom.Node n = nl.item(count);
  1103. * if ( n instanceof SVGElement )
  1104. * {
  1105. * if ( n instanceof GraphicElement )
  1106. * {
  1107. * SVGRect rect = ((GraphicElement)n).getBBox();
  1108. * if ( rect != null )
  1109. * {
  1110. * // currentAnnotList = this.pdfDoc.makeAnnotList();
  1111. * // currentPage.setAnnotList(currentAnnotList);
  1112. * // String dest = linkSet.getDest();
  1113. * // int linkType = linkSet.getLinkType();
  1114. * // currentAnnotList.addLink(
  1115. * // this.pdfDoc.makeLink(lrect.getRectangle(), dest, linkType));
  1116. * // currentAnnotList = null;
  1117. * // }
  1118. * }
  1119. * renderElement(fontState, (SVGElement)n, posx, posy);
  1120. * }
  1121. * }
  1122. * }
  1123. * else if ( area instanceof SVGSwitchElement )
  1124. * {
  1125. * handleSwitchElement(fontState, posx, posy, (SVGSwitchElement)area);
  1126. * }
  1127. * // should be done with some cleanup code, so only
  1128. * // required values are reset.
  1129. * //currentStream.add("Q\n");
  1130. * }
  1131. */
  1132. private void setFont(String name, float size) {
  1133. return;
  1134. }
  1135. /*
  1136. * SVG - Not implemented yet.
  1137. * public void renderText(FontState fontState, SVGTextElementImpl tg, float x, float y)
  1138. * {
  1139. * PDFNumber pdfNumber = new PDFNumber();
  1140. * CSSStyleDeclaration styles;
  1141. * styles = tg.getStyle();
  1142. * //applyStyle(tg, styles);
  1143. * // apply transform
  1144. * // text has a Tm and need to handle each element
  1145. * SVGTransformList trans = tg.getTransform().getBaseVal();
  1146. * SVGMatrix matrix = trans.consolidate().getMatrix();
  1147. * String transstr = (pdfNumber.doubleOut(matrix.getA())
  1148. * + " " + pdfNumber.doubleOut(matrix.getB())
  1149. * + " " + pdfNumber.doubleOut(matrix.getC())
  1150. * + " " + pdfNumber.doubleOut(-matrix.getD()) + " ");
  1151. * String fontFamily = null;
  1152. * CSSValue sp = styles.getPropertyCSSValue("font-family");
  1153. * if ( sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE )
  1154. * {
  1155. * if ( ((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING )
  1156. * fontFamily = sp.getCssText();
  1157. * }
  1158. * if ( fontFamily == null )
  1159. * fontFamily = fontState.getFontFamily();
  1160. * String fontStyle = null;
  1161. * sp = styles.getPropertyCSSValue("font-style");
  1162. * if ( sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE )
  1163. * {
  1164. * if ( ((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING )
  1165. * fontStyle = sp.getCssText();
  1166. * }
  1167. * if ( fontStyle == null )
  1168. * fontStyle = fontState.getFontStyle();
  1169. * String fontWeight = null;
  1170. * sp = styles.getPropertyCSSValue("font-weight");
  1171. * if( sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE )
  1172. * {
  1173. * if ( ((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING )
  1174. * fontWeight = sp.getCssText();
  1175. * }
  1176. * if( fontWeight == null )
  1177. * fontWeight = fontState.getFontWeight();
  1178. * float fontSize;
  1179. * sp = styles.getPropertyCSSValue("font-size");
  1180. * if( sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE )
  1181. * {
  1182. * // if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_NUMBER) {
  1183. * fontSize = ((CSSPrimitiveValue)sp).getFloatValue(CSSPrimitiveValue.CSS_PT);
  1184. * // }
  1185. * }
  1186. * else
  1187. * {
  1188. * fontSize = fontState.getFontSize() / 1000f;
  1189. * }
  1190. * FontState fs = fontState;
  1191. * try
  1192. * {
  1193. * fs = new FontState(fontState.getFontInfo(), fontFamily, fontStyle,
  1194. * fontWeight, (int)(fontSize * 1000));
  1195. * }
  1196. * catch( Exception fope )
  1197. * {
  1198. * // fope.printStackTrace();
  1199. * }
  1200. * //currentStream.add("/" + fs.getFontName() + " " + fontSize + " Tf\n");
  1201. * setFont(fs.getFontName(), fontSize * 1000);
  1202. * float tx = tg.x;
  1203. * float ty = tg.y;
  1204. * float currentX = x + tx;
  1205. * float currentY = y + ty;
  1206. * ArrayList list = tg.textList;
  1207. * for ( Enumeration e = list.elements() ; e.hasMoreElements() ; )
  1208. * {
  1209. * Object o = e.nextElement();
  1210. * styles = tg.getStyle();
  1211. * //applyStyle(tg, styles);
  1212. * if( o instanceof String )
  1213. * {
  1214. * String str = (String)o;
  1215. * //currentStream.add(transstr
  1216. * // + (currentX + matrix.getE()) + " "
  1217. * // + (y+ty + matrix.getF()) + " Tm "
  1218. * // + "(");
  1219. * boolean spacing = "preserve".equals(tg.getXMLspace());
  1220. * //currentX = addSVGStr(fs, currentX, str, spacing);
  1221. * //currentStream.add(") Tj\n");
  1222. * // for(int count = 0; count < str.length(); count++) {
  1223. * // }
  1224. * // currentX += fs.width(' ') / 1000f;
  1225. * currentStream.add("\033&a" + (currentX + matrix.getE())*10 + "h" + (y+ty + matrix.getF())*10 + "V" + str);
  1226. * for ( int count = 0; count < str.length(); count++ )
  1227. * {
  1228. * currentX += fs.width(str.charAt(count)) / 1000f;
  1229. * }
  1230. * currentX += fs.width(' ') / 1000f;
  1231. * } else if(o instanceof SVGTextPathElementImpl) {
  1232. * SVGTextPathElementImpl tpg = (SVGTextPathElementImpl)o;
  1233. * String ref = tpg.str;
  1234. * SVGElement graph = null;
  1235. * // graph = tpg.locateDef(ref);
  1236. * if(graph != null && graph instanceof SVGPathElementImpl) {
  1237. * // probably not the best way to do this, should be able
  1238. * // to render without the style being set.
  1239. * // GraphicImpl parent = graph.getGraphicParent();
  1240. * // graph.setParent(tpg);
  1241. * // set text path??
  1242. * // how should this work
  1243. * // graph.setParent(parent);
  1244. * }
  1245. * } else if(o instanceof SVGTRefElementImpl) {
  1246. * SVGTRefElementImpl trg = (SVGTRefElementImpl)o;
  1247. * String ref = trg.ref;
  1248. * ref = ref.substring(1, ref.length());
  1249. * SVGElement graph = null;
  1250. * // graph = trg.locateDef(ref);
  1251. * if(graph != null && graph instanceof SVGTextElementImpl) {
  1252. * // GraphicImpl parent = graph.getGraphicParent();
  1253. * // graph.setParent(trg);
  1254. * SVGTextElementImpl te = (SVGTextElementImpl)graph;
  1255. * renderText(fs, te, (int)(x + tx), (int)(y + ty));
  1256. * // graph.setParent(parent);
  1257. * }
  1258. * } else if(o instanceof SVGTSpanElementImpl) {
  1259. * SVGTSpanElementImpl tsg = (SVGTSpanElementImpl)o;
  1260. * styles = tsg.getStyle();
  1261. * //applyStyle(tsg, styles);
  1262. * boolean changed = false;
  1263. * String newprop = null;
  1264. * sp = styles.getPropertyCSSValue("font-family");
  1265. * if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
  1266. * if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING) {
  1267. * newprop = sp.getCssText();
  1268. * }
  1269. * }
  1270. * if(newprop != null && !newprop.equals(fontFamily)) {
  1271. * fontFamily = newprop;
  1272. * changed = true;
  1273. * }
  1274. * sp = styles.getPropertyCSSValue("font-style");
  1275. * if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
  1276. * if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING) {
  1277. * newprop = sp.getCssText();
  1278. * }
  1279. * }
  1280. * if(newprop != null && !newprop.equals(fontStyle)) {
  1281. * fontStyle = newprop;
  1282. * changed = true;
  1283. * }
  1284. * sp = styles.getPropertyCSSValue("font-weight");
  1285. * if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
  1286. * if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING) {
  1287. * newprop = sp.getCssText();
  1288. * }
  1289. * }
  1290. * if(newprop != null && !newprop.equals(fontWeight)) {
  1291. * fontWeight = newprop;
  1292. * changed = true;
  1293. * }
  1294. * float newSize = fontSize;
  1295. * sp = styles.getPropertyCSSValue("font-size");
  1296. * if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
  1297. * // if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_NUMBER) {
  1298. * newSize = ((CSSPrimitiveValue)sp).getFloatValue(CSSPrimitiveValue.CSS_PT);
  1299. * // }
  1300. * }
  1301. * if ( fontSize != newSize )
  1302. * {
  1303. * fontSize = newSize;
  1304. * changed = true;
  1305. * }
  1306. * FontState oldfs = null;
  1307. * if ( changed )
  1308. * {
  1309. * oldfs = fs;
  1310. * try
  1311. * {
  1312. * fs = new FontState(fontState.getFontInfo(), fontFamily, fontStyle,
  1313. * fontWeight, (int)(fontSize * 1000));
  1314. * }
  1315. * catch(Exception fope)
  1316. * {
  1317. * }
  1318. * setFont(fs.getFontName(), fontSize * 1000);
  1319. * //currentStream.add("/" + fs.getFontName() + " " + fontSize + " Tf\n");
  1320. * }
  1321. * float baseX;
  1322. * float baseY;
  1323. * StringBuffer pdf = new StringBuffer();
  1324. * boolean spacing = "preserve".equals(tsg.getXMLspace());
  1325. * boolean inbetween = false;
  1326. * boolean addedspace = false;
  1327. * int charPos = 0;
  1328. * float xpos = currentX;
  1329. * float ypos = currentY;
  1330. * for ( int i=0 ; i < tsg.str.length() ; i++ )
  1331. * {
  1332. * char ch = tsg.str.charAt(i);
  1333. * xpos = currentX;
  1334. * ypos = currentY;
  1335. * if ( tsg.ylist.size() > charPos )
  1336. * ypos = y + ty + ((Float)tsg.ylist.get(charPos)).floatValue();
  1337. * if ( tsg.dylist.size() > charPos )
  1338. * ypos = ypos + ((Float)tsg.dylist.get(charPos)).floatValue();
  1339. * if ( tsg.xlist.size() > charPos )
  1340. * xpos = x + tx + ((Float)tsg.xlist.get(charPos)).floatValue();
  1341. * if ( tsg.dxlist.size() > charPos )
  1342. * xpos = xpos + ((Float)tsg.dxlist.get(charPos)).floatValue();
  1343. * switch (ch)
  1344. * {
  1345. * case ' ':
  1346. * case ' ':
  1347. * if ( spacing )
  1348. * {
  1349. * currentX = xpos + fs.width(' ') / 1000f;
  1350. * currentY = ypos;
  1351. * charPos++;
  1352. * }
  1353. * else
  1354. * {
  1355. * if ( inbetween && !addedspace)
  1356. * {
  1357. * addedspace = true;
  1358. * currentX = xpos + fs.width(' ') / 1000f;
  1359. * currentY = ypos;
  1360. * charPos++;
  1361. * }
  1362. * }
  1363. * break;
  1364. * case '\n':
  1365. * case '\r':
  1366. * if ( spacing )
  1367. * {
  1368. * currentX = xpos + fs.width(' ') / 1000f;
  1369. * currentY = ypos;
  1370. * charPos++;
  1371. * }
  1372. * break;
  1373. * default:
  1374. * addedspace = false;
  1375. * pdf = pdf.append(transstr
  1376. * + (xpos + matrix.getE()) + " "
  1377. * + (ypos + matrix.getF()) + " Tm "
  1378. * + "(" + ch + ") Tj\n");
  1379. * pdf = pdf.append("\033&a" + (xpos + matrix.getE())*10 + "h" + (ypos + matrix.getF())*10 + "V" + ch);
  1380. * currentX = xpos + fs.width(ch) / 1000f;
  1381. * currentY = ypos;
  1382. * charPos++;
  1383. * inbetween = true;
  1384. * break;
  1385. * }
  1386. * //currentStream.add(pdf.toString());
  1387. * }
  1388. * // currentX += fs.width(' ') / 1000f;
  1389. * if ( changed )
  1390. * {
  1391. * fs = oldfs;
  1392. * setFont(fs.getFontName(), fs.getFontSize() * 1000);
  1393. * //currentStream.add("/" + fs.getFontName() + " " + fs.getFontSize() / 1000f + " Tf\n");
  1394. * }
  1395. * }
  1396. * else
  1397. * {
  1398. * System.err.println("Error: unknown text element " + o);
  1399. * }
  1400. * }
  1401. * }
  1402. */
  1403. /*
  1404. * SVG - Not yet implemented
  1405. * public void renderGArea(FontState fontState, SVGGElement area, int posx, int posy)
  1406. * {
  1407. * NodeList nl = area.getChildNodes();
  1408. * for ( int count = 0 ; count < nl.getLength() ; count++ )
  1409. * {
  1410. * Node n = nl.item(count);
  1411. * if ( n instanceof SVGElement )
  1412. * renderElement(fontState, (SVGElement)n, posx, posy);
  1413. * }
  1414. * }
  1415. */
  1416. /*
  1417. * SVG - Not yet implemented
  1418. * void handleSwitchElement(FontState fontState, int posx, int posy, SVGSwitchElement ael)
  1419. * {
  1420. * SVGList relist = ael.getRequiredExtensions();
  1421. * SVGList rflist = ael.getRequiredFeatures();
  1422. * SVGList sllist = ael.getSystemLanguage();
  1423. * org.w3c.dom.NodeList nl = ael.getChildNodes();
  1424. * for(int count = 0; count < nl.getLength(); count++) {
  1425. * org.w3c.dom.Node n = nl.item(count);
  1426. * // only render the first child that has a valid
  1427. * // test data
  1428. * if(n instanceof GraphicElement) {
  1429. * GraphicElement graphic = (GraphicElement)n;
  1430. * SVGList grelist = graphic.getRequiredExtensions();
  1431. * // if null it evaluates to true
  1432. * if(grelist != null) {
  1433. * for(int i = 0; i < grelist.getNumberOfItems(); i++) {
  1434. * String str = (String)grelist.getItem(i);
  1435. * if(relist == null) {
  1436. * // use default extension set
  1437. * // currently no extensions are supported
  1438. * // if(!(str.equals("http:// ??"))) {
  1439. * continue;
  1440. * // }
  1441. * } else {
  1442. * }
  1443. * }
  1444. * }
  1445. * SVGList grflist = graphic.getRequiredFeatures();
  1446. * if(grflist != null) {
  1447. * for(int i = 0; i < grflist.getNumberOfItems(); i++) {
  1448. * String str = (String)grflist.getItem(i);
  1449. * if(rflist == null) {
  1450. * // use default feature set
  1451. * if(!(str.equals("org.w3c.svg.static")
  1452. * || str.equals("org.w3c.dom.svg.all"))) {
  1453. * continue;
  1454. * }
  1455. * } else {
  1456. * boolean found = false;
  1457. * for(int j = 0; j < rflist.getNumberOfItems(); j++) {
  1458. * if(rflist.getItem(j).equals(str)) {
  1459. * found = true;
  1460. * break;
  1461. * }
  1462. * }
  1463. * if(!found)
  1464. * continue;
  1465. * }
  1466. * }
  1467. * }
  1468. * SVGList gsllist = graphic.getSystemLanguage();
  1469. * if(gsllist != null) {
  1470. * for(int i = 0; i < gsllist.getNumberOfItems(); i++) {
  1471. * String str = (String)gsllist.getItem(i);
  1472. * if(sllist == null) {
  1473. * // use default feature set
  1474. * if(!(str.equals("en"))) {
  1475. * continue;
  1476. * }
  1477. * } else {
  1478. * boolean found = false;
  1479. * for(int j = 0; j < sllist.getNumberOfItems(); j++) {
  1480. * if(sllist.getItem(j).equals(str)) {
  1481. * found = true;
  1482. * break;
  1483. * }
  1484. * }
  1485. * if(!found)
  1486. * continue;
  1487. * }
  1488. * }
  1489. * }
  1490. * renderElement(fontState, (SVGElement)n, posx, posy);
  1491. * // only render the first valid one
  1492. * break;
  1493. * }
  1494. * }
  1495. * }
  1496. */
  1497. /**
  1498. * render inline area to Text
  1499. *
  1500. * @param area inline area to render
  1501. */
  1502. public void renderWordArea(WordArea area) {
  1503. // System.out.println("TXTRenderer.renderInlineArea: currentXPosition=" + this.currentXPosition + " currentYPosition=" + this.currentYPosition + " text=" + area.getText());
  1504. int rx = this.currentXPosition;
  1505. int bl = this.currentYPosition;
  1506. String s;
  1507. if (area.getPageNumberID() != null) {
  1508. // this text is a page number, so resolve it
  1509. s = idReferences.getPageNumber(area.getPageNumberID());
  1510. if (s == null)
  1511. s = "";
  1512. } else {
  1513. s = area.getText();
  1514. }
  1515. if (debug)
  1516. System.out.println("TXTRenderer.renderInlineArea: rx=" + rx
  1517. + " bl=" + bl + " pageHeight=" + pageHeight);
  1518. addStr((int)((pageHeight - (bl / 100)) * 100 * yFactor) - 1,
  1519. (int)(rx * xFactor), s, true);
  1520. this.currentXPosition += area.getContentWidth();
  1521. }
  1522. /**
  1523. * render inline space to Text
  1524. *
  1525. * @param space space to render
  1526. */
  1527. public void renderInlineSpace(InlineSpace space) {
  1528. this.currentXPosition += space.getSize();
  1529. }
  1530. /**
  1531. * render page into Text
  1532. *
  1533. * @param page page to render
  1534. */
  1535. public void renderPage(Page page) {
  1536. if (debug)
  1537. System.out.println("TXTRenderer.renderPage() page.getHeight() = "
  1538. + page.getHeight());
  1539. maxX = (int)(textCPI * page.getWidth() / 72000 + 1);
  1540. maxY = (int)(textLPI * page.getHeight() / 72000 + 1);
  1541. xFactor = (float)(maxX - 1) / (float)page.getWidth();
  1542. yFactor = (float)(maxY - 1) / (float)page.getHeight();
  1543. charData = new StringBuffer[maxY + 1];
  1544. decoData = new StringBuffer[maxY + 1];
  1545. if (paperheight > 0)
  1546. pageHeight = paperheight;
  1547. else
  1548. pageHeight = page.getHeight() / 100;
  1549. if (debug)
  1550. System.out.println("TXTRenderer.renderPage() maxX=" + maxX
  1551. + " maxY=" + maxY + " xFactor=" + xFactor
  1552. + " yFactor=" + yFactor + " paperHeight="
  1553. + pageHeight);
  1554. this.currentFontName = "";
  1555. this.currentFontSize = 0;
  1556. // currentStream.add("BT\n");
  1557. renderRegions(page);
  1558. // Write out the buffers.
  1559. for (int row = 0; row <= maxY; row++) {
  1560. StringBuffer cr = charData[row];
  1561. StringBuffer dr = decoData[row];
  1562. StringBuffer outr = null;
  1563. if (cr != null && dr == null)
  1564. outr = cr;
  1565. else if (dr != null && cr == null)
  1566. outr = dr;
  1567. else if (cr != null && dr != null) {
  1568. int len = dr.length();
  1569. if (cr.length() > len)
  1570. len = cr.length();
  1571. outr = new StringBuffer();
  1572. for (int countr = 0; countr < len; countr++) {
  1573. if (countr < cr.length() && cr.charAt(countr) != ' ')
  1574. outr.append(cr.charAt(countr));
  1575. else if (countr < dr.length())
  1576. outr.append(dr.charAt(countr));
  1577. else
  1578. outr.append(' ');
  1579. }
  1580. }
  1581. if (outr != null)
  1582. currentStream.add(outr.toString());
  1583. if (row < maxY)
  1584. currentStream.add(lineEnding);
  1585. }
  1586. // End page.
  1587. // if ( ++curdiv == divisions || divisions == -1 )
  1588. // {
  1589. // curdiv = 0;
  1590. // currentStream.add("\f");
  1591. // }
  1592. // Links, etc not implemented...
  1593. /*
  1594. * currentPage = this.pdfDoc.makePage(this.pdfResources, currentStream,
  1595. * page.getWidth()/1000,
  1596. * page.getHeight()/1000, page);
  1597. * if (page.hasLinks()) {
  1598. * currentAnnotList = this.pdfDoc.makeAnnotList();
  1599. * currentPage.setAnnotList(currentAnnotList);
  1600. * Enumeration e = page.getLinkSets().elements();
  1601. * while (e.hasMoreElements()) {
  1602. * LinkSet linkSet = (LinkSet) e.nextElement();
  1603. * linkSet.align();
  1604. * String dest = linkSet.getDest();
  1605. * int linkType = linkSet.getLinkType();
  1606. * Enumeration f = linkSet.getRects().elements();
  1607. * while (f.hasMoreElements()) {
  1608. * LinkedRectangle lrect = (LinkedRectangle) f.nextElement();
  1609. * currentAnnotList.addLink(
  1610. * this.pdfDoc.makeLink(lrect.getRectangle(), dest, linkType));
  1611. * }
  1612. * }
  1613. * } else {
  1614. * // just to be on the safe side
  1615. * currentAnnotList = null;
  1616. * }
  1617. */
  1618. }
  1619. public void startRenderer(OutputStream outputStream)
  1620. throws IOException {
  1621. log.info("rendering areas to TEXT");
  1622. currentStream = new TXTStream(outputStream);
  1623. String encoding = (String)options.get(encodingOptionName);
  1624. try {
  1625. byte buff[] = " ".getBytes(encoding);
  1626. } catch (java.io.UnsupportedEncodingException uee) {
  1627. log.warn("Encoding '"+encoding+"' is not a valid Java encoding. Use UTF-8.");
  1628. encoding = "UTF-8";
  1629. }
  1630. currentStream.setEncoding(encoding);
  1631. firstPage=true;
  1632. }
  1633. /**
  1634. * In Mark's patch, this is endRenderer
  1635. * However, I couldn't see how it builds that way, so
  1636. * i changed it. - Steve gears@apache.org
  1637. */
  1638. public void stopRenderer(OutputStream outputStream)
  1639. throws IOException {
  1640. log.info("writing out TEXT");
  1641. outputStream.flush();
  1642. }
  1643. public void render(Page page, OutputStream outputStream) {
  1644. idReferences = page.getIDReferences();
  1645. if ( firstPage )
  1646. firstPage = false;
  1647. else
  1648. currentStream.add(pageEnding);
  1649. this.renderPage(page);
  1650. currentStream.add(lineEnding);
  1651. }
  1652. }