Pitfalls of transparent rendering of anti-aliased fonts


Windows provides a variety of technologies for rendering monochrome text on color displays, taking advantage of display characteristics to provide smoother results. These include grayscale anti-aliasing as well as the more advanced ClearType technique. Both of these methods read from the background pixels to decide what pixels to draw in the foreground. This means that rendering text requires extra attention.

If you draw text with an opaque background, there is no problem because you are explicitly drawing the background pixels as part of the text-drawing call, so the results are consistent regardless of what the previous background pixels were. But if you draw text with a transparent background, then you must make sure the background pixels that you draw against are the ones you really want.

The most common way people mess this up is by drawing text multiple times. I've seen programs which draw text darker and darker the longer you use it. We'll see here how this can happen and what you need to do to avoid it. Start with the scratch program and make these changes:

HFONT g_hfAntialias;
HFONT g_hfClearType;

BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
 g_hfAntialias = CreateFont(-20, 0, 0, 0, FW_NORMAL, 0, 0, 0,
    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
    ANTIALIASED_QUALITY, DEFAULT_PITCH, TEXT("Tahoma"));
 g_hfClearType = CreateFont(-20, 0, 0, 0, FW_NORMAL, 0, 0, 0,
    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
    CLEARTYPE_QUALITY, DEFAULT_PITCH, TEXT("Tahoma"));
 return g_hfAntialias && g_hfClearType;
}

void
OnDestroy(HWND hwnd)
{
 if (g_hfAntialias) DeleteObject(g_hfAntialias);
 if (g_hfClearType) DeleteObject(g_hfClearType);
 PostQuitMessage(0);
}


void MultiPaint(HDC hdc, int x, int y, int n)
{
 LPCTSTR psz = TEXT("The quick brown fox jumps over the lazy dog.");
 int cch = lstrlen(psz);
 for (int i = 0; i < n; i++) {
   TextOut(hdc, x, y, psz, cch);
 }
}

void
PaintContent(HWND hwnd, PAINTSTRUCT *pps)
{
 int iModePrev = SetBkMode(pps->hdc, TRANSPARENT);
 HFONT hfPrev = SelectFont(pps->hdc, g_hfAntialias);
 MultiPaint(pps->hdc, 10,  0, 1);
 MultiPaint(pps->hdc, 10, 20, 2);
 MultiPaint(pps->hdc, 10, 40, 3);
 SelectFont(pps->hdc, g_hfClearType);
 MultiPaint(pps->hdc, 10, 80, 1);
 MultiPaint(pps->hdc, 10,100, 2);
 MultiPaint(pps->hdc, 10,120, 3);
 SelectFont(pps->hdc, hfPrev);
 SetBkMode(pps->hdc, iModePrev);
}

