Bug 61119 - Fix preset shape rendering and shading
- Fixed conversion of ooxml to awt angle - replace subclasses and reflection calls with enums - implemented tinting/shading of preset shapes git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1796823 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b3c6907741
commit
49e47cb6e1
@ -33,6 +33,7 @@ import java.io.InputStream;
|
||||
import org.apache.poi.sl.usermodel.ColorStyle;
|
||||
import org.apache.poi.sl.usermodel.PaintStyle;
|
||||
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
|
||||
import org.apache.poi.sl.usermodel.PaintStyle.PaintModifier;
|
||||
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
|
||||
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
|
||||
import org.apache.poi.sl.usermodel.PlaceableShape;
|
||||
@ -113,8 +114,15 @@ public class DrawPaint {
|
||||
}
|
||||
|
||||
public Paint getPaint(Graphics2D graphics, PaintStyle paint) {
|
||||
return getPaint(graphics, paint, PaintModifier.NORM);
|
||||
}
|
||||
|
||||
public Paint getPaint(Graphics2D graphics, PaintStyle paint, PaintModifier modifier) {
|
||||
if (modifier == PaintModifier.NONE) {
|
||||
return null;
|
||||
}
|
||||
if (paint instanceof SolidPaint) {
|
||||
return getSolidPaint((SolidPaint)paint, graphics);
|
||||
return getSolidPaint((SolidPaint)paint, graphics, modifier);
|
||||
} else if (paint instanceof GradientPaint) {
|
||||
return getGradientPaint((GradientPaint)paint, graphics);
|
||||
} else if (paint instanceof TexturePaint) {
|
||||
@ -123,8 +131,77 @@ public class DrawPaint {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Paint getSolidPaint(SolidPaint fill, Graphics2D graphics) {
|
||||
return applyColorTransform(fill.getSolidColor());
|
||||
protected Paint getSolidPaint(SolidPaint fill, Graphics2D graphics, final PaintModifier modifier) {
|
||||
final ColorStyle orig = fill.getSolidColor();
|
||||
ColorStyle cs = new ColorStyle() {
|
||||
@Override
|
||||
public Color getColor() {
|
||||
return orig.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAlpha() {
|
||||
return orig.getAlpha();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHueOff() {
|
||||
return orig.getHueOff();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHueMod() {
|
||||
return orig.getHueMod();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSatOff() {
|
||||
return orig.getSatOff();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSatMod() {
|
||||
return orig.getSatMod();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLumOff() {
|
||||
return orig.getLumOff();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLumMod() {
|
||||
return orig.getLumMod();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getShade() {
|
||||
int shade = orig.getShade();
|
||||
switch (modifier) {
|
||||
case DARKEN:
|
||||
return Math.min(100000, Math.max(0,shade)+40000);
|
||||
case DARKEN_LESS:
|
||||
return Math.min(100000, Math.max(0,shade)+20000);
|
||||
default:
|
||||
return shade;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTint() {
|
||||
int tint = orig.getTint();
|
||||
switch (modifier) {
|
||||
case LIGHTEN:
|
||||
return Math.min(100000, Math.max(0,tint)+40000);
|
||||
case LIGHTEN_LESS:
|
||||
return Math.min(100000, Math.max(0,tint)+20000);
|
||||
default:
|
||||
return tint;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return applyColorTransform(cs);
|
||||
}
|
||||
|
||||
protected Paint getGradientPaint(GradientPaint fill, Graphics2D graphics) {
|
||||
@ -272,9 +349,9 @@ public class DrawPaint {
|
||||
return;
|
||||
}
|
||||
|
||||
double fshade = shade / 100000.d;
|
||||
double shadePct = shade / 100000.;
|
||||
|
||||
hsl[2] *= fshade;
|
||||
hsl[2] *= 1. - shadePct;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -289,16 +366,16 @@ public class DrawPaint {
|
||||
return;
|
||||
}
|
||||
|
||||
double ftint = tint / 100000.f;
|
||||
|
||||
hsl[2] = hsl[2] * ftint + (100 - ftint*100.);
|
||||
// see 18.8.19 fgColor (Foreground Color)
|
||||
double tintPct = tint / 100000.;
|
||||
hsl[2] = hsl[2]*(1.-tintPct) + (100.-100.*(1.-tintPct));
|
||||
}
|
||||
|
||||
protected Paint createLinearGradientPaint(GradientPaint fill, Graphics2D graphics) {
|
||||
// TODO: we need to find the two points for gradient - the problem is, which point at the outline
|
||||
// do you take? My solution would be to apply the gradient rotation to the shape in reverse
|
||||
// and then scan the shape for the largest possible horizontal distance
|
||||
|
||||
|
||||
double angle = fill.getGradientAngle();
|
||||
if (!fill.isRotatedWithShape()) {
|
||||
angle -= shape.getRotation();
|
||||
|
@ -48,7 +48,7 @@ public class DrawShape implements Drawable {
|
||||
protected static boolean isHSLF(Shape<?,?> shape) {
|
||||
return shape.getClass().getCanonicalName().toLowerCase(Locale.ROOT).contains("hslf");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Apply 2-D transforms before drawing this shape. This includes rotation and flipping.
|
||||
*
|
||||
@ -184,16 +184,16 @@ public class DrawShape implements Drawable {
|
||||
}
|
||||
|
||||
AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);
|
||||
if(tx != null) {
|
||||
if(tx != null && !tx.isIdentity()) {
|
||||
anchor = tx.createTransformedShape(anchor).getBounds2D();
|
||||
}
|
||||
return anchor;
|
||||
}
|
||||
|
||||
|
||||
protected Shape<?,?> getShape() {
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
protected static BasicStroke getStroke(StrokeStyle strokeStyle) {
|
||||
float lineWidth = (float) strokeStyle.getLineWidth();
|
||||
if (lineWidth == 0.0f) {
|
||||
|
@ -57,7 +57,7 @@ import org.apache.poi.util.Units;
|
||||
|
||||
|
||||
public class DrawSimpleShape extends DrawShape {
|
||||
|
||||
|
||||
private static final double DECO_SIZE_POW = 1.5d;
|
||||
|
||||
public DrawSimpleShape(SimpleShape<?,?> shape) {
|
||||
@ -79,12 +79,15 @@ public class DrawSimpleShape extends DrawShape {
|
||||
|
||||
// then fill the shape interior
|
||||
if (fill != null) {
|
||||
graphics.setPaint(fill);
|
||||
for (Outline o : elems) {
|
||||
if (o.getPath().isFilled()){
|
||||
java.awt.Shape s = o.getOutline();
|
||||
graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s);
|
||||
graphics.fill(s);
|
||||
Paint fillMod = drawPaint.getPaint(graphics, getShape().getFillStyle().getPaint(), o.getPath().getFill());
|
||||
if (fillMod != null) {
|
||||
graphics.setPaint(fillMod);
|
||||
java.awt.Shape s = o.getOutline();
|
||||
graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s);
|
||||
graphics.fill(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,7 +108,7 @@ public class DrawSimpleShape extends DrawShape {
|
||||
}
|
||||
}
|
||||
|
||||
// draw line decorations
|
||||
// draw line decorations
|
||||
drawDecoration(graphics, line, stroke);
|
||||
}
|
||||
|
||||
@ -378,7 +381,7 @@ public class DrawSimpleShape extends DrawShape {
|
||||
|
||||
presets.put(cusName, new CustomGeometry(cusGeom));
|
||||
}
|
||||
|
||||
|
||||
staxFiltRd.close();
|
||||
staxReader.close();
|
||||
} catch (Exception e) {
|
||||
@ -392,43 +395,40 @@ public class DrawSimpleShape extends DrawShape {
|
||||
}
|
||||
|
||||
protected Collection<Outline> computeOutlines(Graphics2D graphics) {
|
||||
final SimpleShape<?,?> sh = getShape();
|
||||
|
||||
List<Outline> lst = new ArrayList<Outline>();
|
||||
CustomGeometry geom = getShape().getGeometry();
|
||||
CustomGeometry geom = sh.getGeometry();
|
||||
if(geom == null) {
|
||||
return lst;
|
||||
}
|
||||
|
||||
Rectangle2D anchor = getAnchor(graphics, getShape());
|
||||
Rectangle2D anchor = getAnchor(graphics, sh);
|
||||
for (Path p : geom) {
|
||||
|
||||
double w = p.getW() == -1 ? anchor.getWidth() * Units.EMU_PER_POINT : p.getW();
|
||||
double h = p.getH() == -1 ? anchor.getHeight() * Units.EMU_PER_POINT : p.getH();
|
||||
double w = p.getW(), h = p.getH(), scaleX = Units.toPoints(1), scaleY = scaleX;
|
||||
if (w == -1) {
|
||||
w = Units.toEMU(anchor.getWidth());
|
||||
} else {
|
||||
scaleX = anchor.getWidth() / w;
|
||||
}
|
||||
if (h == -1) {
|
||||
h = Units.toEMU(anchor.getHeight());
|
||||
} else {
|
||||
scaleY = anchor.getHeight() / h;
|
||||
}
|
||||
|
||||
// the guides in the shape definitions are all defined relative to each other,
|
||||
// so we build the path starting from (0,0).
|
||||
final Rectangle2D pathAnchor = new Rectangle2D.Double(0,0,w,h);
|
||||
|
||||
Context ctx = new Context(geom, pathAnchor, getShape());
|
||||
Context ctx = new Context(geom, pathAnchor, sh);
|
||||
|
||||
java.awt.Shape gp = p.getPath(ctx);
|
||||
|
||||
// translate the result to the canvas coordinates in points
|
||||
AffineTransform at = new AffineTransform();
|
||||
at.translate(anchor.getX(), anchor.getY());
|
||||
|
||||
double scaleX, scaleY;
|
||||
if (p.getW() != -1) {
|
||||
scaleX = anchor.getWidth() / p.getW();
|
||||
} else {
|
||||
scaleX = 1.0 / Units.EMU_PER_POINT;
|
||||
}
|
||||
if (p.getH() != -1) {
|
||||
scaleY = anchor.getHeight() / p.getH();
|
||||
} else {
|
||||
scaleY = 1.0 / Units.EMU_PER_POINT;
|
||||
}
|
||||
|
||||
at.scale(scaleX, scaleY);
|
||||
|
||||
java.awt.Shape canvasShape = at.createTransformedShape(gp);
|
||||
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Absolute Value Formula
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class AbsExpression implements Expression {
|
||||
private String arg;
|
||||
|
||||
AbsExpression(Matcher m){
|
||||
arg = m.group(1);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double val = ctx.getValue(arg);
|
||||
return Math.abs(val);
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Add Divide Formula
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class AddDivideExpression implements Expression {
|
||||
private String arg1, arg2, arg3;
|
||||
|
||||
AddDivideExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
arg3 = m.group(3);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
double z = ctx.getValue(arg3);
|
||||
return (x + y ) / z;
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Add Subtract Formula
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class AddSubtractExpression implements Expression {
|
||||
private String arg1, arg2, arg3;
|
||||
|
||||
AddSubtractExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
arg3 = m.group(3);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
double z = ctx.getValue(arg3);
|
||||
return (x + y ) - z;
|
||||
}
|
||||
|
||||
}
|
@ -23,8 +23,6 @@ import org.apache.poi.sl.draw.binding.CTGeomGuide;
|
||||
|
||||
/**
|
||||
* Represents a shape adjust values (see section 20.1.9.5 in the spec)
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class AdjustValue extends Guide {
|
||||
|
||||
@ -36,10 +34,6 @@ public class AdjustValue extends Guide {
|
||||
public double evaluate(Context ctx){
|
||||
String name = getName();
|
||||
Guide adj = ctx.getAdjustValue(name);
|
||||
if(adj != null) {
|
||||
return adj.evaluate(ctx);
|
||||
}
|
||||
return super.evaluate(ctx);
|
||||
return (adj != null) ? adj.evaluate(ctx) : super.evaluate(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Date: 10/24/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class ArcTanExpression implements Expression {
|
||||
private String arg1, arg2;
|
||||
|
||||
ArcTanExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
return Math.atan(y / x);
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import static org.apache.poi.sl.draw.geom.Formula.OOXML_DEGREE;
|
||||
|
||||
import java.awt.geom.Arc2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Point2D;
|
||||
@ -27,42 +29,114 @@ import org.apache.poi.sl.draw.binding.CTPath2DArcTo;
|
||||
|
||||
/**
|
||||
* ArcTo command within a shape path in DrawingML:
|
||||
* {@code <arcTo wR="wr" hR="hr" stAng="stAng" swAng="swAng"/>}<p>
|
||||
*
|
||||
* <arcTo wR="wr" hR="hr" stAng="stAng" swAng="swAng"/>
|
||||
*
|
||||
* Where <code>wr</code> and <code>wh</code> are the height and width radiuses
|
||||
* Where {@code wr} and {@code wh} are the height and width radiuses
|
||||
* of the supposed circle being used to draw the arc. This gives the circle
|
||||
* a total height of (2 * hR) and a total width of (2 * wR)
|
||||
*
|
||||
* stAng is the <code>start</code> angle and <code></>swAng</code> is the swing angle
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
* stAng is the {@code start} angle and {@code swAng} is the swing angle
|
||||
*/
|
||||
public class ArcToCommand implements PathCommand {
|
||||
private String hr, wr, stAng, swAng;
|
||||
|
||||
ArcToCommand(CTPath2DArcTo arc){
|
||||
hr = arc.getHR().toString();
|
||||
wr = arc.getWR().toString();
|
||||
stAng = arc.getStAng().toString();
|
||||
swAng = arc.getSwAng().toString();
|
||||
hr = arc.getHR();
|
||||
wr = arc.getWR();
|
||||
stAng = arc.getStAng();
|
||||
swAng = arc.getSwAng();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Path2D.Double path, Context ctx){
|
||||
double rx = ctx.getValue(wr);
|
||||
double ry = ctx.getValue(hr);
|
||||
double start = ctx.getValue(stAng) / 60000;
|
||||
double extent = ctx.getValue(swAng) / 60000;
|
||||
Point2D pt = path.getCurrentPoint();
|
||||
double x0 = pt.getX() - rx - rx * Math.cos(Math.toRadians(start));
|
||||
double y0 = pt.getY() - ry - ry * Math.sin(Math.toRadians(start));
|
||||
double ooStart = ctx.getValue(stAng) / OOXML_DEGREE;
|
||||
double ooExtent = ctx.getValue(swAng) / OOXML_DEGREE;
|
||||
|
||||
Arc2D arc = new Arc2D.Double(
|
||||
x0,
|
||||
y0,
|
||||
2 * rx, 2 * ry,
|
||||
-start, -extent,
|
||||
Arc2D.OPEN);
|
||||
// skew the angles for AWT output
|
||||
double awtStart = convertOoxml2AwtAngle(ooStart, rx, ry);
|
||||
double awtSweep = convertOoxml2AwtAngle(ooStart+ooExtent, rx, ry)-awtStart;
|
||||
|
||||
// calculate the inverse angle - taken from the (reversed) preset definition
|
||||
double radStart = Math.toRadians(ooStart);
|
||||
double invStart = Math.atan2(rx * Math.sin(radStart), ry * Math.cos(radStart));
|
||||
|
||||
Point2D pt = path.getCurrentPoint();
|
||||
// calculate top/left corner
|
||||
double x0 = pt.getX() - rx * Math.cos(invStart) - rx;
|
||||
double y0 = pt.getY() - ry * Math.sin(invStart) - ry;
|
||||
|
||||
Arc2D arc = new Arc2D.Double(x0, y0, 2 * rx, 2 * ry, awtStart, awtSweep, Arc2D.OPEN);
|
||||
path.append(arc, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Arc2D angles are skewed, OOXML aren't ... so we need to unskew them<p>
|
||||
*
|
||||
* Furthermore ooxml angle starts at the X-axis and increases clock-wise,
|
||||
* where as Arc2D api states
|
||||
* "45 degrees always falls on the line from the center of the ellipse to
|
||||
* the upper right corner of the framing rectangle"
|
||||
* so we need to reverse it
|
||||
*
|
||||
* <pre>
|
||||
* AWT: OOXML:
|
||||
* |90/-270 |270/-90 (16200000)
|
||||
* | |
|
||||
* +/-180-----------0 +/-180-----------0
|
||||
* | (10800000) |
|
||||
* |270/-90 |90/-270 (5400000)
|
||||
* </pre>
|
||||
*
|
||||
* @param ooAngle the angle in OOXML units
|
||||
* @param width the half width of the bounding box
|
||||
* @param height the half height of the bounding box
|
||||
*
|
||||
* @return the angle in degrees
|
||||
*
|
||||
* @see <a href="http://www.onlinemathe.de/forum/Problem-bei-Winkelberechnungen-einer-Ellipse">unskew angle</a>
|
||||
**/
|
||||
private double convertOoxml2AwtAngle(double ooAngle, double width, double height) {
|
||||
double aspect = (height / width);
|
||||
// reverse angle for awt
|
||||
double awtAngle = -ooAngle;
|
||||
// normalize angle, in case it's < -360 or > 360 degrees
|
||||
double awtAngle2 = awtAngle%360.;
|
||||
double awtAngle3 = awtAngle-awtAngle2;
|
||||
// because of tangens nature, the values left [90°-270°] and right [270°-90°] of the axis are mirrored/the same
|
||||
// and the result of atan2 need to be justified
|
||||
switch ((int)(awtAngle2 / 90)) {
|
||||
case -3:
|
||||
// -270 to -360
|
||||
awtAngle3 -= 360;
|
||||
awtAngle2 += 360;
|
||||
break;
|
||||
case -2:
|
||||
case -1:
|
||||
// -90 to -270
|
||||
awtAngle3 -= 180;
|
||||
awtAngle2 += 180;
|
||||
break;
|
||||
default:
|
||||
case 0:
|
||||
// -90 to 90
|
||||
break;
|
||||
case 2:
|
||||
case 1:
|
||||
// 90 to 270
|
||||
awtAngle3 += 180;
|
||||
awtAngle2 -= 180;
|
||||
break;
|
||||
case 3:
|
||||
// 270 to 360
|
||||
awtAngle3 += 360;
|
||||
awtAngle2 -= 360;
|
||||
break;
|
||||
}
|
||||
|
||||
// skew
|
||||
awtAngle = Math.toDegrees(Math.atan2(Math.tan(Math.toRadians(awtAngle2)), aspect)) + awtAngle3;
|
||||
return awtAngle;
|
||||
}
|
||||
}
|
||||
|
153
src/java/org/apache/poi/sl/draw/geom/BuiltInGuide.java
Normal file
153
src/java/org/apache/poi/sl/draw/geom/BuiltInGuide.java
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/* package */ enum BuiltInGuide implements Formula {
|
||||
_3cd4, _3cd8, _5cd8, _7cd8, _b, _cd2, _cd4, _cd8, _hc, _h, _hd2, _hd3, _hd4, _hd5, _hd6, _hd8,
|
||||
_l, _ls, _r, _ss, _ssd2, _ssd4, _ssd6, _ssd8, _ssd16, _ssd32, _t, _vc,
|
||||
_w, _wd2, _wd3, _wd4, _wd5, _wd6, _wd8, _wd10, _wd32;
|
||||
|
||||
public String getName() {
|
||||
return name().substring(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double evaluate(Context ctx) {
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
double height = anchor.getHeight(), width = anchor.getWidth(), ss = Math.min(width, height);
|
||||
switch (this) {
|
||||
case _3cd4:
|
||||
// 3 circles div 4: 3 x 360 / 4 = 270
|
||||
return 270 * OOXML_DEGREE;
|
||||
case _3cd8:
|
||||
// 3 circles div 8: 3 x 360 / 8 = 135
|
||||
return 135 * OOXML_DEGREE;
|
||||
case _5cd8:
|
||||
// 5 circles div 8: 5 x 360 / 8 = 225
|
||||
return 225 * OOXML_DEGREE;
|
||||
case _7cd8:
|
||||
// 7 circles div 8: 7 x 360 / 8 = 315
|
||||
return 315 * OOXML_DEGREE;
|
||||
case _t:
|
||||
// top
|
||||
return anchor.getY();
|
||||
case _b:
|
||||
// bottom
|
||||
return anchor.getMaxY();
|
||||
case _l:
|
||||
// left
|
||||
return anchor.getX();
|
||||
case _r:
|
||||
// right
|
||||
return anchor.getMaxX();
|
||||
case _cd2:
|
||||
// circle div 2: 360 / 2 = 180
|
||||
return 180 * OOXML_DEGREE;
|
||||
case _cd4:
|
||||
// circle div 4: 360 / 4 = 90
|
||||
return 90 * OOXML_DEGREE;
|
||||
case _cd8:
|
||||
// circle div 8: 360 / 8 = 45
|
||||
return 45 * OOXML_DEGREE;
|
||||
case _hc:
|
||||
// horizontal center
|
||||
return anchor.getCenterX();
|
||||
case _h:
|
||||
// height
|
||||
return height;
|
||||
case _hd2:
|
||||
// height div 2
|
||||
return height / 2.;
|
||||
case _hd3:
|
||||
// height div 3
|
||||
return height / 3.;
|
||||
case _hd4:
|
||||
// height div 4
|
||||
return height / 4.;
|
||||
case _hd5:
|
||||
// height div 5
|
||||
return height / 5.;
|
||||
case _hd6:
|
||||
// height div 6
|
||||
return height / 6.;
|
||||
case _hd8:
|
||||
// height div 8
|
||||
return height / 8.;
|
||||
case _ls:
|
||||
// long side
|
||||
return Math.max(width, height);
|
||||
case _ss:
|
||||
// short side
|
||||
return ss;
|
||||
case _ssd2:
|
||||
// short side div 2
|
||||
return ss / 2.;
|
||||
case _ssd4:
|
||||
// short side div 4
|
||||
return ss / 4.;
|
||||
case _ssd6:
|
||||
// short side div 6
|
||||
return ss / 6.;
|
||||
case _ssd8:
|
||||
// short side div 8
|
||||
return ss / 8.;
|
||||
case _ssd16:
|
||||
// short side div 16
|
||||
return ss / 16.;
|
||||
case _ssd32:
|
||||
// short side div 32
|
||||
return ss / 32.;
|
||||
case _vc:
|
||||
// vertical center
|
||||
return anchor.getCenterY();
|
||||
case _w:
|
||||
// width
|
||||
return width;
|
||||
case _wd2:
|
||||
// width div 2
|
||||
return width / 2.;
|
||||
case _wd3:
|
||||
// width div 3
|
||||
return width / 3.;
|
||||
case _wd4:
|
||||
// width div 4
|
||||
return width / 4.;
|
||||
case _wd5:
|
||||
// width div 5
|
||||
return width / 5.;
|
||||
case _wd6:
|
||||
// width div 6
|
||||
return width / 6.;
|
||||
case _wd8:
|
||||
// width div 8
|
||||
return width / 8.;
|
||||
case _wd10:
|
||||
// width div 10
|
||||
return width / 10.;
|
||||
case _wd32:
|
||||
// width div 32
|
||||
return width / 32.;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -21,16 +21,12 @@ package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.awt.geom.Path2D;
|
||||
|
||||
/**
|
||||
* Date: 10/25/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class ClosePathCommand implements PathCommand {
|
||||
|
||||
ClosePathCommand(){
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Path2D.Double path, Context ctx){
|
||||
path.closePath();
|
||||
}
|
||||
|
@ -23,11 +23,6 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Date: 10/24/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class Context {
|
||||
final Map<String, Double> _ctx = new HashMap<String, Double>();
|
||||
final IAdjustableShape _props;
|
||||
@ -36,8 +31,12 @@ public class Context {
|
||||
public Context(CustomGeometry geom, Rectangle2D anchor, IAdjustableShape props){
|
||||
_props = props;
|
||||
_anchor = anchor;
|
||||
for(Guide gd : geom.adjusts) evaluate(gd);
|
||||
for(Guide gd : geom.guides) evaluate(gd);
|
||||
for(Guide gd : geom.adjusts) {
|
||||
evaluate(gd);
|
||||
}
|
||||
for(Guide gd : geom.guides) {
|
||||
evaluate(gd);
|
||||
}
|
||||
}
|
||||
|
||||
public Rectangle2D getShapeAnchor(){
|
||||
@ -53,22 +52,19 @@ public class Context {
|
||||
return Double.parseDouble(key);
|
||||
}
|
||||
|
||||
Formula builtIn = Formula.builtInFormulas.get(key);
|
||||
if(builtIn != null){
|
||||
return builtIn.evaluate(this);
|
||||
}
|
||||
|
||||
if(!_ctx.containsKey(key)) {
|
||||
throw new RuntimeException("undefined variable: " + key);
|
||||
}
|
||||
|
||||
return _ctx.get(key);
|
||||
Double val = _ctx.get(key);
|
||||
// BuiltInGuide throws IllegalArgumentException if key is not defined
|
||||
return (val != null) ? val : evaluate(BuiltInGuide.valueOf("_"+key));
|
||||
}
|
||||
|
||||
public double evaluate(Formula fmla){
|
||||
double result = fmla.evaluate(this);
|
||||
String key = fmla.getName();
|
||||
if(key != null) _ctx.put(key, result);
|
||||
if (fmla instanceof Guide) {
|
||||
String key = ((Guide)fmla).getName();
|
||||
if (key != null) {
|
||||
_ctx.put(key, result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Date: 10/24/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class CosExpression implements Expression {
|
||||
private String arg1, arg2;
|
||||
|
||||
CosExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2)/ 60000;
|
||||
return x * Math.cos(Math.toRadians(y));
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Date: 10/24/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class CosineArcTanExpression implements Expression {
|
||||
private String arg1, arg2, arg3;
|
||||
|
||||
CosineArcTanExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
arg3 = m.group(3);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
double z = ctx.getValue(arg3);
|
||||
return x*Math.cos(Math.atan(z / y));
|
||||
}
|
||||
|
||||
}
|
@ -23,23 +23,19 @@ import java.awt.geom.Path2D;
|
||||
|
||||
import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
|
||||
|
||||
/**
|
||||
* Date: 10/25/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class CurveToCommand implements PathCommand {
|
||||
private String arg1, arg2, arg3, arg4, arg5, arg6;
|
||||
|
||||
CurveToCommand(CTAdjPoint2D pt1, CTAdjPoint2D pt2, CTAdjPoint2D pt3){
|
||||
arg1 = pt1.getX().toString();
|
||||
arg2 = pt1.getY().toString();
|
||||
arg3 = pt2.getX().toString();
|
||||
arg4 = pt2.getY().toString();
|
||||
arg5 = pt3.getX().toString();
|
||||
arg6 = pt3.getY().toString();
|
||||
arg1 = pt1.getX();
|
||||
arg2 = pt1.getY();
|
||||
arg3 = pt2.getX();
|
||||
arg4 = pt2.getY();
|
||||
arg5 = pt3.getX();
|
||||
arg6 = pt3.getY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Path2D.Double path, Context ctx){
|
||||
double x1 = ctx.getValue(arg1);
|
||||
double y1 = ctx.getValue(arg2);
|
||||
|
@ -19,19 +19,24 @@
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.sl.draw.binding.*;
|
||||
import org.apache.poi.sl.draw.binding.CTCustomGeometry2D;
|
||||
import org.apache.poi.sl.draw.binding.CTGeomGuide;
|
||||
import org.apache.poi.sl.draw.binding.CTGeomGuideList;
|
||||
import org.apache.poi.sl.draw.binding.CTGeomRect;
|
||||
import org.apache.poi.sl.draw.binding.CTPath2D;
|
||||
import org.apache.poi.sl.draw.binding.CTPath2DList;
|
||||
|
||||
/**
|
||||
* Definition of a custom geometric shape
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class CustomGeometry implements Iterable<Path>{
|
||||
List<Guide> adjusts = new ArrayList<Guide>();
|
||||
List<Guide> guides = new ArrayList<Guide>();
|
||||
List<Path> paths = new ArrayList<Path>();
|
||||
final List<Guide> adjusts = new ArrayList<Guide>();
|
||||
final List<Guide> guides = new ArrayList<Guide>();
|
||||
final List<Path> paths = new ArrayList<Path>();
|
||||
Path textBounds;
|
||||
|
||||
public CustomGeometry(CTCustomGeometry2D geom) {
|
||||
@ -59,24 +64,20 @@ public class CustomGeometry implements Iterable<Path>{
|
||||
CTGeomRect rect = geom.getRect();
|
||||
if(rect != null) {
|
||||
textBounds = new Path();
|
||||
textBounds.addCommand(
|
||||
new MoveToCommand(rect.getL().toString(), rect.getT().toString()));
|
||||
textBounds.addCommand(
|
||||
new LineToCommand(rect.getR().toString(), rect.getT().toString()));
|
||||
textBounds.addCommand(
|
||||
new LineToCommand(rect.getR().toString(), rect.getB().toString()));
|
||||
textBounds.addCommand(
|
||||
new LineToCommand(rect.getL().toString(), rect.getB().toString()));
|
||||
textBounds.addCommand(
|
||||
new ClosePathCommand());
|
||||
textBounds.addCommand(new MoveToCommand(rect.getL(), rect.getT()));
|
||||
textBounds.addCommand(new LineToCommand(rect.getR(), rect.getT()));
|
||||
textBounds.addCommand(new LineToCommand(rect.getR(), rect.getB()));
|
||||
textBounds.addCommand(new LineToCommand(rect.getL(), rect.getB()));
|
||||
textBounds.addCommand(new ClosePathCommand());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterator<Path> iterator() {
|
||||
return paths.iterator();
|
||||
}
|
||||
|
||||
public Path getTextBounds(){
|
||||
return textBounds;
|
||||
return textBounds;
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
/**
|
||||
* Date: 10/24/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public interface Expression {
|
||||
|
||||
double evaluate(Context ctx);
|
||||
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A simple regexp-based parser of shape guide formulas in DrawingML
|
||||
*/
|
||||
public class ExpressionParser {
|
||||
private static final Map<String, ExpressionEntry> impls =
|
||||
new HashMap<String, ExpressionEntry>();
|
||||
|
||||
private static class ExpressionEntry {
|
||||
final Pattern regex;
|
||||
final Constructor<? extends Expression> con;
|
||||
ExpressionEntry(String regex, Class<? extends Expression> cls)
|
||||
throws SecurityException, NoSuchMethodException {
|
||||
this.regex = Pattern.compile(regex);
|
||||
this.con = cls.getDeclaredConstructor(Matcher.class);
|
||||
impls.put(op(regex), this);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
try {
|
||||
new ExpressionEntry("\\*/ +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", MultiplyDivideExpression.class);
|
||||
new ExpressionEntry("\\+- +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)( 0)?", AddSubtractExpression.class);
|
||||
new ExpressionEntry("\\+/ +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", AddDivideExpression.class);
|
||||
new ExpressionEntry("\\?: +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", IfElseExpression.class);
|
||||
new ExpressionEntry("val +([\\-\\w]+)", LiteralValueExpression.class);
|
||||
new ExpressionEntry("abs +([\\-\\w]+)", AbsExpression.class);
|
||||
new ExpressionEntry("sqrt +([\\-\\w]+)", SqrtExpression.class);
|
||||
new ExpressionEntry("max +([\\-\\w]+) +([\\-\\w]+)", MaxExpression.class);
|
||||
new ExpressionEntry("min +([\\-\\w]+) +([\\-\\w]+)", MinExpression.class);
|
||||
new ExpressionEntry("at2 +([\\-\\w]+) +([\\-\\w]+)", ArcTanExpression.class);
|
||||
new ExpressionEntry("sin +([\\-\\w]+) +([\\-\\w]+)", SinExpression.class);
|
||||
new ExpressionEntry("cos +([\\-\\w]+) +([\\-\\w]+)", CosExpression.class);
|
||||
new ExpressionEntry("tan +([\\-\\w]+) +([\\-\\w]+)", TanExpression.class);
|
||||
new ExpressionEntry("cat2 +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", CosineArcTanExpression.class);
|
||||
new ExpressionEntry("sat2 +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", SinArcTanExpression.class);
|
||||
new ExpressionEntry("pin +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", PinExpression.class);
|
||||
new ExpressionEntry("mod +([\\-\\w]+) +([\\-\\w]+) +([\\-\\w]+)", ModExpression.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String op(String str) {
|
||||
return (str == null || !str.contains(" "))
|
||||
? "" : str.substring(0, str.indexOf(" ")).replace("\\", "");
|
||||
}
|
||||
|
||||
public static Expression parse(String str) {
|
||||
ExpressionEntry ee = impls.get(op(str));
|
||||
Matcher m = (ee == null) ? null : ee.regex.matcher(str);
|
||||
if (m == null || !m.matches()) {
|
||||
throw new RuntimeException("Unsupported formula: " + str);
|
||||
}
|
||||
|
||||
try {
|
||||
return ee.con.newInstance(m);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unsupported formula: " + str, e);
|
||||
}
|
||||
}
|
||||
}
|
@ -19,367 +19,16 @@
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A guide formula in DrawingML.
|
||||
* This is a base class for adjust values, geometric guides and bilt-in guides
|
||||
* A guide formula in DrawingML.<p>
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
* This is a base interface for adjust values, geometric guides and built-in guides
|
||||
*/
|
||||
public abstract class Formula {
|
||||
|
||||
String getName(){
|
||||
return null;
|
||||
}
|
||||
|
||||
abstract double evaluate(Context ctx);
|
||||
|
||||
static Map<String, Formula> builtInFormulas = new HashMap<String, Formula>();
|
||||
static {
|
||||
// 3 x 360 / 4 = 270
|
||||
builtInFormulas.put("3cd4", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return 270 * 60000.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 3 x 360 / 8 = 135
|
||||
builtInFormulas.put("3cd8", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return 135 * 60000.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 5 x 360 / 8 = 225
|
||||
builtInFormulas.put("5cd8", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return 270 * 60000.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 7 x 360 / 8 = 315
|
||||
builtInFormulas.put("7cd8", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return 270 * 60000.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// bottom
|
||||
builtInFormulas.put("b", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return anchor.getY() + anchor.getHeight();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 360 / 2 = 180
|
||||
builtInFormulas.put("cd2", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return 180 * 60000.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 360 / 4 = 90
|
||||
builtInFormulas.put("cd4", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return 90 * 60000.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 360 / 8 = 45
|
||||
builtInFormulas.put("cd8", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return 45 * 60000.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// horizontal center
|
||||
builtInFormulas.put("hc", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return anchor.getX() + anchor.getWidth()/2.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// height
|
||||
builtInFormulas.put("h", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return anchor.getHeight();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// height / 2
|
||||
builtInFormulas.put("hd2", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return anchor.getHeight()/2.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// height / 3
|
||||
builtInFormulas.put("hd3", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return anchor.getHeight()/3.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// height / 4
|
||||
builtInFormulas.put("hd4", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return anchor.getHeight()/4.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// height / 5
|
||||
builtInFormulas.put("hd5", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return anchor.getHeight()/5.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// height / 6
|
||||
builtInFormulas.put("hd6", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return anchor.getHeight()/6.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// height / 8
|
||||
builtInFormulas.put("hd8", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return anchor.getHeight()/8.;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// left
|
||||
builtInFormulas.put("l", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return anchor.getX();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// long side
|
||||
builtInFormulas.put("ls", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return Math.max(anchor.getWidth(), anchor.getHeight());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// right
|
||||
builtInFormulas.put("r", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return anchor.getX() + anchor.getWidth();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// short side
|
||||
builtInFormulas.put("ss", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return Math.min(anchor.getWidth(), anchor.getHeight());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// short side / 2
|
||||
builtInFormulas.put("ssd2", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
double ss = Math.min(anchor.getWidth(), anchor.getHeight());
|
||||
return ss / 2.;
|
||||
}
|
||||
});
|
||||
|
||||
// short side / 4
|
||||
builtInFormulas.put("ssd4", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
double ss = Math.min(anchor.getWidth(), anchor.getHeight());
|
||||
return ss / 4.;
|
||||
}
|
||||
});
|
||||
|
||||
// short side / 6
|
||||
builtInFormulas.put("ssd6", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
double ss = Math.min(anchor.getWidth(), anchor.getHeight());
|
||||
return ss / 6.;
|
||||
}
|
||||
});
|
||||
|
||||
// short side / 8
|
||||
builtInFormulas.put("ssd8", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
double ss = Math.min(anchor.getWidth(), anchor.getHeight());
|
||||
return ss / 8.;
|
||||
}
|
||||
});
|
||||
|
||||
// short side / 16
|
||||
builtInFormulas.put("ssd16", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
double ss = Math.min(anchor.getWidth(), anchor.getHeight());
|
||||
return ss / 16.;
|
||||
}
|
||||
});
|
||||
|
||||
// short side / 32
|
||||
builtInFormulas.put("ssd32", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
double ss = Math.min(anchor.getWidth(), anchor.getHeight());
|
||||
return ss / 32.;
|
||||
}
|
||||
});
|
||||
|
||||
// top
|
||||
builtInFormulas.put("t", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return ctx.getShapeAnchor().getY();
|
||||
}
|
||||
});
|
||||
|
||||
// vertical center
|
||||
builtInFormulas.put("vc", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
Rectangle2D anchor = ctx.getShapeAnchor();
|
||||
return anchor.getY() + anchor.getHeight()/2.;
|
||||
}
|
||||
});
|
||||
|
||||
// width
|
||||
builtInFormulas.put("w", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return ctx.getShapeAnchor().getWidth();
|
||||
}
|
||||
});
|
||||
|
||||
// width / 2
|
||||
builtInFormulas.put("wd2", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return ctx.getShapeAnchor().getWidth()/2.;
|
||||
}
|
||||
});
|
||||
|
||||
// width / 3
|
||||
builtInFormulas.put("wd3", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return ctx.getShapeAnchor().getWidth()/3.;
|
||||
}
|
||||
});
|
||||
|
||||
// width / 4
|
||||
builtInFormulas.put("wd4", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return ctx.getShapeAnchor().getWidth()/4.;
|
||||
}
|
||||
});
|
||||
|
||||
// width / 5
|
||||
builtInFormulas.put("wd5", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return ctx.getShapeAnchor().getWidth()/5.;
|
||||
}
|
||||
});
|
||||
|
||||
// width / 6
|
||||
builtInFormulas.put("wd6", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return ctx.getShapeAnchor().getWidth()/6.;
|
||||
}
|
||||
});
|
||||
|
||||
// width / 8
|
||||
builtInFormulas.put("wd8", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return ctx.getShapeAnchor().getWidth()/8.;
|
||||
}
|
||||
});
|
||||
|
||||
// width / 10
|
||||
builtInFormulas.put("wd10", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return ctx.getShapeAnchor().getWidth()/10.;
|
||||
}
|
||||
});
|
||||
|
||||
// width / 32
|
||||
builtInFormulas.put("wd32", new Formula(){
|
||||
@Override
|
||||
double evaluate(Context ctx){
|
||||
return ctx.getShapeAnchor().getWidth()/32.;
|
||||
}
|
||||
});
|
||||
}
|
||||
public interface Formula {
|
||||
/**
|
||||
* OOXML units are 60000ths of a degree
|
||||
*/
|
||||
double OOXML_DEGREE = 60000;
|
||||
|
||||
double evaluate(Context ctx);
|
||||
}
|
||||
|
@ -19,16 +19,31 @@
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import static java.lang.Math.abs;
|
||||
import static java.lang.Math.atan2;
|
||||
import static java.lang.Math.cos;
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
import static java.lang.Math.sin;
|
||||
import static java.lang.Math.sqrt;
|
||||
import static java.lang.Math.tan;
|
||||
import static java.lang.Math.toDegrees;
|
||||
import static java.lang.Math.toRadians;
|
||||
|
||||
import org.apache.poi.sl.draw.binding.CTGeomGuide;
|
||||
|
||||
/**
|
||||
* Date: 10/24/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
* A simple pattern parser of shape guide formulas in DrawingML
|
||||
*/
|
||||
public class Guide extends Formula {
|
||||
private String name, fmla;
|
||||
private Expression expr;
|
||||
public class Guide implements Formula {
|
||||
enum Op {
|
||||
muldiv,addsub,adddiv,ifelse,val,abs,sqrt,max,min,at2,sin,cos,tan,cat2,sat2,pin,mod;
|
||||
}
|
||||
|
||||
private final String name, fmla;
|
||||
private final Op op;
|
||||
private final String[] operands;
|
||||
|
||||
|
||||
public Guide(CTGeomGuide gd) {
|
||||
this(gd.getName(), gd.getFmla());
|
||||
@ -37,11 +52,11 @@ public class Guide extends Formula {
|
||||
public Guide(String nm, String fm){
|
||||
name = nm;
|
||||
fmla = fm;
|
||||
expr = ExpressionParser.parse(fm);
|
||||
operands = fm.split("\\s+");
|
||||
op = Op.valueOf(operands[0].replace("*", "mul").replace("/", "div").replace("+", "add").replace("-", "sub").replace("?:", "ifelse"));
|
||||
}
|
||||
|
||||
|
||||
String getName(){
|
||||
public String getName(){
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -50,9 +65,73 @@ public class Guide extends Formula {
|
||||
}
|
||||
|
||||
@Override
|
||||
public double evaluate(Context ctx){
|
||||
return expr.evaluate(ctx);
|
||||
public double evaluate(Context ctx) {
|
||||
double x = (operands.length > 1) ? ctx.getValue(operands[1]) : 0;
|
||||
double y = (operands.length > 2) ? ctx.getValue(operands[2]) : 0;
|
||||
double z = (operands.length > 3) ? ctx.getValue(operands[3]) : 0;
|
||||
switch (op) {
|
||||
case abs:
|
||||
// Absolute Value Formula
|
||||
return abs(x);
|
||||
case adddiv:
|
||||
// Add Divide Formula
|
||||
return (x + y) / z;
|
||||
case addsub:
|
||||
// Add Subtract Formula
|
||||
return (x + y) - z;
|
||||
case at2:
|
||||
// ArcTan Formula: "at2 x y" = arctan( y / z ) = value of this guide
|
||||
return toDegrees(atan2(y, x)) * OOXML_DEGREE;
|
||||
case cos:
|
||||
// Cosine Formula: "cos x y" = (x * cos( y )) = value of this guide
|
||||
return x * cos(toRadians(y / OOXML_DEGREE));
|
||||
case cat2:
|
||||
// Cosine ArcTan Formula: "cat2 x y z" = (x * cos(arctan(z / y) )) = value of this guide
|
||||
return x*cos(atan2(z, y));
|
||||
case ifelse:
|
||||
// If Else Formula: "?: x y z" = if (x > 0), then y = value of this guide,
|
||||
// else z = value of this guide
|
||||
return x > 0 ? y : z;
|
||||
case val:
|
||||
// Literal Value Expression
|
||||
return x;
|
||||
case max:
|
||||
// Maximum Value Formula
|
||||
return max(x, y);
|
||||
case min:
|
||||
// Minimum Value Formula
|
||||
return min(x, y);
|
||||
case mod:
|
||||
// Modulo Formula: "mod x y z" = sqrt(x^2 + b^2 + c^2) = value of this guide
|
||||
return sqrt(x*x + y*y + z*z);
|
||||
case muldiv:
|
||||
// Multiply Divide Formula
|
||||
return (x * y) / z;
|
||||
case pin:
|
||||
// Pin To Formula: "pin x y z" = if (y < x), then x = value of this guide
|
||||
// else if (y > z), then z = value of this guide
|
||||
// else y = value of this guide
|
||||
if(y < x) {
|
||||
return x;
|
||||
} else if (y > z) {
|
||||
return z;
|
||||
} else {
|
||||
return y;
|
||||
}
|
||||
case sat2:
|
||||
// Sine ArcTan Formula: "sat2 x y z" = (x*sin(arctan(z / y))) = value of this guide
|
||||
return x*sin(atan2(z, y));
|
||||
case sin:
|
||||
// Sine Formula: "sin x y" = (x * sin( y )) = value of this guide
|
||||
return x * sin(toRadians(y / OOXML_DEGREE));
|
||||
case sqrt:
|
||||
// Square Root Formula: "sqrt x" = sqrt(x) = value of this guide
|
||||
return sqrt(x);
|
||||
case tan:
|
||||
// Tangent Formula: "tan x y" = (x * tan( y )) = value of this guide
|
||||
return x * tan(toRadians(y / OOXML_DEGREE));
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -21,11 +21,9 @@ package org.apache.poi.sl.draw.geom;
|
||||
|
||||
|
||||
/**
|
||||
* A bridge to the consumer application.
|
||||
* A bridge to the consumer application.<p>
|
||||
*
|
||||
* To get a shape geometry one needs to pass shape bounds and adjust values.
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public interface IAdjustableShape {
|
||||
/**
|
||||
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* If Else Formula:
|
||||
* <p>
|
||||
* Arguments: 3 (fmla="?: x y z")
|
||||
* Usage: "?: x y z" = if (x > 0), then y = value of this guide,
|
||||
* else z = value of this guide
|
||||
* </p>
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class IfElseExpression implements Expression {
|
||||
private String arg1, arg2, arg3;
|
||||
|
||||
IfElseExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
arg3 = m.group(3);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
double z = ctx.getValue(arg3);
|
||||
return x > 0 ? y : z;
|
||||
}
|
||||
|
||||
}
|
@ -23,17 +23,12 @@ import java.awt.geom.Path2D;
|
||||
|
||||
import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
|
||||
|
||||
/**
|
||||
* Date: 10/25/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class LineToCommand implements PathCommand {
|
||||
private String arg1, arg2;
|
||||
|
||||
LineToCommand(CTAdjPoint2D pt){
|
||||
arg1 = pt.getX().toString();
|
||||
arg2 = pt.getY().toString();
|
||||
arg1 = pt.getX();
|
||||
arg2 = pt.getY();
|
||||
}
|
||||
|
||||
LineToCommand(String s1, String s2){
|
||||
@ -41,6 +36,7 @@ public class LineToCommand implements PathCommand {
|
||||
arg2 = s2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Path2D.Double path, Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Date: 10/24/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class LiteralValueExpression implements Expression {
|
||||
private String arg;
|
||||
|
||||
LiteralValueExpression(Matcher m){
|
||||
arg = m.group(1);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
return ctx.getValue(arg);
|
||||
}
|
||||
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Maximum Value Formula
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class MaxExpression implements Expression {
|
||||
private String arg1, arg2;
|
||||
|
||||
MaxExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
return Math.max(x, y);
|
||||
}
|
||||
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Minimum Value Formula
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class MinExpression implements Expression {
|
||||
private String arg1, arg2;
|
||||
|
||||
MinExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
return Math.min(x, y);
|
||||
}
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Modulo Formula:
|
||||
* <p>
|
||||
* Arguments: 3 (fmla="mod x y z")
|
||||
* Usage: "mod x y z" = sqrt(x^2 + b^2 + c^2) = value of this guide
|
||||
* </p>
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class ModExpression implements Expression {
|
||||
private String arg1, arg2, arg3;
|
||||
|
||||
ModExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
arg3 = m.group(3);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
double z = ctx.getValue(arg3);
|
||||
return Math.sqrt(x*x + y*y + z*z);
|
||||
}
|
||||
|
||||
}
|
@ -23,17 +23,12 @@ import java.awt.geom.Path2D;
|
||||
|
||||
import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
|
||||
|
||||
/**
|
||||
* Date: 10/25/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class MoveToCommand implements PathCommand {
|
||||
private String arg1, arg2;
|
||||
|
||||
MoveToCommand(CTAdjPoint2D pt){
|
||||
arg1 = pt.getX().toString();
|
||||
arg2 = pt.getY().toString();
|
||||
arg1 = pt.getX();
|
||||
arg2 = pt.getY();
|
||||
}
|
||||
|
||||
MoveToCommand(String s1, String s2){
|
||||
@ -41,6 +36,7 @@ public class MoveToCommand implements PathCommand {
|
||||
arg2 = s2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Path2D.Double path, Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Multiply Divide Formula
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class MultiplyDivideExpression implements Expression {
|
||||
private String arg1, arg2, arg3;
|
||||
|
||||
MultiplyDivideExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
arg3 = m.group(3);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
double z = ctx.getValue(arg3);
|
||||
return (x * y ) / z;
|
||||
}
|
||||
|
||||
}
|
@ -21,11 +21,6 @@ package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.awt.Shape;
|
||||
|
||||
/**
|
||||
* Date: 11/6/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class Outline {
|
||||
private Shape shape;
|
||||
private Path path;
|
||||
|
@ -31,17 +31,17 @@ import org.apache.poi.sl.draw.binding.CTPath2DCubicBezierTo;
|
||||
import org.apache.poi.sl.draw.binding.CTPath2DLineTo;
|
||||
import org.apache.poi.sl.draw.binding.CTPath2DMoveTo;
|
||||
import org.apache.poi.sl.draw.binding.CTPath2DQuadBezierTo;
|
||||
import org.apache.poi.sl.draw.binding.STPathFillMode;
|
||||
import org.apache.poi.sl.usermodel.PaintStyle.PaintModifier;
|
||||
|
||||
/**
|
||||
* Specifies a creation path consisting of a series of moves, lines and curves
|
||||
* that when combined forms a geometric shape
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class Path {
|
||||
|
||||
private final List<PathCommand> commands;
|
||||
boolean _fill, _stroke;
|
||||
PaintModifier _fill;
|
||||
boolean _stroke;
|
||||
long _w, _h;
|
||||
|
||||
public Path(){
|
||||
@ -52,18 +52,26 @@ public class Path {
|
||||
commands = new ArrayList<PathCommand>();
|
||||
_w = -1;
|
||||
_h = -1;
|
||||
_fill = fill;
|
||||
_fill = (fill) ? PaintModifier.NORM : PaintModifier.NONE;
|
||||
_stroke = stroke;
|
||||
}
|
||||
|
||||
public Path(CTPath2D spPath){
|
||||
_fill = spPath.getFill() != STPathFillMode.NONE;
|
||||
switch (spPath.getFill()) {
|
||||
case NONE: _fill = PaintModifier.NONE; break;
|
||||
case DARKEN: _fill = PaintModifier.DARKEN; break;
|
||||
case DARKEN_LESS: _fill = PaintModifier.DARKEN_LESS; break;
|
||||
case LIGHTEN: _fill = PaintModifier.LIGHTEN; break;
|
||||
case LIGHTEN_LESS: _fill = PaintModifier.LIGHTEN_LESS; break;
|
||||
default:
|
||||
case NORM: _fill = PaintModifier.NORM; break;
|
||||
}
|
||||
_stroke = spPath.isStroke();
|
||||
_w = spPath.isSetW() ? spPath.getW() : -1;
|
||||
_h = spPath.isSetH() ? spPath.getH() : -1;
|
||||
|
||||
_w = spPath.isSetW() ? spPath.getW() : -1;
|
||||
_h = spPath.isSetH() ? spPath.getH() : -1;
|
||||
|
||||
commands = new ArrayList<PathCommand>();
|
||||
|
||||
|
||||
for(Object ch : spPath.getCloseOrMoveToOrLnTo()){
|
||||
if(ch instanceof CTPath2DMoveTo){
|
||||
CTAdjPoint2D pt = ((CTPath2DMoveTo)ch).getPt();
|
||||
@ -102,8 +110,9 @@ public class Path {
|
||||
*/
|
||||
public Path2D.Double getPath(Context ctx) {
|
||||
Path2D.Double path = new Path2D.Double();
|
||||
for(PathCommand cmd : commands)
|
||||
for(PathCommand cmd : commands) {
|
||||
cmd.execute(path, ctx);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
@ -112,9 +121,13 @@ public class Path {
|
||||
}
|
||||
|
||||
public boolean isFilled(){
|
||||
return _fill != PaintModifier.NONE;
|
||||
}
|
||||
|
||||
public PaintModifier getFill() {
|
||||
return _fill;
|
||||
}
|
||||
|
||||
|
||||
public long getW(){
|
||||
return _w;
|
||||
}
|
||||
|
@ -24,15 +24,12 @@ import java.awt.geom.Path2D;
|
||||
/**
|
||||
* A path command in DrawingML. One of:
|
||||
*
|
||||
* - arcTo
|
||||
* - moveTo
|
||||
* - lineTo
|
||||
* - cubicBezTo
|
||||
* - quadBezTo
|
||||
* - close
|
||||
*
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
* <li>arcTo
|
||||
* <li>moveTo
|
||||
* <li>lineTo
|
||||
* <li>cubicBezTo
|
||||
* <li>quadBezTo
|
||||
* <li>close
|
||||
*/
|
||||
public interface PathCommand {
|
||||
/**
|
||||
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Pin To Formula:
|
||||
* <gd name="enAng" fmla="pin 0 adj2 21599999"/>
|
||||
*
|
||||
* <p>
|
||||
* Usage: "pin x y z" = if (y < x), then x = value of this guide
|
||||
* else if (y > z), then z = value of this guide
|
||||
* else y = value of this guide
|
||||
* </p>
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class PinExpression implements Expression {
|
||||
private String arg1, arg2, arg3;
|
||||
|
||||
PinExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
arg3 = m.group(3);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
double z = ctx.getValue(arg3);
|
||||
if(y < x) return x;
|
||||
else if (y > z) return z;
|
||||
else return y;
|
||||
}
|
||||
|
||||
}
|
@ -23,21 +23,17 @@ import java.awt.geom.Path2D;
|
||||
|
||||
import org.apache.poi.sl.draw.binding.CTAdjPoint2D;
|
||||
|
||||
/**
|
||||
* Date: 10/25/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class QuadToCommand implements PathCommand {
|
||||
private String arg1, arg2, arg3, arg4;
|
||||
|
||||
QuadToCommand(CTAdjPoint2D pt1, CTAdjPoint2D pt2){
|
||||
arg1 = pt1.getX().toString();
|
||||
arg2 = pt1.getY().toString();
|
||||
arg3 = pt2.getX().toString();
|
||||
arg4 = pt2.getY().toString();
|
||||
arg1 = pt1.getX();
|
||||
arg2 = pt1.getY();
|
||||
arg3 = pt2.getX();
|
||||
arg4 = pt2.getY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Path2D.Double path, Context ctx){
|
||||
double x1 = ctx.getValue(arg1);
|
||||
double y1 = ctx.getValue(arg2);
|
||||
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Sine ArcTan Formula:
|
||||
* <gd name="dy1" fmla="sat2 x y z"/>
|
||||
*
|
||||
* <p>
|
||||
* Arguments: 3 (fmla="sat2 x y z")
|
||||
* Usage: "sat2 x y z" = (x*sin(arctan(z / y))) = value of this guide
|
||||
* </p>
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class SinArcTanExpression implements Expression {
|
||||
private String arg1, arg2, arg3;
|
||||
|
||||
SinArcTanExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
arg3 = m.group(3);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
double z = ctx.getValue(arg3);
|
||||
return x*Math.sin(Math.atan(z / y));
|
||||
}
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Sine Formula:
|
||||
* <gd name="z" fmla="sin x y"/>
|
||||
*
|
||||
* <p>
|
||||
* Arguments: 2 (fmla="sin x y")
|
||||
* Usage: "sin x y" = (x * sin( y )) = value of this guide
|
||||
* </p>
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class SinExpression implements Expression {
|
||||
private String arg1, arg2;
|
||||
|
||||
SinExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2) / 60000;
|
||||
return x * Math.sin(Math.toRadians(y));
|
||||
}
|
||||
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Square Root Formula:
|
||||
* <gd name="x" fmla="sqrt y"/>
|
||||
*
|
||||
* <p>
|
||||
* Arguments: 1 (fmla="sqrt x")
|
||||
* Usage: "sqrt x" = sqrt(x) = value of this guide
|
||||
* </p>
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class SqrtExpression implements Expression {
|
||||
private String arg;
|
||||
|
||||
SqrtExpression(Matcher m){
|
||||
arg =m.group(1);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double val = ctx.getValue(arg);
|
||||
return Math.sqrt(val);
|
||||
}
|
||||
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* ====================================================================
|
||||
* 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.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.apache.poi.sl.draw.geom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Tangent Formula:
|
||||
*
|
||||
* <gd name="z" fmla="tan x y"/>
|
||||
*
|
||||
* <p>
|
||||
* Arguments: 2 (fmla="tan x y")
|
||||
* Usage: "tan x y" = (x * tan( y )) = value of this guide
|
||||
* </p>
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class TanExpression implements Expression {
|
||||
private String arg1, arg2;
|
||||
|
||||
TanExpression(Matcher m){
|
||||
arg1 = m.group(1);
|
||||
arg2 = m.group(2);
|
||||
}
|
||||
|
||||
public double evaluate(Context ctx){
|
||||
double x = ctx.getValue(arg1);
|
||||
double y = ctx.getValue(arg2);
|
||||
return x * Math.tan(Math.toRadians(y / 60000));
|
||||
}
|
||||
|
||||
}
|
@ -17,6 +17,9 @@
|
||||
|
||||
package org.apache.poi.sl.usermodel;
|
||||
|
||||
/**
|
||||
* This interface is the counterpart to {@link StrokeStyle} - it's specifies the filling of a shape
|
||||
*/
|
||||
public interface FillStyle {
|
||||
PaintStyle getPaint();
|
||||
}
|
||||
|
@ -22,12 +22,30 @@ import java.io.InputStream;
|
||||
|
||||
|
||||
public interface PaintStyle {
|
||||
/**
|
||||
* The PaintStyle can be modified by secondary sources, e.g. the attributes in the preset shapes.
|
||||
* These modifications need to be taken into account when the final color is determined.
|
||||
*/
|
||||
enum PaintModifier {
|
||||
/** don't use any paint/fill */
|
||||
NONE,
|
||||
/** use the paint/filling as-is */
|
||||
NORM,
|
||||
/** lighten the paint/filling */
|
||||
LIGHTEN,
|
||||
/** lighten (... a bit less) the paint/filling */
|
||||
LIGHTEN_LESS,
|
||||
/** darken the paint/filling */
|
||||
DARKEN,
|
||||
/** darken (... a bit less) the paint/filling */
|
||||
DARKEN_LESS;
|
||||
}
|
||||
|
||||
public interface SolidPaint extends PaintStyle {
|
||||
interface SolidPaint extends PaintStyle {
|
||||
ColorStyle getSolidColor();
|
||||
}
|
||||
|
||||
public interface GradientPaint extends PaintStyle {
|
||||
interface GradientPaint extends PaintStyle {
|
||||
enum GradientType { linear, circular, shape }
|
||||
|
||||
/**
|
||||
@ -40,7 +58,7 @@ public interface PaintStyle {
|
||||
GradientType getGradientType();
|
||||
}
|
||||
|
||||
public interface TexturePaint extends PaintStyle {
|
||||
interface TexturePaint extends PaintStyle {
|
||||
/**
|
||||
* @return the raw image stream
|
||||
*/
|
||||
|
@ -17,6 +17,9 @@
|
||||
|
||||
package org.apache.poi.sl.usermodel;
|
||||
|
||||
/**
|
||||
* This interface specifies the line style of a shape
|
||||
*/
|
||||
public interface StrokeStyle {
|
||||
enum LineCap {
|
||||
/** Rounded ends */
|
||||
|
@ -632,8 +632,8 @@ public class TestXSLFTextShape {
|
||||
assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign());
|
||||
assertEquals("Calibri", r1.getFontFamily());
|
||||
assertEquals(12.0, r1.getFontSize(), 0);
|
||||
// TODO calculation of tint is incorrect
|
||||
assertTrue(sameColor(new Color(64,64,64), r1.getFontColor()));
|
||||
// TODO calculation of tint might be incorrect
|
||||
assertTrue(sameColor(new Color(191,191,191), r1.getFontColor()));
|
||||
|
||||
XSLFTextShape dt = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_DT);
|
||||
assertEquals("Friday, October 21, 2011", dt.getText());
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user