{"id":145,"date":"2007-05-12T16:10:22","date_gmt":"2007-05-12T14:10:22","guid":{"rendered":" http:\/\/www.nsonic.de\/blog\/2007\/05\/fonts-anti-aliasing-text\/"},"modified":"2007-05-12T16:10:24","modified_gmt":"2007-05-12T14:10:24","slug":"fonts-anti-aliasing-text","status":"publish","type":"post","link":"https:\/\/www.nsonic.de\/blog\/2007\/05\/fonts-anti-aliasing-text\/","title":{"rendered":"Fonts: Anti-Aliasing Text"},"content":{"rendered":"<p><em>Of course it is slower than non-antialiased text. So it is important to<br \/>\noptimize the routine. Here is some part of the routine I use, it&#8217;s<br \/>\nprobably the part that&#8217;s most important to optimize (might be faster<br \/>\nwhen precalculating OfsPtr to an array?):<br \/>\n<\/em><br \/>\n<!--more--><br \/>\n[code lang=&#8221;delphi&#8221;]For OuterY := 0 To TextDIB.Height-1 Do Begin<br \/>\n        TextPtr := ResultBitmap.ScanLine[OuterY];<br \/>\n        InnerOffset := 0;<br \/>\n        For OuterX := 0 To TempBitmap.Width-1 Do Begin<br \/>\n          \/\/ get average color<br \/>\n          VSum := 0;<br \/>\n          For InnerY := 0 To Zoom2 Do Begin<br \/>\n            OfsPtr := TempBitmap.ScanLine[(OuterY SHL FQuality)+InnerY];<br \/>\n            For InnerX := 0 To Zoom2 Do Begin<br \/>\n              Inc (VSum,OfsPtr^[InnerOffset+InnerX]);<br \/>\n            End;<br \/>\n          End;<br \/>\n          \/\/ set pixel<br \/>\n          TextPtr^ := VSum SHR ShiftValue;<br \/>\n          \/\/ next pixel<br \/>\n          Inc (TextPtr);<br \/>\n          Inc (InnerOffset,FZoom);<br \/>\n        End;<br \/>\n      End;<br \/>\n[\/code]<\/p>\n<p>I guess I have to explain some variables. The quality is set by<br \/>\nFQuality, some variables that are used often are precalculated:<br \/>\n[code lang=&#8221;delphi&#8221;]  FZoom := 1 SHL FQuality;<br \/>\n  Zoom2 := FZoom-1;<br \/>\n  ShiftValue := FQuality SHL 1;<br \/>\nTempBitmap is FZoom times larger than ResultBitmap<br \/>\n[\/code]<\/p>\n<p>As I always draw the text to 8 bit bitmaps, OfsPtr = ^TByteArray where<br \/>\nTByteArray = Array[0..65535] of Byte. The result is 8 bit, too (so<br \/>\nTextPtr = ^Byte) because I use this result to combine it with the<br \/>\noriginal image by some other procedure. This is more flexible, because<br \/>\nyou have to calculate the result only once and can use it for colored<br \/>\ntext, its shadow and any other effect you can think of. Of course you<br \/>\ncan do this in one step, then you have to interpret black (or white) as<br \/>\ntransparent and grays as semi-transparent. The code would look like:<\/p>\n<p>[code lang=&#8221;delphi&#8221;]   VVal := VSum SHR ShiftValue;<br \/>\n   TextPtr^.Red := TextPtr^.Red+((SomeColor.Red-TextPtr^.Red)*VVal DIV 256);<br \/>\n   TextPtr^.Green := TextPtr^.Green+((SomeColor.Green-TextPtr^.Green)*VVal DIV 256);<br \/>\n   TextPtr^.Blue := TextPtr^.Blue+((SomeColor.Blue-TextPtr^.Blue)*VVal DIV 256);<br \/>\n[\/code]<br \/>\nBut I guess it&#8217;s not much slower when doing this in a second step where<br \/>\nVVal := TextPtr^ (the difference is that you save all VVals in<br \/>\nResultBitmap before you use them) and really much more powerful when<br \/>\nadding routines for effects like shadow, glow etc. to your routine.<\/p>\n<p>[tags]Delphi, Graphic, Fonts[\/tags]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Of course it is slower than non-antialiased text. So it is important to optimize the routine. Here is some part of the routine&hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":""},"categories":[11],"tags":[75,103,101],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p71Tml-2l","_links":{"self":[{"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/posts\/145"}],"collection":[{"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/comments?post=145"}],"version-history":[{"count":0,"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/posts\/145\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/media?parent=145"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/categories?post=145"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/tags?post=145"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}