Как обеспечить согласованность ширины шрифта в SVG в разных операционных системах и браузерах?

Я пытаюсь добавить текст в файл SVG. Текст является динамическим и отображается на прямоугольнике, который выступает в качестве фона.

Поскольку текст является динамическим, ширина прямоугольника фона также должна быть динамической. Итак, чтобы быть последовательным, я использую моноширинный шрифт фиксированной ширины (Droid Sans Mono) и вычисляю ширину прямоугольника фона с помощью выражения - (x*6.4)+4), где xколичество символов в тексте, а 4 добавляется для прокладка (2 слева, 2 справа). Кроме того, если предположить, что 6.4это средняя ширина каждого символа в Droid Sans Monoшрифте (просто предположение).

Итак, для текста Ruby on Railsколичество символов равно 13, поэтому ширина прямоугольника фона равна 13*6.4+4 = 87.2.

Что отлично работает в браузерах (Firefox и Chromium) на Ubuntu . Однако при просмотре в тех же браузерах (Firefox и Chrome) в Windows текст выходит за пределы прямоугольника.

Итак, мой вопрос заключается в том, как я могу гарантировать, что изображение будет иметь согласованный вид в разных операционных системах? Изображение имеет одинаковый вид во всех браузерах в одной и той же операционной системе.

Я включаю пример изображения для справки:

SVG-изображение в качестве эталона

ОБНОВИТЬ

Может быть, мне следует перефразировать свой вопрос: как внутри SVG-файла сделать так, чтобы шрифт фиксированной ширины занимал одинаковое количество пикселей на всех платформах, предполагая, что на SVG-файл не влияют никакие внешние стили CSS, а уровень масштабирования нормальный?

Кроме того, я понимаю, что существуют альтернативные технологии (PNG и т. д.), но не каждый вопрос SVG должен заканчиваться заменой его на PNG . Также больше, чем решение, мне интересно понять, почему эта проблема существует с SVG. Я использую шрифт фиксированной ширины, который должен занимать одинаковое количество пикселей во всех операционных системах (это неправильное предположение? Почему? Что я могу с этим поделать?).

Скриншоты

Ubuntu 12.04 amd64/Файрфокс 13

Скриншот из Firefox/Ubuntu

Ubuntu 12.04 amd64 / Хром 18

Скриншот из Chromium/Ubuntu

Windows 7 32-бит (внутри VirtualBox) / Google Chrome 18

Скриншот из Google Chrome/Windows

Windows 7 32-бит (внутри VirtualBox) / Firefox 13

Скриншот из Firefox/Windows

