You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RtfColorTable.java 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.render.rtf.rtflib.rtfdoc;
  19. /*
  20. * This file is part of the RTF library of the FOP project, which was originally
  21. * created by Bertrand Delacretaz <bdelacretaz@codeconsult.ch> and by other
  22. * contributors to the jfor project (www.jfor.org), who agreed to donate jfor to
  23. * the FOP project.
  24. */
  25. import java.io.IOException;
  26. import java.util.Hashtable;
  27. import java.util.Vector;
  28. /**
  29. * <p>Singelton of the RTF color table.
  30. * This class was created for <fo:basic-link> tag processing.</p>
  31. *
  32. * <p>This work was authored by Andreas Putz (a.putz@skynamics.com).</p>
  33. */
  34. public final class RtfColorTable {
  35. //////////////////////////////////////////////////
  36. // @@ Symbolic constants
  37. //////////////////////////////////////////////////
  38. // Defines the bit moving for the colors
  39. private static final int RED = 16;
  40. private static final int GREEN = 8;
  41. private static final int BLUE = 0;
  42. //////////////////////////////////////////////////
  43. // @@ Members
  44. //////////////////////////////////////////////////
  45. /** Singelton instance */
  46. private static RtfColorTable instance = new RtfColorTable();
  47. /** Index table for the colors */
  48. private Hashtable colorIndex;
  49. /** Used colors to this vector */
  50. private Vector colorTable;
  51. /** Map of color names to color numbers */
  52. private Hashtable namedColors;
  53. //////////////////////////////////////////////////
  54. // @@ Construction
  55. //////////////////////////////////////////////////
  56. /**
  57. * Constructor.
  58. */
  59. private RtfColorTable() {
  60. colorTable = new Vector();
  61. colorIndex = new Hashtable();
  62. namedColors = new Hashtable();
  63. init();
  64. }
  65. /**
  66. * Singelton.
  67. *
  68. * @return The instance of RTFColorTable
  69. */
  70. public static RtfColorTable getInstance() {
  71. return instance;
  72. }
  73. //////////////////////////////////////////////////
  74. // @@ Initializing
  75. //////////////////////////////////////////////////
  76. /**
  77. * Initialize the color table.
  78. */
  79. private void init() {
  80. addNamedColor("black", getColorNumber(0, 0, 0).intValue());
  81. addNamedColor("white", getColorNumber(255, 255, 255).intValue());
  82. addNamedColor("red", getColorNumber(255, 0, 0).intValue());
  83. addNamedColor("green", getColorNumber(0, 255, 0).intValue());
  84. addNamedColor("blue", getColorNumber(0, 0, 255).intValue());
  85. addNamedColor("cyan", getColorNumber(0, 255, 255).intValue());
  86. addNamedColor("magenta", getColorNumber(255, 0, 255).intValue());
  87. addNamedColor("yellow", getColorNumber(255, 255, 0).intValue());
  88. getColorNumber(0, 0, 128);
  89. getColorNumber(0, 128, 128);
  90. getColorNumber(0, 128, 0);
  91. getColorNumber(128, 0, 128);
  92. getColorNumber(128, 0, 0);
  93. getColorNumber(128, 128, 0);
  94. getColorNumber(128, 128, 128);
  95. // Added by Normand Masse
  96. // Gray color added
  97. addNamedColor("gray", getColorNumber(128, 128, 128).intValue());
  98. getColorNumber(192, 192, 192);
  99. }
  100. /** define a named color for getColorNumber(String) */
  101. private void addNamedColor(String name, int colorNumber) {
  102. namedColors.put(name.toLowerCase(), colorNumber);
  103. }
  104. //////////////////////////////////////////////////
  105. // @@ Public methods
  106. //////////////////////////////////////////////////
  107. /**
  108. * @param name a named color
  109. * @return the RTF number of a named color, or null if name not found
  110. */
  111. public Integer getColorNumber(String name) {
  112. return ((Integer)namedColors.get(name.toLowerCase()));
  113. }
  114. /**
  115. * Gets the number of color in the color table
  116. *
  117. * @param red Color level red
  118. * @param green Color level green
  119. * @param blue Color level blue
  120. *
  121. * @return The number of the color in the table
  122. */
  123. public Integer getColorNumber(int red, int green, int blue) {
  124. Integer identifier = determineIdentifier(red, green, blue);
  125. Object o = colorIndex.get(identifier);
  126. int retVal;
  127. if (o == null) {
  128. //The color currently does not exist, so add it to the table.
  129. //First add it, then read the size as index (to return it).
  130. //So the first added color gets index 1. That is OK, because
  131. //index 0 is reserved for auto-colored.
  132. addColor(identifier);
  133. retVal = colorTable.size();
  134. } else {
  135. //The color was found. Before returning the index, increment
  136. //it by one. Because index 0 is reserved for auto-colored, but
  137. //is not contained in colorTable.
  138. retVal = ((Integer) o).intValue() + 1;
  139. }
  140. return retVal;
  141. }
  142. /**
  143. * Writes the color table in the header.
  144. *
  145. * @param header The header container to write in
  146. *
  147. * @throws IOException On error
  148. */
  149. public void writeColors(RtfHeader header) throws IOException {
  150. if (colorTable == null || colorTable.size() == 0) {
  151. return;
  152. }
  153. header.newLine();
  154. header.writeGroupMark(true);
  155. //Don't use writeControlWord, because it appends a blank,
  156. //which may confuse Wordpad.
  157. //This also implicitly writes the first color (=index 0), which
  158. //is reserved for auto-colored.
  159. header.write("\\colortbl;");
  160. int len = colorTable.size();
  161. for (int i = 0; i < len; i++) {
  162. int identifier = ((Integer) colorTable.get(i)).intValue();
  163. header.newLine();
  164. header.write("\\red" + determineColorLevel(identifier, RED));
  165. header.write("\\green" + determineColorLevel(identifier, GREEN));
  166. header.write("\\blue" + determineColorLevel(identifier, BLUE) + ";");
  167. }
  168. header.newLine();
  169. header.writeGroupMark(false);
  170. }
  171. //////////////////////////////////////////////////
  172. // @@ Private methods
  173. //////////////////////////////////////////////////
  174. /**
  175. * Adds a color to the table.
  176. *
  177. * @param i Identifier of color
  178. */
  179. private void addColor(Integer i) {
  180. colorIndex.put(i, colorTable.size());
  181. colorTable.addElement(i);
  182. }
  183. /**
  184. * Determines a identifier for the color.
  185. *
  186. * @param red Color level red
  187. * @param green Color level green
  188. * @param blue Color level blue
  189. *
  190. * @return Unique identifier of color
  191. */
  192. private int determineIdentifier(int red, int green, int blue) {
  193. int c = red << RED;
  194. c += green << GREEN;
  195. c += blue << BLUE;
  196. return c;
  197. }
  198. /**
  199. * Determines the color level from the identifier.
  200. *
  201. * @param identifier Unique color identifier
  202. * @param color One of the bit moving constants
  203. *
  204. * @return Color level in byte size
  205. */
  206. private int determineColorLevel(int identifier, int color) {
  207. int retVal = (byte) (identifier >> color);
  208. return retVal < 0 ? retVal + 256 : retVal;
  209. }
  210. }