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

Ich habe also eine Grafikautomatisierungskette, die problemlos in einer Headless-Linux-Umgebung mit programmgesteuert generierten/veränderten SVGs und PhantomJS (derzeit 1.9.0) als endgültige Rendering-Engine ausgeführt wurde. Ich habe einige Anforderungen an die dynamische Textersetzung und daraus resultierende dynamische Skalierungs- und Anpassungsanforderungen für Schriftarten ... Ich habe eingebettete SVG-Schriftarten und einiges beschissenes eingebettetes Javascript verwendet, das bis auf zwei Dinge gut funktioniert:

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

2) Wir schlagen eine Live-Vorschauoption herum und würden gerne das SVG einfach auf der Webseite bereitstellen, ohne vorher ein PNG/JPEG/was auch immer auf unserem Server zu rendern. Halten Sie die Last niedrig, lassen Sie die Client-CPU die schwere Arbeit erledigen, all das.

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

Hier ist also das Problem: Meine automatische Skalierung schlägt kläglich 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 Produktionsleiter und Grafiker, kein Programmierer :P und es sieht so aus:

Geben Sie hier die Bildbeschreibung ein

Was ich will ... (funktioniert aber 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 die SVG-Schriftdaten entfernen, bekomme ich Folgendes:

Geben Sie hier die Bildbeschreibung ein

Ach je. Das ist überhaupt nicht richtig. Ich habe mit meinen Abstandswerten herumgespielt (die dazu da sind, mit einer anderen Situation fertig zu werden, in der ich den Zeichenabstand ändere, um die Schriftgröße basierend auf der Zeichenfolgenlänge zu maximieren ...) und kann es dazu bringen:

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) umzustellen, da ich viel weniger SVGs mit mehr als 20.000 Zeilen hätte, ohne Schriftarten überall einzubetten der verdammte ort...

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

??

Unten sehen Sie ein vereinfachtes Beispiel für ein funktionierendes, eigenständiges SVG mit eingebetteter SVG-Schriftart unter Verwendung der kostenlosen Schriftart Delicious Bold . Offensichtlich funktioniert dies nur in einem Browser, der SVG-Schriftarten unterstützt. Die eingebettete Schriftart wurde aus einem frischen Download des 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, ignorieren der Warnung zu "nicht standardmäßigem ems-Vorsprung" in der TTF-Definition) und einen @font-face-Link mit einem anderen Namen hinzugefügt, der auf das WOFF zeigt, wenn es sich im selben Verzeichnis befindet wie die SVG. Durch Bearbeiten von font-face="xxxxxx" im text/textpath-Element des SVG können Sie schnell zwischen der eingebetteten SVG-Schriftart (die gut funktioniert), der verknüpften WOFF-Schriftart (die falsch skaliert) und der Systemversion der Schriftart wechseln family , falls installiert (was vielleicht zu beachten ist, etwas anders als die eingebettete SVG-Schriftart rendert, aber auch korrekt skaliert)

Dieses Verhalten ist bei allen getesteten Browsern konsistent (Opera-neueste für Windows 7 64-Bit, Mozilla-neueste Linux Ubuntu 14, Chrome-neueste 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-Fonts) Es ist auch konsistent über alle getesteten Fonts (viele...) und Fontkonvertierungs-Engines (squirrel-font, FontForge, Birdfont...)

Da das eigenständige SVG zu groß ist, um es in den Körper einzufügen, ist hier ein Link dazu, der in ein JSfiddle-Projekt eingefügt wurde .

Ja, mir ist klar, dass ich das 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 entlasten, genau das Gegenteil von dem, was Batik tun wird. 3) Das ist nicht der Punkt, verdammt!

Hi JawzX, falls du hier keine Antwort erhältst. Vielleicht möchten Sie versuchen, auf stackoverflow.com zu posten
Danke, ich bin ein Stack Overflow-Mitglied und habe dies bereits gepostet. Bisher hat es hier viel mehr Aufmerksamkeit bekommen, aber an beiden Orten keine Antworten ...
Sie sollten erwägen, in 2 Tagen ein Kopfgeld zu platzieren, aber eher auf SO als hier. Sie sollten auch in Betracht ziehen, Ihre Frage zu überarbeiten, um sie kompakter und direkter zu machen, und möglicherweise die 3 Bilder zu einem zu kombinieren. Vielleicht bekommst du mehr Leser.
Sehr viel TL;DR
war sich nicht bewusst, dass TL; DR außerhalb von redit eine gültige Kritik war.

Antworten (1)

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

Ich arbeite in einer vollwertigen Produktionsumgebung mit Hunderten von Kundenaufträgen pro Tag und kann mir nicht die Zeit leisten, in Illustrator in Pfade zu exportieren. Ich verwende immer noch ein veraltetes System, da es das SCHNELLSTE ist, und das ist es, was für meine Zwecke wirklich zählt ...