Прежде всего, я бы, скорее всего, сделал что-то вроде этого jsfiddle.net/lollero/6tuSH. Во-вторых, это больше похоже на вопрос о переполнении стека. В-третьих, если вы используете изображение, вы можете либо использовать несколько изображений, чтобы повторить части, которые должны быть гибкими, либо сделать его достаточно широким, чтобы оставить место для роста и надежды на лучшее.. (хотя я бы использовал .png )
@Lollero: проблема в том, что он вычисляет размер, а это не работает. Это произойдет независимо от метода, использованного для создания гибкой части изображения.
@horatio Я не говорил, что гибкость исправит любые различия в размере шрифта (масштабирование также может создать некоторые проблемы с этой настройкой svg в некоторых браузерах), но это может решить проблему, которая возникает из-за этого, а именно текст выбивается из цветные области. Тем более в моем примере с jsfiddle, поскольку он гибкий как по горизонтали, так и по вертикали.
..и мне также нравится иметь гибкость там, где это важно. Я действительно не знаю, как это использовать, но что, если вдруг будет 200 голосов? Текст не поместился бы в зеленой области, но если бы он был гибким, он бы помещался как перчатка, независимо от того, сколько у вас голосов. Это, вероятно, будет наиболее практичным примером того, почему эта текущая попытка, возможно, потерпит неудачу (конечно, в зависимости от варианта использования).
Когда я вернулся домой, я заметил, что мой пример не работает в firefox и... это выбило меня из колеи, хотя это всего лишь пример. Вот jsfiddle.net/lollero/6tuSH/3 (заметил, что в этой скрипке я делал некоторые вещи довольно странно, но... сейчас я просто уйду... :D)
Он подсчитывает количество мест, так что «200 голосов», по-видимому, подходят, основываясь на предложенной им формуле. (вычеркивание Note also that your jsfiddle example wraps to two lines on my browser (breaks between -- 1` и vote).`--) Реальное решение состоит в том, чтобы не полагаться на клиентскую сторону, если это возможно, IMO, но это не заданный вопрос.
@ Горацио да, это не сработало должным образом, но значит ли это, что не могло? Нет. Что касается его вопроса, я считаю, что бесполезно отвечать на точный вопрос, потому что решить проблему, которая у него возникла, гораздо проще другими способами.
то же самое можно сказать и о решении OP.
@Горацио Итак, вы говорите, что, поскольку мое доказательство концепции не сработало идеально, точное решение, которое запрашивает OP, было бы лучше? Я не работаю на него, ты же знаешь. Я все еще очень убежден, что было бы намного проще использовать метод, подобный тому, что используется в моем jsfiddle, или аналогичный этому.
Я предполагаю, что «шрифт фиксированной ширины» доступен не во всех системах, поэтому он заменяется другим шрифтом фиксированной ширины.
@Scott, шрифт фиксированной ширины «Droid Sans Mono» встроен прямо в изображение SVG с использованием @font-face.

Ответы (1)

Поскольку вы только связали SVG и не предоставили снимок экрана, чтобы показать, в чем ваша проблема, я могу исходить только из того, что вижу. Изображение, показанное в вопросе, отображается неправильно, потому что это неправильный шрифт, поэтому ваш рендеринг отключен, потому что ваш расчет основан на другом размере букв и интервалах (я вижу Courier). Если я просматриваю SVG на новой вкладке (или перехожу по ссылке для прямой ссылки), он правильно отображается с Droid Sans Mono и правильным размером прямоугольника.

Таким образом, ваша проблема связана с CSS, когда шрифт очищается родительским контейнером или неправильным методом вызова. В этом отношении я соглашусь с Лоллеро, что это не по теме GD.

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

РЕДАКТИРОВАТЬ:___________

Снимок экрана вашего файла svg в 64-битном браузере win7 firefox:

Скриншот

Простое текстовое содержимое вашего файла SVG (XML)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg version="1.1" baseProfile="basic" xmlns="http://www.w3.org/2000/svg" height="14">
  <defs>
    <style type="text/css">
      <![CDATA[
        @import url(https://fonts.googleapis.com/css?family=Droid+Sans+Mono);
      ]]>
    </style>
    <linearGradient id="g1">
      <stop stop-color="#222" offset="0%"/>
      <stop stop-color="#444" offset="100%"/>
    </linearGradient>
    <linearGradient id="g2">
      <stop stop-color="#2a2" offset="0%"/>
      <stop stop-color="#0a0" offset="100%"/>
    </linearGradient>
  </defs>

    <!-- Extra rectangles on left & right for the rounded corners -->
    <rect x="0" y="0" width="16" height="14" fill="#222" rx="4" ry="4"/>
    <rect x="129.6" y="0" width="8" height="14" fill="#0a0" rx="4" ry="4"/>

  <rect x="4" y="0" width="87.2" height="14" fill="url(#g1)" />
  <rect x="91.2" y="0" width="42.4" height="14" fill="url(#g2)" />

  <text x="6.0" y="10" font-size="10.5" font-family="'Droid Sans Mono', monospace" text-anchor="start" fill="#fff">Ruby on Rails</text>
  <text x="93.2" y="10" font-size="10.5" font-family="'Droid Sans Mono', monospace" text-anchor="start" fill="#fff">1 vote</text>
</svg>
Привет @horatio, я обновил свой вопрос в качестве отзыва на ваш ответ. Кроме того, я хотел бы уточнить, что я встраиваю изображение в страницу с помощью <img />тега, поэтому внешний CSS не должен влиять (насколько я знаю). Я также включил скриншоты. Спасибо.
Я отредактировал ответ с несколькими вещами. (1) это файл xml, и вы можете увидеть объявление CSS, указывающее на fonts.googleapis.com (строка 6). По какой-то причине это не соблюдается, и в результате в вашем браузере нет файла шрифта. (2) Снимок экрана — это то, как выглядит файл SVG (с правильным шрифтом). Однако «встроенная версия», отображаемая в тексте вашего вопроса выше, выглядит как шрифт курьера и очень похожа на ваши снимки экрана.