標籤:text height class 源碼下載 顯示 canvas 多邊形 object monkey
原由說明:
之前使用 Obj-C 開發 iOS 的 App 時,使用幾何繪圖是家常便飯,品質更是好的沒話說,因跨平台需求,轉用 Delphi Firemonkey 來開發,它的跨平台能力還算滿意(一份代碼及介面可以輕鬆跨四個平台),唯獨移動平台在幾何繪圖方面,品質總是不盡人意,我也曾試著去修正(如:修正曲線平滑問題),也曾找過第三方案(如:AggPas),但始終不完美,我一直在想,移動平台有這麼強的繪圖能力及品質,如果能直接拿來用,不是很好?為什麼 Firemonkey 要自己重寫(移動平台線段處理計算單元在 FMX.StrokeBuilder.pas 有興趣可以自己研究,品質問題可能就出在這裡?!)?
實做方法:
大家都喜歡簡單,如果能不更動原來繪圖代碼,只要加入幾行代碼,或編譯開關,那是最理想的,就以這個構想出發,做出了目前的原生繪圖方案:
procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);var Rect, DesRect: TRectF;begin Rect := PaintBox1.LocalRect; Canvas.Stroke.Thickness := 10; Canvas.Stroke.Kind := TBrushKind.Solid; Canvas.Stroke.Dash := TStrokeDash.DashDotDot; // 距形 DesRect := Rect; InflateRect(DesRect, -(Canvas.Stroke.Thickness / 2), -(Canvas.Stroke.Thickness / 2)); // 線在區內 Canvas.FillRect(DesRect, 30, 30, AllCorners, 1); Canvas.DrawRect(DesRect, 30, 30, AllCorners, 1);end;
| 說明 |
Android |
iOS |
Windows |
macOS |
上面的代碼,使用 FMX 繪圖方法 (移動平台是有問題的) |
|
|
|
|
下面的代碼,使用原生繪圖方法 (四個平台全部相同了) |
|
|
|
|
下面改成原生繪圖方案,只要在原有絵圖代碼前後加入二行代碼(原繪圖代碼不用更動,但某些情況不一定):
{$i NativeDraw.inc}uses FMX.Graphics.Native,procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);var Rect, DesRect: TRectF;begin Rect := PaintBox1.LocalRect; Canvas.Stroke.Thickness := 10; Canvas.Stroke.Kind := TBrushKind.Solid; Canvas.Stroke.Dash := TStrokeDash.DashDotDot; {$IFDEF UseNativeDraw}Canvas.NativeDraw(Rect{注意:請勿在昵名函數裡改變它}, procedure begin {$ENDIF} // 原生繪圖 by Aone, 昵名函數裡加入繪圖方法, 內部會先畫到 Bitmap // 距形 DesRect := Rect; InflateRect(DesRect, -(Canvas.Stroke.Thickness / 2), -(Canvas.Stroke.Thickness / 2)); // 線在區內 Canvas.FillRect(DesRect, 30, 30, AllCorners, 1); Canvas.DrawRect(DesRect, 30, 30, AllCorners, 1); {$IFDEF UseNativeDraw}end);{$ENDIF} // 原生繪圖 by Aone, 結束後會顯示這個 Bitmapend;
實作原理:
- 它的原理很簡單,就是先配置一個原生的繪圖區域 Bitmap,再將幾何圖形畫在這個地區裡,最後將這個地區裡的內容,轉回 TBitmap,再顯示到 Canvas 裡
- 這種方法僅是一種變通方式,建議用在需要高品質的繪圖上,才不會影響程式整體的效能
已實做 Canvas 函數:
| DrawLine |
畫線 |
| FillRect |
圓距區 |
| DrawRect |
圓距框線 |
| FillPath |
路徑區 |
| DrawPath |
路徑框線 |
| FillEllipse |
橢圓區 |
| DrawEllipse |
橢圓框線 |
| FillArc |
孤線區 |
| DrawArc |
孤框線 |
| FillPolygon |
多邊形區 |
| DrawPolygon |
多邊形框線 |
| IntersectClipRect |
相交剪裁區 |
| ExcludeClipRect |
其它剪裁區 |
塗色及線色筆刷:
已知問題:
- 未完成的函數功能及特性,歡迎大家一起完善
- 真機 iOS 64bit 無法顯示虛線(虛擬機器沒問題)(原因不明,TMS iCL 控制項也有此問題)
- 幾何繪圖只有在移動平台 Android & iOS 上有問題,Windows & macOS 沒有問題
參考資料:
- https://sourceforge.net/projects/dpfdelphiios/
- https://sourceforge.net/projects/alcinoe/
- http://www.applyingcode.com/
源碼下載:(預計年後分享)
[原創] Firemonkey 解決 Canvas 幾何繪圖品質問題(移動平台)