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.

PDFGraphics2D.java 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. /*****************************************************************************
  2. * Copyright (C) The Apache Software Foundation. All rights reserved. *
  3. * ------------------------------------------------------------------------- *
  4. * This software is published under the terms of the Apache Software License *
  5. * version 1.1, a copy of which has been included with this distribution in *
  6. * the LICENSE file. *
  7. *****************************************************************************/
  8. package org.apache.fop.svg;
  9. import org.apache.fop.pdf.*;
  10. import org.apache.fop.layout.*;
  11. import org.apache.fop.fonts.*;
  12. import org.apache.fop.render.pdf.*;
  13. import org.apache.fop.image.*;
  14. import org.apache.fop.datatypes.ColorSpace;
  15. import org.apache.batik.ext.awt.g2d.*;
  16. import java.text.AttributedCharacterIterator;
  17. import java.awt.*;
  18. import java.awt.Font;
  19. import java.awt.Image;
  20. import java.awt.image.*;
  21. import java.awt.font.*;
  22. import java.awt.geom.*;
  23. import java.awt.image.renderable.*;
  24. import java.io.*;
  25. import java.util.Map;
  26. /**
  27. * This concrete implementation of <tt>AbstractGraphics2D</tt> is a
  28. * simple help to programmers to get started with their own
  29. * implementation of <tt>Graphics2D</tt>.
  30. * <tt>DefaultGraphics2D</tt> implements all the abstract methods
  31. * is <tt>AbstractGraphics2D</tt> and makes it easy to start
  32. * implementing a <tt>Graphic2D</tt> piece-meal.
  33. *
  34. * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
  35. * @version $Id$
  36. * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D
  37. */
  38. public class PDFGraphics2D extends AbstractGraphics2D {
  39. protected PDFDocument pdfDoc;
  40. protected FontState fontState;
  41. boolean standalone = false;
  42. /** the PDF Document being created */
  43. //protected PDFDocument pdfDoc;
  44. //protected FontState fontState;
  45. /** the current stream to add PDF commands to */
  46. StringWriter currentStream = new StringWriter();
  47. /** the current (internal) font name */
  48. protected String currentFontName;
  49. /** the current font size in millipoints */
  50. protected int currentFontSize;
  51. /** the current vertical position in millipoints from bottom */
  52. protected int currentYPosition = 0;
  53. /** the current horizontal position in millipoints from left */
  54. protected int currentXPosition = 0;
  55. /** the current colour for use in svg */
  56. PDFColor currentColour = new PDFColor(0, 0, 0);
  57. FontInfo fontInfo;
  58. /**
  59. * Create a new PDFGraphics2D with the given pdf document info.
  60. * This is used to create a Graphics object for use inside an already
  61. * existing document.
  62. */
  63. public PDFGraphics2D(boolean textAsShapes, FontState fs, PDFDocument doc, String font,
  64. int size, int xpos, int ypos){
  65. super(textAsShapes);
  66. pdfDoc = doc;
  67. currentFontName = font;
  68. currentFontSize = size;
  69. currentYPosition = ypos;
  70. currentXPosition = xpos;
  71. fontState = fs;
  72. }
  73. public PDFGraphics2D(boolean textAsShapes)
  74. {
  75. super(textAsShapes);
  76. }
  77. public String getString() {
  78. return currentStream.toString();
  79. }
  80. public void setGraphicContext(GraphicContext c)
  81. {
  82. gc = c;
  83. }
  84. /**
  85. * This constructor supports the create method
  86. */
  87. public PDFGraphics2D(PDFGraphics2D g){
  88. super(g);
  89. }
  90. /**
  91. * Creates a new <code>Graphics</code> object that is
  92. * a copy of this <code>Graphics</code> object.
  93. * @return a new graphics context that is a copy of
  94. * this graphics context.
  95. */
  96. public Graphics create(){
  97. return new PDFGraphics2D(this);
  98. }
  99. /**
  100. * Draws as much of the specified image as is currently available.
  101. * The image is drawn with its top-left corner at
  102. * (<i>x</i>,&nbsp;<i>y</i>) in this graphics context's coordinate
  103. * space. Transparent pixels in the image do not affect whatever
  104. * pixels are already there.
  105. * <p>
  106. * This method returns immediately in all cases, even if the
  107. * complete image has not yet been loaded, and it has not been dithered
  108. * and converted for the current output device.
  109. * <p>
  110. * If the image has not yet been completely loaded, then
  111. * <code>drawImage</code> returns <code>false</code>. As more of
  112. * the image becomes available, the process that draws the image notifies
  113. * the specified image observer.
  114. * @param img the specified image to be drawn.
  115. * @param x the <i>x</i> coordinate.
  116. * @param y the <i>y</i> coordinate.
  117. * @param observer object to be notified as more of
  118. * the image is converted.
  119. * @see java.awt.Image
  120. * @see java.awt.image.ImageObserver
  121. * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
  122. */
  123. public boolean drawImage(Image img, int x, int y, ImageObserver observer){
  124. System.err.println("drawImage:x, y");
  125. final int width = img.getWidth(observer);
  126. final int height = img.getHeight(observer);
  127. if(width == -1 || height == -1) {
  128. return false;
  129. }
  130. Dimension size = new Dimension(width, height);
  131. BufferedImage buf = buildBufferedImage(size);
  132. java.awt.Graphics2D g = buf.createGraphics();
  133. g.setComposite(AlphaComposite.SrcOver);
  134. g.setBackground(new Color(1, 1, 1, 0));
  135. g.setPaint(new Color(1, 1, 1, 0));
  136. g.fillRect(0, 0, width, height);
  137. g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight()));
  138. if(!g.drawImage(img, 0, 0, observer)) {
  139. return false;
  140. }
  141. g.dispose();
  142. final byte[] result = new byte[buf.getWidth() * buf.getHeight() * 3];
  143. Raster raster = buf.getData();
  144. DataBuffer bd = raster.getDataBuffer();
  145. int count = 0;
  146. switch(bd.getDataType()) {
  147. case DataBuffer.TYPE_INT:
  148. int[][] idata = ((DataBufferInt)bd).getBankData();
  149. for(int i = 0; i < idata.length; i++) {
  150. for(int j = 0; j < idata[i].length; j++) {
  151. //System.out.println("data:" + ((idata[i][j] >> 24) & 0xFF));
  152. if(((idata[i][j] >> 24) & 0xFF) != 255) {
  153. System.out.println("data:" + ((idata[i][j] >> 24) & 0xFF));
  154. result[count++] = (byte)0xFF;
  155. result[count++] = (byte)0xFF;
  156. result[count++] = (byte)0xFF;
  157. } else {
  158. result[count++] = (byte)((idata[i][j] >> 16) & 0xFF);
  159. result[count++] = (byte)((idata[i][j] >> 8) & 0xFF);
  160. result[count++] = (byte)((idata[i][j]) & 0xFF);
  161. }
  162. }
  163. }
  164. break;
  165. default:
  166. // error
  167. break;
  168. }
  169. try {
  170. FopImage fopimg = new TempImage(width, height, result);
  171. int xObjectNum = this.pdfDoc.addImage(fopimg);
  172. /*currentStream.write("q\n" + (((float) width)) +
  173. " 0 0 " + (((float) height)) + " " +
  174. x + " " +
  175. ((float)(y - height)) + " cm\n" + "/Im" +
  176. xObjectNum + " Do\nQ\n");*/
  177. AffineTransform at = getTransform();
  178. double[] matrix = new double[6];
  179. at.getMatrix(matrix);
  180. currentStream.write("q\n" + matrix[0] +
  181. " " + matrix[1] + " " + matrix[2] + " " + matrix[3] + " " +
  182. matrix[4] + " " +
  183. matrix[5] + " cm\n");
  184. currentStream.write("" + width +
  185. " 0 0 " + (-height) + " " +
  186. x + " " +
  187. (y + height) + " cm\n" + "/Im" +
  188. xObjectNum + " Do\nQ\n");
  189. } catch(Exception e) {
  190. e.printStackTrace();
  191. }
  192. return true;
  193. }
  194. public BufferedImage buildBufferedImage(Dimension size) {
  195. return new BufferedImage(size.width, size.height,
  196. BufferedImage.TYPE_INT_ARGB);
  197. }
  198. class TempImage implements FopImage {
  199. int m_height;
  200. int m_width;
  201. int m_bitsPerPixel;
  202. ColorSpace m_colorSpace;
  203. int m_bitmapSiye;
  204. byte[] m_bitmaps;
  205. PDFColor transparent = new PDFColor(255, 255, 255);
  206. TempImage(int width, int height, byte[] result) throws FopImageException
  207. {
  208. this.m_height = height;
  209. this.m_width = width;
  210. this.m_bitsPerPixel = 8;
  211. this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB);
  212. //this.m_isTransparent = false;
  213. //this.m_bitmapsSize = this.m_width * this.m_height * 3;
  214. this.m_bitmaps = result;
  215. }
  216. public String getURL() {return "" + m_bitmaps;}
  217. // image size
  218. public int getWidth() throws FopImageException
  219. {
  220. return m_width;
  221. }
  222. public int getHeight() throws FopImageException
  223. {return m_height;}
  224. // DeviceGray, DeviceRGB, or DeviceCMYK
  225. public ColorSpace getColorSpace() throws FopImageException
  226. {return m_colorSpace;}
  227. // bits per pixel
  228. public int getBitsPerPixel() throws FopImageException
  229. {return m_bitsPerPixel;}
  230. // For transparent images
  231. public boolean isTransparent() throws FopImageException
  232. {return transparent != null;}
  233. public PDFColor getTransparentColor() throws FopImageException
  234. {return transparent;}
  235. // get the image bytes, and bytes properties
  236. // get uncompressed image bytes
  237. public byte[] getBitmaps() throws FopImageException
  238. {return m_bitmaps;}
  239. // width * (bitsPerPixel / 8) * height, no ?
  240. public int getBitmapsSize() throws FopImageException
  241. {return m_width * m_height * 3;}
  242. // get compressed image bytes
  243. // I don't know if we really need it, nor if it
  244. // should be changed...
  245. public byte[] getRessourceBytes() throws FopImageException
  246. {return null;}
  247. public int getRessourceBytesSize() throws FopImageException
  248. {return 0;}
  249. // return null if no corresponding PDFFilter
  250. public PDFFilter getPDFFilter() throws FopImageException
  251. {return null;}
  252. // release memory
  253. public void close() {}
  254. }
  255. /**
  256. * Draws as much of the specified image as has already been scaled
  257. * to fit inside the specified rectangle.
  258. * <p>
  259. * The image is drawn inside the specified rectangle of this
  260. * graphics context's coordinate space, and is scaled if
  261. * necessary. Transparent pixels do not affect whatever pixels
  262. * are already there.
  263. * <p>
  264. * This method returns immediately in all cases, even if the
  265. * entire image has not yet been scaled, dithered, and converted
  266. * for the current output device.
  267. * If the current output representation is not yet complete, then
  268. * <code>drawImage</code> returns <code>false</code>. As more of
  269. * the image becomes available, the process that draws the image notifies
  270. * the image observer by calling its <code>imageUpdate</code> method.
  271. * <p>
  272. * A scaled version of an image will not necessarily be
  273. * available immediately just because an unscaled version of the
  274. * image has been constructed for this output device. Each size of
  275. * the image may be cached separately and generated from the original
  276. * data in a separate image production sequence.
  277. * @param img the specified image to be drawn.
  278. * @param x the <i>x</i> coordinate.
  279. * @param y the <i>y</i> coordinate.
  280. * @param width the width of the rectangle.
  281. * @param height the height of the rectangle.
  282. * @param observer object to be notified as more of
  283. * the image is converted.
  284. * @see java.awt.Image
  285. * @see java.awt.image.ImageObserver
  286. * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
  287. */
  288. public boolean drawImage(Image img, int x, int y,
  289. int width, int height,
  290. ImageObserver observer) {
  291. System.out.println("drawImage");
  292. return true;
  293. }
  294. /**
  295. * Disposes of this graphics context and releases
  296. * any system resources that it is using.
  297. * A <code>Graphics</code> object cannot be used after
  298. * <code>dispose</code>has been called.
  299. * <p>
  300. * When a Java program runs, a large number of <code>Graphics</code>
  301. * objects can be created within a short time frame.
  302. * Although the finalization process of the garbage collector
  303. * also disposes of the same system resources, it is preferable
  304. * to manually free the associated resources by calling this
  305. * method rather than to rely on a finalization process which
  306. * may not run to completion for a long period of time.
  307. * <p>
  308. * Graphics objects which are provided as arguments to the
  309. * <code>paint</code> and <code>update</code> methods
  310. * of components are automatically released by the system when
  311. * those methods return. For efficiency, programmers should
  312. * call <code>dispose</code> when finished using
  313. * a <code>Graphics</code> object only if it was created
  314. * directly from a component or another <code>Graphics</code> object.
  315. * @see java.awt.Graphics#finalize
  316. * @see java.awt.Component#paint
  317. * @see java.awt.Component#update
  318. * @see java.awt.Component#getGraphics
  319. * @see java.awt.Graphics#create
  320. */
  321. public void dispose(){
  322. System.out.println("dispose");
  323. }
  324. /**
  325. * Strokes the outline of a <code>Shape</code> using the settings of the
  326. * current <code>Graphics2D</code> context. The rendering attributes
  327. * applied include the <code>Clip</code>, <code>Transform</code>,
  328. * <code>Paint</code>, <code>Composite</code> and
  329. * <code>Stroke</code> attributes.
  330. * @param s the <code>Shape</code> to be rendered
  331. * @see #setStroke
  332. * @see #setPaint
  333. * @see java.awt.Graphics#setColor
  334. * @see #transform
  335. * @see #setTransform
  336. * @see #clip
  337. * @see #setClip
  338. * @see #setComposite
  339. */
  340. public void draw(Shape s){
  341. //System.out.println("draw(Shape)");
  342. Color c = getColor();
  343. currentColour = new PDFColor(c.getRed(), c.getGreen(), c.getBlue());
  344. currentStream.write(currentColour.getColorSpaceOut(true));
  345. c = getBackground();
  346. PDFColor col = new PDFColor(c.getRed(), c.getGreen(), c.getBlue());
  347. currentStream.write(col.getColorSpaceOut(false));
  348. PDFNumber pdfNumber = new PDFNumber();
  349. PathIterator iter = s.getPathIterator(getTransform());
  350. while(!iter.isDone()) {
  351. double vals[] = new double[6];
  352. int type = iter.currentSegment(vals);
  353. switch(type) {
  354. case PathIterator.SEG_CUBICTO:
  355. currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) +
  356. " " + pdfNumber.doubleOut(vals[2]) + " " + pdfNumber.doubleOut(vals[3]) + " " +
  357. pdfNumber.doubleOut(vals[4]) + " " + pdfNumber.doubleOut(vals[5]) + " c\n");
  358. break;
  359. case PathIterator.SEG_LINETO:
  360. currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) + " l\n");
  361. break;
  362. case PathIterator.SEG_MOVETO:
  363. currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) + " m\n");
  364. break;
  365. case PathIterator.SEG_QUADTO:
  366. currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) + " " +
  367. pdfNumber.doubleOut(vals[2]) + " " + pdfNumber.doubleOut(vals[3]) + " y\n");
  368. break;
  369. case PathIterator.SEG_CLOSE:
  370. currentStream.write("h\n");
  371. break;
  372. default:
  373. break;
  374. }
  375. iter.next();
  376. }
  377. doDrawing(false, true, false);
  378. }
  379. /**
  380. * Renders a {@link RenderedImage},
  381. * applying a transform from image
  382. * space into user space before drawing.
  383. * The transformation from user space into device space is done with
  384. * the current <code>Transform</code> in the <code>Graphics2D</code>.
  385. * The specified transformation is applied to the image before the
  386. * transform attribute in the <code>Graphics2D</code> context is applied.
  387. * The rendering attributes applied include the <code>Clip</code>,
  388. * <code>Transform</code>, and <code>Composite</code> attributes. Note
  389. * that no rendering is done if the specified transform is
  390. * noninvertible.
  391. * @param img the image to be rendered
  392. * @param xform the transformation from image space into user space
  393. * @see #transform
  394. * @see #setTransform
  395. * @see #setComposite
  396. * @see #clip
  397. * @see #setClip
  398. */
  399. public void drawRenderedImage(RenderedImage img,
  400. AffineTransform xform) {
  401. System.out.println("drawRenderedImage");
  402. }
  403. /**
  404. * Renders a
  405. * {@link RenderableImage},
  406. * applying a transform from image space into user space before drawing.
  407. * The transformation from user space into device space is done with
  408. * the current <code>Transform</code> in the <code>Graphics2D</code>.
  409. * The specified transformation is applied to the image before the
  410. * transform attribute in the <code>Graphics2D</code> context is applied.
  411. * The rendering attributes applied include the <code>Clip</code>,
  412. * <code>Transform</code>, and <code>Composite</code> attributes. Note
  413. * that no rendering is done if the specified transform is
  414. * noninvertible.
  415. *<p>
  416. * Rendering hints set on the <code>Graphics2D</code> object might
  417. * be used in rendering the <code>RenderableImage</code>.
  418. * If explicit control is required over specific hints recognized by a
  419. * specific <code>RenderableImage</code>, or if knowledge of which hints
  420. * are used is required, then a <code>RenderedImage</code> should be
  421. * obtained directly from the <code>RenderableImage</code>
  422. * and rendered using
  423. *{@link #drawRenderedImage(RenderedImage, AffineTransform) drawRenderedImage}.
  424. * @param img the image to be rendered
  425. * @param xform the transformation from image space into user space
  426. * @see #transform
  427. * @see #setTransform
  428. * @see #setComposite
  429. * @see #clip
  430. * @see #setClip
  431. * @see #drawRenderedImage
  432. */
  433. public void drawRenderableImage(RenderableImage img,
  434. AffineTransform xform){
  435. System.out.println("drawRenderableImage");
  436. }
  437. /**
  438. * Renders the text specified by the specified <code>String</code>,
  439. * using the current <code>Font</code> and <code>Paint</code> attributes
  440. * in the <code>Graphics2D</code> context.
  441. * The baseline of the first character is at position
  442. * (<i>x</i>,&nbsp;<i>y</i>) in the User Space.
  443. * The rendering attributes applied include the <code>Clip</code>,
  444. * <code>Transform</code>, <code>Paint</code>, <code>Font</code> and
  445. * <code>Composite</code> attributes. For characters in script systems
  446. * such as Hebrew and Arabic, the glyphs can be rendered from right to
  447. * left, in which case the coordinate supplied is the location of the
  448. * leftmost character on the baseline.
  449. * @param s the <code>String</code> to be rendered
  450. * @param x,&nbsp;y the coordinates where the <code>String</code>
  451. * should be rendered
  452. * @see #setPaint
  453. * @see java.awt.Graphics#setColor
  454. * @see java.awt.Graphics#setFont
  455. * @see #setTransform
  456. * @see #setComposite
  457. * @see #setClip
  458. */
  459. public void drawString(String s, float x, float y){
  460. System.out.println("drawString(String)");
  461. }
  462. /**
  463. * Renders the text of the specified iterator, using the
  464. * <code>Graphics2D</code> context's current <code>Paint</code>. The
  465. * iterator must specify a font
  466. * for each character. The baseline of the
  467. * first character is at position (<i>x</i>,&nbsp;<i>y</i>) in the
  468. * User Space.
  469. * The rendering attributes applied include the <code>Clip</code>,
  470. * <code>Transform</code>, <code>Paint</code>, and
  471. * <code>Composite</code> attributes.
  472. * For characters in script systems such as Hebrew and Arabic,
  473. * the glyphs can be rendered from right to left, in which case the
  474. * coordinate supplied is the location of the leftmost character
  475. * on the baseline.
  476. * @param iterator the iterator whose text is to be rendered
  477. * @param x,&nbsp;y the coordinates where the iterator's text is to be
  478. * rendered
  479. * @see #setPaint
  480. * @see java.awt.Graphics#setColor
  481. * @see #setTransform
  482. * @see #setComposite
  483. * @see #setClip
  484. */
  485. public void drawString(AttributedCharacterIterator iterator,
  486. float x, float y) {
  487. System.err.println("drawString(AttributedCharacterIterator)");
  488. }
  489. /**
  490. * Fills the interior of a <code>Shape</code> using the settings of the
  491. * <code>Graphics2D</code> context. The rendering attributes applied
  492. * include the <code>Clip</code>, <code>Transform</code>,
  493. * <code>Paint</code>, and <code>Composite</code>.
  494. * @param s the <code>Shape</code> to be filled
  495. * @see #setPaint
  496. * @see java.awt.Graphics#setColor
  497. * @see #transform
  498. * @see #setTransform
  499. * @see #setComposite
  500. * @see #clip
  501. * @see #setClip
  502. */
  503. public void fill(Shape s){
  504. //System.err.println("fill");
  505. Color c = getColor();
  506. currentColour = new PDFColor(c.getRed(), c.getGreen(), c.getBlue());
  507. currentStream.write(currentColour.getColorSpaceOut(true));
  508. c = getBackground();
  509. PDFColor col = new PDFColor(c.getRed(), c.getGreen(), c.getBlue());
  510. currentStream.write(col.getColorSpaceOut(false));
  511. PDFNumber pdfNumber = new PDFNumber();
  512. PathIterator iter = s.getPathIterator(getTransform());
  513. while(!iter.isDone()) {
  514. double vals[] = new double[6];
  515. int type = iter.currentSegment(vals);
  516. switch(type) {
  517. case PathIterator.SEG_CUBICTO:
  518. currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) +
  519. " " + pdfNumber.doubleOut(vals[2]) + " " + pdfNumber.doubleOut(vals[3]) + " " +
  520. pdfNumber.doubleOut(vals[4]) + " " + pdfNumber.doubleOut(vals[5]) + " c\n");
  521. break;
  522. case PathIterator.SEG_LINETO:
  523. currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) + " l\n");
  524. break;
  525. case PathIterator.SEG_MOVETO:
  526. currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) + " m\n");
  527. break;
  528. case PathIterator.SEG_QUADTO:
  529. currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) + " " +
  530. pdfNumber.doubleOut(vals[2]) + " " + pdfNumber.doubleOut(vals[3]) + " y\n");
  531. break;
  532. case PathIterator.SEG_CLOSE:
  533. currentStream.write("h\n");
  534. break;
  535. default:
  536. break;
  537. }
  538. iter.next();
  539. }
  540. doDrawing(true, false, iter.getWindingRule() == PathIterator.WIND_EVEN_ODD);
  541. }
  542. protected void doDrawing(boolean fill, boolean stroke, boolean nonzero) {
  543. if (fill) {
  544. if (stroke) {
  545. if (!nonzero)
  546. currentStream.write("B*\n");
  547. else
  548. currentStream.write("B\n");
  549. } else {
  550. if (!nonzero)
  551. currentStream.write("f*\n");
  552. else
  553. currentStream.write("f\n");
  554. }
  555. } else {
  556. //if(stroke)
  557. currentStream.write("S\n");
  558. }
  559. }
  560. /**
  561. * Returns the device configuration associated with this
  562. * <code>Graphics2D</code>.
  563. */
  564. public GraphicsConfiguration getDeviceConfiguration(){
  565. System.out.println("getDeviceConviguration");
  566. return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
  567. }
  568. /**
  569. * Used to create proper font metrics
  570. */
  571. private Graphics2D fmg;
  572. {
  573. BufferedImage bi
  574. = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
  575. fmg = bi.createGraphics();
  576. }
  577. /**
  578. * Gets the font metrics for the specified font.
  579. * @return the font metrics for the specified font.
  580. * @param f the specified font
  581. * @see java.awt.Graphics#getFont
  582. * @see java.awt.FontMetrics
  583. * @see java.awt.Graphics#getFontMetrics()
  584. */
  585. public FontMetrics getFontMetrics(Font f){
  586. return fmg.getFontMetrics(f);
  587. }
  588. /**
  589. * Sets the paint mode of this graphics context to alternate between
  590. * this graphics context's current color and the new specified color.
  591. * This specifies that logical pixel operations are performed in the
  592. * XOR mode, which alternates pixels between the current color and
  593. * a specified XOR color.
  594. * <p>
  595. * When drawing operations are performed, pixels which are the
  596. * current color are changed to the specified color, and vice versa.
  597. * <p>
  598. * Pixels that are of colors other than those two colors are changed
  599. * in an unpredictable but reversible manner; if the same figure is
  600. * drawn twice, then all pixels are restored to their original values.
  601. * @param c1 the XOR alternation color
  602. */
  603. public void setXORMode(Color c1){
  604. System.out.println("setXORMode");
  605. }
  606. /**
  607. * Copies an area of the component by a distance specified by
  608. * <code>dx</code> and <code>dy</code>. From the point specified
  609. * by <code>x</code> and <code>y</code>, this method
  610. * copies downwards and to the right. To copy an area of the
  611. * component to the left or upwards, specify a negative value for
  612. * <code>dx</code> or <code>dy</code>.
  613. * If a portion of the source rectangle lies outside the bounds
  614. * of the component, or is obscured by another window or component,
  615. * <code>copyArea</code> will be unable to copy the associated
  616. * pixels. The area that is omitted can be refreshed by calling
  617. * the component's <code>paint</code> method.
  618. * @param x the <i>x</i> coordinate of the source rectangle.
  619. * @param y the <i>y</i> coordinate of the source rectangle.
  620. * @param width the width of the source rectangle.
  621. * @param height the height of the source rectangle.
  622. * @param dx the horizontal distance to copy the pixels.
  623. * @param dy the vertical distance to copy the pixels.
  624. */
  625. public void copyArea(int x, int y, int width, int height,
  626. int dx, int dy){
  627. System.out.println("copyArea");
  628. }
  629. }