2009-05-28 2 views
19

У меня возникла необходимость в ярлыке с большим шрифтом в форме Delphi и заметил, что его кривые все еще слегка зазубрены. Я сравнивал это с тем же размером и шрифтом в MSWord, который был намного более плавным. После исследования я нашел код , который позволил мне сгладить мои шрифты, но это грязно, и мне было интересно, был ли лучший способ? Глядя в источнике VCL, TFont кажется преданными NONANTIALIASED_QUALITY что довольно неприятно ...Сглаживание шрифтов в Delphi

Благодарности 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

Так работает ли этот код (и вы просто хотите его очистить и найти какой-то простой способ), или он все еще не достаточно гладко или не работает? – schnaader

+0

Какую часть этого кода вы считаете грязной? –

+0

Кажется расточительным, что я должен выталкивать каждый шрифт на каждом ярлыке, когда VCL уже это сделал. Я искал что-то, что мог бы переопределить или подкласс, но не повезло. Я думаю, это единственный способ добиться того, чего я хочу. Bri –

ответ

29

Вы можете обмануть VCL в создании своего собственного класса, который наследуется от TLabel. Это код доказательной концепции, протестированный с помощью Delphi 4, который должен вас запустить.

Создать новый блок для собственного TLabel класса:

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. 

Теперь измените форму блок, содержащий метку, добавляя AntiAliasedLabel блок послеStdCtrls. Это приводит к созданию собственного класса AntiAliasedLabel.TLabel, где обычно создается StdCtrls.TLabel.

+0

+1 очень интересное решение! – jpfollenius

+4

+1 Woah - Я понятия не имел, что вы можете уйти с такими трюками. Спасибо, что открыли мне глаза! – robsoft

+0

Очень, очень, очень, очень, очень, очень, очень .... Ницца! Спасибо за этот простой трюк. – Codebeat

3

Самый простой способ создать свой собственный компонент на основе TLabel, таких как TSmoothLabel или TAntiAliasedLabel , и добавьте к нему свой код сглаживания. Затем вы используете свой компонент вместо стандартного TLabel.

+0

Правда, но я загружаю существующий DFM, который указывает класс TLabel, поэтому ваше предложение может работать, если есть способ перерегистрировать TLAbel. Bri –

+1

Существует способ, но он требует замены записи TLabel.NewInstance VMT собственным методом во время выполнения. JCL (JEDI Code Library) имеет функции для этого. –

+3

@Brian: Почему вы не можете просто исправить файлы DFM и PAS (вне среды IDE), чтобы использовать свой новый класс? Альтернатива. Если вы используете версию Delphi, которая их поддерживает, вы можете использовать помощник класса для TLabel. (Укажите, в какой Delphi в будущем.) Я не рекомендую класс helper route, если есть какой-либо другой способ, хотя, потому что это повлияет на любой TLabel, который находится в его области. –

7

IMHO, VCL должен проверять сглаживание шрифта системы по умолчанию и применять это как значение по умолчанию во время выполнения. Если нет, по крайней мере, он должен по умолчанию использовать более разумное сглаживание. В этом случае можно утверждать, что ClearType будет лучшим дефолтом, учитывая, что> 50% мониторов в эти дни являются ЖК-дисплеем (и более 50% компьютеров работают с XP или выше).

Это подтвержденный взлом (и, как указывает Кен Уайт, а не лучший подход, если есть альтернативы), но мне нужен был способ исправить это глобально для форм, содержащих буквально сотни сторонних типов компонентов (делая наследование компонентов нереально).

Я изменил значение по умолчанию шрифта качества в Graphics.pas, TFont.GetHandle следующим образом:

// lfQuality: = DEFAULT_QUALITY;

lfКачество: = 5; // (HACK) CLEARTYPE_QUALITY силы ClearType

5

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

«просто используя шрифт, который поддерживает сглаживание шрифтов должен это исправить Delphi использует (или, по крайней мере, имел обыкновение использовать) MS Sans Serif по умолчанию, который не поддерживает сглаживание (ClearType или иначе) .Если вы установите свой шрифт на Tahoma (лучше всего для XP) или пользовательский интерфейс Segoe (лучше всего для Vista), вы получите автоматически сглаживание шрифтов в соответствии с системными настройками в ваше приложение Delphi. "

Подтверждено, оно прекрасно работает с использованием Delphi XE и Win7.Занято изменение всех моих шрифтов прямо сейчас ;-)