GDI + Font Rendering, insbesondere in Ebenenfenstern

8

Dies meine Freunde, wird ein langer sein ...

Ich bekomme ziemlich bizarres Verhalten, wenn ich versuche, Text in einem mehrschichtigen Fenster zu rendern.

Das Seltsame ist, dass GDI + bei einigen Kombinationen von font / font-style / font-size die Rendering-Methode ändert. Für Tahoma-Bold Schriftgrößen zwischen 8.49 und 16.49 (Pixel-Units) inklusive "fail". Für andere Schriftarten und Stile bekomme ich "fehlgeschlagen" in verschiedenen Größen.

Aus Gründen der Übersichtlichkeit habe ich ein ausführbares ausführliches Beispiel weiter unten vorgestellt. Die zwei Schlüsselparameter, mit denen man spielen kann, sind in Zeile 23:

%Vor%

Bei Verwendung von Ebenenfenstern und vollständiger Deckkraft zeichnen die Schriften ein transparentes "Loch" im Hintergrund. Wenn ich jedoch der Textfarbe eine leichte Transparenz hinzufüge (Alpha-Kanal = 254), werden die Schriftarten undurchsichtig. Oder wenn ich normale (nicht geschichtete) Fenster verwende, werden die Schriftarten undurchsichtig wiedergegeben. Was geht hier vor?

Aber auch ohne die geschichteten / Transparenzprobleme ist klar, dass hier etwas Seltsames passiert. Die Schriftgrößen 8.49 - 16.48 werden Pixel perfekt gerendert, die anderen Schriftarten haben eine leichte unscharfe Qualität, besonders die kleinen. Es scheint also, dass das System beim Rendern dieser Mediengrößen einen anderen Ansatz verfolgt. Kann jemand etwas Licht darauf werfen, wie kann ich zum Beispiel Schriftgröße 8.0 Pixel ohne die oben erwähnte Unschärfe wiedergeben? Ich habe alle möglichen Einstellungen für SetTextRenderingHint() und SetTextContrast() ausprobiert, aber keine sah knackig aus für Schriftarten der Größe 8. Ich habe Tahoma & amp versucht; Nur Arial ...

Nebenfrage 1: Ich wollte reines GDI + für die Off-Screen-Zeichnung verwenden, aber ich konnte es nicht schaffen, indem ich einfach Bitmap & amp; Graphics Objekte. Ich musste immer noch alte GDI-Sachen verwenden, um einen DC zu erstellen und die HBitmap darin auszuwählen. Wie kann ich alles in GDI + tun?

Nebenfrage 2 (nur Geeks): Ich habe auch versucht, die Fonts in guten alten GDI zu zeichnen, aber dort habe ich noch bizarrere Effekte: (1) In einem mehrschichtigen Fenster wurde der Text transparent, aber in einem additiven Weg. (So ​​würde ein roter Text gut aussehen, wenn das Fenster dahinter dunkel wäre, aber wenn das Fenster hinter ihm weiß wäre, wäre der Text vollständig verschwunden!) Wenn ich mein eigenes Fenster mit einem halbtransparenten Quadrat füllte, dann verhielt es sich wie erwartet. (Ein rotes Quadrat würde dunkelrot werden, wenn das Fenster dahinter schwarz wäre und das Quadrat sich hellrot über einem weißen Fenster drehen würde). Und ich kann beide Verhaltensweisen gleichzeitig in einem Fenster beobachten. Und (2) als sehr unerwünschter Bonus hat der gezeichnete Text seinen Hit-Test verloren und wurde nicht mehr anklickbar? Irgendwelche Erklärungen da draußen?

Und wenn Sie so weit gelesen haben, danke für das Aushalten und danke für irgendwelche Antworten!

%Vor%

[EDIT] Problem gelöst! Code unten gemäß Rodrogo ausgezeichnete Vorschläge. Kudos und ein immenser Dank an ihn. Ich bin wirklich dankbar.

Alle Bearbeitungen sind mit // # MOD

gekennzeichnet %Vor%     
Adam 13.04.2011, 09:53
quelle

4 Antworten

6

Ich denke, dass das Problem darin besteht, dass GDI (ohne das +) Alpha Transparenz nicht sehr gut unterstützt. Im besten Fall behält es den Alphakanal unberührt.

Wenn Sie ein Graphics-Objekt erstellen, das eine HDC mit einer ausgewählten Bitmap verwendet, die einen Alpha-Kanal hat, werden die Dinge schlecht gemischt. Meine Vermutung ist, dass die GDI + Schriftart rasterisiert entscheidet, welche Methode zum Rendern basierend auf einer Menge von Parametern verwendet wird; Wenn diese Methode in GDI unterstützt wird, wird sie verwendet (und der Alphakanal ignoriert). Wenn die Rendermethode in GDI nicht unterstützt wird, wird auf ein Pixel-für-Pixel-Rendering oder ähnliches zurückgegriffen, und der Alphakanal wird korrekt verwendet.

Um die richtigen Ergebnisse zu erhalten, sollten Sie den HDC nicht verwenden, um den Alphakanal zu ändern. Versuchen Sie die folgenden Änderungen:

  • Verwenden Sie die Bitmap, um das Grafikobjekt zu erstellen, nicht die HDC:

    %Vor%
  • Wählen Sie die Bitmap erst nach dem Rendern in den HDC hOff aus. Um sicher zu sein, ist es besser, dass das Graphics-Objekt zerstört wird und sein Bereich mit {...} eingeschränkt wird.

[EDIT]

Nach dem neuen Code ist die Lösung einfach: Sie sollten nicht nur den Aufruf von SelectObject () nach der Zeichnung verschieben, sondern auch die GetBitmap (). Das heißt, diese beiden Funktionen sollten kurz vor dem Aufruf von: UpdateLayeredWindow ():

stehen %Vor%     
rodrigo 08.08.2011, 14:32
quelle
2

Ich denke, ich habe gestern eine (teilweise) Lösung gefunden, die leichter zu implementieren ist als die von rodrigo: Sie können einfach StringFormatFlags::StringFormatFlagsBypassGDI als Format-Flag innerhalb der StringFormat angeben - Instanz übergeben Sie an DrawString , und voila: Alles wird mit dem Alpha-fähigen Font-Renderer gezeichnet. Dies behebt das Alpha-Kanal-Problem, zumindest ...

    
max 26.10.2011 13:44
quelle
1

Ich konnte seit einiger Zeit keine Erklärungen für dieses seltsame Verhalten finden. Allerdings habe ich festgestellt, dass die Verwendung von Standard-Rendering-Werten mit einigen Schriftarten viel bessere Ergebnisse liefert, versuchen Sie Arial mit den folgenden Einstellungen:

%Vor%     
AntonKrut 02.08.2011 18:16
quelle
0

Ersetzen Sie PixelFormat32bppARGB durch PixelFormat32bppPARGB . Die Dokumentation für die BLENDFUNCTION -Struktur gibt an, dass in der Quelle ein vormultipliziertes Alpha benötigt wird.

    
Mark Ransom 29.07.2011 21:47
quelle

Tags und Links