Wie kann ich die Schriftbreite in SVG über verschiedene Betriebssysteme und Browser hinweg konsistent halten?

Ich versuche, einer SVG-Datei Text hinzuzufügen. Der Text ist dynamisch und wird über einem Rechteck angezeigt, das als Hintergrund dient.

Da der Text dynamisch ist, muss auch die Breite des Hintergrundrechtecks ​​dynamisch sein. Um konsistent zu sein, verwende ich eine Monospace-Schriftart mit fester Breite (Droid Sans Mono) und berechne die Breite des Hintergrundrechtecks ​​mithilfe des Ausdrucks - (x*6.4)+4), wobei xdie Anzahl der Zeichen im Text ist und 4 für hinzugefügt wird Polsterung (2 links, 2 rechts). Angenommen, 6.4dies ist die durchschnittliche Breite jedes Zeichens in der Droid Sans MonoSchriftart (nur eine Vermutung).

Für text Ruby on Railsist die Anzahl der Zeichen also 13, also ist die Breite des Hintergrundrechtecks 13*6.4+4 = 87.2​​.

Was in Browsern (Firefox und Chromium) unter Ubuntu perfekt funktioniert . Wenn er jedoch in denselben Browsern (Firefox und Chrome) unter Windows angezeigt wird, überläuft der Text das Rechteck.

Meine Frage lautet also: Wie kann ich sicherstellen, dass das Bild auf verschiedenen Betriebssystemen einheitlich aussieht? Das Bild sieht in allen Browsern auf demselben Betriebssystem einheitlich aus.

Ich füge ein Beispielbild als Referenz hinzu:

SVG-Bild als Referenz

AKTUALISIEREN

Vielleicht sollte ich meine Frage umformulieren : Wie kann ich in einer SVG-Datei dafür sorgen, dass eine Schriftart mit fester Breite auf allen Plattformen dieselbe Anzahl von Pixeln verwendet, vorausgesetzt, die SVG-Datei wird nicht von externen CSS-Stilen beeinflusst und die Zoomstufe ist normal?

Ich verstehe auch, dass es alternative Technologien gibt (PNG usw.), aber nicht jede SVG-Frage sollte damit enden , sie durch PNG zu ersetzen . Auch mehr als eine Lösung, ich bin daran interessiert zu verstehen, warum dieses Problem mit SVG besteht. Ich verwende eine Schriftart mit fester Breite, die auf allen Betriebssystemen die gleiche Anzahl von Pixeln einnehmen soll (Ist das eine falsche Annahme? Warum? Was kann ich dagegen tun?).

Screenshots

Ubuntu 12.04 amd64 / Firefox 13

Screenshot von Firefox / Ubuntu

Ubuntu 12.04 amd64 / Chromium 18

Screenshot von Chromium / Ubuntu

Windows 7 32-Bit (in VirtualBox) / Google Chrome 18

Screenshot von Google Chrome / Windows

Windows 7 32-Bit (in VirtualBox) / Firefox 13

Screenshot von Firefox / Windows

