Probleme mit dynamischem Text in SVG, wenn die Schriftart nicht SVG ist


7

Ich habe also eine Grafikautomatisierungskette, die problemlos in einer Headless-Linux-Umgebung ausgeführt wird und programmgesteuert generierte / geänderte SVGs und PhantomJS (derzeit 1.9.0) als endgültige Rendering-Engine verwendet. Ich habe einige Anforderungen an das Ersetzen von dynamischem Text und daraus resultierende Anforderungen an die Skalierung und Anpassung dynamischer Schriftarten ... Ich habe eingebettete SVG-Schriftarten und etwas beschissenes eingebettetes Javascript verwendet, das gut funktioniert, abgesehen von zwei Dingen:

1) Der Client hat einige Anfragen nach Schriftarten mit Ligaturen (das SVG-Schriftformat wird nicht unterstützt).

2) Wir haben eine Live-Vorschau-Option im Gange und würden gerne die SVG nur bis zur Webseite bereitstellen können, ohne vorher ein PNG / JPEG / was auch immer auf unserem Server zu rendern. Halten Sie die Last niedrig, lassen Sie die CPU des Clients das schwere Heben übernehmen.

Im Interesse dieser Probleme habe ich mit WOFF-Schriftarten herumgespielt, da die Unterstützung für SVG-Schriftarten nie SEHR gut war und Chrome sie jetzt mit dem Wechsel zur Blink-Engine nicht mehr unterstützt, wenn ich den Client möchte mache meine Arbeit Ich brauche etwas, das mit so vielen gängigen Browsern wie möglich kompatibel ist ...

Hier ist das Problem: Meine automatische Skalierung schlägt miserabel fehl, wenn ich eine WOFF- (oder OFT- oder TTF-) Schriftart und die @ font-face-Funktion verwende.

Ich habe nur die SVG-Schriftart in meine Grafik in die Defs eingebettet und wie jedes andere SVG-Element mit dem DOM referenziert. Dies macht die Dinge, die ich erwarte und brauche, wenn es mit Java-Skript wie folgt kombiniert wird:

<script id="multiscaler1" type="text/javascript">
    var texta = document.getElementById(&quot;text8093&quot;);
    var textb = document.getElementById(&quot;text8100&quot;);
    var textpatha = document.getElementById(&quot;textPath8097&quot;);
    var textpathb = document.getElementById(&quot;textPath8104&quot;);
    var patha = document.getElementById(&quot;path8091&quot;);
    var pathb = document.getElementById(&quot;path8089&quot;);
    var charcounta = textpatha.getNumberOfChars();
    var charcountb = textpathb.getNumberOfChars();
    var fontsizea = 10;
    var fontsizeb = 10;
    var offseta = -13;
    var offsetb = -13;
    var spacing = 0;
    while ( ((textpatha.getComputedTextLength() + (spacing * charcounta)) &lt; patha.getTotalLength()) &amp;&amp; (fontsizea &lt; 43) )
    {
        fontsizea += .5;
        offseta += 0.2
        textpatha.setAttribute(&quot;font-size&quot;, fontsizea);
        texta.setAttribute(&quot;transform&quot;, &quot;translate(&quot; + offseta + &quot;,0)&quot;);
    }
    while ( ((textpathb.getComputedTextLength() + (spacing * charcountb)) &lt; pathb.getTotalLength()) &amp;&amp; (fontsizeb &lt; 43) )
    {
        fontsizeb += .5;
        offsetb += 0.2
        textpathb.setAttribute(&quot;font-size&quot;, fontsizeb);
        textb.setAttribute(&quot;transform&quot;, &quot;translate(&quot; + offsetb + &quot;,0)&quot;);
    } 
</script>

Ziemlich Mist, ich weiß, aber ich bin ein Produktionsleiter und Grafiker, kein Programmierer: P und es sieht so aus:

Geben Sie hier die Bildbeschreibung ein

Welches ist, was ich will ... (aber funktioniert natürlich nur in Browsern, die SVG-Schriftarten unterstützen ...)

Jetzt, wenn ich diese kleine Schönheit zu meinen Deffs hinzufüge

<style type="text/css">
@font-face {
  font-family: Narrow-Bold;
  src: url('WOFFFONTS/Narrow-Bold.woff');
}
</style>

und entfernen Sie die SVG-Schriftdaten, die ich erhalte:

Geben Sie hier die Bildbeschreibung ein

Ach je. Das stimmt überhaupt nicht. Ich habe mich mit meinen Abstandswerten beschäftigt (die dazu dienen, eine andere Situation zu bewältigen, in der ich den Zeichenabstand ändere, um die Schriftgröße basierend auf der Zeichenfolgenlänge zu maximieren ...) und kann dies veranlassen:

Geben Sie hier die Bildbeschreibung ein

auch ganz falsch: /

