[DEV] add capability in font render system
This commit is contained in:
parent
d366431a71
commit
9b8e5c4f35
@ -1,9 +1,9 @@
|
|||||||
package org.atriasoft.esvg;
|
package org.atriasoft.esvg;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
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.Glyph;
|
||||||
import org.atriasoft.esvg.font.Kerning;
|
import org.atriasoft.esvg.font.Kerning;
|
||||||
@ -261,10 +261,10 @@ public class EsvgFont {
|
|||||||
int widthOut = calculateWidth(data, fontSize, withKerning);
|
int widthOut = calculateWidth(data, fontSize, withKerning);
|
||||||
|
|
||||||
int realSize = calculateFontRealHeight(fontSize);
|
int realSize = calculateFontRealHeight(fontSize);
|
||||||
|
return new Vector2i(widthOut, realSize);
|
||||||
|
/*
|
||||||
float scale = (float) realSize / (float) this.unitsPerEm;
|
float scale = (float) realSize / (float) this.unitsPerEm;
|
||||||
|
|
||||||
Weight weight = new Weight(new Vector2i(widthOut, realSize));
|
|
||||||
|
|
||||||
int offsetWriting = 0;
|
int offsetWriting = 0;
|
||||||
int lastValue = 0;
|
int lastValue = 0;
|
||||||
for (char uVal : data.toCharArray()) {
|
for (char uVal : data.toCharArray()) {
|
||||||
@ -283,6 +283,7 @@ public class EsvgFont {
|
|||||||
offsetWriting += advenceXLocal;
|
offsetWriting += advenceXLocal;
|
||||||
}
|
}
|
||||||
return new Vector2i(offsetWriting, realSize);
|
return new Vector2i(offsetWriting, realSize);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public int calculateWidth(final int uVal, final int fontSize) {
|
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) {
|
public int calculateWidth(final String data, final int fontSize, final boolean withKerning) {
|
||||||
int realSize = calculateFontRealHeight(fontSize);
|
int realSize = calculateFontRealHeight(fontSize);
|
||||||
float scale = (float) realSize / (float) this.unitsPerEm;
|
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;
|
int lastValue = 0;
|
||||||
for (char uVal : data.toCharArray()) {
|
for (char uVal : data.toCharArray()) {
|
||||||
Glyph glyph = getGlyph(uVal);
|
Glyph glyph = getGlyph(uVal);
|
||||||
@ -311,12 +313,15 @@ public class EsvgFont {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (withKerning) {
|
if (withKerning) {
|
||||||
out -= glyph.getKerning(lastValue) * scale;
|
offsetWriting -= glyph.getKerning(lastValue) * scale;
|
||||||
lastValue = uVal;
|
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));
|
Weight weight = new Weight(new Vector2i(widthOut, realSize));
|
||||||
|
|
||||||
int offsetWriting = 0;
|
float offsetWriting = 0;
|
||||||
int lastValue = 0;
|
int lastValue = 0;
|
||||||
for (char uVal : data.toCharArray()) {
|
for (char uVal : data.toCharArray()) {
|
||||||
Glyph glyph = getGlyph(uVal);
|
Glyph glyph = getGlyph(uVal);
|
||||||
@ -423,7 +428,7 @@ public class EsvgFont {
|
|||||||
PathModel model = glyph.getModel();
|
PathModel model = glyph.getModel();
|
||||||
if (model != null) {
|
if (model != null) {
|
||||||
Weight redered = model.drawFill(calculateWidthRendering((int) uVal, fontSize), transform, 8, config);
|
Weight redered = model.drawFill(calculateWidthRendering((int) uVal, fontSize), transform, 8, config);
|
||||||
weight.fusion(redered, offsetWriting, 0);
|
weight.fusion(redered, (int)offsetWriting, 0);
|
||||||
}
|
}
|
||||||
offsetWriting += advenceXLocal;
|
offsetWriting += advenceXLocal;
|
||||||
|
|
||||||
|
@ -94,6 +94,10 @@ public class GraphicContext {
|
|||||||
public int getTextHeight() {
|
public int getTextHeight() {
|
||||||
return getTextHeight(Configs.getConfigFonts().getSize());
|
return getTextHeight(Configs.getConfigFonts().getSize());
|
||||||
}
|
}
|
||||||
|
public int getTextSize() {
|
||||||
|
return Configs.getConfigFonts().getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getTextHeight(final float height) {
|
public int getTextHeight(final float height) {
|
||||||
return FontCache.getFont(Configs.getConfigFonts().getName(), false, false).calculateFontRealHeight((int) 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) {
|
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) {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,12 +35,18 @@ public class Text extends Base {
|
|||||||
super(parentPaintState);
|
super(parentPaintState);
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.fontSize = fontSize;
|
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
|
@Override
|
||||||
public void display(final int spacing) {
|
public void display(final int spacing) {
|
||||||
Log.debug(spacingDist(spacing) + "Text : ");
|
Log.verbose(spacingDist(spacing) + "Text : ");
|
||||||
for (TextSpan elem : this.texts) {
|
for (TextSpan elem : this.texts) {
|
||||||
Log.debug(spacingDist(spacing + 1) + elem.toString());
|
Log.debug(spacingDist(spacing + 1) + elem.toString());
|
||||||
}
|
}
|
||||||
@ -48,7 +54,7 @@ public class Text extends Base {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(final Renderer myRenderer, final Matrix2x3f basicTrans, final int level) {
|
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) {
|
if (this.texts.size() == 0) {
|
||||||
Log.verbose(spacingDist(level + 1) + "No text ...");
|
Log.verbose(spacingDist(level + 1) + "No text ...");
|
||||||
return;
|
return;
|
||||||
@ -65,19 +71,21 @@ public class Text extends Base {
|
|||||||
|
|
||||||
int realSize = font.calculateFontRealHeight((int) elem.fontState().fontSize());
|
int realSize = font.calculateFontRealHeight((int) elem.fontState().fontSize());
|
||||||
float scale = realSize / font.getUnitsPerEm();
|
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;
|
float offsetWriting = 0;
|
||||||
int lastValue = 0;
|
int lastValue = 0;
|
||||||
for (char uVal : elem.text().toCharArray()) {
|
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);
|
Glyph glyph = font.getGlyph(uVal);
|
||||||
if (glyph == null) {
|
if (glyph == null) {
|
||||||
lastValue = uVal;
|
//lastValue = uVal;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (withKerning) {
|
if (withKerning) {
|
||||||
//offsetWriting -= glyph.getKerning(lastValue) * scale;
|
offsetWriting -= glyph.getKerning(lastValue) * scale;
|
||||||
Log.info(" ==> kerning offset = " + (glyph.getKerning(lastValue) * scale));
|
Log.verbose(" ==> kerning offset = " + (glyph.getKerning(lastValue) * scale));
|
||||||
lastValue = uVal;
|
lastValue = uVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +93,7 @@ public class Text extends Base {
|
|||||||
|
|
||||||
//Matrix2x3f mtx = this.transformMatrix;
|
//Matrix2x3f mtx = this.transformMatrix;
|
||||||
Vector2f tranlate = new Vector2f(elem.position().x() + offsetWriting, elem.position().y() - font.getDescent() * scale);
|
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 translateGlyph = Matrix2x3f.createTranslate(tranlate);
|
||||||
Matrix2x3f scaleGlyph = Matrix2x3f.createScale(new Vector2f(scale, -scale));
|
Matrix2x3f scaleGlyph = Matrix2x3f.createScale(new Vector2f(scale, -scale));
|
||||||
|
|
||||||
@ -132,7 +140,7 @@ public class Text extends Base {
|
|||||||
if (this.paint.strokeWidth > 0.0f) {
|
if (this.paint.strokeWidth > 0.0f) {
|
||||||
colorStroke = DynamicColor.createColor(this.paint.stroke, mtx);
|
colorStroke = DynamicColor.createColor(this.paint.stroke, mtx);
|
||||||
if (colorStroke == null) {
|
if (colorStroke == null) {
|
||||||
Log.warning("Color stroke is null: ...");
|
Log.verbose("Color stroke is null: ...");
|
||||||
} else {
|
} else {
|
||||||
// check if we need to display stroke:
|
// check if we need to display stroke:
|
||||||
SegmentList listSegmentStroke = new SegmentList();
|
SegmentList listSegmentStroke = new SegmentList();
|
||||||
@ -147,7 +155,7 @@ public class Text extends Base {
|
|||||||
myRenderer.print(tmpFill, colorFill, tmpStroke, colorStroke, this.paint.opacity);
|
myRenderer.print(tmpFill, colorFill, tmpStroke, colorStroke, this.paint.opacity);
|
||||||
}
|
}
|
||||||
offsetWriting += advenceXLocal;
|
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 bold,
|
||||||
boolean italic) {
|
boolean italic) {
|
||||||
public static final FontProperty DEFAULT_FONT = new FontProperty("FreeSans", 15, false, false);
|
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(
|
record TextSpan(
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package org.atriasoft.esvg.render;
|
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.EsvgDocument;
|
||||||
import org.atriasoft.esvg.internal.Log;
|
import org.atriasoft.esvg.internal.Log;
|
||||||
import org.atriasoft.etk.Color;
|
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
|
/** @file
|
||||||
* @author Edouard DUPIN
|
* @author Edouard DUPIN
|
||||||
@ -21,7 +21,7 @@ public interface DynamicColor {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (color.second.isEmpty()) {
|
if (color.second.isEmpty()) {
|
||||||
Log.error("use stroke color :" + color);
|
Log.verbose("use stroke color :" + color);
|
||||||
return new DynamicColorUni(color.first);
|
return new DynamicColorUni(color.first);
|
||||||
}
|
}
|
||||||
return new DynamicColorSpecial(color.second, mtx);
|
return new DynamicColorSpecial(color.second, mtx);
|
||||||
|
@ -4,9 +4,9 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.atriasoft.esvg.internal.Log;
|
import org.atriasoft.esvg.internal.Log;
|
||||||
import org.atriasoft.etk.util.Pair;
|
|
||||||
import org.atriasoft.etk.math.Matrix2x3f;
|
import org.atriasoft.etk.math.Matrix2x3f;
|
||||||
import org.atriasoft.etk.math.Vector2f;
|
import org.atriasoft.etk.math.Vector2f;
|
||||||
|
import org.atriasoft.etk.util.Pair;
|
||||||
|
|
||||||
public class PointList {
|
public class PointList {
|
||||||
public List<List<Point>> data = new ArrayList<>();
|
public List<List<Point>> data = new ArrayList<>();
|
||||||
@ -29,9 +29,9 @@ public class PointList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void display() {
|
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) {
|
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) {
|
for (int iii = 0; iii < it.size(); ++iii) {
|
||||||
Point elem = it.get(iii);
|
Point elem = it.get(iii);
|
||||||
Log.verbose(" [" + iii + "] Find " + elem.type + " " + elem.pos);
|
Log.verbose(" [" + iii + "] Find " + elem.type + " " + elem.pos);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user