This program creates two fonts, one with anti-aliased (grayscale) quality and another with ClearType quality. (I have no idea why people claim that there is no thread-safe way to enable ClearType on an individual basis. We're doing it just fine here.)

Run this program and take a close look at the results. Observe that in each set of three rows of text, the more times we overprint, the darker the text. In particular, notice that overprinting the anti-aliased font makes the result significantly uglier and uglier!

What went wrong?

The first time we drew the text, the background was a solid fill of the window background color. But when the text is drawn over itself, the background it sees is the previous text output. When the algorithm decides that "This pixel should be drawn by making the existing pixel 50% darker," it actually comes out 75% darker since the pixel is darkened twice. And if you draw it three times, the pixel comes out 88% darker.

When you draw text, draw it exactly once, and draw it over the background you ultimately want. This allows the anti-aliasing and ClearType engines to perform their work with accurate information.

The programs that darken the text are falling afoul of the overprinting problem. When the programs decide that some screen content needs to be redrawn (for example, if the focus rectangle needs to be added or removed), they "save time" by refraining from erasing the background and merely drawing the text again (but with/without the focus rectangle). Unfortunately, if you don't erase the background, then the text ends up drawn over a previous copy of itself, resulting in darkening.

The solution is to draw text over the correct background. If you don't know what background is on the screen right now, then you need to erase it in order to set it to a known state. Otherwise, you will be blending text against an unknown quantity, which leads to inconsistent (and ugly) results.

If you keep your eagle eyes open, you can often spot another case where people make the overprinting mistake: When text in a control (say, a check box) becomes darker and darker the more times you tab through it. This happens when programs don't pay close attention to the flags passed in the DRAWITEMSTRUCT that is passed to the WM_DRAWITEM message. For example, some people simply draw the entire item in response to the WM_DRAWITEM message, even though the window manager passed the ODA_FOCUS flag, indicating that you should only draw or erase the focus rectangle. This is not a problem if drawing the entire item includes erasing the background, but if you assume that the WM_ERASEBKGND message had erased the background, then you will end up overprinting your text in the case where you were asked only to draw the focus rectangle. In that case, the control is not erased; all you have to do is draw the focus rectangle. If you also draw the text, you are doing what the MultiPaint function did: Drawing text over text, and the result is text that gets darker each time it repaints.

Comments (41)
  1. Adam says:

    Sorry for the off-topic, but:

    “I have no idea why people claim that there is no thread-safe way
    to enable ClearType on an individual basis. We’re doing it just fine
    here.”

    According to the linked post, the person was not making the
    non-thread-safe claim himself, but was instead claiming that the MSDN
    docs authoritatively stated it was not thread-safe (although there is
    no link to the alleged page).

    In any case, how is saying “We’re doing it just fine here” any
    different from yesterday’s post when one person’s way of doing
    something (in this case, changing the monitor power settings) happened
    to work for him, no matter what the documentation might have happened
    to say broadcasting random messages all over the place?

    _Especially_ for code that might have threading issues?!? Of all
    the places where “it seems to work fine at the moment” can never be
    an indicator of anything, multithreaded code is surely it.

    [It’s just fine here because I didn’t just make up random parameters to see what happened. I followed the documentation. -Raymond]
  2. Ben Ryves says:

    The Windows Media Player 11 beta suffers pretty badly from this problem. Here’s hoping that the developers read your blog :)

  3. Eden says:

    OFF TOPIC:

    Raymond, please do a write-up covering this:

    http://www.wincustomize.com/articles.aspx?aid=117870&c=1

    Just tried it and it works.  Any idea what the back story is?

    [I’m going to say it again: To suggest a topic, use the suggestion box. (Besides, I already covered this topic. I’ll leave it as an exercise for you to find it.) -Raymond]
  4. xix says:

    @eden

    I get some sort of asian looking script (Chinese, Japanese, not sure).  Looks like notepad has a hard time working out what kind of encoding to use with that series of bytes.  Michael Kaplan’s blog had something about this (not this specific case) once if I recall correctly.

  5. Malcolm says:

    @Eden

    I would guess that notepad is using IsTextUnicode to determine the encoding of the file in question, which is   getting it wrong because there isn’t enough data to perform a reliable statistical analysis (it seems to think it’s UTF16 rather than ANSI).

    If you load notepad, choose File->Open and select ANSI encoding before loading the file, it will display correctly.

  6. Dirk says:

    An interesting question is how  LVM_CREATEDRAGIMAGE does the text drawing for anti-aliased fonts (for ClearType it does not draw any text). Do they translate the colour blending to alpha blending?

  7. BradC says:

    For the search-impaired, here’s the article Raymond alluded to:

    http://blogs.msdn.com/oldnewthing/archive/2004/03/24/95235.aspx

  8. KJK::Hyperion says:

    Adam: "not thread safe" refers to the dubious practice of enabling/disabling the global ClearType setting (using SystemParametersInfo) for the duration of the painting operation, which is a criminally lazy way to enforce ClearType without changing your CreateFont calls that use DEFAULT_QUALITY. I find it hard to believe Internet Explorer 7 does this

  9. BryanK says:

    It’s just fine here because I didn’t just make up random parameters to see what happened.

    I think the confusion is related to the difference between creating a ClearType-capable font, and enabling/disabling ClearType on the entire system.  I would guess that if ClearType is disabled, the call you made with CLEARTYPE_QUALITY would return a non-ClearType HFONT, right?  (Or would it fail?)

    Either way, you’re not enabling/disabling system ClearType support for your program, you’re just creating an HFONT that either asks for it or doesn’t.

    If “disabling ClearType support in your program” is implemented by “disabling ClearType for the entire system for a short period of time”, then yes, I can see where there’d be horrible race conditions there.  But that’s not what you’re doing in this code, either.

    [“If neither ANTIALIASED_QUALITY nor NONANTIALIASED_QUALITY is selected (in CreateFont), the font is antialiased only if the user chooses ‘smooth screen fonts’ in Control Panel.” Feel free to confirm whether the documentation is correct by writing a test program. -Raymond]
  10. Koro says:

    The wireless connection dialog is guilty of this too (at least when using Windows Classic), look at the links on the left, some of them become darker with time, but revert back to normal when hovered.

  11. Dewi Morgan says:

    “(I have no idea why people claim that there is no thread-safe way to enable ClearType on an individual basis. We’re doing it just fine here.)”

    My guess? They claim it because there is no thread-safe way to enable ClearType on an individual basis.

    That there is a thread-safe way to USE cleartype, once it is enabled, was never in dispute.

    But I dunno, maybe that’s not the rigth page. MSDN is an impenetrable mess in which I can never find what I want since it has no sensible index or navigable tree. I can’t prove the nonexistence of a solution in there any more than I can prove the nonexistence of an invisible pink unicorn.

    This is why people try posting messages to every window they can find: because finding the Right Way in MSDN is not feasible.

    [??? I just did it. The documentation says that if you pass CLEARTYPE_QUALITY then yuo get ClearType (assuming the font supports it). The control panel setting is used if you pass DEFAULT_QUALITY. The docs say that too. I just turned off ClearType in the control panel and ran my app – the ClearType font was still ClearType. What am I missing? I must be misunderstanding what people are saying because I’ve already pointed to the documentation saying how it works, written a program demonstrating that it works, and people still say it doesn’t work. -Raymond]
  12. Cooney says:

    From reading this, I can see why Apple went with Quartz. Should be interesting to see if the Vista stuff fixes these problems.

    [How can the operating system “fix” this problem? -Raymond]
  13. Mike Capp says:

    Raymond, I’m not disputing what you’re seeing, or what the docs say, but for some people it really doesn’t work. I spent a fair amount of time trying to get this to work the way it’s supposed to, and it consistently didn’t. Quality always seems to be the lower of the global setting and the CreateFont param; I’ve just reconfirmed this now. My plaintive query (unanswered, alas) on the topic is here with more details:

    http://groups.google.com/group/microsoft.public.win32.programmer.gdi/msg/c70a073ac358a708

    Maybe a daft question, but are you definitely seeing non-smoothed fonts elsewhere after turning off ClearType? It doesn’t take effect until you OK the whole Display Properties dialog, not just the Effects popup. Otherwise, I give up. SDK bug that was fixed in a later version? Driver bug?

    [When I disabled ClearType in the control panel and hit √úbernehmen, my fonts went ugly. Then I ran the test app and it still used the smoothed fonts (since it overrode the default). -Raymond]
  14. Cooney says:

    [How can the operating system “fix” this problem? -Raymond]

    Simple – offer better primitives and handle window compositing in the GUI rather than expect apps to do so. It also helps that Quartz is firly well designed, and the GDI is kind of awful (comes from supporting 15 years of legacy, I suppose).

    [Window composition won’t do anything here, since it’s all happening inside a single window. A single window is being asked to paint, and it does so via overprinting. Or would the new primitives somehow disallow overprinting? -Raymond]
  15. BryanK says:

    I just turned off ClearType in the control panel and ran my app – the ClearType font was still ClearType. What am I missing?

    I’m not positive exactly what people are talking about with this issue, but it seems to me that they’re trying to find a way to (1) have ClearType turned on in the control panel, but still (2) get an HFONT that has ClearType disabled.  (Since that’s one thing that an app-specific setting would require.)

    Someone named Xepol, in an IE blog comment, has asserted that "according to the MSDN site", the only way to get that font is by disabling the global ClearType setting, calling CreateFont (with DEFAULT_QUALITY, probably), and re-enabling the setting.  But according to you and the docs, you can get one by passing NONANTIALIASED_QUALITY to CreateFont, or possibly also ANTIALIASED_QUALITY (I don’t know if there’s a difference between an AA’ed font and a ClearType font).

    (If I were writing a Win32 program, I’d just pass DEFAULT_QUALITY, and use the system ClearType setting…  but that’s a separate issue.)

    (Basically, I’m agreeing with the parenthetical in your post here; it sounds like there is a way to thread-safely disable ClearType, although you might also have to disable all AA for your font in the process.  The post that was linked to by the suggestion-box post you linked to, though, was just someone claiming that "MSDN says" you can’t do that.  I doubt that claim is correct, though I don’t know for sure.)

  16. Cooney says:

    My mistake – I thought this was an interaction between AA fonts and transparent windows.

  17. Mike Capp says:

    BryanK – no, the issue is exactly the opposite of what you describe. We’re trying to get a ClearType-enabled HFONT when ClearType is disabled in the control panel.

    [And I tested that scenario as I remarked earlier. This is all clearly documented: The control panel setting is used only if you ask for DEFAULT_QUALITY. If you specify an explicit quality then you get that quality (assuming the font supports it). -Raymond]
  18. Knowbody Nos says:

    Make sure you’re running this on XP as I believe ClearType is not supported on 2K.

  19. Gabe says:

    As far as I can tell, WPF would allow you to create this annoying effect, but since it handles all painting it would prevent this from happening by accident. The new window manager may even prevent it from happening by accident with GDI apps.

    [True, switching to a declarative model instead of a procedural one would avoid this problem since the app doesn’t actually control the painting any more. But that’s not “offering better primitives”; that’s radically changing the painting model. -Raymond]
  20. Mike Capp says:

    Knowbody Nos: Yes, this is XP.

    Raymond: I know it sounds that way, but this honestly isn’t a reading comprehension issue :-)

    Some more info though: I tried your test app and it works as advertised. I tried vanilla TextOut to the window DC in my own paint handler (not something I normally do), and that’s fine too. What was not fine, and still isn’t fine even with the exact same CreateFont call, is TextOut to a memory DC created via CreateCompatibleDC, even though ClearType is manifestly possible on this DC because it works when enabled globally.

    Ah well. Something new for me to chew on, at any rate.

    [Aha, so that’s the difference. I have no idea why memory DCs behave strangely. -Raymond]
  21. Andy "Down" says:

    Btw, I love your new yellow inline comments, Raymond. Thanks for being so patient with us!

  22. rsclient says:

    Raymond,

    The documentation is not a model of clarity.  

    DOCUMENTATION: “If neither ANTIALIASED_QUALITY nor NONANTIALIASED_QUALITY is selected, the font is antialiased only if the user chooses “smooth screen fonts” in Control Panel. ” [in CreateFont]

    REALITY: if CLEARTYPE_QUALITY is chosen, the font will be antialised (if possible) despite the control panel.

    WHY: because the documentation was not properly updated when XP came out.  Cleartype is a type of antialiasing, but it still isn’t fully integrated into the documentation.

    (also, the control panel doesn’t say “smooth screen fonts” — at least, not any more.  It says, “smooth edges of screen fonts” and gives the choice of nothing, Standard, or ClearType.)

    [Aha, my eyes saw what should have been there. I’ll submit a correction to the MSDN folks. -Raymond]
  23. rsclient says:

    Raymond,

    The model that Windows uses for drawing on the screen is not universally used by all windows system.  The VAX windowing system, for example, had the very handy feature that once you drew on the screen once, you didn’t have to redraw it — ever.   If you wanted to change the screen, you just changed it.

    It’s not a change of primitives; it’s a change in who “owns” the job of handling overlapping wndows.  Some systems decided that it was a job that could be done by the window system; others decided that it was too hard, and gave it back to the individual programs.

    The VAX system, BTW, had a neat feature: if you had a mostly-bare window, it would remember all of the drawing commands you used to make it; as the screen got more complicated, the window system would automatically start saving your window as a bitmap instead.

    IMHO, the VAX windowing model was better.  In many Microsoft Windows programs, a lot of time is spent ‘remembering’ just what’s on the screen — thus, a basic cycle is to calculate a certain amount about what should happen, and store it in a unique-per-application structure.  When the application gets a ‘paint’ message, it must then paw through that structure and paint it.

    To me, it’s a pain.  It means I have to chop up every action into two pieces, and keep around a bunch of context just to make things happen.  The context, in turn, has to be managed.  It’s a lot easier to ‘just draw something’ and move on.

    Peter

    [Even with the VAX model, overprinting text would have the same problems we’re seeing here. -Raymond]
  24. Norman Diamond says:

    [Aha, so that’s the difference. I have no

    > idea why memory DCs behave strangely.

    > -Raymond]

    Here’s a guess.  Some internal function is retrieving pixels from screen’s DC, or maybe assuming a value of zero or some other default, instead of retrieving pixels from the memory DC.  Then it computes results based on the incorrectly assumed initial values.

    Wednesday, June 14, 2006 9:00 PM by rsclient

    > IMHO, the VAX windowing model was better.

    Yes, because it didn’t have to maintain compatibility with Windows 3.1, i.e. didn’t have to maintain compatibility with a system that could run in 2MB of RAM (and which by the way didn’t exist yet at the time the VAX windowing model was designed ^_^).

  25. ping and pong says:

    @Dewi Morgan: you claim the following at your website:

    "MorganAlley’s people bring decades of experience with websites and the Internet"

    Decades is plural, making it no less than 20 years. You *really* designed websites back in 1986?

    J

  26. Sarath says:

    Hi,

    Is there any way to prevent this?

  27. Sarath says:

    Hi,

    Is there any way to prevent this?

  28. Dave Harris says:

    BryanK: "(If I were writing a Win32 program, I’d just pass DEFAULT_QUALITY, and use the system ClearType setting…  but that’s a separate issue.)"

    It depends on why you are drawing. I have some library code which draws to a bitmap, and sometimes that bitmap goes directly onto the window (it is a back-buffer) and sometimes it gets exported as a .BMP file. In the latter case I don’t want ClearType. ClearType uses sub-pixel positioning on an LCD screen. The .BMP may end up on a CRT screen or a printer, and ClearType looks poor there.

  29. Dave Van den Eynde says:

    Of course you don’t get anti-aliasing this way, because you’re doing all the rasterization yourself. Perhaps you need a bit of Anti Grain Geometry (http://www.antigrain.com).

  30. Mike Capp says:

    Not sure if anybody still reads these comments a day later, but for the benefit of any future Googlers I tracked down the problem described earlier. And hey, it’s not as if the Microsoft blogging community has anything else to talk about this evening.

    The problem turned out to be an (arguably) undocumented precondition of GetTextMetrics. When you call this function with a memory DC, you MUST have already selected a bitmap into that DC. Otherwise, antialiasing for the selected font is forced down to the worse of the font and global settings. Thus, with ClearType disabled globally, a memory HDC and a ClearType-enabled HFONT:

      SelectObject(hdc, hfont);
      SelectObject(hdc, hbitmap);
      GetTextMetrics(hdc, &tm);

    gives you ClearType text, and

      SelectObject(hdc, hfont);
      GetTextMetrics(hdc, &tm);
      SelectObject(hdc, hbitmap);

    doesn’t.

    Quite why this should be, I’ve no idea. The CreateCompatibleDC docs talk about needing a bitmap for drawing ops, but GetTextMetrics is hardly a drawing op. The same docs mention that the default drawing surface is monochrome, but if that were the deciding factor I’d expect ClearType to be disabled regardless of the global setting, and it isn’t.

    In any case, it’s trivial to work around. Mildly annoying, since I was using the results of GetTextMetrics to calculate the size of bitmap needed, but recreating and reselecting the font before drawing works fine. A dummy bitmap would probably also do the trick.

    [It is documented, though not in so many words. A fresh DC comes with a bitmap pre-selected: a 1×1 monochrome bitmap. And of course you can’t do anti-aliasing with a monochrome bitmap. I knew that this would happen but assumed that you wouldn’t have been so crazy to have selected a monochrome bitmap and then expected anti-aliasing to work… It hadn’t occurred to me that the problem was that you forgot to select your bitmap at all. -Raymond]
  31. Mike Capp says:

    Raymond:

    I think you misread my post. The problem was with GetTextMetrics, not TextOut. Obviously, I was selecting a bitmap before doing any drawing, or I wouldn’t have seen any text, antialiased or otherwise.

    The questions are:

    1) Why does GetTextMetrics care whether I have a bitmap selected? Heck, from the description it should be possible to fill a TEXTMETRIC from just an HFONT, without even an HDC.

    2) Even if it does care, why is a “getter” function like GetTextMetrics  actively changing the state of a font? Reselecting the same HFONT afterwards did not correct the issue; it took another call to CreateFont.

    [It’s not GetTextMetrics that cares. It’s the SelectObject(…, hfont). Selecting an object into a DC causes it to become realized based on the attributes of the DC. And when you selected the font, the DC was monochrome. (I’ll let you guess why reselecting the font doesn’t have any effect. But you don’t need to destroy the font and re-create it. You just have to force the font to re-realize.) -Raymond]
  32. Mike Capp says:

    Ah, OK. Scratch question 1.

    “All sizes are specified in logical units; that is, they depend on the current mapping mode of the display context.” (TEXTMETRIC docs)

    [I thought I already answered question 2. GetTextMetrics doesn’t change the state of the font. SelectObject does. (Except when it doesn’t, which I left as an exercise.) -Raymond]
  33. Mike Capp says:

    No, that doesn’t fit. If that were the root cause, then the first sequence above wouldn’t have worked – select font, select bitmap, call GetTextMetrics – because the bitmap is still monochrome when the font is selected. And it does work; I’ve just checked, twice.

    And recall that I was getting ClearType when it was enabled globally, even when selecting the bitmap after BOTH selecting the font and calling GetTextMetrics.

    The page you linked was interesting; I hadn’t seen that material before. However, UnrealizeObject/SelectObject does not restore ClearType rendering. CreateFont/SelectObject does. There’s definitely something fishy going on.

    [Rats. Then i’m as baffled as you. Note that UnrealizeObject works only for palettes and brushes. I would try selecting a different font, then selecting the original back in. -Raymond]
  34. Mike Capp says:

    (Clarification, since I think server lag is confusing matters. My "scratch question 1" comment was a followup to my 7:42 post, not a reply to your comment on it.)

    Responding to your comment on my 8:39 post…

    The page you linked includes the following passage:

    "When an application changes the logical device mapping of a DC (by changing the mapping mode or the window or viewport definition), the system re-realizes the currently selected pen and font before they are used the next time."

    If selecting a bitmap into a memory DC counts as changing the logical device mapping, this would explain why I could get ClearType even though the DC was monochrome when the font was originally selected.

    I was already selecting a different font before trying UnrealizeObject/SelectObject, just to be on the safe side. Made no difference.

    Probably not much else to be said here; it really does look as though there is something rotten in the state of GetTextMetrics. Might justify a note in the MSDN docs. In any case, many thanks: I wouldn’t have discovered the specific problem and the workaround without the encouraging knowledge that this stuff was working for somebody somewhere.

  35. nksingh says:

    Avalon will generally fix this problem for new app developers who use it and I’m glad for that.

    I really wish it had an unmanaged interface.  Is there a good chance the shell will start using it in Vista++ (Vienna?)?

  36. Gabe says:

    BTW, one reason that GetTextMetrics would care about the bitmap is that it may return different results if ClearType is on. The antialiasing allows it to space letters more precisely, so a run of text may not be the same length on a monochrome bitmap as on a device bitmap.

  37. Ulric says:

    I had a lot of trouble getting Clear Type to work on my menu class, which draws to a memory DC. I remember searching thoroughly combing the documentation and not understanding why my ANTIALIASED did not work.  Since system menus where properly antialiased, and my tear off menus were not, they stood out.

    Now I look back at the file diff and I seems all I ended up doing was use PROOF_QUALITY for the antialiasing flag in the LOGFONT structure — instead of ANTIALIASED_QUALITY.  

    LOGFONT g_lfNormal ={ -11, 0, 0, 0, FW_NORMAL,FALSE, FALSE, FALSE,DEFAULT_CHARSET,

    OUT_STROKE_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH|FF_DONTCARE, _T("Tahoma")};

    With regards to extracting antialiasing font bitmaps with GetGlyphOutline, I have done this as well.  I needed this to generate a font bitmap to use in OpenGL.  But I am doing this ‘offline’ and generating a bitmap file, a mosaic of all ASCII character I need, which I ship with the app.  I didn’t need to go through that trouble, but I investigated using that.

    Using the bitmaps out of GetGlyphOutline is too much work guys, certainly don’t use use this if you want to draw on screen with it at runtime.

    If you want do to something forced antialiasing offscreen like this, I suggest using GDI to draw whatever you need at twice the size, and sizing down the bitmap with a good filter.  It will end up being a lot less image processing code than to apply that 64-shades-of-gray image onto your background.  

    Because once a filter is running and optimized, it runs fast and it scales well, no matter the complexity of the graphics elements or text you want to anti-alias.

  38. Dewi Morgan says:

    @ping and pong

    You write: "Decades is plural[…] You *really* designed websites back in 1986?"

    Thanks, I’ll pass your comment to our copy-writer: I suspect he counted "man-decades". Both directors began webdev work in ’93, and 1.3 "decades" each isn’t really "decades", even to href="">one significant figure</a> (except in the gramatical sense that pluralises any fraction).

    Back on topic:

    Raymond is clearly correct, and I clearly wrong (I should have tested his code before speaking!).

    Thank you for this post, Raymond: I’m writing a "transparent Java1.1 rich-text no-Swing textarea" at the moment (pointless, yes: so sue me!), and if Java respects the system ClearType settings, this "darkening" effect is definitely something I shall have to bear in mind.

  39. stories says:

    Your article is prety nice. It’s a pity that i didn’t see it more later.

  40. GregM says:

    Wow, I’m absolutely astonished.  One of the first things I do after installing Windows is turn off all the effects that just use up more CPU time and make it slower for the information I use  to appear.  Well, I turned on Clear Type today on my notebook (XP Pro SP2).  WOW!!!  I never realized how poorly the fonts looked before.  The letters are nice and crisp.  I was starting to have to squint at the letters, and was considering increasing my font size.  There’s no need for that now.  Even if this does take up some CPU time, I’m keeping it.  Raymond, thank you so much for bringing up this topic.

Comments are closed.