123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- /*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
- package org.apache.fop.render.ps;
-
- // FOP
- import org.apache.fop.svg.SVGArea;
- import org.apache.fop.render.AbstractRenderer;
- import org.apache.fop.render.Renderer;
- import org.apache.fop.image.ImageArea;
- import org.apache.fop.image.FopImage;
- import org.apache.fop.image.FopImageException;
- import org.apache.fop.layout.*;
- import org.apache.fop.layout.inline.*;
- import org.apache.fop.datatypes.*;
- import org.apache.fop.fo.properties.*;
- import org.apache.fop.render.pdf.Font;
- import org.apache.fop.image.*;
-
- import org.apache.batik.bridge.*;
- import org.apache.batik.swing.svg.*;
- import org.apache.batik.swing.gvt.*;
- import org.apache.batik.gvt.*;
- import org.apache.batik.gvt.renderer.*;
- import org.apache.batik.gvt.filter.*;
- import org.apache.batik.gvt.event.*;
-
- import org.apache.log.Logger;
-
- // SVG
- import org.w3c.dom.svg.SVGSVGElement;
- import org.w3c.dom.svg.SVGDocument;
- import org.w3c.dom.*;
- import org.w3c.dom.svg.*;
-
- // Java
- import java.io.*;
- import java.util.*;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.util.Enumeration;
- import java.util.Vector;
- import java.util.Hashtable;
- import java.awt.geom.AffineTransform;
- import java.awt.geom.Dimension2D;
- import java.awt.Point;
- import java.awt.RenderingHints;
- import java.awt.Dimension;
-
- /**
- * Renderer that renders to PostScript.
- * <br>
- * This class currently generates PostScript Level 2 code. The only exception
- * is the FlateEncode filter which is a Level 3 feature. The filters in use
- * are hardcoded at the moment.
- * <br>
- * This class follows the Document Structuring Conventions (DSC) version 3.0
- * (If I did everything right). If anyone modifies this renderer please make
- * sure to also follow the DSC to make it simpler to programmatically modify
- * the generated Postscript files (ex. extract pages etc.).
- * <br>
- * TODO: Character size/spacing, SVG Transcoder for Batik, configuration, move
- * to PrintRenderer, maybe improve filters (I'm not very proud of them), add a
- * RunLengthEncode filter (useful for Level 2 Postscript), Improve
- * DocumentProcessColors stuff (probably needs to be configurable, then maybe
- * add a color to grayscale conversion for bitmaps to make output smaller (See
- * PCLRenderer), font embedding, support different character encodings, try to
- * implement image transparency, positioning of images is wrong etc. <P>
- *
- * Modified by Mark Lillywhite mark-fop@inomial.com, to use the new
- * Renderer interface. This PostScript renderer appears to be the
- * most efficient at producing output.
- *
- * @author Jeremias Märki
- */
- public class PSRenderer extends AbstractRenderer {
-
- /**
- * the application producing the PostScript
- */
- protected String producer;
-
- int imagecount = 0; // DEBUG
-
- private boolean enableComments = true;
-
- /**
- * the stream used to output the PostScript
- */
- protected PSStream out;
- private boolean ioTrouble = false;
-
- private String currentFontName;
- private int currentFontSize;
- private int pageHeight;
- private int pageWidth;
- private float currRed;
- private float currGreen;
- private float currBlue;
-
- private FontInfo fontInfo;
-
- protected IDReferences idReferences;
-
- /**
- * set the document's producer
- *
- * @param producer string indicating application producing the PostScript
- */
- public void setProducer(String producer) {
- this.producer = producer;
- }
-
- /**
- * write out a command
- */
- protected void write(String cmd) {
- try {
- out.write(cmd);
- } catch (IOException e) {
- if (!ioTrouble)
- e.printStackTrace();
- ioTrouble = true;
- }
- }
-
- /**
- * write out a comment
- */
- protected void comment(String comment) {
- if (this.enableComments)
- write(comment);
- }
-
- protected void writeFontDict(FontInfo fontInfo) {
- write("%%BeginResource: procset FOPFonts");
- write("%%Title: Font setup (shortcuts) for this file");
- write("/FOPFonts 100 dict dup begin");
- write("/bd{bind def}bind def");
- write("/ld{load def}bd");
- write("/M/moveto ld");
- write("/RM/rmoveto ld");
- write("/t/show ld");
-
- write("/ux 0.0 def");
- write("/uy 0.0 def");
- // write("/cf /Helvetica def");
- // write("/cs 12000 def");
-
- // <font> <size> F
- write("/F {");
- write(" /Tp exch def");
- // write(" currentdict exch get");
- write(" /Tf exch def");
- write(" Tf findfont Tp scalefont setfont");
- write(" /cf Tf def /cs Tp def /cw ( ) stringwidth pop def");
- write("} bd");
-
- write("/ULS {currentpoint /uy exch def /ux exch def} bd");
- write("/ULE {");
- write(" /Tcx currentpoint pop def");
- write(" gsave");
- write(" newpath");
- write(" cf findfont cs scalefont dup");
- write(" /FontMatrix get 0 get /Ts exch def /FontInfo get dup");
- write(" /UnderlinePosition get Ts mul /To exch def");
- write(" /UnderlineThickness get Ts mul /Tt exch def");
- write(" ux uy To add moveto Tcx uy To add lineto");
- write(" Tt setlinewidth stroke");
- write(" grestore");
- write("} bd");
-
- write("/OLE {");
- write(" /Tcx currentpoint pop def");
- write(" gsave");
- write(" newpath");
- write(" cf findfont cs scalefont dup");
- write(" /FontMatrix get 0 get /Ts exch def /FontInfo get dup");
- write(" /UnderlinePosition get Ts mul /To exch def");
- write(" /UnderlineThickness get Ts mul /Tt exch def");
- write(" ux uy To add cs add moveto Tcx uy To add cs add lineto");
- write(" Tt setlinewidth stroke");
- write(" grestore");
- write("} bd");
-
- write("/SOE {");
- write(" /Tcx currentpoint pop def");
- write(" gsave");
- write(" newpath");
- write(" cf findfont cs scalefont dup");
- write(" /FontMatrix get 0 get /Ts exch def /FontInfo get dup");
- write(" /UnderlinePosition get Ts mul /To exch def");
- write(" /UnderlineThickness get Ts mul /Tt exch def");
- write(" ux uy To add cs 10 mul 26 idiv add moveto Tcx uy To add cs 10 mul 26 idiv add lineto");
- write(" Tt setlinewidth stroke");
- write(" grestore");
- write("} bd");
-
-
-
- // write("/gfF1{/Helvetica findfont} bd");
- // write("/gfF3{/Helvetica-Bold findfont} bd");
- Hashtable fonts = fontInfo.getFonts();
- Enumeration enum = fonts.keys();
- while (enum.hasMoreElements()) {
- String key = (String)enum.nextElement();
- Font fm = (Font)fonts.get(key);
- write("/" + key + " /" + fm.fontName() + " def");
- }
- write("end def");
- write("%%EndResource");
- enum = fonts.keys();
- while (enum.hasMoreElements()) {
- String key = (String)enum.nextElement();
- Font fm = (Font)fonts.get(key);
- write("/" + fm.fontName() + " findfont");
- write("dup length dict begin");
- write(" {1 index /FID ne {def} {pop pop} ifelse} forall");
- write(" /Encoding ISOLatin1Encoding def");
- write(" currentdict");
- write("end");
- write("/" + fm.fontName() + " exch definefont pop");
- }
- }
-
- protected void movetoCurrPosition() {
- write(this.currentIPPosition + " " + this.currentBPPosition + " M");
- }
-
- /**
- * set up the font info
- *
- * @param fontInfo the font info object to set up
- */
- public void setupFontInfo(FontInfo fontInfo) {
- /* use PDF's font setup to get PDF metrics */
- org.apache.fop.render.pdf.FontSetup.setup(fontInfo);
- this.fontInfo = fontInfo;
- }
-
- protected void addFilledRect(int x, int y, int w, int h,
- ColorType col) {
- write("newpath");
- write(x + " " + y + " M");
- write(w + " 0 rlineto");
- write("0 " + (-h) + " rlineto");
- write((-w) + " 0 rlineto");
- write("0 " + h + " rlineto");
- write("closepath");
- useColor(col);
- write("fill");
- }
-
- private long copyStream(InputStream in, OutputStream out,
- int bufferSize) throws IOException {
- long bytes_total = 0;
- byte[] buf = new byte[bufferSize];
- int bytes_read;
- while ((bytes_read = in.read(buf)) != -1) {
- bytes_total += bytes_read;
- out.write(buf, 0, bytes_read);
- }
- return bytes_total;
- }
-
-
- private long copyStream(InputStream in,
- OutputStream out) throws IOException {
- return copyStream(in, out, 4096);
- }
-
- public void useFont(String name, int size) {
- if ((currentFontName != name) || (currentFontSize != size)) {
- write(name + " " + size + " F");
- currentFontName = name;
- currentFontSize = size;
- }
- }
-
- private void useColor(ColorType col) {
- useColor(col.red(), col.green(), col.blue());
- }
-
- private void useColor(float red, float green, float blue) {
- if ((red != currRed) || (green != currGreen) || (blue != currBlue)) {
- write(red + " " + green + " " + blue + " setrgbcolor");
- currRed = red;
- currGreen = green;
- currBlue = blue;
- }
- }
-
- /**
- */
- public void startRenderer(OutputStream outputStream)
- throws IOException {
- log.debug("rendering areas to PostScript");
-
- this.out = new PSStream(outputStream);
- write("%!PS-Adobe-3.0");
- write("%%Creator: "+this.producer);
- write("%%DocumentProcessColors: Black");
- write("%%DocumentSuppliedResources: procset FOPFonts");
- write("%%EndComments");
- write("%%BeginDefaults");
- write("%%EndDefaults");
- write("%%BeginProlog");
- write("%%EndProlog");
- write("%%BeginSetup");
- writeFontDict(fontInfo);
- write("%%EndSetup");
- write("FOPFonts begin");
- }
-
- /**
- */
- public void stopRenderer()
- throws IOException {
- write("%%Trailer");
- write("%%EOF");
- this.out.flush();
- }
-
- }
|