Erstens würde ich das höchstwahrscheinlich so machen : jsfiddle.net/lollero/6tuSH Zweitens scheint mir das eher eine Stackoverflow-Frage zu sein. Drittens, wenn Sie Bilder verwenden, können Sie entweder wenige Bilder verwenden, um die Teile zu wiederholen, die flexibel sein müssen, oder sie breit genug machen, um etwas Raum zum Wachsen zu lassen und auf das Beste zu hoffen ... (obwohl ich .pngs verwenden würde )
@Lollero: Das Problem hier ist, dass er die Größe berechnet und es nicht funktioniert. Dies geschieht unabhängig von der Methode, die zum Erstellen eines flexiblen Teils des Bildes verwendet wird.
@horatio Ich habe nicht gesagt, dass Flexibilität Größenunterschiede der Schriftart beheben würde (das Zoomen kann in einigen Browsern auch einige Probleme mit diesem SVG-Setup verursachen), aber es kann das Problem beheben, das daraus entsteht, nämlich Textausbruch farbige Bereiche. Mehr noch in meinem jsfiddle-Beispiel, da es sowohl horizontal als auch vertikal flexibel ist.
..und ich mag auch Flexibilität, wo es darauf ankommt. Ich kenne den Anwendungsfall dafür nicht wirklich, aber was ist, wenn es plötzlich 200 Stimmen gibt? Der Text würde nicht in den grün gefärbten Bereich passen, aber wenn dieser flexibel wäre, würde er wie angegossen passen, egal wie viele Stimmen Sie hätten. Das wäre wahrscheinlich das praktischste Beispiel dafür, warum dieser aktuelle Versuch vielleicht scheitern würde (je nach Anwendungsfall natürlich).
Als ich nach Hause kam, bemerkte ich, dass mein Beispiel in Firefox nicht funktionierte und ... das nervte mich zu Tode, obwohl es nur ein Beispiel ist. Hier ist jsfiddle.net/lollero/6tuSH/3 (ich habe bemerkt, dass ich in dieser Geige einige Dinge ziemlich seltsam gemacht habe, aber ... ich werde jetzt einfach weggehen ...: D)
Er berechnet den Raum, also würden "200 Stimmen" vermutlich passen, basierend auf der von ihm angegebenen Formel. ( Note also that your jsfiddle example wraps to two lines on my browser (breaks between durchgestrichen-- 1` und vote).`--) Die wirkliche Lösung besteht darin, sich nach Möglichkeit nicht auf die Clientseite zu verlassen, aber dies ist nicht die gestellte Frage.
@Horatio ja, es hat nicht richtig funktioniert, aber bedeutet das, dass es nicht konnte? Nein. Was seine Frage betrifft, möchte ich sagen, dass es sinnlos ist, die genaue Frage zu beantworten, da die Lösung des Problems, das er hat, auf andere Weise viel einfacher ist.
Dasselbe könnte über die Lösung des OP gesagt werden.
@Horatio Sie sagen also, dass, weil mein Proof of Concept nicht perfekt funktioniert hat, die genaue Lösung, nach der OP fragt, besser wäre? Ich arbeite nicht für ihn, wissen Sie. Ich bin immer noch sehr davon überzeugt, dass es viel einfacher wäre, eine Methode wie die in meinem jsfiddle oder eine ähnliche zu verwenden.
Meine Vermutung ist, dass die "Schriftart mit fester Breite" nicht auf allen Systemen verfügbar ist und daher durch eine andere Schriftart mit fester Breite ersetzt wird.
@Scott, die Schriftart "Droid Sans Mono" mit fester Breite wird mithilfe von @font-face.

Antworten (1)

Da Sie nur das SVG verlinkt und keine Bildschirmaufnahme bereitgestellt haben, um zu zeigen, was Ihr Problem ist, kann ich nur nach dem gehen, was ich sehe. Das in der Frage gezeigte Bild wird nicht richtig gerendert, da es nicht die richtige Schriftart ist. Daher ist Ihr Rendering deaktiviert, da Ihre Berechnung auf einer anderen Buchstabengröße und einem anderen Abstand basiert (ich sehe Courier). Wenn ich das SVG in einem neuen Tab ansehe (oder dem Link für den direkten Link folge), wird es mit Droid Sans Mono und der richtigen Rechteckgröße richtig gerendert.

Ihr Problem ist also im Grunde ein CSS-Problem, bei dem die Schriftart durch einen übergeordneten Container oder eine falsche Aufrufmethode gelöscht wird. Insofern würde ich Lollero zustimmen, dass es für GD kein Thema ist.

Eine Möglichkeit, damit umzugehen, besteht darin, die Schriftartdatei auf Ihrem Server zu speichern und sie mit PHP-GD-Aufrufen zu rendern (ziemlich trivial). Sie können das Ergebnis mit einer Prüfsumme usw. speichern, sodass das Bild nur dann neu gerendert wird, wenn sich der Text ändert, und ansonsten die gespeicherte Kopie verwenden.

BEARBEITEN:___________

Ein Screenshot Ihrer SVG-Datei auf Win7 64bit Firefox:

Bildschirmaufnahme

Der Klartextinhalt Ihrer SVG-Datei (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>
Hallo @horatio, ich habe meine Frage als Feedback zu Ihrer Antwort aktualisiert. Außerdem möchte ich klarstellen, dass ich das Bild mithilfe des <img />Tags in eine Seite einbette, sodass externes CSS keine Auswirkungen haben sollte (AFAIK). Screenshots habe ich auch beigefügt. Danke.
Ich habe die Antwort mit ein paar Dingen bearbeitet. (1) Es ist eine XML-Datei und Sie können die CSS-Deklaration sehen, die auf fonts.googleapis.com zeigt (Zeile 6). Dies wird aus irgendeinem Grund nicht berücksichtigt und führt dazu, dass Ihr Browser die Schriftartdatei nicht hat. (2) Die Bildschirmaufnahme entspricht dem Aussehen der SVG-Datei (mit der richtigen Schriftart). Die im Text Ihrer obigen Frage angezeigte "eingebettete Version" scheint jedoch die Kurierschrift zu sein und sieht Ihren Screenshots sehr ähnlich.