PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 0ms 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
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 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. package org.gjt.sp.jedit.print;
  23. //{{{ Imports
  24. import javax.swing.text.*;
  25. import java.awt.font.*;
  26. import java.awt.geom.*;
  27. import java.awt.print.*;
  28. import java.awt.*;
  29. import java.util.*;
  30. import org.gjt.sp.jedit.syntax.*;
  31. import org.gjt.sp.jedit.textarea.ChunkCache;
  32. import org.gjt.sp.jedit.*;
  33. //}}}
  34. class BufferPrintable implements Printable
  35. {
  36. //{{{ BufferPrintable constructor
  37. BufferPrintable(Buffer buffer, Font font, boolean header, boolean footer,
  38. boolean lineNumbers, boolean color)
  39. {
  40. this.buffer = buffer;
  41. this.font = font;
  42. this.header = header;
  43. this.footer = footer;
  44. this.lineNumbers = lineNumbers;
  45. styles = GUIUtilities.loadStyles(jEdit.getProperty("print.font"),
  46. jEdit.getIntegerProperty("print.fontsize",10),color);
  47. styles[Token.NULL] = new SyntaxStyle(textColor,null,font);
  48. lineList = new ArrayList();
  49. } //}}}
  50. //{{{ print() method
  51. public int print(Graphics _gfx, PageFormat pageFormat, int pageIndex)
  52. throws PrinterException
  53. {
  54. if(pageIndex == currentPage)
  55. currentLine = currentPageStart;
  56. else
  57. {
  58. if(end)
  59. return NO_SUCH_PAGE;
  60. currentPageStart = currentLine;
  61. currentPage = pageIndex;
  62. }
  63. double pageX = pageFormat.getImageableX();
  64. double pageY = pageFormat.getImageableY();
  65. double pageWidth = pageFormat.getImageableWidth();
  66. double pageHeight = pageFormat.getImageableHeight();
  67. Graphics2D gfx = (Graphics2D)_gfx;
  68. gfx.setFont(font);
  69. if(header)
  70. {
  71. double headerHeight = paintHeader(gfx,pageX,pageY,pageWidth);
  72. pageY += headerHeight * 2;
  73. pageHeight -= headerHeight * 2;
  74. }
  75. if(footer)
  76. {
  77. double footerHeight = paintFooter(gfx,pageX,pageY,pageWidth,
  78. pageHeight,pageIndex);
  79. pageHeight -= footerHeight * 2;
  80. }
  81. FontRenderContext frc = gfx.getFontRenderContext();
  82. // the +1's ensure that 99 gets 3 digits, 103 gets 4 digits,
  83. // and so on.
  84. int lineNumberDigits = (int)Math.ceil(Math.log(buffer.getLineCount() + 1)
  85. / Math.log(10)) + 1;
  86. //{{{ now that we know how many chars there are, get the width.
  87. char[] chars = new char[lineNumberDigits];
  88. for(int i = 0; i < chars.length; i++)
  89. chars[i] = ' ';
  90. double lineNumberWidth = font.getStringBounds(chars,
  91. 0,lineNumberDigits,frc).getWidth();
  92. //}}}
  93. //{{{ calculate tab size
  94. int tabSize = jEdit.getIntegerProperty("print.tabSize",8);
  95. chars = new char[tabSize];
  96. for(int i = 0; i < chars.length; i++)
  97. chars[i] = ' ';
  98. double tabWidth = font.getStringBounds(chars,
  99. 0,tabSize,frc).getWidth();
  100. PrintTabExpander e = new PrintTabExpander(pageX,tabWidth);
  101. //}}}
  102. Segment seg = new Segment();
  103. double y = 0.0;
  104. print_loop: for(;;)
  105. {
  106. //{{{ get line text
  107. if(currentLine == lineList.size())
  108. {
  109. buffer.getLineText(currentPhysicalLine,seg);
  110. lm = font.getLineMetrics(seg.array,
  111. seg.offset,seg.count,frc);
  112. Token tokens = buffer.markTokens(currentPhysicalLine)
  113. .getFirstToken();
  114. lineList.add(new Integer(++currentPhysicalLine));
  115. ChunkCache.lineToChunkList(seg,tokens,styles,frc,
  116. e,(float)(pageWidth - lineNumberWidth),
  117. lineList);
  118. if(lineList.size() == currentLine + 1)
  119. lineList.add(null);
  120. } //}}}
  121. y += lm.getHeight();
  122. if(y >= pageHeight)
  123. break print_loop;
  124. Object obj = lineList.get(currentLine++);
  125. if(obj instanceof Integer)
  126. {
  127. //{{{ paint line number
  128. if(lineNumbers)
  129. {
  130. gfx.setFont(font);
  131. gfx.setColor(lineNumberColor);
  132. String lineNumberString = String.valueOf(obj);
  133. gfx.drawString(lineNumberString,
  134. (float)pageX,(float)(pageY + y));
  135. } //}}}
  136. obj = lineList.get(currentLine++);
  137. }
  138. if(obj != null)
  139. {
  140. ChunkCache.Chunk line = (ChunkCache.Chunk)obj;
  141. ChunkCache.paintChunkList(line,gfx,
  142. (float)(pageX + lineNumberWidth),
  143. (float)(pageY + y),
  144. (float)(pageWidth - lineNumberWidth),
  145. Color.white,false);
  146. }
  147. if(currentPhysicalLine == buffer.getLineCount()
  148. && currentLine == lineList.size())
  149. {
  150. end = true;
  151. break print_loop;
  152. }
  153. }
  154. return PAGE_EXISTS;
  155. } //}}}
  156. //{{{ Private members
  157. //{{{ Static variables
  158. private static Color headerColor = Color.lightGray;
  159. private static Color headerTextColor = Color.black;
  160. private static Color footerColor = Color.lightGray;
  161. private static Color footerTextColor = Color.black;
  162. private static Color lineNumberColor = Color.gray;
  163. private static Color textColor = Color.black;
  164. //}}}
  165. //{{{ Instance variables
  166. private Buffer buffer;
  167. private Font font;
  168. private SyntaxStyle[] styles;
  169. private boolean header;
  170. private boolean footer;
  171. private boolean lineNumbers;
  172. private int currentPage;
  173. private int currentPageStart;
  174. private int currentLine;
  175. private int currentPhysicalLine;
  176. private boolean end;
  177. private LineMetrics lm;
  178. private ArrayList lineList;
  179. //}}}
  180. //{{{ paintHeader() method
  181. private double paintHeader(Graphics2D gfx, double pageX, double pageY,
  182. double pageWidth)
  183. {
  184. String headerText = jEdit.getProperty("print.headerText",
  185. new String[] { buffer.getPath() });
  186. FontRenderContext frc = gfx.getFontRenderContext();
  187. gfx.setColor(headerColor);
  188. Rectangle2D bounds = font.getStringBounds(headerText,frc);
  189. Rectangle2D headerBounds = new Rectangle2D.Double(
  190. pageX,pageY,pageWidth,bounds.getHeight());
  191. gfx.fill(headerBounds);
  192. gfx.setColor(headerTextColor);
  193. lm = font.getLineMetrics(headerText,frc);
  194. gfx.drawString(headerText,
  195. (float)(pageX + (pageWidth - bounds.getWidth()) / 2),
  196. (float)(pageY + lm.getAscent()));
  197. return headerBounds.getHeight();
  198. }
  199. //}}}
  200. //{{{ paintFooter() method
  201. private double paintFooter(Graphics2D gfx, double pageX, double pageY,
  202. double pageWidth, double pageHeight, int pageIndex)
  203. {
  204. String footerText = jEdit.getProperty("print.footerText",
  205. new Object[] { new Date(), new Integer(pageIndex + 1) });
  206. FontRenderContext frc = gfx.getFontRenderContext();
  207. gfx.setColor(footerColor);
  208. Rectangle2D bounds = font.getStringBounds(footerText,frc);
  209. Rectangle2D footerBounds = new Rectangle2D.Double(
  210. pageX,pageY + pageHeight - bounds.getHeight(),
  211. pageWidth,bounds.getHeight());
  212. gfx.fill(footerBounds);
  213. gfx.setColor(footerTextColor);
  214. lm = font.getLineMetrics(footerText,frc);
  215. gfx.drawString(footerText,
  216. (float)(pageX + (pageWidth - bounds.getWidth()) / 2),
  217. (float)(pageY + pageHeight - bounds.getHeight()
  218. + lm.getAscent()));
  219. return footerBounds.getHeight();
  220. } //}}}
  221. //}}}
  222. //{{{ PrintTabExpander class
  223. static class PrintTabExpander implements TabExpander
  224. {
  225. private double pageX;
  226. private double tabWidth;
  227. //{{{ PrintTabExpander constructor
  228. public PrintTabExpander(double pageX, double tabWidth)
  229. {
  230. this.pageX = pageX;
  231. this.tabWidth = tabWidth;
  232. } //}}}
  233. //{{{ nextTabStop() method
  234. public float nextTabStop(float x, int tabOffset)
  235. {
  236. int ntabs = (int)((x - pageX) / tabWidth);
  237. return (float)((ntabs + 1) * tabWidth + pageX);
  238. } //}}}
  239. } //}}}
  240. }