CodeTyphon實現(xiàn)跨平臺繪制文字

本文針對 CodeTyphon 6.30 及后續(xù)版本。

最近依然堅持在使用 CodeTyphon 做跨平臺的開發(fā),涉及到繪畫的部分,發(fā)現(xiàn)坑不少,特此寫一篇來填坑。

首先是 Graphics 單元,由于各平臺實現(xiàn)機制不同,并且都需要大量的初始化工作,因此不能直接 uses 就完事,必須在 ppr 文件內(nèi)進行對 Interfaces 的引用。如果是 Terminal 應(yīng)用,還需要手動引用 adLCL 庫。

針對 adLCL 這個庫,原本的名稱為 LCL 或 bsLCL,視不同的版本擁有不同的名稱,但是本質(zhì)上是同一個東西,在 6.30 及后續(xù)版本,該庫的名稱被改為 adLCL。

隨后就是要進行繪圖了,這部分其實非常的坑,在各個平臺上,相同的繪圖的函數(shù)將產(chǎn)生不同的作用。舉個栗子,在圖片上添加自動換行的文字:

with Canvas do begin
    Pen.Color := clBlack;
    Brush.Style := bsClear;
    TextStyle.WordBreak := True;
    TextStyle.SingleLine := False;
    TextRect(rect, x, y, str);
end;

這段代碼在 Windows 上工作完善,在 Linux 上將報出 GLib-GObject-CRITICAL 的異常,并最終引起閃退(神奇的是有的時候可以正常工作),而在 Mac 上這段代碼不能實現(xiàn)自動換行!

好了,這樣不穩(wěn)定的代碼還是放棄吧,我們應(yīng)當能有更好的辦法來解決這問題。首先可以確定的是,TextOut 函數(shù)在任何平臺都可以正常工作,因此我們努力的方向也應(yīng)當是將 TextRect 改成 TextOut,這其中需要做一些運算。

首先把要繪制的文字拆成行,注意在拆的時候需要使用 UTF8 編碼,以避免不必要的字符串截斷問題:

function text2Lines(acanvas: TCanvas; astr: string; arect: TRect): TStringArray;
var
  len: Integer;
  w: Integer;
  lines: Integer;
  i: Integer;
  j: Integer;
  atmp: string;
  idx: Integer;
begin
  len := UTF8Length(astr);
  w := acanvas.TextWidth(astr);
  lines:= w div (rect.Right - rect.Left);
  if (w mod (rect.Right - rect.Left) <> 0) then lines += 1;
  SetLength(Result, lines);
  idx := 0;
  for i:= 0 to lines - 1 do begin
    atmp:= '';
    for j := idx to len - 1 do begin
      atmp += UTF8Copy(astr, j, 1);
      if (acanvas.TextWidth(atmp) > awidth) then begin
        UTF8Delete(atmp, UTF8Length(atmp) , 1);
        Result[i] := atmp;
        idx := j;
        Break;
      end;
    end;
  end;
  if (idx < len) then begin
    if (Result[lines - 1].Trim = '') then begin
      Result[lines - 1] := UTF8Copy(astr, idx, len);
    end else begin
      SetLength(Result, lines + 1);
      Result[lines] := UTF8Copy(astr, idx, len);
    end;
  end;
end;

然后用 TextOut 畫出來就行了,這里需要多加一個行高的變量:

with Canvas do begin
    Pen.Color := clBlack;
    Brush.Style := bsClear:
    lines := text2Lines(Canvas, str, rect);
    for i:= 0 to Length(lines) - 1 do begin
      TextOut(x, y + lineHeight * i, lines[i]);
    end;
  end;

到此,在所有的平臺上得到的效果均是相同的了。以上問題已在 CodeTyphon 論壇予以反饋,希望能得到官方的重視,不過說到底,還是自己動手解決來得快,不能懶啊。

這個修改同樣可以被編譯到 Android 以及 iOS 平臺,具體的編譯方法就不細說了,我懶(無意中打了臉)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 2016.10.27-- 到手葉片有一點兒損傷,修根、護花神溶液浸泡、晾根。 2016.11.12上盆,發(fā)了一點根...
    貓與多肉閱讀 191評論 0 0
  • 永平里就在馬路對過,以前邊上大樓還沒造起來的時候,家里的西窗望出去就可以看到永平里的水塔。很小的時候大人就告訴我永...
    XiaoyuWang閱讀 1,198評論 0 1
  • 【日更109】 本期《奇葩說》討論的辯題是:“大家誤會我是老板的關(guān)系戶,我要不要澄清?” 討論范圍嚴格限定在“職場...
    唐斬2086閱讀 1,022評論 0 1
  • 早上開計劃會,會上就方案和小伙伴們發(fā)生了很激烈的討論,當聽到大家的一些質(zhì)疑和反對的聲音時,我的心里是有很強烈的抵抗...
    玉露君閱讀 702評論 0 1
  • 周末推薦一部讓人輕松愉快的片子,我推片子遵循的基本原則是,我自己看過兩遍或者有可能看兩遍,也就是,一定能夠吸引我的...
    若愚D(zhuǎn)S閱讀 409評論 0 0

友情鏈接更多精彩內(nèi)容