diff --git a/src/org/atriasoft/esvg/EsvgFont.java b/src/org/atriasoft/esvg/EsvgFont.java index dece63b..d567bf2 100644 --- a/src/org/atriasoft/esvg/EsvgFont.java +++ b/src/org/atriasoft/esvg/EsvgFont.java @@ -256,6 +256,35 @@ public class EsvgFont { return (float) realSize / (float) this.unitsPerEm; } + public Vector2i calculateTextSize(final int fontSize, final String data) { + boolean withKerning = true; + int widthOut = calculateWidth(data, fontSize, withKerning); + + int realSize = calculateFontRealHeight(fontSize); + float scale = (float) realSize / (float) this.unitsPerEm; + + Weight weight = new Weight(new Vector2i(widthOut, realSize)); + + int offsetWriting = 0; + int lastValue = 0; + for (char uVal : data.toCharArray()) { + Glyph glyph = getGlyph(uVal); + if (glyph == null) { + lastValue = uVal; + continue; + } + if (withKerning) { + offsetWriting -= glyph.getKerning(lastValue) * scale; + lastValue = uVal; + } + + float advenceXLocal = glyph.getHorizAdvX() * scale; + // No generation of output ... + offsetWriting += advenceXLocal; + } + return new Vector2i(offsetWriting, realSize); + } + public int calculateWidth(final int uVal, final int fontSize) { Glyph glyph = getGlyph(uVal); if (glyph == null) { diff --git a/src/org/atriasoft/esvg/GraphicContext.java b/src/org/atriasoft/esvg/GraphicContext.java index 8f01c01..03660d2 100644 --- a/src/org/atriasoft/esvg/GraphicContext.java +++ b/src/org/atriasoft/esvg/GraphicContext.java @@ -1,9 +1,11 @@ package org.atriasoft.esvg; -import org.atriasoft.egami.ImageByteRGBA; +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; @@ -13,7 +15,7 @@ import org.atriasoft.etk.math.Vector2i; * */ public class GraphicContext { - private EsvgDocument document; + private EsvgDocument document = new EsvgDocument(); PaintState paintState; private PathModel path = null; private Vector2i size = Vector2i.VALUE_32; @@ -22,6 +24,10 @@ public class 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())); } @@ -85,6 +91,14 @@ public class GraphicContext { return this.paintState.getStrokeWidth(); } + public int getTextHeight() { + return getTextHeight(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())); } @@ -181,12 +195,8 @@ public class GraphicContext { this.document.addElement(new Rectangle(position, width, this.paintState.clone())); } - public ImageByteRGBA render() { - return null; - } - - public String renderSvg() { - return null; + public ImageByte render() { + return ToolImage.convertImageByte(this.document.renderImageFloatRGBA(null)); } /** @@ -249,7 +259,10 @@ public class GraphicContext { public void text(final Vector2f position, final float height, final String data) { this.document.addElement(new Text(position, height, data, this.paintState.clone())); - + } + + public void text(final Vector2f position, final String data) { + this.document.addElement(new Text(position, Configs.getConfigFonts().getSize(), data, this.paintState.clone())); } } diff --git a/src/org/atriasoft/esvg/Text.java b/src/org/atriasoft/esvg/Text.java index cce8ac9..4010127 100644 --- a/src/org/atriasoft/esvg/Text.java +++ b/src/org/atriasoft/esvg/Text.java @@ -131,13 +131,17 @@ public class Text extends Base { DynamicColor colorStroke = null; if (this.paint.strokeWidth > 0.0f) { colorStroke = DynamicColor.createColor(this.paint.stroke, mtx); - // 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); - 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); + if (colorStroke == null) { + Log.warning("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); + 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); + } } // add on images: myRenderer.print(tmpFill, colorFill, tmpStroke, colorStroke, this.paint.opacity); diff --git a/test/Unnamed document 2.svg b/test/Unnamed document 2.svg new file mode 100644 index 0000000..864f980 --- /dev/null +++ b/test/Unnamed document 2.svg @@ -0,0 +1,127 @@ + + + + + + + + image/svg+xml + + + + + + + Hellosqmlksd + Hello + Hello Bold + Hello Italic + Hello Bold Italic + +