/****************************************************************************
* Copyright (c) 2008, 2009 Jeremy Dowdall
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Jeremy Dowdall <jeremyd@aspencloud.com> - initial API and implementation
*****************************************************************************/
package org.eclipse.nebula.cwt.svg;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Pattern;
class SvgGradient extends SvgElement {
static final int X1 = 0;
static final int Y1 = 1;
static final int X2 = 3;
static final int Y2 = 4;
static final int CX = 3;
static final int CY = 4;
static final int FX = 3;
static final int FY = 4;
static final int R = 5;
static final int PAD = 0;
static final int REFLECT = 1;
static final int REPEAT = 2;
float[] data;
String linkId;
List<SvgGradientStop> stops;
GC gc;
float[] bounds;
Pattern pattern;
boolean boundingBox = true;
int spreadMethod = PAD;
SvgTransform transform;
SvgGradient(SvgContainer container, String id) {
super(container, id);
stops = new ArrayList<SvgGradientStop>();
}
public void apply(boolean foreground) {
SvgGradientStop[] stops = getStops();
if(stops.length == 1) {
apply(gc, stops[0], foreground);
} else if(stops.length > 1) {
if(pattern == null) {
apply(gc, stops[stops.length-1], foreground);
} else {
if(foreground) {
gc.setForegroundPattern(pattern);
} else {
gc.setBackgroundPattern(pattern);
}
}
}
}
private void apply(GC gc, SvgGradientStop stop, boolean foreground) {
Color c = createColor(gc, stop.color);
if(foreground) {
gc.setForeground(c);
} else {
gc.setBackground(c);
}
c.dispose();
gc.setAlpha((int)(255 * stop.opacity));
}
public void create(SvgShape shape, GC gc) {
this.gc = gc;
if(boundingBox) {
bounds = shape.getBounds();
} else {
bounds = shape.getViewport();
}
try {
Class<?> c = Class.forName("org.eclipse.nebula.cwt.SwtAdapter"); //$NON-NLS-1$
Method m = c.getMethod("createPattern", SvgGradient.class); //$NON-NLS-1$
pattern = (Pattern) m.invoke(c, this);
} catch(Exception e) {
System.out.println("Could not create pattern - fragment must be missing"); //$NON-NLS-1$
}
}
private Color createColor(GC gc, int color) {
return new Color(gc.getDevice(), color >> 16, (color & 0x00FF00) >> 8, color & 0x0000FF);
}
public void dispose() {
if(pattern != null) {
gc.setBackgroundPattern(null);
pattern.dispose();
}
gc = null;
bounds = null;
pattern = null;
}
public SvgGradientStop[] getStops() {
if(linkId != null) {
Object def = getFragment().getElement(linkId);
if(def instanceof SvgGradient) {
SvgGradientStop[] linkStops = ((SvgGradient) def).getStops();
if(linkStops.length > 0) {
return linkStops;
}
}
}
return stops.toArray(new SvgGradientStop[stops.size()]);
}
public SvgTransform getTransform() {
return transform;
}
void setLinkId(String id) {
if(id != null && id.length() > 2 && '#' == id.charAt(0)) {
linkId = id.substring(1);
} else {
linkId = null;
}
}
void setSpreadMethod(String s) {
if(s != null) {
if("pad".equals(s)) { //$NON-NLS-1$
spreadMethod = PAD;
} else if("reflect".equals(s)) { //$NON-NLS-1$
spreadMethod = REFLECT;
} else if("repeat".equals(s)) { //$NON-NLS-1$
spreadMethod = REPEAT;
}
}
}
void setTransform(SvgTransform transform) {
this.transform = transform;
}
void setUnits(String s) {
if(s != null) {
boundingBox = "objectBoundingBox".equals(s); //$NON-NLS-1$
}
}
}