SVG 和带有斜线的稀有特殊字符(有角度的删除线?)
SVG and Rare Special Characters with Slashes Through Them (Angled Strike Through?)
我有一个用户的 SVG,他在另一个软件中进行设计,我已经将它翻译成 SVG,通常可以正常工作。然而,他们以某种方式使用了奇怪的特殊字符,可能来自特殊的键盘,我称之为 "angled-strikethrough" 类似于位于每个字符顶部中心的正斜杠。我在 Windows 10 Google Chrome.
的当前版本
更新: 感谢以下答案:这些斜杠称为 "angled solidus" 并且它们作为字母移出它们的正常位置以创建一个"combined glyph" 它们的作用类似于特殊字符,但实际上是两个字形的组合。
示例文本如下:
n̸e̸w̸h̸o̸r̸i̸z̸o̸n̸
根据您的字体,您可能会或可能不会看到与我现在相同的方式,所以这里是原始代码,它可能更标准:
n̸e̸w̸ h̸o̸r̸i̸z̸o̸n̸
但是,当它在带有 Arial 字体的 SVG 中呈现时,斜线不在字符的顶部,而是紧随其后,space 比字母间距小得多。您可以突出显示字形并看到它们是一个特殊字符,而不是具有负字母间距的正斜杠。
有没有一种方法可以使用 SVG 更正此偏移量,以按照用户看到的方式对齐字母上的斜线?
这是一个带有相关文本的 JSFiddle 示例,向下滚动它是大的和垂直的(旋转 90):
https://jsfiddle.net/o5ykche1/1/
这里是他们的原始设计(注意文字)与 SVG 翻译的比较:
SVG 代码示例:
<svg xmlns="http://www.w3.org/2000/svg" id="mystyle-svg-2" class="mystyle-svg " width="1650" height="6750" viewBox="0 0 1650 6750"><desc>SVG Generated by MyStyle Renderer v3.10.3</desc><defs/><g id="image-bg-group"><rect x="0" y="0" width="1650" height="6750" fill="#CCC" id="image-background-fill-color" style="fill-opacity: 2.55;"/></g><g id="design-group" transform="matrix(13.5246,0,0,13.5246,0,0)"><g type="canvas" canvas_id="1" id="mystyle-export-2-canvas-0" class="mystyle-design-canvas"><rect x="0" y="0" width="122" height="500" fill="none" id="canvas-background-color" canvas-id="1" stroke="none" style="fill-opacity: 1; stroke-width: 0; stroke-opacity: 1;"/><g id="mystyle-svg-2-obj-1" mystyle-do-type="TEXT" transform="matrix(0.001,0.8,-0.8,0.001,24.9375,263.48)" style="opacity: 1;" class="mystyle-design-object"><g transform="translate(0,-22.4140625)" class="inner-text-container"><text x="0" y="0" fill="#000000" data-font-fam="arial" id="1" style="font-size: 40px; font-family: arial; dominant-baseline: text-before-edge;" xml:space="preserve"><tspan text-anchor="middle" style="font-family: arial; text-anchor: middle;" alignment-baseline="auto">n̸e̸w̸ h̸o̸r̸i̸z̸o̸n̸</tspan></text></g></g></g></g></svg>
这里有一点猜测,我不是字体专家。
首先,您 运行 感兴趣的功能是 combining diacritics 及其在不同字体格式中的实现。我用 FontForge 查看了不同的字体,例如
- DejaVu Sans (
DejaVuSans.ttf
) 在我的机器上正确呈现斜线删除线,没有关于字形定位的特殊说明。
这对于完全理解 Unicode 并自动将字符重新定位到前一个字符的开头并且不改变前进的渲染器是合适的。
- Consolas(
CONSOLA.ttf
),显示错误,用Δx_adv=-1126
.
设置OpenTypemark
标签和OpenTypemkmk
定位指令
这对于理解 mark
将字符重新定位到前一个字符的开头,但将叠加层的宽度提前添加的渲染器来说是合适的。对我来说,这看起来有问题,但由于 Consolas 是 Microsoft 的专有字体,而 OpenType 也是由它发明的,所以这种行为也许有一些意义。
- Linux Libertine O (
LinLibertine_R.otf
),渲染正确,设置了OpenType mark
标签,但没有定位指令。
这对于理解 mark
将字符重新定位到前一个字符的开头并且不改变前进的渲染器来说是合适的。
我的结论是,您要么需要一个能够正确理解各种指令的字体渲染引擎,要么需要一个能够以您的渲染引擎理解的方式定义变音符号的字体。如果您的最终产品供浏览器使用,则您无法控制渲染引擎。您所做的每项更正可能对一个人是正确的,但对另一个人是错误的。
SVG 级别的解决方案不起作用。虽然有 dx
属性来定位字符串中的单个字符,但它适用于 combined 字形,i。 e.字母和斜线一起移动,彼此没有关系(或者更准确地说,根据我的实验,组合字符的移动指令无效)。
我能看到的唯一可靠的解决方案是构建一种专用字体,其中包含带有斜线删除线的拉丁字符的预组合字符,作为 Web 字体提供。 Unicode,如果 this list 是可信的,不包含那些代码点。
编辑: 一个中途可维护的解决方案可能是使用 regular solidus 0x2F
并重新定位它。您必须计算出所有字母字符的宽度,但它应该可以工作。下面的示例仅使用斜线本身的大小。像这样:Arial 的标称高度是 1638,斜线的宽度是 569,所以对于 20px,宽度是 569 × 20 ÷ 1638 = 6.95。那么斜线的右侧总是与其覆盖的字符的右侧重合。添加 1px 作为字母间距。
text {
font-family: Arial, sans-serif;
}
<svg>
<text x="20" y="50" font-size="20"
dx="0 -6.95 1 -6.95 1 -6.95 1 0
-6.95 1 -6.95 1 -6.95 1 -6.95 1 -6.95 1 -6.95 1 -6.95">n/e/w/ h/o/r/i/z/o/n/</text>
<svg>
我有一个用户的 SVG,他在另一个软件中进行设计,我已经将它翻译成 SVG,通常可以正常工作。然而,他们以某种方式使用了奇怪的特殊字符,可能来自特殊的键盘,我称之为 "angled-strikethrough" 类似于位于每个字符顶部中心的正斜杠。我在 Windows 10 Google Chrome.
的当前版本更新: 感谢以下答案:这些斜杠称为 "angled solidus" 并且它们作为字母移出它们的正常位置以创建一个"combined glyph" 它们的作用类似于特殊字符,但实际上是两个字形的组合。
示例文本如下:
n̸e̸w̸h̸o̸r̸i̸z̸o̸n̸
根据您的字体,您可能会或可能不会看到与我现在相同的方式,所以这里是原始代码,它可能更标准:
n̸e̸w̸ h̸o̸r̸i̸z̸o̸n̸
但是,当它在带有 Arial 字体的 SVG 中呈现时,斜线不在字符的顶部,而是紧随其后,space 比字母间距小得多。您可以突出显示字形并看到它们是一个特殊字符,而不是具有负字母间距的正斜杠。
有没有一种方法可以使用 SVG 更正此偏移量,以按照用户看到的方式对齐字母上的斜线?
这是一个带有相关文本的 JSFiddle 示例,向下滚动它是大的和垂直的(旋转 90):
https://jsfiddle.net/o5ykche1/1/
这里是他们的原始设计(注意文字)与 SVG 翻译的比较:
SVG 代码示例:
<svg xmlns="http://www.w3.org/2000/svg" id="mystyle-svg-2" class="mystyle-svg " width="1650" height="6750" viewBox="0 0 1650 6750"><desc>SVG Generated by MyStyle Renderer v3.10.3</desc><defs/><g id="image-bg-group"><rect x="0" y="0" width="1650" height="6750" fill="#CCC" id="image-background-fill-color" style="fill-opacity: 2.55;"/></g><g id="design-group" transform="matrix(13.5246,0,0,13.5246,0,0)"><g type="canvas" canvas_id="1" id="mystyle-export-2-canvas-0" class="mystyle-design-canvas"><rect x="0" y="0" width="122" height="500" fill="none" id="canvas-background-color" canvas-id="1" stroke="none" style="fill-opacity: 1; stroke-width: 0; stroke-opacity: 1;"/><g id="mystyle-svg-2-obj-1" mystyle-do-type="TEXT" transform="matrix(0.001,0.8,-0.8,0.001,24.9375,263.48)" style="opacity: 1;" class="mystyle-design-object"><g transform="translate(0,-22.4140625)" class="inner-text-container"><text x="0" y="0" fill="#000000" data-font-fam="arial" id="1" style="font-size: 40px; font-family: arial; dominant-baseline: text-before-edge;" xml:space="preserve"><tspan text-anchor="middle" style="font-family: arial; text-anchor: middle;" alignment-baseline="auto">n̸e̸w̸ h̸o̸r̸i̸z̸o̸n̸</tspan></text></g></g></g></g></svg>
这里有一点猜测,我不是字体专家。
首先,您 运行 感兴趣的功能是 combining diacritics 及其在不同字体格式中的实现。我用 FontForge 查看了不同的字体,例如
- DejaVu Sans (
DejaVuSans.ttf
) 在我的机器上正确呈现斜线删除线,没有关于字形定位的特殊说明。
这对于完全理解 Unicode 并自动将字符重新定位到前一个字符的开头并且不改变前进的渲染器是合适的。 - Consolas(
CONSOLA.ttf
),显示错误,用Δx_adv=-1126
.
设置OpenTypemark
标签和OpenTypemkmk
定位指令 这对于理解mark
将字符重新定位到前一个字符的开头,但将叠加层的宽度提前添加的渲染器来说是合适的。对我来说,这看起来有问题,但由于 Consolas 是 Microsoft 的专有字体,而 OpenType 也是由它发明的,所以这种行为也许有一些意义。 - Linux Libertine O (
LinLibertine_R.otf
),渲染正确,设置了OpenTypemark
标签,但没有定位指令。
这对于理解mark
将字符重新定位到前一个字符的开头并且不改变前进的渲染器来说是合适的。
我的结论是,您要么需要一个能够正确理解各种指令的字体渲染引擎,要么需要一个能够以您的渲染引擎理解的方式定义变音符号的字体。如果您的最终产品供浏览器使用,则您无法控制渲染引擎。您所做的每项更正可能对一个人是正确的,但对另一个人是错误的。
SVG 级别的解决方案不起作用。虽然有 dx
属性来定位字符串中的单个字符,但它适用于 combined 字形,i。 e.字母和斜线一起移动,彼此没有关系(或者更准确地说,根据我的实验,组合字符的移动指令无效)。
我能看到的唯一可靠的解决方案是构建一种专用字体,其中包含带有斜线删除线的拉丁字符的预组合字符,作为 Web 字体提供。 Unicode,如果 this list 是可信的,不包含那些代码点。
编辑: 一个中途可维护的解决方案可能是使用 regular solidus 0x2F
并重新定位它。您必须计算出所有字母字符的宽度,但它应该可以工作。下面的示例仅使用斜线本身的大小。像这样:Arial 的标称高度是 1638,斜线的宽度是 569,所以对于 20px,宽度是 569 × 20 ÷ 1638 = 6.95。那么斜线的右侧总是与其覆盖的字符的右侧重合。添加 1px 作为字母间距。
text {
font-family: Arial, sans-serif;
}
<svg>
<text x="20" y="50" font-size="20"
dx="0 -6.95 1 -6.95 1 -6.95 1 0
-6.95 1 -6.95 1 -6.95 1 -6.95 1 -6.95 1 -6.95 1 -6.95">n/e/w/ h/o/r/i/z/o/n/</text>
<svg>