Archive for February, 2004

LCD, ClearType™ & MS Sans Serif

In a long overdue move, I have recently upgraded my computer system. Along with a much faster CPU [and more RAM etc] I decided to shell out the extra money for a 17" LCD display, something I’ve been meaning to get for ages.

Boy, are these things sharp!

The problem is, at 1280 x 1024 – the native resolution for most 17" panels – the pixels are just so gosh-darn small and well defined that fonts which use single pixel stroke widths [eg Courier, MS Sans Serif] are uncomfortable to read at the default sizes. It seems weird but I think maybe a little bit of softening is not such a bad thing. Here is my impression of the difference between pixels on my old Sony 17" CRT and my new Hyundai 17" LCD [magnified 600%]:

CRT

LCD

See how the sharp version is a little too sharp, with the individual pixels drawing attention away from the letterforms themselves.

Enter ClearType™

Fortunately, Microsoft lets you enable ClearType on XP, meaning that spindly fonts on LCD displays become smooth and black again, without getting blurry. This is achieved by using a special form of antialiasing. Here’s how:

Standard

ClearType™

Note that the second example is softer and the letter shapes seem more "continuous". The pixel values here are chosen in a similar way to standard anti-aliasing , but have also been tinted as well. The reason for this can be seen in the next figure:

Standard
LCD

ClearType™
LCD

Here I have magnified not just the pixels, but the color sub-pixels of the display device itself [the individual Red, Green and Blue mini-pixels which constitute each full color pixel]. Note how the second example "sharpens up" again. This is because the colors for each whole pixel are chosen specifically with the RGB sub pixel units in mind. For example, if we want to color only the left side of a pixel black, and we know that the sub pixel components are arranged in RGB order, then we can set the pixel color to RGB(0, 128, 255). This is quite different to standard anti-aliasing, where we would average the value across the whole pixel, choosing RGB(128,128,128) instead. In this way ClearType [and equivalent methods] allows an effective tripling of horizontal resolution.

Visit this site for an extremely good description of both the theory and implementation behind this technique, as well as a downloadable demonstration program.

ClearType makes it all better? Not quite…

For any form of text anti-aliasing to work, we need to have the letterforms stored at a higher resolution than that at which they are being displayed. The best way to do that is to store them as shape descriptions rather than clumps of pixels. Most contemporary fonts are stored this way, including favourites like Times New Roman and Verdana. Collectively these fonts are referred to as vector fonts [TrueType™, OpenType™ and PostScript™ fonts are all examples™ of vector fonts], as opposed to the hand-pixelled variety which are known as raster or bitmap fonts .

WindowsXP uses Tahoma as its default font for dialogs and menus. Since Tahoma is a TrueType font it can be antialiased, and can take advantage of ClearType technology on LCD displays. Unfortunately, Tahoma is not one of the standard fonts included with Windows95/98, so developers don’t tend to use it for their applications. Instead, they will tend to use the default dialog font pre Win2000, which is MS Sans Serif .

And MS Sans Serif is a frikkin bitmap font.

This means that any app which uses this font will not benefit from having ClearType enabled. In general, this covers 90% of all Windows applications! [including mine, for now]. The upshot is, even though turning on ClearType will make your desktop and system dialogs look great on an LCD screen, you will still be seeing copious amounts of spindly pixellated fonts when using 3rd party applications. Only now they will look even worse because the user will be able to make a visual comparison between ClearType Tahoma used by the system and pixellated MS Sans Serif used by everything else.

