From b46878696f02213a1b524fb8e6cf7e93c7d5c398 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Sun, 10 Aug 2025 00:50:06 +0200 Subject: [PATCH] [DEV] some updates --- .../org/atriasoft/esvg/GraphicContext.java | 277 ------------------ src/main/org/atriasoft/esvg/Renderer.java | 60 ++-- 2 files changed, 34 insertions(+), 303 deletions(-) delete mode 100644 src/main/org/atriasoft/esvg/GraphicContext.java diff --git a/src/main/org/atriasoft/esvg/GraphicContext.java b/src/main/org/atriasoft/esvg/GraphicContext.java deleted file mode 100644 index 32060c9..0000000 --- a/src/main/org/atriasoft/esvg/GraphicContext.java +++ /dev/null @@ -1,277 +0,0 @@ -package org.atriasoft.esvg; - -import org.atriasoft.egami.ImageByte; -import org.atriasoft.egami.ToolImage; -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 - * @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); - } - - 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. - */ - public Color getColorFill() { - return this.paintState.getFill(); - } - - /** - * Get the stroke color. - * @return Stroke color. - */ - 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); - } - - 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) { - LOGGER.error("Empty path... Need call pathStart() before"); - return; - } - this.path.lineTo(false, pos); - } - - public void pathLineTo(final Vector2f pos) { - if (this.path == null) { - LOGGER.error("Empty path... Need call pathStart() before"); - return; - } - this.path.lineTo(true, pos); - - } - - public void pathMove(final Vector2f pos) { - if (this.path == null) { - LOGGER.error("Empty path... Need call pathStart() before"); - return; - } - this.path.moveTo(false, pos); - } - - public void pathMoveTo(final Vector2f pos) { - if (this.path == null) { - 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; - } - this.path.close(false); - this.document.addElement(new Path(this.path, this.paintState.clone())); - this.path = null; - } - - public void pathStopLinked() { - if (this.path == null) { - return; - } - this.path.close(true); - 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) { - 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) { - 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) { - 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) { - 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 - * @apiNote use clearFill() if you want to remove drawing of fill - */ - public void setColorFill(final Color color) { - this.paintState.setFill(color); - } - - /** - * set the stroke color - * @param color Color to set on stroke - * @apiNote use clearStroke() if you want to remove drawing of stroke - */ - 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 - * @param yyy Height of the image - * @apiNote It will clear the current context. - */ - 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 - * @apiNote It will clear the current context. - */ - private void setSize(final Vector2i size) { - 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())); - } - - public void text(final Vector2f position, final String data) { - text(position, Configs.getConfigFonts().getSize(), data); - } - -} diff --git a/src/main/org/atriasoft/esvg/Renderer.java b/src/main/org/atriasoft/esvg/Renderer.java index cc7a978..19abe81 100644 --- a/src/main/org/atriasoft/esvg/Renderer.java +++ b/src/main/org/atriasoft/esvg/Renderer.java @@ -14,6 +14,8 @@ import org.atriasoft.etk.Color; import org.atriasoft.etk.math.FMath; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.math.Vector2i; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @file * @author Edouard DUPIN @@ -21,23 +23,24 @@ import org.atriasoft.etk.math.Vector2i; * @license MPL v2.0 (see license file) */ public class Renderer { + private static final Logger LOGGER = LoggerFactory.getLogger(Renderer.class); private static final boolean DEBUG_MODE = false; protected ImageFloatRGBA buffer; // for debug protected EsvgDocument document; // for debug - + private int factor = 1; - + protected int interpolationRecurtionMax = 10; - + protected float interpolationThreshold = 0.25f; protected int nbSubScanLine = 8; protected Vector2i size; private final boolean visualDebug = false; - + public Renderer(final Vector2i size, final EsvgDocument document) { this(size, document, false); } - + public Renderer(final Vector2i size, final EsvgDocument document, final boolean visualDebug) { this.size = size; this.document = document; @@ -48,7 +51,7 @@ public class Renderer { } setSize(size); } - + void addDebugSegment(final SegmentList listSegment) { if (!this.visualDebug) { return; @@ -130,31 +133,31 @@ public class Renderer { } } } - + ImageFloatRGBA getData() { return this.buffer; } - + int getInterpolationRecurtionMax() { return this.interpolationRecurtionMax; } - + float getInterpolationThreshold() { return this.interpolationThreshold; } - + public EsvgDocument getMainDocument() { return this.document; } - + int getNumberSubScanLine() { return this.nbSubScanLine; } - + Vector2i getSize() { return this.size; } - + protected Color mergeColor(final Color base, final Color integration) { /* if (integration.a() < base.a()) { @@ -178,23 +181,24 @@ public class Renderer { */ 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) { + final long startTime = System.currentTimeMillis(); if (colorFill != null) { //colorFill.setViewPort(Pair(new Vector2f(0,0), Vector2f(sizeX, sizeY))); colorFill.generate(this.document); @@ -205,14 +209,16 @@ public class Renderer { } // all together for (int yyy = 0; yyy < this.size.y(); ++yyy) { + final long stopTime2 = System.currentTimeMillis(); + LOGGER.trace("take time to gnerate: " + (stopTime2 - startTime) + " for " + yyy + "/" + this.size.y()); for (int xxx = 0; xxx < this.size.x(); ++xxx) { - + 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; - + Color intermediateColorStroke = Color.NONE; if (colorFill != null && valueFill != 0.0f) { intermediateColorFill = colorFill.getColor(pos); @@ -237,9 +243,9 @@ public class Renderer { } } } - + if (Renderer.DEBUG_MODE) { - + // display the gradient position: if (colorFill instanceof final DynamicColorSpecial tmpColor) { final SegmentList listSegment = new SegmentList(); @@ -266,20 +272,22 @@ public class Renderer { addDebugSegment(listSegment); } } + final long stopTime = System.currentTimeMillis(); + LOGGER.trace("take time to generate: " + (stopTime - startTime)); } - + public void setInterpolationRecurtionMax(final int value) { this.interpolationRecurtionMax = FMath.avg(1, value, 200); } - + void setInterpolationThreshold(final float value) { this.interpolationThreshold = FMath.avg(0.0f, value, 20000.0f); } - + void setNumberSubScanLine(final int value) { this.nbSubScanLine = FMath.avg(1, value, 200); } - + public void setSize(final Vector2i size) { this.size = size; if (Renderer.DEBUG_MODE) { @@ -288,5 +296,5 @@ public class Renderer { this.buffer = new ImageFloatRGBA(this.size.multiply(this.factor)); } } - + }