/* * Scriptographer * * This file is part of Scriptographer, a Scripting Plugin for Adobe Illustrator * http://scriptographer.org/ * * Copyright (c) 2002-2010, Juerg Lehni * http://scratchdisk.com/ * * All rights reserved. See LICENSE file for details. * * File created on 30.12.2004. */ package com.scriptographer.ai; import java.awt.color.ICC_Profile; import java.io.IOException; import com.scratchdisk.script.ChangeEmitter; import com.scriptographer.ScriptographerException; /** * @author lehni */ public abstract class Color implements ChangeEmitter { /** * @jshide */ public static final Color NONE = new RGBColor(-1, -1, -1, -1); protected float alpha; /** * Converts the color to a java.awt.Color equivalent. * * @return the converted Color * * @jshide */ public abstract java.awt.Color toAWTColor(); public abstract boolean equals(Object obj); /** * @jshide */ public abstract float[] getComponents(); /** * @jshide */ public abstract void set(Color color); /** * A value between 0 and 1 that specifies the color's alpha value. * All colors of the different subclasses support alpha values. */ public Float getAlpha() { // an alpha value of -1 means no alpha channel. return alpha == -1f ? null : alpha; } /** * Checks if the color has an alpha value. * * @return {@true if the color has an alpha value} */ public boolean hasAlpha() { return alpha != -1f; } /** * Sets the color's alpha value. * Setting alpha to null deactivates the alpha channel. * * @param alpha the color's new alpha value */ public void setAlpha(Float alpha) { if (alpha == null || alpha == -1) this.alpha = -1f; else if (alpha < 0f) this.alpha = 0f; else if (alpha > 1f) this.alpha = 1f; else this.alpha = alpha; } private native Color nativeConvert(int type); /** * Converts the color into another color space. * * @param type the conversion color type * @return the converted color. */ public Color convert(ColorType type) { return type == getType() ? this : nativeConvert(type.value); } /** * Converts the color into another type. * * @param type the type of the color to convert to, e.g. {@code RGBColor}, * {@code CMYKColor}, {@code GrayColor}. * @return the converted color. * * @jshide */ public Color convert(Class type) { return convert(getType(type, hasAlpha())); } /** * Converts the color into a color model, as returned by * {@link Document#getColorModel}. * * @param model the conversion color type * @return the converted color. * * @jshide */ public Color convert(ColorModel model) { return convert(getType(model, hasAlpha())); } /** * @jshide */ public static ColorType getType(Class type, boolean alpha) { if (CMYKColor.class.isAssignableFrom(type)) { return alpha ? ColorType.ACMYK : ColorType.CMYK; } else if (RGBColor.class.isAssignableFrom(type)) { return alpha ? ColorType.ARGB : ColorType.RGB; } else if (GrayColor.class.isAssignableFrom(type)) { return alpha ? ColorType.AGRAY : ColorType.GRAY; } return null; } /** * @jshide */ public static ColorType getType(ColorModel model, boolean alpha) { switch (model) { case CMYK: return alpha ? ColorType.ACMYK : ColorType.CMYK; case RGB: return alpha ? ColorType.ARGB : ColorType.RGB; case GRAY: return alpha ? ColorType.AGRAY : ColorType.GRAY; } return null; } /** * Returns the type of the color as a string. * * Sample code: * <code> * var color = new RGBColor(1, 0, 0); * print(color.type); // 'rgb' * print(color.type == 'cmyk'); // false * * color = color.convert('cmyk') // convert the color to a CMYKColor * print(color.type); // 'cmyk' * * color.alpha = 0.5; // give the color an alpha value * print(color.type); // 'acmyk' * </code> * * @return the color type */ public ColorType getType() { return getType(getClass(), hasAlpha()); } /** * Returns the native profile for the given space, wrapped in an * ICC_Profile this is pretty nice: the native ICC profile data from Adobe * Illustrator really seems to be compatible with ICC_Profile, so the whole * ColorSpaces from Illustrator can be used in Java as well. */ private static native ICC_Profile nativeGetProfile(int space); /** * Call first nativeGetProfile in order to get the illustrator's profile, * and if this doesn't work, it falls back to the scriptographer's internal * profiles. * * @param model */ protected static ICC_Profile getProfile(ColorModel model) { // first try the illustrator internal WS profiles: ICC_Profile profile = nativeGetProfile(model.value); if (profile == null) { // if this didn't work, use scriptographer's internal profiles: try { profile = ICC_Profile.getInstance( Color.class.getClassLoader().getResourceAsStream( "com/scriptographer/cmm/" + model.name().toLowerCase() + ".icc")); } catch (IOException e) { throw new ScriptographerException(e); } } return profile; } /* * Used in GradientColor, but here to reduce amount of native cpp files */ protected static native void nativeSetGradient(int pointer, int handle, Point origin, double angle, double length, Matrix matrix, double hiliteAngle, double hiliteLength); protected static native void nativeSetPattern(int pointer, int handle, Matrix matrix); }