From: Vincent Hennebert Date: Fri, 18 Jul 2014 19:48:02 +0000 (+0000) Subject: Merged branch FOP-2393_gradient-rendering back into trunk X-Git-Tag: fop-2_0~97 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=cdf8be3d3a3f4fde67723863d368b1096c305de9;p=xmlgraphics-fop.git Merged branch FOP-2393_gradient-rendering back into trunk git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1611783 13f79535-47bb-0310-9956-ffa450edef68 --- cdf8be3d3a3f4fde67723863d368b1096c305de9 diff --cc src/java/org/apache/fop/render/gradient/GradientMaker.java index 000000000,520335dd8..3c847a843 mode 000000,100644..100644 --- a/src/java/org/apache/fop/render/gradient/GradientMaker.java +++ b/src/java/org/apache/fop/render/gradient/GradientMaker.java @@@ -1,0 -1,168 +1,168 @@@ + /* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + /* $Id$ */ + + package org.apache.fop.render.gradient; + + import java.awt.Color; + import java.awt.geom.AffineTransform; + import java.awt.geom.Point2D; + import java.util.ArrayList; + import java.util.List; + + import org.apache.batik.ext.awt.LinearGradientPaint; + import org.apache.batik.ext.awt.MultipleGradientPaint; + import org.apache.batik.ext.awt.RadialGradientPaint; + + import org.apache.xmlgraphics.java2d.color.ColorUtil; + + import org.apache.fop.pdf.PDFDeviceColorSpace; + + public final class GradientMaker { + + public interface DoubleFormatter { + + String formatDouble(double d); + } + + private GradientMaker() { } + + public static Pattern makeLinearGradient(LinearGradientPaint gp, + AffineTransform baseTransform, AffineTransform transform) { + Point2D startPoint = gp.getStartPoint(); + Point2D endPoint = gp.getEndPoint(); + List coords = new java.util.ArrayList(4); + coords.add(Double.valueOf(startPoint.getX())); + coords.add(Double.valueOf(startPoint.getY())); + coords.add(Double.valueOf(endPoint.getX())); + coords.add(Double.valueOf(endPoint.getY())); + return makeGradient(gp, coords, baseTransform, transform); + } + + public static Pattern makeRadialGradient(RadialGradientPaint gradient, + AffineTransform baseTransform, AffineTransform transform) { + double radius = gradient.getRadius(); + Point2D center = gradient.getCenterPoint(); + Point2D focus = gradient.getFocusPoint(); + double dx = focus.getX() - center.getX(); + double dy = focus.getY() - center.getY(); + double d = Math.sqrt(dx * dx + dy * dy); + if (d > radius) { - // The center point must be within the circle with ++ // The focal point must be within the circle with + // radius radius centered at center so limit it to that. + double scale = (radius * .9999) / d; + dx *= scale; + dy *= scale; + } + List coords = new java.util.ArrayList(6); + coords.add(Double.valueOf(center.getX() + dx)); + coords.add(Double.valueOf(center.getY() + dy)); + coords.add(Double.valueOf(0)); + coords.add(Double.valueOf(center.getX())); + coords.add(Double.valueOf(center.getY())); + coords.add(Double.valueOf(radius)); + return makeGradient(gradient, coords, baseTransform, transform); + } + + private static Pattern makeGradient(MultipleGradientPaint gradient, List coords, + AffineTransform baseTransform, AffineTransform transform) { + List matrix = makeTransform(gradient, baseTransform, transform); + List bounds = makeBounds(gradient); + List functions = makeFunctions(gradient); + // Gradients are currently restricted to sRGB + PDFDeviceColorSpace colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB); + Function function = new Function(null, null, functions, bounds, null); + int shadingType = gradient instanceof LinearGradientPaint ? 2 : 3; + Shading shading = new Shading(shadingType, colorSpace, coords, function); + return new Pattern(2, shading, matrix); + } + + private static List makeTransform(MultipleGradientPaint gradient, + AffineTransform baseTransform, AffineTransform transform) { + AffineTransform gradientTransform = new AffineTransform(baseTransform); + gradientTransform.concatenate(transform); + gradientTransform.concatenate(gradient.getTransform()); + List matrix = new ArrayList(6); + double[] m = new double[6]; + gradientTransform.getMatrix(m); + for (double d : m) { + matrix.add(Double.valueOf(d)); + } + return matrix; + } + + private static Color getsRGBColor(Color c) { + // Color space must be consistent, so convert to sRGB if necessary + // TODO really? + return c.getColorSpace().isCS_sRGB() ? c : ColorUtil.toSRGBColor(c); + } + + private static List makeBounds(MultipleGradientPaint gradient) { + float[] fractions = gradient.getFractions(); + List bounds = new java.util.ArrayList(fractions.length); + for (float offset : fractions) { + if (0f < offset && offset < 1f) { + bounds.add(offset); + } + } + return bounds; + } + + private static List makeFunctions(MultipleGradientPaint gradient) { + List colors = makeColors(gradient); + List functions = new ArrayList(); + for (int currentPosition = 0, lastPosition = colors.size() - 1; + currentPosition < lastPosition; + currentPosition++) { + Color currentColor = colors.get(currentPosition); + Color nextColor = colors.get(currentPosition + 1); + float[] c0 = currentColor.getColorComponents(null); + float[] c1 = nextColor.getColorComponents(null); + Function function = new Function(null, null, c0, c1, 1.0); + functions.add(function); + } + return functions; + } + + private static List makeColors(MultipleGradientPaint gradient) { + Color[] svgColors = gradient.getColors(); + List gradientColors = new ArrayList(svgColors.length + 2); + float[] fractions = gradient.getFractions(); + if (fractions[0] > 0f) { + gradientColors.add(getsRGBColor(svgColors[0])); + } + for (Color c : svgColors) { + gradientColors.add(getsRGBColor(c)); + } + if (fractions[fractions.length - 1] < 1f) { + gradientColors.add(getsRGBColor(svgColors[svgColors.length - 1])); + } + return gradientColors; + } + + static void outputDoubles(StringBuilder out, DoubleFormatter doubleFormatter, + List numbers) { + out.append("[ "); + for (Number n : numbers) { + out.append(doubleFormatter.formatDouble(n.doubleValue())); + out.append(" "); + } + out.append("]"); + } + + }