Source code: org/jfor/jfor/rtflib/rtfdoc/RtfColorTable.java
1 /**
2 * File: RtfColorTable.java
3 *
4 *
5 * Date Author Changes
6 * Aug 21 01 Andreas Putz Created
7 */
8 package org.jfor.jfor.rtflib.rtfdoc;
9
10 import java.util.Vector;
11 import java.util.Hashtable;
12 import java.awt.Color;
13 import java.io.IOException;
14
15 /*-----------------------------------------------------------------------------
16 * jfor - Open-Source XSL-FO to RTF converter - see www.jfor.org
17 *
18 * ====================================================================
19 * jfor Apache-Style Software License.
20 * Copyright (c) 2002 by the jfor project. All rights reserved.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 *
26 * 1. Redistributions of source code must retain the above copyright
27 * notice, this list of conditions and the following disclaimer.
28 *
29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in
31 * the documentation and/or other materials provided with the
32 * distribution.
33 *
34 * 3. The end-user documentation included with the redistribution,
35 * if any, must include the following acknowledgment:
36 * "This product includes software developed
37 * by the jfor project (http://www.jfor.org)."
38 * Alternately, this acknowledgment may appear in the software itself,
39 * if and wherever such third-party acknowledgments normally appear.
40 *
41 * 4. The name "jfor" must not be used to endorse
42 * or promote products derived from this software without prior written
43 * permission. For written permission, please contact info@jfor.org.
44 *
45 * 5. Products derived from this software may not be called "jfor",
46 * nor may "jfor" appear in their name, without prior written
47 * permission of info@jfor.org.
48 *
49 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
50 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
51 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52 * DISCLAIMED. IN NO EVENT SHALL THE JFOR PROJECT OR ITS CONTRIBUTORS BE
53 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
54 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
55 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
56 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
57 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
58 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
59 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60 * ====================================================================
61 * Contributor(s):
62 * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
63 -----------------------------------------------------------------------------*/
64
65 /**
66 * Singelton of the RTF color table.
67 * This class was created for <fo:basic-link> tag processing.
68 * @author <a href="mailto:a.putz@skynamics.com">Andreas Putz</a>
69 */
70
71 //------------------------------------------------------------------------------
72 // $Id: RtfColorTable.java,v 1.6 2003/02/18 16:10:59 rmarra Exp $
73 // $Log: RtfColorTable.java,v $
74 // Revision 1.6 2003/02/18 16:10:59 rmarra
75 // Contributions Normand Massé
76 // inheritance and other fixes
77 //
78 // Revision 1.5 2002/07/12 08:08:31 bdelacretaz
79 // License changed to jfor Apache-style license
80 //
81 // Revision 1.4 2001/09/04 07:02:17 bdelacretaz
82 // V0.4.6 - decoding of named and hexadecimal colors implemented
83 //
84 //------------------------------------------------------------------------------
85
86 public class RtfColorTable
87 {
88 //////////////////////////////////////////////////
89 // @@ Symbolic constants
90 //////////////////////////////////////////////////
91
92 // Defines the bit moving for the colors
93 private static int RED = 16;
94 private static int GREEN = 8;
95 private static int BLUE = 0;
96
97
98 //////////////////////////////////////////////////
99 // @@ Members
100 //////////////////////////////////////////////////
101
102 /** Singelton instance */
103 private static RtfColorTable instance = null;
104
105 /** Index table for the colors */
106 private Hashtable colorIndex = null;
107 /** Used colors to this vector */
108 private Vector colorTable = null;
109 /** Map of color names to color numbers */
110 private Hashtable namedColors = null;
111
112
113 //////////////////////////////////////////////////
114 // @@ Construction
115 //////////////////////////////////////////////////
116
117 /**
118 * Constructor.
119 */
120 private RtfColorTable ()
121 {
122 colorTable = new Vector ();
123 colorIndex = new Hashtable ();
124 namedColors = new Hashtable ();
125
126 init ();
127 }
128
129 /**
130 * Singelton.
131 *
132 * @return The instance of RTFColorTable
133 */
134 public static RtfColorTable getInstance ()
135 {
136 if (instance == null)
137 {
138 instance = new RtfColorTable ();
139 }
140
141 return instance;
142 }
143
144
145 //////////////////////////////////////////////////
146 // @@ Initializing
147 //////////////////////////////////////////////////
148
149 /**
150 * Initialize the color table.
151 */
152 private void init ()
153 {
154 addNamedColor("black",getColorNumber (0, 0, 0));
155 addNamedColor("white",getColorNumber (255, 255, 255));
156 addNamedColor("red",getColorNumber (255, 0, 0));
157 addNamedColor("green",getColorNumber (0, 255, 0));
158 addNamedColor("blue",getColorNumber (0, 0, 255));
159 addNamedColor("cyan",getColorNumber (0, 255, 255));
160 addNamedColor("magenta",getColorNumber (255, 0, 255));
161 addNamedColor("yellow",getColorNumber (255, 255, 0));
162
163 getColorNumber (0, 0, 128);
164 getColorNumber (0, 128, 128);
165 getColorNumber (0, 128, 0);
166 getColorNumber (128, 0, 128);
167 getColorNumber (128, 0, 0);
168 getColorNumber (128, 128, 0);
169 getColorNumber (128, 128, 128);
170
171 // Added by Normand Masse
172 // Gray color added
173 addNamedColor( "gray", getColorNumber( 128, 128, 128 ) );
174
175 getColorNumber (192, 192, 192);
176 }
177
178 /** define a named color for getColorNumber(String) */
179 private void addNamedColor(String name,int colorNumber)
180 {
181 namedColors.put(name.toLowerCase(),new Integer(colorNumber));
182 }
183
184 //////////////////////////////////////////////////
185 // @@ Public methods
186 //////////////////////////////////////////////////
187
188 /** get the RTF number of a named color
189 * @return null if name not found
190 */
191 public Integer getColorNumber (String name)
192 {
193 return (Integer)namedColors.get(name.toLowerCase());
194 }
195
196 /**
197 * Gets the number of color in the color table
198 *
199 * @param red Color level red
200 * @param green Color level green
201 * @param blue Color level blue
202 *
203 * @return The number of the color in the table
204 */
205 public int getColorNumber (int red, int green, int blue)
206 {
207 Integer identifier = new Integer (determineIdentifier (red, green, blue));
208 Object o = colorIndex.get (identifier);
209 int retVal;
210
211 if (o == null)
212 {
213 addColor (identifier);
214
215 retVal = colorTable.size ();
216 }
217 else
218 {
219 retVal = ((Integer) o).intValue ();
220 }
221
222 return retVal + 1;
223 }
224
225 /**
226 * Writes the color table in the header.
227 *
228 * @param header The header container to write in
229 *
230 * @throws IOException On error
231 */
232 public void writeColors (RtfHeader header) throws IOException
233 {
234 if (colorTable == null || colorTable.size () == 0)
235 {
236 return;
237 }
238
239 header.writeGroupMark (true);
240 header.writeControlWord ("colortbl;");
241
242 int len = colorTable.size ();
243
244 for (int i = 0; i < len; i++)
245 {
246 int identifier = ((Integer) colorTable.get (i)).intValue ();
247
248 header.write ("\\red" + determineColorLevel (identifier, RED));
249 header.write ("\\green" + determineColorLevel (identifier, GREEN));
250 header.write ("\\blue" + determineColorLevel (identifier, BLUE) + ";");
251 }
252
253 header.writeGroupMark (false);
254 }
255
256
257 //////////////////////////////////////////////////
258 // @@ Private methods
259 //////////////////////////////////////////////////
260
261 /**
262 * Adds a color to the table.
263 *
264 * @param i Identifier of color
265 */
266 private void addColor (Integer i)
267 {
268 colorIndex.put (i, new Integer (colorTable.size () + 1));
269 colorTable.addElement (i);
270 }
271
272 /**
273 * Determines a identifier for the color.
274 *
275 * @param red Color level red
276 * @param green Color level green
277 * @param blue Color level blue
278 *
279 * @return Unique identifier of color
280 */
281 private int determineIdentifier (int red, int green, int blue)
282 {
283 int c = red << RED;
284
285 c += green << GREEN;
286 c += blue << BLUE;
287
288 return c;
289 }
290
291 /**
292 * Determines the color level from the identifier.
293 *
294 * @param identifier Unique color identifier
295 * @param color One of the bit moving constants
296 *
297 * @return Color level in byte size
298 */
299 private int determineColorLevel (int identifier, int color)
300 {
301 int retVal = (byte) (identifier >> color);
302
303 return retVal < 0 ? retVal + 256 : retVal;
304 }
305 }