Compare commits
2 Commits
46989e045c
...
6c0af28ce3
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6c0af28ce3 | ||
![]() |
e78439ef9e |
47
pom.xml
47
pom.xml
@ -1,14 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.atriasoft</groupId>
|
||||
<artifactId>esvg</artifactId>
|
||||
<version>0.1.0</version>
|
||||
<properties>
|
||||
<maven.compiler.version>3.13.0</maven.compiler.version>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<maven.dependency.version>3.1.1</maven.dependency.version>
|
||||
</properties>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Mozilla Public License 2.0</name>
|
||||
<url>https://opensource.org/licenses/MPL-2.0</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>dev1</id>
|
||||
<name>Edouard DUPIN</name>
|
||||
<email>edouard.dupin@proton.me</email>
|
||||
<roles>
|
||||
<role>Lead Developer</role>
|
||||
</roles>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
@ -46,13 +58,13 @@
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.11.0-M2</version>
|
||||
<version>5.11.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.11.0-M2</version>
|
||||
<version>5.11.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -69,29 +81,28 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<sourceDirectory>src/main</sourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${basedir}/src/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<testSourceDirectory>test/src</testSourceDirectory>
|
||||
|
||||
<testSourceDirectory>src/test</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven.compiler.version}</version>
|
||||
<version>3.14.0</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
<!--<encoding>${project.build.sourceEncoding}</encoding>-->
|
||||
<source>21</source>
|
||||
<target>21</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Create the source bundle -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
@ -105,7 +116,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M5</version>
|
||||
<version>3.2.5</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
@ -124,7 +135,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<show>private</show>
|
||||
<nohelp>true</nohelp>
|
||||
@ -138,7 +149,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<show>public</show>
|
||||
</configuration>
|
||||
|
@ -238,7 +238,7 @@ public class Base {
|
||||
} else {
|
||||
if (content.length() != 0) {
|
||||
this.paint.stroke = parseColor(content);
|
||||
LOGGER.error("Parse color : " + this.paint.stroke);
|
||||
//LOGGER.trace("Parse color : " + this.paint.stroke);
|
||||
}
|
||||
content = element.getAttribute("stroke-width", "");
|
||||
if (content.length() != 0) {
|
||||
@ -332,9 +332,9 @@ public class Base {
|
||||
if (inputString.length() == 0) {
|
||||
return;
|
||||
}
|
||||
LOGGER.trace("indexOf transform : '" + inputString + "'");
|
||||
//LOGGER.trace("indexOf transform : '" + inputString + "'");
|
||||
inputString = inputString.replace(',', ' ');
|
||||
LOGGER.trace("indexOf transform : '" + inputString + "'");
|
||||
//LOGGER.trace("indexOf transform : '" + inputString + "'");
|
||||
// need to indexOf elements in order ...
|
||||
String data = Base.extractTransformData(inputString, "matrix");
|
||||
if (data.length() != 0) {
|
||||
@ -352,7 +352,7 @@ public class Base {
|
||||
if (elements != null) {
|
||||
this.transformMatrix = this.transformMatrix
|
||||
.multiply(Matrix2x3f.createTranslate(new Vector2f(elements[0], elements[1])));
|
||||
LOGGER.trace("Translate : " + elements[0] + ", " + elements[1]);
|
||||
//LOGGER.trace("Translate : " + elements[0] + ", " + elements[1]);
|
||||
} else {
|
||||
final float elem = Float.parseFloat(data);
|
||||
this.transformMatrix = this.transformMatrix.multiply(Matrix2x3f.createTranslate(new Vector2f(elem, 0)));
|
||||
@ -364,7 +364,7 @@ public class Base {
|
||||
if (elements != null) {
|
||||
this.transformMatrix = this.transformMatrix
|
||||
.multiply(Matrix2x3f.createScale(new Vector2f(elements[0], elements[1])));
|
||||
LOGGER.trace("Translate : " + elements[0] + ", " + elements[1]);
|
||||
//LOGGER.trace("Translate : " + elements[0] + ", " + elements[1]);
|
||||
} else {
|
||||
final float elem = Float.parseFloat(data);
|
||||
this.transformMatrix = this.transformMatrix.multiply(Matrix2x3f.createScale(elem));
|
@ -27,6 +27,7 @@ public class EsvgDocument extends Base {
|
||||
private String title = ""; //!< sub-element list
|
||||
private Uri uri = null; //!< reference elements ...
|
||||
private String version = "0.0";
|
||||
private static final boolean envDisplayRefs = "true".equals(System.getenv("ESQG_DISPLAY_REFS"));
|
||||
|
||||
public EsvgDocument() {
|
||||
|
||||
@ -380,7 +381,7 @@ public class EsvgDocument extends Base {
|
||||
} else {
|
||||
this.size = Vector2f.clipInt(this.size);
|
||||
}
|
||||
if (!isReference) {
|
||||
if (envDisplayRefs && !isReference) {
|
||||
displayDebug();
|
||||
}
|
||||
return true;
|
@ -53,32 +53,33 @@ public class Renderer {
|
||||
if (!this.visualDebug) {
|
||||
return;
|
||||
}
|
||||
Vector2i dynamicSize = this.size.multiply(this.factor);
|
||||
final Vector2i dynamicSize = this.size.multiply(this.factor);
|
||||
// for each lines:
|
||||
for (int yyy = 0; yyy < dynamicSize.y(); ++yyy) {
|
||||
// Reduce the number of lines in the subsampling parsing:
|
||||
List<Segment> availlableSegmentPixel = new ArrayList<>();
|
||||
for (Segment it : listSegment.data) {
|
||||
final List<Segment> availlableSegmentPixel = new ArrayList<>();
|
||||
for (final Segment it : listSegment.data) {
|
||||
if (it.p0.y() * this.factor <= yyy + 1 && it.p1.y() * this.factor >= (yyy)) {
|
||||
availlableSegmentPixel.add(it);
|
||||
}
|
||||
}
|
||||
//find all the segment that cross the middle of the line of the center of the pixel line:
|
||||
float subSamplingCenterPos = yyy + 0.5f;
|
||||
List<Segment> availlableSegment = new ArrayList<>();
|
||||
final float subSamplingCenterPos = yyy + 0.5f;
|
||||
final List<Segment> availlableSegment = new ArrayList<>();
|
||||
// find in the subList ...
|
||||
for (Segment it : availlableSegmentPixel) {
|
||||
if (it.p0.y() * this.factor <= subSamplingCenterPos && it.p1.y() * this.factor >= subSamplingCenterPos) {
|
||||
for (final Segment it : availlableSegmentPixel) {
|
||||
if (it.p0.y() * this.factor <= subSamplingCenterPos
|
||||
&& it.p1.y() * this.factor >= subSamplingCenterPos) {
|
||||
availlableSegment.add(it);
|
||||
}
|
||||
}
|
||||
// x position, angle
|
||||
for (Segment it : availlableSegment) {
|
||||
Vector2f delta = it.p0.multiply(this.factor).less(it.p1.multiply(this.factor));
|
||||
for (final Segment it : availlableSegment) {
|
||||
final Vector2f delta = it.p0.multiply(this.factor).less(it.p1.multiply(this.factor));
|
||||
// x = coefficent*y+bbb;
|
||||
float coefficient = delta.x() / delta.y();
|
||||
float bbb = it.p0.x() * this.factor - coefficient * it.p0.y() * this.factor;
|
||||
float xpos = coefficient * subSamplingCenterPos + bbb;
|
||||
final float coefficient = delta.x() / delta.y();
|
||||
final float bbb = it.p0.x() * this.factor - coefficient * it.p0.y() * this.factor;
|
||||
final float xpos = coefficient * subSamplingCenterPos + bbb;
|
||||
if (xpos >= 0 && xpos < dynamicSize.x() && yyy >= 0 && yyy < dynamicSize.y()) {
|
||||
if (it.direction == 1.0f) {
|
||||
this.buffer.setColor((int) xpos, yyy, Color.BLUE);
|
||||
@ -91,32 +92,34 @@ public class Renderer {
|
||||
// for each colomn:
|
||||
for (int xxx = 0; xxx < dynamicSize.x(); ++xxx) {
|
||||
// Reduce the number of lines in the subsampling parsing:
|
||||
List<Segment> availlableSegmentPixel = new ArrayList<>();
|
||||
for (Segment it : listSegment.data) {
|
||||
if ((it.p0.x() * this.factor <= xxx + 1 && it.p1.x() * this.factor >= (xxx)) || (it.p0.x() * this.factor >= xxx + 1 && it.p1.x() * this.factor <= (xxx))) {
|
||||
final List<Segment> availlableSegmentPixel = new ArrayList<>();
|
||||
for (final Segment it : listSegment.data) {
|
||||
if ((it.p0.x() * this.factor <= xxx + 1 && it.p1.x() * this.factor >= (xxx))
|
||||
|| (it.p0.x() * this.factor >= xxx + 1 && it.p1.x() * this.factor <= (xxx))) {
|
||||
availlableSegmentPixel.add(it);
|
||||
}
|
||||
}
|
||||
//find all the segment that cross the middle of the line of the center of the pixel line:
|
||||
float subSamplingCenterPos = xxx + 0.5f;
|
||||
List<Segment> availlableSegment = new ArrayList<>();
|
||||
final float subSamplingCenterPos = xxx + 0.5f;
|
||||
final List<Segment> availlableSegment = new ArrayList<>();
|
||||
// find in the subList ...
|
||||
for (Segment it : availlableSegmentPixel) {
|
||||
for (final Segment it : availlableSegmentPixel) {
|
||||
if ((it.p0.x() * this.factor <= subSamplingCenterPos && it.p1.x() * this.factor >= subSamplingCenterPos)
|
||||
|| (it.p0.x() * this.factor >= subSamplingCenterPos && it.p1.x() * this.factor <= subSamplingCenterPos)) {
|
||||
|| (it.p0.x() * this.factor >= subSamplingCenterPos
|
||||
&& it.p1.x() * this.factor <= subSamplingCenterPos)) {
|
||||
availlableSegment.add(it);
|
||||
}
|
||||
}
|
||||
// x position, angle
|
||||
for (Segment it : availlableSegment) {
|
||||
Vector2f delta = it.p0.multiply(this.factor).less(it.p1.multiply(this.factor));
|
||||
for (final Segment it : availlableSegment) {
|
||||
final Vector2f delta = it.p0.multiply(this.factor).less(it.p1.multiply(this.factor));
|
||||
// x = coefficent*y+bbb;
|
||||
if (delta.x() == 0) {
|
||||
continue;
|
||||
}
|
||||
float coefficient = delta.y() / delta.x();
|
||||
float bbb = it.p0.y() * this.factor - coefficient * it.p0.x() * this.factor;
|
||||
float ypos = coefficient * subSamplingCenterPos + bbb;
|
||||
final float coefficient = delta.y() / delta.x();
|
||||
final float bbb = it.p0.y() * this.factor - coefficient * it.p0.x() * this.factor;
|
||||
final float ypos = coefficient * subSamplingCenterPos + bbb;
|
||||
if (ypos >= 0 && ypos < dynamicSize.y() && xxx >= 0 && xxx < dynamicSize.y()) {
|
||||
if (it.direction == 1.0f) {
|
||||
this.buffer.setColor(xxx, (int) ypos, Color.BLUE);
|
||||
@ -160,6 +163,7 @@ public class Renderer {
|
||||
base = result;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
float r = (integration.a() * integration.r() + base.a() * (1.0f - integration.a()) * base.r());
|
||||
float g = (integration.a() * integration.g() + base.a() * (1.0f - integration.a()) * base.g());
|
||||
float b = (integration.a() * integration.b() + base.a() * (1.0f - integration.a()) * base.b());
|
||||
@ -171,9 +175,26 @@ public class Renderer {
|
||||
b *= reverse;
|
||||
}
|
||||
return new Color(r, g, b, a);
|
||||
*/
|
||||
final float a1 = integration.a(); // alpha over
|
||||
final float a0 = base.a(); // alpha under
|
||||
|
||||
final float a = a1 + a0 * (1 - a1);
|
||||
final float aCalc = a != 0 ? 1 / a : 1;
|
||||
|
||||
final float r = (integration.r() * a1 + base.r() * a0 * (1 - a1)) * aCalc;
|
||||
final float g = (integration.g() * a1 + base.g() * a0 * (1 - a1)) * aCalc;
|
||||
final float b = (integration.b() * a1 + base.b() * a0 * (1 - a1)) * aCalc;
|
||||
|
||||
return new Color(r, g, b, a);
|
||||
}
|
||||
|
||||
public void print(final Weight weightFill, final DynamicColor colorFill, final Weight weightStroke, final DynamicColor colorStroke, final float opacity) {
|
||||
public void print(
|
||||
final Weight weightFill,
|
||||
final DynamicColor colorFill,
|
||||
final Weight weightStroke,
|
||||
final DynamicColor colorStroke,
|
||||
final float opacity) {
|
||||
if (colorFill != null) {
|
||||
//colorFill.setViewPort(Pair<Vector2f, Vector2f>(new Vector2f(0,0), Vector2f(sizeX, sizeY)));
|
||||
colorFill.generate(this.document);
|
||||
@ -186,9 +207,9 @@ public class Renderer {
|
||||
for (int yyy = 0; yyy < this.size.y(); ++yyy) {
|
||||
for (int xxx = 0; xxx < this.size.x(); ++xxx) {
|
||||
|
||||
Vector2i pos = new Vector2i(xxx, yyy);
|
||||
float valueFill = weightFill.get(pos);
|
||||
float valueStroke = weightStroke.get(pos);
|
||||
final Vector2i pos = new Vector2i(xxx, yyy);
|
||||
final float valueFill = weightFill.get(pos);
|
||||
final float valueStroke = weightStroke.get(pos);
|
||||
// calculate merge of stroke and fill value:
|
||||
Color intermediateColorFill = Color.NONE;
|
||||
|
||||
@ -206,8 +227,8 @@ public class Renderer {
|
||||
if (Renderer.DEBUG_MODE) {
|
||||
for (int deltaY = 0; deltaY < this.factor; deltaY++) {
|
||||
for (int deltaX = 0; deltaX < this.factor; deltaX++) {
|
||||
int idx = xxx * this.factor + deltaX;
|
||||
int idy = yyy * this.factor + deltaY;
|
||||
final int idx = xxx * this.factor + deltaX;
|
||||
final int idy = yyy * this.factor + deltaY;
|
||||
this.buffer.mergeColor(idx, idy, intermediateColor);
|
||||
}
|
||||
}
|
||||
@ -220,13 +241,19 @@ public class Renderer {
|
||||
if (Renderer.DEBUG_MODE) {
|
||||
|
||||
// display the gradient position:
|
||||
if (colorFill instanceof DynamicColorSpecial tmpColor) {
|
||||
SegmentList listSegment = new SegmentList();
|
||||
if (colorFill instanceof final DynamicColorSpecial tmpColor) {
|
||||
final SegmentList listSegment = new SegmentList();
|
||||
// Display bounding box
|
||||
listSegment.addSegment(new Point(tmpColor.viewPort.first), new Point(new Vector2f(tmpColor.viewPort.first.x(), tmpColor.viewPort.second.y())), false);
|
||||
listSegment.addSegment(new Point(new Vector2f(tmpColor.viewPort.first.x(), tmpColor.viewPort.second.y())), new Point(tmpColor.viewPort.second), false);
|
||||
listSegment.addSegment(new Point(tmpColor.viewPort.second), new Point(new Vector2f(tmpColor.viewPort.second.x(), tmpColor.viewPort.first.y())), false);
|
||||
listSegment.addSegment(new Point(new Vector2f(tmpColor.viewPort.second.x(), tmpColor.viewPort.first.y())), new Point(tmpColor.viewPort.first), false);
|
||||
listSegment.addSegment(new Point(tmpColor.viewPort.first),
|
||||
new Point(new Vector2f(tmpColor.viewPort.first.x(), tmpColor.viewPort.second.y())), false);
|
||||
listSegment.addSegment(
|
||||
new Point(new Vector2f(tmpColor.viewPort.first.x(), tmpColor.viewPort.second.y())),
|
||||
new Point(tmpColor.viewPort.second), false);
|
||||
listSegment.addSegment(new Point(tmpColor.viewPort.second),
|
||||
new Point(new Vector2f(tmpColor.viewPort.second.x(), tmpColor.viewPort.first.y())), false);
|
||||
listSegment.addSegment(
|
||||
new Point(new Vector2f(tmpColor.viewPort.second.x(), tmpColor.viewPort.first.y())),
|
||||
new Point(tmpColor.viewPort.first), false);
|
||||
listSegment.applyMatrix(tmpColor.matrix);
|
||||
// display the gradient axis
|
||||
listSegment.addSegment(new Point(tmpColor.pos1), new Point(tmpColor.pos2), false);
|
@ -20,7 +20,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
public class PathModel {
|
||||
static final Logger LOGGER = LoggerFactory.getLogger(PathModel.class);
|
||||
|
||||
|
||||
private static void interpolateCubicBezier(
|
||||
final List<Point> listPoint,
|
||||
final int recurtionMax,
|
||||
@ -37,11 +37,11 @@ public class PathModel {
|
||||
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);
|
||||
|
||||
|
||||
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;
|
||||
@ -49,13 +49,13 @@ public class PathModel {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* add indentation of the string input.
|
||||
* @param data String where the indentation is done.
|
||||
@ -68,55 +68,55 @@ public class PathModel {
|
||||
}
|
||||
return data.toString();
|
||||
}
|
||||
|
||||
|
||||
private static float vectorAngle(Vector2f uuu, Vector2f vvv) {
|
||||
uuu = uuu.safeNormalize();
|
||||
vvv = vvv.safeNormalize();
|
||||
return (float) Math.atan2(uuu.cross(vvv), uuu.dot(vvv));
|
||||
}
|
||||
|
||||
|
||||
SegmentList debugInformation;
|
||||
|
||||
|
||||
public List<Element> listElement = new ArrayList<>();
|
||||
|
||||
|
||||
public PathModel() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void bezierCurveTo(final boolean relative, final Vector2f pos1, final Vector2f pos) {
|
||||
this.listElement.add(new ElementBezierCurveTo(relative, pos1, pos));
|
||||
}
|
||||
|
||||
|
||||
public void bezierSmoothCurveTo(final boolean relative, final Vector2f pos) {
|
||||
this.listElement.add(new ElementBezierSmoothCurveTo(relative, pos));
|
||||
}
|
||||
|
||||
|
||||
public void clear() {
|
||||
this.listElement.clear();
|
||||
}
|
||||
|
||||
|
||||
public void close() {
|
||||
close(false);
|
||||
}
|
||||
|
||||
|
||||
public void close(final boolean relative) {
|
||||
this.listElement.add(new ElementClose(relative));
|
||||
}
|
||||
|
||||
|
||||
public void curveTo(final boolean relative, final Vector2f pos1, final Vector2f pos2, final Vector2f pos) {
|
||||
this.listElement.add(new ElementCurveTo(relative, pos1, pos2, pos));
|
||||
}
|
||||
|
||||
|
||||
public void display(final int spacing) {
|
||||
LOGGER.warn(PathModel.spacingDist(spacing) + "Path");
|
||||
//LOGGER.trace(PathModel.spacingDist(spacing) + "Path");
|
||||
for (final Element it : this.listElement) {
|
||||
if (it == null) {
|
||||
continue;
|
||||
}
|
||||
LOGGER.warn(PathModel.spacingDist(spacing + 1) + it);
|
||||
//LOGGER.trace(PathModel.spacingDist(spacing + 1) + it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Weight drawFill(
|
||||
final Vector2i size,
|
||||
final Matrix2x3f basicTrans,
|
||||
@ -133,7 +133,7 @@ public class PathModel {
|
||||
weight.generate(size, config.numberOfScanline(), listSegment);
|
||||
return weight;
|
||||
}
|
||||
|
||||
|
||||
public Weight drawStroke(
|
||||
final Vector2i size,
|
||||
final Matrix2x3f basicTrans,
|
||||
@ -151,7 +151,7 @@ public class PathModel {
|
||||
weight.generate(size, config.numberOfScanline(), listSegment);
|
||||
return weight;
|
||||
}
|
||||
|
||||
|
||||
public void ellipticTo(
|
||||
final boolean relative,
|
||||
final Vector2f radius,
|
||||
@ -161,15 +161,15 @@ public class PathModel {
|
||||
final Vector2f pos) {
|
||||
this.listElement.add(new ElementElliptic(relative, radius, angle, largeArcFlag, sweepFlag, pos));
|
||||
}
|
||||
|
||||
|
||||
public PointList generateListPoints(final int level) {
|
||||
return generateListPoints(level, 10);
|
||||
}
|
||||
|
||||
|
||||
public PointList generateListPoints(final int level, final int recurtionMax) {
|
||||
return generateListPoints(level, recurtionMax, 0.25f);
|
||||
}
|
||||
|
||||
|
||||
public PointList generateListPoints(final int level, final int recurtionMax, final float threshold) {
|
||||
LOGGER.trace(PathModel.spacingDist(level) + "Generate List Points ... from a path");
|
||||
final PointList out = new PointList();
|
||||
@ -361,7 +361,7 @@ public class PathModel {
|
||||
+ tmpIt.largeArcFlag);
|
||||
LOGGER.info("TODO:" + PathModel.spacingDist(level + 1) + " this.sweepFlag="
|
||||
+ tmpIt.sweepFlag);
|
||||
|
||||
|
||||
final Vector2f lastPosStore = lastPosition;
|
||||
if (!it.getRelative()) {
|
||||
lastPosition = Vector2f.ZERO;
|
||||
@ -369,7 +369,7 @@ public class PathModel {
|
||||
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();
|
||||
@ -442,7 +442,7 @@ public class PathModel {
|
||||
// Split arc into max 90 degree segments.
|
||||
// The loop assumes an iteration per end point (including start and end), this +1.
|
||||
final int ndivs = (int) (Math.abs(deltaTheta) / ((float) Math.PI * 0.5f)) + 1;
|
||||
|
||||
|
||||
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) {
|
||||
@ -494,29 +494,29 @@ public class PathModel {
|
||||
out.display();
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
public void lineTo(final boolean relative, final Vector2f pos) {
|
||||
this.listElement.add(new ElementLineTo(relative, pos));
|
||||
}
|
||||
|
||||
|
||||
public void lineToH(final boolean relative, final float posX) {
|
||||
this.listElement.add(new ElementLineToH(relative, posX));
|
||||
}
|
||||
|
||||
|
||||
public void lineToV(final boolean relative, final float posY) {
|
||||
this.listElement.add(new ElementLineToV(relative, posY));
|
||||
}
|
||||
|
||||
|
||||
public void moveTo(final boolean relative, final Vector2f pos) {
|
||||
this.listElement.add(new ElementMoveTo(relative, pos));
|
||||
}
|
||||
|
||||
|
||||
public void smoothCurveTo(final boolean relative, final Vector2f pos2, final Vector2f pos) {
|
||||
this.listElement.add(new ElementSmoothCurveTo(relative, pos2, pos));
|
||||
}
|
||||
|
||||
|
||||
public void stop() {
|
||||
this.listElement.add(new ElementStop());
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
/** Basic module interface.
|
||||
*
|
||||
* @author Edouard DUPIN */
|
||||
|
||||
open module org.atriasoft.esvg {
|
||||
exports org.atriasoft.esvg;
|
||||
exports org.atriasoft.esvg.font;
|
||||
exports org.atriasoft.esvg.render;
|
||||
|
||||
requires transitive org.atriasoft.etk;
|
||||
requires transitive org.atriasoft.exml;
|
||||
requires org.atriasoft.pngencoder;
|
||||
requires java.desktop;
|
||||
requires org.atriasoft.egami;
|
||||
}
|
113
src/test/test/atriasoft/esvg/TestFont.java
Normal file
113
src/test/test/atriasoft/esvg/TestFont.java
Normal file
@ -0,0 +1,113 @@
|
||||
package test.atriasoft.esvg;
|
||||
|
||||
import org.atriasoft.esvg.Esvg;
|
||||
import org.atriasoft.esvg.EsvgDocument;
|
||||
import org.atriasoft.esvg.EsvgFont;
|
||||
import org.atriasoft.esvg.render.Weight;
|
||||
import org.atriasoft.etk.Uri;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class TestFont {
|
||||
|
||||
@Test
|
||||
public void testFontError1() {
|
||||
final String data = """
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>\
|
||||
<svg height='900' width='700'>\
|
||||
<path d='M296 463q80 0 125 -45t45 -126q0 -130 -73 -217.5t-187 -87.5q-80 0 -125 45.5t-45 127.5q0 126 73 214.5t187 88.5zM218 51q78 0 123.5 68t45.5 166q0 115 -103 115q-75 0 -122 -66.5t-47 -167.5q0 -115 103 -115z'\
|
||||
stroke='green' stroke-width='3' />\
|
||||
</svg>""";
|
||||
final EsvgDocument doc = new EsvgDocument();
|
||||
doc.parse(data);
|
||||
Assertions.assertDoesNotThrow(
|
||||
() -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestFontError1.svg"), data.replace("'", "\"")));
|
||||
ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestFontError1.png"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontError2() {
|
||||
final String data = """
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>\
|
||||
<svg height='900' width='700'>\
|
||||
<path d='M296 463q80 0 125 -45t45 -126q0 -130 -73 -217.5t-187 -87.5q-80 0 -125 45.5t-45 127.5q0 126 73 214.5t187 88.5z'\
|
||||
stroke='green' stroke-width='3' />\
|
||||
</svg>""";
|
||||
final EsvgDocument doc = new EsvgDocument();
|
||||
doc.parse(data);
|
||||
Assertions.assertDoesNotThrow(
|
||||
() -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestFontError2.svg"), data.replace("'", "\"")));
|
||||
ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestFontError2.png"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontError3() {
|
||||
final String data = """
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>\
|
||||
<svg height='900' width='700'>\
|
||||
<path d='M218 51q78 0 123.5 68t45.5 166q0 115 -103 115q-75 0 -122 -66.5t-47 -167.5q0 -115 103 -115z'\
|
||||
stroke='green' stroke-width='3' />\
|
||||
</svg>""";
|
||||
final EsvgDocument doc = new EsvgDocument();
|
||||
doc.parse(data);
|
||||
Assertions.assertDoesNotThrow(
|
||||
() -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestFontError3.svg"), data.replace("'", "\"")));
|
||||
ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestFontError3.png"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontError4() {
|
||||
final String data = """
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>\
|
||||
<svg height='900' width='700'>\
|
||||
<path d='M1011 -78q51 -11 84.5 -50.5t33.5 -93.5q0 -61 -43 -103t-104 -42q-60 0 -102 43q-43 42 -43 102q0 34 16 67q-2 0 -20 -4.5t-36.5 -8t-47 -7.5t-66.5 -6.5t-80 -2.5q-144 0 -248 27.5t-164.5 80.5t-88.5 123t-28 161q0 124 106 240l33 -30q-101 -101 -101 -206
|
||||
q0 -335 487 -335q304 0 401 123q-39 -10 -68 -10q-95 3 -142 74q-50 -74 -136 -74q-68 0 -120 47t-52 125v92q0 75 -25.5 106t-58.5 31q-49 0 -92 -49t-43 -124q0 -19 3.5 -40.5t13.5 -53t34 -61.5t60 -48l-22 -25q-43 23 -72 58t-41 72.5t-16 63t-4 46.5q0 103 58.5 161.5
|
||||
t130.5 58.5q24 0 47.5 -8t46.5 -26.5t37 -56t14 -89.5v-87q0 -79 37 -112t81 -33q40 0 69.5 22.5t29.5 57.5v322h83v-275q0 -55 27.5 -84.5t67.5 -29.5q60 0 95.5 52.5t35.5 125.5q0 20 -3 40t-12.5 50t-33 57.5t-57.5 46.5l29 25q57 -44 90.5 -105t33.5 -130
|
||||
q0 -195 -115 -291zM972 -218q23 0 37.5 15t14.5 37q0 17 -16 32.5t-35 15.5q-30 0 -41.5 -12t-11.5 -36q0 -23 15 -37.5t37 -14.5zM970 -316q41 0 69.5 29t28.5 69q0 38 -19 60q1 -3 1 -13q0 -38 -25 -62.5t-60 -24.5q-33 0 -57.5 22.5t-28.5 55.5q-7 -20 -7 -38
|
||||
q0 -41 29 -69.5t69 -28.5z'\
|
||||
stroke='green' stroke-width='3' />\
|
||||
</svg>""";
|
||||
final EsvgDocument doc = new EsvgDocument();
|
||||
doc.parse(data);
|
||||
Assertions.assertDoesNotThrow(
|
||||
() -> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestFontError4.svg"), data.replace("'", "\"")));
|
||||
ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestFontError4.png"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontprintE25() {
|
||||
Esvg.init();
|
||||
final EsvgFont font = EsvgFont.load(new Uri("FONTS", "FreeSherif.svg", "esvg"));
|
||||
Assertions.assertNotNull(font);
|
||||
Weight out = font.render('E', 25);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_E25.png"));
|
||||
out = font.render('e', 25);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_e25.png"));
|
||||
out = font.render('É', 25);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_Ecute25.png"));
|
||||
out = font.render('é', 25);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_ecute25.png"));
|
||||
out = font.render('p', 25);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_p25.png"));
|
||||
out = font.render('f', 25);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_f25.png"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontprintSimpleText() {
|
||||
Esvg.init();
|
||||
final EsvgFont font = EsvgFont.load(new Uri("FONTS", "FreeSherif.svg", "esvg"));
|
||||
Weight out = font.render("Hello, How are you? VA // @ ê É", 100, false);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_Hello.png"));
|
||||
out = font.render("Hello, How are you? VA // @ ê É", 100, true);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_Hello_withKerning.png"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontRead() {
|
||||
Esvg.init();
|
||||
final EsvgFont font = EsvgFont.load(new Uri("FONTS", "FreeSherif.svg", "esvg"));
|
||||
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
package test.atriasoft.esvg;
|
||||
|
||||
import org.atriasoft.esvg.Esvg;
|
||||
import org.atriasoft.esvg.EsvgDocument;
|
||||
import org.atriasoft.esvg.EsvgFont;
|
||||
import org.atriasoft.esvg.render.Weight;
|
||||
import org.atriasoft.etk.Uri;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class TestFont {
|
||||
|
||||
@Test
|
||||
public void testFontError1() {
|
||||
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" + "<svg height='900' width='700'>"
|
||||
+ " <path d='M296 463q80 0 125 -45t45 -126q0 -130 -73 -217.5t-187 -87.5q-80 0 -125 45.5t-45 127.5q0 126 73 214.5t187 88.5zM218 51q78 0 123.5 68t45.5 166q0 115 -103 115q-75 0 -122 -66.5t-47 -167.5q0 -115 103 -115z'"
|
||||
+ " stroke='green' stroke-width='3' />" + "</svg>";
|
||||
EsvgDocument doc = new EsvgDocument();
|
||||
doc.parse(data);
|
||||
Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestFontError1.svg"), data.replace("'", "\"")));
|
||||
ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestFontError1.png"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontError2() {
|
||||
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" + "<svg height='900' width='700'>"
|
||||
+ " <path d='M296 463q80 0 125 -45t45 -126q0 -130 -73 -217.5t-187 -87.5q-80 0 -125 45.5t-45 127.5q0 126 73 214.5t187 88.5z'" + " stroke='green' stroke-width='3' />"
|
||||
+ "</svg>";
|
||||
EsvgDocument doc = new EsvgDocument();
|
||||
doc.parse(data);
|
||||
Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestFontError2.svg"), data.replace("'", "\"")));
|
||||
ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestFontError2.png"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontError3() {
|
||||
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" + "<svg height='900' width='700'>"
|
||||
+ " <path d='M218 51q78 0 123.5 68t45.5 166q0 115 -103 115q-75 0 -122 -66.5t-47 -167.5q0 -115 103 -115z'" + " stroke='green' stroke-width='3' />" + "</svg>";
|
||||
EsvgDocument doc = new EsvgDocument();
|
||||
doc.parse(data);
|
||||
Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestFontError3.svg"), data.replace("'", "\"")));
|
||||
ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestFontError3.png"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontError4() {
|
||||
String data = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" + "<svg height='900' width='700'>"
|
||||
+ " <path d='M1011 -78q51 -11 84.5 -50.5t33.5 -93.5q0 -61 -43 -103t-104 -42q-60 0 -102 43q-43 42 -43 102q0 34 16 67q-2 0 -20 -4.5t-36.5 -8t-47 -7.5t-66.5 -6.5t-80 -2.5q-144 0 -248 27.5t-164.5 80.5t-88.5 123t-28 161q0 124 106 240l33 -30q-101 -101 -101 -206\n"
|
||||
+ "q0 -335 487 -335q304 0 401 123q-39 -10 -68 -10q-95 3 -142 74q-50 -74 -136 -74q-68 0 -120 47t-52 125v92q0 75 -25.5 106t-58.5 31q-49 0 -92 -49t-43 -124q0 -19 3.5 -40.5t13.5 -53t34 -61.5t60 -48l-22 -25q-43 23 -72 58t-41 72.5t-16 63t-4 46.5q0 103 58.5 161.5\n"
|
||||
+ "t130.5 58.5q24 0 47.5 -8t46.5 -26.5t37 -56t14 -89.5v-87q0 -79 37 -112t81 -33q40 0 69.5 22.5t29.5 57.5v322h83v-275q0 -55 27.5 -84.5t67.5 -29.5q60 0 95.5 52.5t35.5 125.5q0 20 -3 40t-12.5 50t-33 57.5t-57.5 46.5l29 25q57 -44 90.5 -105t33.5 -130\n"
|
||||
+ "q0 -195 -115 -291zM972 -218q23 0 37.5 15t14.5 37q0 17 -16 32.5t-35 15.5q-30 0 -41.5 -12t-11.5 -36q0 -23 15 -37.5t37 -14.5zM970 -316q41 0 69.5 29t28.5 69q0 38 -19 60q1 -3 1 -13q0 -38 -25 -62.5t-60 -24.5q-33 0 -57.5 22.5t-28.5 55.5q-7 -20 -7 -38\n"
|
||||
+ "q0 -41 29 -69.5t69 -28.5z'" + " stroke='green' stroke-width='3' />" + "</svg>";
|
||||
EsvgDocument doc = new EsvgDocument();
|
||||
doc.parse(data);
|
||||
Assertions.assertDoesNotThrow(()-> Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestFontError4.svg"), data.replace("'", "\"")));
|
||||
ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestFontError4.png"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontprintE25() {
|
||||
Esvg.init();
|
||||
EsvgFont font = EsvgFont.load(new Uri("FONTS", "FreeSherif.svg", "esvg"));
|
||||
Weight out = font.render('E', 25);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_E25.png"));
|
||||
out = font.render('e', 25);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_e25.png"));
|
||||
out = font.render('É', 25);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_Ecute25.png"));
|
||||
out = font.render('é', 25);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_ecute25.png"));
|
||||
out = font.render('p', 25);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_p25.png"));
|
||||
out = font.render('f', 25);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_f25.png"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontprintSimpleText() {
|
||||
Esvg.init();
|
||||
EsvgFont font = EsvgFont.load(new Uri("FONTS", "FreeSherif.svg", "esvg"));
|
||||
Weight out = font.render("Hello, How are you? VA // @ ê É", 100, false);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_Hello.png"));
|
||||
out = font.render("Hello, How are you? VA // @ ê É", 100, true);
|
||||
ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_Hello_withKerning.png"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFontRead() {
|
||||
Esvg.init();
|
||||
EsvgFont font = EsvgFont.load(new Uri("FONTS", "FreeSherif.svg", "esvg"));
|
||||
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user