歡迎光臨 Code²

Code Square, CodeSqaure, Pascal, Javascript

2008年12月18日星期四

完整範例 - 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.TextWidthCanvas.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;

  為了避免复雜和增加可讀性,顯示的文字用CharsetNameGetSampleText求得。如果第二行和第三行有一行是空白的,則將之合併起來。

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;

  兩行合併的例子。

沒有留言:

發佈留言