2011-04-05 21 views
11

C++ 'da sadece vanilla Win32 API'sini kullanarak bir metin düzenleyicisi uyguluyorum ve sözdizimi vurgulamanın uygulanmasının en iyi yolunu bulmaya çalışıyorum. Orada scintilla gibi mevcut kontroller olduğunu biliyorum, ama bunu eğlenmek için yapıyorum, bu yüzden işin çoğunu kendim yapmak istiyorum. Ayrıca hızlı ve hafif olmasını istiyorum.Win32 API'sinde biçimlendirilmiş metin çizmenin en hızlı yolu nedir?

Şimdiye kadar öğrendiklerimden, GDI metninin çiziminde en düşük seviye seçeneğinin TextOut işlevi olduğu anlaşılıyor. Ancak, yazı tipi rengini değiştirmeye devam etmem gerekirse, o zaman karışık biçimlendirmeyle bir metin metni çizmek için TextOut numarasına çok sayıda çağrı yapmam gerekecek demektir. Bu verimsiz mi? Sözdizimi vurgulama ve zengin metin denetimleri uygulandığında, sahnelerin ardında TextOut'u kullanacaklar mı yoksa başka bir yolu var mıdır? GDI'da metin çizmenin diğer her yöntemi, TextOut etrafında daha yüksek düzeyli bir sarmalayıcı mıdır?

+1

Doğru yapmak zaten zor bir iştir. [Uniscribe ile Metin Gösterimi] (http://msdn.microsoft.com/en-us/library/dd317792.aspx) adresinize girmeniz gereken sorunlara iyi bir giriş niteliğindedir. – MSalters

cevap

13

Hem DrawText hem de TextOut, ExtTextOut için sarmalayıcılardır, bu nedenle ExtTextOut düşük düzeyli API'dir. Benim deneyimime göre, ExtTextOut oldukça hızlı, bu yüzden ExtTextOut'un kendisi ile ilgili herhangi bir performans sorunu göreceğinizden şüpheliyim. Ancak, yazı tipleri oluşturmak/seçmek bir performans sorunu kaynağı olabilir, bu nedenle fontlar arasında ileri ve geri geçiş yaparsanız, her seferinde CreateFont/SelectObject/DeleteObject yerine fontları (HFONT) önbelleğe alarak ve yeniden kullanarak önemli performans kazanımları elde edebilirsiniz. Temel olarak, yeni bir yazı tipi oluşturduktan sonra SelectObject'i ilk kez çağırdığınızda, Windows, istediğiniz mantıksal yazı tipi için en iyi fiziksel yazı tipini bulmak üzere bir font eşleştirme işlemini gerçekleştirir. Bu oldukça karmaşık bir süreçtir, bu nedenle performansın önemli olduğu durumlarda gerçekleşen süreyi en aza indirmek istersiniz.

Uzun yıllar önce Microsoft Word'ün küçük bir sürümü olan zengin bir düzenleme denetimi geliştirdim. ExtTextOut'u tüm metin çıktıları için ana çalışma olarak kullandım. Kontrol, en son kullanılan yazı tiplerinin bir yazı tipi önbelleğini koruyacaktır (varsayılan önbellek boyutu 10 yazı tipidir). WYSIWYG mizanpajını destekledi, bu yüzden bir yazıcı DC'si ve yazı tiplerini kullanarak tüm düzenleri yapıyordu, daha sonra bir ekran DC ve benzeri yazı tiplerini kullanarak ekran uyumlu bir sürüm oluşturuyordu, bu yüzden fazladan bir iş çıkmayacaktı. senin durumun. Öyle olsa bile, performans günün tipik donanımında mükemmel bir şekilde çalışıyordu (ör. 266 mhz Pentium). Yerine düşünürken ait

+2

Tamamen doğru değil. Örneğin, 'ExtTextOut', API’nin Uniscribe gibi kullanıyor. Ve bu da sizin için yazı tipi değişimi yapabilir. Yani, "düşük" düzeyli API'yi arıyorsanız, Uniscribe daha iyi olabilir. [ScriptItemize'] gibi ilkel özelliklere sahiptir (http://msdn.microsoft.com/en-us/library/dd368556.aspx) "Bir Unicode dizesini tek tek şekilli öğelere ayırır." – MSalters

+4

@MSalters: ExtTextOut'un Uniscribe API'lerini kullanabileceği doğrudur, ancak Uniscribe, gerçek görüntülemeyi yapmak için ExtTextOut'a geri çağırmayı sona erdirir; bu nedenle, hala ExtTextOut'un "the" düşük düzeyli API olduğunu iddia ediyorum (ayrıntılar için bu bağlantıya bakın: [ www.catch22.net/tuts/neatpad/11](http://www.catch22.net/tuts/neatpad/11)). Bununla birlikte, Uniscribe, işlevsellik açısından daha iyi bir seçenek olabilir, ancak metin çizmenin "en hızlı yolu" ExtTextOut'dur. – cbranch

+0

"DrawText ve TextOut, ExtTextOut için sarmalayıcılardır": Bu, Windows 7 için doğrudur, ancak Windows XP'ye uygulanmaz. Bunun dışında PolyTextOut, ExtTextOut'a çağrı yapmayan tek metin çizim API'sidir. PolyTextOut'un hızını test etmek ilginç olabilir. – Elmue

1

Karmaşık kullanım için, TextOut'dan daha fazla denetim sağladığı için muhtemelen DrawText olmasını istersiniz. Bazı temel biçimlendirme desteklerine sahiptir, ancak bir editör için gerekenden daha azdır. Bir sonraki adım, ortak kontrol kütüphanesinden gelen zengin metin editörüdür.

+1

'DrawText' yalnızca 'TextOut' etrafında bir sarıcı işlevi gören bir kolaylık işlevi midir yoksa tamamen ayrı mı? Bazı çok basit testler yaptım ve 'TextOut''un fark edilir derecede hızlı olduğunu keşfettim. Riched32.dll RICHEDIT pencere sınıfı gibi zengin düzenleme denetimleri farkındayım, ancak düşük düzey işlevleri kullanarak mümkünse zengin metin denetimi uygulamak istiyorum. –

+1

Win32 API'leri çoğunlukla bir "kara kutu", ancak bir meta dosyasına "DrawText" çağrıları kaydedip incelerseniz, ExtTextOutW için bir çağrı dizisi görürsünüz. –

7

hangi ne konuda akıllı kalarak, işlevi "nasıl her de işlemek zorunda metin miktarını en aza indirebilir", dikkate alınması gereken muhtemelen çok daha avantajlı olduğunu, en hızlı "metnini çizmek" Metin değişiklikleri olarak yeniden çiz/geçersiz kıl veya kaydırma için işlenmiş metni nasıl önbelleğe alabilir.

+0

İlginç bir nokta. Önbelleklemeye bakmamıştım. Fikir için teşekkürler. –

+2

Bu, sorunun cevabı değildir. Örneğin bir pencereye veya bir ListBox'a büyük bir günlük çıkışı çiziyorsanız, tekrar kullanılabilecek veya atlanabilecek hiçbir şey yoktur. – Elmue

İlgili konular