]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/richtext/print/MConstTextPrintable.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / richtext / print / MConstTextPrintable.java
1 /*\r
2  * (C) Copyright IBM Corp. 1998-2004.  All Rights Reserved.\r
3  *\r
4  * The program is provided "as is" without any warranty express or\r
5  * implied, including the warranty of non-infringement and the implied\r
6  * warranties of merchantibility and fitness for a particular purpose.\r
7  * IBM will not be liable for any damages suffered by you as a result\r
8  * of using the Program. In no event will IBM be liable for any\r
9  * special, indirect or consequential damages or lost profits even if\r
10  * IBM has been advised of the possibility of their occurrence. IBM\r
11  * will not be liable for any third party claims against you.\r
12  */\r
13 package com.ibm.richtext.print;\r
14 \r
15 import com.ibm.richtext.styledtext.MConstText;\r
16 \r
17 import com.ibm.richtext.textformat.MFormatter;\r
18 \r
19 import com.ibm.richtext.textlayout.attributes.AttributeMap;\r
20 \r
21 import java.awt.Color;\r
22 import java.awt.Graphics;\r
23 import java.awt.Point;\r
24 import java.awt.Rectangle;\r
25 \r
26 import java.util.Vector;\r
27 \r
28 /**\r
29  * This class's interface is very close to that of the JDK 1.2 Printable \r
30  * interface, but can execute on JDK 1.1.  On 1.2, this class is wrapped\r
31  * in a real Printable.  On 1.1, the PrintContext class uses this class\r
32  * and a PrintJob for printing.\r
33  *\r
34  * Note that this class paginates the text in the first call to print,\r
35  * or to getPageCount.\r
36  * After construction, its page size is essentially fixed.  This is not \r
37  * as flexible as the 1.2 classes allow, but it should suffice.\r
38  */\r
39 final class MConstTextPrintable {\r
40 \r
41     static final String COPYRIGHT =\r
42                 "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";\r
43 \r
44     static final int PAGE_EXISTS = 0;\r
45     static final int NO_SUCH_PAGE = 1;\r
46     \r
47     private MConstText fText;\r
48     private AttributeMap fDefaultStyles;\r
49     private Rectangle fPageRect;\r
50     \r
51     // If these two fields are null the text has not been paginated.\r
52     private MFormatter fFormatter;\r
53     private Vector fPageStarts;\r
54 \r
55     /**\r
56      * Construct an MConstTextPrintable to print the given text.  Each page will fit\r
57      * into pageRect.\r
58      */\r
59     MConstTextPrintable(MConstText text, \r
60                         AttributeMap defaultStyles,\r
61                         Rectangle pageRect) {\r
62 \r
63         fText = text;\r
64         fDefaultStyles = defaultStyles;\r
65         fPageRect = new Rectangle(pageRect);\r
66     }\r
67     \r
68     private static boolean emptyParagraphAtEndOfText(MConstText text) {\r
69 \r
70         if (text.length() > 0) {\r
71             char ch = text.at(text.length()-1);\r
72             return ch == '\n' || ch == '\u2029';\r
73         }\r
74         else {\r
75             return false;\r
76         }\r
77     }\r
78 \r
79     private void paginate(Graphics graphics) {\r
80         \r
81         if (fPageStarts == null) {\r
82 \r
83             fFormatter = MFormatter.createFormatter(fText,\r
84                                                     fDefaultStyles,\r
85                                                     fPageRect.width,\r
86                                                     true,\r
87                                                     graphics);\r
88  \r
89             fFormatter.formatToHeight(Integer.MAX_VALUE);\r
90             fFormatter.stopBackgroundFormatting();\r
91 \r
92             fPageStarts = new Vector();\r
93             \r
94             int lineCount = fFormatter.getLineCount();\r
95             if (emptyParagraphAtEndOfText(fText)) {\r
96                 lineCount -= 1;\r
97             }\r
98 \r
99             int startLine = 0;\r
100             fPageStarts.addElement(new Integer(startLine));\r
101             int startHeight = 0;\r
102             final int pageHeight = fPageRect.height;\r
103 \r
104             while (startLine < lineCount) {\r
105 \r
106                 int nextStart = fFormatter.lineAtHeight(startHeight + pageHeight);\r
107                 fPageStarts.addElement(new Integer(nextStart));\r
108                 startHeight = fFormatter.lineGraphicStart(nextStart);\r
109                 startLine = nextStart;\r
110             }\r
111         }\r
112     }\r
113 \r
114     /**\r
115      * Print the given page in the given graphics.  Page numbers are\r
116      * 0-based.  The the return value indicates whether\r
117      * the page number is valid (as in JDK 1.2).  Since you can get the page count\r
118      * directly, there's really no excuse for passing in an invalid page\r
119      * index.\r
120      * @param graphics the Graphics to print to\r
121      * @param pageNumber the 0-based page number.  Should be nonnegative and\r
122      * less than getPageCount()\r
123      * @return PAGE_EXISTS if the page number is valid, or \r
124      *         NO_SUCH_PAGE otherwise\r
125      */\r
126     int print(Graphics graphics, int pageNumber) {\r
127         \r
128         paginate(graphics);\r
129         \r
130         if (pageNumber < getPageCount(graphics) && pageNumber >= 0) {\r
131             graphics.setColor(Color.black); // workaround for 1.2 printing bug\r
132             int startLine = ((Integer)fPageStarts.elementAt(pageNumber)).intValue();\r
133             int limitLine = ((Integer)fPageStarts.elementAt(pageNumber+1)).intValue();\r
134 \r
135             int topOfPage = fFormatter.lineGraphicStart(startLine);\r
136             int pageHeight = fFormatter.lineGraphicStart(limitLine) - topOfPage;\r
137 \r
138             Point origin = new Point(fPageRect.x, fPageRect.y - topOfPage);\r
139             Rectangle drawRect = new Rectangle(fPageRect);\r
140             drawRect.height = pageHeight;\r
141             \r
142             fFormatter.draw(graphics, drawRect, origin);\r
143             return PAGE_EXISTS;\r
144         }\r
145         else {\r
146             return NO_SUCH_PAGE;\r
147         }\r
148     }\r
149     \r
150     /**\r
151      * Return the number of pages that can be printed.\r
152      * @param graphics a Graphics instance representative of those \r
153      * which will be printed into\r
154      */\r
155     int getPageCount(Graphics graphics) {\r
156         \r
157         paginate(graphics);\r
158         return fPageStarts.size() - 1;\r
159     }\r
160 }