Was gibt es hier? Irgendeine Hilfe? Ehrlich gesagt wäre es schön, alle auf WOFF-Schriftarten (oder mit @ font-face verknüpfte OTF- oder TTF-Schriftarten, die übrigens dasselbe tun) umzuschalten, da ich viel weniger SVGs mit mehr als 20.000 Zeilen hätte, ohne überall Schriftarten einzubetten der verdammte Ort ...

Ich habe verschiedene Tools zur Schriftkonvertierung und sogar einen Trick ausprobiert, den ich in einigen Google-Suchergebnissen gefunden habe, in denen Sie den WOFF aus der SVG erstellen, nicht aus der TTF oder der OTF ... dieselben Ergebnisse.

??

Im Folgenden finden Sie ein vereinfachtes Beispiel für ein eigenständiges SVG mit eingebetteter SVG-Schriftart unter Verwendung der kostenlosen Schriftart Delicious Bold . Dies funktioniert natürlich nur in einem Browser, der SVG-Schriftarten unterstützt. Die eingebettete Schriftart wurde aus einem neuen Download der OTF mit FontForge für Windows Release 2015-06-12 erstellt . Ich habe auch eine WOFF-Version derselben Schriftart erstelltAuf die gleiche Weise (alle Standardeinstellungen, wobei die Warnung zu "Nicht-Standard-Ems-Fortschritt" in der TTF-Definition ignoriert wird) wurde ein @ font-face-Link mit einem anderen Namen hinzugefügt, der auf WOFF verweist, wenn er sich im selben Verzeichnis wie befindet die SVG. Durch Bearbeiten der Schriftart = "xxxxxx" im Text / Textpfad-Element der SVG können Sie schnell zwischen der eingebetteten SVG-Schriftart (die einwandfrei funktioniert), der verknüpften WOFF-Schriftart (die falsch skaliert) und der Systemversion der Schriftart wechseln Familie, falls installiert (was vielleicht bemerkenswert ist, rendert etwas anders als die eingebettete SVG-Schriftart, skaliert aber auch korrekt)

Dieses Verhalten ist in allen getesteten Browsern konsistent (Opera-neueste Version für Windows 7 64-Bit, Mozilla-neueste Linux Ubuntu 14, Chrome-neueste Version Windows 7/8 64-Bit, Safari 5.1.7 für Windows (unterstützt SVG-Schriftarten) und PhantomJS 1.9.7 Linux CentOS 6.4 final (unterstützt SVG-Schriftarten). Es ist auch für alle getesteten (viele ...) und Konvertierungs-Engines (Eichhörnchen-Schriftarten, FontForge, Birdfont ...) konsistent.

Da das in sich geschlossene SVG zu groß ist, um es in den Körper einzufügen , wird hier ein Link dazu in ein JSfiddle-Projekt eingefügt .

Ja, mir ist klar, dass ich dies durch Rendern mit Apache Batik lösen könnte, aber: 1) Batik ist slooooooooooooow. Sooooo slooooooooooooooooooooooooow ... OMG ist es langsam. 2) Ich möchte in der Lage sein, so viel CPU-Last wie möglich von meinem Server zu entfernen, die genaue Umkehrung dessen, was Batik tun wird. 3) Das ist nicht der Punkt, verdammt!


Hallo JawzX, wenn du hier keine Antwort bekommst. Vielleicht möchten Sie versuchen, auf stackoverflow.com
AndrewH

Vielen Dank, ich bin ein Stack Overflow-Mitglied und habe dies bereits gekreuzt. Bisher hat es hier viel mehr Aufmerksamkeit bekommen, aber keine Antworten an beiden
Orten

1
Sie sollten in Betracht ziehen, innerhalb von 2 Tagen ein Kopfgeld zu platzieren, jedoch nicht hier. Sie sollten auch überlegen, Ihre Frage zu überarbeiten, um sie kompakter und einfacher zu gestalten, und möglicherweise die drei Bilder zu einem kombinieren. Sie könnten mehr Leser bekommen.
Alin

1
Sehr viel TL; DR
Zach Saucier

1
war sich TL nicht bewusst; DR war eine berechtigte Kritik außerhalb von redit.
JawzX

Antworten:


1

Ich arbeite viel mit SVGs, da ich Webdesigner bin. Wenn ich die Form (Schriftart) meines Textes beibehalten möchte, öffne ich Adobe Illustrator, schreibe, was ich will, und erstelle daraus Konturen. Es ist nicht so zeitaufwändig. Stellen Sie einfach sicher, dass Sie den Text kopieren, bevor Sie ihn skizzieren, um eine bearbeitbare Version beizubehalten.


Ich arbeite In einer vollständigen Produktionsumgebung mit Hunderten von Kundenaufträgen pro Tag kann ich mir die Zeit für den Export auf Pfade in Illustrator nicht leisten. Ich verwende immer noch ein veraltetes System, da es das SCHNELLSTE ist, und das ist wirklich wichtig für meine Zwecke ...
JawzX
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.