Единицы шрифта SVG на em в мм

В приложении, которое я пишу, мне нужно взять путь глифа из шрифта SVG и масштабировать его до определенного размера, который указывается в миллиметрах. Я беру свойство пути 'd' из шрифта SVG, масштабирую его, применяя коэффициент масштабирования к координатам пути, а затем использую его как обычный путь в SVG, который я генерирую. (Для моего приложения я не могу использовать «матрицу», «высоту», «ширину» или любые другие встроенные методы масштабирования; координаты пути должны точно отражать окончательный размер и масштаб). Механика нанесения шкалы на путь не проблема; Мне просто нужно выяснить правильный коэффициент масштабирования для применения.

Шрифт SVG обеспечивает «единицу на единицу измерения», то есть 2048 или 1000. Я знаю, что «эм» — это относительная единица измерения, а «мм» — абсолютная единица, и я совершенно уверен, что преобразование может быть сделано. Было бы полезно, если бы кто-нибудь объяснил детали такого преобразования или указал, что то, что я пытаюсь сделать, не имеет смысла.

Некоторый контекст: файл SVG, который я создаю с помощью своего (Python) программного обеспечения, затем преобразуется в файл координат (Gerber), который используется для физического изготовления объекта. Все элементы в обоих файлах должны представлять точные размеры без какого-либо другого масштабирования или преобразования.

Не могли бы вы дать больше информации о том, что вы подразумеваете под «размеры должны быть указаны в мм»? Или наоборот, как вы собираетесь делать конвертацию файлов? Достаточно ли преобразовать глиф шрифта SVG в стандартную графику SVG с определенной высотой и шириной в мм, или вы хотите, чтобы все координаты кривых Безье были в мм?
Я отредактировал вопрос; Надеюсь, теперь стало понятнее.

Ответы (1)

В типографике единицей «em» является максимальная высота набора символов. Для латинского текста это означает высоту от ударения над заглавными буквами до низа нисходящих строчных букв. Например, это будет общая высота Ég.

Значение «em» — это то, что вы устанавливаете, когда определяете размер шрифта — если вы устанавливаете шрифт равным 24pt, то 1em=24pt=1/3 дюйма. В CSS вы также можете установить размер шрифта, используя метрические единицы, поэтому вы можете специально установить, font-size:20mmи программа просмотра SVG будет масштабировать шрифт до этой высоты при печати (или приблизительно на экране).

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

Как вы уже поняли, ключ находится в units-per-emатрибуте элемента <font-face>или объявлении CSS @font-face. Стандартные значения (1000 и 2048) взяты из других форматов шрифтов; теоретически вы можете использовать любые значения для шрифтов SVG.

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

Если у вас есть 1000 единиц на em, и вы хотите, чтобы окончательная максимальная высота ваших слов составляла 500 мм, то ваш коэффициент масштабирования равен

scalingFactor = (desired em height)/(units per em) 
              = (500mm/em) / (1000 units/em)
              = 0.5mm/unit

Другими словами, чтобы преобразовать необработанные единицы в миллиметры, вы должны умножить каждую координату на 0,5.

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

  • Единица em определяет только высоту символов. Ширина (в большинстве шрифтов) будет варьироваться. В SVG horiz-adv-xатрибут каждого глифа (или, если он не указан для отдельного глифа, самого шрифта) определяет ширину этого символа, включая интервал между символами по умолчанию, в виде количества единиц координат. Если вы хотите масштабировать текст до указанной ширины вместо указанной высоты в мм, это количество единиц, которые вы должны использовать в своих расчетах:

    scalingFactor = (desired width)/(horizontal advance in coordinate units) 
    
  • В качестве альтернативы, если вам важна высота, но только высота заглавной буквы (без выносных элементов, поэтому не полная высота em), вам нужно будет рассчитать количество единиц этой высоты из атрибутов и cap-height, alphabeticalкоторые определить положение верхней и нижней части заглавных букв в системе координат:

    scalingFactor = (desired height of capital letter) /
                   [(cap-height coordinate)-(alphabetic baseline coordinate)] 
    

    (Существуют различные другие высоты, которые вы можете использовать для расчета масштаба аналогичным образом.)

  • В отличие от всего остального в SVG, координаты Y шрифтов увеличиваются при движении вверх, а не вниз. (Это опять же сделано для согласованности с другими форматами шрифтов.) Если ваше программное обеспечение для преобразования ожидает обратное, вам придется перевернуть каждую координату Y, прежде чем масштабировать ее:

    newYValue = [(units-per-em) - (oldY)] * scalingFactor
    
  • Наконец, вам может понадобиться настроить абсолютное значение координат так, чтобы начало координат (0,0) находилось в правильном положении для того, что вы делаете. Вы можете работать с одним из атрибутов, заданных для элемента <font-face>, или с атрибутами horiz//vert-origin-xy элемента <font>. Эти атрибуты определяют положение начала глифа (для латинского текста пересечение базовой линии с левым краем буквы) в системе координат. Если они равны нулю (по умолчанию, если они не указаны), то нисходящие элементы будут даны в отрицательных координатах. Если отрицательные координаты являются проблемой, вам нужно выяснить минимальную координату в каждом направлении и перевести каждую координату на эту величину, чтобы все стало положительным.

Я надеюсь, что этого достаточно, чтобы вы поняли, что означают числа и как вы можете адаптировать их к своим потребностям.

Последний вариант, особенно если это одноразовое преобразование и вам не нужно создавать повторно используемый сценарий, — открыть SVG в визуальном редакторе, таком как Inkscape. Вы можете написать текст, а затем использовать команду «Путь > Объект к пути». Я не могу найти простой способ заставить его масштабировать координаты до мм, но это избавит от большинства головных болей, связанных с размером шрифта! Если у вас уже есть программа преобразования, которая работает с путями SVG, то это будет самый простой подход.

Вау, какой ответ! Да, это значительно приближает меня к тому, чего я хочу достичь. Для дальнейшего контекста, это проект: bitbucket.org/boldport/pcbmode , и это то, что я с ним делаю;) boldport.com
Ха! Печатная плата как искусство -- определенно интересный проект. Я был немного удивлен, когда просмотрел формат Gerber и большинство результатов, связанных с печатными платами, но я просто предположил, что тот же формат файла был принят более общим оборудованием для резки материалов.
Не имеет значения, хотите ли вы тогда преобразовать ширину или высоту глифа в миллиметры или единицы пикселей? Если я хочу иметь высоту, скажем, 500 пикселей, я должен умножить каждую координату на коэффициент 0,5, как для желаемой высоты 500 мм?
@user141169 user141169 Да, вы бы подставили любое значение в часть формулы «желаемая высота em», и вы бы получили результат в тех же единицах.