mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-05-27 20:45:10 +00:00
Improve Text on a path layout rules conformance.
Correct glyph point and delta x / y calculation and context handling. Remove incorrect whitespace from getLinePath method call. Correct the y coordinate of the text's origin when rendering glyphs into paths using getTextPath. Remove strange postTranslate transform. https://www.w3.org/TR/SVG11/text.html#TextOnAPath
This commit is contained in:
@@ -25,6 +25,7 @@ public class GlyphContext {
|
||||
|
||||
private ArrayList<ReadableMap> mFontContext;
|
||||
private ArrayList<PointF> mLocationContext;
|
||||
private ArrayList<PointF> mDeltaContext;
|
||||
private ArrayList<ArrayList<Float>> mDeltaXContext;
|
||||
private ArrayList<ArrayList<Float>> mDeltaYContext;
|
||||
private ArrayList<Float> mXContext;
|
||||
@@ -42,6 +43,7 @@ public class GlyphContext {
|
||||
mCurrentLocation = new PointF();
|
||||
mFontContext = new ArrayList<>();
|
||||
mLocationContext = new ArrayList<>();
|
||||
mDeltaContext = new ArrayList<>();
|
||||
mDeltaXContext = new ArrayList<>();
|
||||
mDeltaYContext = new ArrayList<>();
|
||||
mXContext = new ArrayList<>();
|
||||
@@ -59,6 +61,7 @@ public class GlyphContext {
|
||||
}
|
||||
|
||||
mLocationContext.add(location);
|
||||
mDeltaContext.add(new PointF(0, 0));
|
||||
mFontContext.add(font);
|
||||
mDeltaXContext.add(getFloatArrayListFromReadableArray(deltaX));
|
||||
mDeltaYContext.add(getFloatArrayListFromReadableArray(deltaY));
|
||||
@@ -72,6 +75,7 @@ public class GlyphContext {
|
||||
float x = mXContext.get(mContextLength - 1);
|
||||
mFontContext.remove(mContextLength - 1);
|
||||
mLocationContext.remove(mContextLength - 1);
|
||||
mDeltaContext.remove(mContextLength - 1);
|
||||
mDeltaXContext.remove(mContextLength - 1);
|
||||
mDeltaYContext.remove(mContextLength - 1);
|
||||
mXContext.remove(mContextLength - 1);
|
||||
@@ -87,23 +91,28 @@ public class GlyphContext {
|
||||
}
|
||||
|
||||
public PointF getNextGlyphPoint(float offset, float glyphWidth) {
|
||||
float dx = getNextDelta(mDeltaXContext);
|
||||
mCurrentLocation.x += dx;
|
||||
|
||||
float dy = getNextDelta(mDeltaYContext);
|
||||
mCurrentLocation.y += dy;
|
||||
|
||||
for (PointF point: mLocationContext) {
|
||||
point.x += dx;
|
||||
point.y += dy;
|
||||
}
|
||||
|
||||
mXContext.set(mXContext.size() - 1, mCurrentLocation.x + offset + glyphWidth);
|
||||
|
||||
return new PointF(mCurrentLocation.x + offset, mCurrentLocation.y);
|
||||
|
||||
}
|
||||
|
||||
public PointF getNextGlyphDelta() {
|
||||
float dx = getNextDelta(mDeltaXContext);
|
||||
float dy = getNextDelta(mDeltaYContext);
|
||||
|
||||
if (mContextLength > 0) {
|
||||
for (PointF point: mDeltaContext) {
|
||||
point.x += dx;
|
||||
point.y += dy;
|
||||
}
|
||||
|
||||
return mDeltaContext.get(mContextLength - 1);
|
||||
}
|
||||
|
||||
return new PointF(dx, dy);
|
||||
}
|
||||
|
||||
private float getNextDelta(ArrayList<ArrayList<Float>> deltaContext) {
|
||||
float value = 0;
|
||||
boolean valueSet = false;
|
||||
|
||||
@@ -78,7 +78,7 @@ public class TSpanShadowNode extends TextShadowNode {
|
||||
|
||||
pushGlyphContext();
|
||||
applyTextPropertiesToPaint(paint);
|
||||
getLinePath(mContent + " ", paint, path);
|
||||
getLinePath(mContent + "", paint, path);
|
||||
|
||||
mCache = path;
|
||||
popGlyphContext();
|
||||
@@ -99,13 +99,14 @@ public class TSpanShadowNode extends TextShadowNode {
|
||||
Path glyph = new Path();
|
||||
float width = widths[index];
|
||||
|
||||
paint.getTextPath(letter, 0, 1, 0, -paint.ascent(), glyph);
|
||||
paint.getTextPath(letter, 0, 1, 0, 0, glyph);
|
||||
PointF glyphDelta = getGlyphDeltaFromContext();
|
||||
PointF glyphPoint = getGlyphPointFromContext(glyphPosition, width);
|
||||
glyphPosition += width;
|
||||
Matrix matrix = new Matrix();
|
||||
|
||||
if (mBezierTransformer != null) {
|
||||
matrix = mBezierTransformer.getTransformAtDistance(glyphPoint.x);
|
||||
matrix = mBezierTransformer.getTransformAtDistance(glyphPoint.x + glyphDelta.x);
|
||||
|
||||
if (textPathHasReachedEnd()) {
|
||||
break;
|
||||
@@ -113,22 +114,16 @@ public class TSpanShadowNode extends TextShadowNode {
|
||||
continue;
|
||||
}
|
||||
|
||||
matrix.preTranslate(0, glyphDelta.y);
|
||||
matrix.postTranslate(0, glyphPoint.y);
|
||||
} else {
|
||||
matrix.setTranslate(glyphPoint.x, glyphPoint.y);
|
||||
matrix.setTranslate(glyphPoint.x + glyphDelta.x, glyphPoint.y + glyphDelta.y);
|
||||
}
|
||||
|
||||
|
||||
glyph.transform(matrix);
|
||||
path.addPath(glyph);
|
||||
}
|
||||
|
||||
if (mBezierTransformer != null) {
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postTranslate(0, paint.ascent() * 1.1f);
|
||||
path.transform(matrix);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
@@ -200,6 +200,10 @@ public class TextShadowNode extends GroupShadowNode {
|
||||
return getTextRoot().getGlyphContext().getNextGlyphPoint(offset, glyphWidth);
|
||||
}
|
||||
|
||||
protected PointF getGlyphDeltaFromContext() {
|
||||
return getTextRoot().getGlyphContext().getNextGlyphDelta();
|
||||
}
|
||||
|
||||
private Matrix getAlignMatrix(Path path) {
|
||||
RectF box = new RectF();
|
||||
path.computeBounds(box, true);
|
||||
|
||||
Reference in New Issue
Block a user