SVG和带有斜线的稀有特殊字符(斜线穿过?)

时间:2018-08-30 19:29:08

标签: css svg fonts special-characters

我有一个用户的SVG,该用户使用其他软件进行设计,我已经将其翻译为通常可以正常工作的SVG。但是,他们以某种方式使用了奇怪的特殊字符,可能是从特殊键盘输入的,这些字符具有我所说的“斜线删除线”,类似于在每个字符顶部居中的正斜杠。我使用的是Windows 10的最新版本。

更新: 由于以下回答:这些斜线被称为“倾斜的固相线”,它们以字母的形式移出其正常位置以创建“组合字形”,它们就像一个特殊字符,但实际上是两个字形的组合。

这是示例文本:

n̸e̸w̸h̸o̸r̸i̸z̸o̸n̸

根据您的字体,您可能会或可能不会以现在的方式看到它,所以这里是原始代码,可能更标准:

n̸e̸w̸ h̸o̸r̸i̸z̸o̸n̸

但是,当它以Arial字体在SVG中呈现时,斜杠不在字符顶部,而是紧随其后,其空间比字母间距小得多。您可以突出显示字形,并看到它们是一个特殊字符,而不是带有负字母间距的正斜杠。

是否可以使用SVG纠正此偏移,以使斜线与用户看到的字母对齐?

这是一个带有相关文本的JSFiddle示例,向下滚动时,使其大而垂直(旋转90度):

https://jsfiddle.net/o5ykche1/1/

这是原始设计(请注意文字)与SVG翻译的比较:

screenshot of user's raster design with slashes thru letter characters compared to 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>    

1 个答案:

答案 0 :(得分:2)

这里有些猜测,我不是字体专家。

首先,您要运行的功能是combining diacritics及其以不同的字体格式实现。我用FontForge查看了不同的字体,例如发现

  • DejaVu Sans(DejaVuSans.ttf)可以在我的机器上正确显示固相线删除线,并且没有关于字形定位的特殊说明。
    对于完全理解Unicode并自动将字符重新定位到前一个字符的开头并且不改变前进距离的渲染器来说,这是合适的。
  • 显示错误的
  • Consolas(CONSOLA.ttf)使用mark设置了OpenType mkmk标签和OpenType Δx_adv=-1126定位指令。
    这适用于理解mark将该字符重新定位到前一个字符的开头,但是将覆盖的宽度作为提前添加的渲染器。在我看来,这似乎有问题,但是由于Consolas是Microsoft专有的字体,并且OpenType是由Microsoft发明的,因此这种行为也许有一定意义。
  • 正确渲染的Linux Libertine O(LinLibertine_R.otf)设置了OpenType mark标签,但没有定位指令。
    对于知道mark将该字符重新定位到前一个字符的开头并且不改变前进位置的渲染器来说,这是适当的。

我的结论是,您需要一个字体渲染引擎来正确理解各种指令,或者需要一种字体来定义您的渲染引擎所理解的变音符号。如果最终产品供浏览器使用,则您无法控制渲染引擎。您所做的每个更正可能对一个人是正确的,但对另一个却是错误的。

SVG级别的解决方案不起作用。尽管有dx属性可将单个字符放置在字符串中,但它可用于组合字形i。 e。字母和固线移动在一起,而不是相互移动(或更准确地说,根据我的实验,有关组合字符的移动说明无效)。

我能看到的唯一可靠的解决方案是构造一种特殊的字体,该字体包含带有线性删除线的拉丁字符的预组合字符,并以网络字体的形式提供。如果要信任this list,则Unicode不包含这些代码点。

编辑:一种可维护的解决方案可能是使用常规固相线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>