[DEV] some updates
This commit is contained in:
parent
cba9f75a77
commit
b46878696f
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -14,6 +14,8 @@ import org.atriasoft.etk.Color;
|
|||||||
import org.atriasoft.etk.math.FMath;
|
import org.atriasoft.etk.math.FMath;
|
||||||
import org.atriasoft.etk.math.Vector2f;
|
import org.atriasoft.etk.math.Vector2f;
|
||||||
import org.atriasoft.etk.math.Vector2i;
|
import org.atriasoft.etk.math.Vector2i;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
* @author Edouard DUPIN
|
* @author Edouard DUPIN
|
||||||
@ -21,23 +23,24 @@ import org.atriasoft.etk.math.Vector2i;
|
|||||||
* @license MPL v2.0 (see license file)
|
* @license MPL v2.0 (see license file)
|
||||||
*/
|
*/
|
||||||
public class Renderer {
|
public class Renderer {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(Renderer.class);
|
||||||
private static final boolean DEBUG_MODE = false;
|
private static final boolean DEBUG_MODE = false;
|
||||||
protected ImageFloatRGBA buffer; // for debug
|
protected ImageFloatRGBA buffer; // for debug
|
||||||
protected EsvgDocument document; // for debug
|
protected EsvgDocument document; // for debug
|
||||||
|
|
||||||
private int factor = 1;
|
private int factor = 1;
|
||||||
|
|
||||||
protected int interpolationRecurtionMax = 10;
|
protected int interpolationRecurtionMax = 10;
|
||||||
|
|
||||||
protected float interpolationThreshold = 0.25f;
|
protected float interpolationThreshold = 0.25f;
|
||||||
protected int nbSubScanLine = 8;
|
protected int nbSubScanLine = 8;
|
||||||
protected Vector2i size;
|
protected Vector2i size;
|
||||||
private final boolean visualDebug = false;
|
private final boolean visualDebug = false;
|
||||||
|
|
||||||
public Renderer(final Vector2i size, final EsvgDocument document) {
|
public Renderer(final Vector2i size, final EsvgDocument document) {
|
||||||
this(size, document, false);
|
this(size, document, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Renderer(final Vector2i size, final EsvgDocument document, final boolean visualDebug) {
|
public Renderer(final Vector2i size, final EsvgDocument document, final boolean visualDebug) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.document = document;
|
this.document = document;
|
||||||
@ -48,7 +51,7 @@ public class Renderer {
|
|||||||
}
|
}
|
||||||
setSize(size);
|
setSize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDebugSegment(final SegmentList listSegment) {
|
void addDebugSegment(final SegmentList listSegment) {
|
||||||
if (!this.visualDebug) {
|
if (!this.visualDebug) {
|
||||||
return;
|
return;
|
||||||
@ -130,31 +133,31 @@ public class Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageFloatRGBA getData() {
|
ImageFloatRGBA getData() {
|
||||||
return this.buffer;
|
return this.buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getInterpolationRecurtionMax() {
|
int getInterpolationRecurtionMax() {
|
||||||
return this.interpolationRecurtionMax;
|
return this.interpolationRecurtionMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getInterpolationThreshold() {
|
float getInterpolationThreshold() {
|
||||||
return this.interpolationThreshold;
|
return this.interpolationThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EsvgDocument getMainDocument() {
|
public EsvgDocument getMainDocument() {
|
||||||
return this.document;
|
return this.document;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getNumberSubScanLine() {
|
int getNumberSubScanLine() {
|
||||||
return this.nbSubScanLine;
|
return this.nbSubScanLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2i getSize() {
|
Vector2i getSize() {
|
||||||
return this.size;
|
return this.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Color mergeColor(final Color base, final Color integration) {
|
protected Color mergeColor(final Color base, final Color integration) {
|
||||||
/*
|
/*
|
||||||
if (integration.a() < base.a()) {
|
if (integration.a() < base.a()) {
|
||||||
@ -178,23 +181,24 @@ public class Renderer {
|
|||||||
*/
|
*/
|
||||||
final float a1 = integration.a(); // alpha over
|
final float a1 = integration.a(); // alpha over
|
||||||
final float a0 = base.a(); // alpha under
|
final float a0 = base.a(); // alpha under
|
||||||
|
|
||||||
final float a = a1 + a0 * (1 - a1);
|
final float a = a1 + a0 * (1 - a1);
|
||||||
final float aCalc = a != 0 ? 1 / a : 1;
|
final float aCalc = a != 0 ? 1 / a : 1;
|
||||||
|
|
||||||
final float r = (integration.r() * a1 + base.r() * a0 * (1 - a1)) * aCalc;
|
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 g = (integration.g() * a1 + base.g() * a0 * (1 - a1)) * aCalc;
|
||||||
final float b = (integration.b() * a1 + base.b() * a0 * (1 - a1)) * aCalc;
|
final float b = (integration.b() * a1 + base.b() * a0 * (1 - a1)) * aCalc;
|
||||||
|
|
||||||
return new Color(r, g, b, a);
|
return new Color(r, g, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void print(
|
public void print(
|
||||||
final Weight weightFill,
|
final Weight weightFill,
|
||||||
final DynamicColor colorFill,
|
final DynamicColor colorFill,
|
||||||
final Weight weightStroke,
|
final Weight weightStroke,
|
||||||
final DynamicColor colorStroke,
|
final DynamicColor colorStroke,
|
||||||
final float opacity) {
|
final float opacity) {
|
||||||
|
final long startTime = System.currentTimeMillis();
|
||||||
if (colorFill != null) {
|
if (colorFill != null) {
|
||||||
//colorFill.setViewPort(Pair<Vector2f, Vector2f>(new Vector2f(0,0), Vector2f(sizeX, sizeY)));
|
//colorFill.setViewPort(Pair<Vector2f, Vector2f>(new Vector2f(0,0), Vector2f(sizeX, sizeY)));
|
||||||
colorFill.generate(this.document);
|
colorFill.generate(this.document);
|
||||||
@ -205,14 +209,16 @@ public class Renderer {
|
|||||||
}
|
}
|
||||||
// all together
|
// all together
|
||||||
for (int yyy = 0; yyy < this.size.y(); ++yyy) {
|
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) {
|
for (int xxx = 0; xxx < this.size.x(); ++xxx) {
|
||||||
|
|
||||||
final Vector2i pos = new Vector2i(xxx, yyy);
|
final Vector2i pos = new Vector2i(xxx, yyy);
|
||||||
final float valueFill = weightFill.get(pos);
|
final float valueFill = weightFill.get(pos);
|
||||||
final float valueStroke = weightStroke.get(pos);
|
final float valueStroke = weightStroke.get(pos);
|
||||||
// calculate merge of stroke and fill value:
|
// calculate merge of stroke and fill value:
|
||||||
Color intermediateColorFill = Color.NONE;
|
Color intermediateColorFill = Color.NONE;
|
||||||
|
|
||||||
Color intermediateColorStroke = Color.NONE;
|
Color intermediateColorStroke = Color.NONE;
|
||||||
if (colorFill != null && valueFill != 0.0f) {
|
if (colorFill != null && valueFill != 0.0f) {
|
||||||
intermediateColorFill = colorFill.getColor(pos);
|
intermediateColorFill = colorFill.getColor(pos);
|
||||||
@ -237,9 +243,9 @@ public class Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Renderer.DEBUG_MODE) {
|
if (Renderer.DEBUG_MODE) {
|
||||||
|
|
||||||
// display the gradient position:
|
// display the gradient position:
|
||||||
if (colorFill instanceof final DynamicColorSpecial tmpColor) {
|
if (colorFill instanceof final DynamicColorSpecial tmpColor) {
|
||||||
final SegmentList listSegment = new SegmentList();
|
final SegmentList listSegment = new SegmentList();
|
||||||
@ -266,20 +272,22 @@ public class Renderer {
|
|||||||
addDebugSegment(listSegment);
|
addDebugSegment(listSegment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
final long stopTime = System.currentTimeMillis();
|
||||||
|
LOGGER.trace("take time to generate: " + (stopTime - startTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInterpolationRecurtionMax(final int value) {
|
public void setInterpolationRecurtionMax(final int value) {
|
||||||
this.interpolationRecurtionMax = FMath.avg(1, value, 200);
|
this.interpolationRecurtionMax = FMath.avg(1, value, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setInterpolationThreshold(final float value) {
|
void setInterpolationThreshold(final float value) {
|
||||||
this.interpolationThreshold = FMath.avg(0.0f, value, 20000.0f);
|
this.interpolationThreshold = FMath.avg(0.0f, value, 20000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNumberSubScanLine(final int value) {
|
void setNumberSubScanLine(final int value) {
|
||||||
this.nbSubScanLine = FMath.avg(1, value, 200);
|
this.nbSubScanLine = FMath.avg(1, value, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSize(final Vector2i size) {
|
public void setSize(final Vector2i size) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
if (Renderer.DEBUG_MODE) {
|
if (Renderer.DEBUG_MODE) {
|
||||||
@ -288,5 +296,5 @@ public class Renderer {
|
|||||||
this.buffer = new ImageFloatRGBA(this.size.multiply(this.factor));
|
this.buffer = new ImageFloatRGBA(this.size.multiply(this.factor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user