2009-05-28 21 views
19

Ich hatte Grund, ein Etikett mit einer großen Schrift in einem Delphi-Formular zu benötigen und bemerkte, dass seine Kurven noch leicht gezackt waren. Ich verglich dies mit der gleichen Größe und Schriftart in MSWord, die viel glatter war. Nach der Recherche fand ich Code , der mir erlaubt, meine Schriften zu glätten, aber es ist chaotisch und ich fragte mich, ob gab es einen besseren Weg? Suchen Sie in der VCL Quelle scheint TFont zu NONANTIALIASED_QUALITY fest gebunden, die ziemlich frustrierend ...Schriftart Glättung in Delphi

Dank Bri

procedure TForm1.SetFontSmoothing(AFont: TFont); 
var 
    tagLOGFONT: TLogFont; 
begin 
    GetObject(
    AFont.Handle, 
    SizeOf(TLogFont), 
    @tagLOGFONT); 
    tagLOGFONT.lfQuality := ANTIALIASED_QUALITY; 
    AFont.Handle := CreateFontIndirect(tagLOGFONT); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
var 
    I : integer; 
begin 
    For I :=0 to ComponentCount-1 do 
    If Components[I] is TLabel then 
     SetFontSmoothing(TLabel(Components[I]).Font); 
end; 
+3

So funktioniert dieser Code (und Sie wollen es nur reinigen und finden Sie einen einfachen Weg) oder ist es immer noch nicht glatt genug oder funktioniert nicht? – schnaader

+0

Welchen Teil dieses Codes halten Sie für chaotisch? –

+0

Es scheint verschwenderisch, dass ich jede Schrift auf jedem Etikett stoßen muss, wenn die VCL dies bereits getan hat. Ich suchte nach etwas, das ich außer Kraft setzen oder unterordnen konnte, aber ohne Glück. Ich denke, das ist der einzige Weg, um das zu erreichen, was ich will. Bri –

Antwort

29

Sie können die VCL dazu bringen, eine eigene Klasse zu erstellen, die von TLabel erbt. Dies ist ein Proof-of-Concept-Code, getestet mit Delphi 4, der Ihnen den Einstieg erleichtern soll.

Erstellen Sie eine neue Einheit für die eigene TLabel Klasse:

unit AntiAliasedLabel; 

interface 

uses 
    Windows, Messages, SysUtils, Controls, StdCtrls, Graphics; 

type 
    TLabel = class(StdCtrls.TLabel) 
    private 
    fFontChanged: boolean; 
    public 
    procedure Paint; override; 
    end; 

implementation 

procedure TLabel.Paint; 
var 
    LF: TLogFont; 
begin 
    if not fFontChanged then begin 
    Win32Check(GetObject(Font.Handle, SizeOf(TLogFont), @LF) <> 0); 
    LF.lfQuality := ANTIALIASED_QUALITY; 
    Font.Handle := CreateFontIndirect(LF); 
    fFontChanged := TRUE; 
    end; 
    inherited; 
end; 

end. 

Jetzt ist Ihre Form Einheit ändern, die das Etikett enthält, das Hinzufügen der AntiAliasedLabel Einheit nachStdCtrls. Dies führt dazu, dass Ihre eigene Klasse AntiAliasedLabel.TLabel erstellt wird, wo normalerweise StdCtrls.TLabel erstellt würde.

+0

+1 sehr interessante Lösung! – jpfollenius

+4

+1 Woah - Ich hatte keine Ahnung, dass du mit solchen Tricks durchkommen kannst. Danke, dass du meine Augen geöffnet hast! – robsoft

+0

Sehr, sehr, sehr, sehr, sehr, sehr, sehr .... SCHÖN! Danke für diesen einfachen Trick. – Codebeat

3

Der einfachste Weg ist Ihre eigene Komponente zu schaffen, basierend auf TLabel, wie TSmoothLabel oder TAntiAliasedLabel , und fügen Sie Ihren Glättungscode hinzu. Dann verwenden Sie Ihre Komponente anstelle des Standard TLabel.

+0

True, aber ich lade einen vorhandenen DFM, der die TLabel-Klasse angibt, also könnte Ihr Vorschlag funktionieren, wenn es eine Möglichkeit gibt, TLAbel erneut zu registrieren. Bri –

+1

Es gibt einen Weg, aber es erfordert den Austausch der TLabel.NewInstance VMT Eintrag durch eine eigene Methode zur Laufzeit. Die JCL (JEDI Code Library) verfügt über Funktionen, um dies zu tun. –

+3

@Brian: Warum können Sie nicht einfach die DFM- und PAS-Dateien (von außerhalb der IDE) reparieren, um Ihre neue Klasse zu verwenden? Alternative: Wenn Sie eine Delphi-Version verwenden, die sie unterstützt, können Sie einen Klassenhelfer für TLabel verwenden. (Geben Sie an, welches Delphi in der Zukunft verwendet werden soll.) Ich empfehle die Klassenhilfsroute nicht, wenn es andere Wege gibt, da dies alle TLabel betrifft, die sich in ihrem Gültigkeitsbereich befinden. –

7

IMHO sollte die VCL die Standard Schriftart Glättung überprüfen und diese als Standard zur Laufzeit anwenden. Wenn nicht, sollte es zumindest auf eine vernünftigere Glättung zurückgreifen. Man könnte argumentieren, dass ClearType in diesem Fall ein besserer Standard wäre, wenn man bedenkt, dass heutzutage mehr als 50% der Monitore LCD sind (und mehr als 50% der Computer XP oder besser).

Dies ist eine anerkannte Hack (und wie Ken Weiß erwähnt, nicht der beste Ansatz, wenn es Alternativen gibt), aber ich brauchte eine Möglichkeit, diese buchstäblich Hunderte von 3rd-Party-Komponententypen enthält, die für Formen global zu fixieren (Komponente Erbe machen unrealistisch).

geändert ich die Standard-Schriftqualität im Graphics.pas, TFont.GetHandle wie folgt:

// lfQuality: = DEFAULT_QUALITY;

lfQualität: = 5; // (HACK) CLEARTYPE_QUALITY, Kräfte cleartype

5

Von:. http://objectmix.com/delphi/725245-tlabel-antialiasing-possibile-3.html

„einfach eine Schriftart, die Schriftglättung unterstützt, sollte dieses Problem beheben Delphi Anwendungen (oder zumindest verwendet zu verwenden) MS Sans Serif als Standard, die nicht unterstützt Unterstützung Glättung (ClearType oder anders). Wenn Sie Ihre Schriftart auf Tahoma (am besten für XP) oder Segoe UI (am besten für Vista), werden Sie automatisch Schriftartenglättung nach Systemeinstellungen in Ihre Delphi App. "

Bestätigt, es funktioniert wunderbar mit Delphi XE und Win7.Beschäftigt, alle meine Schriftarten gerade zu ändern ;-)