SVG и редкие специальные персонажи с прорезями (Anged Strike Through?) - PullRequest
0 голосов
/ 30 августа 2018

У меня есть SVG от пользователя, который сделал свой дизайн в другом программном обеспечении, и я перевел его на SVG, который обычно работает нормально. Однако они как-то использовали странные специальные символы, возможно, со специальной клавиатуры, которые имеют то, что я бы назвал «угловой зачеркиванием», напоминающее косую черту, расположенную по центру над каждым символом. Я нахожусь на Windows 10 в текущей версии Google Chrome.

ОБНОВЛЕНИЕ: Благодаря ответам ниже: Эти косые черты называются «угловым солидусом», и они перемещаются из своего обычного места в виде буквы, чтобы создать «комбинированный глиф», в котором они действуют как специальный символ, но на самом деле это два глифа вместе взятых.

Вот пример текста:

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

В зависимости от вашего шрифта, вы можете видеть, а можете и не видеть его так же, как сейчас, поэтому здесь он выглядит как необработанный код, где он, вероятно, более стандартен:

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

Однако, когда это рендерится в SVG со шрифтом Arial, косые черты располагаются не поверх символов, а сразу после них с гораздо меньшим пространством, чем межбуквенный интервал. Вы можете выделить глифы и увидеть, что это один специальный символ, а не косая черта с отрицательным межбуквенным интервалом.

Есть ли способ исправить это смещение с помощью 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 голосов
/ 31 августа 2018

Здесь есть немного догадок, я не специалист по шрифту.

Во-первых, функция, с которой вы работаете, это , сочетающая диакритические знаки и их реализацию в различных форматах шрифтов. Я просмотрел различные шрифты с помощью FontForge и обнаружил, что, например,

  • DejaVu Sans (DejaVuSans.ttf), который правильно выполняет зачистку солидуса на моей машине, не имеет специальных инструкций по размещению глифа.
    Это было бы целесообразно для средства визуализации, которое полностью понимает Unicode и автоматически перемещает символ в начало предыдущего символа и не изменяет продвижение.
  • Consolas (CONSOLA.ttf), который показывает ошибку, устанавливает тег OpenType mark и инструкцию позиционирования OpenType mkmk с помощью Δx_adv=-1126.
    Это было бы целесообразно для средства визуализации, которое понимает, что mark перемещает символ в начало предыдущего символа, но добавляет ширину наложения по мере продвижения. Для меня это выглядит некорректно, но так как Consolas является проприетарным шрифтом от Microsoft, а OpenType был изобретен тем же, возможно, в этом есть какой-то смысл.
  • Linux Libertine O (LinLibertine_R.otf), который правильно отображает, устанавливает тег OpenType mark, но без инструкции позиционирования.
    Это было бы целесообразно для средства визуализации, которое понимает, что mark перемещает символ в начало предыдущего символа и не изменяет продвижение.

Я пришел к выводу, что вам либо нужен механизм рендеринга шрифтов, который правильно понимает различные инструкции, либо шрифт, который определяет диакритические знаки так, как это понимает ваш механизм рендеринга. Если ваш конечный продукт предназначен для браузера, у вас нет контроля над механизмом рендеринга. Каждое исправление, которое вы делаете, может быть правильным для одного, но неправильным для другого.

Решение на уровне SVG не работает. Хотя для размещения отдельных символов внутри строки имеется атрибут dx, он работает на комбинированном глифе , т.е. е. буква и солидус перемещаются вместе, а не по отношению друг к другу (или, точнее, из моих экспериментов, инструкции по перемещению при объединении символов не действуют).

Единственное надежное решение, которое я вижу, - это создание специализированного шрифта, который содержит предварительно составленные символы для латинских символов с зачеркиванием solidus, поставляемые в виде веб-шрифта. Unicode, если этот список заслуживает доверия, не содержит кодовых точек для них.

Редактировать: На полпути для обслуживания можно использовать обычный solidus 0x2F и изменить его положение. Вам нужно будет определить ширину всех букв алфавита, но тогда это должно сработать. В приведенном ниже примере используется только размер самого солидуса. Например: номинальная высота для Arial - 1638, ширина для солидуса - 569, поэтому для 20 пикселей ширина равна 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>
...