(empty log message)
@@ -1,10 +1,14 @@ | ||
1 | 1 | package jp.cssj.homare.css.util; |
2 | 2 | |
3 | 3 | import java.awt.SystemColor; |
4 | +import java.util.ArrayList; | |
4 | 5 | import java.util.Collections; |
5 | 6 | import java.util.HashMap; |
7 | +import java.util.List; | |
6 | 8 | import java.util.Map; |
7 | 9 | |
10 | +import org.apache.commons.collections.primitives.ArrayDoubleList; | |
11 | + | |
8 | 12 | import jp.cssj.homare.css.value.BackgroundAttachmentValue; |
9 | 13 | import jp.cssj.homare.css.value.BackgroundRepeatValue; |
10 | 14 | import jp.cssj.homare.css.value.ColorValue; |
@@ -1155,11 +1159,140 @@ | ||
1155 | 1159 | |
1156 | 1160 | private static PaintValue toLinearGradient(UserAgent ua, LexicalUnit lu) { |
1157 | 1161 | try { |
1158 | - ColorValue color1 = toColor(ua, lu); | |
1159 | - lu = lu.getNextLexicalUnit().getNextLexicalUnit(); | |
1160 | - ColorValue color2 = toColor(ua, lu); | |
1162 | + double angle = 180 * Math.PI * 2 / 360; | |
1163 | + switch (lu.getLexicalUnitType()) { | |
1164 | + case LexicalUnit.SAC_DEGREE: | |
1165 | + angle = lu.getFloatValue() * Math.PI * 2 / 360; | |
1166 | + lu = lu.getNextLexicalUnit().getNextLexicalUnit(); | |
1167 | + break; | |
1168 | + case LexicalUnit.SAC_IDENT: | |
1169 | + if (!lu.getStringValue().equalsIgnoreCase("to")) { | |
1170 | + break; | |
1171 | + } | |
1172 | + lu = lu.getNextLexicalUnit(); | |
1173 | + if (lu.getLexicalUnitType() != LexicalUnit.SAC_IDENT) { | |
1174 | + throw new IllegalArgumentException(); | |
1175 | + } | |
1176 | + String ident = lu.getStringValue(); | |
1177 | + if (ident.equalsIgnoreCase("top")) { | |
1178 | + lu = lu.getNextLexicalUnit(); | |
1179 | + if (lu.getLexicalUnitType() != LexicalUnit.SAC_IDENT) { | |
1180 | + angle = 0 * Math.PI * 2 / 360; | |
1181 | + break; | |
1182 | + } | |
1183 | + ident = lu.getStringValue(); | |
1184 | + lu = lu.getNextLexicalUnit(); | |
1185 | + if (ident.equalsIgnoreCase("left")) { | |
1186 | + angle = 315 * Math.PI * 2 / 360; | |
1187 | + } | |
1188 | + else if (ident.equalsIgnoreCase("right")) { | |
1189 | + angle = 45 * Math.PI * 2 / 360; | |
1190 | + } | |
1191 | + break; | |
1192 | + } | |
1193 | + else if (ident.equalsIgnoreCase("bottom")) { | |
1194 | + lu = lu.getNextLexicalUnit(); | |
1195 | + if (lu.getLexicalUnitType() != LexicalUnit.SAC_IDENT) { | |
1196 | + angle = 180 * Math.PI * 2 / 360; | |
1197 | + break; | |
1198 | + } | |
1199 | + ident = lu.getStringValue(); | |
1200 | + lu = lu.getNextLexicalUnit(); | |
1201 | + if (ident.equalsIgnoreCase("left")) { | |
1202 | + angle = 225 * Math.PI * 2 / 360; | |
1203 | + } | |
1204 | + else if (ident.equalsIgnoreCase("right")) { | |
1205 | + angle = 135 * Math.PI * 2 / 360; | |
1206 | + } | |
1207 | + break; | |
1208 | + } | |
1209 | + else if (ident.equalsIgnoreCase("left")) { | |
1210 | + lu = lu.getNextLexicalUnit(); | |
1211 | + if (lu.getLexicalUnitType() != LexicalUnit.SAC_IDENT) { | |
1212 | + angle = 270 * Math.PI * 2 / 360; | |
1213 | + break; | |
1214 | + } | |
1215 | + ident = lu.getStringValue(); | |
1216 | + lu = lu.getNextLexicalUnit(); | |
1217 | + if (ident.equalsIgnoreCase("top")) { | |
1218 | + angle = 315 * Math.PI * 2 / 360; | |
1219 | + } | |
1220 | + else if (ident.equalsIgnoreCase("bottom")) { | |
1221 | + angle = 225 * Math.PI * 2 / 360; | |
1222 | + } | |
1223 | + break; | |
1224 | + } | |
1225 | + else if (ident.equalsIgnoreCase("right")) { | |
1226 | + lu = lu.getNextLexicalUnit(); | |
1227 | + if (lu.getLexicalUnitType() != LexicalUnit.SAC_IDENT) { | |
1228 | + angle = 90 * Math.PI * 2 / 360; | |
1229 | + break; | |
1230 | + } | |
1231 | + ident = lu.getStringValue(); | |
1232 | + lu = lu.getNextLexicalUnit(); | |
1233 | + if (ident.equalsIgnoreCase("top")) { | |
1234 | + angle = 45 * Math.PI * 2 / 360; | |
1235 | + } | |
1236 | + else if (ident.equalsIgnoreCase("bottom")) { | |
1237 | + angle = 135 * Math.PI * 2 / 360; | |
1238 | + } | |
1239 | + break; | |
1240 | + } | |
1241 | + } | |
1161 | 1242 | |
1162 | - return new LinearGradientValue(new double[] { 0, 1 }, new Color[] { color1.getColor(), color2.getColor() }); | |
1243 | + List<Color> colors = new ArrayList<Color>(); | |
1244 | + ArrayDoubleList fracs = new ArrayDoubleList(); | |
1245 | + | |
1246 | + for (;;) { | |
1247 | + if (lu.getLexicalUnitType() == LexicalUnit.SAC_PERCENTAGE || lu.getLexicalUnitType() == LexicalUnit.SAC_OPERATOR_COMMA) { | |
1248 | + lu = lu.getNextLexicalUnit(); | |
1249 | + continue; | |
1250 | + } | |
1251 | + ColorValue cv = toColor(ua, lu); | |
1252 | + if (cv == null) { | |
1253 | + throw new IllegalArgumentException(); | |
1254 | + } | |
1255 | + Color color = cv.getColor(); | |
1256 | + lu = lu.getNextLexicalUnit(); | |
1257 | + if (lu == null || lu.getLexicalUnitType() == LexicalUnit.SAC_OPERATOR_COMMA) { | |
1258 | + colors.add(color); | |
1259 | + fracs.add(-1); | |
1260 | + } else { | |
1261 | + while (lu != null && lu.getLexicalUnitType() != LexicalUnit.SAC_OPERATOR_COMMA) { | |
1262 | + if (lu.getLexicalUnitType() != LexicalUnit.SAC_PERCENTAGE) { | |
1263 | + throw new IllegalArgumentException(); | |
1264 | + } | |
1265 | + colors.add(color); | |
1266 | + fracs.add(lu.getFloatValue() / 100f); | |
1267 | + lu = lu.getNextLexicalUnit(); | |
1268 | + } | |
1269 | + } | |
1270 | + if (lu == null) { | |
1271 | + break; | |
1272 | + } | |
1273 | + lu = lu.getNextLexicalUnit(); | |
1274 | + } | |
1275 | + double[] ds = fracs.toArray(); | |
1276 | + if (ds[0] == -1) { | |
1277 | + ds[0] = 0; | |
1278 | + } | |
1279 | + ds[ds.length - 1] = 1; | |
1280 | + double a = ds[0]; | |
1281 | + for (int i = 1; i < ds.length; ++i) { | |
1282 | + if (ds[i] == -1) { | |
1283 | + int j = i + 1; | |
1284 | + for (; ds[j] == -1; ++j) ; | |
1285 | + double b = ds[j]; | |
1286 | + double step = (b - a) / (j - i); | |
1287 | + for(; i < j; ++i) { | |
1288 | + a += step; | |
1289 | + ds[i] = a; | |
1290 | + } | |
1291 | + } | |
1292 | + a = ds[i]; | |
1293 | + } | |
1294 | + | |
1295 | + return new LinearGradientValue(angle, ds, colors.toArray(new Color[colors.size()])); | |
1163 | 1296 | } catch (IllegalArgumentException e) { |
1164 | 1297 | return null; |
1165 | 1298 | } |
@@ -14,16 +14,20 @@ | ||
14 | 14 | * @version $Id: ColorValue.java 1624 2022-05-02 08:59:55Z miyabe $ |
15 | 15 | */ |
16 | 16 | public class LinearGradientValue implements PaintValue { |
17 | + protected final double angle; | |
17 | 18 | protected final Color[] colors; |
18 | 19 | protected final double[] fractions; |
19 | 20 | |
20 | - public LinearGradientValue(double[] fractions, Color[] colors) { | |
21 | + public LinearGradientValue(double angle, double[] fractions, Color[] colors) { | |
22 | + this.angle = angle; | |
21 | 23 | this.colors = colors; |
22 | 24 | this.fractions = fractions; |
23 | 25 | } |
24 | - | |
26 | + | |
25 | 27 | public Paint getPaint(Rectangle2D box) { |
26 | - return new LinearGradient(0, box.getMinY(), 0, box.getMaxY(), this.fractions, this.colors, new AffineTransform()); | |
28 | + double mx = (box.getMinX() + box.getMaxX()) / 2; | |
29 | + return new LinearGradient(mx, box.getMaxY(), mx, box.getMinY(), this.fractions, this.colors, | |
30 | + AffineTransform.getRotateInstance(this.angle, mx, (box.getMinY() + box.getMaxY()) / 2)); | |
27 | 31 | } |
28 | 32 | |
29 | 33 | public short getValueType() { |