Chrome canvas 2d Kontext measureText gibt mir seltsame Ergebnisse

8

Hier ist eine kompakte Version meines Problems

%Vor%

Wenn Sie diesen Code in Chrome ausführen, werden zumindest am Ende falsche Zahlen ausgegeben. Zuerst setze ich die Schriftart auf '11pt Calibri', aber Chrom ändert es aus irgendeinem Grund sofort in '15px Calibri', und deswegen produziert es Text, der etwas größer als korrekt ist. Ich habe gelesen, dass die Leinwand mit 96 dpi läuft, also sollte der richtige px 14,6 sein.

Danach messe ich die Breite eines Textes M, der für mich bei 12,53401184 herauskommt, diese Nummer ist wichtig.

Danach habe ich die Schriftart so geändert, dass sie fett und kursiv ist, und dann stelle ich sie auf die ursprüngliche Schriftart zurück. Jetzt, wenn ich es messe, gibt es mir 12.824707, was eine massive 0.3px aus ist. Ich zeichne Text auf einer Leinwand mit einer Breite von 600px bis 800px, und ich brauche es um richtig zu wickeln, also brauche ich es genau 1px über die Linie, so dass einzelne Buchstaben mindestens 0,02px Genauigkeit haben müssen, die Ich habe anständig gearbeitet, bis ich fett und kursiv geschrieben habe.

Keines der oben genannten Probleme gibt es bei Firefox, und die Deaktivierung der Canvas-Hardwarebeschleunigung für Chrome scheint keine Auswirkungen zu haben. Ich benutze Chrome 52.0, welches die aktuellste Version ist.

Edit: Ich habe herausgefunden, dass Sie nicht einmal irgendetwas davon machen müssen, um die falsche Nummer zu bekommen, einfach genügt das.

%Vor%
    
orchlon Batsaikhan 08.08.2016, 07:20
quelle

2 Antworten

3

Verwenden Sie nicht "pt" für die Schriftgrößenanpassung im Zeichenbereich.

CSS Absolute und Magic Units

Die Verwendung von pt für die Schriftgröße ist nicht zu empfehlen es hat keine wirkliche Bedeutung für Medien, die visuelle Informationen in Form von Pixeln (diskrete unteilbare Bildeinheiten) darstellen und auf Bildschirmen angezeigt werden, die keine feste Pixeldichte haben.

pt ist eine absolute Maßeinheit, das gleiche wie cm , während px eine "magische Einheit" ist und nur dann eine absolute Bedeutung hat, wenn der Medientyp gedruckt ist.

  

OP: "Ich habe gelesen, dass die Leinwand mit 96 dpi läuft, also sollte der richtige px 14,6 sein."

Dies ist nicht korrekt, die Leinwand hat keine absolute Maßeinheit. Ein Pixel als CSS-Einheit hat nur eine absolute Dimension, wenn der Medientyp gedruckt wird, in diesem Fall 1px = 1/96 Zoll. Die Leinwand wird nicht als gedrucktes Medium betrachtet.

Warum ändert sich die Breite?

Das scheinbare Problem

%Vor%

Obwohl die ctx.font -Werte gleich sind, sind die gemessenen Schriftbreiten unterschiedlich.

Die einfache Lösung

%Vor%

Vermeide die gemessenen Größenabweichungen, aber ich bin sicher, dass niemand dies als etwas anderes als eine hässliche Arbeit um einen "offensichtlichen" Browser-spezifischen Fehler betrachten würde.

Die Lösung

Verwenden Sie nicht die pt -Einheiten beim Festlegen von Zeichensatzschriften.

Was ist los?

Das Problem ist ein Missverständnis dessen, was die Eigenschaft ctx.font tatsächlich ist. Es repräsentiert nicht die tatsächliche interne Darstellung der aktuellen Schriftart, sondern eine abstrakte, von Menschen lesbare Form.

  

W3C 2D Canvas : "Beim Abrufen muss das font-Attribut die serialisiert zurückgeben form der aktuellen Schriftart des Kontexts. "

Der Prozess der Serialisierung verliert an Genauigkeit. Serialisierung von CSS-Werten . Der W3C-Standard gibt an, dass font-size in% co_de steht % Einheiten, die in diesem Fall den scheinbaren "Bug" noch verstärken.

Die% set-Funktion px übernimmt die CSS-Schriftart, analysiert sie. Wenn valid, wird die interne Zeichensatzschriftart festgelegt und der Wert für die serialisierte CSS-Schriftart wird in font geschrieben. Die beiden müssen nicht übereinstimmen und der Standard gibt nicht an, dass sie dies tun sollen.

Zusammenfassung

Das in der Frage beschriebene Verhalten ist kein "Bug". Inkonsistenz zwischen den Browsern ist jedoch (wie immer) ein Problem. Wenn wir den Standards folgen, könnte man meinen, dass Browser, die die Messungsinkonsistenz nicht zeigen, den Standard falsch interpretiert haben und eine Zweideutigkeit mit ihrer eigenen Interpretation gefüllt haben (obwohl dies meinerseits spekulativ ist).

Die einfache Lösung des Problems besteht darin, die Richtlinien des Standards zu befolgen und context.font nicht zu verwenden, wenn Sie pt -Werte für alles außer Druckmedien einstellen.

Wie bei allen Computermedien hat "dpi" nur beim Drucken eine Bedeutung und wird erst dann definiert. Pixel entsprechen beim Drucken auch nicht unbedingt Punkten. Verwenden Sie immer die Auflösung, wenn Sie auf Pixel und nicht auf font-size (mein Haustier) verweisen

    
Blindman67 08.08.2016 14:40
quelle
2

Ich habe verstanden, warum es kaputt ist. Chrome tut etwas intern, um pt-Werte zu kompensieren, obwohl die Schriftart auf 15px hochjacked wird. Also, wenn ich den Font-Wert von der ctx.font bekomme, um es zu ändern, bekomme ich den geänderten px-Wert anstelle des ursprünglichen pt, also gebe ich ihm einen rohen 15px-Wert, wenn das passiert, tut chrome das nicht kompensieren. Eine Problemumgehung besteht darin, die ursprüngliche Schriftart an einem anderen Ort wie ctx.originalFont zu belassen und sie dann anstelle von ctx.font zum Modifizieren zu verwenden.

Zum Beispiel funktioniert das

%Vor%
    
orchlon Batsaikhan 08.08.2016 09:25
quelle