完整範例 - Fontlist (6/10)
本篇的目的,是讓顯示的樣本好看一點,這是因為我認為一行呆板的文字太難看,想加點變化。好聽點說,是對美有著基本的執著,不好聽,便是多此一舉。無論如何,把輸出變成下面的樣子,觀感的確是好很多。
我們的樣本分三行,第一行是字型名稱、文件名和charset,第二行是東亞字型樣本,第三行是ascii字型樣本,第二行和第三行的前半可以合併,顯示較大的文字。個人覺得這種設計很好看,它還很好利用了空間,能同時顯示中/英和不同大小的字,方便比較。
以下是相關的常量,三個行高、兩個行距和兩個水平間格。為了清晰起見,第一行用標準字體,否則有些手寫體根本連字型名稱也看不懂:
const LineHeight1 = 18; LineHeight2 = 24; LineHeight3 = 18; LineSpace1 = 2; LineSpace2 = 1; SpaceLeft = 2; SpaceMiddle = 1; FirstLineFont = 'Tahoma'; DefaultSample = 'ABCDEFGabcdefg0123456789+-*/&=(){}<>,.?%$#';
定義常量,是王道。直接使用數值,對程序的修改維護很不利。
樣本變了,Grid列高當然要隨之改變:
procedure TForm1.FormCreate(Sender: TObject); begin .... Grid.DefaultRowHeight:=LineHeight1+LineHeight2+LineHeight3+LineSpace1+LineSpace2; .... end;
DrawCell頗有一些修改,關鍵是多了一個p: Tpoint;,用來標示文字的左上角,在印出文字後,我們便加上字寬或字高(用Canvas.TextWidth和Canvas.TextHeight)。
procedure TForm1.DrawCell(Canvas: tCanvas; Rect: tRect; Row: integer; Selected: boolean); //Gridwidth changed to be 0 var HeadStr, Str1, Str2: string; p: tPoint; w: integer; begin with Canvas do begin if Selected then Brush.Color:=FontBgColorHl else if Row mod 2=0 then Brush.Color:=FontBgColor0 else Brush.Color:=FontBgColor1; FillRect(rect); if Row>=Length(fFonts^) then exit; if Selected then Font.Color:=FontColorHl else if Row mod 2=0 then Font.Color:=FontColor0 else Font.Color:=FontColor1; SetBkMode(Handle, TRANSPARENT); Font.Name:=FirstLineFont; Font.Charset:=DEFAULT_CHARSET; Font.Height:=LineHeight1; P:=Rect.TopLeft; inc(p.x, SpaceLeft); HeadStr:='Charset: '+CharsetName(fFonts^[Row].Charset); if fFontS^[Row].Filename<>'' then HeadStr:=ExtractFilename(fFonts^[Row].Filename)+', '+HeadStr; HeadStr:=fFonts^[Row].Fontname+' ('+HeadStr+')'; Textout(p.x, p.y, HeadStr); Font.Name:=fFonts^[Row].Fontname; inc(p.y, LineHeight1+LineSpace1); Font.Charset:=fFonts^[Row].Charset; GetSampleText(fFonts^[Row].Charset, HeadStr, Str1, Str2); if (Str1='') or (Str2='') then begin HeadStr:=HeadStr+Str1+Str2; Str1:=''; Str2:=''; end; if HeadStr<>'' then begin Font.Height:=LineHeight2+LineSpace2+LineHeight3; Textout(p.x ,p.y, HeadStr); Inc(p.x, SpaceMiddle+TextWidth(Headstr)); end; if Str1<>'' then begin Font.Height:=LineHeight2; Textout(p.x, p.y, Str1); end; if Str2<>'' then begin Inc(p.y, LineHeight2+LineSpace2); Font.Height:=LineHeight3; Textout(p.x, p.y, Str2); end; end; end;
為了避免复雜和增加可讀性,顯示的文字用CharsetName和GetSampleText求得。如果第二行和第三行有一行是空白的,則將之合併起來。
function CharsetName(Charset: integer): string; begin case charset of CHINESEBIG5_CHARSET: Result:='Chinese Big5'; GB2312_CHARSET: Result:='Chinese GB'; ANSI_CHARSET: Result:='Ansi'; DEFAULT_CHARSET: Result:='Default'; SYMBOL_CHARSET: Result:='Symbol'; SHIFTJIS_CHARSET: Result:='Janpanese ShiftJIS'; HANGEUL_CHARSET: Result:='Korean Hanguel'; OEM_CHARSET: Result:='OEM'; JOHAB_CHARSET: Result:='Johab'; HEBREW_CHARSET: Result:='Hebrew: '; ARABIC_CHARSET: Result:='Arabic'; GREEK_CHARSET: Result:='Greek'; TURKISH_CHARSET: Result:='Turkish'; VIETNAMESE_CHARSET: Result:='Vietnamese'; THAI_CHARSET: Result:='Thai'; EASTEUROPE_CHARSET: Result:='East Europe'; RUSSIAN_CHARSET: Result:='Russian'; BALTIC_CHARSET: Result:='Baltic'; MAC_CHARSET: Result:='MAC'; else Result:='Unknown'; end end; procedure GetSampleText(Charset: integer; var Head, Str1, Str2: string); begin case Charset of CHINESEBIG5_CHARSET: Head:='詩中天'; GB2312_CHARSET: Head:='坅笢毞'; SHIFTJIS_CHARSET: Head:=#$90#$9f#138;C'; HANGEUL_CHARSET: Head:='憡臐'; else Head:=''; end; case Charset of CHINESEBIG5_CHARSET: Str1:='地闊,一卷與君遊。--歸木淡'; GB2312_CHARSET: Str1:='華屨ㄛ珨橙迵澱蚔﹝ㄜㄜ寥躂筏'; SHIFTJIS_CHARSET: Str1:=''#$95#$97''#$8d#$81''; HANGEUL_CHARSET: Str1:='夥塋擎 離紫 曖 翎擎 霤腎橫塭'; else Str1:=''; end; Str2:=DefaultSample; end;
兩行合併的例子。
沒有留言:
發佈留言