2 * Copyright (c) 2009, Takeyuki Nagao
5 * Redistribution and use in source and binary forms, with or
6 * without modification, are permitted provided that the
7 * following conditions are met:
9 * * Redistributions of source code must retain the above
10 * copyright notice, this list of conditions and the
11 * following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the
14 * following disclaimer in the documentation and/or other
15 * materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
18 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
29 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
33 package jp.sourceforge.dvibrowser.dvicore.special;
36 import java.io.PrintWriter;
37 import java.io.StringWriter;
38 import java.util.HashMap;
39 import java.util.Vector;
41 import jp.sourceforge.dvibrowser.dvicore.DviException;
42 import jp.sourceforge.dvibrowser.dvicore.DviObject;
43 import jp.sourceforge.dvibrowser.dvicore.DviUnit;
44 import jp.sourceforge.dvibrowser.dvicore.api.DviContextSupport;
45 import jp.sourceforge.dvibrowser.dvicore.util.DviUtils;
48 public class EmbeddedPostScript
50 // private static final Logger LOGGER = Logger.getLogger(EmbeddedPostScript.class.getName());
52 private final Vector<Prologue> prologues = new Vector<Prologue>();
53 private final Vector<Global> globals = new Vector<Global>();
54 private final HashMap<Integer, Vector<Local>> page2locals
55 = new HashMap<Integer, Vector<Local>>();
57 private Vector<Local> locals = null;
59 public void beginPage(int pageNum)
61 if (page2locals.containsKey(pageNum)) {
62 locals = page2locals.get(pageNum);
64 locals = new Vector<Local>();
65 page2locals.put(pageNum, locals);
74 public void add(Prologue a)
79 public void add(Global a)
84 public void add(Local a)
89 private static void writePostScript(Vector<? extends Element> ce,
90 PrintWriter pw, Config cfg) throws DviException
92 for (Element e : ce) {
93 e.writePostScript(pw, cfg);
97 public String toPostScript(int pageNum, int dpi)
100 if (!page2locals.containsKey(pageNum))
103 Vector<Local> ls = page2locals.get(pageNum);
105 if (ls == null || ls.size() == 0)
108 Config cfg = new Config(dpi);
111 StringWriter sw = new StringWriter();
112 PrintWriter pw = new PrintWriter(sw);
114 pw.println("%!PS-Adobe-2.0");
115 pw.println("%%Pages: 1");
116 pw.println("%%BoundingBox: 0 0 595 842"); // Change bounding box depending on paper sizes.
117 pw.println("%%EndComments");
120 writePostScript(prologues, pw, cfg);
122 // TODO: Use the paper size to set the bounding boxes
125 + " 39158280 55380996 "
131 pw.println("TeXDict begin 1 0 bop 0 0 a");
133 writePostScript(globals, pw, cfg);
135 writePostScript(ls, pw, cfg);
138 pw.println("showpage");
141 return sw.toString();
142 } catch (Exception ex) {
143 throw new DviException(ex);
147 private static class Config
149 public final int dpi;
150 private Config(int dpi) {
155 private static interface Element
157 public abstract void writePostScript(PrintWriter pw, Config cfg) throws DviException;
160 public static interface Local extends Element {}
161 public static interface Global extends Element {}
162 public static interface Prologue extends Element {}
164 public static class ProloguePostScript
166 public final String postScript;
167 public ProloguePostScript(String postScript) {
168 this.postScript = postScript;
171 public void writePostScript(PrintWriter pw, Config cfg)
173 pw.println(postScript);
177 // TODO: support encoding.
178 private static String escapeFilenameForPS(String s)
180 return s.replaceAll("\\\\", "\\\\\\\\");
183 public static class PrologueFile
187 public final String fileName;
188 public PrologueFile(DviContextSupport dcs, String fileName) {
190 this.fileName = fileName;
193 public void writePostScript(PrintWriter pw, Config cfg) throws DviException
195 File file = DviUtils.toLocalFile(getDviContext().getDviResource(fileName));
196 if (file == null || !file.exists())
197 throw new DviException("Cannot find postscript prologue: " + fileName);
199 String escapedFilename = escapeFilenameForPS(file.getAbsolutePath());
201 " (" + escapedFilename + ") run"
206 public static class HeaderSpecial
209 public final String fileName;
210 public HeaderSpecial(String fileName) {
211 this.fileName = fileName;
214 public void writePostScript(PrintWriter pw, Config cfg)
216 String escapedFilename = escapeFilenameForPS(fileName);
218 " (" + escapedFilename + ") run"
223 public static class BangSpecial
226 public final String postScript;
227 public BangSpecial(String postScript) {
228 this.postScript = postScript;
231 public void writePostScript(PrintWriter pw, Config cfg)
234 " @defspecial " + postScript + " @fedspecial"
239 private static class WithReferencePoint
244 public final DviUnit dviUnit;
245 private WithReferencePoint(int h, int v, DviUnit dviUnit)
249 this.dviUnit = dviUnit;
252 public void writePostScript(PrintWriter pw, Config cfg)
254 double psH = dviUnit.mapToPixelDouble(h, cfg.dpi);
255 double psV = dviUnit.mapToPixelDouble(v, cfg.dpi);
257 " " + psH + " " + psV + " moveto "
262 public static class PSFileSpecial
263 extends WithReferencePoint
265 public final String fileName;
266 public final int llx;
267 public final int lly;
268 public final int urx;
269 public final int ury;
270 public final int rwi;
271 public final int rhi;
272 public final int angle;
273 public PSFileSpecial(
274 int h, int v, DviUnit dviUnit,
276 int llx, int lly, int urx, int ury,
277 int rwi, int rhi, int angle
279 super(h, v, dviUnit);
280 this.fileName = fileName;
290 public void writePostScript(PrintWriter pw, Config cfg)
292 super.writePostScript(pw, cfg);
293 String escapedFilename = escapeFilenameForPS(fileName);
294 // if (new File(realFile).exists()) {
297 + " " + llx + " @llx"
298 + " " + lly + " @lly"
299 + " " + urx + " @urx"
300 + " " + ury + " @ury"
301 + ((rwi != 0) ? (" " + rwi + " @rwi") : "")
302 + ((rhi != 0) ? (" " + rhi + " @rhi") : "")
303 + ((angle != 0) ? (" " + angle + " @angle") : "")
305 + " (" + escapedFilename + ") run"
313 public static class PSSpecial
314 extends WithReferencePoint
316 public final String postScript;
317 public PSSpecial(int h, int v, DviUnit dviUnit, String postScript)
319 super(h, v, dviUnit);
320 this.postScript = postScript;
323 public void writePostScript(PrintWriter pw, Config cfg)
325 super.writePostScript(pw, cfg);
332 public static class QuoteSpecial
335 public QuoteSpecial(int h, int v, DviUnit dviUnit, String postScript)
337 super(h, v, dviUnit, postScript);
340 public void writePostScript(PrintWriter pw, Config cfg)
342 super.writePostScript(pw, cfg);