001/* 002 * Copyright 2006 - 2013 003 * Stefan Balev <stefan.balev@graphstream-project.org> 004 * Julien Baudry <julien.baudry@graphstream-project.org> 005 * Antoine Dutot <antoine.dutot@graphstream-project.org> 006 * Yoann Pigné <yoann.pigne@graphstream-project.org> 007 * Guilhelm Savin <guilhelm.savin@graphstream-project.org> 008 * 009 * This file is part of GraphStream <http://graphstream-project.org>. 010 * 011 * GraphStream is a library whose purpose is to handle static or dynamic 012 * graph, create them from scratch, file or any source and display them. 013 * 014 * This program is free software distributed under the terms of two licenses, the 015 * CeCILL-C license that fits European law, and the GNU Lesser General Public 016 * License. You can use, modify and/ or redistribute the software under the terms 017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following 018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by 019 * the Free Software Foundation, either version 3 of the License, or (at your 020 * option) any later version. 021 * 022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY 023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 024 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 025 * 026 * You should have received a copy of the GNU Lesser General Public License 027 * along with this program. If not, see <http://www.gnu.org/licenses/>. 028 * 029 * The fact that you are presently reading this means that you have had 030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms. 031 */ 032package org.graphstream.ui.swingViewer.util; 033 034import java.awt.Color; 035import java.awt.GradientPaint; 036import java.awt.LinearGradientPaint; 037import java.awt.MultipleGradientPaint; 038import java.awt.Paint; 039import java.awt.RadialGradientPaint; 040 041import org.graphstream.ui.graphicGraph.stylesheet.Style; 042import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants.FillMode; 043 044public class GradientFactory { 045 /** 046 * Generate a gradient in the given pixel area following the given style. 047 * This produces a gradient only if the style fill-mode is compatible. 048 * 049 * @param x0 050 * The left corner of the area. 051 * @param y0 052 * The bottom corner of the area. 053 * @param width 054 * The area width. 055 * @param height 056 * The area height. 057 * @param style 058 * The style. 059 * @return A gradient paint or null if the style does not specify a 060 * gradient. 061 */ 062 public static Paint gradientInArea(int x0, int y0, int width, int height, 063 Style style) { 064 switch (style.getFillMode()) { 065 case GRADIENT_VERTICAL: 066 return linearGradientFromStyle(x0, y0, x0, y0 + height, style); 067 case GRADIENT_HORIZONTAL: 068 return linearGradientFromStyle(x0, y0, x0 + width, y0, style); 069 case GRADIENT_DIAGONAL1: 070 return linearGradientFromStyle(x0, y0, x0 + width, y0 + height, 071 style); 072 case GRADIENT_DIAGONAL2: 073 return linearGradientFromStyle(x0 + width, y0, x0, y0 + height, 074 style); 075 case GRADIENT_RADIAL: 076 return radialGradientFromStyle(x0 + (width / 2), y0 + (height / 2), 077 width > height ? width / 2 : height / 2, style); 078 default: 079 return null; 080 } 081 } 082 083 /** 084 * Generate a linear gradient between two given points corresponding to the 085 * given style. 086 * 087 * @param x0 088 * The start point abscissa. 089 * @param y0 090 * The start point ordinate. 091 * @param x1 092 * The end point abscissa. 093 * @param y1 094 * The end point ordinate. 095 * @param style 096 * The style. 097 * @return A paint for the gradient or null if the style specifies no 098 * gradient (the fill mode is not a linear gradient or there is only 099 * one fill colour). 100 */ 101 public static Paint linearGradientFromStyle(float x0, float y0, float x1, 102 float y1, Style style) { 103 Paint paint = null; 104 105 if (style.getFillColorCount() > 1) { 106 switch (style.getFillMode()) { 107 case GRADIENT_DIAGONAL1: 108 case GRADIENT_DIAGONAL2: 109 case GRADIENT_HORIZONTAL: 110 case GRADIENT_VERTICAL: 111 if (version16) 112 paint = new LinearGradientPaint(x0, y0, x1, y1, 113 createFractions(style), createColors(style)); 114 else 115 paint = new GradientPaint(x0, y0, style.getFillColor(0), 116 x1, y1, style.getFillColor(1)); 117 break; 118 default: 119 break; 120 } 121 } 122 123 return paint; 124 } 125 126 public static Paint radialGradientFromStyle(float cx, float cy, 127 float radius, Style style) { 128 return radialGradientFromStyle(cx, cy, radius, cx, cy, style); 129 } 130 131 /** 132 * Generate a radial gradient between whose center is at (cx,cy) with the 133 * given radius. The focus (fx,fy) is the start position of the gradient in 134 * the circle. 135 * 136 * @param cx 137 * The center point abscissa. 138 * @param cy 139 * The center point ordinate. 140 * @param fx 141 * The start point abscissa. 142 * @param fy 143 * The start point ordinate. 144 * @param radius 145 * The gradient radius. 146 * @param style 147 * The style. 148 * @return A paint for the gradient or null if the style specifies no 149 * gradient (the fill mode is not a radial gradient or there is only 150 * one fill colour). 151 */ 152 public static Paint radialGradientFromStyle(float cx, float cy, 153 float radius, float fx, float fy, Style style) { 154 Paint paint = null; 155 156 if (version16) { 157 if (style.getFillColorCount() > 1 158 && style.getFillMode() == FillMode.GRADIENT_RADIAL) { 159 float fractions[] = createFractions(style); 160 Color colors[] = createColors(style); 161 paint = new RadialGradientPaint(cx, cy, radius, fx, fy, 162 fractions, colors, 163 MultipleGradientPaint.CycleMethod.REFLECT); 164 } 165 } 166 167 return paint; 168 } 169 170 protected static float[] createFractions(Style style) { 171 int n = style.getFillColorCount(); 172 173 if (n < predefFractions.length) 174 return predefFractions[n]; 175 176 float fractions[] = new float[n]; 177 float div = 1f / (n - 1); 178 179 for (int i = 1; i < (n - 1); i++) 180 fractions[i] = div * i; 181 182 fractions[0] = 0f; 183 fractions[n - 1] = 1f; 184 185 return fractions; 186 } 187 188 protected static Color[] createColors(Style style) { 189 int n = style.getFillColorCount(); 190 Color colors[] = new Color[n]; 191 192 for (int i = 0; i < n; i++) 193 colors[i] = style.getFillColor(i); 194 195 return colors; 196 } 197 198 public static boolean version16 = false; 199 public static float[][] predefFractions = new float[11][]; 200 public static float[] predefFractions2 = { 0f, 1f }; 201 public static float[] predefFractions3 = { 0f, 0.5f, 1f }; 202 public static float[] predefFractions4 = { 0f, 0.33f, 0.66f, 1f }; 203 public static float[] predefFractions5 = { 0f, 0.25f, 0.5f, 0.75f, 1f }; 204 public static float[] predefFractions6 = { 0f, 0.2f, 0.4f, 0.6f, 0.8f, 1f }; 205 public static float[] predefFractions7 = { 0f, 0.1666f, 0.3333f, 0.4999f, 206 0.6666f, 0.8333f, 1f }; 207 public static float[] predefFractions8 = { 0f, 0.1428f, 0.2856f, 0.4284f, 208 0.5712f, 0.7140f, 0.8568f, 1f }; 209 public static float[] predefFractions9 = { 0f, 0.125f, 0.25f, 0.375f, 0.5f, 210 0.625f, .75f, 0.875f, 1f }; 211 public static float[] predefFractions10 = { 0f, 0.1111f, 0.2222f, 0.3333f, 212 0.4444f, 0.5555f, 0.6666f, 0.7777f, 0.8888f, 1f }; 213 214 static { 215 String version = System.getProperty("java.version"); 216 217 if (version.startsWith("1.") && version.length() >= 3) { 218 String v = version.substring(2, 3); 219 int n = Integer.parseInt(v); 220 221 if (n >= 6) 222 version16 = true; 223 } 224 225 predefFractions[0] = null; 226 predefFractions[1] = null; 227 predefFractions[2] = predefFractions2; 228 predefFractions[3] = predefFractions3; 229 predefFractions[4] = predefFractions4; 230 predefFractions[5] = predefFractions5; 231 predefFractions[6] = predefFractions6; 232 predefFractions[7] = predefFractions7; 233 predefFractions[8] = predefFractions8; 234 predefFractions[9] = predefFractions9; 235 predefFractions[10] = predefFractions10; 236 } 237}