summaryrefslogtreecommitdiff
path: root/xmerge/source/xmerge/java/org/openoffice/xmerge/util/ColourConverter.java
diff options
context:
space:
mode:
Diffstat (limited to 'xmerge/source/xmerge/java/org/openoffice/xmerge/util/ColourConverter.java')
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/util/ColourConverter.java446
1 files changed, 446 insertions, 0 deletions
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/util/ColourConverter.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/ColourConverter.java
new file mode 100644
index 000000000000..33ef294d4ae8
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/util/ColourConverter.java
@@ -0,0 +1,446 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package org.openoffice.xmerge.util;
+
+
+import java.awt.Color;
+
+/**
+ * Utility class mapping RGB colour specifications to the colour indices used
+ * in the Pocket PC. The original converter was written for use with Pocket
+ * Word it was later put into the utils so Pocket excel could use this code
+ * also. For this reason the defualt values are those used by Pocket Word but
+ * a colour table can be passed in through the constructor to map the 16
+ * values to a colour table.
+ *
+ * These colour indices are based on the Windows VGA 16 colour palette, which
+ * later was used as the basis for the named colours in the HTML 3.2
+ * specification.
+ *
+ * In Pocket Word's case, the match to the VGA 16 palette is not exact as it
+ * swaps Grey and Silver, with Silver being the darker colour (i.e. having the
+ * lower RGB value).
+ */
+
+public class ColourConverter {
+
+ /** Colour table index for Black */
+ private static final short BLACK = 0;
+
+ /** Colour table index for Silver */
+ private static final short SILVER = 1;
+
+ /** Colour table index for Grey */
+ private static final short GREY = 2;
+
+ /** Colour table index for White */
+ private static final short WHITE = 3;
+
+ /** Colour table index for Red */
+ private static final short RED = 4;
+
+ /** Colour table index for Lime */
+ private static final short LIME = 5;
+
+ /** Colour table index for Blue */
+ private static final short BLUE = 6;
+
+ /** Colour table index for Aqua */
+ private static final short AQUA = 7;
+
+ /** Colour table index for Fuchsia */
+ private static final short FUCHSIA = 8;
+
+ /** Colour table index for Yellow */
+ private static final short YELLOW = 9;
+
+ /** Colour table index for Maroon */
+ private static final short MAROON = 10;
+
+ /** Colour table index for Green */
+ private static final short GREEN = 11;
+
+ /** Colour table index for Navy */
+ private static final short NAVY = 12;
+
+ /** Colour table index for Teal */
+ private static final short TEAL = 13;
+
+ /** Colour table index for Purple */
+ private static final short PURPLE = 14;
+
+ /** Colour table index for Olive */
+ public static final short OLIVE = 15;
+
+ private short tableLookup[] = null;
+
+ /**
+ * Default constructor used in the case where a lookup table is not
+ * required
+ */
+ public ColourConverter() {
+
+ }
+
+ /**
+ * Constructor that passes in the colour lookup table. This is required in
+ * cases where the 16 colour values are something other than there default
+ * values (e.g. in the case of pocket Excel)
+ *
+ * @param short[] a 16 bit array mapping the 16 colours to there values
+ */
+ public ColourConverter(short lookup[]) {
+
+ tableLookup = lookup;
+ }
+
+ /**
+ * Uses the colour table it it exists to translate default values to
+ * values in the colorTable
+ */
+ private short colourLookup(short colour) {
+
+ if(tableLookup!=null) {
+ return tableLookup[colour];
+ } else {
+ return colour;
+ }
+ }
+
+ /**
+ * Uses the colour table it it exists to translate default values to
+ * values in the colorTable
+ */
+ private short indexLookup(short index) {
+
+ short result = 0;
+
+ if(tableLookup!=null) {
+ for(short i = 0;i < tableLookup.length;i++) {
+ if(tableLookup[i]==index)
+ result = i;
+ }
+ } else {
+ result = index;
+ }
+
+ return result;
+ }
+ /**
+ * This method maps a Pocket Word colour index value to an RGB value as
+ * used by OpenOffice.
+ *
+ * @param index The index into Pocket Word's colour table.
+ *
+ * @return A Color object representing the RGB value of the Pocket Word
+ * colour.
+ */
+ public Color convertToRGB (short colour) {
+
+ short index = indexLookup(colour);
+
+ int r = 0;
+ int g = 0;
+ int b = 0;
+
+ switch (index) {
+ case SILVER:
+ r = g = b = 128;
+ break;
+
+ case GREY:
+ r = g = b = 192;
+ break;
+
+ case WHITE:
+ r = g = b = 255;
+ break;
+
+ case RED:
+ r = 255;
+ break;
+
+ case LIME:
+ g = 255;
+ break;
+
+ case BLUE:
+ b = 255;
+ break;
+
+ case AQUA:
+ g = b = 255;
+ break;
+
+ case FUCHSIA:
+ r = b = 255;
+ break;
+
+ case YELLOW:
+ r = g = 255;
+ break;
+
+ case MAROON:
+ r = 128;
+ break;
+
+ case GREEN:
+ g = 128;
+ break;
+
+ case NAVY:
+ b = 128;
+ break;
+
+ case TEAL:
+ b = g = 128;
+ break;
+
+ case PURPLE:
+ r = b = 128;
+ break;
+
+ case OLIVE:
+ r = g = 128;
+ break;
+
+ case BLACK:
+ default:
+ r = g = b = 0;
+ break;
+ }
+
+ return new Color(r, g, b);
+ }
+
+
+ /**
+ * This method approximates an RGB value (as used by Writer) to one of the
+ * 16 available colours
+ *
+ * Most of the supported colours have their components set to either 0, 128
+ * or 255. The exception is 'Grey' which is 0xC0C0C0.
+ *
+ * @param colour Color object representing the RGB value of the colour.
+ *
+ * @return Index into the Pocket Word colour table which represents the
+ * closest match to the specified colour.
+ */
+ public short convertFromRGB (Color colour) {
+ int matchedRGB = 0;
+ short indexColour = 0;
+ int reducedMap[] = new int[] { 0, 0, 128 };
+
+ int red = colour.getRed();
+ int green = colour.getGreen();
+ int blue = colour.getBlue();
+
+ // We need to convert the pale colors to their base color rather than
+ // white so we modify the rgb values if the colour is sufficently
+ // white
+ if(red>0xC0 && green>0xC0 && blue>0xC0) {
+
+ if(red!=0xFF)
+ red = getClosest(red, reducedMap);
+ if(green!=0xFF)
+ green = getClosest(green, reducedMap);
+ if(blue!=0xFF)
+ blue = getClosest(blue, reducedMap);
+ }
+
+ /*
+ * Need to derive an RGB value that has been rounded to match the ones
+ * Pocket Word knows about.
+ */
+ matchedRGB += getClosest(red) << 16;
+ matchedRGB += getClosest(green) << 8;
+ matchedRGB += getClosest(blue);
+
+ /*
+ * The colour map used by Pocket Word doesn't have any combinations of
+ * values beyond 0 and any other value. A value of 255 in any RGB
+ * code indicates a dominant colour. Other colours are only modifiers
+ * to the principal colour(s). Thus, for this conversion, modifiers
+ * can be dropped.
+ */
+ if ((matchedRGB & 0xFF0000) == 0xFF0000 || (matchedRGB & 0xFF00) == 0xFF00
+ || (matchedRGB & 0xFF) == 0xFF) {
+ if ((matchedRGB & 0xFF0000) == 0x800000) {
+ matchedRGB ^= 0x800000;
+ }
+ if ((matchedRGB & 0xFF00) == 0x8000) {
+ matchedRGB ^= 0x8000;
+ }
+ if ((matchedRGB & 0xFF) == 0x80) {
+ matchedRGB ^= 0x80;
+ }
+ }
+
+
+ /*
+ * And now for the actual matching ...
+ *
+ * Colours are based on the Windows VGA 16 palette. One difference
+ * though is that Pocket Word seems to switch the RGB codes for Grey
+ * and Silver. In Pocket Word Silver is the darker colour leaving Grey
+ * is closest to White.
+ *
+ * Shades of grey will be converted to either Silver or White, where
+ * Grey may be a more appropraite colour. This is handled specially
+ * only for Silver and White matches.
+ */
+ switch (matchedRGB) {
+ case 0x000000:
+ indexColour = BLACK;
+ break;
+
+ case 0x808080:
+ if (!isGrey(colour)) {
+ indexColour = SILVER;
+ }
+ else {
+ indexColour = GREY;
+ }
+ break;
+
+ case 0xFFFFFF:
+ if (!isGrey(colour)) {
+ indexColour = WHITE;
+ }
+ else {
+ indexColour = GREY;
+ }
+ break;
+
+ case 0xFF0000:
+ indexColour = RED;
+ break;
+
+ case 0x00FF00:
+ indexColour = LIME;
+ break;
+
+ case 0x0000FF:
+ indexColour = BLUE;
+ break;
+
+ case 0x00FFFF:
+ indexColour = AQUA;
+ break;
+
+ case 0xFF00FF:
+ indexColour = FUCHSIA;
+ break;
+
+ case 0xFFFF00:
+ indexColour = YELLOW;
+ break;
+
+ case 0x800000:
+ indexColour = MAROON;
+ break;
+
+ case 0x008000:
+ indexColour = GREEN;
+ break;
+
+ case 0x000080:
+ indexColour = NAVY;
+ break;
+
+ case 0x008080:
+ indexColour = TEAL;
+ break;
+
+ case 0x800080:
+ indexColour = PURPLE;
+ break;
+
+ case 0x808000:
+ indexColour = OLIVE;
+ break;
+
+ default: // Just in case!
+ indexColour = BLACK;
+ break;
+ }
+
+ return colourLookup(indexColour);
+ }
+
+
+ /*
+ * Default implementation, checks for the closest of value to 0, 128 or 255.
+ */
+ private int getClosest(int value) {
+ int points[] = new int[] { 0, 128, 255 };
+
+ return getClosest(value, points);
+ }
+
+
+ /*
+ * Utility method that returns the closest of the three points to the value
+ * supplied.
+ */
+ private int getClosest(int value, int[] points) {
+
+ if (value == points[0] || value == points[1] || value == points[2]) {
+ return value;
+ }
+
+ if (value < points[1]) {
+ int x = value - points[0];
+ return (Math.round((float)x / (points[1] - points[0])) == 1 ? points[1] : points[0]);
+ }
+ else {
+ int x = value - points[1];
+ return (Math.round((float)x / (points[2] - points[1])) >= 1 ? points[2] : points[1]);
+ }
+ }
+
+
+ /*
+ * Checks to see if the supplied colour can be considered to be grey.
+ */
+ private boolean isGrey(Color c) {
+ int matchedRGB = 0;
+ int points[] = new int[] { 128, 192, 255 };
+
+ matchedRGB += getClosest(c.getRed(), points) << 16;
+ matchedRGB += getClosest(c.getGreen(), points) << 8;
+ matchedRGB += getClosest(c.getBlue(), points);
+
+ if (matchedRGB == 0xC0C0C0) {
+ return true;
+ }
+
+ return false;
+ }
+}
+