KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > print > BufferPrintable


1 /*
2  * BufferPrintable.java - Printable implementation
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 2001, 2003 Slava Pestov
7  * Portions copyright (C) 2002 Thomas Dilts
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22  */

23
24 package org.gjt.sp.jedit.print;
25
26 //{{{ Imports
27
import javax.swing.text.TabExpander JavaDoc;
28 import javax.swing.SwingUtilities JavaDoc;
29 import java.awt.font.*;
30 import java.awt.geom.*;
31 import java.awt.print.*;
32 import java.awt.*;
33 import java.lang.reflect.Method JavaDoc;
34 import java.util.*;
35 import java.util.List JavaDoc;
36
37 import org.gjt.sp.jedit.syntax.*;
38 import org.gjt.sp.jedit.*;
39 import org.gjt.sp.util.*;
40 //}}}
41

42 /**
43  * @version $Id: BufferPrintable.java 8258 2006-12-25 21:39:27Z kpouer $
44  */

45 class BufferPrintable implements Printable
46 {
47     //{{{ BufferPrintable constructor
48
BufferPrintable(PrinterJob job, Object JavaDoc format,
49         View view, Buffer buffer, Font font, boolean header,
50         boolean footer, boolean lineNumbers, boolean color)
51     {
52         this.job = job;
53         this.format = format;
54         this.view = view;
55         this.buffer = buffer;
56         this.font = font;
57         this.header = header;
58         this.footer = footer;
59         this.lineNumbers = lineNumbers;
60
61         styles = GUIUtilities.loadStyles(jEdit.getProperty("print.font"),
62             jEdit.getIntegerProperty("print.fontsize",10),color);
63         styles[Token.NULL] = new SyntaxStyle(textColor,null,font);
64
65         // Change any white text to black
66
for(int i = 0; i < styles.length; i++)
67         {
68             SyntaxStyle s = styles[i];
69             if(s.getForegroundColor().equals(Color.WHITE)
70                 && s.getBackgroundColor() == null)
71             {
72                 styles[i] = new SyntaxStyle(
73                     Color.BLACK,
74                     styles[i].getBackgroundColor(),
75                     styles[i].getFont());
76             }
77         }
78
79         lineList = new ArrayList<Chunk>();
80
81         tokenHandler = new DisplayTokenHandler();
82     } //}}}
83

84     //{{{ print() method
85
public void print()
86     {
87         try
88         {
89             //buffer.readLock();
90

91             if(format == null)
92                 job.print();
93             else
94             {
95                 Method JavaDoc method = PrinterJob.class.getMethod(
96                     "print",new Class JavaDoc[] { Class.forName(
97                     "javax.print.attribute.PrintRequestAttributeSet") });
98                 method.invoke(job,new Object JavaDoc[] { format });
99             }
100         }
101         catch(PrinterAbortException ae)
102         {
103             Log.log(Log.DEBUG,this,ae);
104         }
105         catch(Exception JavaDoc e)
106         {
107             Log.log(Log.ERROR,this,e);
108             final String JavaDoc[] args = { e.toString() };
109             SwingUtilities.invokeLater(new Runnable JavaDoc()
110             {
111                 public void run()
112                 {
113                     GUIUtilities.error(view,"print-error",args);
114                 }
115             });
116         }
117         finally
118         {
119             //buffer.readUnlock();
120
}
121     } //}}}
122

123     //{{{ print() method
124
public int print(Graphics _gfx, PageFormat pageFormat, int pageIndex)
125         throws PrinterException
126     {
127         // we keep the first non-null frc we get, since sometimes
128
// we get invalid ones on subsequent pages on Windows
129
if(frc == null)
130         {
131             frc = ((Graphics2D)_gfx).getFontRenderContext();
132             Log.log(Log.DEBUG,this,"Font render context is " + frc);
133         }
134
135         Log.log(Log.DEBUG,this,"Asked to print page " + pageIndex);
136         Log.log(Log.DEBUG,this,"Current page is " + currentPage);
137
138         if(pageIndex > currentPage)
139         {
140             for(int i = currentPage; i < pageIndex; i++)
141             {
142                 Log.log(Log.DEBUG,this,"Current physical line is now " + currentPageStart);
143                 currentPhysicalLine = currentPageStart;
144                 printPage(_gfx,pageFormat,i,true);
145             }
146
147             currentPage = pageIndex - 1;
148             Log.log(Log.DEBUG,this,"Current page is now " + currentPage);
149         }
150
151         if(pageIndex == currentPage + 1)
152         {
153             if(end)
154             {
155                 Log.log(Log.DEBUG,this,"The end");
156                 return NO_SUCH_PAGE;
157             }
158
159             currentPageStart = currentPhysicalLine;
160             Log.log(Log.DEBUG,this,"#2 - Current physical line is now " + currentPageStart);
161             currentPage = pageIndex;
162             Log.log(Log.DEBUG,this,"#2 - Current page is now " + currentPage);
163         }
164         else if(pageIndex == currentPage)
165         {
166             currentPhysicalLine = currentPageStart;
167             Log.log(Log.DEBUG,this,"#3 - Current physical line is now " + currentPageStart);
168         }
169
170         printPage(_gfx,pageFormat,pageIndex,true);
171
172         return PAGE_EXISTS;
173     } //}}}
174

175     //{{{ Private members
176

177     //{{{ Static variables
178
private static Color headerColor = Color.lightGray;
179     private static Color headerTextColor = Color.black;
180     private static Color footerColor = Color.lightGray;
181     private static Color footerTextColor = Color.black;
182     private static Color lineNumberColor = Color.gray;
183     private static Color textColor = Color.black;
184     //}}}
185

186     //{{{ Instance variables
187
private PrinterJob job;
188     private Object JavaDoc format;
189
190     private View view;
191     private Buffer buffer;
192     private Font font;
193     private SyntaxStyle[] styles;
194     private boolean header;
195     private boolean footer;
196     private boolean lineNumbers;
197
198     private int currentPage;
199     private int currentPageStart;
200     private int currentPhysicalLine;
201     private boolean end;
202
203     private LineMetrics lm;
204     private final List JavaDoc<Chunk> lineList;
205
206     private FontRenderContext frc;
207
208     private DisplayTokenHandler tokenHandler;
209     //}}}
210

211     //{{{ printPage() method
212
private void printPage(Graphics _gfx, PageFormat pageFormat, int pageIndex,
213         boolean actuallyPaint)
214     {
215         Log.log(Log.DEBUG,this,"printPage(" + pageIndex + ',' + actuallyPaint + ')');
216         Graphics2D gfx = (Graphics2D)_gfx;
217         gfx.setFont(font);
218
219         double pageX = pageFormat.getImageableX();
220         double pageY = pageFormat.getImageableY();
221         double pageWidth = pageFormat.getImageableWidth();
222         double pageHeight = pageFormat.getImageableHeight();
223
224         Log.log(Log.DEBUG,this,"#1 - Page dimensions: " + pageWidth
225             + 'x' + pageHeight);
226
227         if(header)
228         {
229             double headerHeight = paintHeader(gfx,pageX,pageY,pageWidth,
230                 actuallyPaint);
231             pageY += headerHeight;
232             pageHeight -= headerHeight;
233         }
234
235         if(footer)
236         {
237             double footerHeight = paintFooter(gfx,pageX,pageY,pageWidth,
238                 pageHeight,pageIndex,actuallyPaint);
239             pageHeight -= footerHeight;
240         }
241
242         boolean glyphVector = jEdit.getBooleanProperty("print.glyphVector");
243         double lineNumberWidth;
244
245         //{{{ determine line number width
246
if(lineNumbers)
247         {
248             // the +1's ensure that 99 gets 3 digits, 103 gets 4 digits,
249
// and so on.
250
int lineNumberDigits = (int)Math.ceil(Math.log(buffer.getLineCount() + 1)
251                 / Math.log(10)) + 1;
252
253             // now that we know how many chars there are, get the width.
254
char[] chars = new char[lineNumberDigits];
255             for(int i = 0; i < chars.length; i++)
256                 chars[i] = ' ';
257             lineNumberWidth = font.getStringBounds(chars,
258                 0,lineNumberDigits,frc).getWidth();
259         }
260         else
261             lineNumberWidth = 0.0;
262         //}}}
263

264         Log.log(Log.DEBUG,this,"#2 - Page dimensions: "
265             + (pageWidth - lineNumberWidth)
266             + 'x' + pageHeight);
267
268         //{{{ calculate tab size
269
int tabSize = jEdit.getIntegerProperty("print.tabSize",8);
270         char[] chars = new char[tabSize];
271         for(int i = 0; i < chars.length; i++)
272             chars[i] = ' ';
273         double tabWidth = font.getStringBounds(chars,
274             0,tabSize,frc).getWidth();
275         PrintTabExpander e = new PrintTabExpander(tabWidth);
276         //}}}
277

278         lm = font.getLineMetrics("gGyYX",frc);
279         Log.log(Log.DEBUG,this,"Line height is " + lm.getHeight());
280
281         double y = 0.0;
282 print_loop: for(;;)
283         {
284             if(currentPhysicalLine == buffer.getLineCount())
285             {
286                 Log.log(Log.DEBUG,this,"Finished buffer");
287                 end = true;
288                 break print_loop;
289             }
290             if (!jEdit.getBooleanProperty("print.folds",true) &&
291                 !view.getTextArea().getDisplayManager().isLineVisible(currentPhysicalLine))
292             {
293                 
294                 Log.log(Log.DEBUG,this,"Skipping invisible line");
295                 currentPhysicalLine++;
296                 continue;
297             }
298                 
299             lineList.clear();
300
301             tokenHandler.init(styles,frc,e,lineList,
302                 (float)(pageWidth - lineNumberWidth));
303
304             buffer.markTokens(currentPhysicalLine,tokenHandler);
305             if(lineList.isEmpty())
306                 lineList.add(null);
307
308             if(y + (lm.getHeight() * lineList.size()) >= pageHeight)
309             {
310                 Log.log(Log.DEBUG,this,"Finished page before line " + currentPhysicalLine);
311                 break print_loop;
312             }
313
314             if(lineNumbers && actuallyPaint)
315             {
316                 gfx.setFont(font);
317                 gfx.setColor(lineNumberColor);
318                 gfx.drawString(String.valueOf(currentPhysicalLine + 1),
319                     (float)pageX,(float)(pageY + y + lm.getHeight()));
320             }
321
322             for(int i = 0; i < lineList.size(); i++)
323             {
324                 y += lm.getHeight();
325                 Chunk chunks = lineList.get(i);
326                 if(chunks != null && actuallyPaint)
327                 {
328                     Chunk.paintChunkBackgrounds(chunks,gfx,
329                         (float)(pageX + lineNumberWidth),
330                         (float)(pageY + y));
331                     Chunk.paintChunkList(chunks,gfx,
332                         (float)(pageX + lineNumberWidth),
333                         (float)(pageY + y),glyphVector);
334                 }
335             }
336
337             currentPhysicalLine++;
338         }
339     } //}}}
340

341     //{{{ paintHeader() method
342
private double paintHeader(Graphics2D gfx, double pageX, double pageY,
343         double pageWidth, boolean actuallyPaint)
344     {
345         String JavaDoc headerText = jEdit.getProperty("print.headerText",
346             new String JavaDoc[] { buffer.getName() });
347         FontRenderContext frc = gfx.getFontRenderContext();
348         lm = font.getLineMetrics(headerText,frc);
349
350         Rectangle2D bounds = font.getStringBounds(headerText,frc);
351         Rectangle2D headerBounds = new Rectangle2D.Double(
352             pageX,pageY,pageWidth,bounds.getHeight());
353
354         if(actuallyPaint)
355         {
356             gfx.setColor(headerColor);
357             gfx.fill(headerBounds);
358             gfx.setColor(headerTextColor);
359             gfx.drawString(headerText,
360                 (float)(pageX + (pageWidth - bounds.getWidth()) / 2),
361                 (float)(pageY + lm.getAscent()));
362         }
363
364         return headerBounds.getHeight();
365     }
366     //}}}
367

368     //{{{ paintFooter() method
369
private double paintFooter(Graphics2D gfx, double pageX, double pageY,
370         double pageWidth, double pageHeight, int pageIndex,
371         boolean actuallyPaint)
372     {
373         String JavaDoc footerText = jEdit.getProperty("print.footerText",
374             new Object JavaDoc[] { new Date(), Integer.valueOf(pageIndex + 1)});
375         FontRenderContext frc = gfx.getFontRenderContext();
376         lm = font.getLineMetrics(footerText,frc);
377
378         Rectangle2D bounds = font.getStringBounds(footerText,frc);
379         Rectangle2D footerBounds = new Rectangle2D.Double(
380             pageX,pageY + pageHeight - bounds.getHeight(),
381             pageWidth,bounds.getHeight());
382
383         if(actuallyPaint)
384         {
385             gfx.setColor(footerColor);
386             gfx.fill(footerBounds);
387             gfx.setColor(footerTextColor);
388             gfx.drawString(footerText,
389                 (float)(pageX + (pageWidth - bounds.getWidth()) / 2),
390                 (float)(pageY + pageHeight - bounds.getHeight()
391                 + lm.getAscent()));
392         }
393
394         return footerBounds.getHeight();
395     } //}}}
396

397     //}}}
398

399     //{{{ PrintTabExpander class
400
static class PrintTabExpander implements TabExpander JavaDoc
401     {
402         private double tabWidth;
403
404         //{{{ PrintTabExpander constructor
405
PrintTabExpander(double tabWidth)
406         {
407             this.tabWidth = tabWidth;
408         } //}}}
409

410         //{{{ nextTabStop() method
411
public float nextTabStop(float x, int tabOffset)
412         {
413             int ntabs = (int)((x + 1) / tabWidth);
414             return (float)((ntabs + 1) * tabWidth);
415         } //}}}
416
} //}}}
417
}
418
Popular Tags