2011-04-05 58 views
11

我正在C++中使用香草Win32 API實現文本編輯器,並試圖找到實現語法高亮的最佳方法。我知道有像閃爍石那樣的現有控制器,但我爲了好玩而做這個,所以我想自己完成大部分的工作。我也希望它快速輕量。什麼是在Win32 API中繪製格式化文本的最快方法?

從我迄今爲止所瞭解到的情況來看,它看起來像GDI中繪圖文本的最低級別選項是TextOut函數。但是,如果我需要不斷更改字體顏色,那麼這意味着我需要撥打TextOut以便以混合格式繪製一個文本主體。這是低效的嗎?當實現語法​​高亮和富文本控件時,他們可能會在幕後使用TextOut還是有其他方法?在GDI中繪製文本的其他方法只是圍繞TextOut的更高級別的包裝?

+1

獲得正確已經是一個挑戰。 [使用Uniscribe顯示文本](http://msdn.microsoft.com/en-us/library/dd317792.aspx)是您需要解決的問題的良好介紹。 – MSalters 2011-04-05 07:28:15

回答

13

DrawText和TextOut都是ExtTextOut的包裝器,因此ExtTextOut是低級API。根據我的經驗,ExtTextOut非常快,所以我懷疑你會看到ExtTextOut本身的任何性能問題。但是,創建/選擇字體可能是性能問題的一個來源,因此如果您在字體之間來回切換,則每次都可以通過緩存和重用字體(HFONT)而不是CreateFont/SelectObject/DeleteObject來實現顯着的性能提升。基本上,第一次在創建新字體後調用SelectObject時,Windows將執行字體匹配過程以找到您所請求的邏輯字體的最佳物理字體。這是一個相當複雜的過程,因此您希望將性能至關重要的情況下發生的次數降至最低。

許多年前,我開發了一個豐富的編輯控件,它本質上是微軟Word的一個迷你版本。我使用ExtTextOut作爲所有文本輸出的主要主力。該控件將維護最近使用的字體的字體緩存(默認緩存大小爲10個字體)。它支持所見即所得的佈局,所以它實際上是使用打印機DC和字體進行所有佈局,然後使用屏幕DC和類似的字體呈現屏幕兼容版本,因此有很多額外的工作可能不適用於你的情況。即使如此,當天的典型硬件(例如,266MHz的Pentium)上的性能也非常出色。

+2

這並不完全準確。例如,'ExtTextOut'反過來使用像Uniscribe這樣的API。而這又可能會爲你做字體替換。因此,如果您正在尋找「低級API」,Uniscribe可能會更好。它具有像['ScriptItemize'](http://msdn.microsoft.com/zh-cn/com/en-us/library/dd368556.aspx)「將Unicode字符串分解爲單獨的可形狀項目。」 – MSalters 2011-04-05 07:22:41

+4

@ MSalters:的確,ExtTextOut可能會使用Uniscribe API,但Uniscribe最終會調用ExtTextOut來完成實際渲染,所以我仍然會爭辯說ExtTextOut是「低級API」(請參閱​​此鏈接瞭解詳情:[[ www.catch22.net/tuts/neatpad/11](http://www.catch22.net/tuts/neatpad/11))。也就是說,Uniscribe在功能方面可能是更好的選擇,但繪製文本的「最快方法」是ExtTextOut。 – cbranch 2011-04-05 18:37:44

+0

「DrawText和TextOut是ExtTextOut的包裝器」:這對於Windows 7是正確的,但不適用於Windows XP。除此之外,PolyTextOut是唯一不會調用ExtTextOut的文本繪圖API。測試PolyTextOut的速度可能會很有趣。 – Elmue 2016-10-18 14:46:26

1

對於複雜的用法,您可能需要DrawText,因爲它可以提供比TextOut更多的控制。它有一些基本的格式支持,但比編輯器所需要的要少。下一步是來自公共控件庫的富文本編輯器,它幾乎爲您提供所有這些。

+1

'DrawText'只是一個方便的函數,它作爲'TextOut'的包裝器,還是完全獨立的?我做了一些非常簡單的測試,發現'TextOut'明顯更快。我知道豐富的編輯控件,例如Riched32.dll中的RICHEDIT窗口類,但我想盡可能使用低級函數來實現富文本控件。 – 2011-04-05 05:18:51

+1

Win32 API大多是一個「黑匣子」,但如果您將DrawText調用記錄到圖元文件並檢查它,您會看到一系列對「ExtTextOutW」的調用。 – 2011-04-05 17:57:49

7

而不是考慮哪個「繪圖文本」功能是最快的,考慮「我怎樣才能最大限度地減少我必須呈現在所有」的文本量,當文本更改時重繪/無效,或者如何緩存呈現的滾動文本。

+0

有趣的一點。我沒有考慮過緩存。感謝這個想法。 – 2011-04-05 15:37:40

+2

這不是問題的答案。例如,如果您將大型日誌輸出繪製到窗口或ListBox中,則沒有任何東西可以重複使用或省略。 – Elmue 2016-10-18 14:34:34

相關問題