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.

HSSFColor.java 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  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. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.hssf.util;
  16. import java.util.Collections;
  17. import java.util.EnumMap;
  18. import java.util.HashMap;
  19. import java.util.Locale;
  20. import java.util.Map;
  21. import java.util.Objects;
  22. import org.apache.poi.ss.usermodel.Color;
  23. import org.apache.poi.util.Removal;
  24. /**
  25. * Intends to provide support for the very evil index to triplet issue and
  26. * will likely replace the color constants interface for HSSF 2.0.
  27. * This class contains static inner class members for representing colors.
  28. * Each color has an index (for the standard palette in Excel (tm) ),
  29. * native (RGB) triplet and string triplet. The string triplet is as the
  30. * color would be represented by Gnumeric. Having (string) this here is a bit of a
  31. * collision of function between HSSF and the HSSFSerializer but I think its
  32. * a reasonable one in this case.
  33. */
  34. public class HSSFColor implements Color {
  35. private static Map<Integer,HSSFColor> indexHash;
  36. private static Map<HSSFColorPredefined,HSSFColor> enumList;
  37. private java.awt.Color color;
  38. private int index;
  39. private int index2;
  40. /**
  41. * Predefined HSSFColors with their given palette index (and an optional 2nd index)
  42. *
  43. * @since POI 3.16 beta 2
  44. */
  45. public enum HSSFColorPredefined {
  46. BLACK (0x08, -1, 0x000000),
  47. BROWN (0x3C, -1, 0x993300),
  48. OLIVE_GREEN (0x3B, -1, 0x333300),
  49. DARK_GREEN (0x3A, -1, 0x003300),
  50. DARK_TEAL (0x38, -1, 0x003366),
  51. DARK_BLUE (0x12, 0x20, 0x000080),
  52. INDIGO (0x3E, -1, 0x333399),
  53. GREY_80_PERCENT (0x3F, -1, 0x333333),
  54. ORANGE (0x35, -1, 0xFF6600),
  55. DARK_YELLOW (0x13, -1, 0x808000),
  56. GREEN (0x11, -1, 0x008000),
  57. TEAL (0x15, 0x26, 0x008080),
  58. BLUE (0x0C, 0x27, 0x0000FF),
  59. BLUE_GREY (0x36, -1, 0x666699),
  60. GREY_50_PERCENT (0x17, -1, 0x808080),
  61. RED (0x0A, -1, 0xFF0000),
  62. LIGHT_ORANGE (0x34, -1, 0xFF9900),
  63. LIME (0x32, -1, 0x99CC00),
  64. SEA_GREEN (0x39, -1, 0x339966),
  65. AQUA (0x31, -1, 0x33CCCC),
  66. LIGHT_BLUE (0x30, -1, 0x3366FF),
  67. VIOLET (0x14, 0x24, 0x800080),
  68. GREY_40_PERCENT (0x37, -1, 0x969696),
  69. PINK (0x0E, 0x21, 0xFF00FF),
  70. GOLD (0x33, -1, 0xFFCC00),
  71. YELLOW (0x0D, 0x22, 0xFFFF00),
  72. BRIGHT_GREEN (0x0B, -1, 0x00FF00),
  73. TURQUOISE (0x0F, 0x23, 0x00FFFF),
  74. DARK_RED (0x10, 0x25, 0x800000),
  75. SKY_BLUE (0x28, -1, 0x00CCFF),
  76. PLUM (0x3D, 0x19, 0x993366),
  77. GREY_25_PERCENT (0x16, -1, 0xC0C0C0),
  78. ROSE (0x2D, -1, 0xFF99CC),
  79. LIGHT_YELLOW (0x2B, -1, 0xFFFF99),
  80. LIGHT_GREEN (0x2A, -1, 0xCCFFCC),
  81. LIGHT_TURQUOISE (0x29, 0x1B, 0xCCFFFF),
  82. PALE_BLUE (0x2C, -1, 0x99CCFF),
  83. LAVENDER (0x2E, -1, 0xCC99FF),
  84. WHITE (0x09, -1, 0xFFFFFF),
  85. CORNFLOWER_BLUE (0x18, -1, 0x9999FF),
  86. LEMON_CHIFFON (0x1A, -1, 0xFFFFCC),
  87. MAROON (0x19, -1, 0x7F0000),
  88. ORCHID (0x1C, -1, 0x660066),
  89. CORAL (0x1D, -1, 0xFF8080),
  90. ROYAL_BLUE (0x1E, -1, 0x0066CC),
  91. LIGHT_CORNFLOWER_BLUE(0x1F, -1, 0xCCCCFF),
  92. TAN (0x2F, -1, 0xFFCC99),
  93. /**
  94. * Special Default/Normal/Automatic color.<p>
  95. * <i>Note:</i> This class is NOT in the default Map returned by HSSFColor.
  96. * The index is a special case which is interpreted in the various setXXXColor calls.
  97. */
  98. AUTOMATIC (0x40, -1, 0x000000);
  99. private HSSFColor color;
  100. HSSFColorPredefined(int index, int index2, int rgb) {
  101. this.color = new HSSFColor(index, index2, new java.awt.Color(rgb));
  102. }
  103. /**
  104. * @see HSSFColor#getIndex()
  105. */
  106. public short getIndex() {
  107. return color.getIndex();
  108. }
  109. /**
  110. * @see HSSFColor#getIndex2()
  111. */
  112. public short getIndex2() {
  113. return color.getIndex2();
  114. }
  115. /**
  116. * @see HSSFColor#getTriplet()
  117. */
  118. public short [] getTriplet() {
  119. return color.getTriplet();
  120. }
  121. /**
  122. * @see HSSFColor#getHexString()
  123. */
  124. public String getHexString() {
  125. return color.getHexString();
  126. }
  127. /**
  128. * @return (a copy of) the HSSFColor assigned to the enum
  129. */
  130. public HSSFColor getColor() {
  131. return new HSSFColor(getIndex(), getIndex2(), color.color);
  132. }
  133. }
  134. /** Creates a new instance of HSSFColor */
  135. public HSSFColor() {
  136. // automatic index
  137. this(0x40, -1, java.awt.Color.BLACK);
  138. }
  139. public HSSFColor(int index, int index2, java.awt.Color color) {
  140. this.index = index;
  141. this.index2 = index2;
  142. this.color = color;
  143. }
  144. /**
  145. * This function returns all the colours in an unmodifiable Map.
  146. * The map is cached on first use.
  147. *
  148. * @return a Map containing all colours keyed by <tt>Integer</tt> excel-style palette indexes
  149. */
  150. public static synchronized Map<Integer,HSSFColor> getIndexHash() {
  151. if(indexHash == null) {
  152. indexHash = Collections.unmodifiableMap( createColorsByIndexMap() );
  153. }
  154. return indexHash;
  155. }
  156. /**
  157. * This function returns all the Colours, stored in a Map that
  158. * can be edited. No caching is performed. If you don't need to edit
  159. * the table, then call {@link #getIndexHash()} which returns a
  160. * statically cached immutable map of colours.
  161. */
  162. public static Map<Integer,HSSFColor> getMutableIndexHash() {
  163. return createColorsByIndexMap();
  164. }
  165. private static Map<Integer,HSSFColor> createColorsByIndexMap() {
  166. Map<HSSFColorPredefined,HSSFColor> eList = mapEnumToColorClass();
  167. Map<Integer,HSSFColor> result = new HashMap<>(eList.size() * 3 / 2);
  168. for (Map.Entry<HSSFColorPredefined,HSSFColor> colorRef : eList.entrySet()) {
  169. Integer index1 = (int)colorRef.getKey().getIndex();
  170. if (!result.containsKey(index1)) {
  171. result.put(index1, colorRef.getValue());
  172. }
  173. Integer index2 = (int)colorRef.getKey().getIndex2();
  174. if (index2 != -1 && !result.containsKey(index2)) {
  175. result.put(index2, colorRef.getValue());
  176. }
  177. }
  178. return result;
  179. }
  180. /**
  181. * this function returns all colors in a hastable. It's not implemented as a
  182. * static member/statically initialized because that would be dirty in a
  183. * server environment as it is intended. This means you'll eat the time
  184. * it takes to create it once per request but you will not hold onto it
  185. * if you have none of those requests.
  186. *
  187. * @return a Map containing all colors keyed by String gnumeric-like triplets
  188. */
  189. public static Map<String,HSSFColor> getTripletHash()
  190. {
  191. return createColorsByHexStringMap();
  192. }
  193. private static Map<String,HSSFColor> createColorsByHexStringMap() {
  194. Map<HSSFColorPredefined,HSSFColor> eList = mapEnumToColorClass();
  195. Map<String,HSSFColor> result = new HashMap<>(eList.size());
  196. for (Map.Entry<HSSFColorPredefined,HSSFColor> colorRef : eList.entrySet()) {
  197. String hexString = colorRef.getKey().getHexString();
  198. if (!result.containsKey(hexString)) {
  199. result.put(hexString, colorRef.getValue());
  200. }
  201. }
  202. return result;
  203. }
  204. /**
  205. * Maps the Enums to the HSSFColor, in cases of user code evaluating the classname
  206. *
  207. * @deprecated in 3.16 - remove mapping when subclasses are removed and access
  208. * HSSFColorPredefined.values() directly (but exclude AUTOMATIC)
  209. */
  210. @Deprecated
  211. @Removal(version="3.18")
  212. private static synchronized Map<HSSFColorPredefined,HSSFColor> mapEnumToColorClass() {
  213. if (enumList == null) {
  214. enumList = new EnumMap<>(HSSFColorPredefined.class);
  215. // AUTOMATIC is not add to list
  216. addHSSFColorPredefined(HSSFColorPredefined.BLACK);
  217. addHSSFColorPredefined(HSSFColorPredefined.BROWN);
  218. addHSSFColorPredefined(HSSFColorPredefined.OLIVE_GREEN);
  219. addHSSFColorPredefined(HSSFColorPredefined.DARK_GREEN);
  220. addHSSFColorPredefined(HSSFColorPredefined.DARK_TEAL);
  221. addHSSFColorPredefined(HSSFColorPredefined.DARK_BLUE);
  222. addHSSFColorPredefined(HSSFColorPredefined.INDIGO);
  223. addHSSFColorPredefined(HSSFColorPredefined.GREY_80_PERCENT);
  224. addHSSFColorPredefined(HSSFColorPredefined.ORANGE);
  225. addHSSFColorPredefined(HSSFColorPredefined.DARK_YELLOW);
  226. addHSSFColorPredefined(HSSFColorPredefined.GREEN);
  227. addHSSFColorPredefined(HSSFColorPredefined.TEAL);
  228. addHSSFColorPredefined(HSSFColorPredefined.BLUE);
  229. addHSSFColorPredefined(HSSFColorPredefined.BLUE_GREY);
  230. addHSSFColorPredefined(HSSFColorPredefined.GREY_50_PERCENT);
  231. addHSSFColorPredefined(HSSFColorPredefined.RED);
  232. addHSSFColorPredefined(HSSFColorPredefined.LIGHT_ORANGE);
  233. addHSSFColorPredefined(HSSFColorPredefined.LIME);
  234. addHSSFColorPredefined(HSSFColorPredefined.SEA_GREEN);
  235. addHSSFColorPredefined(HSSFColorPredefined.AQUA);
  236. addHSSFColorPredefined(HSSFColorPredefined.LIGHT_BLUE);
  237. addHSSFColorPredefined(HSSFColorPredefined.VIOLET);
  238. addHSSFColorPredefined(HSSFColorPredefined.GREY_40_PERCENT);
  239. addHSSFColorPredefined(HSSFColorPredefined.PINK);
  240. addHSSFColorPredefined(HSSFColorPredefined.GOLD);
  241. addHSSFColorPredefined(HSSFColorPredefined.YELLOW);
  242. addHSSFColorPredefined(HSSFColorPredefined.BRIGHT_GREEN);
  243. addHSSFColorPredefined(HSSFColorPredefined.TURQUOISE);
  244. addHSSFColorPredefined(HSSFColorPredefined.DARK_RED);
  245. addHSSFColorPredefined(HSSFColorPredefined.SKY_BLUE);
  246. addHSSFColorPredefined(HSSFColorPredefined.PLUM);
  247. addHSSFColorPredefined(HSSFColorPredefined.GREY_25_PERCENT);
  248. addHSSFColorPredefined(HSSFColorPredefined.ROSE);
  249. addHSSFColorPredefined(HSSFColorPredefined.LIGHT_YELLOW);
  250. addHSSFColorPredefined(HSSFColorPredefined.LIGHT_GREEN);
  251. addHSSFColorPredefined(HSSFColorPredefined.LIGHT_TURQUOISE);
  252. addHSSFColorPredefined(HSSFColorPredefined.PALE_BLUE);
  253. addHSSFColorPredefined(HSSFColorPredefined.LAVENDER);
  254. addHSSFColorPredefined(HSSFColorPredefined.WHITE);
  255. addHSSFColorPredefined(HSSFColorPredefined.CORNFLOWER_BLUE);
  256. addHSSFColorPredefined(HSSFColorPredefined.LEMON_CHIFFON);
  257. addHSSFColorPredefined(HSSFColorPredefined.MAROON);
  258. addHSSFColorPredefined(HSSFColorPredefined.ORCHID);
  259. addHSSFColorPredefined(HSSFColorPredefined.CORAL);
  260. addHSSFColorPredefined(HSSFColorPredefined.ROYAL_BLUE);
  261. addHSSFColorPredefined(HSSFColorPredefined.LIGHT_CORNFLOWER_BLUE);
  262. addHSSFColorPredefined(HSSFColorPredefined.TAN);
  263. }
  264. return enumList;
  265. }
  266. private static void addHSSFColorPredefined(HSSFColorPredefined color) {
  267. enumList.put(color, color.getColor());
  268. }
  269. /**
  270. * returns color standard palette index
  271. * @return index to the standard palette
  272. */
  273. public short getIndex() {
  274. return (short)index;
  275. }
  276. /**
  277. * returns alternative color standard palette index
  278. * @return alternative index to the standard palette, if -1 this index is not defined
  279. */
  280. public short getIndex2() {
  281. return (short)index2;
  282. }
  283. /**
  284. * returns RGB triplet (0, 0, 0)
  285. * @return triplet representation like that in Excel
  286. */
  287. public short [] getTriplet() {
  288. return new short[] { (short)color.getRed(), (short)color.getGreen(), (short)color.getBlue() };
  289. }
  290. /**
  291. * returns colon-delimited hex string "0:0:0"
  292. * @return a hex string exactly like a gnumeric triplet
  293. */
  294. public String getHexString() {
  295. return (Integer.toHexString(color.getRed()*0x101) + ":" +
  296. Integer.toHexString(color.getGreen()*0x101) + ":" +
  297. Integer.toHexString(color.getBlue()*0x101)).toUpperCase(Locale.ROOT);
  298. }
  299. @Override
  300. public boolean equals(Object o) {
  301. if (this == o) return true;
  302. if (o == null || getClass() != o.getClass()) return false;
  303. HSSFColor hssfColor = (HSSFColor) o;
  304. if (index != hssfColor.index) return false;
  305. if (index2 != hssfColor.index2) return false;
  306. return color != null ? color.equals(hssfColor.color) : hssfColor.color == null;
  307. }
  308. @Override
  309. public int hashCode() {
  310. return Objects.hash(color,index,index2);
  311. }
  312. /**
  313. * Checked type cast <tt>color</tt> to an HSSFColor.
  314. *
  315. * @param color the color to type cast
  316. * @return the type casted color
  317. * @throws IllegalArgumentException if color is null or is not an instance of HSSFColor
  318. */
  319. public static HSSFColor toHSSFColor(Color color) {
  320. // FIXME: this method would be more useful if it could convert any Color to an HSSFColor
  321. // Currently the only benefit of this method is to throw an IllegalArgumentException
  322. // instead of a ClassCastException.
  323. if (color != null && !(color instanceof HSSFColor)) {
  324. throw new IllegalArgumentException("Only HSSFColor objects are supported, but had " + color.getClass());
  325. }
  326. return (HSSFColor)color;
  327. }
  328. }