diff --git a/.classpath b/.classpath index 46ec0e4..41e1dcf 100644 --- a/.classpath +++ b/.classpath @@ -1,37 +1,29 @@ - - - + + + + + + + + - + + - + - + - - - - - - - - - - - - - - - - + + diff --git a/.project b/.project index 0c4903f..9489f23 100644 --- a/.project +++ b/.project @@ -1,35 +1,28 @@ - atriasoft-esvg + esvg - atriasoft-esvg + + org.python.pydev.PyDevBuilder + + + org.eclipse.jdt.core.javabuilder - net.sf.eclipsecs.core.CheckstyleBuilder + org.eclipse.m2e.core.maven2Builder org.eclipse.jdt.core.javanature - net.sf.eclipsecs.core.CheckstyleNature + org.eclipse.m2e.core.maven2Nature - - - 1646149232192 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - diff --git a/esvg.iml b/esvg.iml deleted file mode 100644 index c90834f..0000000 --- a/esvg.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/lutin_org-atriasoft-esvg.py b/lutin_org-atriasoft-esvg.py index 58492b6..251f1f6 100644 --- a/lutin_org-atriasoft-esvg.py +++ b/lutin_org-atriasoft-esvg.py @@ -38,7 +38,7 @@ def configure(target, my_module): 'src/org/atriasoft/esvg/Base.java', 'src/org/atriasoft/esvg/Text.java', 'src/org/atriasoft/esvg/RadialGradient.java', - 'src/org/atriasoft/esvg/internal/Log.java', + 'src/org/atriasoft/esvg/internal/LOGGER.java', 'src/org/atriasoft/esvg/font/Kerning.java', 'src/org/atriasoft/esvg/font/Glyph.java', 'src/org/atriasoft/esvg/Renderer.java', diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..754c59e --- /dev/null +++ b/pom.xml @@ -0,0 +1,144 @@ + + 4.0.0 + org.atriasoft + esvg + 0.1.0 + + 3.13.0 + 21 + 21 + 3.1.1 + + + + + gitea + https://gitea.atria-soft.org/api/packages/org.atriasoft/maven + + + + + gitea + https://gitea.atria-soft.org/api/packages/org.atriasoft/maven + + + gitea + https://gitea.atria-soft.org/api/packages/org.atriasoft/maven + + + + + + org.atriasoft + exml + 0.1.0 + + + org.atriasoft + png-encoder + 0.1.0 + + + org.atriasoft + egami + 0.1.0 + + + org.junit.jupiter + junit-jupiter-api + 5.11.0-M2 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.11.0-M2 + test + + + org.slf4j + slf4j-simple + 2.0.7 + test + + + + + src + + + ${basedir}/resources + + + test/src + ${project.basedir}/out/maven/ + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + + maven-assembly-plugin + + + + fully.qualified.MainClass + + + + jar-with-dependencies + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + private + true + + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + public + + + + + + diff --git a/src/module-info.java b/src/module-info.java index 58111ef..f70c763 100644 --- a/src/module-info.java +++ b/src/module-info.java @@ -6,8 +6,7 @@ open module org.atriasoft.esvg { exports org.atriasoft.esvg; exports org.atriasoft.esvg.font; exports org.atriasoft.esvg.render; - - requires transitive org.atriasoft.reggol; + requires transitive org.atriasoft.etk; requires transitive org.atriasoft.exml; requires org.atriasoft.pngencoder; diff --git a/src/org/atriasoft/esvg/Base.java b/src/org/atriasoft/esvg/Base.java index 9790d99..6c12123 100644 --- a/src/org/atriasoft/esvg/Base.java +++ b/src/org/atriasoft/esvg/Base.java @@ -2,7 +2,6 @@ package org.atriasoft.esvg; import java.util.List; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.etk.Color; import org.atriasoft.etk.Distance; import org.atriasoft.etk.math.FMath; @@ -11,6 +10,8 @@ import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.util.Dynamic; import org.atriasoft.etk.util.Pair; import org.atriasoft.exml.model.XmlElement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -19,6 +20,7 @@ import org.atriasoft.exml.model.XmlElement; */ public class Base { + static final Logger LOGGER = LoggerFactory.getLogger(Base.class); public static float kappa90 = 0.5522847493f; //!< proportional lenght to the radius of a bezier handle for 90° arcs. @@ -30,7 +32,7 @@ public class Base { } posStart += base.length(); if (value.length() < posStart + 2) { - Log.error("Not enought spece in the String to have transform value for ' (' or '()' in '" + value + "'"); + LOGGER.error("Not enought spece in the String to have transform value for ' (' or '()' in '" + value + "'"); return ""; } if (value.charAt(posStart) == '(') { @@ -39,19 +41,19 @@ public class Base { } else if (value.charAt(posStart) == ' ' && value.charAt(posStart + 1) == '(') { posStart += 2; } else { - Log.error("Can not indexOf ' (' or '(' in '" + value.substring(posStart) + "' for '" + value + "'"); + LOGGER.error("Can not indexOf ' (' or '(' in '" + value.substring(posStart) + "' for '" + value + "'"); return ""; } if (value.length() < posStart + 1) { - Log.error("Not enought spece in the String to have transform value for ')' in '" + value + "'"); + LOGGER.error("Not enought spece in the String to have transform value for ')' in '" + value + "'"); return ""; } - int posEnd = value.indexOf(')', posStart); + final int posEnd = value.indexOf(')', posStart); if (posEnd == -1) { - Log.error("Missing element ')' in '" + value + "' for " + base); + LOGGER.error("Missing element ')' in '" + value + "' for " + base); return ""; } - Log.verbose("indexOf : '" + value.substring(posStart, posEnd) + "' for " + base); + LOGGER.trace("indexOf : '" + value.substring(posStart, posEnd) + "' for " + base); return value.substring(posStart, posEnd); } @@ -83,10 +85,14 @@ public class Base { * @param level Level of the tree */ void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - Log.warning(spacingDist(level) + "DRAW esvg::Base ... ==> No drawing availlable"); + LOGGER.warn(spacingDist(level) + "DRAW esvg::Base ... ==> No drawing availlable"); } - public void drawShapePoints(final List> out, final int recurtionMax, final float threshold, final Matrix2x3f basicTrans) { + public void drawShapePoints( + final List> out, + final int recurtionMax, + final float threshold, + final Matrix2x3f basicTrans) { drawShapePoints(out, recurtionMax, threshold, basicTrans, 1); } @@ -95,10 +101,15 @@ public class Base { * @param out where the lines are added * @param recurtionMax interpolation recurtion max * @param threshold threshold to stop recurtion - * @param basicTrans Parant transformation of the environement + * @param basicTrans Parant transformation of the environement * @param level Level of the tree */ - void drawShapePoints(final List> out, final int recurtionMax, final float threshold, final Matrix2x3f basicTrans, final int level) { + void drawShapePoints( + final List> out, + final int recurtionMax, + final float threshold, + final Matrix2x3f basicTrans, + final int level) { } @@ -117,22 +128,24 @@ public class Base { */ Pair parseColor(final String inputData) { Pair 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) == '#') { - String color = inputData.substring(5, inputData.length() - 1); + final 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 ..."); + LOGGER.error( + "Problem in parsing the color : '" + inputData + "' == > url(XXX) is not supported now ..."); } } else { try { localColor = new Pair<>(Color.valueOf256(inputData), ""); - } catch (Exception e) { + } catch (final Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } - Log.verbose("Parse color : \"" + inputData + "\" == > " + localColor.first + " " + localColor.second); + LOGGER.trace("Parse color : \"" + inputData + "\" == > " + localColor.first + " " + localColor.second); return localColor; } @@ -142,31 +155,21 @@ public class Base { * @return standard number of pixels */ float parseLength(final String dataInput) { - Pair value = parseLength2(dataInput); - Log.verbose(" lenght : '" + value.first + "' => unit=" + value.second); - float fontsize = 20.0f; - switch (value.second) { - case POURCENT: - return value.first;// / 100.0 * this.paint.viewPort.x(); - case ELEMENT: - return value.first * fontsize; - case EX: - return value.first / 2.0f * fontsize; - case PIXEL: - return value.first; - case POINT: - return value.first * 1.25f; - case PC: - return value.first * 15.0f; - case MILLIMETER: - return value.first * 3.543307f; - case CENTIMETER: - return value.first * 35.43307f; - case INCH: - return value.first * 90.0f; - default: - return 0.0f; - } + final Pair value = parseLength2(dataInput); + LOGGER.trace(" lenght : '" + value.first + "' => unit=" + value.second); + final float fontsize = 20.0f; + return switch (value.second) { + case POURCENT -> value.first; // / 100.0 * this.paint.viewPort.x(); + case ELEMENT -> value.first * fontsize; + case EX -> value.first / 2.0f * fontsize; + case PIXEL -> value.first; + case POINT -> value.first * 1.25f; + case PC -> value.first * 15.0f; + case MILLIMETER -> value.first * 3.543307f; + case CENTIMETER -> value.first * 35.43307f; + case INCH -> value.first * 90.0f; + default -> 0.0f; + }; } Pair parseLength2(String config) { @@ -235,7 +238,7 @@ public class Base { } else { if (content.length() != 0) { this.paint.stroke = parseColor(content); - Log.error("Parse color : " + this.paint.stroke); + LOGGER.error("Parse color : " + this.paint.stroke); } content = element.getAttribute("stroke-width", ""); if (content.length() != 0) { @@ -253,7 +256,7 @@ public class Base { if (content.equals("none")) { // OK, Nothing to do ... } else { - Log.todo(" 'stroke-dasharray' not implemented ..."); + LOGGER.info("TODO 'stroke-dasharray' not implemented ..."); } } content = element.getAttribute("stroke-linecap", ""); @@ -266,7 +269,7 @@ public class Base { this.paint.lineCap = CapMode.SQUARE; } else { this.paint.lineCap = CapMode.BUTT; - Log.error("not know stroke-linecap value : '" + content + "', not in [butt,round,square]"); + LOGGER.error("not know stroke-linecap value : '" + content + "', not in [butt,round,square]"); } } content = element.getAttribute("stroke-linejoin", ""); @@ -279,12 +282,12 @@ public class Base { this.paint.lineJoin = JoinMode.BEVEL; } else { this.paint.lineJoin = JoinMode.MITER; - Log.error("not know stroke-linejoin value : '" + content + "', not in [miter,round,bevel]"); + LOGGER.error("not know stroke-linejoin value : '" + content + "', not in [miter,round,bevel]"); } } content = element.getAttribute("stroke-miterlimit", ""); if (content.length() != 0) { - float tmp = parseLength(content); + final float tmp = parseLength(content); this.paint.miterLimit = FMath.max(0.0f, tmp); } } @@ -309,7 +312,7 @@ public class Base { } else if (content.equals("evenodd")) { this.paint.flagEvenOdd = true; } else { - Log.error("not know fill-rule value : \"" + content + "\", not in [nonzero,evenodd]"); + LOGGER.error("not know fill-rule value : \"" + content + "\", not in [nonzero,evenodd]"); } } // ---------------- opacity ---------------- @@ -329,51 +332,56 @@ public class Base { if (inputString.length() == 0) { return; } - Log.verbose("indexOf transform : '" + inputString + "'"); + LOGGER.trace("indexOf transform : '" + inputString + "'"); inputString = inputString.replace(',', ' '); - Log.verbose("indexOf transform : '" + inputString + "'"); + LOGGER.trace("indexOf transform : '" + inputString + "'"); // need to indexOf elements in order ... String data = Base.extractTransformData(inputString, "matrix"); if (data.length() != 0) { - double[] matrix = FMath.getTableDouble(data, " ", 6); + final double[] matrix = FMath.getTableDouble(data, " ", 6); if (matrix != null) { this.transformMatrix = new Matrix2x3f(matrix); // indexOf a matrix : simply exit ... return; } - Log.error("Parsing matrix() with wrong data ... '" + data + "'"); + LOGGER.error("Parsing matrix() with wrong data ... '" + data + "'"); } data = Base.extractTransformData(inputString, "translate"); if (data.length() != 0) { - float[] elements = FMath.getTableFloat(data, " ", 2); + final float[] elements = FMath.getTableFloat(data, " ", 2); if (elements != null) { - this.transformMatrix = this.transformMatrix.multiply(Matrix2x3f.createTranslate(new Vector2f(elements[0], elements[1]))); - Log.verbose("Translate : " + elements[0] + ", " + elements[1]); + this.transformMatrix = this.transformMatrix + .multiply(Matrix2x3f.createTranslate(new Vector2f(elements[0], elements[1]))); + LOGGER.trace("Translate : " + elements[0] + ", " + elements[1]); } else { - float elem = Float.parseFloat(data); + final float elem = Float.parseFloat(data); this.transformMatrix = this.transformMatrix.multiply(Matrix2x3f.createTranslate(new Vector2f(elem, 0))); } } data = Base.extractTransformData(inputString, "scale"); if (data.length() != 0) { - float[] elements = FMath.getTableFloat(data, " ", 2); + final float[] elements = FMath.getTableFloat(data, " ", 2); if (elements != null) { - this.transformMatrix = this.transformMatrix.multiply(Matrix2x3f.createScale(new Vector2f(elements[0], elements[1]))); - Log.verbose("Translate : " + elements[0] + ", " + elements[1]); + this.transformMatrix = this.transformMatrix + .multiply(Matrix2x3f.createScale(new Vector2f(elements[0], elements[1]))); + LOGGER.trace("Translate : " + elements[0] + ", " + elements[1]); } else { - float elem = Float.parseFloat(data); + final float elem = Float.parseFloat(data); this.transformMatrix = this.transformMatrix.multiply(Matrix2x3f.createScale(elem)); } } data = Base.extractTransformData(inputString, "rotate"); if (data.length() != 0) { - float[] elements = FMath.getTableFloat(data, " ", 3); + final float[] elements = FMath.getTableFloat(data, " ", 3); if (elements != null) { - float angle = (float) Math.toRadians(elements[0]); - this.transformMatrix = this.transformMatrix.multiply(Matrix2x3f.createTranslate(new Vector2f(-elements[1], -elements[2]))); + final float angle = (float) Math.toRadians(elements[0]); + this.transformMatrix = this.transformMatrix + .multiply(Matrix2x3f.createTranslate(new Vector2f(-elements[1], -elements[2]))); this.transformMatrix = this.transformMatrix.multiply(Matrix2x3f.createRotate(angle)); - this.transformMatrix = this.transformMatrix.multiply(Matrix2x3f.createTranslate(new Vector2f(elements[1], elements[2]))); - this.transformMatrix = this.transformMatrix.multiply(Matrix2x3f.createScale(new Vector2f(elements[0], elements[1]))); + this.transformMatrix = this.transformMatrix + .multiply(Matrix2x3f.createTranslate(new Vector2f(elements[1], elements[2]))); + this.transformMatrix = this.transformMatrix + .multiply(Matrix2x3f.createScale(new Vector2f(elements[0], elements[1]))); } else { float elem = Float.parseFloat(data); elem = (float) Math.toRadians(elem); @@ -455,7 +463,7 @@ public class Base { } protected String spacingDist(final int spacing) { - StringBuilder out = new StringBuilder(); + final StringBuilder out = new StringBuilder(); for (int iii = 0; iii < spacing; iii++) { out.append(" "); } diff --git a/src/org/atriasoft/esvg/Circle.java b/src/org/atriasoft/esvg/Circle.java index 6488265..c8e168a 100644 --- a/src/org/atriasoft/esvg/Circle.java +++ b/src/org/atriasoft/esvg/Circle.java @@ -3,7 +3,6 @@ package org.atriasoft.esvg; import java.util.ArrayList; import java.util.List; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.esvg.render.DynamicColor; import org.atriasoft.esvg.render.PathModel; import org.atriasoft.esvg.render.Point; @@ -14,6 +13,8 @@ import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.util.Dynamic; import org.atriasoft.exml.model.XmlElement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -22,55 +23,61 @@ import org.atriasoft.exml.model.XmlElement; */ public class Circle extends Base { + static final Logger LOGGER = LoggerFactory.getLogger(Circle.class); private Vector2f position; //!< Position of the Circle private float radius; //!< Radius of the Circle - + public Circle(final PaintState parentPaintState) { super(parentPaintState); } - + public Circle(final Vector2f position, final float radius, final PaintState parentPaintState) { super(parentPaintState); this.position = position; this.radius = radius; } - + private PathModel createPath() { - PathModel out = new PathModel(); + final PathModel out = new PathModel(); out.moveTo(false, this.position.addX(this.radius)); - out.curveTo(false, this.position.add(this.radius, this.radius * Base.kappa90), this.position.add(this.radius * Base.kappa90, this.radius), this.position.addY(this.radius)); - out.curveTo(false, this.position.add(-this.radius * Base.kappa90, this.radius), this.position.add(-this.radius, this.radius * Base.kappa90), this.position.lessX(this.radius)); - out.curveTo(false, this.position.add(-this.radius, -this.radius * Base.kappa90), this.position.add(-this.radius * Base.kappa90, -this.radius), this.position.lessY(this.radius)); - out.curveTo(false, this.position.add(this.radius * Base.kappa90, -this.radius), this.position.add(this.radius, -this.radius * Base.kappa90), this.position.addX(this.radius)); + out.curveTo(false, this.position.add(this.radius, this.radius * Base.kappa90), + this.position.add(this.radius * Base.kappa90, this.radius), this.position.addY(this.radius)); + out.curveTo(false, this.position.add(-this.radius * Base.kappa90, this.radius), + this.position.add(-this.radius, this.radius * Base.kappa90), this.position.lessX(this.radius)); + out.curveTo(false, this.position.add(-this.radius, -this.radius * Base.kappa90), + this.position.add(-this.radius * Base.kappa90, -this.radius), this.position.lessY(this.radius)); + out.curveTo(false, this.position.add(this.radius * Base.kappa90, -this.radius), + this.position.add(this.radius, -this.radius * Base.kappa90), this.position.addX(this.radius)); out.close(); return out; } - + @Override public void display(final int spacing) { - Log.debug(spacingDist(spacing) + "Circle " + this.position + " radius=" + this.radius); + LOGGER.debug(spacingDist(spacing) + "Circle " + this.position + " radius=" + this.radius); } - + @Override public void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW esvg::Circle"); + LOGGER.trace(spacingDist(level) + "DRAW esvg::Circle"); if (this.radius <= 0.0f) { - Log.verbose(spacingDist(level + 1) + "Too small radius" + this.radius); + LOGGER.trace(spacingDist(level + 1) + "Too small radius" + this.radius); return; } - PathModel listElement = createPath(); - + final PathModel listElement = createPath(); + Matrix2x3f mtx = this.transformMatrix; mtx = mtx.multiply(basicTrans); - + PointList listPoints = new PointList(); - listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), myRenderer.getInterpolationThreshold()); + listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), + myRenderer.getInterpolationThreshold()); //listPoints.applyMatrix(mtx); - SegmentList listSegmentFill = new SegmentList(); - SegmentList listSegmentStroke = new SegmentList(); - Weight tmpFill = new Weight(); - Weight tmpStroke = new Weight(); - DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); + final SegmentList listSegmentFill = new SegmentList(); + final SegmentList listSegmentStroke = new SegmentList(); + final Weight tmpFill = new Weight(); + final Weight tmpStroke = new Weight(); + final DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); DynamicColor colorStroke = null; if (this.paint.strokeWidth > 0.0f) { colorStroke = DynamicColor.createColor(this.paint.stroke, mtx); @@ -85,7 +92,8 @@ public class Circle extends Base { } // check if we need to display stroke: if (colorStroke != null) { - listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, this.paint.lineJoin, this.paint.miterLimit); + listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, + this.paint.lineJoin, this.paint.miterLimit); colorStroke.setViewPort(listSegmentStroke.getViewPort()); listSegmentStroke.applyMatrix(mtx); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule @@ -96,25 +104,30 @@ public class Circle extends Base { //myRenderer.addDebugSegment(listSegmentFill); //myRenderer.addDebugSegment(listSegmentStroke); } - + @Override - public void drawShapePoints(final List> out, final int recurtionMax, final float threshold, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW Shape esvg::Circle"); - PathModel listElement = createPath(); + public void drawShapePoints( + final List> out, + final int recurtionMax, + final float threshold, + final Matrix2x3f basicTrans, + final int level) { + LOGGER.trace(spacingDist(level) + "DRAW Shape esvg::Circle"); + final PathModel listElement = createPath(); Matrix2x3f mtx = this.transformMatrix; mtx = mtx.multiply(basicTrans); PointList listPoints = new PointList(); listPoints = listElement.generateListPoints(level, recurtionMax, threshold); listPoints.applyMatrix(mtx); - for (List it : listPoints.data) { - List listPoint = new ArrayList<>(); - for (Point itDot : it) { + for (final List it : listPoints.data) { + final List listPoint = new ArrayList<>(); + for (final Point itDot : it) { listPoint.add(itDot.pos); } out.add(listPoint); } } - + @Override public boolean parseXML(final XmlElement element, final Matrix2x3f parentTrans, final Dynamic sizeMax) { this.radius = 0.0f; @@ -124,10 +137,10 @@ public class Circle extends Base { } parseTransform(element); parsePaintAttr(element); - + // add the property of the parrent modifications ... this.transformMatrix = this.transformMatrix.multiply(parentTrans); - + String content = element.getAttribute("cx", ""); if (content.length() != 0) { this.position = this.position.withX(parseLength(content)); @@ -138,13 +151,13 @@ public class Circle extends Base { } content = element.getAttribute("r", ""); if (content.length() == 0) { - Log.error("Circle \"r\" is not present"); + LOGGER.error("Circle \"r\" is not present"); return false; } this.radius = parseLength(content); if (0 > this.radius) { this.radius = 0; - Log.error("Circle \"r\" is negative"); + LOGGER.error("Circle \"r\" is negative"); return false; } sizeMax.value = new Vector2f(this.position.x() + this.radius, this.position.y() + this.radius); diff --git a/src/org/atriasoft/esvg/Ellipse.java b/src/org/atriasoft/esvg/Ellipse.java index e457417..2612366 100644 --- a/src/org/atriasoft/esvg/Ellipse.java +++ b/src/org/atriasoft/esvg/Ellipse.java @@ -2,7 +2,7 @@ package org.atriasoft.esvg; import java.util.ArrayList; import java.util.List; -import org.atriasoft.esvg.internal.Log; + import org.atriasoft.esvg.render.DynamicColor; import org.atriasoft.esvg.render.PathModel; import org.atriasoft.esvg.render.Point; @@ -13,6 +13,8 @@ import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.util.Dynamic; import org.atriasoft.exml.model.XmlElement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -21,55 +23,61 @@ import org.atriasoft.exml.model.XmlElement; */ public class Ellipse extends Base { + static final Logger LOGGER = LoggerFactory.getLogger(Ellipse.class); private Vector2f c; //!< Center property of the ellipse private Vector2f r; //!< Radius property of the ellipse - + public Ellipse(final PaintState parentPaintState) { super(parentPaintState); } - + public Ellipse(final Vector2f center, final Vector2f radius, final PaintState parentPaintState) { super(parentPaintState); this.c = center; this.r = radius; } - + PathModel createPath() { - PathModel out = new PathModel(); + final PathModel out = new PathModel(); out.moveTo(false, this.c.add(this.r.x(), 0.0f)); - out.curveTo(false, this.c.add(this.r.x(), this.r.y() * Base.kappa90), this.c.add(this.r.x() * Base.kappa90, this.r.y()), this.c.add(0.0f, this.r.y())); - out.curveTo(false, this.c.add(-this.r.x() * Base.kappa90, this.r.y()), this.c.add(-this.r.x(), this.r.y() * Base.kappa90), this.c.add(-this.r.x(), 0.0f)); - out.curveTo(false, this.c.add(-this.r.x(), -this.r.y() * Base.kappa90), this.c.add(-this.r.x() * Base.kappa90, -this.r.y()), this.c.add(0.0f, -this.r.y())); - out.curveTo(false, this.c.add(this.r.x() * Base.kappa90, -this.r.y()), this.c.add(this.r.x(), -this.r.y() * Base.kappa90), this.c.add(this.r.x(), 0.0f)); + out.curveTo(false, this.c.add(this.r.x(), this.r.y() * Base.kappa90), + this.c.add(this.r.x() * Base.kappa90, this.r.y()), this.c.add(0.0f, this.r.y())); + out.curveTo(false, this.c.add(-this.r.x() * Base.kappa90, this.r.y()), + this.c.add(-this.r.x(), this.r.y() * Base.kappa90), this.c.add(-this.r.x(), 0.0f)); + out.curveTo(false, this.c.add(-this.r.x(), -this.r.y() * Base.kappa90), + this.c.add(-this.r.x() * Base.kappa90, -this.r.y()), this.c.add(0.0f, -this.r.y())); + out.curveTo(false, this.c.add(this.r.x() * Base.kappa90, -this.r.y()), + this.c.add(this.r.x(), -this.r.y() * Base.kappa90), this.c.add(this.r.x(), 0.0f)); out.close(); return out; } - + @Override public void display(final int spacing) { - Log.debug(spacingDist(spacing) + "Ellipse c=" + this.c + " r=" + this.r); + LOGGER.debug(spacingDist(spacing) + "Ellipse c=" + this.c + " r=" + this.r); } - + @Override public void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW esvg::Ellipse"); + LOGGER.trace(spacingDist(level) + "DRAW esvg::Ellipse"); if (this.r.x() <= 0.0f || this.r.y() <= 0.0f) { - Log.verbose(spacingDist(level + 1) + "Too small radius" + this.r); + LOGGER.trace(spacingDist(level + 1) + "Too small radius" + this.r); return; } - PathModel listElement = createPath(); - + final PathModel listElement = createPath(); + Matrix2x3f mtx = this.transformMatrix; mtx = mtx.multiply(basicTrans); - + PointList listPoints = new PointList(); - listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), myRenderer.getInterpolationThreshold()); + listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), + myRenderer.getInterpolationThreshold()); //listPoints.applyMatrix(mtx); - SegmentList listSegmentFill = new SegmentList(); - SegmentList listSegmentStroke = new SegmentList(); - Weight tmpFill = new Weight(); - Weight tmpStroke = new Weight(); - DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); + final SegmentList listSegmentFill = new SegmentList(); + final SegmentList listSegmentStroke = new SegmentList(); + final Weight tmpFill = new Weight(); + final Weight tmpStroke = new Weight(); + final DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); DynamicColor colorStroke = null; if (this.paint.strokeWidth > 0.0f) { colorStroke = DynamicColor.createColor(this.paint.stroke, mtx); @@ -84,7 +92,8 @@ public class Ellipse extends Base { } // check if we need to display stroke: if (colorStroke != null) { - listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, this.paint.lineJoin, this.paint.miterLimit); + listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, + this.paint.lineJoin, this.paint.miterLimit); colorStroke.setViewPort(listSegmentStroke.getViewPort()); listSegmentStroke.applyMatrix(mtx); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule @@ -95,25 +104,30 @@ public class Ellipse extends Base { //myRenderer.addDebugSegment(listSegmentFill); //myRenderer.addDebugSegment(listSegmentStroke) } - + @Override - public void drawShapePoints(final List> out, final int recurtionMax, final float threshold, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW Shape esvg::Ellipse"); - PathModel listElement = createPath(); + public void drawShapePoints( + final List> out, + final int recurtionMax, + final float threshold, + final Matrix2x3f basicTrans, + final int level) { + LOGGER.trace(spacingDist(level) + "DRAW Shape esvg::Ellipse"); + final PathModel listElement = createPath(); Matrix2x3f mtx = this.transformMatrix; mtx = mtx.multiply(basicTrans); PointList listPoints; listPoints = listElement.generateListPoints(level, recurtionMax, threshold); listPoints.applyMatrix(mtx); - for (List it : listPoints.data) { - List listPoint = new ArrayList<>(); - for (Point itDot : it) { + for (final List it : listPoints.data) { + final List listPoint = new ArrayList<>(); + for (final Point itDot : it) { listPoint.add(itDot.pos); } out.add(listPoint); } } - + @Override public boolean parseXML(final XmlElement element, final Matrix2x3f parentTrans, final Dynamic sizeMax) { if (element == null) { @@ -121,13 +135,13 @@ public class Ellipse extends Base { } parseTransform(element); parsePaintAttr(element); - + // add the property of the parrent modifications ... this.transformMatrix = this.transformMatrix.multiply(parentTrans); - + this.c = Vector2f.ZERO; this.r = Vector2f.ZERO; - + String content = element.getAttribute("cx", ""); if (content.length() != 0) { this.c = this.c.withX(parseLength(content)); @@ -138,18 +152,18 @@ public class Ellipse extends Base { } content = element.getAttribute("rx", ""); if (content.length() == 0) { - Log.error("Ellipse \"rx\" is not present"); + LOGGER.error("Ellipse \"rx\" is not present"); return false; } this.r = this.r.withX(parseLength(content)); content = element.getAttribute("ry", ""); if (content.length() == 0) { - Log.error("Ellipse \"ry\" is not present"); + LOGGER.error("Ellipse \"ry\" is not present"); return false; } this.r = this.r.withY(parseLength(content)); sizeMax.value = new Vector2f(this.c.x() + this.r.x(), this.c.y() + this.r.y()); - + return true; } } diff --git a/src/org/atriasoft/esvg/EsvgDocument.java b/src/org/atriasoft/esvg/EsvgDocument.java index fe37d33..05af93b 100644 --- a/src/org/atriasoft/esvg/EsvgDocument.java +++ b/src/org/atriasoft/esvg/EsvgDocument.java @@ -5,7 +5,6 @@ import java.util.List; import org.atriasoft.aknot.exception.AknotException; import org.atriasoft.egami.ImageFloatRGBA; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.etk.Uri; import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; @@ -16,8 +15,11 @@ import org.atriasoft.exml.exception.ExmlException; import org.atriasoft.exml.exception.ExmlNodeDoesNotExist; import org.atriasoft.exml.model.XmlElement; import org.atriasoft.exml.model.XmlNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class EsvgDocument extends Base { + static final Logger LOGGER = LoggerFactory.getLogger(EsvgDocument.class); private boolean loadOK = false; private final List refList = new ArrayList<>(); private Vector2f size = Vector2f.ZERO; @@ -25,19 +27,19 @@ public class EsvgDocument extends Base { private String title = ""; //!< sub-element list private Uri uri = null; //!< reference elements ... private String version = "0.0"; - + public EsvgDocument() { - + } - + public EsvgDocument(final Vector2i size) { this.size = new Vector2f(size.x(), size.y()); } - + public void addElement(final Base elem) { this.subElementList.add(elem); } - + /** * change all style in a xml atribute */ @@ -55,7 +57,7 @@ public class EsvgDocument extends Base { for (final String it1 : listStyle) { final String[] value = it1.split(":"); if (value.length != 2) { - Log.error("parsing style with a wrong patern : " + it1 + " missing ':'"); + LOGGER.error("parsing style with a wrong patern : " + it1 + " missing ':'"); continue; } // TODO Check if the attibute already exist ... @@ -70,7 +72,7 @@ public class EsvgDocument extends Base { } return true; } - + public void clear() { this.uri = null; this.version = "0.0"; @@ -78,54 +80,59 @@ public class EsvgDocument extends Base { this.paint.clear(); this.size = Vector2f.ZERO; } - + /** * Display all the node in the svg file. */ public void displayDebug() { - Log.debug("Main SVG: size=" + this.size); - Log.debug(" refs:"); - for (int iii = 0; iii < this.refList.size(); iii++) { - if (this.refList.get(iii) != null) { - this.refList.get(iii).display(2); + LOGGER.debug("Main SVG: size=" + this.size); + LOGGER.debug(" refs:"); + for (final Base element : this.refList) { + if (element != null) { + element.display(2); } } - Log.debug(" Nodes:"); - for (int iii = 0; iii < this.subElementList.size(); iii++) { - if (this.subElementList.get(iii) != null) { - this.subElementList.get(iii).display(2); + LOGGER.debug(" Nodes:"); + for (final Base element : this.subElementList) { + if (element != null) { + element.display(2); } } } - + @Override protected void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - for (int iii = 0; iii < this.subElementList.size(); iii++) { - if (this.subElementList.get(iii) != null) { - this.subElementList.get(iii).draw(myRenderer, basicTrans); + for (final Base element : this.subElementList) { + if (element != null) { + element.draw(myRenderer, basicTrans); } } } - + @Override - protected void drawShapePoints(final List> out, final int recurtionMax, final float threshold, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW shape EsvgDocument"); + protected void drawShapePoints( + final List> out, + final int recurtionMax, + final float threshold, + final Matrix2x3f basicTrans, + final int level) { + LOGGER.trace(spacingDist(level) + "DRAW shape EsvgDocument"); for (final Base it : this.subElementList) { if (it != null) { it.drawShapePoints(out, recurtionMax, threshold, basicTrans, level + 1); } } } - + // TODO remove this fucntion : use generic function ... public Vector2f getDefinedSize() { return this.size; } - + public List> getLines() { return getLines(new Vector2f(256, 256)); } - + public List> getLines(Vector2f size) { final List> out = new ArrayList<>(); if (size.x() <= 0) { @@ -134,16 +141,17 @@ public class EsvgDocument extends Base { if (size.y() <= 0) { size = size.withY(this.size.y()); } - Log.debug("lineification size " + size); + LOGGER.debug("lineification size " + size); // create the first element matrix modification ... - final Matrix2x3f basicTrans = Matrix2x3f.IDENTITY.multiply(Matrix2x3f.createScale(new Vector2f(size.x() / this.size.x(), size.y() / this.size.y()))); + final Matrix2x3f basicTrans = Matrix2x3f.IDENTITY + .multiply(Matrix2x3f.createScale(new Vector2f(size.x() / this.size.x(), size.y() / this.size.y()))); drawShapePoints(out, 10, 0.25f, basicTrans); return out; } - + public Base getReference(final String name) { if (name.isEmpty()) { - Log.error("request a reference with no name ... "); + LOGGER.error("request a reference with no name ... "); return null; } for (final Base it : this.refList) { @@ -154,14 +162,14 @@ public class EsvgDocument extends Base { return it; } } - Log.error("Can not find reference name : '" + name + "'"); + LOGGER.error("Can not find reference name : '" + name + "'"); return null; } - + public boolean isLoadOk() { return this.loadOK; } - + /* //! @previous public List renderImageFloatRGB(final Vector2i size) { @@ -174,7 +182,7 @@ public class EsvgDocument extends Base { } return out; } - + //! @previous public List> renderImageU8RGBA(final Vector2i size) { List data = renderImageFloatRGBA(size); @@ -186,7 +194,7 @@ public class EsvgDocument extends Base { } return out; } - + //! @previous public List> renderImageU8RGB(final Vector2i size) { List data = renderImageFloatRGBA(size); @@ -230,7 +238,7 @@ public class EsvgDocument extends Base { } return this.loadOK; } - + /** * parse a string that contain an svg stream * @param data Data to parse @@ -262,11 +270,11 @@ public class EsvgDocument extends Base { } return this.loadOK; } - + public boolean parseXMLData(final XmlElement root) { return parseXMLData(root, false); } - + public boolean parseXMLData(final XmlElement root, final boolean isReference) { // get the svg version : this.version = root.getAttribute("version", ""); @@ -277,11 +285,11 @@ public class EsvgDocument extends Base { pos = parseXmlPosition(root); this.size = parseXmlSize(root); parsePaintAttr(root); - Log.verbose("parsed .ROOT trans: " + this.transformMatrix); + LOGGER.trace("parsed .ROOT trans: " + this.transformMatrix); } else { - Log.verbose("Parse Reference section ... (no attibute)"); + LOGGER.trace("Parse Reference section ... (no attibute)"); } - + Vector2f maxSize = Vector2f.ZERO; final Dynamic size = new Dynamic<>(Vector2f.ZERO); // parse all sub node: @@ -294,7 +302,7 @@ public class EsvgDocument extends Base { if (child.getValue().equals("g")) { elementParser = new Group(this.paint); } else if (child.getValue().equals("a")) { - Log.info("Note : 'a' balise is parsed like a g balise ..."); + LOGGER.info("Note : 'a' balise is parsed like a g balise ..."); elementParser = new Group(this.paint); } else if (child.getValue().equals("title")) { this.title = "TODO : set the title here ..."; @@ -317,19 +325,19 @@ public class EsvgDocument extends Base { elementParser = new Text(this.paint); } else if (child.getValue().equals("radialGradient")) { if (!isReference) { - Log.error("'" + child.getValue() + "' node must not be defined outside a defs Section"); + LOGGER.error("'" + child.getValue() + "' node must not be defined outside a defs Section"); continue; } elementParser = new RadialGradient(this.paint); } else if (child.getValue().equals("linearGradient")) { if (!isReference) { - Log.error("'" + child.getValue() + "' node must not be defined outside a defs Section"); + LOGGER.error("'" + child.getValue() + "' node must not be defined outside a defs Section"); continue; } elementParser = new LinearGradient(this.paint); } else if (child.getValue().equals("defs")) { if (isReference) { - Log.error("'" + child.getValue() + "' node must not be defined in a defs Section"); + LOGGER.error("'" + child.getValue() + "' node must not be defined in a defs Section"); continue; } final boolean retRefs = parseXMLData(child, true); @@ -342,14 +350,15 @@ public class EsvgDocument extends Base { // Node ignore : generaly inkscape data continue; } else { - Log.error("node not suported : '" + child.getValue() + "' must be [title,g,a,path,rect,circle,ellipse,line,polyline,polygon,text,metadata]"); + LOGGER.error("node not suported : '" + child.getValue() + + "' must be [title,g,a,path,rect,circle,ellipse,line,polyline,polygon,text,metadata]"); } if (elementParser == null) { - Log.error("error on node: '" + child.getValue() + "' allocation error or not supported ..."); + LOGGER.error("error on node: '" + child.getValue() + "' allocation error or not supported ..."); continue; } if (!elementParser.parseXML(child, this.transformMatrix, size)) { - Log.error("error on node: '" + child.getValue() + "' Sub Parsing ERROR"); + LOGGER.error("error on node: '" + child.getValue() + "' Sub Parsing ERROR"); elementParser = null; continue; } @@ -376,12 +385,12 @@ public class EsvgDocument extends Base { } return true; } - + /* public float[][] renderImageFloat(final Vector2i size) { return renderImageFloat(size, false); } - + public float[][] renderImageFloat(Vector2i size, final boolean visualDebug) { if (size == null) { size = new Vector2i((int) this.size.x(), (int) this.size.y()); @@ -393,12 +402,12 @@ public class EsvgDocument extends Base { size = size.withY((int) this.size.y()); } } - Log.debug("Generate size " + size); + LOGGER.debug("Generate size " + size); Renderer renderedElement = new Renderer(size, this, visualDebug); // create the first element matrix modification ... Matrix2x3f basicTrans = Matrix2x3f.IDENTITY.multiply(Matrix2x3f.createScale(new Vector2f(size.x() / this.size.x(), size.y() / this.size.y()))); draw(renderedElement, basicTrans); - + // direct return the generated data ... return renderedElement.getData(); } @@ -411,7 +420,7 @@ public class EsvgDocument extends Base { public ImageFloatRGBA renderImageFloatRGBA(final Vector2i size) { return renderImageFloatRGBA(size, false); } - + public ImageFloatRGBA renderImageFloatRGBA(Vector2i size, final boolean visualDebug) { if (size == null) { size = new Vector2i((int) this.size.x(), (int) this.size.y()); @@ -424,19 +433,20 @@ public class EsvgDocument extends Base { } } if (size.x() <= 0) { - Log.error("Generate size " + size); + LOGGER.error("Generate size " + size); } if (size.y() <= 0) { - Log.error("Generate size " + size); + LOGGER.error("Generate size " + size); } - Log.verbose("Generate size " + size); + LOGGER.trace("Generate size " + size); final Renderer renderedElement = new Renderer(size, this, visualDebug); // create the first element matrix modification ... - final Matrix2x3f basicTrans = Matrix2x3f.IDENTITY.multiply(Matrix2x3f.createScale(new Vector2f(size.x() / this.size.x(), size.y() / this.size.y()))); + final Matrix2x3f basicTrans = Matrix2x3f.IDENTITY + .multiply(Matrix2x3f.createScale(new Vector2f(size.x() / this.size.x(), size.y() / this.size.y()))); draw(renderedElement, basicTrans); - + // direct return the generated data ... return renderedElement.getData(); } - + } diff --git a/src/org/atriasoft/esvg/EsvgFont.java b/src/org/atriasoft/esvg/EsvgFont.java index bbca268..849b78d 100644 --- a/src/org/atriasoft/esvg/EsvgFont.java +++ b/src/org/atriasoft/esvg/EsvgFont.java @@ -8,7 +8,6 @@ import java.util.Map; import org.atriasoft.aknot.exception.AknotException; import org.atriasoft.esvg.font.Glyph; import org.atriasoft.esvg.font.Kerning; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.esvg.render.PathModel; import org.atriasoft.esvg.render.RenderingConfig; import org.atriasoft.esvg.render.Weight; @@ -21,6 +20,8 @@ import org.atriasoft.exml.Exml; import org.atriasoft.exml.exception.ExmlException; import org.atriasoft.exml.model.XmlElement; import org.atriasoft.exml.model.XmlNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; // https://www.w3.org/TR/SVGTiny12/fonts.html @@ -52,11 +53,11 @@ import org.atriasoft.exml.model.XmlNode; <------------------------> : advance.x <------------> : sizeTexture.x <---> : bearing.x - - - - + + + + _ *----------------------* ^ ==> calculateFontRealHeight(fontSize); | | | ^ ==> getAscent(fontSize); @@ -72,12 +73,13 @@ import org.atriasoft.exml.model.XmlNode; | | | |==> getDescent(fontSize); | | | | *----------------------* | | - - + + */ public class EsvgFont { - + static final Logger LOGGER = LoggerFactory.getLogger(EsvgFont.class); + /** * Load the file that might contain the svg * @param uri File of the svg @@ -99,24 +101,25 @@ public class EsvgFont { return null; } if (!(doc instanceof final XmlElement root)) { - Log.error("can not load the SVG font ==> wrong root node"); + LOGGER.error("can not load the SVG font ==> wrong root node"); return null; } if (!root.existNode("svg") || !(root.getNodeNoExcept("svg") instanceof final XmlElement svgNode)) { - Log.error("can not load Node in svg document"); + LOGGER.error("can not load Node in svg document"); return null; } if (!svgNode.existNode("defs") || !(svgNode.getNodeNoExcept("defs") instanceof final XmlElement defsNode)) { - Log.error("can not load Node in svg document"); + LOGGER.error("can not load Node in svg document"); return null; } - if (!defsNode.existNode("font") || !(defsNode.getNodeNoExcept("font") instanceof final XmlElement fontElement)) { - Log.error("can not load Node in svg document"); + if (!defsNode.existNode("font") + || !(defsNode.getNodeNoExcept("font") instanceof final XmlElement fontElement)) { + LOGGER.error("can not load Node in svg document"); return null; } - + font.horizAdvX = Integer.parseInt(fontElement.getAttribute("horiz-adv-x", "100")); - + int nbGlyph = 0; for (final XmlNode values : fontElement.getNodes()) { if (values.getValue().equals("font-face")) { @@ -157,7 +160,7 @@ public class EsvgFont { for (final XmlNode values : fontElement.getNodes()) { if (values.getValue().equals("glyph")) { nbGlyph++; - //Log.info("find flyph: " + nbGlyph); + //LOGGER.info("find flyph: " + nbGlyph); final Glyph tmp = Glyph.valueOf(values.toElement(), font); if (tmp != null) { font.glyphs.put(tmp.getUnicodeValue(), tmp); @@ -169,7 +172,7 @@ public class EsvgFont { } else if (values.getValue().equals("font-face")) { // already done ... } else { - Log.warning("unsupported node name :" + values.getValue()); + LOGGER.warn("unsupported node name :" + values.getValue()); } } for (final XmlNode values : fontElement.getNodes()) { @@ -188,18 +191,18 @@ public class EsvgFont { final String[] g2Splited = g2.split(","); // create the list of kerning of the next elements final List elementsKerning = new ArrayList<>(); - for (int iii = 0; iii < g2Splited.length; iii++) { + for (final String element : g2Splited) { for (final Map.Entry entry : font.glyphs.entrySet()) { - if (entry.getValue().getName().equals(g2Splited[iii])) { + if (entry.getValue().getName().equals(element)) { elementsKerning.add(new Kerning(offset, entry.getKey())); break; } } } // add it on the - for (int iii = 0; iii < g1Splited.length; iii++) { + for (final String element : g1Splited) { for (final Map.Entry entry : font.glyphs.entrySet()) { - if (entry.getValue().getName().equals(g1Splited[iii])) { + if (entry.getValue().getName().equals(element)) { entry.getValue().addKerning(elementsKerning); font.hasKerning = true; break; @@ -211,7 +214,7 @@ public class EsvgFont { } return font; } - + // The maximum accented height of the font within the font coordinate system. private int ascent = 800; // this is the height of the font (on top...) private int[] bbox = { -879, -545, 1767, 934 }; @@ -235,7 +238,7 @@ public class EsvgFont { private int unitsPerEm = 1000; // full size of the font // The height of lowercase glyphs in the font within the font coordinate system. private int xHeight = 450; - + /** * Get the font real size use (height) for all the characters. * @param fontSize size of the font the user require @@ -243,33 +246,33 @@ public class EsvgFont { */ public int calculateFontRealHeight(final int fontSize) { return fontSize * this.unitsPerEm / this.capHeight; - + } - + public float calculateFontSizeWithHeight(final float fontHeight) { return fontHeight * this.capHeight / this.unitsPerEm; } - + public Vector2f calculateRenderOffset(final int fontSize) { final int realSize = calculateFontRealHeight(fontSize); final float deltaY = realSize * this.ascent / this.unitsPerEm; return new Vector2f(0, deltaY); } - + public float calculateSclaleFactor(final int fontSize) { final int realSize = calculateFontRealHeight(fontSize); return (float) realSize / (float) this.unitsPerEm; } - + public Vector2i calculateTextSize(final int fontSize, final String data) { final boolean withKerning = true; final int widthOut = calculateWidth(data, fontSize, withKerning); - + final int realSize = calculateFontRealHeight(fontSize); return new Vector2i(widthOut, realSize); /* float scale = (float) realSize / (float) this.unitsPerEm; - + int offsetWriting = 0; int lastValue = 0; for (char uVal : data.toCharArray()) { @@ -282,7 +285,7 @@ public class EsvgFont { offsetWriting -= glyph.getKerning(lastValue) * scale; lastValue = uVal; } - + float advenceXLocal = glyph.getHorizAdvX() * scale; // No generation of output ... offsetWriting += advenceXLocal; @@ -290,7 +293,7 @@ public class EsvgFont { return new Vector2i(offsetWriting, realSize); */ } - + public int calculateWidth(final int uVal, final int fontSize) { final Glyph glyph = getGlyph(uVal); if (glyph == null) { @@ -300,15 +303,15 @@ public class EsvgFont { final float scale = (float) realSize / (float) this.unitsPerEm; return (int) (glyph.getHorizAdvX() * scale); } - + public int calculateWidth(final String uVal, final int fontSize) { return calculateWidth(uVal, fontSize, true); } - + public int calculateWidth(final String data, final int fontSize, final boolean withKerning) { final int realSize = calculateFontRealHeight(fontSize); final float scale = (float) realSize / (float) this.unitsPerEm; - //Log.error("scale =" + scale+ " font size = " + fontSize + " realSize=" + realSize); + //LOGGER.error("scale =" + scale+ " font size = " + fontSize + " realSize=" + realSize); float offsetWriting = 0; int lastValue = 0; for (final char uVal : data.toCharArray()) { @@ -321,14 +324,14 @@ public class EsvgFont { offsetWriting -= glyph.getKerning(lastValue) * scale; lastValue = uVal; } - + final float advenceXLocal = glyph.getHorizAdvX() * scale; offsetWriting += advenceXLocal; - //Log.error("offset X =" + offsetWriting + " + " + advenceXLocal + " " + uVal); + //LOGGER.error("offset X =" + offsetWriting + " + " + advenceXLocal + " " + uVal); } return (int) offsetWriting; } - + /** * Get the rendering size of the specific glyph (size rendered in the Weight class). * @param unicodeValue Unicode value to render @@ -338,11 +341,11 @@ public class EsvgFont { public Vector2i calculateWidthRendering(final Integer unicodeValue, final int fontSize) { return new Vector2i(calculateWidth(unicodeValue, fontSize), calculateFontRealHeight(fontSize)); } - + public int getDescent() { return this.descent; } - + public Glyph getGlyph(final int glyphIndex) { final Glyph out = this.glyphs.get(glyphIndex); if (out == null) { @@ -350,7 +353,7 @@ public class EsvgFont { } return out; } - + public Glyph getGlyphNullIfMissing(final int glyphIndex) { final Glyph out = this.glyphs.get(glyphIndex); if (out == null) { @@ -358,11 +361,11 @@ public class EsvgFont { } return out; } - + public int getHorizAdvX() { return this.horizAdvX; } - + /** * Get the number of available glyph in the Font * @return the glyph count. @@ -370,11 +373,11 @@ public class EsvgFont { public int getNumGlyphs() { return this.glyphs.size(); } - + public float getUnitsPerEm() { return this.unitsPerEm; } - + /** * Check if the font have some kerning data * @return true if kerning is availlable. @@ -382,7 +385,7 @@ public class EsvgFont { public boolean hasKerning() { return this.hasKerning; } - + public Weight render(final int uVal, final int fontSize) { final int realSize = calculateFontRealHeight(fontSize); final Glyph glyph = getGlyph(uVal); @@ -391,7 +394,8 @@ public class EsvgFont { } final float scale = (float) realSize / (float) this.unitsPerEm; final RenderingConfig config = new RenderingConfig(10, 0.25f, 8); - final Matrix2x3f transform = Matrix2x3f.createTranslate(new Vector2f(0, -this.descent)).multiply(Matrix2x3f.createScale(scale)); + final Matrix2x3f transform = Matrix2x3f.createTranslate(new Vector2f(0, -this.descent)) + .multiply(Matrix2x3f.createScale(scale)); final PathModel model = glyph.getModel(); if (model == null) { return null; @@ -399,19 +403,19 @@ public class EsvgFont { final Weight data = glyph.getModel().drawFill(calculateWidthRendering(uVal, fontSize), transform, 8, config); return data; } - + public Weight render(final String uVal, final int fontSize) { return render(uVal, fontSize, true); } - + public Weight render(final String data, final int fontSize, final boolean withKerning) { final int widthOut = calculateWidth(data, fontSize, withKerning); - + final int realSize = calculateFontRealHeight(fontSize); final float scale = (float) realSize / (float) this.unitsPerEm; - + final Weight weight = new Weight(new Vector2i(widthOut, realSize)); - + float offsetWriting = 0; int lastValue = 0; for (final char uVal : data.toCharArray()) { @@ -422,21 +426,23 @@ public class EsvgFont { } if (withKerning) { offsetWriting -= glyph.getKerning(lastValue) * scale; - Log.info(" ==> kerning offset = " + (glyph.getKerning(lastValue) * scale)); + LOGGER.info(" ==> kerning offset = " + (glyph.getKerning(lastValue) * scale)); lastValue = uVal; } - + final float advenceXLocal = glyph.getHorizAdvX() * scale; - + final RenderingConfig config = new RenderingConfig(10, 0.25f, 8); - final Matrix2x3f transform = Matrix2x3f.createTranslate(new Vector2f(0, -this.descent)).multiply(Matrix2x3f.createScale(scale)); + final Matrix2x3f transform = Matrix2x3f.createTranslate(new Vector2f(0, -this.descent)) + .multiply(Matrix2x3f.createScale(scale)); final PathModel model = glyph.getModel(); if (model != null) { - final Weight redered = model.drawFill(calculateWidthRendering((int) uVal, fontSize), transform, 8, config); + final Weight redered = model.drawFill(calculateWidthRendering((int) uVal, fontSize), transform, 8, + config); weight.fusion(redered, (int) offsetWriting, 0); } offsetWriting += advenceXLocal; - + } return weight; } diff --git a/src/org/atriasoft/esvg/GraphicContext.java b/src/org/atriasoft/esvg/GraphicContext.java index 4a95864..32060c9 100644 --- a/src/org/atriasoft/esvg/GraphicContext.java +++ b/src/org/atriasoft/esvg/GraphicContext.java @@ -2,59 +2,62 @@ package org.atriasoft.esvg; import org.atriasoft.egami.ImageByte; import org.atriasoft.egami.ToolImage; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.esvg.render.PathModel; import org.atriasoft.etk.Color; import org.atriasoft.etk.Configs; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.math.Vector2i; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * Graphic context is used to manage dynamic + * Graphic context is used to manage dynamic * @author heero * */ public class GraphicContext { + static final Logger LOGGER = LoggerFactory.getLogger(GraphicContext.class); private EsvgDocument document = new EsvgDocument(); PaintState paintState; private PathModel path = null; private Vector2i size = Vector2i.VALUE_32; - + public GraphicContext() { clear(); } - + public Vector2i calculateTextSize(final String data) { - return FontCache.getFont(Configs.getConfigFonts().getName(), false, false).calculateTextSize(Configs.getConfigFonts().getSize(), data); + return FontCache.getFont(Configs.getConfigFonts().getName(), false, false) + .calculateTextSize(Configs.getConfigFonts().getSize(), data); } - + public void circle(final Vector2f position, final float radius) { this.document.addElement(new Circle(position, radius, this.paintState.clone())); } - + public void clear() { this.document = new EsvgDocument(this.size); this.paintState = new PaintState(); } - + /** * Clear the fill color (disable fill ==> better that set it transparent) */ public void clearColorFill() { this.paintState.fill = null; } - + /** * Clear the Stroke color (disable stroke) */ public void clearColorStroke() { this.paintState.clearStroke(); } - + public void ellipse(final Vector2f center, final Vector2f radius) { this.document.addElement(new Ellipse(center, radius, this.paintState.clone())); } - + /** * Get the fill color. * @return fill color. @@ -62,7 +65,7 @@ public class GraphicContext { public Color getColorFill() { return this.paintState.getFill(); } - + /** * Get the stroke color. * @return Stroke color. @@ -70,85 +73,86 @@ public class GraphicContext { public Color getColorStroke() { return this.paintState.getStroke(); } - + public CapMode getLineCap() { return this.paintState.getLineCap(); } - + public JoinMode getLineJoin() { return this.paintState.getLineJoin(); } - + public float getMiterLimit() { return this.paintState.getMiterLimit(); } - + public float getOpacity() { return this.paintState.getOpacity(); } - + public float getStrokeWidth() { return this.paintState.getStrokeWidth(); } - + public int getTextHeight() { return getTextHeight(Configs.getConfigFonts().getSize()); } + public int getTextSize() { return Configs.getConfigFonts().getSize(); } - public int getTextHeight(final float height) { - return FontCache.getFont(Configs.getConfigFonts().getName(), false, false).calculateFontRealHeight((int) height); + return FontCache.getFont(Configs.getConfigFonts().getName(), false, false) + .calculateFontRealHeight((int) height); } - + public void line(final Vector2f origin, final Vector2f destination) { this.document.addElement(new Line(origin, destination, this.paintState.clone())); } - + public void lineRel(final Vector2f origin, final Vector2f relativeDestination) { this.document.addElement(new Line(origin, origin.add(relativeDestination), this.paintState.clone())); } - + public void pathLine(final Vector2f pos) { if (this.path == null) { - Log.error("Empty path... Need call pathStart() before"); + LOGGER.error("Empty path... Need call pathStart() before"); return; } this.path.lineTo(false, pos); } - + public void pathLineTo(final Vector2f pos) { if (this.path == null) { - Log.error("Empty path... Need call pathStart() before"); + LOGGER.error("Empty path... Need call pathStart() before"); return; } this.path.lineTo(true, pos); - + } - + public void pathMove(final Vector2f pos) { if (this.path == null) { - Log.error("Empty path... Need call pathStart() before"); + LOGGER.error("Empty path... Need call pathStart() before"); return; } this.path.moveTo(false, pos); } - + public void pathMoveTo(final Vector2f pos) { if (this.path == null) { - Log.error("Empty path... Need call pathStart() before"); + LOGGER.error("Empty path... Need call pathStart() before"); return; } this.path.moveTo(true, pos); } - + public void pathStart() { pathStop(); this.path = new PathModel(); } - + public void pathStop() { if (this.path == null) { return; @@ -157,7 +161,7 @@ public class GraphicContext { this.document.addElement(new Path(this.path, this.paintState.clone())); this.path = null; } - + public void pathStopLinked() { if (this.path == null) { return; @@ -166,43 +170,43 @@ public class GraphicContext { this.document.addElement(new Path(this.path, this.paintState.clone())); this.path = null; } - + public void rectangle(final Vector2f position, final Vector2f destination) { if (this.path != null) { - Log.error("Path not empty ... Need call pathStart() before"); + LOGGER.error("Path not empty ... Need call pathStart() before"); pathStop(); } this.document.addElement(new Rectangle(position, destination.less(position), this.paintState.clone())); } - + public void rectangleRounded(final Vector2f position, final Vector2f destination, final Vector2f ruound) { if (this.path != null) { - Log.error("Path not empty ... Need call pathStart() before"); + LOGGER.error("Path not empty ... Need call pathStart() before"); pathStop(); } this.document.addElement(new Rectangle(position, destination.less(position), ruound, this.paintState.clone())); } - + public void rectangleRoundedWidth(final Vector2f position, final Vector2f width, final Vector2f ruound) { if (this.path != null) { - Log.error("Path not empty ... Need call pathStart() before"); + LOGGER.error("Path not empty ... Need call pathStart() before"); pathStop(); } this.document.addElement(new Rectangle(position, width, ruound, this.paintState.clone())); } - + public void rectangleWidth(final Vector2f position, final Vector2f width) { if (this.path != null) { - Log.error("Path not empty ... Need call pathStart() before"); + LOGGER.error("Path not empty ... Need call pathStart() before"); pathStop(); } this.document.addElement(new Rectangle(position, width, this.paintState.clone())); } - + public ImageByte render() { return ToolImage.convertImageByte(this.document.renderImageFloatRGBA(null)); } - + /** * set the fill color * @param color Color to set on fill @@ -211,7 +215,7 @@ public class GraphicContext { public void setColorFill(final Color color) { this.paintState.setFill(color); } - + /** * set the stroke color * @param color Color to set on stroke @@ -220,23 +224,23 @@ public class GraphicContext { public void setColorStroke(final Color color) { this.paintState.setStroke(color); } - + public void setLineCap(final CapMode lineCap) { this.paintState.setLineCap(lineCap); } - + public void setLineJoin(final JoinMode lineJoin) { this.paintState.setLineJoin(lineJoin); } - + public void setMiterLimit(final float miterLimit) { this.paintState.setMiterLimit(miterLimit); } - + public void setOpacity(final float opacity) { this.paintState.setOpacity(opacity); } - + /** * Set global size of the Graphic context (output render size) * @param xxx Width of the image @@ -246,7 +250,7 @@ public class GraphicContext { public void setSize(final int xxx, final int yyy) { setSize(new Vector2i(xxx, yyy)); } - + /** * Set global size of the Graphic contexct (output render size) * @param vector2i New size of the image @@ -256,17 +260,18 @@ public class GraphicContext { this.size = size; clear(); } - + public void setStrokeWidth(final float strokeWidth) { this.paintState.setStrokeWidth(strokeWidth); } - + public void text(final Vector2f position, final float height, final String data) { - this.document.addElement(new Text(position, Configs.getConfigFonts().getName(), height, data, this.paintState.clone())); + this.document.addElement( + new Text(position, Configs.getConfigFonts().getName(), height, data, this.paintState.clone())); } - + public void text(final Vector2f position, final String data) { text(position, Configs.getConfigFonts().getSize(), data); } - + } diff --git a/src/org/atriasoft/esvg/Group.java b/src/org/atriasoft/esvg/Group.java index 2ce780d..b005b1a 100644 --- a/src/org/atriasoft/esvg/Group.java +++ b/src/org/atriasoft/esvg/Group.java @@ -3,12 +3,13 @@ package org.atriasoft.esvg; import java.util.ArrayList; import java.util.List; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.util.Dynamic; import org.atriasoft.exml.model.XmlElement; import org.atriasoft.exml.model.XmlNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -16,44 +17,51 @@ import org.atriasoft.exml.model.XmlNode; * @license MPL v2.0 (see license file) */ public class Group extends Base { + static final Logger LOGGER = LoggerFactory.getLogger(Group.class); private final List subElementList = new ArrayList<>(); //!< sub elements ... - + public Group(final PaintState parentPaintState) { super(parentPaintState); } - + @Override 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); + LOGGER.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 (final Base it : this.subElementList) { if (it != null) { it.display(spacing + 1); } } - Log.debug(spacingDist(spacing) + "Group (STOP)"); + LOGGER.debug(spacingDist(spacing) + "Group (STOP)"); } - + @Override public void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW esvg::group"); - for (Base it : this.subElementList) { + LOGGER.trace(spacingDist(level) + "DRAW esvg::group"); + for (final Base it : this.subElementList) { if (it != null) { it.draw(myRenderer, basicTrans, level + 1); } } } - + @Override - public void drawShapePoints(final List> out, final int recurtionMax, final float threshold, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW shape esvg::group"); - for (Base it : this.subElementList) { + public void drawShapePoints( + final List> out, + final int recurtionMax, + final float threshold, + final Matrix2x3f basicTrans, + final int level) { + LOGGER.trace(spacingDist(level) + "DRAW shape esvg::group"); + for (final Base it : this.subElementList) { if (it != null) { it.drawShapePoints(out, recurtionMax, threshold, basicTrans, level + 1); } } } - + @Override public boolean parseXML(final XmlElement element, final Matrix2x3f parentTrans, final Dynamic sizeMax) { if (element == null) { @@ -66,18 +74,18 @@ public class Group extends Base { pos = parseXmlPosition(element); size = parseXmlSize(element); parsePaintAttr(element); - Log.verbose("parsed G1. trans : " + this.transformMatrix); - + LOGGER.trace("parsed G1. trans : " + this.transformMatrix); + // add the property of the parrent modifications ... this.transformMatrix = this.transformMatrix.multiply(parentTrans); - - Log.verbose("parsed G2. trans : " + this.transformMatrix); - + + LOGGER.trace("parsed G2. trans : " + this.transformMatrix); + sizeMax.value = Vector2f.ZERO; - Dynamic tmpPos = new Dynamic(Vector2f.ZERO); + final Dynamic tmpPos = new Dynamic<>(Vector2f.ZERO); // parse all sub node : - for (XmlNode it : element.getNodes()) { - if (!(it instanceof XmlElement child)) { + for (final XmlNode it : element.getNodes()) { + if (!(it instanceof final XmlElement child)) { // can be a comment ... continue; } @@ -103,14 +111,15 @@ public class Group extends Base { } else if (child.getValue().equals("text")) { elementParser = new Text(this.paint); } else { - Log.error("node not suported : '" + child.getValue() + "' must be [g,a,path,rect,circle,ellipse,line,polyline,polygon,text]"); + LOGGER.error("node not suported : '" + child.getValue() + + "' must be [g,a,path,rect,circle,ellipse,line,polyline,polygon,text]"); } if (elementParser == null) { - Log.error("error on node: '" + child.getValue() + "' allocation error or not supported ..."); + LOGGER.error("error on node: '" + child.getValue() + "' allocation error or not supported ..."); continue; } if (!elementParser.parseXML(child, this.transformMatrix, tmpPos)) { - Log.error(" error on node: '" + child.getValue() + "' Sub Parsing ERROR"); + LOGGER.error(" error on node: '" + child.getValue() + "' Sub Parsing ERROR"); elementParser = null; continue; } diff --git a/src/org/atriasoft/esvg/Line.java b/src/org/atriasoft/esvg/Line.java index 025234e..1edeb59 100644 --- a/src/org/atriasoft/esvg/Line.java +++ b/src/org/atriasoft/esvg/Line.java @@ -3,7 +3,6 @@ package org.atriasoft.esvg; import java.util.ArrayList; import java.util.List; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.esvg.render.DynamicColor; import org.atriasoft.esvg.render.PathModel; import org.atriasoft.esvg.render.Point; @@ -14,6 +13,8 @@ import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.util.Dynamic; import org.atriasoft.exml.model.XmlElement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -21,47 +22,49 @@ import org.atriasoft.exml.model.XmlElement; * @license MPL v2.0 (see license file) */ public class Line extends Base { + static final Logger LOGGER = LoggerFactory.getLogger(Line.class); private Vector2f startPos = Vector2f.ZERO; //!< Start line position private Vector2f stopPos = Vector2f.ZERO; //!< Stop line position - + public Line(final PaintState parentPaintState) { super(parentPaintState); } - + public Line(final Vector2f startPos, final Vector2f stopPos, final PaintState parentPaintState) { super(parentPaintState); this.startPos = startPos; this.stopPos = stopPos; } - + private PathModel createPath() { - PathModel out = new PathModel(); + final PathModel out = new PathModel(); out.clear(); out.moveTo(false, this.startPos); out.lineTo(false, this.stopPos); out.stop(); return out; } - + @Override public void display(final int spacing) { - Log.debug(spacingDist(spacing) + "Line " + this.startPos + " to " + this.stopPos); + LOGGER.debug(spacingDist(spacing) + "Line " + this.startPos + " to " + this.stopPos); } - + @Override public void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW esvg::Line"); - - PathModel listElement = createPath(); - - Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); - + LOGGER.trace(spacingDist(level) + "DRAW esvg::Line"); + + final PathModel listElement = createPath(); + + final Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); + PointList listPoints = new PointList(); - listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), myRenderer.getInterpolationThreshold()); - SegmentList listSegmentStroke = new SegmentList(); - Weight tmpFill = new Weight(); - Weight tmpStroke = new Weight(); - DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); + listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), + myRenderer.getInterpolationThreshold()); + final SegmentList listSegmentStroke = new SegmentList(); + final Weight tmpFill = new Weight(); + final Weight tmpStroke = new Weight(); + final DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); DynamicColor colorStroke = null; if (this.paint.strokeWidth > 0.0f) { colorStroke = DynamicColor.createColor(this.paint.stroke, mtx); @@ -70,7 +73,8 @@ public class Line extends Base { // No background ... // check if we need to display stroke: if (colorStroke != null) { - listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, this.paint.lineJoin, this.paint.miterLimit); + listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, + this.paint.lineJoin, this.paint.miterLimit); colorStroke.setViewPort(listSegmentStroke.getViewPort()); listSegmentStroke.applyMatrix(mtx); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule @@ -79,24 +83,29 @@ public class Line extends Base { // add on images: myRenderer.print(tmpFill, colorFill, tmpStroke, colorStroke, this.paint.opacity); } - + @Override - public void drawShapePoints(final List> out, final int recurtionMax, final float threshold, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW Shape esvg::Line"); - PathModel listElement = createPath(); - Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); + public void drawShapePoints( + final List> out, + final int recurtionMax, + final float threshold, + final Matrix2x3f basicTrans, + final int level) { + LOGGER.trace(spacingDist(level) + "DRAW Shape esvg::Line"); + final PathModel listElement = createPath(); + final Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); PointList listPoints; listPoints = listElement.generateListPoints(level, recurtionMax, threshold); listPoints.applyMatrix(mtx); - for (List it : listPoints.data) { - List listPoint = new ArrayList<>(); - for (Point itDot : it) { + for (final List it : listPoints.data) { + final List listPoint = new ArrayList<>(); + for (final Point itDot : it) { listPoint.add(itDot.pos); } out.add(listPoint); } } - + @Override public boolean parseXML(final XmlElement element, final Matrix2x3f parentTrans, final Dynamic sizeMax) { // line must have a minimum size... @@ -106,10 +115,10 @@ public class Line extends Base { } parseTransform(element); parsePaintAttr(element); - + // add the property of the parrent modifications ... this.transformMatrix = this.transformMatrix.multiply(parentTrans); - + String content = element.getAttribute("x1", ""); if (content.length() != 0) { this.startPos = this.startPos.withX(parseLength(content)); diff --git a/src/org/atriasoft/esvg/LinearGradient.java b/src/org/atriasoft/esvg/LinearGradient.java index 703b3ee..402416b 100644 --- a/src/org/atriasoft/esvg/LinearGradient.java +++ b/src/org/atriasoft/esvg/LinearGradient.java @@ -3,7 +3,6 @@ package org.atriasoft.esvg; import java.util.ArrayList; import java.util.List; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.etk.Color; import org.atriasoft.etk.Dimension2f; import org.atriasoft.etk.Distance; @@ -14,6 +13,8 @@ import org.atriasoft.etk.util.Dynamic; import org.atriasoft.etk.util.Pair; import org.atriasoft.exml.model.XmlElement; import org.atriasoft.exml.model.XmlNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -22,63 +23,64 @@ import org.atriasoft.exml.model.XmlNode; */ public class LinearGradient extends Base { + static final Logger LOGGER = LoggerFactory.getLogger(LinearGradient.class); private final List> data = new ArrayList<>(); //!< gradient position x1 y1 private String href = ""; //!< gradient position x2 y2 private Dimension2f pos1 = new Dimension2f(new Vector2f(50, 50), Distance.POURCENT); private Dimension2f pos2 = new Dimension2f(new Vector2f(50, 50), Distance.POURCENT); - + public SpreadMethod spread = SpreadMethod.PAD; //!< in case of using a single gradient in multiple gradient, the gradient is store in an other element... - + public GradientUnits unit = GradientUnits.GRADIENT_UNITS_OBJECT_BOUNDING_BOX; //!< incompatible with href - + public LinearGradient(final PaintState parentPaintState) { super(parentPaintState); } - + @Override public void display(final int spacing) { - - Log.debug(spacingDist(spacing) + "LinearGradient " + this.pos1 + " to " + this.pos2); - for (Pair it : this.data) { - Log.debug(spacingDist(spacing + 1) + "STOP: offset=" + it.first + " color=" + it.second); + + LOGGER.debug(spacingDist(spacing) + "LinearGradient " + this.pos1 + " to " + this.pos2); + for (final Pair it : this.data) { + LOGGER.debug(spacingDist(spacing + 1) + "STOP: offset=" + it.first + " color=" + it.second); } } - + @Override public void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW esvg::LinearGradient"); + LOGGER.trace(spacingDist(level) + "DRAW esvg::LinearGradient"); } - + public List> getColors(final EsvgDocument document) { if (this.href.isEmpty()) { return this.data; } if (document == null) { - Log.error("Get null input for document"); + LOGGER.error("Get null input for document"); return this.data; } - Base base = document.getReference(this.href); + final Base base = document.getReference(this.href); if (base == null) { - Log.error("Can not get base : '" + this.href + "'"); + LOGGER.error("Can not get base : '" + this.href + "'"); return this.data; } - if (base instanceof RadialGradient gradientR) { + if (base instanceof final RadialGradient gradientR) { return gradientR.getColors(document); } - if (base instanceof LinearGradient gradientL) { + if (base instanceof final LinearGradient gradientL) { return gradientL.getColors(document); } return this.data; } - + public Dimension2f getPosition1() { return this.pos1; } - + public Dimension2f getPosition2() { return this.pos2; } - + @Override public boolean parseXML(final XmlElement element, final Matrix2x3f parentTrans, final Dynamic sizeMax) { { @@ -87,16 +89,16 @@ public class LinearGradient extends Base { if (element == null) { return false; } - + // ---------------- get unique ID ---------------- this.id = element.getAttribute("id", ""); - + //parseTransform(element); //parsePaintAttr(element); - + // add the property of the parrent modifications ... this.transformMatrix = this.transformMatrix.multiply(parentTrans); - + String contentX = element.getAttribute("x1", ""); String contentY = element.getAttribute("y1", ""); if (!contentX.isEmpty() && !contentY.isEmpty()) { @@ -113,7 +115,8 @@ public class LinearGradient extends Base { } else { this.unit = GradientUnits.GRADIENT_UNITS_OBJECT_BOUNDING_BOX; if (contentX.length() != 0 && contentX != "objectBoundingBox") { - Log.error("Parsing error of 'gradientUnits' ==> not suported value: '" + contentX + "' not in : {userSpaceOnUse/objectBoundingBox} use objectBoundingBox"); + LOGGER.error("Parsing error of 'gradientUnits' ==> not suported value: '" + contentX + + "' not in : {userSpaceOnUse/objectBoundingBox} use objectBoundingBox"); } } contentX = element.getAttribute("spreadMethod", ""); @@ -124,7 +127,8 @@ public class LinearGradient extends Base { } else { this.spread = SpreadMethod.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"); + LOGGER.error("Parsing error of 'spreadMethod' ==> not suported value: '" + contentX + + "' not in : {reflect/repeate/pad} use pad"); } } // note: xlink:href is incompatible with subNode "stop" @@ -133,19 +137,20 @@ public class LinearGradient extends Base { this.href = this.href.substring(1); } // parse all sub node : - for (XmlNode it : element.getNodes()) { - if (it instanceof XmlElement child) { + for (final XmlNode it : element.getNodes()) { + if (it instanceof final XmlElement child) { if (child.getValue().equals("stop")) { float offset = 100; Color stopColor = Color.NONE; String content = child.getAttribute("offset", ""); if (content.length() != 0) { - Pair tmp = parseLength2(content); + final Pair tmp = parseLength2(content); if (tmp.second == Distance.PIXEL) { // special case ==> all time % then no type define ==> % in [0.0 .. 1.0] offset = tmp.first * 100.0f; } else if (tmp.second != Distance.POURCENT) { - Log.error("offset : " + content + " res=" + tmp.first + "," + tmp.second + " Not support other than pourcent %"); + LOGGER.error("offset : " + content + " res=" + tmp.first + "," + tmp.second + + " Not support other than pourcent %"); } else { offset = tmp.first; } @@ -153,29 +158,30 @@ public class LinearGradient extends Base { content = child.getAttribute("stop-color", ""); if (content.length() != 0) { stopColor = parseColor(content).first; - Log.verbose(" color : '" + content + "' == > " + stopColor); + LOGGER.trace(" color : '" + content + "' == > " + stopColor); } content = child.getAttribute("stop-opacity", ""); if (content.length() != 0) { float opacity = parseLength(content); opacity = FMath.avg(0.0f, opacity, 1.0f); stopColor = stopColor.withA(opacity); - Log.verbose(" opacity : '" + content + "' == > " + stopColor); + LOGGER.trace(" opacity : '" + content + "' == > " + stopColor); } this.data.add(new Pair<>(offset, stopColor)); } else { - Log.error(" node not suported : '" + child.getValue() + "' must be [stop]"); + LOGGER.error(" node not suported : '" + child.getValue() + "' must be [stop]"); } } } if (this.data.size() != 0) { if (!this.href.isEmpty()) { - Log.error(" node can not have an xlink:href element with sub node named: stop ==> removing href"); + LOGGER.error( + " node can not have an xlink:href element with sub node named: stop ==> removing href"); this.href = ""; } } return true; } - + } } diff --git a/src/org/atriasoft/esvg/Path.java b/src/org/atriasoft/esvg/Path.java index 04d2f8e..7e647be 100644 --- a/src/org/atriasoft/esvg/Path.java +++ b/src/org/atriasoft/esvg/Path.java @@ -3,7 +3,6 @@ package org.atriasoft.esvg; import java.util.ArrayList; import java.util.List; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.esvg.render.DynamicColor; import org.atriasoft.esvg.render.PathModel; import org.atriasoft.esvg.render.Point; @@ -15,6 +14,8 @@ import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.util.Dynamic; import org.atriasoft.exml.model.XmlElement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -22,6 +23,8 @@ import org.atriasoft.exml.model.XmlElement; * @license MPL v2.0 (see license file) */ public class Path extends Base { + static final Logger LOGGER = LoggerFactory.getLogger(Path.class); + private record Command( char cmd, String[] listElem, @@ -31,42 +34,43 @@ public class Path extends Base { this.listElem = listElem; this.offset = offset; } - + Command(final char cmd, final int offset) { this(cmd, null, offset); } - + } - + public static PathModel createPathModel(final String d) { final PathModel out = new PathModel(); - Log.verbose("Parse Path : \"" + d + "\""); + LOGGER.trace("Parse Path : \"" + d + "\""); final List commandsSplited = Path.splitCommand(d); String[] listDot = null; - + // TODO REWORK this, can be done with a simple split and search in a list... - for (Command sss = Path.extractCmd(commandsSplited, 0); sss != null; sss = Path.extractCmd(commandsSplited, sss.offset())) { + for (Command sss = Path.extractCmd(commandsSplited, 0); sss != null; + sss = Path.extractCmd(commandsSplited, sss.offset())) { boolean relative = false; listDot = sss.listElem(); - - // Log.verbose("Find new command : '" + sss.cmd + "'"); + + // LOGGER.trace("Find new command : '" + sss.cmd + "'"); // if (listDot != null) { // for (int jjj = 0; jjj < listDot.length; jjj++) { - // Log.verbose(" -> '" + listDot[jjj] + "'"); + // LOGGER.trace(" -> '" + listDot[jjj] + "'"); // } // } else { - // Log.verbose(" -> no elements"); + // LOGGER.trace(" -> no elements"); // } switch (sss.cmd) { case 'm': // Move to (relative) relative = true; case 'M': // Move to (absolute) if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); break; } if (listDot.length % 2 != 0) { - Log.warning("the PATH command " + sss.cmd + " must be a multiple of 2"); + LOGGER.warn("the PATH command " + sss.cmd + " must be a multiple of 2"); break; } // 2 Elements ... @@ -74,134 +78,145 @@ public class Path extends Base { out.moveTo(relative, new Vector2f(Float.parseFloat(listDot[0]), Float.parseFloat(listDot[1]))); } for (int iii = 2; iii < listDot.length; iii += 2) { - out.lineTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1]))); + out.lineTo(relative, + new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1]))); } break; case 'l': // Line to (relative) relative = true; case 'L': // Line to (absolute) if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); break; } if (listDot.length % 2 != 0) { - Log.warning("the PATH command " + sss.cmd + " must be a multiple of 2"); + LOGGER.warn("the PATH command " + sss.cmd + " must be a multiple of 2"); break; } for (int iii = 0; iii < listDot.length; iii += 2) { - out.lineTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1]))); + out.lineTo(relative, + new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1]))); } break; - + case 'v': // Vertical Line to (relative) relative = true; case 'V': // Vertical Line to (absolute) // 1 Element ... if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); break; } - for (int iii = 0; iii < listDot.length; iii++) { - out.lineToV(relative, Float.parseFloat(listDot[iii])); + for (final String element : listDot) { + out.lineToV(relative, Float.parseFloat(element)); } break; - + case 'h': // Horizantal Line to (relative) relative = true; case 'H': // Horizantal Line to (absolute) // 1 Element ... if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); break; } - for (int iii = 0; iii < listDot.length; iii++) { - out.lineToH(relative, Float.parseFloat(listDot[iii])); + for (final String element : listDot) { + out.lineToH(relative, Float.parseFloat(element)); } 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); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); break; } // 4 Elements ... if (listDot.length % 4 != 0) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length + " (must have 4 numbers)"); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + + listDot.length + " (must have 4 numbers)"); break; } for (int iii = 0; iii < listDot.length; iii += 4) { - out.bezierCurveTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1])), + out.bezierCurveTo(relative, + new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1])), new Vector2f(Float.parseFloat(listDot[iii + 2]), Float.parseFloat(listDot[iii + 3]))); } break; - + case 't': // smooth quadratic Bezier curve to (relative) relative = true; case 'T': // smooth quadratic Bezier curve to (absolute) if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); break; } // 4 Elements ... if (listDot.length % 2 != 0) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length + " (must have 2 numbers)"); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + + listDot.length + " (must have 2 numbers)"); break; } // 2 Elements ... for (int iii = 0; iii < listDot.length; iii += 2) { - out.bezierSmoothCurveTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1]))); + out.bezierSmoothCurveTo(relative, + new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1]))); } 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); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); break; } // 6 Elements ... if (listDot.length % 6 != 0) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length + "(Must be a multiple of 6)"); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + + listDot.length + "(Must be a multiple of 6)"); break; } for (int iii = 0; iii < listDot.length; iii += 6) { - out.curveTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1])), + out.curveTo(relative, + new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1])), new Vector2f(Float.parseFloat(listDot[iii + 2]), Float.parseFloat(listDot[iii + 3])), new Vector2f(Float.parseFloat(listDot[iii + 4]), Float.parseFloat(listDot[iii + 5]))); } 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); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); break; } // 4 Elements ... if (listDot.length % 4 != 0) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length + "(Must be a multiple of 4)"); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + + listDot.length + "(Must be a multiple of 4)"); break; } for (int iii = 0; iii < listDot.length; iii += 4) { - out.smoothCurveTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1])), + out.smoothCurveTo(relative, + new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1])), new Vector2f(Float.parseFloat(listDot[iii + 2]), Float.parseFloat(listDot[iii + 3]))); } break; - + case 'a': // elliptical Arc (relative) relative = true; case 'A': // elliptical Arc (absolute) if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + LOGGER.warn("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 % 7 != 0) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + + listDot.length); break; } for (int iii = 0; iii < listDot.length; iii += 7) { @@ -213,7 +228,9 @@ public class Path extends Base { if (Integer.parseInt(listDot[iii + 4]) == 0) { sweepFlag = false; } - out.ellipticTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1])), Float.parseFloat(listDot[iii + 2]), largeArcFlag, sweepFlag, + out.ellipticTo(relative, + new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1])), + Float.parseFloat(listDot[iii + 2]), largeArcFlag, sweepFlag, new Vector2f(Float.parseFloat(listDot[iii + 5]), Float.parseFloat(listDot[iii + 6]))); } break; @@ -222,38 +239,39 @@ public class Path extends Base { case 'Z': // closepath (absolute) // 0 Element ... if (listDot != null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length); + LOGGER.warn("the PATH command " + sss.cmd + " has not the good number of element = " + + listDot.length); break; } out.close(relative); break; default: - Log.error("Unknow error : '" + sss.cmd + "'"); + LOGGER.error("Unknow error : '" + sss.cmd + "'"); } } return out; } - + //return the next char position ... (after 'X' or NULL) private static Command extractCmd(final List input, final int offset) { if (input.size() <= offset) { - // Log.warning("parse command : END"); + // LOGGER.warn("parse command : END"); return null; } - // Log.warning("parse command : (rest) " + offset); + // LOGGER.warn("parse command : (rest) " + offset); // for (int iii = offset; iii < input.size(); iii++) { - // Log.warning(" -[" + iii + "] '" + input.get(iii) + "'"); + // LOGGER.warn(" -[" + iii + "] '" + input.get(iii) + "'"); // } if (input.get(offset).length() != 1) { - Log.error("Error in the SVG Path : '" + input.get(offset) + "' [" + Integer.toString(offset)); + LOGGER.error("Error in the SVG Path : '" + input.get(offset) + "' [" + Integer.toString(offset)); return null; } final char cmd = input.get(offset).charAt(0); if (!((cmd <= 'Z' && cmd >= 'A') || (cmd <= 'z' && cmd >= 'a'))) { - Log.error("Error in the SVG Path : '" + cmd + "' [" + Integer.toString(offset)); + LOGGER.error("Error in the SVG Path : '" + cmd + "' [" + Integer.toString(offset)); return null; } - //Log.verbose("Find command : " + cmd); + //LOGGER.trace("Find command : " + cmd); if (input.size() == offset) { return new Command(cmd, offset + 1); } @@ -275,7 +293,7 @@ public class Path extends Base { } return new Command(cmd, outputList, iii); } - + static List splitCommand(final String data) { final List out = new ArrayList<>(); final StringBuilder tmpString = new StringBuilder(20); @@ -300,7 +318,7 @@ public class Path extends Base { isNumber = false; out.add(Character.toString(it)); } else { - Log.error("Can not parse path : '" + it + "'"); + LOGGER.error("Can not parse path : '" + it + "'"); } } final String elements = tmpString.toString(); @@ -309,31 +327,32 @@ public class Path extends Base { } return out; } - + public PathModel listElement = new PathModel(); - + public Path(final PaintState parentPaintState) { super(parentPaintState); } - + public Path(final PathModel elements, final PaintState parentPaintState) { super(parentPaintState); this.listElement = elements; } - + @Override void display(final int spacing) { this.listElement.display(spacing); } - + @Override void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW esvg::Path"); - + LOGGER.trace(spacingDist(level) + "DRAW esvg::Path"); + final Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); - + PointList listPoints = new PointList(); - listPoints = this.listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), myRenderer.getInterpolationThreshold()); + listPoints = this.listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), + myRenderer.getInterpolationThreshold()); //listPoints.applyMatrix(mtx); final SegmentList listSegmentFill = new SegmentList(); final SegmentList listSegmentStroke = new SegmentList(); @@ -354,7 +373,8 @@ public class Path extends Base { } // check if we need to display stroke: if (colorStroke != null) { - listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, this.paint.lineJoin, this.paint.miterLimit); + listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, + this.paint.lineJoin, this.paint.miterLimit); colorStroke.setViewPort(listSegmentStroke.getViewPort()); listSegmentStroke.applyMatrix(mtx); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule @@ -366,15 +386,20 @@ public class Path extends Base { //myRenderer.addDebugSegment(listSegmentStroke); //this.listElement.debugInformation.applyMatrix(mtx); //myRenderer.addDebugSegment(this.listElement.debugInformation); - + } - + @Override - void drawShapePoints(final List> out, final int recurtionMax, final float threshold, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW Shape esvg::Path"); - + void drawShapePoints( + final List> out, + final int recurtionMax, + final float threshold, + final Matrix2x3f basicTrans, + final int level) { + LOGGER.trace(spacingDist(level) + "DRAW Shape esvg::Path"); + final Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); - + PointList listPoints = new PointList(); listPoints = this.listElement.generateListPoints(level, recurtionMax, threshold); listPoints.applyMatrix(mtx); @@ -386,7 +411,7 @@ public class Path extends Base { out.add(listPoint); } } - + @Override boolean parseXML(final XmlElement element, final Matrix2x3f parentTrans, final Dynamic sizeMax) { if (element == null) { @@ -394,17 +419,17 @@ public class Path extends Base { } parseTransform(element); parsePaintAttr(element); - + // add the property of the parrent modifications ... this.transformMatrix = this.transformMatrix.multiply(parentTrans); - + final String elementXML1 = element.getAttribute("d", ""); if (elementXML1.length() == 0) { - Log.warning("path: missing 'd' attribute or empty"); + LOGGER.warn("path: missing 'd' attribute or empty"); return false; } this.listElement = Path.createPathModel(elementXML1); return this.listElement != null; } - + } diff --git a/src/org/atriasoft/esvg/Polygon.java b/src/org/atriasoft/esvg/Polygon.java index f0f2524..daae6b6 100644 --- a/src/org/atriasoft/esvg/Polygon.java +++ b/src/org/atriasoft/esvg/Polygon.java @@ -1,5 +1,8 @@ package org.atriasoft.esvg; +import java.util.ArrayList; +import java.util.List; + import org.atriasoft.esvg.render.DynamicColor; import org.atriasoft.esvg.render.PathModel; import org.atriasoft.esvg.render.Point; @@ -10,11 +13,8 @@ import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.util.Dynamic; import org.atriasoft.exml.model.XmlElement; - -import java.util.ArrayList; -import java.util.List; - -import org.atriasoft.esvg.internal.Log; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -23,14 +23,15 @@ import org.atriasoft.esvg.internal.Log; */ public class Polygon extends Base { + static final Logger LOGGER = LoggerFactory.getLogger(Polygon.class); private final List listPoint = new ArrayList<>(); //!< list of all point of the polygone - + public Polygon(final PaintState parentPaintState) { super(parentPaintState); } - + private PathModel createPath() { - PathModel out = new PathModel(); + final PathModel out = new PathModel(); out.moveTo(false, this.listPoint.get(0)); for (int iii = 1; iii < this.listPoint.size(); iii++) { out.lineTo(false, this.listPoint.get(iii)); @@ -38,28 +39,29 @@ public class Polygon extends Base { out.close(); return out; } - + @Override public void display(final int spacing) { - Log.debug(spacingDist(spacing) + "Polygon nbPoint=" + this.listPoint.size()); + LOGGER.debug(spacingDist(spacing) + "Polygon nbPoint=" + this.listPoint.size()); } - + @Override public void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW esvg::Polygon"); - - PathModel listElement = createPath(); - - Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); - + LOGGER.trace(spacingDist(level) + "DRAW esvg::Polygon"); + + final PathModel listElement = createPath(); + + final Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); + PointList listPoints = new PointList(); - listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), myRenderer.getInterpolationThreshold()); + listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), + myRenderer.getInterpolationThreshold()); //listPoints.applyMatrix(mtx); - SegmentList listSegmentFill = new SegmentList(); - SegmentList listSegmentStroke = new SegmentList(); - Weight tmpFill = new Weight(); - Weight tmpStroke = new Weight(); - DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); + final SegmentList listSegmentFill = new SegmentList(); + final SegmentList listSegmentStroke = new SegmentList(); + final Weight tmpFill = new Weight(); + final Weight tmpStroke = new Weight(); + final DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); DynamicColor colorStroke = null; if (this.paint.strokeWidth > 0.0f) { colorStroke = DynamicColor.createColor(this.paint.stroke, mtx); @@ -74,7 +76,8 @@ public class Polygon extends Base { } // check if we need to display stroke: if (colorStroke != null) { - listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, this.paint.lineJoin, this.paint.miterLimit); + listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, + this.paint.lineJoin, this.paint.miterLimit); colorStroke.setViewPort(listSegmentStroke.getViewPort()); listSegmentStroke.applyMatrix(mtx); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule @@ -85,24 +88,29 @@ public class Polygon extends Base { //myRenderer.addDebugSegment(listSegmentFill); //myRenderer.addDebugSegment(listSegmentStroke); } - + @Override - public void drawShapePoints(final List> out, final int recurtionMax, final float threshold, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW Shape esvg::Polygon"); - PathModel listElement = createPath(); - Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); + public void drawShapePoints( + final List> out, + final int recurtionMax, + final float threshold, + final Matrix2x3f basicTrans, + final int level) { + LOGGER.trace(spacingDist(level) + "DRAW Shape esvg::Polygon"); + final PathModel listElement = createPath(); + final Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); PointList listPoints; listPoints = listElement.generateListPoints(level, recurtionMax, threshold); listPoints.applyMatrix(mtx); - for (List it : listPoints.data) { - List listPoint = new ArrayList<>(); - for (Point itDot : it) { + for (final List it : listPoints.data) { + final List listPoint = new ArrayList<>(); + for (final Point itDot : it) { listPoint.add(itDot.pos); } out.add(listPoint); } } - + @Override public boolean parseXML(final XmlElement element, final Matrix2x3f parentTrans, final Dynamic sizeMax) { if (element == null) { @@ -110,25 +118,25 @@ public class Polygon extends Base { } parseTransform(element); parsePaintAttr(element); - - Log.verbose("parsed P1. trans: " + this.transformMatrix); - + + LOGGER.trace("parsed P1. trans: " + this.transformMatrix); + // add the property of the parrent modifications ... this.transformMatrix = this.transformMatrix.multiply(parentTrans); - - Log.verbose("parsed P2. trans: " + this.transformMatrix); - - String sss1 = element.getAttribute("points", ""); + + LOGGER.trace("parsed P2. trans: " + this.transformMatrix); + + final String sss1 = element.getAttribute("points", ""); if (sss1.length() == 0) { - Log.error("(l "/*+element.Pos()*/ + ") polygon: missing points attribute"); + LOGGER.error("(l "/*+element.Pos()*/ + ") polygon: missing points attribute"); return false; } - + sizeMax.value = Vector2f.ZERO; - Log.verbose("Parse polyline : '" + sss1 + "'"); - String[] elems = sss1.split(" "); - for (String elem : elems) { - Vector2f pos = Vector2f.valueOf(elem); + LOGGER.trace("Parse polyline : '" + sss1 + "'"); + final String[] elems = sss1.split(" "); + for (final String elem : elems) { + final Vector2f pos = Vector2f.valueOf(elem); this.listPoint.add(pos); sizeMax.value = Vector2f.max(sizeMax.value, pos); } diff --git a/src/org/atriasoft/esvg/Polyline.java b/src/org/atriasoft/esvg/Polyline.java index 9d27d43..4fc9623 100644 --- a/src/org/atriasoft/esvg/Polyline.java +++ b/src/org/atriasoft/esvg/Polyline.java @@ -1,5 +1,8 @@ package org.atriasoft.esvg; +import java.util.ArrayList; +import java.util.List; + import org.atriasoft.esvg.render.DynamicColor; import org.atriasoft.esvg.render.PathModel; import org.atriasoft.esvg.render.Point; @@ -10,11 +13,8 @@ import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.util.Dynamic; import org.atriasoft.exml.model.XmlElement; - -import java.util.ArrayList; -import java.util.List; - -import org.atriasoft.esvg.internal.Log; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -22,14 +22,15 @@ import org.atriasoft.esvg.internal.Log; * @license MPL v2.0 (see license file) */ public class Polyline extends Base { + static final Logger LOGGER = LoggerFactory.getLogger(Polyline.class); private final List listPoint = new ArrayList<>(); //!< list of all point of the polyline - + public Polyline(final PaintState parentPaintState) { super(parentPaintState); } - + private PathModel createPath() { - PathModel out = new PathModel(); + final PathModel out = new PathModel(); out.clear(); out.moveTo(false, this.listPoint.get(0)); for (int iii = 1; iii < this.listPoint.size(); iii++) { @@ -38,28 +39,29 @@ public class Polyline extends Base { out.stop(); return out; } - + @Override public void display(final int spacing) { - Log.debug(spacingDist(spacing) + "Polyline nbPoint=" + this.listPoint.size()); + LOGGER.debug(spacingDist(spacing) + "Polyline nbPoint=" + this.listPoint.size()); } - + @Override public void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW esvg::Polyline"); - - PathModel listElement = createPath(); - - Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); - + LOGGER.trace(spacingDist(level) + "DRAW esvg::Polyline"); + + final PathModel listElement = createPath(); + + final Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); + PointList listPoints; - listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), myRenderer.getInterpolationThreshold()); + listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), + myRenderer.getInterpolationThreshold()); //listPoints.applyMatrix(mtx); - SegmentList listSegmentFill = new SegmentList(); - SegmentList listSegmentStroke = new SegmentList(); - Weight tmpFill = new Weight(); - Weight tmpStroke = new Weight(); - DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); + final SegmentList listSegmentFill = new SegmentList(); + final SegmentList listSegmentStroke = new SegmentList(); + final Weight tmpFill = new Weight(); + final Weight tmpStroke = new Weight(); + final DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); DynamicColor colorStroke = null; if (this.paint.strokeWidth > 0.0f) { colorStroke = DynamicColor.createColor(this.paint.stroke, mtx); @@ -74,7 +76,8 @@ public class Polyline extends Base { } // check if we need to display stroke: if (colorStroke != null) { - listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, this.paint.lineJoin, this.paint.miterLimit); + listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, + this.paint.lineJoin, this.paint.miterLimit); colorStroke.setViewPort(listSegmentStroke.getViewPort()); listSegmentStroke.applyMatrix(mtx); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule @@ -85,24 +88,29 @@ public class Polyline extends Base { //myRenderer.addDebugSegment(listSegmentFill); //myRenderer.addDebugSegment(listSegmentStroke); } - + @Override - public void drawShapePoints(final List> out, final int recurtionMax, final float threshold, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW Shape esvg::Polyline"); - PathModel listElement = createPath(); - Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); + public void drawShapePoints( + final List> out, + final int recurtionMax, + final float threshold, + final Matrix2x3f basicTrans, + final int level) { + LOGGER.trace(spacingDist(level) + "DRAW Shape esvg::Polyline"); + final PathModel listElement = createPath(); + final Matrix2x3f mtx = this.transformMatrix.multiply(basicTrans); PointList listPoints; listPoints = listElement.generateListPoints(level, recurtionMax, threshold); listPoints.applyMatrix(mtx); - for (List it : listPoints.data) { - List listPoint = new ArrayList<>(); - for (Point itDot : it) { + for (final List it : listPoints.data) { + final List listPoint = new ArrayList<>(); + for (final Point itDot : it) { listPoint.add(itDot.pos); } out.add(listPoint); } } - + @Override public boolean parseXML(final XmlElement element, final Matrix2x3f parentTrans, final Dynamic sizeMax) { // line must have a minimum size... @@ -112,20 +120,20 @@ public class Polyline extends Base { } parseTransform(element); parsePaintAttr(element); - + // add the property of the parrent modifications ... this.transformMatrix = this.transformMatrix.multiply(parentTrans); - - String sss1 = element.getAttribute("points", ""); + + final String sss1 = element.getAttribute("points", ""); if (sss1.length() == 0) { - Log.error("polyline: missing points attribute"); + LOGGER.error("polyline: missing points attribute"); return false; } sizeMax.value = Vector2f.ZERO; - Log.verbose("Parse polyline : '" + sss1 + "'"); - String[] elems = sss1.split(" "); - for (String elem : elems) { - Vector2f pos = Vector2f.valueOf(elem); + LOGGER.trace("Parse polyline : '" + sss1 + "'"); + final String[] elems = sss1.split(" "); + for (final String elem : elems) { + final Vector2f pos = Vector2f.valueOf(elem); this.listPoint.add(pos); sizeMax.value = Vector2f.max(sizeMax.value, pos); } diff --git a/src/org/atriasoft/esvg/RadialGradient.java b/src/org/atriasoft/esvg/RadialGradient.java index 2f6ed05..51aa2cc 100644 --- a/src/org/atriasoft/esvg/RadialGradient.java +++ b/src/org/atriasoft/esvg/RadialGradient.java @@ -3,7 +3,6 @@ package org.atriasoft.esvg; import java.util.ArrayList; import java.util.List; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.etk.Color; import org.atriasoft.etk.Dimension1f; import org.atriasoft.etk.Dimension2f; @@ -15,6 +14,8 @@ import org.atriasoft.etk.util.Dynamic; import org.atriasoft.etk.util.Pair; import org.atriasoft.exml.model.XmlElement; import org.atriasoft.exml.model.XmlNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -22,6 +23,7 @@ import org.atriasoft.exml.model.XmlNode; * @license MPL v2.0 (see license file) */ public class RadialGradient extends Base { + static final Logger LOGGER = LoggerFactory.getLogger(RadialGradient.class); private Dimension2f center = new Dimension2f(new Vector2f(50, 50), Distance.POURCENT); //!< gradient position cx cy private final List> data = new ArrayList<>(); //!< incompatible with href private Dimension2f focal = new Dimension2f(new Vector2f(50, 50), Distance.POURCENT); //!< gradient Focal fx fy @@ -29,58 +31,59 @@ public class RadialGradient extends Base { private Dimension1f radius = new Dimension1f(50, Distance.POURCENT); //!< Radius of the gradient public SpreadMethod spread = SpreadMethod.PAD; public GradientUnits unit = GradientUnits.GRADIENT_UNITS_OBJECT_BOUNDING_BOX; - + public RadialGradient(final PaintState parentPaintState) { super(parentPaintState); } - + @Override public void display(final int spacing) { - Log.debug(spacingDist(spacing) + "RadialGradient center=" + this.center + " focal=" + this.focal + " radius=" + this.radius); - for (Pair it : this.data) { - Log.debug(spacingDist(spacing + 1) + "STOP: offset=" + it.first + " color=" + it.second); + LOGGER.debug(spacingDist(spacing) + "RadialGradient center=" + this.center + " focal=" + this.focal + " radius=" + + this.radius); + for (final Pair it : this.data) { + LOGGER.debug(spacingDist(spacing + 1) + "STOP: offset=" + it.first + " color=" + it.second); } } - + @Override public void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW esvg::RadialGradient"); + LOGGER.trace(spacingDist(level) + "DRAW esvg::RadialGradient"); } - + public Dimension2f getCenter() { return this.center; } - + public List> getColors(final EsvgDocument document) { if (this.href.isEmpty()) { return this.data; } if (document == null) { - Log.error("Get null input for document"); + LOGGER.error("Get null input for document"); return this.data; } - Base base = document.getReference(this.href); + final Base base = document.getReference(this.href); if (base == null) { - Log.error("Can not get base : '" + this.href + "'"); + LOGGER.error("Can not get base : '" + this.href + "'"); return this.data; } - if (base instanceof RadialGradient gradientR) { + if (base instanceof final RadialGradient gradientR) { return gradientR.getColors(document); } - if (base instanceof LinearGradient gradientL) { + if (base instanceof final LinearGradient gradientL) { return gradientL.getColors(document); } return this.data; } - + public Dimension2f getFocal() { return this.focal; } - + public Dimension1f getRadius() { return this.radius; } - + @Override public boolean parseXML(final XmlElement element, final Matrix2x3f parentTrans, final Dynamic sizeMax) { // line must have a minimum size... @@ -88,16 +91,16 @@ public class RadialGradient extends Base { if (element == null) { return false; } - + // ---------------- get unique ID ---------------- this.id = element.getAttribute("id", ""); - + //parseTransform(element); //parsePaintAttr(element); - + // add the property of the parrent modifications ... this.transformMatrix = this.transformMatrix.multiply(parentTrans); - + String contentX = element.getAttribute("cx", ""); String contentY = element.getAttribute("cy", ""); if (!contentX.isEmpty() && !contentY.isEmpty()) { @@ -118,7 +121,8 @@ public class RadialGradient extends Base { } else { this.unit = GradientUnits.GRADIENT_UNITS_OBJECT_BOUNDING_BOX; if (contentX.length() != 0 && contentX != "objectBoundingBox") { - Log.error("Parsing error of 'gradientUnits' ==> not suported value: '" + contentX + "' not in : {userSpaceOnUse/objectBoundingBox} use objectBoundingBox"); + LOGGER.error("Parsing error of 'gradientUnits' ==> not suported value: '" + contentX + + "' not in : {userSpaceOnUse/objectBoundingBox} use objectBoundingBox"); } } contentX = element.getAttribute("spreadMethod", ""); @@ -129,7 +133,8 @@ public class RadialGradient extends Base { } else { this.spread = SpreadMethod.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"); + LOGGER.error("Parsing error of 'spreadMethod' ==> not suported value: '" + contentX + + "' not in : {reflect/repeate/pad} use pad"); } } // note: xlink:href is incompatible with subNode "stop" @@ -138,19 +143,20 @@ public class RadialGradient extends Base { this.href = this.href.substring(1); } // parse all sub node : - for (XmlNode it : element.getNodes()) { - if (it instanceof XmlElement child) { + for (final XmlNode it : element.getNodes()) { + if (it instanceof final XmlElement child) { if (child.getValue().equals("stop")) { float offset = 100; Color stopColor = Color.NONE; String content = child.getAttribute("offset", ""); if (content.length() != 0) { - Pair tmp = parseLength2(content); + final Pair tmp = parseLength2(content); if (tmp.second == Distance.PIXEL) { // special case ==> all time % then no type define ==> % in [0.0 .. 1.0] offset = tmp.first * 100.0f; } else if (tmp.second != Distance.POURCENT) { - Log.error("offset : " + content + " res=" + tmp.first + "," + tmp.second + " Not support other than pourcent %"); + LOGGER.error("offset : " + content + " res=" + tmp.first + "," + tmp.second + + " Not support other than pourcent %"); } else { offset = tmp.first; } @@ -158,28 +164,28 @@ public class RadialGradient extends Base { content = child.getAttribute("stop-color", ""); if (content.length() != 0) { stopColor = parseColor(content).first; - Log.verbose(" color : \"" + content + "\" == > " + stopColor); + LOGGER.trace(" color : \"" + content + "\" == > " + stopColor); } content = child.getAttribute("stop-opacity", ""); if (content.length() != 0) { float opacity = parseLength(content); opacity = FMath.avg(0.0f, opacity, 1.0f); stopColor = stopColor.withA(opacity); - Log.verbose(" opacity : '" + content + "' == > " + stopColor); + LOGGER.trace(" opacity : '" + content + "' == > " + stopColor); } this.data.add(new Pair<>(offset, stopColor)); } else { - Log.error("node not suported : '" + child.getValue() + "' must be [stop]"); + LOGGER.error("node not suported : '" + child.getValue() + "' must be [stop]"); } } } if (this.data.size() != 0) { if (!this.href.isEmpty()) { - Log.error("node can not have an xlink:href element with sub node named: stop ==> removing href"); + LOGGER.error("node can not have an xlink:href element with sub node named: stop ==> removing href"); this.href = ""; } } return true; } - + } diff --git a/src/org/atriasoft/esvg/Rectangle.java b/src/org/atriasoft/esvg/Rectangle.java index 88e0c8f..9c2f2dc 100644 --- a/src/org/atriasoft/esvg/Rectangle.java +++ b/src/org/atriasoft/esvg/Rectangle.java @@ -1,20 +1,20 @@ package org.atriasoft.esvg; -import org.atriasoft.etk.math.Matrix2x3f; -import org.atriasoft.exml.model.XmlElement; - import java.util.ArrayList; import java.util.List; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.esvg.render.DynamicColor; import org.atriasoft.esvg.render.PathModel; import org.atriasoft.esvg.render.Point; import org.atriasoft.esvg.render.PointList; import org.atriasoft.esvg.render.SegmentList; import org.atriasoft.esvg.render.Weight; +import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.util.Dynamic; +import org.atriasoft.exml.model.XmlElement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -22,29 +22,31 @@ import org.atriasoft.etk.util.Dynamic; * @license MPL v2.0 (see license file) */ public class Rectangle extends Base { + static final Logger LOGGER = LoggerFactory.getLogger(Rectangle.class); private Vector2f position = Vector2f.ZERO; //!< position of the rectangle private Vector2f roundedCorner = Vector2f.ZERO; //!< property of the rounded corner private Vector2f size = Vector2f.ZERO; //!< size of the rectangle - + public Rectangle(final PaintState parentPaintState) { super(parentPaintState); } - + public Rectangle(final Vector2f position, final Vector2f size, final PaintState parentPaintState) { super(parentPaintState); this.position = position; this.size = size; } - - public Rectangle(final Vector2f position, final Vector2f size, final Vector2f roundedCorner, final PaintState parentPaintState) { + + public Rectangle(final Vector2f position, final Vector2f size, final Vector2f roundedCorner, + final PaintState parentPaintState) { super(parentPaintState); this.position = position; this.size = size; this.roundedCorner = roundedCorner; } - + private PathModel createPath() { - PathModel out = new PathModel(); + final PathModel out = new PathModel(); out.clear(); if (this.roundedCorner.x() == 0.0f || this.roundedCorner.y() == 0.0f) { out.moveTo(false, this.position); @@ -55,43 +57,50 @@ public class Rectangle extends Base { // Rounded rectangle out.moveTo(false, this.position.add(this.roundedCorner.x(), 0.0f)); out.lineToH(true, this.size.x() - this.roundedCorner.x() * 2.0f); - out.curveTo(true, new Vector2f(this.roundedCorner.x() * Base.kappa90, 0.0f), new Vector2f(this.roundedCorner.x(), this.roundedCorner.y() * (1.0f - Base.kappa90)), + out.curveTo(true, new Vector2f(this.roundedCorner.x() * Base.kappa90, 0.0f), + new Vector2f(this.roundedCorner.x(), this.roundedCorner.y() * (1.0f - Base.kappa90)), new Vector2f(this.roundedCorner.x(), this.roundedCorner.y())); out.lineToV(true, this.size.y() - this.roundedCorner.y() * 2.0f); - out.curveTo(true, new Vector2f(0.0f, this.roundedCorner.y() * Base.kappa90), new Vector2f(-this.roundedCorner.x() * (1.0f - Base.kappa90), this.roundedCorner.y()), + out.curveTo(true, new Vector2f(0.0f, this.roundedCorner.y() * Base.kappa90), + new Vector2f(-this.roundedCorner.x() * (1.0f - Base.kappa90), this.roundedCorner.y()), new Vector2f(-this.roundedCorner.x(), this.roundedCorner.y())); out.lineToH(true, -(this.size.x() - this.roundedCorner.x() * 2.0f)); - out.curveTo(true, new Vector2f(-this.roundedCorner.x() * Base.kappa90, 0.0f), new Vector2f(-this.roundedCorner.x(), -this.roundedCorner.y() * (1.0f - Base.kappa90)), + out.curveTo(true, new Vector2f(-this.roundedCorner.x() * Base.kappa90, 0.0f), + new Vector2f(-this.roundedCorner.x(), -this.roundedCorner.y() * (1.0f - Base.kappa90)), new Vector2f(-this.roundedCorner.x(), -this.roundedCorner.y())); out.lineToV(true, -(this.size.y() - this.roundedCorner.y() * 2.0f)); - out.curveTo(true, new Vector2f(0.0f, -this.roundedCorner.y() * Base.kappa90), new Vector2f(this.roundedCorner.x() * (1.0f - Base.kappa90), -this.roundedCorner.y()), + out.curveTo(true, new Vector2f(0.0f, -this.roundedCorner.y() * Base.kappa90), + new Vector2f(this.roundedCorner.x() * (1.0f - Base.kappa90), -this.roundedCorner.y()), new Vector2f(this.roundedCorner.x(), -this.roundedCorner.y())); } out.close(); return out; } - + @Override public void display(final int spacing) { - Log.debug(spacingDist(spacing) + "Rectangle : pos=" + this.position + " size=" + this.size + " corner=" + this.roundedCorner); + LOGGER.debug(spacingDist(spacing) + "Rectangle : pos=" + this.position + " size=" + this.size + " corner=" + + this.roundedCorner); } - + @Override public void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW esvg::Rectangle: fill=" + this.paint.fill.first + "/" + this.paint.fill.second + " stroke=" + this.paint.stroke.first + "/" + this.paint.stroke.second); - PathModel listElement = createPath(); - + LOGGER.trace(spacingDist(level) + "DRAW esvg::Rectangle: fill=" + this.paint.fill.first + "/" + + this.paint.fill.second + " stroke=" + this.paint.stroke.first + "/" + this.paint.stroke.second); + final PathModel listElement = createPath(); + Matrix2x3f mtx = this.transformMatrix; mtx = mtx.multiply(basicTrans); listElement.display(2); PointList listPoints = new PointList(); - listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), myRenderer.getInterpolationThreshold()); + listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), + myRenderer.getInterpolationThreshold()); //listPoints.applyMatrix(mtx); - SegmentList listSegmentFill = new SegmentList(); - SegmentList listSegmentStroke = new SegmentList(); - Weight tmpFill = new Weight(); - Weight tmpStroke = new Weight(); - DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); + final SegmentList listSegmentFill = new SegmentList(); + final SegmentList listSegmentStroke = new SegmentList(); + final Weight tmpFill = new Weight(); + final Weight tmpStroke = new Weight(); + final DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); DynamicColor colorStroke = null; if (this.paint.strokeWidth > 0.0f) { colorStroke = DynamicColor.createColor(this.paint.stroke, mtx); @@ -106,7 +115,8 @@ public class Rectangle extends Base { } // check if we need to display stroke: if (colorStroke != null) { - listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, this.paint.lineJoin, this.paint.miterLimit); + listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, + this.paint.lineJoin, this.paint.miterLimit); colorStroke.setViewPort(listSegmentStroke.getViewPort()); listSegmentStroke.applyMatrix(mtx); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule @@ -116,27 +126,32 @@ public class Rectangle extends Base { myRenderer.print(tmpFill, colorFill, tmpStroke, colorStroke, this.paint.opacity); //myRenderer.addDebugSegment(listSegmentFill); //myRenderer.addDebugSegment(listSegmentStroke) - + } - + @Override - public void drawShapePoints(final List> out, final int recurtionMax, final float threshold, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW Shape esvg::Rectangle"); - PathModel listElement = createPath(); + public void drawShapePoints( + final List> out, + final int recurtionMax, + final float threshold, + final Matrix2x3f basicTrans, + final int level) { + LOGGER.trace(spacingDist(level) + "DRAW Shape esvg::Rectangle"); + final PathModel listElement = createPath(); Matrix2x3f mtx = this.transformMatrix; mtx = mtx.multiply(basicTrans); PointList listPoints; listPoints = listElement.generateListPoints(level, recurtionMax, threshold); listPoints.applyMatrix(mtx); - for (List it : listPoints.data) { - List listPoint = new ArrayList<>(); - for (Point itDot : it) { + for (final List it : listPoints.data) { + final List listPoint = new ArrayList<>(); + for (final Point itDot : it) { listPoint.add(itDot.pos); } out.add(listPoint); } } - + @Override public boolean parseXML(final XmlElement element, final Matrix2x3f parentTrans, final Dynamic sizeMax) { if (element == null) { @@ -145,16 +160,16 @@ public class Rectangle extends Base { this.position = Vector2f.ZERO; this.size = Vector2f.ZERO; this.roundedCorner = Vector2f.ZERO; - + parseTransform(element); parsePaintAttr(element); - + // add the property of the parrent modifications ... this.transformMatrix = this.transformMatrix.multiply(parentTrans); - + this.position = parseXmlPosition(element); this.size = parseXmlSize(element); - + String content = element.getAttribute("rx", ""); if (content.length() != 0) { this.roundedCorner = this.roundedCorner.withX(parseLength(content)); @@ -163,7 +178,8 @@ public class Rectangle extends Base { if (content.length() != 0) { this.roundedCorner = this.roundedCorner.withY(parseLength(content)); } - sizeMax.value = new Vector2f(this.position.x() + this.size.x() + this.paint.strokeWidth, this.position.y() + this.size.y() + this.paint.strokeWidth); + sizeMax.value = new Vector2f(this.position.x() + this.size.x() + this.paint.strokeWidth, + this.position.y() + this.size.y() + this.paint.strokeWidth); return true; } } diff --git a/src/org/atriasoft/esvg/Text.java b/src/org/atriasoft/esvg/Text.java index 08fa8e0..57e6b53 100644 --- a/src/org/atriasoft/esvg/Text.java +++ b/src/org/atriasoft/esvg/Text.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.List; import org.atriasoft.esvg.font.Glyph; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.esvg.render.DynamicColor; import org.atriasoft.esvg.render.PathModel; import org.atriasoft.esvg.render.PointList; @@ -16,6 +15,8 @@ import org.atriasoft.etk.util.Dynamic; import org.atriasoft.exml.model.XmlElement; import org.atriasoft.exml.model.XmlNode; import org.atriasoft.exml.model.XmlText; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -23,106 +24,116 @@ import org.atriasoft.exml.model.XmlText; * @license MPL v2.0 (see license file) */ public class Text extends Base { + static final Logger LOGGER = LoggerFactory.getLogger(Text.class); private float fontSize = 42; private Vector2f position = Vector2f.ZERO; private final List texts = new ArrayList<>(); - + public Text(final PaintState parentPaintState) { super(parentPaintState); } - - public Text(final Vector2f position, final float fontSize, final String decoratedText, final PaintState parentPaintState) { + + public Text(final Vector2f position, final float fontSize, final String decoratedText, + final PaintState parentPaintState) { super(parentPaintState); this.position = position; this.fontSize = fontSize; - this.texts.add(new TextSpan(position, decoratedText, FontProperty.DEFAULT_FONT.withSize(fontSize), parentPaintState.clone())); - } - public Text(final Vector2f position, final String fontName,final float fontSize, final String decoratedText, final PaintState parentPaintState) { - super(parentPaintState); - this.position = position; - this.fontSize = fontSize; - this.texts.add(new TextSpan(position, decoratedText, FontProperty.DEFAULT_FONT.withSize(fontSize).withFontName(fontName), parentPaintState.clone())); + this.texts.add(new TextSpan(position, decoratedText, FontProperty.DEFAULT_FONT.withSize(fontSize), + parentPaintState.clone())); } + public Text(final Vector2f position, final String fontName, final float fontSize, final String decoratedText, + final PaintState parentPaintState) { + super(parentPaintState); + this.position = position; + this.fontSize = fontSize; + this.texts.add(new TextSpan(position, decoratedText, + FontProperty.DEFAULT_FONT.withSize(fontSize).withFontName(fontName), parentPaintState.clone())); + } + @Override public void display(final int spacing) { - Log.verbose(spacingDist(spacing) + "Text : "); - for (TextSpan elem : this.texts) { - Log.debug(spacingDist(spacing + 1) + elem.toString()); + LOGGER.trace(spacingDist(spacing) + "Text : "); + for (final TextSpan elem : this.texts) { + LOGGER.debug(spacingDist(spacing + 1) + elem.toString()); } } - + @Override public void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) { - Log.verbose(spacingDist(level) + "DRAW esvg::Text ==> position = " + this.position); + LOGGER.trace(spacingDist(level) + "DRAW esvg::Text ==> position = " + this.position); if (this.texts.size() == 0) { - Log.verbose(spacingDist(level + 1) + "No text ..."); + LOGGER.trace(spacingDist(level + 1) + "No text ..."); return; } - boolean withKerning = true; - - for (TextSpan elem : this.texts) { + final boolean withKerning = true; + + for (final TextSpan elem : this.texts) { // get the font or a generic font of the program. - EsvgFont font = FontCache.getFont(elem.fontState().fontName(), elem.fontState().bold(), elem.fontState().italic()); + final EsvgFont font = FontCache.getFont(elem.fontState().fontName(), elem.fontState().bold(), + elem.fontState().italic()); if (font == null) { - Log.error("Can not get the font :" + elem.fontState()); + LOGGER.error("Can not get the font :" + elem.fontState()); return; } - - int realSize = font.calculateFontRealHeight((int) elem.fontState().fontSize()); - float scale = realSize / font.getUnitsPerEm(); - //Log.warning("elem.fontState() =" + elem.fontState()); - //Log.warning("scale =" + scale + " font size = " + elem.fontState().fontSize() + " realSize=" + realSize); - + + final int realSize = font.calculateFontRealHeight((int) elem.fontState().fontSize()); + final float scale = realSize / font.getUnitsPerEm(); + //LOGGER.warn("elem.fontState() =" + elem.fontState()); + //LOGGER.warn("scale =" + scale + " font size = " + elem.fontState().fontSize() + " realSize=" + realSize); + float offsetWriting = 0; int lastValue = 0; - for (char uVal : elem.text().toCharArray()) { - Log.verbose(spacingDist(level) + " elem.position = " + elem.position()); - Glyph glyph = font.getGlyph(uVal); + for (final char uVal : elem.text().toCharArray()) { + LOGGER.trace( + spacingDist(level) + " elem.position = " + elem.position()); + final Glyph glyph = font.getGlyph(uVal); if (glyph == null) { //lastValue = uVal; continue; } if (withKerning) { offsetWriting -= glyph.getKerning(lastValue) * scale; - Log.verbose(" ==> kerning offset = " + (glyph.getKerning(lastValue) * scale)); + LOGGER.trace(" ==> kerning offset = " + (glyph.getKerning(lastValue) * scale)); lastValue = uVal; } - - float advenceXLocal = glyph.getHorizAdvX() * scale; - + + final float advenceXLocal = glyph.getHorizAdvX() * scale; + //Matrix2x3f mtx = this.transformMatrix; - Vector2f tranlate = new Vector2f(elem.position().x() + offsetWriting, elem.position().y() - font.getDescent() * scale); - Log.verbose("translate : " + tranlate); - Matrix2x3f translateGlyph = Matrix2x3f.createTranslate(tranlate); - Matrix2x3f scaleGlyph = Matrix2x3f.createScale(new Vector2f(scale, -scale)); - + final Vector2f tranlate = new Vector2f(elem.position().x() + offsetWriting, + elem.position().y() - font.getDescent() * scale); + LOGGER.trace("translate : " + tranlate); + final Matrix2x3f translateGlyph = Matrix2x3f.createTranslate(tranlate); + final Matrix2x3f scaleGlyph = Matrix2x3f.createScale(new Vector2f(scale, -scale)); + //Matrix2x3f translateGlyph = Matrix2x3f.createTranslate(tranlate).multiply(Matrix2x3f.createScale(scale)); //mtx = translateGlyph.multiply(this.transformMatrix); //mtx = mtx.multiply(translateGlyph); //mtx = mtx.multiply(basicTrans); - + //Matrix2x3f mtx = this.transformMatrix; //mtx = mtx.multiply(basicTrans); - + Matrix2x3f mtx = scaleGlyph; mtx = mtx.multiply(translateGlyph); mtx = mtx.multiply(this.transformMatrix); mtx = mtx.multiply(basicTrans); //Matrix2x3f mtx = this.transformMatrix; //mtx = mtx.multiply(basicTrans); - - PathModel listElement = glyph.getModel(); + + final PathModel listElement = glyph.getModel(); if (listElement != null) { //-------------------------------------------------- // -- Generate Fill weight //-------------------------------------------------- - PointList listPoints = listElement.generateListPoints(level, myRenderer.getInterpolationRecurtionMax(), myRenderer.getInterpolationThreshold()); - DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); - Weight tmpFill = new Weight(); + final PointList listPoints = listElement.generateListPoints(level, + myRenderer.getInterpolationRecurtionMax(), myRenderer.getInterpolationThreshold()); + final DynamicColor colorFill = DynamicColor.createColor(this.paint.fill, mtx); + final Weight tmpFill = new Weight(); // Check if we need to display background if (colorFill != null) { - SegmentList listSegmentFill = new SegmentList(); + final SegmentList listSegmentFill = new SegmentList(); listSegmentFill.createSegmentList(listPoints); colorFill.setViewPort(listSegmentFill.getViewPort()); listSegmentFill.applyMatrix(mtx); @@ -130,36 +141,38 @@ public class Text extends Base { // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule tmpFill.generate(myRenderer.getSize(), myRenderer.getNumberSubScanLine(), listSegmentFill); } - + //-------------------------------------------------- // -- Generate Stroke weight //-------------------------------------------------- - - Weight tmpStroke = new Weight(); + + final Weight tmpStroke = new Weight(); DynamicColor colorStroke = null; if (this.paint.strokeWidth > 0.0f) { colorStroke = DynamicColor.createColor(this.paint.stroke, mtx); if (colorStroke == null) { - Log.verbose("Color stroke is null: ..."); + LOGGER.trace("Color stroke is null: ..."); } else { // check if we need to display stroke: - SegmentList listSegmentStroke = new SegmentList(); - listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, this.paint.lineCap, this.paint.lineJoin, this.paint.miterLimit); + final SegmentList listSegmentStroke = new SegmentList(); + listSegmentStroke.createSegmentListStroke(listPoints, this.paint.strokeWidth, + this.paint.lineCap, this.paint.lineJoin, this.paint.miterLimit); colorStroke.setViewPort(listSegmentStroke.getViewPort()); listSegmentStroke.applyMatrix(mtx); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule - tmpStroke.generate(myRenderer.getSize(), myRenderer.getNumberSubScanLine(), listSegmentStroke); + tmpStroke.generate(myRenderer.getSize(), myRenderer.getNumberSubScanLine(), + listSegmentStroke); } } // add on images: myRenderer.print(tmpFill, colorFill, tmpStroke, colorStroke, this.paint.opacity); } offsetWriting += advenceXLocal; - //Log.warning("offset X =" + offsetWriting + " + " + advenceXLocal + " " + uVal); + //LOGGER.warn("offset X =" + offsetWriting + " + " + advenceXLocal + " " + uVal); } } } - + @Override public boolean parseXML(final XmlElement element, final Matrix2x3f parentTrans, final Dynamic sizeMax) { // line must have a minimum size... @@ -169,37 +182,37 @@ public class Text extends Base { } parseTransform(element); parsePaintAttr(element); - + // add the property of the parrent modifications ... this.transformMatrix = this.transformMatrix.multiply(parentTrans); - + boolean italic = false; - String fontStyle = element.getAttribute("font-style", "normal"); + final String fontStyle = element.getAttribute("font-style", "normal"); if ("italic".equals(fontStyle)) { italic = true; } else if ("normal".equals(fontStyle)) { italic = false; } else { - Log.error("can not parse font-style='" + fontStyle + "' support ['normal', 'italic']"); + LOGGER.error("can not parse font-style='" + fontStyle + "' support ['normal', 'italic']"); } boolean bold = false; - String fontWeight = element.getAttribute("font-weight", "normal"); + final String fontWeight = element.getAttribute("font-weight", "normal"); if ("bold".equals(fontWeight)) { bold = true; } else if ("normal".equals(fontWeight)) { bold = false; } else { - Log.error("can not parse font-weight='" + fontWeight + "' support ['normal', 'bold']"); + LOGGER.error("can not parse font-weight='" + fontWeight + "' support ['normal', 'bold']"); } String fontFamily = element.getAttribute("font-family", "FreeSans"); if (fontStyle.contains(";")) { fontFamily = fontFamily.split(";")[0]; } - Log.info("Get font family: '" + fontFamily + "'"); - - float fontSize = parseLength(element.getAttribute("font-size", "50")); + LOGGER.info("Get font family: '" + fontFamily + "'"); + + final float fontSize = parseLength(element.getAttribute("font-size", "50")); this.position = Vector2f.ZERO; - + String content = element.getAttribute("x", ""); if (content.length() != 0) { this.position = this.position.withX(parseLength(content)); @@ -208,31 +221,32 @@ public class Text extends Base { if (content.length() != 0) { this.position = this.position.withY(parseLength(content)); } - + // parse all subElement in the Text - for (XmlNode elem : element.getNodes()) { - if (elem instanceof XmlElement elementSpan && "tspan".equals(elementSpan.getValue())) { - - } else if (elem instanceof XmlText elementText) { - this.texts.add(new TextSpan(this.position, elementText.getValue(), new FontProperty(fontFamily, fontSize, bold, italic), this.paint.clone())); + for (final XmlNode elem : element.getNodes()) { + if (elem instanceof final XmlElement elementSpan && "tspan".equals(elementSpan.getValue())) { + + } else if (elem instanceof final XmlText elementText) { + this.texts.add(new TextSpan(this.position, elementText.getValue(), + new FontProperty(fontFamily, fontSize, bold, italic), this.paint.clone())); } else { - Log.warning("not managed element : " + elem); + LOGGER.warn("not managed element : " + elem); } } - + //sizeMax.value = Vector2f.max(this.startPos, this.stopPos); return true; - + } /* public Weight render(final String data, final int fontSize, final boolean withKerning) { int widthOut = calculateWidth(data, fontSize, withKerning); - + int realSize = calculateFontRealHeight(fontSize); float scale = realSize / (float) this.unitsPerEm; - + Weight weight = new Weight(new Vector2i(widthOut, realSize)); - + int offsetWriting = 0; int lastValue = 0; for (char uVal : data.toCharArray()) { @@ -243,12 +257,12 @@ public class Text extends Base { } if (withKerning) { offsetWriting -= glyph.getKerning(lastValue) * scale; - Log.info(" ==> kerning offset = " + (glyph.getKerning(lastValue) * scale)); + LOGGER.info(" ==> kerning offset = " + (glyph.getKerning(lastValue) * scale)); lastValue = uVal; } - + float advenceXLocal = glyph.getHorizAdvX() * scale; - + RenderingConfig config = new RenderingConfig(10, 0.25f, 8); Matrix2x3f transform = Matrix2x3f.createTranslate(new Vector2f(0, -this.descent)).multiply(Matrix2x3f.createScale(scale)); PathModel model = glyph.getModel(); @@ -257,7 +271,7 @@ public class Text extends Base { weight.fusion(redered, offsetWriting, 0); } offsetWriting += advenceXLocal; - + } return weight; } @@ -269,17 +283,21 @@ record FontProperty( float fontSize, boolean bold, boolean italic) { + public static final FontProperty DEFAULT_FONT = new FontProperty("FreeSans", 15, false, false); - + public FontProperty withSize(final float fontSize) { return new FontProperty(this.fontName, fontSize, this.bold, this.italic); } + public FontProperty withFontName(final String fontName) { return new FontProperty(fontName, this.fontSize, this.bold, this.italic); } + public FontProperty withBold(final boolean bold) { return new FontProperty(this.fontName, this.fontSize, bold, this.italic); } + public FontProperty withSize(final boolean italic) { return new FontProperty(this.fontName, this.fontSize, this.bold, italic); } diff --git a/src/org/atriasoft/esvg/font/Glyph.java b/src/org/atriasoft/esvg/font/Glyph.java index 1fde067..9d3277b 100644 --- a/src/org/atriasoft/esvg/font/Glyph.java +++ b/src/org/atriasoft/esvg/font/Glyph.java @@ -5,77 +5,80 @@ import java.util.List; import org.atriasoft.esvg.EsvgFont; import org.atriasoft.esvg.Path; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.esvg.render.PathModel; import org.atriasoft.exml.model.XmlElement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Glyph { private static final boolean LAZY_MODE = true; - + static final Logger LOGGER = LoggerFactory.getLogger(Glyph.class); + public static Glyph valueOf(final XmlElement element) { return Glyph.valueOf(element, null); } - + public static Glyph valueOf(final XmlElement element, final EsvgFont font) { if (element == null) { return null; } - String name = element.getAttribute("glyph-name", null); - Log.verbose("get glyph name = '" + name + "'"); - String tmpValue = element.getAttribute("horiz-adv-x", null); + final String name = element.getAttribute("glyph-name", null); + LOGGER.trace("get glyph name = '" + name + "'"); + final String tmpValue = element.getAttribute("horiz-adv-x", null); int horizAdvX = font == null ? 100 : font.getHorizAdvX(); if (tmpValue != null && tmpValue.length() != 0) { horizAdvX = Integer.parseInt(tmpValue); } - Log.verbose(" horizAdvX= '" + horizAdvX + "'"); - String unicode = element.getAttribute("unicode", null); - Log.verbose(" unicode= '" + unicode + "'"); + LOGGER.trace(" horizAdvX= '" + horizAdvX + "'"); + final String unicode = element.getAttribute("unicode", null); + LOGGER.trace(" unicode= '" + unicode + "'"); if (unicode == null) { - Log.debug("Not manage glyph : '" + name + "' (missing unicode value)"); + LOGGER.debug("Not manage glyph : '" + name + "' (missing unicode value)"); return null; } - String d = element.getAttribute("d", null); - Log.verbose(" d= '" + d + "'"); + final String d = element.getAttribute("d", null); + LOGGER.trace(" d= '" + d + "'"); int unicodeValue = 0; if (unicode.startsWith("&#x") && unicode.endsWith(";")) { - String subElement = unicode.substring(3, unicode.length() - 1); + final String subElement = unicode.substring(3, unicode.length() - 1); if (subElement.indexOf("&") != -1) { - Log.debug("not supported glyph concatenarion" + name + " value='" + unicode + "'"); + LOGGER.debug("not supported glyph concatenarion" + name + " value='" + unicode + "'"); return null; } unicodeValue = Integer.parseInt(subElement, 16); } else if (unicode.startsWith("&#") && unicode.endsWith(";")) { - String subElement = unicode.substring(2, unicode.length() - 1); + final String subElement = unicode.substring(2, unicode.length() - 1); if (subElement.indexOf("&") != -1) { - Log.debug("not supported glyph concatenarion" + name + " value='" + unicode + "'"); + LOGGER.debug("not supported glyph concatenarion" + name + " value='" + unicode + "'"); return null; } unicodeValue = Integer.parseInt(subElement, 16); } else if (unicode.length() != 1) { - Log.debug("not supported glyph concatenarion" + name + " value='" + unicode + "'"); + LOGGER.debug("not supported glyph concatenarion" + name + " value='" + unicode + "'"); return null; } else { unicodeValue = unicode.charAt(0); } - Log.verbose(" unicodeValue= '" + unicodeValue + "'"); - Glyph out = new Glyph(horizAdvX, d, name, unicode, unicodeValue); + LOGGER.trace(" unicodeValue= '" + unicodeValue + "'"); + final Glyph out = new Glyph(horizAdvX, d, name, unicode, unicodeValue); if (!Glyph.LAZY_MODE) { // when not in lazy mode we force the parsing of the model, this permit to check the whole font... otherwise many font is really big > 8000 glyph, then it is a waste of time... out.getModel(); } return out; } - + private int horizAdvX; private List kernings = new ArrayList<>(); private PathModel model; private String name; private final String path; private String unicode; - + private int unicodeValue; - - public Glyph(final int horizAdvX, final PathModel model, final String name, final String unicode, final int unicodeValue) { + + public Glyph(final int horizAdvX, final PathModel model, final String name, final String unicode, + final int unicodeValue) { this.horizAdvX = horizAdvX; this.model = model; this.path = null; @@ -83,8 +86,9 @@ public class Glyph { this.unicode = unicode; this.unicodeValue = unicodeValue; } - - public Glyph(final int horizAdvX, final String path, final String name, final String unicode, final int unicodeValue) { + + public Glyph(final int horizAdvX, final String path, final String name, final String unicode, + final int unicodeValue) { this.horizAdvX = horizAdvX; this.model = null; this.path = path; @@ -92,73 +96,74 @@ public class Glyph { this.unicode = unicode; this.unicodeValue = unicodeValue; } - + public void addKerning(final List elementsKerning) { this.kernings.addAll(elementsKerning); } - + public int getHorizAdvX() { return this.horizAdvX; } - + public float getKerning(final int unicodeValue) { if (unicodeValue == 0) { return 0.0f; } - for (Kerning elem : this.kernings) { + for (final Kerning elem : this.kernings) { if (elem.unicode() == unicodeValue) { - Log.verbose("Get kerning between : '" + (char) this.unicodeValue + "' and '" + (char) unicodeValue + "' => " + elem.offset()); + LOGGER.trace("Get kerning between : '" + (char) this.unicodeValue + "' and '" + (char) unicodeValue + + "' => " + elem.offset()); return elem.offset(); } } return 0; } - + public List getKernings() { return this.kernings; } - + public PathModel getModel() { if (this.model == null && this.path != null) { this.model = Path.createPathModel(this.path); } return this.model; } - + public String getName() { return this.name; } - + public String getUnicode() { return this.unicode; } - + public Integer getUnicodeValue() { return this.unicodeValue; } - + public void setHorizAdvX(final int horizAdvX) { this.horizAdvX = horizAdvX; } - + public void setKernings(final List kernings) { this.kernings = kernings; } - + public void setModel(final PathModel model) { this.model = model; } - + public void setName(final String name) { this.name = name; } - + public void setUnicode(final String unicode) { this.unicode = unicode; } - + public void setUnicodeValue(final int unicodeValue) { this.unicodeValue = unicodeValue; } - + } diff --git a/src/org/atriasoft/esvg/internal/Log.java b/src/org/atriasoft/esvg/internal/Log.java deleted file mode 100644 index 17ea66e..0000000 --- a/src/org/atriasoft/esvg/internal/Log.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.atriasoft.esvg.internal; - -import org.atriasoft.reggol.LogLevel; -import org.atriasoft.reggol.Logger; - -public class Log { - private static final boolean FORCE_ALL = false; - private static final String LIB_NAME = "esvg"; - private static final String LIB_NAME_DRAW = Logger.getDrawableName(Log.LIB_NAME); - private static final boolean PRINT_CRITICAL = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.CRITICAL); - private static final boolean PRINT_DEBUG = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.DEBUG); - private static final boolean PRINT_ERROR = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.ERROR); - private static final boolean PRINT_INFO = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.INFO); - private static final boolean PRINT_PRINT = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.PRINT); - private static final boolean PRINT_TODO = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.TODO); - private static final boolean PRINT_VERBOSE = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.VERBOSE); - private static final boolean PRINT_WARNING = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.WARNING); - - public static void critical(final Exception e, final String data) { - e.printStackTrace(); - if (PRINT_CRITICAL || FORCE_ALL) { - Logger.critical(LIB_NAME_DRAW, data + " : " + e.getMessage()); - } - } - - public static void critical(final String data, final Object... objects) { - if (PRINT_CRITICAL || FORCE_ALL) { - Logger.critical(LIB_NAME_DRAW, data, objects); - } - } - - public static void debug(final String data, final Object... objects) { - if (PRINT_DEBUG || FORCE_ALL) { - Logger.debug(LIB_NAME_DRAW, data, objects); - } - } - - public static void error(final String data, final Object... objects) { - if (PRINT_ERROR || FORCE_ALL) { - Logger.error(LIB_NAME_DRAW, data, objects); - } - } - - public static void info(final String data, final Object... objects) { - if (PRINT_INFO || FORCE_ALL) { - Logger.info(LIB_NAME_DRAW, data, objects); - } - } - - public static void print(final String data, final Object... objects) { - if (PRINT_PRINT || FORCE_ALL) { - Logger.print(LIB_NAME_DRAW, data, objects); - } - } - - public static void todo(final String data, final Object... objects) { - if (PRINT_TODO || FORCE_ALL) { - Logger.todo(LIB_NAME_DRAW, data, objects); - } - } - - public static void verbose(final String data, final Object... objects) { - if (PRINT_VERBOSE || FORCE_ALL) { - Logger.verbose(LIB_NAME_DRAW, data, objects); - } - } - - public static void warning(final String data, final Object... objects) { - if (PRINT_WARNING || FORCE_ALL) { - Logger.warning(LIB_NAME_DRAW, data, objects); - } - } - - private Log() {} - -} diff --git a/src/org/atriasoft/esvg/render/DynamicColor.java b/src/org/atriasoft/esvg/render/DynamicColor.java index 7ca5c64..15c17b1 100644 --- a/src/org/atriasoft/esvg/render/DynamicColor.java +++ b/src/org/atriasoft/esvg/render/DynamicColor.java @@ -1,12 +1,13 @@ package org.atriasoft.esvg.render; import org.atriasoft.esvg.EsvgDocument; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.etk.Color; import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.math.Vector2i; import org.atriasoft.etk.util.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -15,22 +16,24 @@ import org.atriasoft.etk.util.Pair; */ public interface DynamicColor { + static final Logger LOGGER = LoggerFactory.getLogger(DynamicColor.class); + public static DynamicColor createColor(final Pair color, final Matrix2x3f mtx) { // Check if need to create a color: if (color.first.a() == 0 && color.second.isEmpty()) { return null; } if (color.second.isEmpty()) { - Log.verbose("use stroke color :" + color); + LOGGER.trace("use stroke color :" + color); return new DynamicColorUni(color.first); } return new DynamicColorSpecial(color.second, mtx); } - + void generate(EsvgDocument document); - + public Color getColor(Vector2i pos); - + public void setViewPort(Pair viewPort); - + } diff --git a/src/org/atriasoft/esvg/render/DynamicColorSpecial.java b/src/org/atriasoft/esvg/render/DynamicColorSpecial.java index d646b6a..dcb5e2f 100644 --- a/src/org/atriasoft/esvg/render/DynamicColorSpecial.java +++ b/src/org/atriasoft/esvg/render/DynamicColorSpecial.java @@ -8,7 +8,6 @@ import org.atriasoft.esvg.GradientUnits; import org.atriasoft.esvg.LinearGradient; import org.atriasoft.esvg.RadialGradient; import org.atriasoft.esvg.SpreadMethod; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.etk.Color; import org.atriasoft.etk.Dimension1f; import org.atriasoft.etk.Dimension2f; @@ -18,38 +17,54 @@ import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.math.Vector2i; import org.atriasoft.etk.util.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DynamicColorSpecial implements DynamicColor { - protected static Vector2f getIntersect(final Vector2f point1, final Vector2f vect1, final Vector2f point2, final Vector2f vect2) { - float diviseur = vect1.x() * vect2.y() - vect1.y() * vect2.x(); + static final Logger LOGGER = LoggerFactory.getLogger(DynamicColorSpecial.class); + + protected static Vector2f getIntersect( + final Vector2f point1, + final Vector2f vect1, + final Vector2f point2, + final Vector2f vect2) { + final float diviseur = vect1.x() * vect2.y() - vect1.y() * vect2.x(); if (diviseur != 0.0f) { - float mmm = (vect1.x() * point1.y() - vect1.x() * point2.y() - vect1.y() * point1.x() + vect1.y() * point2.x()) / diviseur; + final float mmm = (vect1.x() * point1.y() - vect1.x() * point2.y() - vect1.y() * point1.x() + + vect1.y() * point2.x()) / diviseur; return point2.add(vect2.multiply(mmm)); } - Log.error("Get divider / 0.0f"); + LOGGER.error("Get divider / 0.0f"); return point2; } - + protected static Pair intersectLineToCircle(final Vector2f pos1, final Vector2f pos2) { return DynamicColorSpecial.intersectLineToCircle(pos1, pos2, Vector2f.ZERO); } - - protected static Pair intersectLineToCircle(final Vector2f pos1, final Vector2f pos2, final Vector2f center) { + + protected static Pair intersectLineToCircle( + final Vector2f pos1, + final Vector2f pos2, + final Vector2f center) { return DynamicColorSpecial.intersectLineToCircle(pos1, pos2, center, 1.0f); } - - protected static Pair intersectLineToCircle(final Vector2f pos1, final Vector2f pos2, final Vector2f center, final float radius) { + + protected static Pair intersectLineToCircle( + final Vector2f pos1, + final Vector2f pos2, + final Vector2f center, + final float radius) { Vector2f v1; Vector2f v2; //vector2D from point 1 to point 2 v1 = pos2.less(pos1); //vector2D from point 1 to the circle's center v2 = center.less(pos1); - - float dot = v1.dot(v2); - Vector2f proj1 = new Vector2f(((dot / (v1.length2())) * v1.x()), ((dot / (v1.length2())) * v1.y())); - Vector2f midpt = pos1.add(proj1); - + + final float dot = v1.dot(v2); + final Vector2f proj1 = new Vector2f(((dot / (v1.length2())) * v1.x()), ((dot / (v1.length2())) * v1.y())); + final Vector2f midpt = pos1.add(proj1); + float distToCenter = midpt.less(center).length2(); if (distToCenter > radius * radius) { return new Pair<>(Vector2f.ZERO, Vector2f.ZERO); @@ -69,7 +84,7 @@ public class DynamicColorSpecial implements DynamicColor { v1 = v1.multiply(distToIntersection); return new Pair<>(midpt.add(v1), midpt.less(v1)); } - + public Vector2f axeX; public Vector2f axeY; public Vector2f baseSize; @@ -81,56 +96,56 @@ public class DynamicColorSpecial implements DynamicColor { public float focalLength; public boolean linear; public Matrix2x3f matrix; - + public Vector2f pos1; // in radius ==> center - + public Vector2f pos2; // in radius ==> radius end position - + public SpreadMethod spread; - + public GradientUnits unit; - + public Pair viewPort; - + public DynamicColorSpecial(final String link, final Matrix2x3f mtx) { this.linear = true; this.colorName = link; this.matrix = mtx; this.viewPort = new Pair<>(Vector2f.MAX_VALUE, Vector2f.MAX_VALUE); } - + @Override public void generate(final EsvgDocument document) { if (document == null) { - Log.error("Get null input for document"); + LOGGER.error("Get null input for document"); } - Base base = document.getReference(this.colorName); + final Base base = document.getReference(this.colorName); if (base == null) { - Log.error("Can not get base : '" + this.colorName + "'"); + LOGGER.error("Can not get base : '" + this.colorName + "'"); return; } // Now we can know if we use linear or radial gradient ... - if (base instanceof LinearGradient gradient) { + if (base instanceof final LinearGradient gradient) { this.linear = true; - Log.verbose("get for color linear:"); + LOGGER.trace("get for color linear:"); gradient.display(2); this.unit = gradient.unit; this.spread = gradient.spread; - Log.verbose(" viewport = {" + this.viewPort.first + "," + this.viewPort.second + "}"); - Vector2f size = this.viewPort.second.less(this.viewPort.first); - - Dimension2f dimPos1 = gradient.getPosition1(); + LOGGER.trace(" viewport = {" + this.viewPort.first + "," + this.viewPort.second + "}"); + final Vector2f size = this.viewPort.second.less(this.viewPort.first); + + final Dimension2f dimPos1 = gradient.getPosition1(); this.pos1 = dimPos1.getPixel(size); if (dimPos1.getType() == Distance.POURCENT) { this.pos1 = this.pos1.add(this.viewPort.first); } - Dimension2f dimPos2 = gradient.getPosition2(); + final Dimension2f dimPos2 = gradient.getPosition2(); this.pos2 = dimPos2.getPixel(size); if (dimPos2.getType() == Distance.POURCENT) { this.pos2 = this.pos2.add(this.viewPort.first); } // in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object.. - Vector2f delta = this.pos2.less(this.pos1); + final Vector2f delta = this.pos2.less(this.pos1); if (delta.x() < 0.0f) { this.axeX = new Vector2f(-1.0f, 0.0f); } else { @@ -147,41 +162,41 @@ public class DynamicColorSpecial implements DynamicColor { this.axeX = this.matrix.applyScaleRotation(this.axeX); this.axeY = this.matrix.applyScaleRotation(this.axeY); // in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object.. - Vector2f intersecX = DynamicColorSpecial.getIntersect(this.pos1, this.axeX, this.pos2, this.axeY); - Vector2f intersecY = DynamicColorSpecial.getIntersect(this.pos1, this.axeY, this.pos2, this.axeX); + final Vector2f intersecX = DynamicColorSpecial.getIntersect(this.pos1, this.axeX, this.pos2, this.axeY); + final Vector2f intersecY = DynamicColorSpecial.getIntersect(this.pos1, this.axeY, this.pos2, this.axeX); this.baseSize = new Vector2f((this.pos1.less(intersecX)).length(), (this.pos1.less(intersecY)).length()); // get all the colors this.data = gradient.getColors(document); } else { this.linear = false; - if (!(base instanceof RadialGradient gradient)) { - Log.error("Can not cast in a linear gradient: '" + this.colorName + "' ==> wrong type"); + if (!(base instanceof final RadialGradient gradient)) { + LOGGER.error("Can not cast in a linear gradient: '" + this.colorName + "' ==> wrong type"); return; } - Log.verbose("get for color Radial:"); + LOGGER.trace("get for color Radial:"); gradient.display(2); this.unit = gradient.unit; this.spread = gradient.spread; - Log.verbose(" viewport = {" + this.viewPort.first + "," + this.viewPort.second + "}"); - Vector2f size = this.viewPort.second.less(this.viewPort.first); - - Dimension2f dimCenter = gradient.getCenter(); + LOGGER.trace(" viewport = {" + this.viewPort.first + "," + this.viewPort.second + "}"); + final Vector2f size = this.viewPort.second.less(this.viewPort.first); + + final Dimension2f dimCenter = gradient.getCenter(); Vector2f center = dimCenter.getPixel(size); if (dimCenter.getType() == Distance.POURCENT) { center = center.add(this.viewPort.first); } - Dimension2f dimFocal = gradient.getFocal(); + final Dimension2f dimFocal = gradient.getFocal(); Vector2f focal = dimFocal.getPixel(size); if (dimFocal.getType() == Distance.POURCENT) { focal = focal.add(this.viewPort.first); } - Dimension1f dimRadius = gradient.getRadius(); + final Dimension1f dimRadius = gradient.getRadius(); // in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object).. if (center == focal) { this.centerIsFocal = true; this.pos2 = new Vector2f(dimRadius.getPixel(size.x()), dimRadius.getPixel(size.y())); this.pos2 = this.pos2.add(center); - Vector2f delta = center.less(this.pos2); + final Vector2f delta = center.less(this.pos2); if (delta.x() < 0.0f) { this.axeX = new Vector2f(-1.0f, 0.0f); } else { @@ -197,8 +212,9 @@ public class DynamicColorSpecial implements DynamicColor { this.centerIsFocal = false; this.axeX = center.less(focal).safeNormalize(); this.axeY = new Vector2f(this.axeX.y(), -this.axeX.x()); - - this.pos2 = this.axeX.multiply(dimRadius.getPixel(size.x())).add(this.axeY.multiply(dimRadius.getPixel(size.y()))); + + this.pos2 = this.axeX.multiply(dimRadius.getPixel(size.x())) + .add(this.axeY.multiply(dimRadius.getPixel(size.y()))); this.pos2 = this.pos2.add(center); this.pos1 = center; } @@ -209,25 +225,26 @@ public class DynamicColorSpecial implements DynamicColor { this.axeX = this.matrix.applyScaleRotation(this.axeX); this.axeY = this.matrix.applyScaleRotation(this.axeY); // in the basic version of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object.. - Vector2f intersecX = DynamicColorSpecial.getIntersect(this.pos1, this.axeX, this.pos2, this.axeY); - Vector2f intersecY = DynamicColorSpecial.getIntersect(this.pos1, this.axeY, this.pos2, this.axeX); + final Vector2f intersecX = DynamicColorSpecial.getIntersect(this.pos1, this.axeX, this.pos2, this.axeY); + final Vector2f intersecY = DynamicColorSpecial.getIntersect(this.pos1, this.axeY, this.pos2, this.axeX); this.baseSize = new Vector2f((intersecX.less(this.pos1)).length(), (intersecY.less(this.pos1)).length()); if (!this.centerIsFocal) { this.focalLength = (center.less(this.matrix.multiply(focal))).length(); if (this.focalLength >= this.baseSize.x()) { - Log.debug("Change position of the Focal ... ==> set it inside the circle"); + LOGGER.debug("Change position of the Focal ... ==> set it inside the circle"); this.focalLength = this.baseSize.x() * 0.999998f; this.clipOut = true; } else { this.clipOut = false; } } - Log.verbose("baseSize=" + this.baseSize + " this.pos1=" + this.pos1 + " dim=" + dimCenter + " this.focal=" + this.focal + " this.pos2=" + this.pos2 + " dim=" + dimRadius); + LOGGER.trace("baseSize=" + this.baseSize + " this.pos1=" + this.pos1 + " dim=" + dimCenter + + " this.focal=" + this.focal + " this.pos2=" + this.pos2 + " dim=" + dimRadius); // get all the colors this.data = gradient.getColors(document); } } - + @Override public Color getColor(final Vector2i pos) { if (this.data.size() < 2) { @@ -238,16 +255,17 @@ public class DynamicColorSpecial implements DynamicColor { } return getColorRadial(pos); } - + private Color getColorLinear(final Vector2i pos) { float ratio = 0.0f; if (this.unit == GradientUnits.GRADIENT_UNITS_USER_SPACE_ON_USE) { - Vector2f vectorBase = this.pos2.less(this.pos1); - Vector2f vectorOrtho = new Vector2f(vectorBase.y(), -vectorBase.x()); - Vector2f intersec = DynamicColorSpecial.getIntersect(this.pos1, vectorBase, new Vector2f(pos.x(), pos.y()), vectorOrtho); - float baseSize = vectorBase.length(); - Vector2f vectorBaseDraw = intersec.less(this.pos1); - float baseDraw = vectorBaseDraw.length(); + final Vector2f vectorBase = this.pos2.less(this.pos1); + final Vector2f vectorOrtho = new Vector2f(vectorBase.y(), -vectorBase.x()); + final Vector2f intersec = DynamicColorSpecial.getIntersect(this.pos1, vectorBase, + new Vector2f(pos.x(), pos.y()), vectorOrtho); + final float baseSize = vectorBase.length(); + final Vector2f vectorBaseDraw = intersec.less(this.pos1); + final float baseDraw = vectorBaseDraw.length(); ratio = baseDraw / baseSize; switch (this.spread) { default: @@ -267,7 +285,7 @@ public class DynamicColorSpecial implements DynamicColor { ratio *= -1.0; } ratio -= ((int) (ratio)); - + if (ratio < 0.0f) { ratio = 1.0f - FMath.abs(ratio); } @@ -275,10 +293,12 @@ public class DynamicColorSpecial implements DynamicColor { } } else { // in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object.. - Vector2f intersecX = DynamicColorSpecial.getIntersect(this.pos1, this.axeX, new Vector2f(pos.x(), pos.y()), this.axeY); - Vector2f intersecY = DynamicColorSpecial.getIntersect(this.pos1, this.axeY, new Vector2f(pos.x(), pos.y()), this.axeX); - Vector2f vectorBaseDrawX = intersecX.less(this.pos1); - Vector2f vectorBaseDrawY = intersecY.less(this.pos1); + final Vector2f intersecX = DynamicColorSpecial.getIntersect(this.pos1, this.axeX, + new Vector2f(pos.x(), pos.y()), this.axeY); + final Vector2f intersecY = DynamicColorSpecial.getIntersect(this.pos1, this.axeY, + new Vector2f(pos.x(), pos.y()), this.axeX); + final Vector2f vectorBaseDrawX = intersecX.less(this.pos1); + final Vector2f vectorBaseDrawY = intersecY.less(this.pos1); float baseDrawX = vectorBaseDrawX.length(); float baseDrawY = vectorBaseDrawY.length(); if (this.axeX.dot(vectorBaseDrawX) < 0) { @@ -289,7 +309,8 @@ public class DynamicColorSpecial implements DynamicColor { } if (this.baseSize.x() + this.baseSize.y() != 0.0f) { if (this.baseSize.x() != 0.0f && this.baseSize.y() != 0.0f) { - ratio = (baseDrawX * this.baseSize.y() + baseDrawY * this.baseSize.x()) / (this.baseSize.x() * this.baseSize.y() * 2.0f); + ratio = (baseDrawX * this.baseSize.y() + baseDrawY * this.baseSize.x()) + / (this.baseSize.x() * this.baseSize.y() * 2.0f); } else if (this.baseSize.x() != 0.0f) { ratio = baseDrawX / this.baseSize.x(); } else { @@ -328,22 +349,29 @@ public class DynamicColorSpecial implements DynamicColor { if (ratio <= this.data.get(iii).first * 0.01f) { float localRatio = ratio - this.data.get(iii - 1).first * 0.01f; localRatio = localRatio / ((this.data.get(iii).first - this.data.get(iii - 1).first) * 0.01f); - return new Color(this.data.get(iii - 1).second.r() * (1.0 - localRatio) + this.data.get(iii).second.r() * localRatio, - this.data.get(iii - 1).second.g() * (1.0 - localRatio) + this.data.get(iii).second.g() * localRatio, - this.data.get(iii - 1).second.b() * (1.0 - localRatio) + this.data.get(iii).second.b() * localRatio, - this.data.get(iii - 1).second.a() * (1.0 - localRatio) + this.data.get(iii).second.a() * localRatio); + return new Color( + this.data.get(iii - 1).second.r() * (1.0 - localRatio) + + this.data.get(iii).second.r() * localRatio, + this.data.get(iii - 1).second.g() * (1.0 - localRatio) + + this.data.get(iii).second.g() * localRatio, + this.data.get(iii - 1).second.b() * (1.0 - localRatio) + + this.data.get(iii).second.b() * localRatio, + this.data.get(iii - 1).second.a() * (1.0 - localRatio) + + this.data.get(iii).second.a() * localRatio); } } return Color.GREEN; } - + private Color getColorRadial(final Vector2i pos) { float ratio = 0.0f; // in the basic vertion of the gradient the color is calculated with the ration in X and Y in the bonding box associated (it is rotate with the object).. - Vector2f intersecX = DynamicColorSpecial.getIntersect(this.pos1, this.axeX, new Vector2f(pos.x(), pos.y()), this.axeY); - Vector2f intersecY = DynamicColorSpecial.getIntersect(this.pos1, this.axeY, new Vector2f(pos.x(), pos.y()), this.axeX); - Vector2f vectorBaseDrawX = intersecX.less(this.pos1); - Vector2f vectorBaseDrawY = intersecY.less(this.pos1); + final Vector2f intersecX = DynamicColorSpecial.getIntersect(this.pos1, this.axeX, + new Vector2f(pos.x(), pos.y()), this.axeY); + final Vector2f intersecY = DynamicColorSpecial.getIntersect(this.pos1, this.axeY, + new Vector2f(pos.x(), pos.y()), this.axeX); + final Vector2f vectorBaseDrawX = intersecX.less(this.pos1); + final Vector2f vectorBaseDrawY = intersecY.less(this.pos1); float baseDrawX = vectorBaseDrawX.length(); float baseDrawY = vectorBaseDrawY.length(); // specal case when focal == center (this is faster ...) @@ -376,15 +404,16 @@ public class DynamicColorSpecial implements DynamicColor { if (this.clipOut && baseDrawX <= -1.0f) { ratio = 1.0f; } else { - float tmpLength = -this.focalLength / this.baseSize.x(); - Vector2f focalCenter = new Vector2f(tmpLength, 0.0f); - Vector2f currentPoint = new Vector2f(baseDrawX, baseDrawY); + final float tmpLength = -this.focalLength / this.baseSize.x(); + final Vector2f focalCenter = new Vector2f(tmpLength, 0.0f); + final Vector2f currentPoint = new Vector2f(baseDrawX, baseDrawY); if (focalCenter == currentPoint) { ratio = 0.0f; } else { - Pair positions = DynamicColorSpecial.intersectLineToCircle(focalCenter, currentPoint); - float lenghtBase = currentPoint.less(focalCenter).length(); - float lenghtBorder1 = positions.first.less(focalCenter).length(); + final Pair positions = DynamicColorSpecial.intersectLineToCircle(focalCenter, + currentPoint); + final float lenghtBase = currentPoint.less(focalCenter).length(); + final float lenghtBorder1 = positions.first.less(focalCenter).length(); //float lenghtBorder2 = positions.second.less(focalCenter).length(); ratio = lenghtBase / lenghtBorder1; } @@ -418,15 +447,20 @@ public class DynamicColorSpecial implements DynamicColor { if (ratio <= this.data.get(iii).first * 0.01f) { float localRatio = ratio - this.data.get(iii - 1).first * 0.01f; localRatio = localRatio / ((this.data.get(iii).first - this.data.get(iii - 1).first) * 0.01f); - return new Color(this.data.get(iii - 1).second.r() * (1.0 - localRatio) + this.data.get(iii).second.r() * localRatio, - this.data.get(iii - 1).second.g() * (1.0 - localRatio) + this.data.get(iii).second.g() * localRatio, - this.data.get(iii - 1).second.b() * (1.0 - localRatio) + this.data.get(iii).second.b() * localRatio, - this.data.get(iii - 1).second.a() * (1.0 - localRatio) + this.data.get(iii).second.a() * localRatio); + return new Color( + this.data.get(iii - 1).second.r() * (1.0 - localRatio) + + this.data.get(iii).second.r() * localRatio, + this.data.get(iii - 1).second.g() * (1.0 - localRatio) + + this.data.get(iii).second.g() * localRatio, + this.data.get(iii - 1).second.b() * (1.0 - localRatio) + + this.data.get(iii).second.b() * localRatio, + this.data.get(iii - 1).second.a() * (1.0 - localRatio) + + this.data.get(iii).second.a() * localRatio); } } return Color.GREEN; } - + @Override public void setViewPort(final Pair viewPort) { this.viewPort = viewPort; diff --git a/src/org/atriasoft/esvg/render/PathModel.java b/src/org/atriasoft/esvg/render/PathModel.java index ee46557..ae4b7e3 100644 --- a/src/org/atriasoft/esvg/render/PathModel.java +++ b/src/org/atriasoft/esvg/render/PathModel.java @@ -5,11 +5,12 @@ import java.util.List; import org.atriasoft.esvg.CapMode; import org.atriasoft.esvg.JoinMode; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.etk.math.FMath; import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.math.Vector2i; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -18,29 +19,41 @@ import org.atriasoft.etk.math.Vector2i; */ public class PathModel { - private static void interpolateCubicBezier(final List listPoint, final int recurtionMax, final float threshold, final Vector2f pos1, final Vector2f pos2, final Vector2f pos3, - final Vector2f pos4, final int level, final PointType type) { + static final Logger LOGGER = LoggerFactory.getLogger(PathModel.class); + + private static void interpolateCubicBezier( + final List listPoint, + final int recurtionMax, + final float threshold, + final Vector2f pos1, + final Vector2f pos2, + final Vector2f pos3, + final Vector2f pos4, + final int level, + final PointType type) { if (level > recurtionMax) { return; } - Vector2f pos12 = pos1.add(pos2).multiply(0.5f); - Vector2f pos23 = pos2.add(pos3).multiply(0.5f); - Vector2f pos34 = pos3.add(pos4).multiply(0.5f); + final Vector2f pos12 = pos1.add(pos2).multiply(0.5f); + final Vector2f pos23 = pos2.add(pos3).multiply(0.5f); + final Vector2f pos34 = pos3.add(pos4).multiply(0.5f); - Vector2f delta = pos4.less(pos1); - float distance2 = Math.abs(((pos2.x() - pos4.x()) * delta.y() - (pos2.y() - pos4.y()) * delta.x())); - float distance3 = Math.abs(((pos3.x() - pos4.x()) * delta.y() - (pos3.y() - pos4.y()) * delta.x())); + final Vector2f delta = pos4.less(pos1); + final float distance2 = Math.abs(((pos2.x() - pos4.x()) * delta.y() - (pos2.y() - pos4.y()) * delta.x())); + final float distance3 = Math.abs(((pos3.x() - pos4.x()) * delta.y() - (pos3.y() - pos4.y()) * delta.x())); if ((distance2 + distance3) * (distance2 + distance3) < threshold * delta.length2()) { listPoint.add(new Point(pos4, type)); return; } - Vector2f pos123 = pos12.add(pos23).multiply(0.5f); - Vector2f pos234 = pos23.add(pos34).multiply(0.5f); - Vector2f pos1234 = pos123.add(pos234).multiply(0.5f); + final Vector2f pos123 = pos12.add(pos23).multiply(0.5f); + final Vector2f pos234 = pos23.add(pos34).multiply(0.5f); + final Vector2f pos1234 = pos123.add(pos234).multiply(0.5f); - PathModel.interpolateCubicBezier(listPoint, recurtionMax, threshold, pos1, pos12, pos123, pos1234, level + 1, PointType.interpolation); - PathModel.interpolateCubicBezier(listPoint, recurtionMax, threshold, pos1234, pos234, pos34, pos4, level + 1, type); + PathModel.interpolateCubicBezier(listPoint, recurtionMax, threshold, pos1, pos12, pos123, pos1234, level + 1, + PointType.interpolation); + PathModel.interpolateCubicBezier(listPoint, recurtionMax, threshold, pos1234, pos234, pos34, pos4, level + 1, + type); } /** @@ -95,20 +108,24 @@ public class PathModel { } public void display(final int spacing) { - Log.warning(PathModel.spacingDist(spacing) + "Path"); - for (Element it : this.listElement) { + LOGGER.warn(PathModel.spacingDist(spacing) + "Path"); + for (final Element it : this.listElement) { if (it == null) { continue; } - Log.warning(PathModel.spacingDist(spacing + 1) + it); + LOGGER.warn(PathModel.spacingDist(spacing + 1) + it); } } - public Weight drawFill(final Vector2i size, final Matrix2x3f basicTrans, final int level, final RenderingConfig config) { + public Weight drawFill( + final Vector2i size, + final Matrix2x3f basicTrans, + final int level, + final RenderingConfig config) { PointList listPoints = new PointList(); listPoints = generateListPoints(level, config.recurtionMax(), config.interpolationThreshold()); - SegmentList listSegment = new SegmentList(); - Weight weight = new Weight(); + final SegmentList listSegment = new SegmentList(); + final Weight weight = new Weight(); // Check if we need to display background listSegment.createSegmentList(listPoints); listSegment.applyMatrix(basicTrans); @@ -117,11 +134,16 @@ public class PathModel { return weight; } - public Weight drawStroke(final Vector2i size, final Matrix2x3f basicTrans, final int level, final float strokeWidth, final RenderingConfig config) { + public Weight drawStroke( + final Vector2i size, + final Matrix2x3f basicTrans, + final int level, + final float strokeWidth, + final RenderingConfig config) { PointList listPoints = new PointList(); listPoints = generateListPoints(level, config.recurtionMax(), config.interpolationThreshold()); - SegmentList listSegment = new SegmentList(); - Weight weight = new Weight(); + final SegmentList listSegment = new SegmentList(); + final Weight weight = new Weight(); // Check if we need to display background listSegment.createSegmentListStroke(listPoints, strokeWidth, CapMode.BUTT, JoinMode.MITER, 4.0f); listSegment.applyMatrix(basicTrans); @@ -130,7 +152,13 @@ public class PathModel { return weight; } - public void ellipticTo(final boolean relative, final Vector2f radius, final float angle, final boolean largeArcFlag, final boolean sweepFlag, final Vector2f pos) { + public void ellipticTo( + final boolean relative, + final Vector2f radius, + final float angle, + final boolean largeArcFlag, + final boolean sweepFlag, + final Vector2f pos) { this.listElement.add(new ElementElliptic(relative, radius, angle, largeArcFlag, sweepFlag, pos)); } @@ -143,22 +171,23 @@ public class PathModel { } public PointList generateListPoints(final int level, final int recurtionMax, final float threshold) { - Log.verbose(PathModel.spacingDist(level) + "Generate List Points ... from a path"); - PointList out = new PointList(); + LOGGER.trace(PathModel.spacingDist(level) + "Generate List Points ... from a path"); + final PointList out = new PointList(); List tmpListPoint = new ArrayList<>(); Vector2f lastPosition = Vector2f.ZERO; Vector2f lastAngle = Vector2f.ZERO; // Foreach element, we move in the path: - for (Element it : this.listElement) { + for (final Element it : this.listElement) { if (it == null) { continue; } - Log.verbose(PathModel.spacingDist(level + 1) + " Draw : " + it.toString()); + LOGGER.trace(PathModel.spacingDist(level + 1) + " Draw : " + it.toString()); switch (it.getType()) { case STOP: if (tmpListPoint.size() != 0) { if (tmpListPoint.size() == 0) { - Log.warning(PathModel.spacingDist(level + 1) + " Request path stop of not starting path ..."); + LOGGER.warn( + PathModel.spacingDist(level + 1) + " Request path stop of not starting path ..."); } else { tmpListPoint.get(tmpListPoint.size() - 1).setEndPath(); out.addList(tmpListPoint); @@ -171,14 +200,17 @@ public class PathModel { case CLOSE: if (tmpListPoint.size() != 0) { if (tmpListPoint.size() == 0) { - Log.warning(PathModel.spacingDist(level + 1) + " Request path close of not starting path ..."); + LOGGER.warn( + PathModel.spacingDist(level + 1) + " Request path close of not starting path ..."); } else { // find the previous tart of the path ... tmpListPoint.get(0).type = PointType.join; // Remove the last point if it is the same position... - Vector2f delta = (tmpListPoint.get(0).pos.less(tmpListPoint.get(tmpListPoint.size() - 1).pos)).abs(); + final Vector2f delta = (tmpListPoint.get(0).pos + .less(tmpListPoint.get(tmpListPoint.size() - 1).pos)).abs(); if (delta.x() <= 0.00001 && delta.y() <= 0.00001) { - Log.verbose(" Remove point Z property : " + tmpListPoint.get(tmpListPoint.size() - 1).pos + " with delta=" + delta); + LOGGER.trace(" Remove point Z property : " + + tmpListPoint.get(tmpListPoint.size() - 1).pos + " with delta=" + delta); tmpListPoint.remove(tmpListPoint.size() - 1); } out.addList(tmpListPoint); @@ -244,14 +276,15 @@ public class PathModel { if (tmpListPoint.size() == 0) { tmpListPoint.add(new Point(lastPosition, PointType.join)); } { - Vector2f lastPosStore = lastPosition; + final Vector2f lastPosStore = lastPosition; if (!it.getRelative()) { lastPosition = Vector2f.ZERO; } - Vector2f pos1 = lastPosition.add(it.getPos1()); - Vector2f pos2 = lastPosition.add(it.getPos2()); - Vector2f pos = lastPosition.add(it.getPos()); - PathModel.interpolateCubicBezier(tmpListPoint, recurtionMax, threshold, lastPosStore, pos1, pos2, pos, 0, PointType.join); + final Vector2f pos1 = lastPosition.add(it.getPos1()); + final Vector2f pos2 = lastPosition.add(it.getPos2()); + final Vector2f pos = lastPosition.add(it.getPos()); + PathModel.interpolateCubicBezier(tmpListPoint, recurtionMax, threshold, lastPosStore, pos1, pos2, + pos, 0, PointType.join); lastPosition = pos; lastAngle = pos2; } @@ -261,15 +294,16 @@ public class PathModel { if (tmpListPoint.size() == 0) { tmpListPoint.add(new Point(lastPosition, PointType.join)); } { - Vector2f lastPosStore = lastPosition; + final Vector2f lastPosStore = lastPosition; if (!it.getRelative()) { lastPosition = Vector2f.ZERO; } - Vector2f pos2 = lastPosition.add(it.getPos2()); - Vector2f pos = lastPosition.add(it.getPos()); + final Vector2f pos2 = lastPosition.add(it.getPos2()); + final Vector2f pos = lastPosition.add(it.getPos()); // generate Pos 1 - Vector2f pos1 = lastPosStore.multiply(2.0f).less(lastAngle); - PathModel.interpolateCubicBezier(tmpListPoint, recurtionMax, threshold, lastPosStore, pos1, pos2, pos, 0, PointType.join); + final Vector2f pos1 = lastPosStore.multiply(2.0f).less(lastAngle); + PathModel.interpolateCubicBezier(tmpListPoint, recurtionMax, threshold, lastPosStore, pos1, pos2, + pos, 0, PointType.join); lastPosition = pos; lastAngle = pos2; } @@ -279,16 +313,17 @@ public class PathModel { if (tmpListPoint.size() == 0) { tmpListPoint.add(new Point(lastPosition, PointType.join)); } { - Vector2f lastPosStore = lastPosition; + final Vector2f lastPosStore = lastPosition; if (!it.getRelative()) { lastPosition = Vector2f.ZERO; } - Vector2f pos = lastPosition.add(it.getPos()); - Vector2f tmp1 = lastPosition.add(it.getPos1()); + final Vector2f pos = lastPosition.add(it.getPos()); + final Vector2f tmp1 = lastPosition.add(it.getPos1()); // generate pos1 and pos2 - Vector2f pos1 = lastPosStore.add(tmp1.less(lastPosStore).multiply(0.666666666f)); - Vector2f pos2 = pos.add(tmp1.less(pos).multiply(0.666666666f)); - PathModel.interpolateCubicBezier(tmpListPoint, recurtionMax, threshold, lastPosStore, pos1, pos2, pos, 0, PointType.join); + final Vector2f pos1 = lastPosStore.add(tmp1.less(lastPosStore).multiply(0.666666666f)); + final Vector2f pos2 = pos.add(tmp1.less(pos).multiply(0.666666666f)); + PathModel.interpolateCubicBezier(tmpListPoint, recurtionMax, threshold, lastPosStore, pos1, pos2, + pos, 0, PointType.join); lastPosition = pos; lastAngle = tmp1; } @@ -298,16 +333,17 @@ public class PathModel { if (tmpListPoint.size() == 0) { tmpListPoint.add(new Point(lastPosition, PointType.join)); } { - Vector2f lastPosStore = lastPosition; + final Vector2f lastPosStore = lastPosition; if (!it.getRelative()) { lastPosition = Vector2f.ZERO; } - Vector2f pos = lastPosition.add(it.getPos()); - Vector2f tmp1 = lastPosStore.multiply(2.0f).less(lastAngle); + final Vector2f pos = lastPosition.add(it.getPos()); + final Vector2f tmp1 = lastPosStore.multiply(2.0f).less(lastAngle); // generate pos1 and pos2 - Vector2f pos1 = lastPosStore.add(tmp1.less(lastPosStore).multiply(0.666666666f)); - Vector2f pos2 = pos.add(tmp1.less(pos).multiply(0.66666666f)); - PathModel.interpolateCubicBezier(tmpListPoint, recurtionMax, threshold, lastPosStore, pos1, pos2, pos, 0, PointType.join); + final Vector2f pos1 = lastPosStore.add(tmp1.less(lastPosStore).multiply(0.666666666f)); + final Vector2f pos2 = pos.add(tmp1.less(pos).multiply(0.66666666f)); + PathModel.interpolateCubicBezier(tmpListPoint, recurtionMax, threshold, lastPosStore, pos1, pos2, + pos, 0, PointType.join); lastPosition = pos; lastAngle = tmp1; } @@ -317,25 +353,28 @@ public class PathModel { if (tmpListPoint.size() == 0) { tmpListPoint.add(new Point(lastPosition, PointType.join)); } { - ElementElliptic tmpIt = (ElementElliptic) it; - Log.todo(PathModel.spacingDist(level + 1) + " Elliptic arc: radius=" + tmpIt.getPos1()); - Log.todo(PathModel.spacingDist(level + 1) + " angle=" + tmpIt.angle); - Log.todo(PathModel.spacingDist(level + 1) + " this.largeArcFlag=" + tmpIt.largeArcFlag); - Log.todo(PathModel.spacingDist(level + 1) + " this.sweepFlag=" + tmpIt.sweepFlag); + final ElementElliptic tmpIt = (ElementElliptic) it; + LOGGER.info( + "TODO:" + PathModel.spacingDist(level + 1) + " Elliptic arc: radius=" + tmpIt.getPos1()); + LOGGER.info("TODO:" + PathModel.spacingDist(level + 1) + " angle=" + tmpIt.angle); + LOGGER.info("TODO:" + PathModel.spacingDist(level + 1) + " this.largeArcFlag=" + + tmpIt.largeArcFlag); + LOGGER.info("TODO:" + PathModel.spacingDist(level + 1) + " this.sweepFlag=" + + tmpIt.sweepFlag); - Vector2f lastPosStore = lastPosition; + final Vector2f lastPosStore = lastPosition; if (!it.getRelative()) { lastPosition = Vector2f.ZERO; } - Vector2f pos = lastPosition.add(it.getPos()); - float rotationX = tmpIt.angle * ((float) Math.PI / 180.0f); + final Vector2f pos = lastPosition.add(it.getPos()); + final float rotationX = tmpIt.angle * ((float) Math.PI / 180.0f); Vector2f radius = tmpIt.getPos1(); //this.debugInformation.addSegment(lastPosStore, pos); Vector2f delta = lastPosStore.less(pos); float ddd = delta.length(); if (ddd < 1e-6f || radius.x() < 1e-6f || radius.y() < 1e-6f) { - Log.warning("Degenerate arc in Line"); + LOGGER.warn("Degenerate arc in Line"); if (tmpListPoint.size() == 0) { tmpListPoint.add(new Point(lastPosition, PointType.join)); } @@ -345,18 +384,21 @@ public class PathModel { // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes // procedure describe here : http://www.w3.org/TR/SVG11/implnote.html#ArcConversionCenterToEndpoint // Compute delta' - Matrix2x3f matrixRotationCenter = Matrix2x3f.createRotate(-rotationX); - Vector2f deltaPrim = matrixRotationCenter.multiply(delta.multiply(0.5f)); - ddd = (deltaPrim.x() * deltaPrim.x()) / (radius.x() * radius.x()) + (deltaPrim.y() * deltaPrim.y()) / (radius.y() * radius.y()); + final Matrix2x3f matrixRotationCenter = Matrix2x3f.createRotate(-rotationX); + final Vector2f deltaPrim = matrixRotationCenter.multiply(delta.multiply(0.5f)); + ddd = (deltaPrim.x() * deltaPrim.x()) / (radius.x() * radius.x()) + + (deltaPrim.y() * deltaPrim.y()) / (radius.y() * radius.y()); if (ddd > 1.0f) { ddd = (float) Math.sqrt(ddd); radius = radius.multiply(ddd); } // Compute center' float sss = 0.0f; - float ssa = radius.x() * radius.x() * radius.y() * radius.y() - radius.x() * radius.x() * deltaPrim.y() * deltaPrim.y() + float ssa = radius.x() * radius.x() * radius.y() * radius.y() + - radius.x() * radius.x() * deltaPrim.y() * deltaPrim.y() - radius.y() * radius.y() * deltaPrim.x() * deltaPrim.x(); - float ssb = radius.x() * radius.x() * deltaPrim.y() * deltaPrim.y() + radius.y() * radius.y() * deltaPrim.x() * deltaPrim.x(); + final float ssb = radius.x() * radius.x() * deltaPrim.y() * deltaPrim.y() + + radius.y() * radius.y() * deltaPrim.x() * deltaPrim.x(); if (ssa < 0.0f) { ssa = 0.0f; } @@ -366,19 +408,21 @@ public class PathModel { if (tmpIt.largeArcFlag == tmpIt.sweepFlag) { sss *= -1.0f; } - Vector2f centerPrime = new Vector2f(sss * radius.x() * deltaPrim.y() / radius.y(), sss * -radius.y() * deltaPrim.x() / radius.x()); + final Vector2f centerPrime = new Vector2f(sss * radius.x() * deltaPrim.y() / radius.y(), + sss * -radius.y() * deltaPrim.x() / radius.x()); // Compute center from center' - Matrix2x3f matrix = Matrix2x3f.createRotate(rotationX); - Vector2f center = lastPosStore.multiply(pos).multiply(0.5f).add(matrix.multiply(centerPrime)); + final Matrix2x3f matrix = Matrix2x3f.createRotate(rotationX); + final Vector2f center = lastPosStore.multiply(pos).multiply(0.5f) + .add(matrix.multiply(centerPrime)); //this.debugInformation.addSegment(center-Vector2f(3.0,3.0), center+Vector2f(3.0,3.0)); // this.debugInformation.addSegment(center-Vector2f(3.0,-3.0), center+Vector2f(3.0,-3.0)); // Calculate theta1, and delta theta. - Vector2f vectorA = deltaPrim.less(centerPrime).devide(radius); - Vector2f vectorB = deltaPrim.add(centerPrime).devide(radius.multiply(-1.0f)); + final Vector2f vectorA = deltaPrim.less(centerPrime).devide(radius); + final Vector2f vectorB = deltaPrim.add(centerPrime).devide(radius.multiply(-1.0f)); //this.debugInformation.addSegment(center, center+vectorA*radius.x()); //this.debugInformation.addSegment(center, center+vectorB*radius.y()); // Initial angle - float theta1 = PathModel.vectorAngle(new Vector2f(1.0f, 0.0f), vectorA); + final float theta1 = PathModel.vectorAngle(new Vector2f(1.0f, 0.0f), vectorA); // Delta angle float deltaTheta = PathModel.vectorAngle(vectorA, vectorB); // special case of invert angle... @@ -397,9 +441,9 @@ public class PathModel { matrix.translate(center); // Split arc into max 90 degree segments. // The loop assumes an iteration per end point (including start and end), this +1. - int ndivs = (int) (Math.abs(deltaTheta) / ((float) Math.PI * 0.5f)) + 1; + final int ndivs = (int) (Math.abs(deltaTheta) / ((float) Math.PI * 0.5f)) + 1; - float hda = (deltaTheta / ndivs) * 0.5f; + final float hda = (deltaTheta / ndivs) * 0.5f; float kappa = (float) Math.abs(4.0f / 3.0f * (1.0f - Math.cos(hda)) / Math.sin(hda)); if (deltaTheta < 0.0f) { kappa = -kappa; @@ -407,21 +451,24 @@ public class PathModel { Vector2f pointPosPrevious = Vector2f.ZERO; Vector2f tangentPrevious = Vector2f.ZERO; for (int iii = 0; iii <= ndivs; ++iii) { - float a = theta1 + deltaTheta * ((float) iii / (float) ndivs); + final float a = theta1 + deltaTheta * ((float) iii / (float) ndivs); delta = new Vector2f(FMath.cos(a), FMath.sin(a)); // position - Vector2f pointPos = matrix.multiply(new Vector2f(delta.x() * radius.x(), delta.y() * radius.y())); + final Vector2f pointPos = matrix + .multiply(new Vector2f(delta.x() * radius.x(), delta.y() * radius.y())); // tangent - Vector2f tangent = matrix.applyScaleRotation(new Vector2f(-delta.y() * radius.x() * kappa, delta.x() * radius.y() * kappa)); + final Vector2f tangent = matrix.applyScaleRotation( + new Vector2f(-delta.y() * radius.x() * kappa, delta.x() * radius.y() * kappa)); if (iii > 0) { - Vector2f zlastPosStore = lastPosition; + final Vector2f zlastPosStore = lastPosition; if (!it.getRelative()) { lastPosition = Vector2f.ZERO; } - Vector2f zpos1 = pointPosPrevious.add(tangentPrevious); - Vector2f zpos2 = pointPos.less(tangent); - Vector2f zpos = pointPos; - PathModel.interpolateCubicBezier(tmpListPoint, recurtionMax, threshold, zlastPosStore, zpos1, zpos2, zpos, 0, PointType.join); + final Vector2f zpos1 = pointPosPrevious.add(tangentPrevious); + final Vector2f zpos2 = pointPos.less(tangent); + final Vector2f zpos = pointPos; + PathModel.interpolateCubicBezier(tmpListPoint, recurtionMax, threshold, zlastPosStore, + zpos1, zpos2, zpos, 0, PointType.join); lastPosition = zpos; lastAngle = zpos2; } @@ -433,13 +480,13 @@ public class PathModel { } break; default: - Log.error(PathModel.spacingDist(level + 1) + " Unknow PATH commant (internal error)"); + LOGGER.error(PathModel.spacingDist(level + 1) + " Unknow PATH commant (internal error)"); break; } } // special case : No request end of path ==> open path: if (tmpListPoint.size() != 0) { - Log.verbose("Auto-end PATH"); + LOGGER.trace("Auto-end PATH"); tmpListPoint.get(tmpListPoint.size() - 1).setEndPath(); out.addList(tmpListPoint); tmpListPoint = new ArrayList<>(); diff --git a/src/org/atriasoft/esvg/render/Point.java b/src/org/atriasoft/esvg/render/Point.java index 3ad6cf8..9ce592f 100644 --- a/src/org/atriasoft/esvg/render/Point.java +++ b/src/org/atriasoft/esvg/render/Point.java @@ -1,7 +1,8 @@ package org.atriasoft.esvg.render; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.etk.math.Vector2f; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -10,6 +11,7 @@ import org.atriasoft.etk.math.Vector2f; */ public class Point { + static final Logger LOGGER = LoggerFactory.getLogger(Point.class); public Vector2f delta = Vector2f.ZERO; public float len = 0; public Vector2f miterAxe = Vector2f.ZERO; @@ -20,35 +22,35 @@ public class Point { public Vector2f posNext = Vector2f.ZERO; public Vector2f posPrevious = Vector2f.ZERO; public PointType type; - + public Point() { this.pos = Vector2f.ZERO; this.type = PointType.join; } - + public Point(final Vector2f pos) { this.pos = pos; this.type = PointType.join; } - + public Point(final Vector2f pos, final PointType type) { this.pos = pos; this.type = type; } - + void normalize(final Vector2f nextPoint) { this.delta = nextPoint.less(this.pos); this.len = this.delta.length(); } - + void setEndPath() { if (this.type == PointType.interpolation) { - Log.warning("Request stop path of an interpolate Point"); + LOGGER.warn("Request stop path of an interpolate Point"); this.type = PointType.stop; return; } if (this.type == PointType.stop) { - Log.warning("Request stop path of an STOP Point"); + LOGGER.warn("Request stop path of an STOP Point"); return; } if (this.type == PointType.start) { diff --git a/src/org/atriasoft/esvg/render/PointList.java b/src/org/atriasoft/esvg/render/PointList.java index f0d4e9d..7461364 100644 --- a/src/org/atriasoft/esvg/render/PointList.java +++ b/src/org/atriasoft/esvg/render/PointList.java @@ -3,46 +3,48 @@ package org.atriasoft.esvg.render; import java.util.ArrayList; import java.util.List; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.util.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class PointList { + static final Logger LOGGER = LoggerFactory.getLogger(PointList.class); public List> data = new ArrayList<>(); - + public PointList() { - + } - + public void addList(final List list) { this.data.add(list); // TODO : Add a checker of correct list ... } - + public void applyMatrix(final Matrix2x3f transformationMatrix) { - for (List it : this.data) { - for (Point val : it) { + for (final List it : this.data) { + for (final Point val : it) { val.pos = transformationMatrix.multiply(val.pos); } } } - + public void display() { - Log.verbose(" Display list of points : size=" + this.data.size()); - for (List it : this.data) { - Log.verbose(" Find List " + it.size() + " members"); + LOGGER.trace(" Display list of points : size=" + this.data.size()); + for (final List it : this.data) { + LOGGER.trace(" Find List " + it.size() + " members"); for (int iii = 0; iii < it.size(); ++iii) { - Point elem = it.get(iii); - Log.verbose(" [" + iii + "] Find " + elem.type + " " + elem.pos); + final Point elem = it.get(iii); + LOGGER.trace(" [" + iii + "] Find " + elem.type + " " + elem.pos); } } } - + public Pair getViewPort() { Pair out = new Pair<>(Vector2f.MAX_VALUE, Vector2f.MIN_VALUE); - for (List it : this.data) { - for (Point it2 : it) { + for (final List it : this.data) { + for (final Point it2 : it) { out = new Pair<>(Vector2f.min(out.first, it2.pos), Vector2f.max(out.second, it2.pos)); } } diff --git a/src/org/atriasoft/esvg/render/SegmentList.java b/src/org/atriasoft/esvg/render/SegmentList.java index 680e5b7..abf9589 100644 --- a/src/org/atriasoft/esvg/render/SegmentList.java +++ b/src/org/atriasoft/esvg/render/SegmentList.java @@ -4,14 +4,15 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.atriasoft.esvg.CapMode; +import org.atriasoft.esvg.JoinMode; +import org.atriasoft.etk.math.FMath; +import org.atriasoft.etk.math.Matrix2x3f; 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; -import org.atriasoft.esvg.CapMode; -import org.atriasoft.esvg.JoinMode; -import org.atriasoft.esvg.internal.Log; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -20,13 +21,20 @@ import org.atriasoft.esvg.internal.Log; */ public class SegmentList { - static Vector2f getIntersect(final Vector2f point1, final Vector2f vect1, final Vector2f point2, final Vector2f vect2) { - float diviseur = vect1.x() * vect2.y() - vect1.y() * vect2.x(); + static final Logger LOGGER = LoggerFactory.getLogger(SegmentList.class); + + static Vector2f getIntersect( + final Vector2f point1, + final Vector2f vect1, + final Vector2f point2, + final Vector2f vect2) { + final float diviseur = vect1.x() * vect2.y() - vect1.y() * vect2.x(); if (diviseur != 0.0f) { - float mmm = (vect1.x() * point1.y() - vect1.x() * point2.y() - vect1.y() * point1.x() + vect1.y() * point2.x()) / diviseur; + final float mmm = (vect1.x() * point1.y() - vect1.x() * point2.y() - vect1.y() * point1.x() + + vect1.y() * point2.x()) / diviseur; return point2.add(vect2.multiply(mmm)); } - Log.error("Get divider / 0.0f"); + LOGGER.error("Get divider / 0.0f"); return point2; } @@ -55,16 +63,16 @@ public class SegmentList { } public void applyMatrix(final Matrix2x3f transformationMatrix) { - for (Segment it : this.data) { + for (final Segment it : this.data) { it.applyMatrix(transformationMatrix); } } public void clearHorizontals() { // TODO Auto-generated method stub - Iterator itr = this.data.iterator(); + final Iterator itr = this.data.iterator(); while (itr.hasNext()) { - Segment seg = itr.next(); + final Segment seg = itr.next(); if (seg.p0.y() == seg.p1.y()) { itr.remove(); } @@ -72,7 +80,7 @@ public class SegmentList { } public void createSegmentList(final PointList listPoint) { - for (List it : listPoint.data) { + for (final List it : listPoint.data) { // Build Segments for (int iii = 0, jjj = it.size() - 1; iii < it.size(); jjj = iii++) { addSegment(it.get(jjj), it.get(iii)); @@ -80,45 +88,52 @@ public class SegmentList { } } - public void createSegmentListStroke(final PointList listPoint, final float width, final CapMode cap, final JoinMode join, final float miterLimit) { - for (List itListPoint : listPoint.data) { + public void createSegmentListStroke( + final PointList listPoint, + final float width, + final CapMode cap, + final JoinMode join, + final float miterLimit) { + for (final List itListPoint : listPoint.data) { // generate for every point all the orthogonal elements - // - // normal edge * end path - // (mitter) * | * * * * * * * * * * * * * * - // * |<--*----this | * - // * | * this -->| * - // * * * | * - // * . | . * . . . . . . . . * * - // * . | . * | * - // * A . | . B * | * - // . * . | * - // . * * . * * * * * * * * * * * * * - // * * - // * * - for (int idPevious = itListPoint.size() - 1, idCurrent = 0, idNext = 1; idCurrent < itListPoint.size(); idPevious = idCurrent++, idNext++) { + // + // normal edge * end path + // (mitter) * | * * * * * * * * * * * * * * + // * |<--*----this | * + // * | * this -->| * + // * * * | * + // * . | . * . . . . . . . . * * + // * . | . * | * + // * A . | . B * | * + // . * . | * + // . * * . * * * * * * * * * * * * * + // * * + // * * + for (int idPevious = itListPoint.size() - 1, idCurrent = 0, idNext = 1; idCurrent < itListPoint.size(); + idPevious = idCurrent++, idNext++) { if (idNext == itListPoint.size()) { idNext = 0; } - if (itListPoint.get(idCurrent).type == PointType.join || itListPoint.get(idCurrent).type == PointType.interpolation) { + if (itListPoint.get(idCurrent).type == PointType.join + || itListPoint.get(idCurrent).type == PointType.interpolation) { if (idPevious < 0) { - Log.error("an error occure a previous ID is < 0.... "); + LOGGER.error("an error occure a previous ID is < 0.... "); continue; } if (idNext >= itListPoint.size()) { - Log.error("an error occure a next ID is >= nbPoint len .... "); + LOGGER.error("an error occure a next ID is >= nbPoint len .... "); continue; } - //Log.debug("JOIN : id : prev/curr/next : " + idPevious + "/" + idCurrent + "/" + idNext); - //Log.debug("JOIN : val : prev/curr/next : " + itListPoint.get(idPevious).pos + "/" + itListPoint.get(idCurrent).pos + "/" + itListPoint.get(idNext).pos); + //LOGGER.debug("JOIN : id : prev/curr/next : " + idPevious + "/" + idCurrent + "/" + idNext); + //LOGGER.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); + //LOGGER.debug("JOIN : vecA : " + vecA); vecA = vecA.safeNormalize(); Vector2f vecB = itListPoint.get(idNext).pos.less(itListPoint.get(idCurrent).pos); - //Log.debug("JOIN : vecB : " + vecB); + //LOGGER.debug("JOIN : vecB : " + vecB); vecB = vecB.safeNormalize(); Vector2f vecC = vecA.less(vecB); - //Log.debug("JOIN : vecC : " + vecC); + //LOGGER.debug("JOIN : vecC : " + vecC); if (vecC.isZero()) { // special case: 1 line ... itListPoint.get(idCurrent).miterAxe = new Vector2f(vecA.y(), vecA.x()); @@ -134,7 +149,7 @@ public class SegmentList { vecB = itListPoint.get(idCurrent).pos.less(itListPoint.get(idPevious).pos); vecB = vecB.safeNormalize(); itListPoint.get(idCurrent).orthoAxePrevious = new Vector2f(vecB.y(), -vecB.x()); - //Log.debug("JOIN : miterAxe " + itListPoint.get(idCurrent).miterAxe); + //LOGGER.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); @@ -144,7 +159,7 @@ public class SegmentList { itListPoint.get(idCurrent).orthoAxeNext = itListPoint.get(idCurrent).miterAxe; } else if (itListPoint.get(idCurrent).type == PointType.stop) { if (idPevious < 0) { - Log.error("an error occure a previous ID is < 0.... "); + LOGGER.error("an error occure a previous ID is < 0.... "); continue; } itListPoint.get(idCurrent).posPrevious = itListPoint.get(idPevious).pos; @@ -154,25 +169,27 @@ public class SegmentList { itListPoint.get(idCurrent).orthoAxePrevious = itListPoint.get(idCurrent).miterAxe; itListPoint.get(idCurrent).orthoAxeNext = itListPoint.get(idCurrent).miterAxe; } else { - Log.todo("Unsupported type of point ...."); + LOGGER.info("TODO: Unsupported type of point ...."); } } // create segment list: boolean haveStartLine = false; - Dynamic leftPoint = new Dynamic(Vector2f.ZERO); + final Dynamic leftPoint = new Dynamic<>(Vector2f.ZERO); - Dynamic rightPoint = new Dynamic(Vector2f.ZERO); + final Dynamic rightPoint = new Dynamic<>(Vector2f.ZERO); if (itListPoint.size() > 0) { if (itListPoint.get(0).type == PointType.join) { - Point it = itListPoint.get(itListPoint.size() - 1); + final Point it = itListPoint.get(itListPoint.size() - 1); // 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.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); + 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 perpendicular axis ... leftPoint.value = it.pos.add(it.orthoAxePrevious.multiply(width * 0.5f)); @@ -180,12 +197,14 @@ public class SegmentList { // project on the miter Axis ... switch (join) { case MITER: { - 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); + final Vector2f left = SegmentList.getIntersect(leftPoint.value, + it.pos.less(it.posPrevious), it.pos, it.miterAxe); + final 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); + final float limitRight = (left.less(it.pos)).length() / width * 2.0f; + final float limitLeft = (right.less(it.pos)).length() / width * 2.0f; + LOGGER.trace(" miter Limit: " + limitRight + " " + limitLeft + " <= " + miterLimit); if (limitRight <= miterLimit && limitLeft <= miterLimit) { leftPoint.value = left; rightPoint.value = right; @@ -194,14 +213,16 @@ public class SegmentList { } case ROUND: case BEVEL: { - Vector2f axePrevious = (it.pos.less(it.posPrevious)).safeNormalize(); - Vector2f axeNext = (it.posNext.less(it.pos)).safeNormalize(); - float cross = axePrevious.cross(axeNext); + final Vector2f axePrevious = (it.pos.less(it.posPrevious)).safeNormalize(); + final Vector2f axeNext = (it.posNext.less(it.pos)).safeNormalize(); + final float cross = axePrevious.cross(axeNext); if (cross > 0.0f) { - rightPoint.value = SegmentList.getIntersect(rightPoint.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); leftPoint.value = it.pos.add(it.orthoAxeNext.multiply(width * 0.5f)); } else { - leftPoint.value = SegmentList.getIntersect(leftPoint.value, 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 = it.pos.less(it.orthoAxeNext.multiply(width * 0.5f)); } break; @@ -210,106 +231,112 @@ public class SegmentList { break; } } else { - Log.error("Start list point with a join, but last lement is not a join"); + LOGGER.error("Start list point with a join, but last lement is not a join"); } } } - for (Point it : itListPoint) { + for (final Point it : itListPoint) { switch (it.type) { case single: // just do nothing .... - Log.verbose("Find Single " + it.pos); + LOGGER.trace("Find Single " + it.pos); break; case start: - Log.verbose("Find Start " + it.pos); + LOGGER.trace("Find Start " + it.pos); if (haveStartLine) { // close previous : - Log.warning(" find a non close path ..."); + LOGGER.warn(" find a non close path ..."); addSegment(leftPoint.value, rightPoint.value); } haveStartLine = true; startStopPoint(leftPoint, rightPoint, it, cap, width, true); break; case stop: - Log.verbose("Find Stop " + it.pos); + LOGGER.trace("Find Stop " + it.pos); if (!haveStartLine) { - Log.warning("find close path without start part ..."); + LOGGER.warn("find close path without start part ..."); break; } haveStartLine = false; startStopPoint(leftPoint, rightPoint, it, cap, width, false); break; case interpolation: { - Log.verbose("Find interpolation " + it.pos); - 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); + LOGGER.trace("Find interpolation " + it.pos); + final Vector2f left = SegmentList.getIntersect(leftPoint.value, it.pos.less(it.posPrevious), + it.pos, it.miterAxe); + final Vector2f right = SegmentList.getIntersect(rightPoint.value, it.pos.less(it.posPrevious), + it.pos, it.miterAxe); //Draw from previous point: addSegment(leftPoint.value, left); - Log.verbose(" segment :" + leftPoint + " . " + left); + LOGGER.trace(" segment :" + leftPoint + " . " + left); addSegment(right, rightPoint.value); - Log.verbose(" segment :" + right + " . " + rightPoint); + LOGGER.trace(" segment :" + right + " . " + rightPoint); leftPoint.value = left; rightPoint.value = right; } break; case join: - Log.verbose("Find join " + it.pos); + LOGGER.trace("Find join " + it.pos); switch (join) { case MITER: { - 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); + final Vector2f left = SegmentList.getIntersect(leftPoint.value, + it.pos.less(it.posPrevious), it.pos, it.miterAxe); + final 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); + final float limitRight = left.less(it.pos).length() / width * 2.0f; + final float limitLeft = right.less(it.pos).length() / width * 2.0f; + LOGGER.trace(" miter Limit: " + limitRight + " " + limitLeft + " <= " + miterLimit); if (limitRight <= miterLimit && limitLeft <= miterLimit) { //Draw from previous point: addSegment(leftPoint.value, left); - Log.verbose(" segment :" + leftPoint + " . " + left); + LOGGER.trace(" segment :" + leftPoint + " . " + left); addSegment(right, rightPoint.value); - Log.verbose(" segment :" + right + " . " + rightPoint); + LOGGER.trace(" segment :" + right + " . " + rightPoint); leftPoint.value = left; rightPoint.value = right; break; } - Log.verbose(" Find miter Limit ... ==> create BEVEL"); + LOGGER.trace(" Find miter Limit ... ==> create BEVEL"); } case ROUND: case BEVEL: { - Vector2f axePrevious = (it.pos.less(it.posPrevious)).safeNormalize(); - Vector2f axeNext = (it.posNext.less(it.pos)).safeNormalize(); - float cross = axePrevious.cross(axeNext); + final Vector2f axePrevious = (it.pos.less(it.posPrevious)).safeNormalize(); + final Vector2f axeNext = (it.posNext.less(it.pos)).safeNormalize(); + final float cross = axePrevious.cross(axeNext); if (cross > 0.0f) { - 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)); + final Vector2f right = SegmentList.getIntersect(rightPoint.value, + it.pos.less(it.posPrevious), it.pos, it.miterAxe); + final Vector2f left1 = it.pos.add(it.orthoAxePrevious.multiply(width * 0.5f)); + final Vector2f left2 = it.pos.add(it.orthoAxeNext.multiply(width * 0.5f)); //Draw from previous point: addSegment(leftPoint.value, left1); - Log.verbose(" segment :" + leftPoint + " . " + left1); + LOGGER.trace(" segment :" + leftPoint + " . " + left1); if (join != JoinMode.ROUND) { // Miter and bevel: addSegment(left1, left2); - Log.verbose(" segment :" + left1 + " . " + left2); + LOGGER.trace(" segment :" + left1 + " . " + left2); } else { createSegmentListStroke(left1, left2, it.pos, width, false); } addSegment(right, rightPoint.value); - Log.verbose(" segment :" + right + " . " + rightPoint); + LOGGER.trace(" segment :" + right + " . " + rightPoint); leftPoint.value = left2; rightPoint.value = right; } else { - 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)); + final Vector2f left = SegmentList.getIntersect(leftPoint.value, + it.pos.less(it.posPrevious), it.pos, it.miterAxe); + final Vector2f right1 = it.pos.less(it.orthoAxePrevious.multiply(width * 0.5f)); + final Vector2f right2 = it.pos.less(it.orthoAxeNext.multiply(width * 0.5f)); //Draw from previous point: addSegment(leftPoint.value, left); - Log.verbose(" segment :" + leftPoint + " . " + left); + LOGGER.trace(" segment :" + leftPoint + " . " + left); addSegment(right1, rightPoint.value); - Log.verbose(" segment :" + right1 + " . " + rightPoint); + LOGGER.trace(" segment :" + right1 + " . " + rightPoint); if (join != JoinMode.ROUND) { // Miter and bevel: addSegment(right2, right1); - Log.verbose(" segment :" + right2 + " . " + right1); + LOGGER.trace(" segment :" + right2 + " . " + right1); } else { createSegmentListStroke(right1, right2, it.pos, width, true); } @@ -330,15 +357,21 @@ public class SegmentList { } - private void createSegmentListStroke(final Vector2f point1, final Vector2f point2, final Vector2f center, final float width, final boolean isStart) { + private void createSegmentListStroke( + final Vector2f point1, + final Vector2f point2, + final Vector2f center, + final float width, + final boolean isStart) { int nbDot = (int) width; if (nbDot <= 2) { nbDot = 2; } - float angleToDraw = FMath.acos((point1.less(center)).safeNormalize().dot((point2.less(center)).safeNormalize())); - float baseAngle = angleToDraw / nbDot; + final float angleToDraw = FMath + .acos((point1.less(center)).safeNormalize().dot((point2.less(center)).safeNormalize())); + final float baseAngle = angleToDraw / nbDot; float iii; - Vector2f axe = (point1.less(center)).safeNormalize(); + final Vector2f axe = (point1.less(center)).safeNormalize(); Vector2f ppp1 = point1; @@ -350,68 +383,74 @@ public class SegmentList { } else { tmpMat = Matrix2x3f.createRotate(iii); } - Vector2f axeRotate = tmpMat.multiply(axe); + final Vector2f axeRotate = tmpMat.multiply(axe); ppp2 = center.add(axeRotate.multiply(width * 0.5f)); if (isStart) { addSegment(ppp2, ppp1); - Log.verbose(" segment :" + ppp2 + " . " + ppp1); + LOGGER.trace(" segment :" + ppp2 + " . " + ppp1); } else { addSegment(ppp1, ppp2); - Log.verbose(" segment :" + ppp1 + " . " + ppp2); + LOGGER.trace(" segment :" + ppp1 + " . " + ppp2); } ppp1 = ppp2; } if (isStart) { addSegment(point2, ppp1); - Log.verbose(" segment :" + point2 + " . " + ppp1); + LOGGER.trace(" segment :" + point2 + " . " + ppp1); } else { addSegment(ppp1, point2); - Log.verbose(" segment :" + ppp1 + " . " + point2); + LOGGER.trace(" segment :" + ppp1 + " . " + point2); } } public Pair getViewPort() { Pair out = new Pair<>(Vector2f.MAX_VALUE, Vector2f.MIN_VALUE); - for (Segment it : this.data) { + for (final Segment it : this.data) { out = new Pair<>(Vector2f.min(out.first, it.p0, it.p1), Vector2f.max(out.second, it.p0, it.p1)); } return out; } - private void startStopPoint(final Dynamic leftPoint, final Dynamic rightPoint, final Point point, final CapMode cap, final float width, final boolean isStart) { + private void startStopPoint( + final Dynamic leftPoint, + final Dynamic 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)); + final Vector2f left = point.pos.add(point.miterAxe.multiply(width * 0.5f)); + final Vector2f right = point.pos.less(point.miterAxe.multiply(width * 0.5f)); if (!isStart) { //Draw from previous point: addSegment(leftPoint.value, left); - Log.verbose(" segment :" + leftPoint + " . " + left); + LOGGER.trace(" segment :" + leftPoint + " . " + left); addSegment(right, rightPoint.value); - Log.verbose(" segment :" + right + " . " + rightPoint); + LOGGER.trace(" segment :" + right + " . " + rightPoint); } leftPoint.value = left; rightPoint.value = right; } if (!isStart) { addSegment(leftPoint.value, rightPoint.value); - Log.verbose(" segment :" + leftPoint + " . " + rightPoint); + LOGGER.trace(" segment :" + leftPoint + " . " + rightPoint); } else { addSegment(rightPoint.value, leftPoint.value); - Log.verbose(" segment :" + rightPoint + " . " + leftPoint); + LOGGER.trace(" segment :" + rightPoint + " . " + leftPoint); } break; case ROUND: { if (!isStart) { - Vector2f left = point.pos.add(point.miterAxe.multiply(width * 0.5f)); - Vector2f right = point.pos.less(point.miterAxe.multiply(width * 0.5f)); + final Vector2f left = point.pos.add(point.miterAxe.multiply(width * 0.5f)); + final Vector2f right = point.pos.less(point.miterAxe.multiply(width * 0.5f)); if (!isStart) { //Draw from previous point: addSegment(leftPoint.value, left); - Log.verbose(" segment :" + leftPoint + " . " + left); + LOGGER.trace(" segment :" + leftPoint + " . " + left); addSegment(right, rightPoint.value); - Log.verbose(" segment :" + right + " . " + rightPoint); + LOGGER.trace(" segment :" + right + " . " + rightPoint); } leftPoint.value = left; rightPoint.value = right; @@ -434,30 +473,30 @@ public class SegmentList { } Vector2f left = point.pos.add(point.miterAxe.multiply(width * 0.5f)); Vector2f right = point.pos.less(point.miterAxe.multiply(width * 0.5f)); - Matrix2x3f tmpMat = Matrix2x3f.createTranslate(nextAxe.safeNormalize().multiply(width * -0.5f)); + final Matrix2x3f tmpMat = Matrix2x3f.createTranslate(nextAxe.safeNormalize().multiply(width * -0.5f)); left = tmpMat.multiply(left); right = tmpMat.multiply(right); if (!isStart) { //Draw from previous point: addSegment(leftPoint.value, left); - Log.verbose(" segment :" + leftPoint + " . " + left); + LOGGER.trace(" segment :" + leftPoint + " . " + left); addSegment(right, rightPoint.value); - Log.verbose(" segment :" + right + " . " + rightPoint); + LOGGER.trace(" segment :" + right + " . " + rightPoint); } leftPoint.value = left; rightPoint.value = right; if (!isStart) { addSegment(leftPoint.value, rightPoint.value); - Log.verbose(" segment :" + leftPoint + " . " + rightPoint); + LOGGER.trace(" segment :" + leftPoint + " . " + rightPoint); } else { addSegment(rightPoint.value, leftPoint.value); - Log.verbose(" segment :" + rightPoint + " . " + leftPoint); + LOGGER.trace(" segment :" + rightPoint + " . " + leftPoint); } - Log.verbose(" segment :" + leftPoint + " . " + rightPoint); + LOGGER.trace(" segment :" + leftPoint + " . " + rightPoint); } break; default: - Log.error(" Undefined CAP TYPE"); + LOGGER.error(" Undefined CAP TYPE"); break; } } diff --git a/src/org/atriasoft/esvg/render/Weight.java b/src/org/atriasoft/esvg/render/Weight.java index 9ddefca..648f04a 100644 --- a/src/org/atriasoft/esvg/render/Weight.java +++ b/src/org/atriasoft/esvg/render/Weight.java @@ -4,27 +4,29 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.etk.math.FMath; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.math.Vector2i; import org.atriasoft.etk.util.ArraysTools; import org.atriasoft.etk.util.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Weight { + static final Logger LOGGER = LoggerFactory.getLogger(Weight.class); private float[][] data = null; private Vector2i size; - + // constructor : public Weight() { this.size = Vector2i.ZERO; } - + public Weight(final Vector2i size) { this.size = size; resize(size); } - + public void append(final int posY, final Scanline data) { if (posY >= 0 && posY < this.size.y()) { for (int xxx = 0; xxx < this.size.x(); ++xxx) { @@ -32,28 +34,29 @@ public class Weight { } } } - + public void clear(final float fill) { ArraysTools.fill2(this.data, fill); } - + public void fusion(final Weight redered, final int offsetXXX, final int offsetYYY) { for (int yyy = 0; yyy < redered.getHeight(); yyy++) { for (int xxx = 0; xxx < redered.getWidth(); xxx++) { - this.data[offsetYYY + yyy][offsetXXX + xxx] = FMath.avg(0.0f, this.data[offsetYYY + yyy][offsetXXX + xxx] + redered.get(xxx, yyy), 1.0f); + this.data[offsetYYY + yyy][offsetXXX + xxx] = FMath.avg(0.0f, + this.data[offsetYYY + yyy][offsetXXX + xxx] + redered.get(xxx, yyy), 1.0f); } } - + } - + public void generate(final Vector2i size, final int subSamplingCount, final SegmentList listSegment) { resize(size); // for each lines: for (int yyy = 0; yyy < size.y(); ++yyy) { - Log.verbose("Weighting ... " + yyy + " / " + size.y()); + LOGGER.trace("Weighting ... " + yyy + " / " + size.y()); // Reduce the number of lines in the subsampling parsing: - List availlableSegmentPixel = new ArrayList(); - for (Segment it : listSegment.data) { + final List availlableSegmentPixel = new ArrayList<>(); + for (final Segment it : listSegment.data) { if (it.p0.y() < yyy + 1 && it.p1.y() > (yyy)) { availlableSegmentPixel.add(it); } @@ -61,20 +64,21 @@ public class Weight { if (availlableSegmentPixel.size() == 0) { continue; } - Log.verbose(" Find Basic segments " + availlableSegmentPixel.size()); + LOGGER.trace(" Find Basic segments " + availlableSegmentPixel.size()); // This represent the pondaration on the subSampling - float deltaSize = 1.0f / subSamplingCount; + final float deltaSize = 1.0f / subSamplingCount; for (int kkk = 0; kkk < subSamplingCount; ++kkk) { - Log.verbose(" Scanline ... " + kkk + " / " + subSamplingCount); - Scanline scanline = new Scanline(size.x()); + LOGGER.trace(" Scanline ... " + kkk + " / " + subSamplingCount); + final Scanline scanline = new Scanline(size.x()); //find all the segment that cross the middle of the line of the center of the pixel line: - float subSamplingCenterPos = yyy + deltaSize * 0.5f + deltaSize * kkk; - List availlableSegment = new ArrayList<>(); + final float subSamplingCenterPos = yyy + deltaSize * 0.5f + deltaSize * kkk; + final List availlableSegment = new ArrayList<>(); // find in the subList ... - for (Segment it : availlableSegmentPixel) { + for (final Segment it : availlableSegmentPixel) { if (it.p0.y() <= subSamplingCenterPos && it.p1.y() > subSamplingCenterPos) { // check if we not get 2 identical lines: - if (availlableSegment.size() > 0 && availlableSegment.get(availlableSegment.size() - 1).p1 == it.p0 + if (availlableSegment.size() > 0 + && availlableSegment.get(availlableSegment.size() - 1).p1 == it.p0 && availlableSegment.get(availlableSegment.size() - 1).direction == it.direction) { // we not add this point in this case to prevent double count of the same point. } else { @@ -82,27 +86,27 @@ public class Weight { } } } - Log.verbose(" Availlable Segment " + availlableSegment.size()); + LOGGER.trace(" Availlable Segment " + availlableSegment.size()); if (availlableSegment.size() == 0) { continue; } - for (Segment it : availlableSegment) { - Log.verbose(" Availlable Segment " + it.p0 + " . " + it.p1 + " dir=" + it.direction); + for (final Segment it : availlableSegment) { + LOGGER.trace(" Availlable Segment " + it.p0 + " . " + it.p1 + " dir=" + it.direction); } // x position, angle - List> listPosition = new ArrayList<>(); - for (Segment it : availlableSegment) { - Vector2f delta = it.p0.less(it.p1); + final List> listPosition = new ArrayList<>(); + for (final Segment it : availlableSegment) { + final Vector2f delta = it.p0.less(it.p1); // x = coefficent*y+bbb; - float coefficient = delta.x() / delta.y(); - float bbb = it.p0.x() - coefficient * it.p0.y(); - float xpos = coefficient * subSamplingCenterPos + bbb; - listPosition.add(new Pair(xpos, it.direction)); + final float coefficient = delta.x() / delta.y(); + final float bbb = it.p0.x() - coefficient * it.p0.y(); + final float xpos = coefficient * subSamplingCenterPos + bbb; + listPosition.add(new Pair<>(xpos, it.direction)); } - Log.verbose(" List position " + listPosition.size()); + LOGGER.trace(" List position " + listPosition.size()); // now we order position of the xPosition: Collections.sort(listPosition, (e1, e2) -> ((int) (e1.first - e2.first))); - + // move through all element in the point: int lastState = 0; float currentValue = 0.0f; @@ -111,30 +115,30 @@ public class Weight { // * current pos // * pos ... // TODO Code the Odd/even and non-zero ... - for (Pair it : listPosition) { + for (final Pair it : listPosition) { if (currentPos != it.first.intValue()) { // fill to the new pos -1: - float endValue = FMath.min(1.0f, FMath.abs(lastState)) * deltaSize; + final float endValue = FMath.min(1.0f, FMath.abs(lastState)) * deltaSize; for (int iii = currentPos + 1; iii < it.first.intValue(); ++iii) { scanline.set(iii, endValue); } currentPos = it.first.intValue(); currentValue = endValue; } - int oldState = lastState; + final int oldState = lastState; lastState += it.second; if (oldState == 0) { // nothing to draw before ... - float ratio = 1.0f - (it.first - it.first.intValue()); + final float ratio = 1.0f - (it.first - it.first.intValue()); currentValue += ratio * deltaSize; } else if (lastState == 0) { // something new to draw ... - float ratio = 1.0f - (it.first - it.first.intValue()); + final float ratio = 1.0f - (it.first - it.first.intValue()); currentValue -= ratio * deltaSize; } else { // nothing to do ... } - + if (currentPos == it.first.intValue()) { scanline.set(currentPos, currentValue); } @@ -142,7 +146,7 @@ public class Weight { // if the counter is not at 0 ==> fill if to the end with full value ... 2.0 if (lastState != 0) { // just past the last state to the end of the image ... - Log.error("end of Path whith no end ... " + currentPos + " . " + size.x()); + LOGGER.error("end of Path whith no end ... " + currentPos + " . " + size.x()); for (int xxx = currentPos; xxx < size.x(); ++xxx) { scanline.set(xxx, 100.0f); } @@ -151,50 +155,50 @@ public class Weight { } } } - + public float get(final int xxx, final int yyy) { if (this.data == null) { return 0; } return this.data[yyy][xxx]; } - + public float get(final Vector2i pos) { if (this.data == null) { return 0; } return this.data[pos.y()][pos.x()]; } - + public int getHeight() { return this.size.y(); } - + public Vector2i getSize() { return this.size; } - + public int getWidth() { return this.size.x(); } - + // ----------------------------------------------- // -- basic tools : // ----------------------------------------------- public void resize(final Vector2i size) { this.size = size; if (this.size.x() <= 0) { - Log.error("Error in the Weight size : " + this.size); + LOGGER.error("Error in the Weight size : " + this.size); this.size = this.size.withX(1); } if (this.size.y() <= 0) { - Log.error("Error in the Weight size : " + this.size); + LOGGER.error("Error in the Weight size : " + this.size); this.size = this.size.withY(1); } this.data = new float[this.size.y()][this.size.x()]; clear(0); } - + public void set(final int posY, final Scanline data) { if (posY >= 0 && posY < this.size.y()) { for (int xxx = 0; xxx < this.size.x(); ++xxx) { @@ -202,9 +206,9 @@ public class Weight { } } } - + public void set(final Vector2i pos, final float newColor) { this.data[pos.y()][pos.x()] = newColor; } - + } diff --git a/test/src/test/atriasoft/esvg/ConfigTest.java b/test/src/test/atriasoft/esvg/ConfigTest.java index b0733bf..46df353 100644 --- a/test/src/test/atriasoft/esvg/ConfigTest.java +++ b/test/src/test/atriasoft/esvg/ConfigTest.java @@ -1,36 +1,37 @@ package test.atriasoft.esvg; -import org.atriasoft.egami.ImageFloatRGBA; import org.atriasoft.egami.Image; +import org.atriasoft.egami.ImageFloatRGBA; import org.atriasoft.esvg.EsvgDocument; -import org.atriasoft.esvg.internal.Log; import org.atriasoft.esvg.render.Weight; import org.atriasoft.etk.Color; import org.atriasoft.etk.Uri; import org.atriasoft.etk.math.Vector2i; - import org.atriasoft.pngencoder.PngEncoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ConfigTest { + static final Logger LOGGER = LoggerFactory.getLogger(ConfigTest.class); 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) { - Image data = doc.renderImageFloatRGBA(null, ConfigTest.VISUAL_DEBUG); + final Image data = doc.renderImageFloatRGBA(null, ConfigTest.VISUAL_DEBUG); if (data == null) { - Log.critical("No data generated ..."); + LOGGER.error("No data generated ..."); } - Log.warning("Save file in " + uri.getPath()); - byte[] outElem = new PngEncoder().withBufferedImage(data).withCompressionLevel(9).toBytes(); - Log.warning("outsize = " + outElem.length); + LOGGER.warn("Save file in " + uri.getPath()); + final byte[] outElem = new PngEncoder().withBufferedImage(data).withCompressionLevel(9).toBytes(); + LOGGER.warn("outsize = " + outElem.length); new PngEncoder().withBufferedImage(data).withCompressionLevel(9).toFile(uri.getPath()); } - + public static void generateAnImage(final Weight weight, final Uri uri) { - ImageFloatRGBA image = new ImageFloatRGBA(weight.getWidth() + 2, weight.getHeight() + 2); + final ImageFloatRGBA image = new ImageFloatRGBA(weight.getWidth() + 2, weight.getHeight() + 2); for (int yyy = 0; yyy < weight.getHeight(); yyy++) { for (int xxx = 0; xxx < weight.getWidth(); xxx++) { - float elem = weight.get(new Vector2i(xxx, yyy)); + final float elem = weight.get(new Vector2i(xxx, yyy)); image.setColorFloat(xxx, yyy, 1.0f, 1.0f, 1.0f, elem); } } @@ -42,11 +43,11 @@ public class ConfigTest { image.setColor(xxx, 0, Color.ORANGE); image.setColor(xxx, weight.getHeight() + 1, Color.ORANGE); } - Log.warning("Save file in " + uri.getPath()); - byte[] outElem = new PngEncoder().withBufferedImage(image).withCompressionLevel(9).toBytes(); - Log.warning("outsize = " + outElem.length); + LOGGER.warn("Save file in " + uri.getPath()); + final byte[] outElem = new PngEncoder().withBufferedImage(image).withCompressionLevel(9).toBytes(); + LOGGER.warn("outsize = " + outElem.length); new PngEncoder().withBufferedImage(image).withCompressionLevel(9).toFile(uri.getPath()); } - + private ConfigTest() {} } diff --git a/test/src/test/atriasoft/esvg/TestCap.java b/test/src/test/atriasoft/esvg/TestCap.java index 463c188..a076880 100644 --- a/test/src/test/atriasoft/esvg/TestCap.java +++ b/test/src/test/atriasoft/esvg/TestCap.java @@ -2,140 +2,187 @@ package test.atriasoft.esvg; import org.atriasoft.esvg.EsvgDocument; import org.atriasoft.etk.Uri; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; class TestCap { @Test public void testTestCapButt() { - String data = "" + "" - + " " - + " " + ""; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + \ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapbutt.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapbutt.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCapbutt.png")); } - + @Test public void testTestCapButtDiag1() { - String data = "" + "" - + " " - + " " + ""; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + \ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapbuttDiag1.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapbuttDiag1.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCapbuttDiag1.png")); } - + @Test public void testTestCapButtDiag2() { - String data = "" + "" - + " " - + " " + ""; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + \ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapbuttDiag2.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapbuttDiag2.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCapbuttDiag2.png")); } - + @Test public void testTestCapButtVert() { - String data = "" + "" - + " " - + " " + ""; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + \ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapbuttVert.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapbuttVert.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCapbuttVert.png")); } - + @Test public void testTestCapRound() { - String data = "" + "" - + " " - + " " + ""; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + \ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapround.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapround.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCapround.png")); } - + @Test public void testTestCapRoundDiag1() { - String data = "" + "" - + " " - + " " + ""; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + \ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCaproundDiag1.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCaproundDiag1.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCaproundDiag1.png")); } - + @Test public void testTestCapRoundDiag2() { - String data = "" + "" - + " " - + " " + ""; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + \ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCaproundDiag2.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCaproundDiag2.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCaproundDiag2.png")); } - + @Test public void testTestCapRoundVert() { - String data = "" + "" - + " " - + " " + ""; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + \ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCaproundVert.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCaproundVert.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCaproundVert.png")); } - + @Test public void testTestCapSquare() { - String data = "" + "" - + " " - + " " + ""; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + \ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapsquare.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapsquare.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCapsquare.png")); } - + @Test public void testTestCapSquareDiag1() { - String data = "" + "" - + " " - + " " + ""; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + \ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapsquareDiag1.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapsquareDiag1.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCapsquareDiag1.png")); } - + @Test public void testTestCapSquareDiag2() { - String data = "" + "" - + " " - + " " + ""; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + \ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapsquareDiag2.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapsquareDiag2.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCapsquareDiag2.png")); } - + @Test public void testTestCapSquareVert() { - String data = "" + "" - + " " - + " " + ""; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + \ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapsquareVert.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCapsquareVert.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCapsquareVert.png")); } } diff --git a/test/src/test/atriasoft/esvg/TestCircle.java b/test/src/test/atriasoft/esvg/TestCircle.java index 78c94cf..6a95be4 100644 --- a/test/src/test/atriasoft/esvg/TestCircle.java +++ b/test/src/test/atriasoft/esvg/TestCircle.java @@ -2,37 +2,50 @@ package test.atriasoft.esvg; import org.atriasoft.esvg.EsvgDocument; import org.atriasoft.etk.Uri; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; class TestCircle { @Test - public void testTestCircleFill() { - String data = "" + "" + " " + ""; - EsvgDocument doc = new EsvgDocument(); + public void testTestCircleFill() throws RuntimeException { + final String data = """ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCirclefill.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCirclefill.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCirclefill.png")); } @Test - public void testTestCircleFillandstroke() { - String data = "" + "" + " " - + ""; - EsvgDocument doc = new EsvgDocument(); + public void testTestCircleFillandstroke() throws RuntimeException { + final String data = """ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCirclefillandstroke.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCirclefillandstroke.svg"), + data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCirclefillandstroke.png")); } @Test - public void testTestCircleStroke() { - String data = "" + "" + " " + ""; - EsvgDocument doc = new EsvgDocument(); + public void testTestCircleStroke() throws RuntimeException { + final String data = """ + \ + \ + \ + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCirclestroke.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestCirclestroke.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestCirclestroke.png")); } } \ No newline at end of file diff --git a/test/src/test/atriasoft/esvg/TestGradientLinear.java b/test/src/test/atriasoft/esvg/TestGradientLinear.java index 697b265..03c1787 100644 --- a/test/src/test/atriasoft/esvg/TestGradientLinear.java +++ b/test/src/test/atriasoft/esvg/TestGradientLinear.java @@ -2,7 +2,6 @@ package test.atriasoft.esvg; import org.atriasoft.esvg.EsvgDocument; import org.atriasoft.etk.Uri; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -10,251 +9,405 @@ class TestGradientLinear { @Test public void testTestGradientLinearDiag1() { //@formatter:off - String data = "\n" - + "\n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + "\n"; + final String data = """ + + + + + + + + + + + + + """; //@formatter:on - EsvgDocument doc = new EsvgDocument(); + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag1.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag1.svg"), + data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag1.png")); } - + @Test public void testTestGradientLinearDiag1Partiel() { //@formatter:off - String data = "\n" - + "\n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + "\n"; + final String data = """ + + + + + + + + + + + """; //@formatter:on - EsvgDocument doc = new EsvgDocument(); + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag1Partiel.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag1Partiel.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag1Partiel.png")); } - + @Test public void testTestGradientLinearDiag2() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2.svg"), + data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2.png")); } - + @Test public void testTestGradientLinearDiag2Rotate0() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2Rotate0.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2Rotate0.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2Rotate0.png")); } - + @Test public void testTestGradientLinearDiag2Rotate1() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2Rotate1.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2Rotate1.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2Rotate1.png")); } - + @Test public void testTestGradientLinearDiag2Rotate2() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2Rotate2.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2Rotate2.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2Rotate2.png")); } - + @Test public void testTestGradientLinearDiag2scale() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2scale.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri + .writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2scale.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLineardiag2scale.png")); } - + @Test public void testTestGradientLinearHorizontal() { //@formatter:off - String data = "\n" - + "\n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + "\n"; + final String data = """ + + + + + + + + + + + + + """; //@formatter:on - EsvgDocument doc = new EsvgDocument(); + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearhorizontal.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri + .writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearhorizontal.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLinearhorizontal.png")); } - + @Test public void testTestGradientLinearInternalHref() { - String data = "\n" + "\n" + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearinternalHref.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientLinearinternalHref.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLinearinternalHref.png")); } - + @Test public void testTestGradientLinearUnitBoxspreadNone() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitBoxspreadNone.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitBoxspreadNone.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitBoxspreadNone.png")); } - + @Test public void testTestGradientLinearUnitBoxspreadPad() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitBoxspreadPad.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitBoxspreadPad.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitBoxspreadPad.png")); } - + @Test public void testTestGradientLinearUnitBoxspreadReflect() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitBoxspreadReflect.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitBoxspreadReflect.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitBoxspreadReflect.png")); } - + @Test public void testTestGradientLinearUnitBoxspreadRepeat() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitBoxspreadRepeat.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitBoxspreadRepeat.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitBoxspreadRepeat.png")); } - + @Test public void testTestGradientLinearUnitUserspreadNone() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitUserspreadNone.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitUserspreadNone.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitUserspreadNone.png")); } - + @Test public void testTestGradientLinearUnitUserspreadPad() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitUserspreadPad.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitUserspreadPad.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitUserspreadPad.png")); } - + @Test public void testTestGradientLinearUnitUserspreadReflect() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitUserspreadReflect.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitUserspreadReflect.svg"), + data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitUserspreadReflect.png")); } - + @Test public void testTestGradientLinearUnitUserspreadRepeate() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitUserspreadRepeate.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitUserspreadRepeate.svg"), + data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLinearunitUserspreadRepeate.png")); } - + @Test public void testTestGradientLinearVertical() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearvertical.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri + .writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientLinearvertical.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientLinearvertical.png")); } } diff --git a/test/src/test/atriasoft/esvg/TestGradientRadial.java b/test/src/test/atriasoft/esvg/TestGradientRadial.java index 2671efd..82e6748 100644 --- a/test/src/test/atriasoft/esvg/TestGradientRadial.java +++ b/test/src/test/atriasoft/esvg/TestGradientRadial.java @@ -2,217 +2,387 @@ package test.atriasoft.esvg; import org.atriasoft.esvg.EsvgDocument; import org.atriasoft.etk.Uri; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; class TestGradientRadial { @Test public void testTestGradientRadialCircle() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialcircle.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialcircle.svg"), + data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialcircle.png")); } - + @Test public void testTestGradientRadialFull() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialfull.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialfull.svg"), + data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialfull.png")); } - + @Test public void testTestGradientRadialPartial() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialpartial.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri + .writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialpartial.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialpartial.png")); } - + @Test public void testTestGradientRadialUnitBoxspreadNone() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitBoxspreadNone.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitBoxspreadNone.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitBoxspreadNone.png")); } - + @Test public void testTestGradientRadialUnitBoxspreadPad() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitBoxspreadPad.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitBoxspreadPad.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitBoxspreadPad.png")); } - + @Test public void testTestGradientRadialUnitBoxspreadReflect() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitBoxspreadReflect.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitBoxspreadReflect.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitBoxspreadReflect.png")); } - + @Test public void testTestGradientRadialUnitBoxspreadRepeat() { - String data = "\n" + "\n" + " \n" - + " \n" + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitBoxspreadRepeat.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitBoxspreadRepeat.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitBoxspreadRepeat.png")); } - + @Test public void testTestGradientRadialUnitUserspreadNone() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadNone.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadNone.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadNone.png")); } - + @Test public void testTestGradientRadialUnitUserspreadPad() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadPad.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadPad.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadPad.png")); } - + @Test public void testTestGradientRadialUnitUserspreadPadunCenter() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadPadunCenter.svg"), data.replace("'", "\""))); - ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadPadunCenter.png")); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadPadunCenter.svg"), + data.replace("'", "\""))); + ConfigTest.generateAnImage(doc, + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadPadunCenter.png")); } - + @Test public void testTestGradientRadialUnitUserspreadReflect() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadReflect.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadReflect.svg"), + data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadReflect.png")); } - + @Test public void testTestGradientRadialUnitUserspreadReflectunCenter() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadReflectunCenter.svg"), data.replace("'", "\""))); - ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadReflectunCenter.png")); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadReflectunCenter.svg"), + data.replace("'", "\""))); + ConfigTest.generateAnImage(doc, + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadReflectunCenter.png")); } - + @Test public void testTestGradientRadialUnitUserspreadRepeat() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeat.svg"), data.replace("'", "\""))); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeat.svg"), data.replace("'", "\""))); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeat.png")); } - + @Test public void testTestGradientRadialUnitUserspreadRepeatout() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeatout.svg"), data.replace("'", "\""))); - ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeatout.png")); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeatout.svg"), + data.replace("'", "\""))); + ConfigTest.generateAnImage(doc, + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeatout.png")); } - + @Test public void testTestGradientRadialUnitUserspreadRepeatunCenter() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeatunCenter.svg"), data.replace("'", "\""))); - ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeatunCenter.png")); + Assertions.assertDoesNotThrow( + () -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeatunCenter.svg"), + data.replace("'", "\""))); + ConfigTest.generateAnImage(doc, + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeatunCenter.png")); } - + @Test public void testTestGradientRadialUnitUserspreadRepeatunCenter2() { - String data = "\n" + "\n" + " \n" - + " \n" - + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" + " \n" + "\n"; - EsvgDocument doc = new EsvgDocument(); + final String data = """ + + + + + + + + + + + + + """; + final EsvgDocument doc = new EsvgDocument(); doc.parse(data); - Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeatunCenter2.svg"), data.replace("'", "\""))); - ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeatunCenter2.png")); + Assertions.assertDoesNotThrow(() -> Uri.writeAll( + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeatunCenter2.svg"), + data.replace("'", "\""))); + ConfigTest.generateAnImage(doc, + new Uri(ConfigTest.BASE_PATH + "TestGradientRadialunitUserspreadRepeatunCenter2.png")); } - + } \ No newline at end of file