[DEV] add capability in font render system

This commit is contained in:
Edouard DUPIN 2021-05-29 00:52:11 +02:00
parent d366431a71
commit 9b8e5c4f35
5 changed files with 64 additions and 34 deletions

View File

@ -1,9 +1,9 @@
package org.atriasoft.esvg;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.atriasoft.esvg.font.Glyph;
import org.atriasoft.esvg.font.Kerning;
@ -261,10 +261,10 @@ public class EsvgFont {
int widthOut = calculateWidth(data, fontSize, withKerning);
int realSize = calculateFontRealHeight(fontSize);
return new Vector2i(widthOut, realSize);
/*
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()) {
@ -283,6 +283,7 @@ public class EsvgFont {
offsetWriting += advenceXLocal;
}
return new Vector2i(offsetWriting, realSize);
*/
}
public int calculateWidth(final int uVal, final int fontSize) {
@ -302,7 +303,8 @@ public class EsvgFont {
public int calculateWidth(final String data, final int fontSize, final boolean withKerning) {
int realSize = calculateFontRealHeight(fontSize);
float scale = (float) realSize / (float) this.unitsPerEm;
int out = 0;
//Log.error("scale =" + scale+ " font size = " + fontSize + " realSize=" + realSize);
float offsetWriting = 0;
int lastValue = 0;
for (char uVal : data.toCharArray()) {
Glyph glyph = getGlyph(uVal);
@ -311,12 +313,15 @@ public class EsvgFont {
continue;
}
if (withKerning) {
out -= glyph.getKerning(lastValue) * scale;
offsetWriting -= glyph.getKerning(lastValue) * scale;
lastValue = uVal;
}
out += glyph.getHorizAdvX() * scale;
float advenceXLocal = glyph.getHorizAdvX() * scale;
offsetWriting += advenceXLocal;
//Log.error("offset X =" + offsetWriting + " + " + advenceXLocal + " " + uVal);
}
return out;
return (int)offsetWriting;
}
/**
@ -402,7 +407,7 @@ public class EsvgFont {
Weight weight = new Weight(new Vector2i(widthOut, realSize));
int offsetWriting = 0;
float offsetWriting = 0;
int lastValue = 0;
for (char uVal : data.toCharArray()) {
Glyph glyph = getGlyph(uVal);
@ -423,7 +428,7 @@ public class EsvgFont {
PathModel model = glyph.getModel();
if (model != null) {
Weight redered = model.drawFill(calculateWidthRendering((int) uVal, fontSize), transform, 8, config);
weight.fusion(redered, offsetWriting, 0);
weight.fusion(redered, (int)offsetWriting, 0);
}
offsetWriting += advenceXLocal;

View File

@ -94,6 +94,10 @@ public class GraphicContext {
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);
@ -258,11 +262,11 @@ 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()));
this.document.addElement(new Text(position, Configs.getConfigFonts().getName(), 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()));
text(position, Configs.getConfigFonts().getSize(), data);
}
}

View File

@ -35,12 +35,18 @@ public class Text extends Base {
super(parentPaintState);
this.position = position;
this.fontSize = fontSize;
this.texts.add(new TextSpan(position, decoratedText, FontProperty.DEFAULT_FONT, 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.debug(spacingDist(spacing) + "Text : ");
Log.verbose(spacingDist(spacing) + "Text : ");
for (TextSpan elem : this.texts) {
Log.debug(spacingDist(spacing + 1) + elem.toString());
}
@ -48,7 +54,7 @@ public class Text extends Base {
@Override
public void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) {
Log.warning(spacingDist(level) + "DRAW esvg::Text ==> position = " + this.position);
Log.verbose(spacingDist(level) + "DRAW esvg::Text ==> position = " + this.position);
if (this.texts.size() == 0) {
Log.verbose(spacingDist(level + 1) + "No text ...");
return;
@ -65,19 +71,21 @@ public class Text extends Base {
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);
float offsetWriting = 0;
int lastValue = 0;
for (char uVal : elem.text().toCharArray()) {
Log.warning(spacingDist(level) + " elem.position = " + elem.position());
Log.verbose(spacingDist(level) + " elem.position = " + elem.position());
Glyph glyph = font.getGlyph(uVal);
if (glyph == null) {
lastValue = uVal;
//lastValue = uVal;
continue;
}
if (withKerning) {
//offsetWriting -= glyph.getKerning(lastValue) * scale;
Log.info(" ==> kerning offset = " + (glyph.getKerning(lastValue) * scale));
offsetWriting -= glyph.getKerning(lastValue) * scale;
Log.verbose(" ==> kerning offset = " + (glyph.getKerning(lastValue) * scale));
lastValue = uVal;
}
@ -85,7 +93,7 @@ public class Text extends Base {
//Matrix2x3f mtx = this.transformMatrix;
Vector2f tranlate = new Vector2f(elem.position().x() + offsetWriting, elem.position().y() - font.getDescent() * scale);
Log.warning("translate : " + tranlate);
Log.verbose("translate : " + tranlate);
Matrix2x3f translateGlyph = Matrix2x3f.createTranslate(tranlate);
Matrix2x3f scaleGlyph = Matrix2x3f.createScale(new Vector2f(scale, -scale));
@ -132,7 +140,7 @@ public class Text extends Base {
if (this.paint.strokeWidth > 0.0f) {
colorStroke = DynamicColor.createColor(this.paint.stroke, mtx);
if (colorStroke == null) {
Log.warning("Color stroke is null: ...");
Log.verbose("Color stroke is null: ...");
} else {
// check if we need to display stroke:
SegmentList listSegmentStroke = new SegmentList();
@ -147,7 +155,7 @@ public class Text extends Base {
myRenderer.print(tmpFill, colorFill, tmpStroke, colorStroke, this.paint.opacity);
}
offsetWriting += advenceXLocal;
Log.error("offset X =" + offsetWriting + " + " + advenceXLocal + " " + uVal);
//Log.warning("offset X =" + offsetWriting + " + " + advenceXLocal + " " + uVal);
}
}
}
@ -262,6 +270,19 @@ record FontProperty(
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);
}
}
record TextSpan(

View File

@ -1,12 +1,12 @@
package org.atriasoft.esvg.render;
import org.atriasoft.etk.math.Vector2i;
import org.atriasoft.etk.util.Pair;
import org.atriasoft.etk.math.Matrix2x3f;
import org.atriasoft.etk.math.Vector2f;
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;
/** @file
* @author Edouard DUPIN
@ -21,7 +21,7 @@ public interface DynamicColor {
return null;
}
if (color.second.isEmpty()) {
Log.error("use stroke color :" + color);
Log.verbose("use stroke color :" + color);
return new DynamicColorUni(color.first);
}
return new DynamicColorSpecial(color.second, mtx);

View File

@ -4,9 +4,9 @@ import java.util.ArrayList;
import java.util.List;
import org.atriasoft.esvg.internal.Log;
import org.atriasoft.etk.util.Pair;
import org.atriasoft.etk.math.Matrix2x3f;
import org.atriasoft.etk.math.Vector2f;
import org.atriasoft.etk.util.Pair;
public class PointList {
public List<List<Point>> data = new ArrayList<>();
@ -29,9 +29,9 @@ public class PointList {
}
public void display() {
Log.warning(" Display list of points : size=" + this.data.size());
Log.verbose(" Display list of points : size=" + this.data.size());
for (List<Point> it : this.data) {
Log.warning(" Find List " + it.size() + " members");
Log.verbose(" 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);