PageRenderTime 36ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-2-pre4/org/gjt/sp/jedit/print/BufferPrintable.java

#
Java | 360 lines | 259 code | 52 blank | 49 comment | 29 complexity | 0ac8e251a8b3116b9bc5e102d72ec3ef MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  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. package org.gjt.sp.jedit.print;
  24. //{{{ Imports
  25. import javax.swing.text.Segment;
  26. import javax.swing.text.TabExpander;
  27. import javax.swing.SwingUtilities;
  28. import java.awt.font.*;
  29. import java.awt.geom.*;
  30. import java.awt.print.*;
  31. import java.awt.*;
  32. import java.lang.reflect.Method;
  33. import java.util.*;
  34. import org.gjt.sp.jedit.syntax.*;
  35. import org.gjt.sp.jedit.*;
  36. import org.gjt.sp.util.*;
  37. //}}}
  38. class BufferPrintable implements Printable
  39. {
  40. //{{{ BufferPrintable constructor
  41. BufferPrintable(PrinterJob job, Object format,
  42. View view, Buffer buffer, Font font, boolean header,
  43. boolean footer, boolean lineNumbers, boolean color)
  44. {
  45. this.job = job;
  46. this.format = format;
  47. this.view = view;
  48. this.buffer = buffer;
  49. this.font = font;
  50. this.header = header;
  51. this.footer = footer;
  52. this.lineNumbers = lineNumbers;
  53. styles = GUIUtilities.loadStyles(jEdit.getProperty("print.font"),
  54. jEdit.getIntegerProperty("print.fontsize",10),color);
  55. styles[Token.NULL] = new SyntaxStyle(textColor,null,font);
  56. lineList = new ArrayList();
  57. tokenHandler = new DisplayTokenHandler();
  58. } //}}}
  59. //{{{ print() method
  60. public void print()
  61. {
  62. try
  63. {
  64. //buffer.readLock();
  65. if(format == null)
  66. job.print();
  67. else
  68. {
  69. Method method = PrinterJob.class.getMethod(
  70. "print",new Class[] { Class.forName(
  71. "javax.print.attribute.PrintRequestAttributeSet") });
  72. method.invoke(job,new Object[] { format });
  73. }
  74. }
  75. catch(PrinterAbortException ae)
  76. {
  77. Log.log(Log.DEBUG,this,ae);
  78. }
  79. catch(Exception e)
  80. {
  81. Log.log(Log.ERROR,this,e);
  82. final String[] args = { e.toString() };
  83. SwingUtilities.invokeLater(new Runnable()
  84. {
  85. public void run()
  86. {
  87. GUIUtilities.error(view,"print-error",args);
  88. }
  89. });
  90. }
  91. finally
  92. {
  93. //buffer.readUnlock();
  94. }
  95. } //}}}
  96. //{{{ print() method
  97. public int print(Graphics _gfx, PageFormat pageFormat, int pageIndex)
  98. throws PrinterException
  99. {
  100. if(pageIndex > currentPage)
  101. {
  102. for(int i = currentPage; i < pageIndex; i++)
  103. {
  104. currentPhysicalLine = currentPageStart;
  105. printPage(_gfx,pageFormat,i,true);
  106. }
  107. currentPage = pageIndex - 1;
  108. }
  109. if(pageIndex == currentPage + 1)
  110. {
  111. if(end)
  112. return NO_SUCH_PAGE;
  113. currentPageStart = currentPhysicalLine;
  114. currentPage = pageIndex;
  115. }
  116. else if(pageIndex == currentPage)
  117. {
  118. currentPhysicalLine = currentPageStart;
  119. }
  120. printPage(_gfx,pageFormat,pageIndex,true);
  121. return PAGE_EXISTS;
  122. } //}}}
  123. //{{{ Private members
  124. //{{{ Static variables
  125. private static Color headerColor = Color.lightGray;
  126. private static Color headerTextColor = Color.black;
  127. private static Color footerColor = Color.lightGray;
  128. private static Color footerTextColor = Color.black;
  129. private static Color lineNumberColor = Color.gray;
  130. private static Color textColor = Color.black;
  131. //}}}
  132. //{{{ Instance variables
  133. private PrinterJob job;
  134. private Object format;
  135. private View view;
  136. private Buffer buffer;
  137. private Font font;
  138. private SyntaxStyle[] styles;
  139. private boolean header;
  140. private boolean footer;
  141. private boolean lineNumbers;
  142. private int currentPage;
  143. private int currentPageStart;
  144. private int currentPhysicalLine;
  145. private boolean end;
  146. private LineMetrics lm;
  147. private ArrayList lineList;
  148. private DisplayTokenHandler tokenHandler;
  149. //}}}
  150. //{{{ printPage() method
  151. private void printPage(Graphics _gfx, PageFormat pageFormat, int pageIndex,
  152. boolean actuallyPaint)
  153. {
  154. Graphics2D gfx = (Graphics2D)_gfx;
  155. gfx.setFont(font);
  156. double pageX = pageFormat.getImageableX();
  157. double pageY = pageFormat.getImageableY();
  158. double pageWidth = pageFormat.getImageableWidth();
  159. double pageHeight = pageFormat.getImageableHeight();
  160. if(header)
  161. {
  162. double headerHeight = paintHeader(gfx,pageX,pageY,pageWidth,
  163. actuallyPaint);
  164. pageY += headerHeight;
  165. pageHeight -= headerHeight;
  166. }
  167. if(footer)
  168. {
  169. double footerHeight = paintFooter(gfx,pageX,pageY,pageWidth,
  170. pageHeight,pageIndex,actuallyPaint);
  171. pageHeight -= footerHeight;
  172. }
  173. FontRenderContext frc = gfx.getFontRenderContext();
  174. boolean glyphVector = jEdit.getBooleanProperty("print.glyphVector");
  175. double lineNumberWidth;
  176. //{{{ determine line number width
  177. if(lineNumbers)
  178. {
  179. // the +1's ensure that 99 gets 3 digits, 103 gets 4 digits,
  180. // and so on.
  181. int lineNumberDigits = (int)Math.ceil(Math.log(buffer.getLineCount() + 1)
  182. / Math.log(10)) + 1;
  183. // now that we know how many chars there are, get the width.
  184. char[] chars = new char[lineNumberDigits];
  185. for(int i = 0; i < chars.length; i++)
  186. chars[i] = ' ';
  187. lineNumberWidth = font.getStringBounds(chars,
  188. 0,lineNumberDigits,frc).getWidth();
  189. }
  190. else
  191. lineNumberWidth = 0.0;
  192. //}}}
  193. //{{{ calculate tab size
  194. int tabSize = jEdit.getIntegerProperty("print.tabSize",8);
  195. char[] chars = new char[tabSize];
  196. for(int i = 0; i < chars.length; i++)
  197. chars[i] = ' ';
  198. double tabWidth = font.getStringBounds(chars,
  199. 0,tabSize,frc).getWidth();
  200. PrintTabExpander e = new PrintTabExpander(tabWidth);
  201. //}}}
  202. double y = 0.0;
  203. lm = font.getLineMetrics("gGyYX",frc);
  204. print_loop: for(;;)
  205. {
  206. if(currentPhysicalLine == buffer.getLineCount())
  207. {
  208. end = true;
  209. break print_loop;
  210. }
  211. lineList.clear();
  212. tokenHandler.init(styles,frc,e,lineList,
  213. (float)(pageWidth - lineNumberWidth));
  214. buffer.markTokens(currentPhysicalLine,tokenHandler);
  215. if(lineList.size() == 0)
  216. lineList.add(null);
  217. if(y + (lm.getHeight() * lineList.size()) >= pageHeight)
  218. break print_loop;
  219. if(lineNumbers && actuallyPaint)
  220. {
  221. gfx.setFont(font);
  222. gfx.setColor(lineNumberColor);
  223. gfx.drawString(String.valueOf(currentPhysicalLine + 1),
  224. (float)pageX,(float)(pageY + y + lm.getHeight()));
  225. }
  226. for(int i = 0; i < lineList.size(); i++)
  227. {
  228. y += lm.getHeight();
  229. Chunk chunks = (Chunk)lineList.get(i);
  230. if(chunks != null && actuallyPaint)
  231. {
  232. Chunk.paintChunkBackgrounds(chunks,gfx,
  233. (float)(pageX + lineNumberWidth),
  234. (float)(pageY + y));
  235. Chunk.paintChunkList(chunks,gfx,
  236. (float)(pageX + lineNumberWidth),
  237. (float)(pageY + y),glyphVector);
  238. }
  239. }
  240. currentPhysicalLine++;
  241. }
  242. } //}}}
  243. //{{{ paintHeader() method
  244. private double paintHeader(Graphics2D gfx, double pageX, double pageY,
  245. double pageWidth, boolean actuallyPaint)
  246. {
  247. String headerText = jEdit.getProperty("print.headerText",
  248. new String[] { buffer.getName() });
  249. FontRenderContext frc = gfx.getFontRenderContext();
  250. lm = font.getLineMetrics(headerText,frc);
  251. Rectangle2D bounds = font.getStringBounds(headerText,frc);
  252. Rectangle2D headerBounds = new Rectangle2D.Double(
  253. pageX,pageY,pageWidth,bounds.getHeight());
  254. if(actuallyPaint)
  255. {
  256. gfx.setColor(headerColor);
  257. gfx.fill(headerBounds);
  258. gfx.setColor(headerTextColor);
  259. gfx.drawString(headerText,
  260. (float)(pageX + (pageWidth - bounds.getWidth()) / 2),
  261. (float)(pageY + lm.getAscent()));
  262. }
  263. return headerBounds.getHeight();
  264. }
  265. //}}}
  266. //{{{ paintFooter() method
  267. private double paintFooter(Graphics2D gfx, double pageX, double pageY,
  268. double pageWidth, double pageHeight, int pageIndex,
  269. boolean actuallyPaint)
  270. {
  271. String footerText = jEdit.getProperty("print.footerText",
  272. new Object[] { new Date(), new Integer(pageIndex + 1) });
  273. FontRenderContext frc = gfx.getFontRenderContext();
  274. lm = font.getLineMetrics(footerText,frc);
  275. Rectangle2D bounds = font.getStringBounds(footerText,frc);
  276. Rectangle2D footerBounds = new Rectangle2D.Double(
  277. pageX,pageY + pageHeight - bounds.getHeight(),
  278. pageWidth,bounds.getHeight());
  279. if(actuallyPaint)
  280. {
  281. gfx.setColor(footerColor);
  282. gfx.fill(footerBounds);
  283. gfx.setColor(footerTextColor);
  284. gfx.drawString(footerText,
  285. (float)(pageX + (pageWidth - bounds.getWidth()) / 2),
  286. (float)(pageY + pageHeight - bounds.getHeight()
  287. + lm.getAscent()));
  288. }
  289. return footerBounds.getHeight();
  290. } //}}}
  291. //}}}
  292. //{{{ PrintTabExpander class
  293. static class PrintTabExpander implements TabExpander
  294. {
  295. private double tabWidth;
  296. //{{{ PrintTabExpander constructor
  297. public PrintTabExpander(double tabWidth)
  298. {
  299. this.tabWidth = tabWidth;
  300. } //}}}
  301. //{{{ nextTabStop() method
  302. public float nextTabStop(float x, int tabOffset)
  303. {
  304. int ntabs = (int)((x + 1) / tabWidth);
  305. return (float)((ntabs + 1) * tabWidth);
  306. } //}}}
  307. } //}}}
  308. }