本文針對 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 平臺,具體的編譯方法就不細說了,我懶(無意中打了臉)。