[DEBUG] generation is opk, except the gradiant reflect that have some errors.
This commit is contained in:
parent
9a8e73d883
commit
fb91ff5cbf
@ -67,7 +67,7 @@ public class Base {
|
|||||||
|
|
||||||
Base(final PaintState parentPaintState) {
|
Base(final PaintState parentPaintState) {
|
||||||
// copy the parent painting properties ...
|
// copy the parent painting properties ...
|
||||||
this.paint = parentPaintState;
|
this.paint = parentPaintState.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void display(final int spacing) {}
|
void display(final int spacing) {}
|
||||||
@ -119,14 +119,14 @@ public class Base {
|
|||||||
Pair<Color, String> localColor = new Pair<>(Color.WHITE, "");
|
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.length() > 4 && inputData.charAt(0) == 'u' && inputData.charAt(1) == 'r' && inputData.charAt(2) == 'l' && inputData.charAt(3) == '(') {
|
||||||
if (inputData.charAt(4) == '#') {
|
if (inputData.charAt(4) == '#') {
|
||||||
String color = inputData.substring(5);
|
String color = inputData.substring(5, inputData.length() - 1);
|
||||||
localColor = new Pair<>(Color.NONE, color);
|
localColor = new Pair<>(Color.NONE, color);
|
||||||
} else {
|
} else {
|
||||||
Log.error("Problem in parsing the color : '" + inputData + "' == > url(XXX) is not supported now ...");
|
Log.error("Problem in parsing the color : '" + inputData + "' == > url(XXX) is not supported now ...");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
localColor = new Pair<>(Color.valueOf(inputData), "");
|
localColor = new Pair<>(Color.valueOf256(inputData), "");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -169,50 +169,48 @@ public class Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair<Float, Distance> parseLength2(final String dataInput) {
|
Pair<Float, Distance> parseLength2(String config) {
|
||||||
Log.verbose(" lenght : '" + dataInput + "'");
|
|
||||||
float n = Float.parseFloat(dataInput);
|
Distance type = Distance.PIXEL;
|
||||||
String unit = "";
|
if (config.endsWith("%")) {
|
||||||
for (int iii = 0; iii < dataInput.length(); ++iii) {
|
type = Distance.POURCENT;
|
||||||
if ((dataInput.charAt(iii) >= '0' && dataInput.charAt(iii) <= '9') || dataInput.charAt(iii) == '+' || dataInput.charAt(iii) == '-' || dataInput.charAt(iii) == '.') {
|
config = config.substring(0, config.length() - 1);
|
||||||
continue;
|
} else if (config.endsWith("px")) {
|
||||||
}
|
type = Distance.PIXEL;
|
||||||
unit = dataInput.substring(iii);
|
config = config.substring(0, config.length() - 2);
|
||||||
break;
|
} 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);
|
final float tmp = Float.parseFloat(config);
|
||||||
// note : ";" is for the parsing of the style elements ...
|
return new Pair<>(tmp, type);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -237,6 +235,7 @@ public class Base {
|
|||||||
} else {
|
} else {
|
||||||
if (content.length() != 0) {
|
if (content.length() != 0) {
|
||||||
this.paint.stroke = parseColor(content);
|
this.paint.stroke = parseColor(content);
|
||||||
|
Log.error("Parse color : " + this.paint.stroke);
|
||||||
}
|
}
|
||||||
content = element.getAttribute("stroke-width", "");
|
content = element.getAttribute("stroke-width", "");
|
||||||
if (content.length() != 0) {
|
if (content.length() != 0) {
|
||||||
|
@ -133,7 +133,7 @@ public class EsvgDocument extends Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Base getReference(final String name) {
|
public Base getReference(final String name) {
|
||||||
if (name == "") {
|
if (name.isEmpty()) {
|
||||||
Log.error("request a reference with no name ... ");
|
Log.error("request a reference with no name ... ");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ public class EsvgDocument extends Base {
|
|||||||
if (it == null) {
|
if (it == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (it.getId() == name) {
|
if (it.getId().equals(name)) {
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.atriasoft.esvg;
|
package org.atriasoft.esvg;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.atriasoft.esvg.internal.Log;
|
import org.atriasoft.esvg.internal.Log;
|
||||||
@ -15,7 +16,7 @@ import org.atriasoft.exml.model.XmlNode;
|
|||||||
* @license MPL v2.0 (see license file)
|
* @license MPL v2.0 (see license file)
|
||||||
*/
|
*/
|
||||||
public class Group extends Base {
|
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) {
|
public Group(final PaintState parentPaintState) {
|
||||||
super(parentPaintState);
|
super(parentPaintState);
|
||||||
@ -25,7 +26,7 @@ public class Group extends Base {
|
|||||||
public void display(final int spacing) {
|
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
|
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);
|
+ " stroke-width=" + this.paint.strokeWidth);
|
||||||
for (Base it : this.subElementList) {
|
for (final Base it : this.subElementList) {
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
it.display(spacing + 1);
|
it.display(spacing + 1);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ public class LinearGradient extends Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Pair<Float, Color>> getColors(final EsvgDocument document) {
|
public List<Pair<Float, Color>> getColors(final EsvgDocument document) {
|
||||||
if (this.href == "") {
|
if (this.href.isEmpty()) {
|
||||||
return this.data;
|
return this.data;
|
||||||
}
|
}
|
||||||
if (document == null) {
|
if (document == null) {
|
||||||
@ -99,16 +99,16 @@ public class LinearGradient extends Base {
|
|||||||
|
|
||||||
String contentX = element.getAttribute("x1", "");
|
String contentX = element.getAttribute("x1", "");
|
||||||
String contentY = element.getAttribute("y1", "");
|
String contentY = element.getAttribute("y1", "");
|
||||||
if (contentX != "" && contentY != "") {
|
if (!contentX.isEmpty() && !contentY.isEmpty()) {
|
||||||
this.pos1 = new Dimension(new Vector2f(Float.parseFloat(contentX), Float.parseFloat(contentY)));
|
this.pos1 = Dimension.valueOf(contentX, contentY);
|
||||||
}
|
}
|
||||||
contentX = element.getAttribute("x2", "");
|
contentX = element.getAttribute("x2", "");
|
||||||
contentY = element.getAttribute("y2", "");
|
contentY = element.getAttribute("y2", "");
|
||||||
if (contentX != "" && contentY != "") {
|
if (!contentX.isEmpty() && !contentY.isEmpty()) {
|
||||||
this.pos2 = new Dimension(new Vector2f(Float.parseFloat(contentX), Float.parseFloat(contentY)));
|
this.pos2 = Dimension.valueOf(contentX, contentY);
|
||||||
}
|
}
|
||||||
contentX = element.getAttribute("gradientUnits", "");
|
contentX = element.getAttribute("gradientUnits", "");
|
||||||
if (contentX == "userSpaceOnUse") {
|
if (contentX.equals("userSpaceOnUse")) {
|
||||||
this.unit = GradientUnits.gradientUnitsuserSpaceOnUse;
|
this.unit = GradientUnits.gradientUnitsuserSpaceOnUse;
|
||||||
} else {
|
} else {
|
||||||
this.unit = GradientUnits.gradientUnitsobjectBoundingBox;
|
this.unit = GradientUnits.gradientUnitsobjectBoundingBox;
|
||||||
@ -117,13 +117,13 @@ public class LinearGradient extends Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
contentX = element.getAttribute("spreadMethod", "");
|
contentX = element.getAttribute("spreadMethod", "");
|
||||||
if (contentX == "reflect") {
|
if (contentX.equals("reflect")) {
|
||||||
this.spread = SpreadMethod.REFLECT;
|
this.spread = SpreadMethod.REFLECT;
|
||||||
} else if (contentX == "repeat") {
|
} else if (contentX.equals("repeat")) {
|
||||||
this.spread = SpreadMethod.REPEAT;
|
this.spread = SpreadMethod.REPEAT;
|
||||||
} else {
|
} else {
|
||||||
this.spread = SpreadMethod.PAD;
|
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");
|
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 :
|
// parse all sub node :
|
||||||
for (XmlNode it : element.getNodes()) {
|
for (XmlNode it : element.getNodes()) {
|
||||||
if (it instanceof XmlElement child) {
|
if (it instanceof XmlElement child) {
|
||||||
if (child.getValue() == "stop") {
|
if (child.getValue().equals("stop")) {
|
||||||
float offset = 100;
|
float offset = 100;
|
||||||
Color stopColor = Color.NONE;
|
Color stopColor = Color.NONE;
|
||||||
String content = child.getAttribute("offset", "");
|
String content = child.getAttribute("offset", "");
|
||||||
@ -169,7 +169,7 @@ public class LinearGradient extends Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.data.size() != 0) {
|
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");
|
Log.error(" node can not have an xlink:href element with sub node named: stop ==> removing href");
|
||||||
this.href = "";
|
this.href = "";
|
||||||
}
|
}
|
||||||
|
@ -29,4 +29,20 @@ public class PaintState {
|
|||||||
this.miterLimit = 4.0f;
|
this.miterLimit = 4.0f;
|
||||||
this.opacity = 1.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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import org.atriasoft.esvg.render.DynamicColor;
|
|||||||
import org.atriasoft.esvg.render.SegmentList;
|
import org.atriasoft.esvg.render.SegmentList;
|
||||||
import org.atriasoft.etk.math.Matrix2x3f;
|
import org.atriasoft.etk.math.Matrix2x3f;
|
||||||
import org.atriasoft.etk.math.Vector2f;
|
import org.atriasoft.etk.math.Vector2f;
|
||||||
|
import org.atriasoft.etk.math.Vector2i;
|
||||||
import org.atriasoft.etk.util.Dynamic;
|
import org.atriasoft.etk.util.Dynamic;
|
||||||
import org.atriasoft.exml.model.XmlElement;
|
import org.atriasoft.exml.model.XmlElement;
|
||||||
import org.atriasoft.exml.parser.Tools;
|
import org.atriasoft.exml.parser.Tools;
|
||||||
@ -24,11 +25,11 @@ import org.atriasoft.exml.parser.Tools;
|
|||||||
public class Path extends Base {
|
public class Path extends Base {
|
||||||
private record Command(
|
private record Command(
|
||||||
char cmd,
|
char cmd,
|
||||||
float[] listDot,
|
String[] listElem,
|
||||||
int offset) {
|
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.cmd = cmd;
|
||||||
this.listDot = listDot;
|
this.listElem = listElem;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ public class Path extends Base {
|
|||||||
StringBuilder out = new StringBuilder(input.length());
|
StringBuilder out = new StringBuilder(input.length());
|
||||||
boolean haveSpace = false;
|
boolean haveSpace = false;
|
||||||
for (char it : input.toCharArray()) {
|
for (char it : input.toCharArray()) {
|
||||||
if (it == ' ' || it == '\t' || it == '\t' || it == '\r') {
|
if (it == ' ' || it == '\t' || it == '\r') {
|
||||||
haveSpace = true;
|
haveSpace = true;
|
||||||
} else {
|
} else {
|
||||||
if (haveSpace) {
|
if (haveSpace) {
|
||||||
@ -56,52 +57,48 @@ public class Path extends Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//return the next char position ... (after 'X' or NULL)
|
//return the next char position ... (after 'X' or NULL)
|
||||||
private static Command extractCmd(final char[] input, final int offset) {
|
private static Command extractCmd(final List<String> input, final int offset) {
|
||||||
if (input[offset] == '\0') {
|
if (input.size() <= offset) {
|
||||||
|
// Log.warning("parse command : END");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
char cmd = '\0';
|
// Log.warning("parse command : (rest) " + offset);
|
||||||
if (!((input[offset] <= 'Z' && input[offset] >= 'A') || (input[offset] <= 'z' && input[offset] >= 'a'))) {
|
// for (int iii = offset; iii < input.size(); iii++) {
|
||||||
Log.error("Error in the SVG Path : '" + input + "' [" + offset);
|
// 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;
|
return null;
|
||||||
}
|
}
|
||||||
cmd = input[0];
|
char cmd = input.get(offset).charAt(0);
|
||||||
Log.verbose("Find command : " + cmd);
|
if (!((cmd <= 'Z' && cmd >= 'A') || (cmd <= 'z' && cmd >= 'a'))) {
|
||||||
if (input[offset + 1] == '\0') {
|
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);
|
return new Command(cmd, offset + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder tmpData = new StringBuilder();
|
|
||||||
List<String> elements = new ArrayList<>();
|
|
||||||
int iii;
|
int iii;
|
||||||
for (iii = offset; iii < input.length; iii++) {
|
for (iii = offset + 1; iii < input.size(); iii++) {
|
||||||
if (Tools.checkNumber(input[iii], iii == offset)) {
|
char startElem = input.get(iii).charAt(0);
|
||||||
tmpData.append(input[iii]);
|
if ((startElem <= 'Z' && startElem >= 'A') || (startElem <= 'z' && startElem >= 'a')) {
|
||||||
continue;
|
// 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 length = iii - (offset + 1);
|
||||||
int jjj = 0;
|
if (length == 0) {
|
||||||
for (String ekems : elements) {
|
return new Command(cmd, null, iii + 1);
|
||||||
outputList[jjj++] = Float.parseFloat(ekems);
|
|
||||||
}
|
}
|
||||||
// remove after white space...
|
String[] outputList = new String[length];
|
||||||
for (; iii < input.length; iii++) {
|
for (int jjj = 0; jjj < length; jjj++) {
|
||||||
if (input[iii] == ' ' || input[iii] == '\t' || input[iii] == '\n' || input[iii] == '\r') {
|
outputList[jjj] = input.get(offset + 1 + jjj);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
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) {
|
public Path(final PaintState parentPaintState) {
|
||||||
super(parentPaintState);
|
super(parentPaintState);
|
||||||
@ -190,41 +187,47 @@ public class Path extends Base {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Log.verbose("Parse Path : \"" + elementXML1 + "\"");
|
Log.verbose("Parse Path : \"" + elementXML1 + "\"");
|
||||||
|
List<String> commandsSplited = splitCommand(elementXML1);
|
||||||
float[] listDot = null;
|
String[] listDot = null;
|
||||||
elementXML1 = Path.cleanBadSpaces(elementXML1);
|
|
||||||
char[] elementXML = elementXML1.toCharArray();
|
|
||||||
|
|
||||||
// TODO REWORK this, can be done with a simple split and search in a list...
|
// 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;
|
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) {
|
switch (sss.cmd) {
|
||||||
case 'm': // Move to (relative)
|
case 'm': // Move to (relative)
|
||||||
relative = true;
|
relative = true;
|
||||||
case 'M': // Move to (absolute)
|
case 'M': // Move to (absolute)
|
||||||
// 2 Elements ...
|
if (listDot == null) {
|
||||||
if (listDot.length % 2 != 0) {
|
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot);
|
||||||
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (listDot.length >= 2) {
|
// 2 Elements ...
|
||||||
this.listElement.moveTo(relative, new Vector2f(listDot[0], listDot[1]));
|
if (listDot.length >= 1) {
|
||||||
|
this.listElement.moveTo(relative, Vector2f.valueOf(listDot[0]));
|
||||||
}
|
}
|
||||||
for (int iii = 2; iii < listDot.length; iii += 2) {
|
for (int iii = 1; iii < listDot.length; iii++) {
|
||||||
this.listElement.lineTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]));
|
this.listElement.lineTo(relative, Vector2f.valueOf(listDot[iii]));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'l': // Line to (relative)
|
case 'l': // Line to (relative)
|
||||||
relative = true;
|
relative = true;
|
||||||
case 'L': // Line to (absolute)
|
case 'L': // Line to (absolute)
|
||||||
// 2 Elements ...
|
if (listDot == null) {
|
||||||
if (listDot.length % 2 != 0) {
|
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot);
|
||||||
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (int iii = 0; iii < listDot.length; iii += 2) {
|
for (int iii = 0; iii < listDot.length; iii++) {
|
||||||
this.listElement.lineTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]));
|
this.listElement.lineTo(relative, Vector2f.valueOf(listDot[iii]));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -232,12 +235,12 @@ public class Path extends Base {
|
|||||||
relative = true;
|
relative = true;
|
||||||
case 'V': // Vertical Line to (absolute)
|
case 'V': // Vertical Line to (absolute)
|
||||||
// 1 Element ...
|
// 1 Element ...
|
||||||
if (listDot.length == 0) {
|
if (listDot == null) {
|
||||||
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
|
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (int iii = 0; iii < listDot.length; iii += 1) {
|
for (int iii = 0; iii < listDot.length; iii++) {
|
||||||
this.listElement.lineToV(relative, listDot[iii]);
|
this.listElement.lineToV(relative, Float.parseFloat(listDot[iii]));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -245,25 +248,29 @@ public class Path extends Base {
|
|||||||
relative = true;
|
relative = true;
|
||||||
case 'H': // Horizantal Line to (absolute)
|
case 'H': // Horizantal Line to (absolute)
|
||||||
// 1 Element ...
|
// 1 Element ...
|
||||||
if (listDot.length == 0) {
|
if (listDot == null) {
|
||||||
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
|
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (int iii = 0; iii < listDot.length; iii += 1) {
|
for (int iii = 0; iii < listDot.length; iii++) {
|
||||||
this.listElement.lineToH(relative, listDot[iii]);
|
this.listElement.lineToH(relative, Float.parseFloat(listDot[iii]));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'q': // Quadratic Bezier curve (relative)
|
case 'q': // Quadratic Bezier curve (relative)
|
||||||
relative = true;
|
relative = true;
|
||||||
case 'Q': // Quadratic Bezier curve (absolute)
|
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 ...
|
// 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);
|
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (int iii = 0; iii < listDot.length; iii += 4) {
|
for (int iii = 0; iii < listDot.length; iii += 2) {
|
||||||
this.listElement.bezierCurveTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]), new Vector2f(listDot[iii + 2], listDot[iii + 3]));
|
this.listElement.bezierCurveTo(relative, Vector2f.valueOf(listDot[iii]), Vector2f.valueOf(listDot[iii + 1]));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -271,68 +278,75 @@ public class Path extends Base {
|
|||||||
relative = true;
|
relative = true;
|
||||||
case 'T': // smooth quadratic Bezier curve to (absolute)
|
case 'T': // smooth quadratic Bezier curve to (absolute)
|
||||||
// 2 Elements ...
|
// 2 Elements ...
|
||||||
if (listDot.length % 2 != 0) {
|
for (int iii = 0; iii < listDot.length; iii++) {
|
||||||
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
|
this.listElement.bezierSmoothCurveTo(relative, Vector2f.valueOf(listDot[iii]));
|
||||||
break;
|
|
||||||
}
|
|
||||||
for (int iii = 0; iii < listDot.length; iii += 2) {
|
|
||||||
this.listElement.bezierSmoothCurveTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c': // curve to (relative)
|
case 'c': // curve to (relative)
|
||||||
relative = true;
|
relative = true;
|
||||||
case 'C': // curve to (absolute)
|
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 ...
|
// 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);
|
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (int iii = 0; iii < listDot.length; iii += 6) {
|
for (int iii = 0; iii < listDot.length; iii += 3) {
|
||||||
this.listElement.curveTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]), new Vector2f(listDot[iii + 2], listDot[iii + 3]),
|
this.listElement.curveTo(relative, Vector2f.valueOf(listDot[iii]), Vector2f.valueOf(listDot[iii + 1]), Vector2f.valueOf(listDot[iii + 2]));
|
||||||
new Vector2f(listDot[iii + 4], listDot[iii + 5]));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's': // smooth curve to (relative)
|
case 's': // smooth curve to (relative)
|
||||||
relative = true;
|
relative = true;
|
||||||
case 'S': // smooth curve to (absolute)
|
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 ...
|
// 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);
|
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (int iii = 0; iii < listDot.length; iii += 4) {
|
for (int iii = 0; iii < listDot.length; iii += 2) {
|
||||||
this.listElement.smoothCurveTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]), new Vector2f(listDot[iii + 2], listDot[iii + 3]));
|
this.listElement.smoothCurveTo(relative, Vector2f.valueOf(listDot[iii]), Vector2f.valueOf(listDot[iii + 1]));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'a': // elliptical Arc (relative)
|
case 'a': // elliptical Arc (relative)
|
||||||
relative = true;
|
relative = true;
|
||||||
case 'A': // elliptical Arc (absolute)
|
case 'A': // elliptical Arc (absolute)
|
||||||
// 7 Elements ...
|
if (listDot == null) {
|
||||||
if (listDot.length % 7 != 0) {
|
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);
|
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (int iii = 0; iii < listDot.length; iii += 7) {
|
for (int iii = 0; iii < listDot.length; iii += 7) {
|
||||||
boolean largeArcFlag = true;
|
boolean largeArcFlag = true;
|
||||||
boolean sweepFlag = true;
|
boolean sweepFlag = true;
|
||||||
if (listDot[iii + 3] == 0.0f) {
|
Vector2i tmp = Vector2i.valueOf(listDot[iii + 2]);
|
||||||
|
if (tmp.x() == 0) {
|
||||||
largeArcFlag = false;
|
largeArcFlag = false;
|
||||||
}
|
}
|
||||||
if (listDot[iii + 4] == 0.0f) {
|
if (tmp.y() == 0) {
|
||||||
sweepFlag = false;
|
sweepFlag = false;
|
||||||
}
|
}
|
||||||
this.listElement.ellipticTo(relative, new Vector2f(listDot[iii], listDot[iii + 1]), listDot[iii + 2], largeArcFlag, sweepFlag,
|
this.listElement.ellipticTo(relative, Vector2f.valueOf(listDot[iii]), Float.parseFloat(listDot[iii + 1]), largeArcFlag, sweepFlag, Vector2f.valueOf(listDot[iii + 3]));
|
||||||
new Vector2f(listDot[iii + 5], listDot[iii + 6]));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'z': // closepath (relative)
|
case 'z': // closepath (relative)
|
||||||
relative = true;
|
relative = true;
|
||||||
case 'Z': // closepath (absolute)
|
case 'Z': // closepath (absolute)
|
||||||
// 0 Element ...
|
// 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);
|
Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -346,4 +360,45 @@ public class Path extends Base {
|
|||||||
return true;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import org.atriasoft.esvg.internal.Log;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class Polygon extends Base {
|
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) {
|
public Polygon(final PaintState parentPaintState) {
|
||||||
super(parentPaintState);
|
super(parentPaintState);
|
||||||
|
@ -52,7 +52,7 @@ public class RadialGradient extends Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Pair<Float, Color>> getColors(final EsvgDocument document) {
|
public List<Pair<Float, Color>> getColors(final EsvgDocument document) {
|
||||||
if (this.href == "") {
|
if (this.href.isEmpty()) {
|
||||||
return this.data;
|
return this.data;
|
||||||
}
|
}
|
||||||
if (document == null) {
|
if (document == null) {
|
||||||
@ -100,20 +100,20 @@ public class RadialGradient extends Base {
|
|||||||
|
|
||||||
String contentX = element.getAttribute("cx", "");
|
String contentX = element.getAttribute("cx", "");
|
||||||
String contentY = element.getAttribute("cy", "");
|
String contentY = element.getAttribute("cy", "");
|
||||||
if (contentX != "" && contentY != "") {
|
if (!contentX.isEmpty() && !contentY.isEmpty()) {
|
||||||
this.center = new Dimension(new Vector2f(Float.parseFloat(contentX), Float.parseFloat(contentY)));
|
this.center = Dimension.valueOf(contentX, contentY);
|
||||||
}
|
}
|
||||||
contentX = element.getAttribute("r", "");
|
contentX = element.getAttribute("r", "");
|
||||||
if (contentX != "") {
|
if (contentX != "") {
|
||||||
this.radius = new Dimension1D(Float.parseFloat(contentX));
|
this.radius = Dimension1D.valueOf(contentX);
|
||||||
}
|
}
|
||||||
contentX = element.getAttribute("fx", "");
|
contentX = element.getAttribute("fx", "");
|
||||||
contentY = element.getAttribute("fy", "");
|
contentY = element.getAttribute("fy", "");
|
||||||
if (contentX != "" && contentY != "") {
|
if (!contentX.isEmpty() && !contentY.isEmpty()) {
|
||||||
this.focal = new Dimension(new Vector2f(Float.parseFloat(contentX), Float.parseFloat(contentY)));
|
this.focal = Dimension.valueOf(contentX, contentY);
|
||||||
}
|
}
|
||||||
contentX = element.getAttribute("gradientUnits", "");
|
contentX = element.getAttribute("gradientUnits", "");
|
||||||
if (contentX == "userSpaceOnUse") {
|
if (contentX.equals("userSpaceOnUse")) {
|
||||||
this.unit = GradientUnits.gradientUnitsuserSpaceOnUse;
|
this.unit = GradientUnits.gradientUnitsuserSpaceOnUse;
|
||||||
} else {
|
} else {
|
||||||
this.unit = GradientUnits.gradientUnitsobjectBoundingBox;
|
this.unit = GradientUnits.gradientUnitsobjectBoundingBox;
|
||||||
@ -122,13 +122,13 @@ public class RadialGradient extends Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
contentX = element.getAttribute("spreadMethod", "");
|
contentX = element.getAttribute("spreadMethod", "");
|
||||||
if (contentX == "reflect") {
|
if (contentX.equals("reflect")) {
|
||||||
this.spread = SpreadMethod.REFLECT;
|
this.spread = SpreadMethod.REFLECT;
|
||||||
} else if (contentX == "repeat") {
|
} else if (contentX.equals("repeat")) {
|
||||||
this.spread = SpreadMethod.REPEAT;
|
this.spread = SpreadMethod.REPEAT;
|
||||||
} else {
|
} else {
|
||||||
this.spread = SpreadMethod.PAD;
|
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");
|
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 :
|
// parse all sub node :
|
||||||
for (XmlNode it : element.getNodes()) {
|
for (XmlNode it : element.getNodes()) {
|
||||||
if (it instanceof XmlElement child) {
|
if (it instanceof XmlElement child) {
|
||||||
if (child.getValue() == "stop") {
|
if (child.getValue().equals("stop")) {
|
||||||
float offset = 100;
|
float offset = 100;
|
||||||
Color stopColor = Color.NONE;
|
Color stopColor = Color.NONE;
|
||||||
String content = child.getAttribute("offset", "");
|
String content = child.getAttribute("offset", "");
|
||||||
@ -174,7 +174,7 @@ public class RadialGradient extends Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.data.size() != 0) {
|
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");
|
Log.error("node can not have an xlink:href element with sub node named: stop ==> removing href");
|
||||||
this.href = "";
|
this.href = "";
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ import org.atriasoft.etk.util.ArraysTools;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class Renderer {
|
public class Renderer {
|
||||||
private static final boolean DEBUG_MODE = true;
|
private static final boolean DEBUG_MODE = false;
|
||||||
protected Color[][] buffer; // for debug
|
protected Color[][] buffer; // for debug
|
||||||
protected EsvgDocument document; // for debug
|
protected EsvgDocument document; // for debug
|
||||||
|
|
||||||
@ -205,8 +205,8 @@ public class Renderer {
|
|||||||
Color intermediateColor = mergeColor(intermediateColorFill, intermediateColorStroke);
|
Color intermediateColor = mergeColor(intermediateColorFill, intermediateColorStroke);
|
||||||
intermediateColor = intermediateColor.withA(intermediateColor.a() * opacity);
|
intermediateColor = intermediateColor.withA(intermediateColor.a() * opacity);
|
||||||
if (Renderer.DEBUG_MODE) {
|
if (Renderer.DEBUG_MODE) {
|
||||||
for (int deltaY = 0; deltaY < this.factor; ++deltaY) {
|
for (int deltaY = 0; deltaY < this.factor; deltaY++) {
|
||||||
for (int deltaX = 0; deltaX < this.factor; ++deltaX) {
|
for (int deltaX = 0; deltaX < this.factor; deltaX++) {
|
||||||
int idx = xxx * this.factor + deltaX;
|
int idx = xxx * this.factor + deltaX;
|
||||||
int idy = yyy * this.factor + deltaY;
|
int idy = yyy * this.factor + deltaY;
|
||||||
this.buffer[idy][idx] = mergeColor(this.buffer[idy][idx], intermediateColor);
|
this.buffer[idy][idx] = mergeColor(this.buffer[idy][idx], intermediateColor);
|
||||||
@ -257,9 +257,9 @@ public class Renderer {
|
|||||||
public void setSize(final Vector2i size) {
|
public void setSize(final Vector2i size) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
if (Renderer.DEBUG_MODE) {
|
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 {
|
} 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);
|
ArraysTools.fill2(this.buffer, Color.NONE);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import org.atriasoft.etk.util.Pair;
|
|||||||
import org.atriasoft.etk.math.Matrix2x3f;
|
import org.atriasoft.etk.math.Matrix2x3f;
|
||||||
import org.atriasoft.etk.math.Vector2f;
|
import org.atriasoft.etk.math.Vector2f;
|
||||||
import org.atriasoft.esvg.EsvgDocument;
|
import org.atriasoft.esvg.EsvgDocument;
|
||||||
|
import org.atriasoft.esvg.internal.Log;
|
||||||
import org.atriasoft.etk.Color;
|
import org.atriasoft.etk.Color;
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
@ -20,6 +21,7 @@ public interface DynamicColor {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (color.second.isEmpty()) {
|
if (color.second.isEmpty()) {
|
||||||
|
Log.error("use stroke color :" + color);
|
||||||
return new DynamicColorUni(color.first);
|
return new DynamicColorUni(color.first);
|
||||||
}
|
}
|
||||||
return new DynamicColorSpecial(color.second, mtx);
|
return new DynamicColorSpecial(color.second, mtx);
|
||||||
|
@ -65,7 +65,7 @@ public class DynamicColorSpecial implements DynamicColor {
|
|||||||
distToIntersection = FMath.sqrt(radius * radius - distToCenter * distToCenter);
|
distToIntersection = FMath.sqrt(radius * radius - distToCenter * distToCenter);
|
||||||
}
|
}
|
||||||
// normalize...
|
// normalize...
|
||||||
v1.safeNormalize();
|
v1 = v1.safeNormalize();
|
||||||
v1 = v1.multiply(distToIntersection);
|
v1 = v1.multiply(distToIntersection);
|
||||||
return new Pair<>(midpt.add(v1), midpt.less(v1));
|
return new Pair<>(midpt.add(v1), midpt.less(v1));
|
||||||
}
|
}
|
||||||
@ -396,7 +396,7 @@ public class DynamicColorSpecial implements DynamicColor {
|
|||||||
// nothing to do ...
|
// nothing to do ...
|
||||||
break;
|
break;
|
||||||
case REFLECT:
|
case REFLECT:
|
||||||
ratio -= ((int) (ratio) >> 1) + 1;
|
ratio -= (((int) (ratio)) >> 1) + 1;
|
||||||
if (ratio > 1.0f) {
|
if (ratio > 1.0f) {
|
||||||
ratio = 2.0f - ratio;
|
ratio = 2.0f - ratio;
|
||||||
}
|
}
|
||||||
|
@ -149,8 +149,8 @@ public class PathModel {
|
|||||||
// Remove the last point if it is the same position...
|
// Remove the last point if it is the same position...
|
||||||
Vector2f delta = (tmpListPoint.get(0).pos.less(tmpListPoint.get(tmpListPoint.size() - 1).pos)).abs();
|
Vector2f delta = (tmpListPoint.get(0).pos.less(tmpListPoint.get(tmpListPoint.size() - 1).pos)).abs();
|
||||||
if (delta.x() <= 0.00001 && delta.y() <= 0.00001) {
|
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);
|
Log.verbose(" Remove point Z property : " + tmpListPoint.get(tmpListPoint.size() - 1).pos + " with delta=" + delta);
|
||||||
|
tmpListPoint.remove(tmpListPoint.size() - 1);
|
||||||
}
|
}
|
||||||
out.addList(tmpListPoint);
|
out.addList(tmpListPoint);
|
||||||
tmpListPoint = new ArrayList<>();
|
tmpListPoint = new ArrayList<>();
|
||||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.atriasoft.etk.math.Vector2f;
|
import org.atriasoft.etk.math.Vector2f;
|
||||||
|
import org.atriasoft.etk.util.Dynamic;
|
||||||
import org.atriasoft.etk.util.Pair;
|
import org.atriasoft.etk.util.Pair;
|
||||||
import org.atriasoft.etk.math.FMath;
|
import org.atriasoft.etk.math.FMath;
|
||||||
import org.atriasoft.etk.math.Matrix2x3f;
|
import org.atriasoft.etk.math.Matrix2x3f;
|
||||||
@ -50,8 +51,10 @@ public class SegmentList {
|
|||||||
this.data.add(new Segment(pos0.pos, pos1.pos));
|
this.data.add(new Segment(pos0.pos, pos1.pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO is it really needed...
|
|
||||||
void addSegment(final Vector2f pos0, final Vector2f pos1) {
|
void addSegment(final Vector2f pos0, final Vector2f pos1) {
|
||||||
|
if (pos0.y() == pos1.y()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.data.add(new Segment(pos0, pos1));
|
this.data.add(new Segment(pos0, pos1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +80,7 @@ public class SegmentList {
|
|||||||
// normal edge * end path
|
// normal edge * end path
|
||||||
// (mitter) * | * * * * * * * * * * * * * *
|
// (mitter) * | * * * * * * * * * * * * * *
|
||||||
// * |<--*----this | *
|
// * |<--*----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);
|
//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);
|
Vector2f vecA = itListPoint.get(idCurrent).pos.less(itListPoint.get(idPevious).pos);
|
||||||
//Log.debug("JOIN : vecA : " + vecA);
|
//Log.debug("JOIN : vecA : " + vecA);
|
||||||
vecA.safeNormalize();
|
vecA = vecA.safeNormalize();
|
||||||
Vector2f vecB = itListPoint.get(idNext).pos.less(itListPoint.get(idCurrent).pos);
|
Vector2f vecB = itListPoint.get(idNext).pos.less(itListPoint.get(idCurrent).pos);
|
||||||
//Log.debug("JOIN : vecB : " + vecB);
|
//Log.debug("JOIN : vecB : " + vecB);
|
||||||
vecB.safeNormalize();
|
vecB = vecB.safeNormalize();
|
||||||
Vector2f vecC = vecA.less(vecB);
|
Vector2f vecC = vecA.less(vecB);
|
||||||
//Log.debug("JOIN : vecC : " + vecC);
|
//Log.debug("JOIN : vecC : " + vecC);
|
||||||
if (vecC.isZero()) {
|
if (vecC.isZero()) {
|
||||||
// special case: 1 line ...
|
// special case: 1 line ...
|
||||||
itListPoint.get(idCurrent).miterAxe = new Vector2f(vecA.y(), vecA.x());
|
itListPoint.get(idCurrent).miterAxe = new Vector2f(vecA.y(), vecA.x());
|
||||||
} else {
|
} else {
|
||||||
vecC.safeNormalize();
|
vecC = vecC.safeNormalize();
|
||||||
itListPoint.get(idCurrent).miterAxe = vecC;
|
itListPoint.get(idCurrent).miterAxe = vecC;
|
||||||
}
|
}
|
||||||
itListPoint.get(idCurrent).posPrevious = itListPoint.get(idPevious).pos;
|
itListPoint.get(idCurrent).posPrevious = itListPoint.get(idPevious).pos;
|
||||||
itListPoint.get(idCurrent).posNext = itListPoint.get(idNext).pos;
|
itListPoint.get(idCurrent).posNext = itListPoint.get(idNext).pos;
|
||||||
vecB = itListPoint.get(idNext).pos.less(itListPoint.get(idCurrent).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());
|
itListPoint.get(idCurrent).orthoAxeNext = new Vector2f(vecB.y(), -vecB.x());
|
||||||
vecB = itListPoint.get(idCurrent).pos.less(itListPoint.get(idPevious).pos);
|
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());
|
itListPoint.get(idCurrent).orthoAxePrevious = new Vector2f(vecB.y(), -vecB.x());
|
||||||
//Log.debug("JOIN : miterAxe " + itListPoint.get(idCurrent).miterAxe);
|
//Log.debug("JOIN : miterAxe " + itListPoint.get(idCurrent).miterAxe);
|
||||||
} else if (itListPoint.get(idCurrent).type == PointType.start) {
|
} else if (itListPoint.get(idCurrent).type == PointType.start) {
|
||||||
itListPoint.get(idCurrent).posNext = itListPoint.get(idNext).pos;
|
itListPoint.get(idCurrent).posNext = itListPoint.get(idNext).pos;
|
||||||
Vector2f vecB = itListPoint.get(idNext).pos.less(itListPoint.get(idCurrent).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).miterAxe = new Vector2f(vecB.y(), -vecB.x());
|
||||||
itListPoint.get(idCurrent).orthoAxePrevious = itListPoint.get(idCurrent).miterAxe;
|
itListPoint.get(idCurrent).orthoAxePrevious = itListPoint.get(idCurrent).miterAxe;
|
||||||
itListPoint.get(idCurrent).orthoAxeNext = 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;
|
itListPoint.get(idCurrent).posPrevious = itListPoint.get(idPevious).pos;
|
||||||
Vector2f vecA = itListPoint.get(idCurrent).pos.less(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).miterAxe = new Vector2f(vecA.y(), -vecA.x());
|
||||||
itListPoint.get(idCurrent).orthoAxePrevious = itListPoint.get(idCurrent).miterAxe;
|
itListPoint.get(idCurrent).orthoAxePrevious = itListPoint.get(idCurrent).miterAxe;
|
||||||
itListPoint.get(idCurrent).orthoAxeNext = itListPoint.get(idCurrent).miterAxe;
|
itListPoint.get(idCurrent).orthoAxeNext = itListPoint.get(idCurrent).miterAxe;
|
||||||
@ -150,35 +153,35 @@ public class SegmentList {
|
|||||||
// create segment list:
|
// create segment list:
|
||||||
boolean haveStartLine = false;
|
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.size() > 0) {
|
||||||
if (itListPoint.get(0).type == PointType.join) {
|
if (itListPoint.get(0).type == PointType.join) {
|
||||||
Point it = itListPoint.get(itListPoint.size() - 1);
|
Point it = itListPoint.get(itListPoint.size() - 1);
|
||||||
// Calculate the perpendiculary axis ...
|
// Calculate the perpendicular axis ...
|
||||||
leftPoint = it.pos.add(it.orthoAxePrevious.multiply(width * 0.5f));
|
leftPoint.value = it.pos.add(it.orthoAxePrevious.multiply(width * 0.5f));
|
||||||
rightPoint = it.pos.less(it.orthoAxePrevious.multiply(width * 0.5f));
|
rightPoint.value = it.pos.less(it.orthoAxePrevious.multiply(width * 0.5f));
|
||||||
// cyclic path...
|
// cyclic path...
|
||||||
if (it.type == PointType.interpolation) {
|
if (it.type == PointType.interpolation) {
|
||||||
leftPoint = SegmentList.getIntersect(leftPoint, 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 = SegmentList.getIntersect(rightPoint, 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) {
|
} else if (it.type == PointType.join) {
|
||||||
// Calculate the perpendiculary axis ...
|
// Calculate the perpendicular axis ...
|
||||||
leftPoint = it.pos.add(it.orthoAxePrevious.multiply(width * 0.5f));
|
leftPoint.value = it.pos.add(it.orthoAxePrevious.multiply(width * 0.5f));
|
||||||
rightPoint = it.pos.less(it.orthoAxePrevious.multiply(width * 0.5f));
|
rightPoint.value = it.pos.less(it.orthoAxePrevious.multiply(width * 0.5f));
|
||||||
// project on the miter Axis ...
|
// project on the miter Axis ...
|
||||||
switch (join) {
|
switch (join) {
|
||||||
case MITER: {
|
case MITER: {
|
||||||
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 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);
|
||||||
// Check the miter limit:
|
// Check the miter limit:
|
||||||
float limitRight = (left.less(it.pos)).length() / width * 2.0f;
|
float limitRight = (left.less(it.pos)).length() / width * 2.0f;
|
||||||
float limitLeft = (right.less(it.pos)).length() / width * 2.0f;
|
float limitLeft = (right.less(it.pos)).length() / width * 2.0f;
|
||||||
Log.verbose(" miter Limit: " + limitRight + " " + limitLeft + " <= " + miterLimit);
|
Log.verbose(" miter Limit: " + limitRight + " " + limitLeft + " <= " + miterLimit);
|
||||||
if (limitRight <= miterLimit && limitLeft <= miterLimit) {
|
if (limitRight <= miterLimit && limitLeft <= miterLimit) {
|
||||||
leftPoint = left;
|
leftPoint.value = left;
|
||||||
rightPoint = right;
|
rightPoint.value = right;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,11 +191,11 @@ public class SegmentList {
|
|||||||
Vector2f axeNext = (it.posNext.less(it.pos)).safeNormalize();
|
Vector2f axeNext = (it.posNext.less(it.pos)).safeNormalize();
|
||||||
float cross = axePrevious.cross(axeNext);
|
float cross = axePrevious.cross(axeNext);
|
||||||
if (cross > 0.0f) {
|
if (cross > 0.0f) {
|
||||||
rightPoint = SegmentList.getIntersect(rightPoint, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
|
rightPoint.value = SegmentList.getIntersect(rightPoint.value, it.pos.less(it.posPrevious), it.pos, it.miterAxe);
|
||||||
leftPoint = it.pos.add(it.orthoAxeNext.multiply(width * 0.5f));
|
leftPoint.value = it.pos.add(it.orthoAxeNext.multiply(width * 0.5f));
|
||||||
} else {
|
} else {
|
||||||
leftPoint = SegmentList.getIntersect(leftPoint, 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 = it.pos.less(it.orthoAxeNext.multiply(width * 0.5f));
|
rightPoint.value = it.pos.less(it.orthoAxeNext.multiply(width * 0.5f));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -215,7 +218,7 @@ public class SegmentList {
|
|||||||
if (haveStartLine) {
|
if (haveStartLine) {
|
||||||
// close previous :
|
// close previous :
|
||||||
Log.warning(" find a non close path ...");
|
Log.warning(" find a non close path ...");
|
||||||
addSegment(leftPoint, rightPoint);
|
addSegment(leftPoint.value, rightPoint.value);
|
||||||
}
|
}
|
||||||
haveStartLine = true;
|
haveStartLine = true;
|
||||||
startStopPoint(leftPoint, rightPoint, it, cap, width, true);
|
startStopPoint(leftPoint, rightPoint, it, cap, width, true);
|
||||||
@ -231,35 +234,35 @@ public class SegmentList {
|
|||||||
break;
|
break;
|
||||||
case interpolation: {
|
case interpolation: {
|
||||||
Log.verbose("Find interpolation " + it.pos);
|
Log.verbose("Find interpolation " + it.pos);
|
||||||
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 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);
|
||||||
//Draw from previous point:
|
//Draw from previous point:
|
||||||
addSegment(leftPoint, left);
|
addSegment(leftPoint.value, left);
|
||||||
Log.verbose(" segment :" + leftPoint + " . " + left);
|
Log.verbose(" segment :" + leftPoint + " . " + left);
|
||||||
addSegment(right, rightPoint);
|
addSegment(right, rightPoint.value);
|
||||||
Log.verbose(" segment :" + right + " . " + rightPoint);
|
Log.verbose(" segment :" + right + " . " + rightPoint);
|
||||||
leftPoint = left;
|
leftPoint.value = left;
|
||||||
rightPoint = right;
|
rightPoint.value = right;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case join:
|
case join:
|
||||||
Log.verbose("Find join " + it.pos);
|
Log.verbose("Find join " + it.pos);
|
||||||
switch (join) {
|
switch (join) {
|
||||||
case MITER: {
|
case MITER: {
|
||||||
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 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);
|
||||||
// Check the miter limit:
|
// Check the miter limit:
|
||||||
float limitRight = left.less(it.pos).length() / width * 2.0f;
|
float limitRight = left.less(it.pos).length() / width * 2.0f;
|
||||||
float limitLeft = right.less(it.pos).length() / width * 2.0f;
|
float limitLeft = right.less(it.pos).length() / width * 2.0f;
|
||||||
Log.verbose(" miter Limit: " + limitRight + " " + limitLeft + " <= " + miterLimit);
|
Log.verbose(" miter Limit: " + limitRight + " " + limitLeft + " <= " + miterLimit);
|
||||||
if (limitRight <= miterLimit && limitLeft <= miterLimit) {
|
if (limitRight <= miterLimit && limitLeft <= miterLimit) {
|
||||||
//Draw from previous point:
|
//Draw from previous point:
|
||||||
addSegment(leftPoint, left);
|
addSegment(leftPoint.value, left);
|
||||||
Log.verbose(" segment :" + leftPoint + " . " + left);
|
Log.verbose(" segment :" + leftPoint + " . " + left);
|
||||||
addSegment(right, rightPoint);
|
addSegment(right, rightPoint.value);
|
||||||
Log.verbose(" segment :" + right + " . " + rightPoint);
|
Log.verbose(" segment :" + right + " . " + rightPoint);
|
||||||
leftPoint = left;
|
leftPoint.value = left;
|
||||||
rightPoint = right;
|
rightPoint.value = right;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Log.verbose(" Find miter Limit ... ==> create BEVEL");
|
Log.verbose(" Find miter Limit ... ==> create BEVEL");
|
||||||
@ -270,11 +273,11 @@ public class SegmentList {
|
|||||||
Vector2f axeNext = (it.posNext.less(it.pos)).safeNormalize();
|
Vector2f axeNext = (it.posNext.less(it.pos)).safeNormalize();
|
||||||
float cross = axePrevious.cross(axeNext);
|
float cross = axePrevious.cross(axeNext);
|
||||||
if (cross > 0.0f) {
|
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 left1 = it.pos.add(it.orthoAxePrevious.multiply(width * 0.5f));
|
||||||
Vector2f left2 = it.pos.add(it.orthoAxeNext.multiply(width * 0.5f));
|
Vector2f left2 = it.pos.add(it.orthoAxeNext.multiply(width * 0.5f));
|
||||||
//Draw from previous point:
|
//Draw from previous point:
|
||||||
addSegment(leftPoint, left1);
|
addSegment(leftPoint.value, left1);
|
||||||
Log.verbose(" segment :" + leftPoint + " . " + left1);
|
Log.verbose(" segment :" + leftPoint + " . " + left1);
|
||||||
if (join != JoinMode.ROUND) {
|
if (join != JoinMode.ROUND) {
|
||||||
// Miter and bevel:
|
// Miter and bevel:
|
||||||
@ -283,18 +286,18 @@ public class SegmentList {
|
|||||||
} else {
|
} else {
|
||||||
createSegmentListStroke(left1, left2, it.pos, width, false);
|
createSegmentListStroke(left1, left2, it.pos, width, false);
|
||||||
}
|
}
|
||||||
addSegment(right, rightPoint);
|
addSegment(right, rightPoint.value);
|
||||||
Log.verbose(" segment :" + right + " . " + rightPoint);
|
Log.verbose(" segment :" + right + " . " + rightPoint);
|
||||||
leftPoint = left2;
|
leftPoint.value = left2;
|
||||||
rightPoint = right;
|
rightPoint.value = right;
|
||||||
} else {
|
} 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 right1 = it.pos.less(it.orthoAxePrevious.multiply(width * 0.5f));
|
||||||
Vector2f right2 = it.pos.less(it.orthoAxeNext.multiply(width * 0.5f));
|
Vector2f right2 = it.pos.less(it.orthoAxeNext.multiply(width * 0.5f));
|
||||||
//Draw from previous point:
|
//Draw from previous point:
|
||||||
addSegment(leftPoint, left);
|
addSegment(leftPoint.value, left);
|
||||||
Log.verbose(" segment :" + leftPoint + " . " + left);
|
Log.verbose(" segment :" + leftPoint + " . " + left);
|
||||||
addSegment(right1, rightPoint);
|
addSegment(right1, rightPoint.value);
|
||||||
Log.verbose(" segment :" + right1 + " . " + rightPoint);
|
Log.verbose(" segment :" + right1 + " . " + rightPoint);
|
||||||
if (join != JoinMode.ROUND) {
|
if (join != JoinMode.ROUND) {
|
||||||
// Miter and bevel:
|
// Miter and bevel:
|
||||||
@ -303,8 +306,8 @@ public class SegmentList {
|
|||||||
} else {
|
} else {
|
||||||
createSegmentListStroke(right1, right2, it.pos, width, true);
|
createSegmentListStroke(right1, right2, it.pos, width, true);
|
||||||
}
|
}
|
||||||
leftPoint = left;
|
leftPoint.value = left;
|
||||||
rightPoint = right2;
|
rightPoint.value = right2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -369,26 +372,26 @@ public class SegmentList {
|
|||||||
return out;
|
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) {
|
switch (cap) {
|
||||||
case BUTT: {
|
case BUTT: {
|
||||||
Vector2f left = point.pos.add(point.miterAxe.multiply(width * 0.5f));
|
Vector2f left = point.pos.add(point.miterAxe.multiply(width * 0.5f));
|
||||||
Vector2f right = point.pos.less(point.miterAxe.multiply(width * 0.5f));
|
Vector2f right = point.pos.less(point.miterAxe.multiply(width * 0.5f));
|
||||||
if (!isStart) {
|
if (!isStart) {
|
||||||
//Draw from previous point:
|
//Draw from previous point:
|
||||||
addSegment(leftPoint, left);
|
addSegment(leftPoint.value, left);
|
||||||
Log.verbose(" segment :" + leftPoint + " . " + left);
|
Log.verbose(" segment :" + leftPoint + " . " + left);
|
||||||
addSegment(right, rightPoint);
|
addSegment(right, rightPoint.value);
|
||||||
Log.verbose(" segment :" + right + " . " + rightPoint);
|
Log.verbose(" segment :" + right + " . " + rightPoint);
|
||||||
}
|
}
|
||||||
leftPoint = left;
|
leftPoint.value = left;
|
||||||
rightPoint = right;
|
rightPoint.value = right;
|
||||||
}
|
}
|
||||||
if (!isStart) {
|
if (!isStart) {
|
||||||
addSegment(leftPoint, rightPoint);
|
addSegment(leftPoint.value, rightPoint.value);
|
||||||
Log.verbose(" segment :" + leftPoint + " . " + rightPoint);
|
Log.verbose(" segment :" + leftPoint + " . " + rightPoint);
|
||||||
} else {
|
} else {
|
||||||
addSegment(rightPoint, leftPoint);
|
addSegment(rightPoint.value, leftPoint.value);
|
||||||
Log.verbose(" segment :" + rightPoint + " . " + leftPoint);
|
Log.verbose(" segment :" + rightPoint + " . " + leftPoint);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -398,21 +401,21 @@ public class SegmentList {
|
|||||||
Vector2f right = point.pos.less(point.miterAxe.multiply(width * 0.5f));
|
Vector2f right = point.pos.less(point.miterAxe.multiply(width * 0.5f));
|
||||||
if (!isStart) {
|
if (!isStart) {
|
||||||
//Draw from previous point:
|
//Draw from previous point:
|
||||||
addSegment(leftPoint, left);
|
addSegment(leftPoint.value, left);
|
||||||
Log.verbose(" segment :" + leftPoint + " . " + left);
|
Log.verbose(" segment :" + leftPoint + " . " + left);
|
||||||
addSegment(right, rightPoint);
|
addSegment(right, rightPoint.value);
|
||||||
Log.verbose(" segment :" + right + " . " + rightPoint);
|
Log.verbose(" segment :" + right + " . " + rightPoint);
|
||||||
}
|
}
|
||||||
leftPoint = left;
|
leftPoint.value = left;
|
||||||
rightPoint = right;
|
rightPoint.value = right;
|
||||||
}
|
}
|
||||||
int nbDot = (int) width;
|
int nbDot = (int) width;
|
||||||
if (nbDot <= 2) {
|
if (nbDot <= 2) {
|
||||||
nbDot = 2;
|
nbDot = 2;
|
||||||
}
|
}
|
||||||
leftPoint = point.pos.add(point.miterAxe.multiply(width * 0.5f));
|
leftPoint.value = point.pos.add(point.miterAxe.multiply(width * 0.5f));
|
||||||
rightPoint = point.pos.less(point.miterAxe.multiply(width * 0.5f));
|
rightPoint.value = point.pos.less(point.miterAxe.multiply(width * 0.5f));
|
||||||
createSegmentListStroke(leftPoint, rightPoint, point.pos, width, isStart);
|
createSegmentListStroke(leftPoint.value, rightPoint.value, point.pos, width, isStart);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SQUARE: {
|
case SQUARE: {
|
||||||
@ -428,21 +431,19 @@ public class SegmentList {
|
|||||||
left = tmpMat.multiply(left);
|
left = tmpMat.multiply(left);
|
||||||
right = tmpMat.multiply(right);
|
right = tmpMat.multiply(right);
|
||||||
if (!isStart) {
|
if (!isStart) {
|
||||||
if (!isStart) {
|
//Draw from previous point:
|
||||||
//Draw from previous point:
|
addSegment(leftPoint.value, left);
|
||||||
addSegment(leftPoint, left);
|
Log.verbose(" segment :" + leftPoint + " . " + left);
|
||||||
Log.verbose(" segment :" + leftPoint + " . " + left);
|
addSegment(right, rightPoint.value);
|
||||||
addSegment(right, rightPoint);
|
Log.verbose(" segment :" + right + " . " + rightPoint);
|
||||||
Log.verbose(" segment :" + right + " . " + rightPoint);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
leftPoint = left;
|
leftPoint.value = left;
|
||||||
rightPoint = right;
|
rightPoint.value = right;
|
||||||
if (!isStart) {
|
if (!isStart) {
|
||||||
addSegment(leftPoint, rightPoint);
|
addSegment(leftPoint.value, rightPoint.value);
|
||||||
Log.verbose(" segment :" + leftPoint + " . " + rightPoint);
|
Log.verbose(" segment :" + leftPoint + " . " + rightPoint);
|
||||||
} else {
|
} else {
|
||||||
addSegment(rightPoint, leftPoint);
|
addSegment(rightPoint.value, leftPoint.value);
|
||||||
Log.verbose(" segment :" + rightPoint + " . " + leftPoint);
|
Log.verbose(" segment :" + rightPoint + " . " + leftPoint);
|
||||||
}
|
}
|
||||||
Log.verbose(" segment :" + leftPoint + " . " + rightPoint);
|
Log.verbose(" segment :" + leftPoint + " . " + rightPoint);
|
||||||
|
@ -10,11 +10,14 @@ import org.atriasoft.etk.Uri;
|
|||||||
import com.pngencoder.PngEncoder;
|
import com.pngencoder.PngEncoder;
|
||||||
|
|
||||||
public class ConfigTest {
|
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 final boolean VISUAL_DEBUG = true;
|
||||||
|
|
||||||
public static void generateAnImage(final EsvgDocument doc, final Uri uri) {
|
public static void generateAnImage(final EsvgDocument doc, final Uri uri) {
|
||||||
Color[][] data = doc.renderImageFloatRGBA(null, ConfigTest.VISUAL_DEBUG);
|
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);
|
BufferedImage bufferedImage = new BufferedImage(data[0].length, data.length, BufferedImage.TYPE_INT_ARGB);
|
||||||
for (int yyy = 0; yyy < data.length; yyy++) {
|
for (int yyy = 0; yyy < data.length; yyy++) {
|
||||||
for (int xxx = 0; xxx < data[yyy].length; xxx++) {
|
for (int xxx = 0; xxx < data[yyy].length; xxx++) {
|
||||||
|
@ -7,11 +7,20 @@ import org.junit.jupiter.api.Test;
|
|||||||
class TestGradientLinear {
|
class TestGradientLinear {
|
||||||
@Test
|
@Test
|
||||||
public void testTestGradientLinearDiag1() {
|
public void testTestGradientLinearDiag1() {
|
||||||
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n" + "<svg height='100' width='100'>\n" + " <defs>\n"
|
//@formatter:off
|
||||||
+ " <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"
|
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\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"
|
+ "<svg height='100' width='100'>\n"
|
||||||
+ " <stop offset='100%' style='stop-color:rgb(255,0,255);stop-opacity:1' />\n" + " </linearGradient>\n" + " </defs>\n"
|
+ " <defs>\n"
|
||||||
+ " <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad2)' />\n" + "</svg>\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();
|
EsvgDocument doc = new EsvgDocument();
|
||||||
doc.parse(data);
|
doc.parse(data);
|
||||||
Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag1.svg"), data.replace("'", "\""));
|
Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag1.svg"), data.replace("'", "\""));
|
||||||
@ -20,10 +29,18 @@ class TestGradientLinear {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTestGradientLinearDiag1Partiel() {
|
public void testTestGradientLinearDiag1Partiel() {
|
||||||
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n" + "<svg height='100' width='100'>\n" + " <defs>\n"
|
//@formatter:off
|
||||||
+ " <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"
|
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
|
||||||
+ " <stop offset='100%' style='stop-color:rgb(0,0,255);stop-opacity:1' />\n" + " </linearGradient>\n" + " </defs>\n"
|
+ "<svg height='100' width='100'>\n"
|
||||||
+ " <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad2)' />\n" + "</svg>\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();
|
EsvgDocument doc = new EsvgDocument();
|
||||||
doc.parse(data);
|
doc.parse(data);
|
||||||
Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag1Partiel.svg"), data.replace("'", "\""));
|
Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag1Partiel.svg"), data.replace("'", "\""));
|
||||||
@ -97,11 +114,20 @@ class TestGradientLinear {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTestGradientLinearHorizontal() {
|
public void testTestGradientLinearHorizontal() {
|
||||||
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n" + "<svg height='100' width='100'>\n" + " <defs>\n"
|
//@formatter:off
|
||||||
+ " <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"
|
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\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"
|
+ "<svg height='100' width='100'>\n"
|
||||||
+ " <stop offset='100%' style='stop-color:rgb(255,0,255);stop-opacity:1' />\n" + " </linearGradient>\n" + " </defs>\n"
|
+ " <defs>\n"
|
||||||
+ " <ellipse cx='50' cy='50' rx='50' ry='20' fill='url(#grad1)' />\n" + "</svg>\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();
|
EsvgDocument doc = new EsvgDocument();
|
||||||
doc.parse(data);
|
doc.parse(data);
|
||||||
Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearhorizontal.svg"), data.replace("'", "\""));
|
Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearhorizontal.svg"), data.replace("'", "\""));
|
||||||
|
@ -2,10 +2,9 @@ package test.atriasoft.esvg;
|
|||||||
|
|
||||||
import org.atriasoft.esvg.EsvgDocument;
|
import org.atriasoft.esvg.EsvgDocument;
|
||||||
import org.atriasoft.etk.Uri;
|
import org.atriasoft.etk.Uri;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
class TestStyle {
|
class TestStyle {
|
||||||
@Test
|
|
||||||
public void testTestExternWorddown() {
|
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"
|
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"
|
+ " 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"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user