]> git.somenet.org - irc/pjirc-ng.git/blob - src/main/java/irc/style/CharactersDrawer.java
Pjirc 2.2.1 as available on the net, reformatted and made it compile.
[irc/pjirc-ng.git] / src / main / java / irc / style / CharactersDrawer.java
1 /*****************************************************/
2 /*          This java file is a part of the          */
3 /*                                                   */
4 /*           -  Plouf's Java IRC Client  -           */
5 /*                                                   */
6 /*   Copyright (C)  2002 - 2004 Philippe Detournay   */
7 /*                                                   */
8 /*         All contacts : theplouf@yahoo.com         */
9 /*                                                   */
10 /*  PJIRC is free software; you can redistribute     */
11 /*  it and/or modify it under the terms of the GNU   */
12 /*  General Public License as published by the       */
13 /*  Free Software Foundation; version 2 or later of  */
14 /*  the License.                                     */
15 /*                                                   */
16 /*  PJIRC is distributed in the hope that it will    */
17 /*  be useful, but WITHOUT ANY WARRANTY; without     */
18 /*  even the implied warranty of MERCHANTABILITY or  */
19 /*  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   */
20 /*  General Public License for more details.         */
21 /*                                                   */
22 /*  You should have received a copy of the GNU       */
23 /*  General Public License along with PJIRC; if      */
24 /*  not, write to the Free Software Foundation,      */
25 /*  Inc., 59 Temple Place, Suite 330, Boston,        */
26 /*  MA  02111-1307  USA                              */
27 /*                                                   */
28 /*****************************************************/
29
30 package irc.style;
31
32 import irc.IRCConfiguration;
33 import irc.SmileyTable;
34
35 import java.awt.Dimension;
36 import java.awt.FontMetrics;
37 import java.awt.Graphics;
38 import java.awt.Image;
39 import java.awt.image.ImageObserver;
40 import java.util.Vector;
41
42 /**
43  * Atomic characters drawer. The CharactersDrawer handles graphical smileys.
44  */
45 public class CharactersDrawer {
46         private IRCConfiguration _ircConfiguration;
47         private char[] _current;
48         private int _lineSpacing;
49
50         /**
51          * Create a new CharactersDrawer.
52          * 
53          * @param config
54          *          the irc configuration.
55          */
56         public CharactersDrawer(IRCConfiguration config) {
57                 _ircConfiguration = config;
58                 _current = new char[256];
59                 _lineSpacing = config.getI("style:linespacing");
60         }
61
62         private int getBitmapSmileyWidth(int c, ImageObserver obs) {
63                 Image img = _ircConfiguration.getSmileyTable().getImage(c);
64                 if (img == null)
65                         return 0;
66                 return img.getWidth(obs);
67         }
68
69         private int getBitmapSmileyHeight(int c, ImageObserver obs) {
70                 Image img = _ircConfiguration.getSmileyTable().getImage(c);
71                 if (img == null)
72                         return 0;
73                 return img.getHeight(obs);
74         }
75
76         private Object drawBitmapSmiley(Graphics g, FontMetrics fm, int smiley, int x, int y, ImageObserver obs) {
77                 Image img = _ircConfiguration.getSmileyTable().getImage(smiley);
78                 if (img == null)
79                         return null;
80                 int h = getBitmapSmileyHeight(smiley, obs);
81                 y -= h;
82                 y += fm.getDescent();
83
84                 g.drawImage(img, x, y, obs);
85                 return img;
86         }
87
88         private String handleSmiley(String line, String ascii, char code) {
89                 int pos = line.indexOf(ascii);
90                 if (pos == -1)
91                         return line;
92
93                 String previous = line.substring(0, pos);
94                 String after = line.substring(pos + ascii.length());
95                 char toAdd = (char) (code + 0xE000);
96                 line = previous + toAdd + after;
97                 return handleSmiley(line, ascii, code);
98         }
99
100         /**
101          * Prepare and decode the given line for smileys.
102          * 
103          * @param line
104          *          source line, before smileys replacement.
105          * @return prepared line with special characters.
106          */
107         public String decodeLine(String line) {
108                 SmileyTable table = _ircConfiguration.getSmileyTable();
109                 int s = table.getSize();
110                 for (int i = 0; i < s; i++) {
111                         String m = table.getMatch(i);
112                         line = handleSmiley(line, m, (char) (i));
113                 }
114                 return line;
115         }
116
117         /**
118          * Get the given string width, in pixel.
119          * 
120          * @param str
121          *          the prepared line.
122          * @param fm
123          *          the FontMetrics that will be used on display.
124          * @param obs
125          *          the image observer in case of bitmap handling.
126          * @return the string width, in pixel.
127          */
128         public int getWidth(String str, FontMetrics fm, ImageObserver obs) {
129                 if (_current.length < str.length())
130                         _current = new char[str.length() * 2];
131                 int size = 0;
132                 int w = 0;
133                 for (int i = 0; i < str.length(); i++) {
134                         char c = str.charAt(i);
135                         if ((c >= 0xE000) && (c <= 0xF8FF)) {
136                                 c -= 0xE000;
137                                 w += fm.charsWidth(_current, 0, size);
138                                 size = 0;
139                                 w += getBitmapSmileyWidth(c, obs);
140                         } else {
141                                 _current[size++] = c;
142                         }
143                 }
144                 w += fm.charsWidth(_current, 0, size);
145                 return w;
146         }
147
148         /**
149          * Get the given string height, in pixel.
150          * 
151          * @param str
152          *          the prepared line.
153          * @param fm
154          *          the FontMetrics that will be used on display.
155          * @param obs
156          *          the image observer in case of bitmap handling.
157          * @return the string height, in pixel.
158          */
159         public int getHeight(String str, FontMetrics fm, ImageObserver obs) {
160                 int h = 0;
161                 int mh = 0;
162                 for (int i = 0; i < str.length(); i++) {
163                         char c = str.charAt(i);
164                         if ((c >= 0xE000) && (c <= 0xF8FF)) {
165                                 c -= 0xE000;
166                                 h = getBitmapSmileyHeight(c, obs);
167                                 if (h > mh)
168                                         mh = h;
169                         }
170                 }
171                 h = fm.getFont().getSize() + 1;
172                 if (h > mh)
173                         mh = h;
174                 return mh + _lineSpacing;
175         }
176
177         /**
178          * Get the given string width and height, in pixel.
179          * 
180          * @param str
181          *          the prepared line.
182          * @param fm
183          *          the FontMetrics that will be used on display.
184          * @param res
185          *          Dimension to be used for result.
186          * @param obs
187          *          the image observer in case of bitmap handling.
188          */
189         public void getWidthHeight(String str, FontMetrics fm, Dimension res, ImageObserver obs) {
190                 if (_current.length < str.length())
191                         _current = new char[str.length() * 2];
192                 int size = 0;
193                 int h = 0;
194                 int w = 0;
195                 int mh = 0;
196                 for (int i = 0; i < str.length(); i++) {
197                         char c = str.charAt(i);
198                         if ((c >= 0xE000) && (c <= 0xF8FF)) {
199                                 c -= 0xE000;
200                                 w += fm.charsWidth(_current, 0, size);
201                                 h = getBitmapSmileyHeight(c, obs);
202                                 if (h > mh)
203                                         mh = h;
204                                 w += getBitmapSmileyWidth(c, obs);
205                                 size = 0;
206                         } else {
207                                 _current[size++] = c;
208                         }
209                 }
210                 w += fm.charsWidth(_current, 0, size);
211                 h = fm.getFont().getSize() + 1;
212                 if (h > mh)
213                         mh = h;
214                 res.width = w;
215                 res.height = mh + _lineSpacing;
216         }
217
218         /**
219          * Draw the given prepared line.
220          * 
221          * @param str
222          *          prepared line to draw.
223          * @param g
224          *          graphics to draw onto.
225          * @param fm
226          *          fontmetrics to use.
227          * @param x
228          *          x position.
229          * @param y
230          *          y position.
231          * @param obs
232          *          the image observer in case of bitmap display.
233          * @param handles
234          *          target vector, where all update handles will be put.
235          */
236         public void draw(String str, Graphics g, FontMetrics fm, int x, int y, ImageObserver obs, Vector handles) {
237                 if (_current.length < str.length())
238                         _current = new char[str.length() * 2];
239                 int size = 0;
240                 for (int i = 0; i < str.length(); i++) {
241                         char c = str.charAt(i);
242                         if ((c >= 0xE000) && (c <= 0xF8FF)) {
243                                 c -= 0xE000;
244                                 g.drawChars(_current, 0, size, x, y);
245                                 x += fm.charsWidth(_current, 0, size);
246                                 size = 0;
247                                 Object handle = drawBitmapSmiley(g, fm, c, x, y, obs);
248                                 if (handles == null)
249                                         handles = new Vector();
250                                 handles.insertElementAt(handle, handles.size());
251                                 x += getBitmapSmileyWidth(c, obs);
252                         } else {
253                                 _current[size++] = c;
254                         }
255                 }
256                 g.drawChars(_current, 0, size, x, y);
257         }
258 }