Always Remember:

  • Use vector fonts (eg TrueType) wherever possible, because you never know what sort of hardware will be displaying your text. Take special care to avoid bitmap fonts on web pages, or anything that might need to be printed. [Eg: this site looks like crap on my new monitor, because it uses MS Sans Serif, instead of Microsoft Sans Serif, the TrueType version of the same font.]
  • If running on an LCD display, make sure that your desktop resolution matches your displays native resolution. If you run a 1024 x 768 desktop on a 1280 x 1024 LCD (125% scaling), you may get crappy pixel doubling and smudging effect, and using ClearType may actually make things look worse ! [although my LCD does do a surprisingly good job at this kind of scaling]

    100%
    ClearType

    125%
    ClearType
    bicubic filtering

    125%
    ClearType
    no filtering

  • If you’re a developer, bear in mind that the default font MS Sans Serif is NOT a TrueType font, and will not benefit from anti-aliasing, ClearType or related technologies. Also bear in mind that changing your application’s font can introduce whole new problems. Namely, if you are coding for Win98 or earlier, neither Tahoma nor Microsoft Sans Serif can be counted on to be present. It may be necessary to do a run-time check and set the font dynamically.*

__________

* UPDATE (28/2/05): Raymond Chen has some useful information for developers about getting the desired Windows2000 system font without screwing up under Win98, which avoids run-time checking hassles.

Short-circuits and the ternary operator

Recently I added support for the C-style ternary [I always say ‘trinary’] operator ?: to Jujuscript… it was just one of those things that I’d been putting off for years, but I finally did it [surprisingly painlessly]. The ?: operator creates a conditional-expression, allowing you to do the following:

return a ? b : c;

If a is ‘true’ here, then we return b, otherwise we return c. Without the ?: operator we would have to write:

if (a)
return b;
else
return c;

Neat, huh?

Short-circuiting

Since the ?: operator was a success, I then went on to add support for another aspect of C which I had been long ignoring: the short-circuiting && and || operators [also particularly neat].

Short-circuiting is a great feature of C/C++ which means that the minimum amount of processing is done in boolean expressions. Short-circuiting allows expressions like this to be used:

if (ob && ob->member == 1)
// do stuff

Here ob is first tested to see if it is non-NULL, and only if this is the case will its member be tested. Without short-circuiting this expression would cause an exception when ob is NULL, and so it would have to be replaced with the clumsier:

if (ob)
if (ob->member == 1)
// do stuff

Similarly, the logical-OR operator can simplify your code.

if (string == "end" || string == "eof")
// do stuff

In this example, if string is "end" then the second comparison is never performed, thus saving valuable clock cycles.

Beyond C…

In C, the && and || operators return boolean values only. So yes, they’re neat, but not as neat as they could be.

In Jujuscript [and Perl and Python and probably others] these operators actually return the last value evaluated. So (2 || 3) returns 2, and (2 && 3) returns 3 [whereas in C they would both simply return true]

This extra flexibility allows for constructs such as this:

return sz || "default"

In this example, if sz is non-NULL then sz will be returned, otherwise "default" will be returned. To achieve the same result in C you have to use the slightly less convenient form:

return sz ? sz : "default"

For a brief period of time, I actually thought these new operator behaviours might allow me to dispense with the ternary ?: operator [which I only just added…programmers love throwing away code, even if they’ve only just written it].

remember that although the syntax and operators are C-like, this is not C, and the && and || operators can return other types besides bool

return c ? (b=3) : (a=4);
return c && (b=3) || (a=4);

In this case the 2 forms produce exactly the same results (both will only modify a or b depending on the value of c, and return the new a or b). In spite of this, can you see why they are NOT equivalent? It took me a while to notice…

ANSWER: The two expressions are only equivalent if the value of the second component [in this case (b=3)] can be considered true. If it is not, the expression will "fall through" and return the value of the third component, regardless of the value of the test expression.

Inside Jujusoft – Part 1

Here at Jujusoft you’ll find only the most revolutionary software being developed and run on the latest hardware.

To the right you can see me teaching my computer the futility of war. [it turns out the only winning move is not to play ]

__________

UPDATE: Chris K follows up on this outburst of geeky nostalgia on his site, where you can find a link to download a Flash Tic-Tac-Toe screensaver! Mine is implemented in Jujuscript and is fairly thick [you can actually beat it occasionally, which means it plays about as well as I do].

