From d08103168a4ee78c163f2614e5f3e8e7cede6b9d Mon Sep 17 00:00:00 2001 From: Mikael Sand Date: Wed, 26 Jul 2017 03:51:57 +0300 Subject: [PATCH] Suggest adding a compatibility mid-line rendering attribute to textPath. --- .../main/java/com/horcrux/svg/TSpanShadowNode.java | 10 +++++++++- .../main/java/com/horcrux/svg/TextPathMidLine.java | 12 ++++++++++++ .../java/com/horcrux/svg/TextPathShadowNode.java | 11 +++++++++++ lib/attributes.js | 1 + lib/props.js | 13 +++++++++++++ 5 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 android/src/main/java/com/horcrux/svg/TextPathMidLine.java diff --git a/android/src/main/java/com/horcrux/svg/TSpanShadowNode.java b/android/src/main/java/com/horcrux/svg/TSpanShadowNode.java index 77ef4cba..01e67ff8 100644 --- a/android/src/main/java/com/horcrux/svg/TSpanShadowNode.java +++ b/android/src/main/java/com/horcrux/svg/TSpanShadowNode.java @@ -29,6 +29,7 @@ import static android.graphics.Matrix.MTRANS_X; import static android.graphics.Matrix.MTRANS_Y; import static android.graphics.PathMeasure.POSITION_MATRIX_FLAG; import static android.graphics.PathMeasure.TANGENT_MATRIX_FLAG; +import static com.horcrux.svg.TextPathMidLine.sharp; /** * Shadow node for virtual TSpan view @@ -128,7 +129,9 @@ class TSpanShadowNode extends TextShadowNode { double distance = 0; PathMeasure pm = null; + boolean sharpMidline = false; if (textPath != null) { + sharpMidline = textPath.getMidLine() == sharp; pm = new PathMeasure(textPath.getPath(), false); distance = pm.getLength(); if (distance == 0) { @@ -368,9 +371,14 @@ class TSpanShadowNode extends TextShadowNode { Position the glyph such that the glyph-midline passes through the midpoint-on-the-path and is perpendicular to the line through the startpoint-on-the-path and the endpoint-on-the-path. + + TODO suggest adding a compatibility mid-line rendering attribute to textPath, + for a chrome/firefox/opera/safari compatible sharp text path rendering, + which doesn't bend text smoothly along a right angle curve, (like Edge does) + but keeps the mid-line orthogonal to the mid-point tangent at all times instead. */ assert pm != null; - if (startpoint < 0 || endpoint > distance) { + if (startpoint < 0 || endpoint > distance || sharpMidline) { /* In the calculation above, if either the startpoint-on-the-path or the endpoint-on-the-path is off the end of the path, diff --git a/android/src/main/java/com/horcrux/svg/TextPathMidLine.java b/android/src/main/java/com/horcrux/svg/TextPathMidLine.java new file mode 100644 index 00000000..764a6478 --- /dev/null +++ b/android/src/main/java/com/horcrux/svg/TextPathMidLine.java @@ -0,0 +1,12 @@ +package com.horcrux.svg; + +/* + TODO suggest adding a compatibility mid-line rendering attribute to textPath, + for a chrome/firefox/opera/safari compatible sharp text path rendering, + which doesn't bend text smoothly along a right angle curve, (like Edge does) + but keeps the mid-line orthogonal to the mid-point tangent at all times instead. +*/ +enum TextPathMidLine { + sharp, + smooth +} diff --git a/android/src/main/java/com/horcrux/svg/TextPathShadowNode.java b/android/src/main/java/com/horcrux/svg/TextPathShadowNode.java index 6223e1f7..6c976b7a 100644 --- a/android/src/main/java/com/horcrux/svg/TextPathShadowNode.java +++ b/android/src/main/java/com/horcrux/svg/TextPathShadowNode.java @@ -23,6 +23,7 @@ import javax.annotation.Nullable; class TextPathShadowNode extends TextShadowNode { private String mHref; + private TextPathMidLine mMidLine; private @Nullable String mStartOffset; private TextPathMethod mMethod = TextPathMethod.align; private TextPathSpacing mSpacing = TextPathSpacing.exact; @@ -58,6 +59,12 @@ class TextPathShadowNode extends TextShadowNode { markUpdated(); } + @ReactProp(name = "midLine") + public void setSharp(@Nullable String midLine) { + mMidLine = TextPathMidLine.valueOf(midLine); + markUpdated(); + } + TextPathMethod getMethod() { return mMethod; } @@ -70,6 +77,10 @@ class TextPathShadowNode extends TextShadowNode { return mSide; } + public TextPathMidLine getMidLine() { + return mMidLine; + } + String getStartOffset() { return mStartOffset; } diff --git a/lib/attributes.js b/lib/attributes.js index 8854e66b..9865a069 100644 --- a/lib/attributes.js +++ b/lib/attributes.js @@ -134,6 +134,7 @@ const TextPathAttributes = { method: true, spacing: true, side: true, + midLine: true, }; const TSpanAttibutes = { diff --git a/lib/props.js b/lib/props.js index 0c14884f..51fda003 100644 --- a/lib/props.js +++ b/lib/props.js @@ -263,6 +263,18 @@ const method = PropTypes.oneOf(['align', 'stretch']); */ const spacing = PropTypes.oneOf(['auto', 'exact']); +/* + Name + mid-line + Value + sharp | smooth + initial value + smooth + Animatable + yes + */ +const midLine = PropTypes.oneOf(['sharp', 'smooth']); + // https://svgwg.org/svg2-draft/text.html#TextPathAttributes // https://developer.mozilla.org/en/docs/Web/SVG/Element/textPath const textPathProps = { @@ -272,6 +284,7 @@ const textPathProps = { method, spacing, side, + midLine, }; export {