[DEBUG] generation is opk, except the gradiant reflect that have some errors.

This commit is contained in:
Edouard DUPIN 2021-04-06 01:10:39 +02:00
parent 9a8e73d883
commit fb91ff5cbf
16 changed files with 362 additions and 260 deletions

View File

@ -67,7 +67,7 @@ public class Base {
Base(final PaintState parentPaintState) {
// copy the parent painting properties ...
this.paint = parentPaintState;
this.paint = parentPaintState.clone();
}
void display(final int spacing) {}
@ -119,14 +119,14 @@ public class Base {
Pair<Color, String> localColor = new Pair<>(Color.WHITE, "");
if (inputData.length() > 4 && inputData.charAt(0) == 'u' && inputData.charAt(1) == 'r' && inputData.charAt(2) == 'l' && inputData.charAt(3) == '(') {
if (inputData.charAt(4) == '#') {
String color = inputData.substring(5);
String color = inputData.substring(5, inputData.length() - 1);
localColor = new Pair<>(Color.NONE, color);
} else {
Log.error("Problem in parsing the color : '" + inputData + "' == > url(XXX) is not supported now ...");
}
} else {
try {
localColor = new Pair<>(Color.valueOf(inputData), "");
localColor = new Pair<>(Color.valueOf256(inputData), "");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
@ -169,50 +169,48 @@ public class Base {
}
}
Pair<Float, Distance> parseLength2(final String dataInput) {
Log.verbose(" lenght : '" + dataInput + "'");
float n = Float.parseFloat(dataInput);
String unit = "";
for (int iii = 0; iii < dataInput.length(); ++iii) {
if ((dataInput.charAt(iii) >= '0' && dataInput.charAt(iii) <= '9') || dataInput.charAt(iii) == '+' || dataInput.charAt(iii) == '-' || dataInput.charAt(iii) == '.') {
continue;
}
unit = dataInput.substring(iii);
break;
Pair<Float, Distance> parseLength2(String config) {
Distance type = Distance.PIXEL;
if (config.endsWith("%")) {
type = Distance.POURCENT;
config = config.substring(0, config.length() - 1);
} else if (config.endsWith("px")) {
type = Distance.PIXEL;
config = config.substring(0, config.length() - 2);
} else if (config.endsWith("ft")) {
type = Distance.FOOT;
config = config.substring(0, config.length() - 2);
} else if (config.endsWith("in")) {
type = Distance.INCH;
config = config.substring(0, config.length() - 2);
} else if (config.endsWith("km")) {
type = Distance.KILOMETER;
config = config.substring(0, config.length() - 2);
} else if (config.endsWith("mm")) {
type = Distance.MILLIMETER;
config = config.substring(0, config.length() - 2);
} else if (config.endsWith("cm")) {
type = Distance.CENTIMETER;
config = config.substring(0, config.length() - 2);
} else if (config.endsWith("m")) {
type = Distance.METER;
config = config.substring(0, config.length() - 1);
} else if (config.endsWith("em")) {
type = Distance.ELEMENT;
config = config.substring(0, config.length() - 2);
} else if (config.endsWith("ex")) {
type = Distance.EX;
config = config.substring(0, config.length() - 2);
} else if (config.endsWith("pt")) {
type = Distance.POINT;
config = config.substring(0, config.length() - 2);
} else if (config.endsWith("pc")) {
type = Distance.PC;
config = config.substring(0, config.length() - 2);
}
Log.verbose(" lenght : '" + n + "' => unit=" + unit);
// note : ";" is for the parsing of the style elements ...
if (unit.length() == 0) {
return new Pair<>(n, Distance.PIXEL);
}
if (unit.charAt(0) == '%') { // xxx %
return new Pair<>(n, Distance.POURCENT);
}
if (unit.charAt(0) == 'e' && unit.charAt(1) == 'm') { // xxx em
return new Pair<>(n, Distance.ELEMENT);
}
if (unit.charAt(0) == 'e' && unit.charAt(1) == 'x') { // xxx ex
return new Pair<>(n, Distance.EX);
}
if (unit.charAt(0) == 'p' && unit.charAt(1) == 'x') { // xxx px
return new Pair<>(n, Distance.PIXEL);
}
if (unit.charAt(0) == 'p' && unit.charAt(1) == 't') { // xxx pt
return new Pair<>(n, Distance.POINT);
}
if (unit.charAt(0) == 'p' && unit.charAt(1) == 'c') { // xxx pc
return new Pair<>(n, Distance.PC);
}
if (unit.charAt(0) == 'm' && unit.charAt(1) == 'm') { // xxx mm
return new Pair<>(n, Distance.MILLIMETER);
}
if (unit.charAt(0) == 'c' && unit.charAt(1) == 'm') { // xxx cm
return new Pair<>(n, Distance.CENTIMETER);
}
if (unit.charAt(0) == 'i' && unit.charAt(1) == 'n') { // xxx in
return new Pair<>(n, Distance.INCH);
}
return new Pair<>(0.0f, Distance.PIXEL);
final float tmp = Float.parseFloat(config);
return new Pair<>(tmp, type);
}
/**
@ -237,6 +235,7 @@ public class Base {
} else {
if (content.length() != 0) {
this.paint.stroke = parseColor(content);
Log.error("Parse color : " + this.paint.stroke);
}
content = element.getAttribute("stroke-width", "");
if (content.length() != 0) {

View File

@ -133,7 +133,7 @@ public class EsvgDocument extends Base {
}
public Base getReference(final String name) {
if (name == "") {
if (name.isEmpty()) {
Log.error("request a reference with no name ... ");
return null;
}
@ -141,7 +141,7 @@ public class EsvgDocument extends Base {
if (it == null) {
continue;
}
if (it.getId() == name) {
if (it.getId().equals(name)) {
return it;
}
}

View File

@ -1,5 +1,6 @@
package org.atriasoft.esvg;
import java.util.ArrayList;
import java.util.List;
import org.atriasoft.esvg.internal.Log;
@ -15,7 +16,7 @@ import org.atriasoft.exml.model.XmlNode;
* @license MPL v2.0 (see license file)
*/
public class Group extends Base {
private List<Base> subElementList; //!< sub elements ...
private final List<Base> subElementList = new ArrayList<>(); //!< sub elements ...
public Group(final PaintState parentPaintState) {
super(parentPaintState);
@ -25,7 +26,7 @@ public class Group extends Base {
public void display(final int spacing) {
Log.debug(spacingDist(spacing) + "Group (START) fill=" + this.paint.fill.first + "/" + this.paint.fill.second + " stroke=" + this.paint.stroke.first + "/" + this.paint.stroke.second
+ " stroke-width=" + this.paint.strokeWidth);
for (Base it : this.subElementList) {
for (final Base it : this.subElementList) {
if (it != null) {
it.display(spacing + 1);
}

View File

@ -50,7 +50,7 @@ public class LinearGradient extends Base {
}
public List<Pair<Float, Color>> getColors(final EsvgDocument document) {
if (this.href == "") {
if (this.href.isEmpty()) {
return this.data;
}
if (document == null) {
@ -99,16 +99,16 @@ public class LinearGradient extends Base {
String contentX = element.getAttribute("x1", "");
String contentY = element.getAttribute("y1", "");
if (contentX != "" && contentY != "") {
this.pos1 = new Dimension(new Vector2f(Float.parseFloat(contentX), Float.parseFloat(contentY)));
if (!contentX.isEmpty() && !contentY.isEmpty()) {
this.pos1 = Dimension.valueOf(contentX, contentY);
}
contentX = element.getAttribute("x2", "");
contentY = element.getAttribute("y2", "");
if (contentX != "" && contentY != "") {
this.pos2 = new Dimension(new Vector2f(Float.parseFloat(contentX), Float.parseFloat(contentY)));
if (!contentX.isEmpty() && !contentY.isEmpty()) {
this.pos2 = Dimension.valueOf(contentX, contentY);
}
contentX = element.getAttribute("gradientUnits", "");
if (contentX == "userSpaceOnUse") {
if (contentX.equals("userSpaceOnUse")) {
this.unit = GradientUnits.gradientUnitsuserSpaceOnUse;
} else {
this.unit = GradientUnits.gradientUnitsobjectBoundingBox;
@ -117,13 +117,13 @@ public class LinearGradient extends Base {
}
}
contentX = element.getAttribute("spreadMethod", "");
if (contentX == "reflect") {
if (contentX.equals("reflect")) {
this.spread = SpreadMethod.REFLECT;
} else if (contentX == "repeat") {
} else if (contentX.equals("repeat")) {
this.spread = SpreadMethod.REPEAT;
} else {
this.spread = SpreadMethod.PAD;
if (contentX.length() != 0 && contentX != "pad") {
if (contentX.length() != 0 && !contentX.equals("pad")) {
Log.error("Parsing error of 'spreadMethod' ==> not suported value: '" + contentX + "' not in : {reflect/repeate/pad} use pad");
}
}
@ -135,7 +135,7 @@ public class LinearGradient extends Base {
// parse all sub node :
for (XmlNode it : element.getNodes()) {
if (it instanceof XmlElement child) {
if (child.getValue() == "stop") {
if (child.getValue().equals("stop")) {
float offset = 100;
Color stopColor = Color.NONE;
String content = child.getAttribute("offset", "");
@ -169,7 +169,7 @@ public class LinearGradient extends Base {
}
}
if (this.data.size() != 0) {
if (this.href != "") {
if (!this.href.isEmpty()) {
Log.error(" node can not have an xlink:href element with sub node named: stop ==> removing href");
this.href = "";
}

View File

@ -29,4 +29,20 @@ public class PaintState {
this.miterLimit = 4.0f;
this.opacity = 1.0f;
}
@Override
protected PaintState clone() {
PaintState out = new PaintState();
out.fill = this.fill;
out.stroke = this.stroke;
out.strokeWidth = this.strokeWidth;
out.viewPort = this.viewPort;
out.flagEvenOdd = this.flagEvenOdd;
out.lineJoin = this.lineJoin;
out.lineCap = this.lineCap;
out.miterLimit = this.miterLimit;
out.opacity = this.opacity;
return out;
}
}

View File

@ -12,6 +12,7 @@ import org.atriasoft.esvg.render.DynamicColor;
import org.atriasoft.esvg.render.SegmentList;
import org.atriasoft.etk.math.Matrix2x3f;
import org.atriasoft.etk.math.Vector2f;
import org.atriasoft.etk.math.Vector2i;
import org.atriasoft.etk.util.Dynamic;
import org.atriasoft.exml.model.XmlElement;
import org.atriasoft.exml.parser.Tools;
@ -24,11 +25,11 @@ import org.atriasoft.exml.parser.Tools;
public class Path extends Base {
private record Command(
char cmd,
float[] listDot,
String[] listElem,
int offset) {
Command(final char cmd, final float[] listDot, final int offset) {
Command(final char cmd, final String[] listElem, final int offset) {
this.cmd = cmd;
this.listDot = listDot;
this.listElem = listElem;
this.offset = offset;
}
@ -42,7 +43,7 @@ public class Path extends Base {
StringBuilder out = new StringBuilder(input.length());
boolean haveSpace = false;
for (char it : input.toCharArray()) {
if (it == ' ' || it == '\t' || it == '\t' || it == '\r') {
if (it == ' ' || it == '\t' || it == '\r') {
haveSpace = true;
} else {
if (haveSpace) {
@ -56,52 +57,48 @@ public class Path extends Base {
}
//return the next char position ... (after 'X' or NULL)
private static Command extractCmd(final char[] input, final int offset) {
if (input[offset] == '\0') {
private static Command extractCmd(final List<String> input, final int offset) {
if (input.size() <= offset) {
// Log.warning("parse command : END");
return null;
}
char cmd = '\0';
if (!((input[offset] <= 'Z' && input[offset] >= 'A') || (input[offset] <= 'z' && input[offset] >= 'a'))) {
Log.error("Error in the SVG Path : '" + input + "' [" + offset);
// Log.warning("parse command : (rest) " + offset);
// for (int iii = offset; iii < input.size(); iii++) {
// Log.warning(" -[" + iii + "] '" + input.get(iii) + "'");
// }
if (input.get(offset).length() != 1) {
Log.error("Error in the SVG Path : '" + input.get(offset) + "' [" + offset);
return null;
}
cmd = input[0];
Log.verbose("Find command : " + cmd);
if (input[offset + 1] == '\0') {
char cmd = input.get(offset).charAt(0);
if (!((cmd <= 'Z' && cmd >= 'A') || (cmd <= 'z' && cmd >= 'a'))) {
Log.error("Error in the SVG Path : '" + cmd + "' [" + offset);
return null;
}
//Log.verbose("Find command : " + cmd);
if (input.size() == offset) {
return new Command(cmd, offset + 1);
}
StringBuilder tmpData = new StringBuilder();
List<String> elements = new ArrayList<>();
int iii;
for (iii = offset; iii < input.length; iii++) {
if (Tools.checkNumber(input[iii], iii == offset)) {
tmpData.append(input[iii]);
continue;
for (iii = offset + 1; iii < input.size(); iii++) {
char startElem = input.get(iii).charAt(0);
if ((startElem <= 'Z' && startElem >= 'A') || (startElem <= 'z' && startElem >= 'a')) {
// find end of elements
break;
}
elements.add(tmpData.toString());
tmpData.setLength(0);
if (input[iii] == ' ' || input[iii] == '\t' || input[iii] == '\n' || input[iii] == '\r' || input[iii] == ',' || input[iii] == ';') {
continue;
}
break;
}
float[] outputList = new float[elements.size()];
int jjj = 0;
for (String ekems : elements) {
outputList[jjj++] = Float.parseFloat(ekems);
int length = iii - (offset + 1);
if (length == 0) {
return new Command(cmd, null, iii + 1);
}
// remove after white space...
for (; iii < input.length; iii++) {
if (input[iii] == ' ' || input[iii] == '\t' || input[iii] == '\n' || input[iii] == '\r') {
continue;
}
break;
String[] outputList = new String[length];
for (int jjj = 0; jjj < length; jjj++) {
outputList[jjj] = input.get(offset + 1 + jjj);
}
return new Command(cmd, outputList, offset + 1);
return new Command(cmd, outputList, iii);
}
public PathModel listElement;
public PathModel listElement = new PathModel();
public Path(final PaintState parentPaintState) {
super(parentPaintState);
@ -190,41 +187,47 @@ public class Path extends Base {
return false;
}
Log.verbose("Parse Path : \"" + elementXML1 + "\"");
float[] listDot = null;
elementXML1 = Path.cleanBadSpaces(elementXML1);
char[] elementXML = elementXML1.toCharArray();
List<String> commandsSplited = splitCommand(elementXML1);
String[] listDot = null;
// TODO REWORK this, can be done with a simple split and search in a list...
for (Command sss = Path.extractCmd(elementXML, 0); sss != null; sss = Path.extractCmd(elementXML, sss.offset())) {
for (Command sss = Path.extractCmd(commandsSplited, 0); sss != null; sss = Path.extractCmd(commandsSplited, sss.offset())) {
boolean relative = false;
listDot = sss.listDot();
listDot = sss.listElem();
Log.error("Find new command : '" + sss.cmd + "'");
if (listDot != null) {
for (int jjj = 0; jjj < listDot.length; jjj++) {
Log.error(" -> '" + listDot[jjj] + "'");
}
} else {
Log.error(" -> no elements");
}
switch (sss.cmd) {
case 'm': // Move to (relative)
relative = true;
case 'M': // Move to (absolute)
// 2 Elements ...
if (listDot.length % 2 != 0) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
if (listDot == null) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot);
break;
}
if (listDot.length >= 2) {
this.listElement.moveTo(relative, new Vector2f(listDot[0], listDot[1]));
// 2 Elements ...
if (listDot.length >= 1) {
this.listElement.moveTo(relative, Vector2f.valueOf(listDot[0]));
}
for (int iii = 2; iii < listDot.length; iii += 2) {
this.listElement.lineTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]));
for (int iii = 1; iii < listDot.length; iii++) {
this.listElement.lineTo(relative, Vector2f.valueOf(listDot[iii]));
}
break;
case 'l': // Line to (relative)
relative = true;
case 'L': // Line to (absolute)
// 2 Elements ...
if (listDot.length % 2 != 0) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
if (listDot == null) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot);
break;
}
for (int iii = 0; iii < listDot.length; iii += 2) {
this.listElement.lineTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]));
for (int iii = 0; iii < listDot.length; iii++) {
this.listElement.lineTo(relative, Vector2f.valueOf(listDot[iii]));
}
break;
@ -232,12 +235,12 @@ public class Path extends Base {
relative = true;
case 'V': // Vertical Line to (absolute)
// 1 Element ...
if (listDot.length == 0) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
if (listDot == null) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot);
break;
}
for (int iii = 0; iii < listDot.length; iii += 1) {
this.listElement.lineToV(relative, listDot[iii]);
for (int iii = 0; iii < listDot.length; iii++) {
this.listElement.lineToV(relative, Float.parseFloat(listDot[iii]));
}
break;
@ -245,25 +248,29 @@ public class Path extends Base {
relative = true;
case 'H': // Horizantal Line to (absolute)
// 1 Element ...
if (listDot.length == 0) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
if (listDot == null) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot);
break;
}
for (int iii = 0; iii < listDot.length; iii += 1) {
this.listElement.lineToH(relative, listDot[iii]);
for (int iii = 0; iii < listDot.length; iii++) {
this.listElement.lineToH(relative, Float.parseFloat(listDot[iii]));
}
break;
case 'q': // Quadratic Bezier curve (relative)
relative = true;
case 'Q': // Quadratic Bezier curve (absolute)
if (listDot == null) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot);
break;
}
// 4 Elements ...
if (listDot.length % 4 != 0) {
if (listDot.length % 2 != 0) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
break;
}
for (int iii = 0; iii < listDot.length; iii += 4) {
this.listElement.bezierCurveTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]), new Vector2f(listDot[iii + 2], listDot[iii + 3]));
for (int iii = 0; iii < listDot.length; iii += 2) {
this.listElement.bezierCurveTo(relative, Vector2f.valueOf(listDot[iii]), Vector2f.valueOf(listDot[iii + 1]));
}
break;
@ -271,68 +278,75 @@ public class Path extends Base {
relative = true;
case 'T': // smooth quadratic Bezier curve to (absolute)
// 2 Elements ...
if (listDot.length % 2 != 0) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
break;
}
for (int iii = 0; iii < listDot.length; iii += 2) {
this.listElement.bezierSmoothCurveTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]));
for (int iii = 0; iii < listDot.length; iii++) {
this.listElement.bezierSmoothCurveTo(relative, Vector2f.valueOf(listDot[iii]));
}
break;
case 'c': // curve to (relative)
relative = true;
case 'C': // curve to (absolute)
if (listDot == null) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot);
break;
}
// 6 Elements ...
if (listDot.length % 6 != 0) {
if (listDot.length % 3 != 0) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
break;
}
for (int iii = 0; iii < listDot.length; iii += 6) {
this.listElement.curveTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]), new Vector2f(listDot[iii + 2], listDot[iii + 3]),
new Vector2f(listDot[iii + 4], listDot[iii + 5]));
for (int iii = 0; iii < listDot.length; iii += 3) {
this.listElement.curveTo(relative, Vector2f.valueOf(listDot[iii]), Vector2f.valueOf(listDot[iii + 1]), Vector2f.valueOf(listDot[iii + 2]));
}
break;
case 's': // smooth curve to (relative)
relative = true;
case 'S': // smooth curve to (absolute)
if (listDot == null) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot);
break;
}
// 4 Elements ...
if (listDot.length % 4 != 0) {
if (listDot.length % 2 != 0) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
break;
}
for (int iii = 0; iii < listDot.length; iii += 4) {
this.listElement.smoothCurveTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]), new Vector2f(listDot[iii + 2], listDot[iii + 3]));
for (int iii = 0; iii < listDot.length; iii += 2) {
this.listElement.smoothCurveTo(relative, Vector2f.valueOf(listDot[iii]), Vector2f.valueOf(listDot[iii + 1]));
}
break;
case 'a': // elliptical Arc (relative)
relative = true;
case 'A': // elliptical Arc (absolute)
// 7 Elements ...
if (listDot.length % 7 != 0) {
if (listDot == null) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot);
break;
}
// 4 element ff,ff f i,i ff,ff Elements ...
if (listDot.length % 4 != 0) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
break;
}
for (int iii = 0; iii < listDot.length; iii += 7) {
boolean largeArcFlag = true;
boolean sweepFlag = true;
if (listDot[iii + 3] == 0.0f) {
Vector2i tmp = Vector2i.valueOf(listDot[iii + 2]);
if (tmp.x() == 0) {
largeArcFlag = false;
}
if (listDot[iii + 4] == 0.0f) {
if (tmp.y() == 0) {
sweepFlag = false;
}
this.listElement.ellipticTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]), listDot[iii + 2], largeArcFlag, sweepFlag,
new Vector2f(listDot[iii + 5], listDot[iii + 6]));
this.listElement.ellipticTo(relative, Vector2f.valueOf(listDot[iii]), Float.parseFloat(listDot[iii + 1]), largeArcFlag, sweepFlag, Vector2f.valueOf(listDot[iii + 3]));
}
break;
case 'z': // closepath (relative)
relative = true;
case 'Z': // closepath (absolute)
// 0 Element ...
if (listDot.length != 0) {
if (listDot != null) {
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
break;
}
@ -346,4 +360,45 @@ public class Path extends Base {
return true;
}
List<String> splitCommand(final String data) {
List<String> out = new ArrayList<>();
StringBuilder tmpString = new StringBuilder(20);
boolean isText = false;
boolean isNumber = false;
for (char it : data.toCharArray()) {
if (it == ' ' || it == '\t' || it == '\r') {
String elements = tmpString.toString();
if (!elements.isEmpty()) {
out.add(elements);
}
tmpString.setLength(0);
isText = false;
isNumber = false;
} else if (Tools.checkNumber(it, true) || it == ',' || it == '.') {
if (isText) {
out.add(tmpString.toString());
tmpString.setLength(0);
}
isText = false;
isNumber = true;
tmpString.append(it);
} else if ((it <= 'Z' && it >= 'A') || (it <= 'z' && it >= 'a')) {
if (isNumber) {
out.add(tmpString.toString());
tmpString.setLength(0);
}
isText = true;
isNumber = false;
tmpString.append(it);
} else {
Log.error("Can not parse path : '" + it + "'");
}
}
String elements = tmpString.toString();
if (!elements.isEmpty()) {
out.add(elements);
}
return out;
}
}

View File

@ -23,7 +23,7 @@ import org.atriasoft.esvg.internal.Log;
*/
public class Polygon extends Base {
private List<Vector2f> listPoint; //!< list of all point of the polygone
private final List<Vector2f> listPoint = new ArrayList<>(); //!< list of all point of the polygone
public Polygon(final PaintState parentPaintState) {
super(parentPaintState);

View File

@ -52,7 +52,7 @@ public class RadialGradient extends Base {
}
public List<Pair<Float, Color>> getColors(final EsvgDocument document) {
if (this.href == "") {
if (this.href.isEmpty()) {
return this.data;
}
if (document == null) {
@ -100,20 +100,20 @@ public class RadialGradient extends Base {
String contentX = element.getAttribute("cx", "");
String contentY = element.getAttribute("cy", "");
if (contentX != "" && contentY != "") {
this.center = new Dimension(new Vector2f(Float.parseFloat(contentX), Float.parseFloat(contentY)));
if (!contentX.isEmpty() && !contentY.isEmpty()) {
this.center = Dimension.valueOf(contentX, contentY);
}
contentX = element.getAttribute("r", "");
if (contentX != "") {
this.radius = new Dimension1D(Float.parseFloat(contentX));
this.radius = Dimension1D.valueOf(contentX);
}
contentX = element.getAttribute("fx", "");
contentY = element.getAttribute("fy", "");
if (contentX != "" && contentY != "") {
this.focal = new Dimension(new Vector2f(Float.parseFloat(contentX), Float.parseFloat(contentY)));
if (!contentX.isEmpty() && !contentY.isEmpty()) {
this.focal = Dimension.valueOf(contentX, contentY);
}
contentX = element.getAttribute("gradientUnits", "");
if (contentX == "userSpaceOnUse") {
if (contentX.equals("userSpaceOnUse")) {
this.unit = GradientUnits.gradientUnitsuserSpaceOnUse;
} else {
this.unit = GradientUnits.gradientUnitsobjectBoundingBox;
@ -122,13 +122,13 @@ public class RadialGradient extends Base {
}
}
contentX = element.getAttribute("spreadMethod", "");
if (contentX == "reflect") {
if (contentX.equals("reflect")) {
this.spread = SpreadMethod.REFLECT;
} else if (contentX == "repeat") {
} else if (contentX.equals("repeat")) {
this.spread = SpreadMethod.REPEAT;
} else {
this.spread = SpreadMethod.PAD;
if (contentX.length() != 0 && contentX != "pad") {
if (contentX.length() != 0 && !contentX.equals("pad")) {
Log.error("Parsing error of 'spreadMethod' ==> not suported value: '" + contentX + "' not in : {reflect/repeate/pad} use pad");
}
}
@ -140,7 +140,7 @@ public class RadialGradient extends Base {
// parse all sub node :
for (XmlNode it : element.getNodes()) {
if (it instanceof XmlElement child) {
if (child.getValue() == "stop") {
if (child.getValue().equals("stop")) {
float offset = 100;
Color stopColor = Color.NONE;
String content = child.getAttribute("offset", "");
@ -174,7 +174,7 @@ public class RadialGradient extends Base {
}
}
if (this.data.size() != 0) {
if (this.href != "") {
if (!this.href.isEmpty()) {
Log.error("node can not have an xlink:href element with sub node named: stop ==> removing href");
this.href = "";
}

View File

@ -22,7 +22,7 @@ import org.atriasoft.etk.util.ArraysTools;
*/
public class Renderer {
private static final boolean DEBUG_MODE = true;
private static final boolean DEBUG_MODE = false;
protected Color[][] buffer; // for debug
protected EsvgDocument document; // for debug
@ -205,8 +205,8 @@ public class Renderer {
Color intermediateColor = mergeColor(intermediateColorFill, intermediateColorStroke);
intermediateColor = intermediateColor.withA(intermediateColor.a() * opacity);
if (Renderer.DEBUG_MODE) {
for (int deltaY = 0; deltaY < this.factor; ++deltaY) {
for (int deltaX = 0; deltaX < this.factor; ++deltaX) {
for (int deltaY = 0; deltaY < this.factor; deltaY++) {
for (int deltaX = 0; deltaX < this.factor; deltaX++) {
int idx = xxx * this.factor + deltaX;
int idy = yyy * this.factor + deltaY;
this.buffer[idy][idx] = mergeColor(this.buffer[idy][idx], intermediateColor);
@ -257,9 +257,9 @@ public class Renderer {
public void setSize(final Vector2i size) {
this.size = size;
if (Renderer.DEBUG_MODE) {
this.buffer = new Color[this.size.x()][this.size.y()];
this.buffer = new Color[this.size.y()][this.size.x()];
} else {
this.buffer = new Color[this.size.x() * this.factor][this.size.y() * this.factor];
this.buffer = new Color[this.size.y() * this.factor][this.size.x() * this.factor];
}
ArraysTools.fill2(this.buffer, Color.NONE);
}

View File

@ -5,6 +5,7 @@ import org.atriasoft.etk.util.Pair;
import org.atriasoft.etk.math.Matrix2x3f;
import org.atriasoft.etk.math.Vector2f;
import org.atriasoft.esvg.EsvgDocument;
import org.atriasoft.esvg.internal.Log;
import org.atriasoft.etk.Color;
/** @file
@ -20,6 +21,7 @@ public interface DynamicColor {
return null;
}
if (color.second.isEmpty()) {
Log.error("use stroke color :" + color);
return new DynamicColorUni(color.first);
}
return new DynamicColorSpecial(color.second, mtx);

View File

@ -65,7 +65,7 @@ public class DynamicColorSpecial implements DynamicColor {
distToIntersection = FMath.sqrt(radius * radius - distToCenter * distToCenter);
}
// normalize...
v1.safeNormalize();
v1 = v1.safeNormalize();
v1 = v1.multiply(distToIntersection);
return new Pair<>(midpt.add(v1), midpt.less(v1));
}
@ -396,7 +396,7 @@ public class DynamicColorSpecial implements DynamicColor {
// nothing to do ...
break;
case REFLECT:
ratio -= ((int) (ratio) >> 1) + 1;
ratio -= (((int) (ratio)) >> 1) + 1;
if (ratio > 1.0f) {
ratio = 2.0f - ratio;
}

View File

@ -149,8 +149,8 @@ public class PathModel {
// Remove the last point if it is the same position...
Vector2f delta = (tmpListPoint.get(0).pos.less(tmpListPoint.get(tmpListPoint.size() - 1).pos)).abs();
if (delta.x() <= 0.00001 && delta.y() <= 0.00001) {
tmpListPoint.remove(tmpListPoint.size() - 1);
Log.verbose(" Remove point Z property : " + tmpListPoint.get(tmpListPoint.size() - 1).pos + " with delta=" + delta);
tmpListPoint.remove(tmpListPoint.size() - 1);
}
out.addList(tmpListPoint);
tmpListPoint = new ArrayList<>();

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import org.atriasoft.etk.math.Vector2f;
import org.atriasoft.etk.util.Dynamic;
import org.atriasoft.etk.util.Pair;
import org.atriasoft.etk.math.FMath;
import org.atriasoft.etk.math.Matrix2x3f;
@ -50,8 +51,10 @@ public class SegmentList {
this.data.add(new Segment(pos0.pos, pos1.pos));
}
// TODO is it really needed...
void addSegment(final Vector2f pos0, final Vector2f pos1) {
if (pos0.y() == pos1.y()) {
return;
}
this.data.add(new Segment(pos0, pos1));
}
@ -77,7 +80,7 @@ public class SegmentList {
// normal edge * end path
// (mitter) * | * * * * * * * * * * * * * *
// * |<--*----this | *
// * | * this -.| *
// * | * this -->| *
// * * * | *
// * . | . * . . . . . . . . * *
// * . | . * | *
@ -103,32 +106,32 @@ public class SegmentList {
//Log.debug("JOIN : val : prev/curr/next : " + itListPoint.get(idPevious).pos + "/" + itListPoint.get(idCurrent).pos + "/" + itListPoint.get(idNext).pos);
Vector2f vecA = itListPoint.get(idCurrent).pos.less(itListPoint.get(idPevious).pos);
//Log.debug("JOIN : vecA : " + vecA);
vecA.safeNormalize();
vecA = vecA.safeNormalize();
Vector2f vecB = itListPoint.get(idNext).pos.less(itListPoint.get(idCurrent).pos);
//Log.debug("JOIN : vecB : " + vecB);
vecB.safeNormalize();
vecB = vecB.safeNormalize();
Vector2f vecC = vecA.less(vecB);
//Log.debug("JOIN : vecC : " + vecC);
if (vecC.isZero()) {
// special case: 1 line ...
itListPoint.get(idCurrent).miterAxe = new Vector2f(vecA.y(), vecA.x());
} else {
vecC.safeNormalize();
vecC = vecC.safeNormalize();
itListPoint.get(idCurrent).miterAxe = vecC;
}
itListPoint.get(idCurrent).posPrevious = itListPoint.get(idPevious).pos;
itListPoint.get(idCurrent).posNext = itListPoint.get(idNext).pos;
vecB = itListPoint.get(idNext).pos.less(itListPoint.get(idCurrent).pos);
vecB.safeNormalize();
vecB = vecB.safeNormalize();
itListPoint.get(idCurrent).orthoAxeNext = new Vector2f(vecB.y(), -vecB.x());
vecB = itListPoint.get(idCurrent).pos.less(itListPoint.get(idPevious).pos);
vecB.safeNormalize();
vecB = vecB.safeNormalize();
itListPoint.get(idCurrent).orthoAxePrevious = new Vector2f(vecB.y(), -vecB.x());
//Log.debug("JOIN : miterAxe " + itListPoint.get(idCurrent).miterAxe);
} else if (itListPoint.get(idCurrent).type == PointType.start) {
itListPoint.get(idCurrent).posNext = itListPoint.get(idNext).pos;
Vector2f vecB = itListPoint.get(idNext).pos.less(itListPoint.get(idCurrent).pos);
vecB.safeNormalize();
vecB = vecB.safeNormalize();
itListPoint.get(idCurrent).miterAxe = new Vector2f(vecB.y(), -vecB.x());
itListPoint.get(idCurrent).orthoAxePrevious = itListPoint.get(idCurrent).miterAxe;
itListPoint.get(idCurrent).orthoAxeNext = itListPoint.get(idCurrent).miterAxe;
@ -139,7 +142,7 @@ public class SegmentList {
}
itListPoint.get(idCurrent).posPrevious = itListPoint.get(idPevious).pos;
Vector2f vecA = itListPoint.get(idCurrent).pos.less(itListPoint.get(idPevious).pos);
vecA.safeNormalize();
vecA = vecA.safeNormalize();
itListPoint.get(idCurrent).miterAxe = new Vector2f(vecA.y(), -vecA.x());
itListPoint.get(idCurrent).orthoAxePrevious = itListPoint.get(idCurrent).miterAxe;
itListPoint.get(idCurrent).orthoAxeNext = itListPoint.get(idCurrent).miterAxe;
@ -150,35 +153,35 @@ public class SegmentList {
// create segment list:
boolean haveStartLine = false;
Vector2f leftPoint = Vector2f.ZERO;
Dynamic<Vector2f> leftPoint = new Dynamic<Vector2f>(Vector2f.ZERO);
Vector2f rightPoint = Vector2f.ZERO;
Dynamic<Vector2f> rightPoint = new Dynamic<Vector2f>(Vector2f.ZERO);
if (itListPoint.size() > 0) {
if (itListPoint.get(0).type == PointType.join) {
Point it = itListPoint.get(itListPoint.size() - 1);
// Calculate the perpendiculary axis ...
leftPoint = it.pos.add(it.orthoAxePrevious.multiply(width * 0.5f));
rightPoint = it.pos.less(it.orthoAxePrevious.multiply(width * 0.5f));
// Calculate the perpendicular axis ...
leftPoint.value = it.pos.add(it.orthoAxePrevious.multiply(width * 0.5f));
rightPoint.value = it.pos.less(it.orthoAxePrevious.multiply(width * 0.5f));
// cyclic path...
if (it.type == PointType.interpolation) {
leftPoint = SegmentList.getIntersect(leftPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
rightPoint = SegmentList.getIntersect(rightPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
leftPoint.value = SegmentList.getIntersect(leftPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
rightPoint.value = SegmentList.getIntersect(rightPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
} else if (it.type == PointType.join) {
// Calculate the perpendiculary axis ...
leftPoint = it.pos.add(it.orthoAxePrevious.multiply(width * 0.5f));
rightPoint = it.pos.less(it.orthoAxePrevious.multiply(width * 0.5f));
// Calculate the perpendicular axis ...
leftPoint.value = it.pos.add(it.orthoAxePrevious.multiply(width * 0.5f));
rightPoint.value = it.pos.less(it.orthoAxePrevious.multiply(width * 0.5f));
// project on the miter Axis ...
switch (join) {
case MITER: {
Vector2f left = SegmentList.getIntersect(leftPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f right = SegmentList.getIntersect(rightPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f left = SegmentList.getIntersect(leftPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f right = SegmentList.getIntersect(rightPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
// Check the miter limit:
float limitRight = (left.less(it.pos)).length() / width * 2.0f;
float limitLeft = (right.less(it.pos)).length() / width * 2.0f;
Log.verbose(" miter Limit: " + limitRight + " " + limitLeft + " <= " + miterLimit);
if (limitRight <= miterLimit && limitLeft <= miterLimit) {
leftPoint = left;
rightPoint = right;
leftPoint.value = left;
rightPoint.value = right;
break;
}
}
@ -188,11 +191,11 @@ public class SegmentList {
Vector2f axeNext = (it.posNext.less(it.pos)).safeNormalize();
float cross = axePrevious.cross(axeNext);
if (cross > 0.0f) {
rightPoint = SegmentList.getIntersect(rightPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
leftPoint = it.pos.add(it.orthoAxeNext.multiply(width * 0.5f));
rightPoint.value = SegmentList.getIntersect(rightPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
leftPoint.value = it.pos.add(it.orthoAxeNext.multiply(width * 0.5f));
} else {
leftPoint = SegmentList.getIntersect(leftPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
rightPoint = it.pos.less(it.orthoAxeNext.multiply(width * 0.5f));
leftPoint.value = SegmentList.getIntersect(leftPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
rightPoint.value = it.pos.less(it.orthoAxeNext.multiply(width * 0.5f));
}
break;
}
@ -215,7 +218,7 @@ public class SegmentList {
if (haveStartLine) {
// close previous :
Log.warning(" find a non close path ...");
addSegment(leftPoint, rightPoint);
addSegment(leftPoint.value, rightPoint.value);
}
haveStartLine = true;
startStopPoint(leftPoint, rightPoint, it, cap, width, true);
@ -231,35 +234,35 @@ public class SegmentList {
break;
case interpolation: {
Log.verbose("Find interpolation " + it.pos);
Vector2f left = SegmentList.getIntersect(leftPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f right = SegmentList.getIntersect(rightPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f left = SegmentList.getIntersect(leftPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f right = SegmentList.getIntersect(rightPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
//Draw from previous point:
addSegment(leftPoint, left);
addSegment(leftPoint.value, left);
Log.verbose(" segment :" + leftPoint + " . " + left);
addSegment(right, rightPoint);
addSegment(right, rightPoint.value);
Log.verbose(" segment :" + right + " . " + rightPoint);
leftPoint = left;
rightPoint = right;
leftPoint.value = left;
rightPoint.value = right;
}
break;
case join:
Log.verbose("Find join " + it.pos);
switch (join) {
case MITER: {
Vector2f left = SegmentList.getIntersect(leftPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f right = SegmentList.getIntersect(rightPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f left = SegmentList.getIntersect(leftPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f right = SegmentList.getIntersect(rightPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
// Check the miter limit:
float limitRight = left.less(it.pos).length() / width * 2.0f;
float limitLeft = right.less(it.pos).length() / width * 2.0f;
Log.verbose(" miter Limit: " + limitRight + " " + limitLeft + " <= " + miterLimit);
if (limitRight <= miterLimit && limitLeft <= miterLimit) {
//Draw from previous point:
addSegment(leftPoint, left);
addSegment(leftPoint.value, left);
Log.verbose(" segment :" + leftPoint + " . " + left);
addSegment(right, rightPoint);
addSegment(right, rightPoint.value);
Log.verbose(" segment :" + right + " . " + rightPoint);
leftPoint = left;
rightPoint = right;
leftPoint.value = left;
rightPoint.value = right;
break;
}
Log.verbose(" Find miter Limit ... ==> create BEVEL");
@ -270,11 +273,11 @@ public class SegmentList {
Vector2f axeNext = (it.posNext.less(it.pos)).safeNormalize();
float cross = axePrevious.cross(axeNext);
if (cross > 0.0f) {
Vector2f right = SegmentList.getIntersect(rightPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f right = SegmentList.getIntersect(rightPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f left1 = it.pos.add(it.orthoAxePrevious.multiply(width * 0.5f));
Vector2f left2 = it.pos.add(it.orthoAxeNext.multiply(width * 0.5f));
//Draw from previous point:
addSegment(leftPoint, left1);
addSegment(leftPoint.value, left1);
Log.verbose(" segment :" + leftPoint + " . " + left1);
if (join != JoinMode.ROUND) {
// Miter and bevel:
@ -283,18 +286,18 @@ public class SegmentList {
} else {
createSegmentListStroke(left1, left2, it.pos, width, false);
}
addSegment(right, rightPoint);
addSegment(right, rightPoint.value);
Log.verbose(" segment :" + right + " . " + rightPoint);
leftPoint = left2;
rightPoint = right;
leftPoint.value = left2;
rightPoint.value = right;
} else {
Vector2f left = SegmentList.getIntersect(leftPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f left = SegmentList.getIntersect(leftPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
Vector2f right1 = it.pos.less(it.orthoAxePrevious.multiply(width * 0.5f));
Vector2f right2 = it.pos.less(it.orthoAxeNext.multiply(width * 0.5f));
//Draw from previous point:
addSegment(leftPoint, left);
addSegment(leftPoint.value, left);
Log.verbose(" segment :" + leftPoint + " . " + left);
addSegment(right1, rightPoint);
addSegment(right1, rightPoint.value);
Log.verbose(" segment :" + right1 + " . " + rightPoint);
if (join != JoinMode.ROUND) {
// Miter and bevel:
@ -303,8 +306,8 @@ public class SegmentList {
} else {
createSegmentListStroke(right1, right2, it.pos, width, true);
}
leftPoint = left;
rightPoint = right2;
leftPoint.value = left;
rightPoint.value = right2;
}
}
break;
@ -369,26 +372,26 @@ public class SegmentList {
return out;
}
private void startStopPoint(Vector2f leftPoint, Vector2f rightPoint, final Point point, final CapMode cap, final float width, final boolean isStart) {
private void startStopPoint(final Dynamic<Vector2f> leftPoint, final Dynamic<Vector2f> rightPoint, final Point point, final CapMode cap, final float width, final boolean isStart) {
switch (cap) {
case BUTT: {
Vector2f left = point.pos.add(point.miterAxe.multiply(width * 0.5f));
Vector2f right = point.pos.less(point.miterAxe.multiply(width * 0.5f));
if (!isStart) {
//Draw from previous point:
addSegment(leftPoint, left);
addSegment(leftPoint.value, left);
Log.verbose(" segment :" + leftPoint + " . " + left);
addSegment(right, rightPoint);
addSegment(right, rightPoint.value);
Log.verbose(" segment :" + right + " . " + rightPoint);
}
leftPoint = left;
rightPoint = right;
leftPoint.value = left;
rightPoint.value = right;
}
if (!isStart) {
addSegment(leftPoint, rightPoint);
addSegment(leftPoint.value, rightPoint.value);
Log.verbose(" segment :" + leftPoint + " . " + rightPoint);
} else {
addSegment(rightPoint, leftPoint);
addSegment(rightPoint.value, leftPoint.value);
Log.verbose(" segment :" + rightPoint + " . " + leftPoint);
}
break;
@ -398,21 +401,21 @@ public class SegmentList {
Vector2f right = point.pos.less(point.miterAxe.multiply(width * 0.5f));
if (!isStart) {
//Draw from previous point:
addSegment(leftPoint, left);
addSegment(leftPoint.value, left);
Log.verbose(" segment :" + leftPoint + " . " + left);
addSegment(right, rightPoint);
addSegment(right, rightPoint.value);
Log.verbose(" segment :" + right + " . " + rightPoint);
}
leftPoint = left;
rightPoint = right;
leftPoint.value = left;
rightPoint.value = right;
}
int nbDot = (int) width;
if (nbDot <= 2) {
nbDot = 2;
}
leftPoint = point.pos.add(point.miterAxe.multiply(width * 0.5f));
rightPoint = point.pos.less(point.miterAxe.multiply(width * 0.5f));
createSegmentListStroke(leftPoint, rightPoint, point.pos, width, isStart);
leftPoint.value = point.pos.add(point.miterAxe.multiply(width * 0.5f));
rightPoint.value = point.pos.less(point.miterAxe.multiply(width * 0.5f));
createSegmentListStroke(leftPoint.value, rightPoint.value, point.pos, width, isStart);
}
break;
case SQUARE: {
@ -428,21 +431,19 @@ public class SegmentList {
left = tmpMat.multiply(left);
right = tmpMat.multiply(right);
if (!isStart) {
if (!isStart) {
//Draw from previous point:
addSegment(leftPoint, left);
Log.verbose(" segment :" + leftPoint + " . " + left);
addSegment(right, rightPoint);
Log.verbose(" segment :" + right + " . " + rightPoint);
}
//Draw from previous point:
addSegment(leftPoint.value, left);
Log.verbose(" segment :" + leftPoint + " . " + left);
addSegment(right, rightPoint.value);
Log.verbose(" segment :" + right + " . " + rightPoint);
}
leftPoint = left;
rightPoint = right;
leftPoint.value = left;
rightPoint.value = right;
if (!isStart) {
addSegment(leftPoint, rightPoint);
addSegment(leftPoint.value, rightPoint.value);
Log.verbose(" segment :" + leftPoint + " . " + rightPoint);
} else {
addSegment(rightPoint, leftPoint);
addSegment(rightPoint.value, leftPoint.value);
Log.verbose(" segment :" + rightPoint + " . " + leftPoint);
}
Log.verbose(" segment :" + leftPoint + " . " + rightPoint);

View File

@ -10,11 +10,14 @@ import org.atriasoft.etk.Uri;
import com.pngencoder.PngEncoder;
public class ConfigTest {
public static final String BASE_PATH = "./";//"~/dev/workspace-game/atriasoft/esvg/";
public static final String BASE_PATH = "./testResult/";//"~/dev/workspace-game/atriasoft/esvg/";
public static final boolean VISUAL_DEBUG = true;
public static void generateAnImage(final EsvgDocument doc, final Uri uri) {
Color[][] data = doc.renderImageFloatRGBA(null, ConfigTest.VISUAL_DEBUG);
if (data.length == 0) {
Log.critical("No data generated ...");
}
BufferedImage bufferedImage = new BufferedImage(data[0].length, data.length, BufferedImage.TYPE_INT_ARGB);
for (int yyy = 0; yyy < data.length; yyy++) {
for (int xxx = 0; xxx < data[yyy].length; xxx++) {

View File

@ -7,11 +7,20 @@ import org.junit.jupiter.api.Test;
class TestGradientLinear {
@Test
public void testTestGradientLinearDiag1() {
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n" + "<svg height='100' width='100'>\n" + " <defs>\n"
+ " <linearGradient id='grad2' x1='0%' y1='0%' x2='100%' y2='100%'>\n" + " <stop offset='0%' style='stop-color:rgb(255,0,0);stop-opacity:1' />\n"
+ " <stop offset='45%' style='stop-color:rgb(0,255,0);stop-opacity:1' />\n" + " <stop offset='55%' style='stop-color:rgb(0,0,255);stop-opacity:1' />\n"
+ " <stop offset='100%' style='stop-color:rgb(255,0,255);stop-opacity:1' />\n" + " </linearGradient>\n" + " </defs>\n"
+ " <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad2)' />\n" + "</svg>\n";
//@formatter:off
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
+ "<svg height='100' width='100'>\n"
+ " <defs>\n"
+ " <linearGradient id='grad2' x1='0%' y1='0%' x2='100%' y2='100%'>\n"
+ " <stop offset='0%' style='stop-color:rgb(255,0,0);stop-opacity:1' />\n"
+ " <stop offset='45%' style='stop-color:rgb(0,255,0);stop-opacity:1' />\n"
+ " <stop offset='55%' style='stop-color:rgb(0,0,255);stop-opacity:1' />\n"
+ " <stop offset='100%' style='stop-color:rgb(255,0,255);stop-opacity:1' />\n"
+ " </linearGradient>\n"
+ " </defs>\n"
+ " <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad2)' />\n"
+ "</svg>\n";
//@formatter:on
EsvgDocument doc = new EsvgDocument();
doc.parse(data);
Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag1.svg"), data.replace("'", "\""));
@ -20,10 +29,18 @@ class TestGradientLinear {
@Test
public void testTestGradientLinearDiag1Partiel() {
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n" + "<svg height='100' width='100'>\n" + " <defs>\n"
+ " <linearGradient id='grad2' x1='40%' y1='40%' x2='70%' y2='70%'>\n" + " <stop offset='0%' style='stop-color:rgb(0,255,0);stop-opacity:1' />\n"
+ " <stop offset='100%' style='stop-color:rgb(0,0,255);stop-opacity:1' />\n" + " </linearGradient>\n" + " </defs>\n"
+ " <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad2)' />\n" + "</svg>\n";
//@formatter:off
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
+ "<svg height='100' width='100'>\n"
+ " <defs>\n"
+ " <linearGradient id='grad2' x1='40%' y1='40%' x2='70%' y2='70%'>\n"
+ " <stop offset='0%' style='stop-color:rgb(0,255,0);stop-opacity:1' />\n"
+ " <stop offset='100%' style='stop-color:rgb(0,0,255);stop-opacity:1' />\n"
+ " </linearGradient>\n"
+ " </defs>\n"
+ " <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad2)' />\n"
+ "</svg>\n";
//@formatter:on
EsvgDocument doc = new EsvgDocument();
doc.parse(data);
Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag1Partiel.svg"), data.replace("'", "\""));
@ -97,11 +114,20 @@ class TestGradientLinear {
@Test
public void testTestGradientLinearHorizontal() {
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n" + "<svg height='100' width='100'>\n" + " <defs>\n"
+ " <linearGradient id='grad1' x1='0%' y1='0%' x2='100%' y2='0%'>\n" + " <stop offset='0%' style='stop-color:rgb(255,0,0);stop-opacity:1' />\n"
+ " <stop offset='45%' style='stop-color:rgb(0,255,0);stop-opacity:1' />\n" + " <stop offset='55%' style='stop-color:rgb(0,0,255);stop-opacity:1' />\n"
+ " <stop offset='100%' style='stop-color:rgb(255,0,255);stop-opacity:1' />\n" + " </linearGradient>\n" + " </defs>\n"
+ " <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad1)' />\n" + "</svg>\n";
//@formatter:off
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
+ "<svg height='100' width='100'>\n"
+ " <defs>\n"
+ " <linearGradient id='grad1' x1='0%' y1='0%' x2='100%' y2='0%'>\n"
+ " <stop offset='0%' style='stop-color:rgb(255,0,0);stop-opacity:1' />\n"
+ " <stop offset='45%' style='stop-color:rgb(0,255,0);stop-opacity:1' />\n"
+ " <stop offset='55%' style='stop-color:rgb(0,0,255);stop-opacity:1' />\n"
+ " <stop offset='100%' style='stop-color:rgb(255,0,255);stop-opacity:1' />\n"
+ " </linearGradient>\n"
+ " </defs>\n"
+ " <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad1)' />\n"
+ "</svg>\n";
//@formatter:on
EsvgDocument doc = new EsvgDocument();
doc.parse(data);
Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearhorizontal.svg"), data.replace("'", "\""));

View File

@ -2,10 +2,9 @@ package test.atriasoft.esvg;
import org.atriasoft.esvg.EsvgDocument;
import org.atriasoft.etk.Uri;
import org.junit.jupiter.api.Test;
class TestStyle {
@Test
public void testTestExternWorddown() {
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n" + "<!-- Created with Inkscape (http://www.inkscape.org/) -.\n" + "\n" + "<svg\n"
+ " xmlns:dc='http://purl.org/dc/elements/1.1/'\n" + " xmlns:cc='http://creativecommons.org/ns#'\n" + " xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'\n"