PageRenderTime 261ms CodeModel.GetById 234ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre5/org/gjt/sp/jedit/print/BufferPrintable.java

#
Java | 290 lines | 195 code | 50 blank | 45 comment | 21 complexity | 942371f7adeb6fb66bc95a147381d32a MD5 | raw file
  1/*
  2 * BufferPrintable.java - Printable implementation
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2001 Slava Pestov
  7 *
  8 * This program is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU General Public License
 10 * as published by the Free Software Foundation; either version 2
 11 * of the License, or any later version.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; if not, write to the Free Software
 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 21 */
 22
 23package org.gjt.sp.jedit.print;
 24
 25//{{{ Imports
 26import javax.swing.text.*;
 27import java.awt.font.*;
 28import java.awt.geom.*;
 29import java.awt.print.*;
 30import java.awt.*;
 31import java.util.*;
 32import org.gjt.sp.jedit.syntax.*;
 33import org.gjt.sp.jedit.textarea.ChunkCache;
 34import org.gjt.sp.jedit.*;
 35//}}}
 36
 37class BufferPrintable implements Printable
 38{
 39	//{{{ BufferPrintable constructor
 40	BufferPrintable(Buffer buffer, Font font, boolean header, boolean footer,
 41		boolean lineNumbers, boolean color)
 42	{
 43		this.buffer = buffer;
 44		this.font = font;
 45		this.header = header;
 46		this.footer = footer;
 47		this.lineNumbers = lineNumbers;
 48
 49		styles = GUIUtilities.loadStyles(jEdit.getProperty("print.font"),
 50			jEdit.getIntegerProperty("print.fontsize",10),color);
 51		styles[Token.NULL] = new SyntaxStyle(textColor,null,font);
 52
 53		lineList = new ArrayList();
 54	} //}}}
 55
 56	//{{{ print() method
 57	public int print(Graphics _gfx, PageFormat pageFormat, int pageIndex)
 58		throws PrinterException
 59	{
 60		if(pageIndex == currentPage)
 61			currentLine = currentPageStart;
 62		else
 63		{
 64			if(end)
 65				return NO_SUCH_PAGE;
 66
 67			currentPageStart = currentLine;
 68			currentPage = pageIndex;
 69		}
 70
 71		double pageX = pageFormat.getImageableX();
 72		double pageY = pageFormat.getImageableY();
 73		double pageWidth = pageFormat.getImageableWidth();
 74		double pageHeight = pageFormat.getImageableHeight();
 75
 76		Graphics2D gfx = (Graphics2D)_gfx;
 77
 78		gfx.setFont(font);
 79
 80		if(header)
 81		{
 82			double headerHeight = paintHeader(gfx,pageX,pageY,pageWidth);
 83			pageY += headerHeight * 2;
 84			pageHeight -= headerHeight * 2;
 85		}
 86
 87		if(footer)
 88		{
 89			double footerHeight = paintFooter(gfx,pageX,pageY,pageWidth,
 90				pageHeight,pageIndex);
 91			pageHeight -= footerHeight * 2;
 92		}
 93
 94		FontRenderContext frc = gfx.getFontRenderContext();
 95
 96		// the +1's ensure that 99 gets 3 digits, 103 gets 4 digits,
 97		// and so on.
 98		int lineNumberDigits = (int)Math.ceil(Math.log(buffer.getLineCount() + 1)
 99			/ Math.log(10)) + 1;
100
101		//{{{ now that we know how many chars there are, get the width.
102		char[] chars = new char[lineNumberDigits];
103		for(int i = 0; i < chars.length; i++)
104			chars[i] = ' ';
105		double lineNumberWidth = font.getStringBounds(chars,
106			0,lineNumberDigits,frc).getWidth();
107		//}}}
108
109		//{{{ calculate tab size
110		int tabSize = jEdit.getIntegerProperty("print.tabSize",8);
111		chars = new char[tabSize];
112		for(int i = 0; i < chars.length; i++)
113			chars[i] = ' ';
114		double tabWidth = font.getStringBounds(chars,
115			0,tabSize,frc).getWidth();
116		PrintTabExpander e = new PrintTabExpander(pageX,tabWidth);
117		//}}}
118
119		Segment seg = new Segment();
120		double y = 0.0;
121
122print_loop:	for(;;)
123		{
124			//{{{ get line text
125			if(currentLine == lineList.size())
126			{
127				buffer.getLineText(currentPhysicalLine,seg);
128				lm = font.getLineMetrics(seg.array,
129					seg.offset,seg.count,frc);
130
131				Token tokens = buffer.markTokens(currentPhysicalLine)
132					.getFirstToken();
133
134				lineList.add(new Integer(++currentPhysicalLine));
135
136				ChunkCache.lineToChunkList(seg,tokens,styles,frc,
137					e,(float)(pageWidth - lineNumberWidth),
138					lineList);
139				if(lineList.size() == currentLine + 1)
140					lineList.add(null);
141			} //}}}
142
143			y += lm.getHeight();
144			if(y >= pageHeight)
145				break print_loop;
146
147			Object obj = lineList.get(currentLine++);
148			if(obj instanceof Integer)
149			{
150				//{{{ paint line number
151				if(lineNumbers)
152				{
153					gfx.setFont(font);
154					gfx.setColor(lineNumberColor);
155					String lineNumberString = String.valueOf(obj);
156					gfx.drawString(lineNumberString,
157						(float)pageX,(float)(pageY + y));
158				} //}}}
159
160				obj = lineList.get(currentLine++);
161			}
162
163			if(obj != null)
164			{
165				ChunkCache.Chunk line = (ChunkCache.Chunk)obj;
166
167				ChunkCache.paintChunkList(line,gfx,
168					(float)(pageX + lineNumberWidth),
169					(float)(pageY + y),
170					(float)(pageWidth - lineNumberWidth),
171					Color.white,false);
172			}
173
174			if(currentPhysicalLine == buffer.getLineCount()
175				&& currentLine == lineList.size())
176			{
177				end = true;
178				break print_loop;
179			}
180		}
181
182		return PAGE_EXISTS;
183	} //}}}
184
185	//{{{ Private members
186
187	//{{{ Static variables
188	private static Color headerColor = Color.lightGray;
189	private static Color headerTextColor = Color.black;
190	private static Color footerColor = Color.lightGray;
191	private static Color footerTextColor = Color.black;
192	private static Color lineNumberColor = Color.gray;
193	private static Color textColor = Color.black;
194	//}}}
195
196	//{{{ Instance variables
197	private Buffer buffer;
198	private Font font;
199	private SyntaxStyle[] styles;
200	private boolean header;
201	private boolean footer;
202	private boolean lineNumbers;
203
204	private int currentPage;
205	private int currentPageStart;
206	private int currentLine;
207	private int currentPhysicalLine;
208	private boolean end;
209
210	private LineMetrics lm;
211	private ArrayList lineList;
212	//}}}
213
214	//{{{ paintHeader() method
215	private double paintHeader(Graphics2D gfx, double pageX, double pageY,
216		double pageWidth)
217	{
218		String headerText = jEdit.getProperty("print.headerText",
219			new String[] { buffer.getPath() });
220		FontRenderContext frc = gfx.getFontRenderContext();
221
222		gfx.setColor(headerColor);
223
224		Rectangle2D bounds = font.getStringBounds(headerText,frc);
225
226		Rectangle2D headerBounds = new Rectangle2D.Double(
227			pageX,pageY,pageWidth,bounds.getHeight());
228		gfx.fill(headerBounds);
229
230		gfx.setColor(headerTextColor);
231
232		lm = font.getLineMetrics(headerText,frc);
233		gfx.drawString(headerText,
234			(float)(pageX + (pageWidth - bounds.getWidth()) / 2),
235			(float)(pageY + lm.getAscent()));
236
237		return headerBounds.getHeight();
238	}
239	//}}}
240
241	//{{{ paintFooter() method
242	private double paintFooter(Graphics2D gfx, double pageX, double pageY,
243		double pageWidth, double pageHeight, int pageIndex)
244	{
245		String footerText = jEdit.getProperty("print.footerText",
246			new Object[] { new Date(), new Integer(pageIndex + 1) });
247		FontRenderContext frc = gfx.getFontRenderContext();
248
249		gfx.setColor(footerColor);
250
251		Rectangle2D bounds = font.getStringBounds(footerText,frc);
252		Rectangle2D footerBounds = new Rectangle2D.Double(
253			pageX,pageY + pageHeight - bounds.getHeight(),
254			pageWidth,bounds.getHeight());
255		gfx.fill(footerBounds);
256
257		gfx.setColor(footerTextColor);
258
259		lm = font.getLineMetrics(footerText,frc);
260		gfx.drawString(footerText,
261			(float)(pageX + (pageWidth - bounds.getWidth()) / 2),
262			(float)(pageY + pageHeight - bounds.getHeight()
263			+ lm.getAscent()));
264
265		return footerBounds.getHeight();
266	} //}}}
267
268	//}}}
269
270	//{{{ PrintTabExpander class
271	static class PrintTabExpander implements TabExpander
272	{
273		private double pageX;
274		private double tabWidth;
275
276		//{{{ PrintTabExpander constructor
277		public PrintTabExpander(double pageX, double tabWidth)
278		{
279			this.pageX = pageX;
280			this.tabWidth = tabWidth;
281		} //}}}
282
283		//{{{ nextTabStop() method
284		public float nextTabStop(float x, int tabOffset)
285		{
286			int ntabs = (int)((x - pageX) / tabWidth);
287			return (float)((ntabs + 1) * tabWidth + pageX);
288		} //}}}
289	} //}}}
290}