Odd things about C/C++

  • There is no syntax for describing a number in binary notation. You can express a number in decimal [65], hexadecimal [0x41], octal [0101] or as a character-constant [‘A’], but there is no binary equivalent [eg 0b1000001]. Seriously, who needs octal more than binary?
  • The character-constant notation [‘A’] can contain more than 1 character, thus allowing a large base-256 number to be described (as long as characters used are legal within the c-char sequence). eg: the character sequence ‘AB’ equates to the decimal value 16706 [‘A’ * 256 + ‘B’]. Although it is of course very bad programming practise, this allows a sort of middle ground between evil magic numbers and annoying enums. Eg: you could return integer codes which are actually human readable to a degree (as long as they have no more than 4 characters) Examples: ‘ok’, ‘err’, ‘stop’, ‘play’ etc
  • When operator overloading is used on postfix operators [eg: T++] a dummy parameter is used to differentiate between postfix and prefix. This seems a bit like a quick hack that just got left in. So to override ++T we use T operator++(), whereas to override T++ we use T operator++(int), with an integer parameter that isn’t actually there. What’s really annoying about this syntax is that it implies a binary operator++ [perhaps the original implementation did in fact create this dummy int, and the postfix operator is actually a binary operator with an implied parameter]

What’s wrong with this picture?

Something is not quite right here… Can you spot what it is?

Answer: The sliding lever is in the up position while the toasty holders are sitting comfortably down in the body of the toaster.

Interestingly, this is not a photoshop issue, ie the picture has not been touched up or anything like that. This is actually the way the toaster is, ie: it does not have a pop-up mechanism! I know this to be true because we have one, and without those basket things you can’t actually get bread out of it!

The funny thing is, the manual that comes with the thing mentions a "bread-carriage" component, and the sliding switch is clearly spring-loaded and pretty similar to what you would find on one of those new-fangled pop-up toasters. So our best guess is that there was a major screw-up in the manufacturing process, and in true "Arthur Daley" fashion the distributors have decided to go on and sell the thing anyway, describing the remnant of the disfunctional pop-up mechanism as a "convenient sliding switch"

[kudos to Jo for spotting this detail in the catalog photo]

Useful Resources

  1. Last night I found myself in urgent need of a chatroom [after a conference call failed due to technical issues], and I didn’t want to have to sign up for anything or download any software. To my delight I discovered: Chatzy. It has the most minimal requirements I have seen for a chat room, with no signup or password, and is supported by a single banner ad which appears at the bottom of the page. Simply enter a nickname and subject and you’ve got your own chat room. Neat!
  2. Also I have starting using Bloglines, an online RSS aggregator which can show you all your unread news on a single page (if you like). The RSS client I had been using up until now was a .NET monster which took ages to start up, and it didn’t really present news the way I wanted it [too much clicking].

Tempus Fugit

I know that talking about time passing is about as interesting as telling someone about your dreams, but sometimes I get a shock when I see the dates on my software. I mean, I know I created JujuScript a while ago, but 2001…? [JujuScript itself was actually created at the end of 2000 – the calculator was written a month or so later ]

Slow-moving Fads

The funny thing is, one of the reasons I cooled a bit on the development of JujuScript [apart from the fact that there wasn’t a particular need for it] was that I simply assumed that Microsoft’s new script-like language C# would become ubiquitous within a year of its introduction.

And yet… It’s now 2004 and I am just one of many programmers still happily using VC++ 6.0 as my primary development environment, and VC6 must be 6 or 7 years old now. Most people I know who are using .NET are using it grudgingly, because a particular project [or manager] requires it. Joel [on Software] makes a good point that developing simple .NET applications is a real drag at the moment because they will only run when the 22MB runtime is installed (and up to date).

Only now am I beginning to understand that New Tech doesn’t catch on quite so fast these days. Even Microsoft has to be patient now, and can’t just expect everyone to change the way they do things overnight. I guess that’s why subscription/service models are becoming popular [with vendors]. If people already have software that does everything they want, why would they upgrade?