Mike Schaeffer's Blog

Articles with tag: tech
May 17, 2005

Better Text for GDI Applications

This is well documentes on MSDN , but it's still pretty cool.

I've never been happy with the text quality of the vCalc display: it's jagged and at a font size that doesn't rasterize well on the displays I have access to. Well, as it turns out, this is relatively easy to fix. The LOGFONT structure that GDI uses to select fonts has a field, lfQuality, that is used to select the quality of the text rendering. Back in olden days, this field was used to do things like disallow scaling of bitmap fonts (if you don't know what that is, be thankful: it was awful). These days, it's used to turn on Antialiasing and Cleartype (on winXP). Thus, this one line of code improved the quality of the text.

lf.lfQuality = CLEARTYPE_QUALITY;

Note from August 2025: There used to be before/after pictures here, but neither I nor the Wayback Machine can can find the images. Twenty years ago, this setting made a big improvement, but modern machines do far better than either, so you're not missing much.

There's also a setting for anti-aliasing:

lf.lfQuality = ANTIALIAS_QUALITY;

Anti-aliasing (in Windows) dates back to the Windows 95 Plus pack, so this setting should be much more widely supported. However, it's also much less powerful: it doesn't do any of the sub-pixel stuff and it is enabled far less often. In my experimentation, non-bold fonts had to be pretty big before anti-aliasing was used at all.

The other caveat is that this doesn't automatically buy you decent formatting of the text you display. That is, if you're still computing text positioning on per-pixel increments, you'll still get mediocre layout. vCalc does this, but it also has very minimal text layout requirements for now.

May 17, 2005

Seymour Cray

For some reason, I've been thinking a lot lately about Seymour Cray. When I was growing up, I remember asking my dad about who made the fastest computers in the world, and the answer at the time was Cray. I don't know if he meant the man or the company, but for a while both were true. I suppose it made an impression.

I've found a bunch of good things online about the man and his work:

Reading through them, a couple of things made impressions on me:

  • He didn't mind throwing bad ideas away (or saving them for later). The Cray 1 took a very different approach from the CDC 8600.
  • Cray failed a lot. He was always pushing the limits and taking risks, and paid the price of those risks. The CDC 8600 failed, as did several designs for the Cray 2. The Cray 3 failed to sell, and the 4 doesn't seem to have hit the prototype stage at all. Even the Cray 2 doesn't seem to have been an unqualified success, thanks to issues with memory bandwidth.
  • He had a very 'startup mentality'. His career seems to be a repeating story of initial success, spin off lab, and spin off company.
  • A lot of his design problems weren't electronic at all. He seems to have struggled as much (if not more) with packaging and cooling as with anything else.
  • He had a keen sense of style. With the possible exception of the Connection Machine CM-1/2, his machines were the most visually striking of the major supercomputers. Maybe it's superficial, but it can't have hurt the sales or publicity.
  • He knew what he had accomplished. There's a story about his suprise when Steve Chen developed the X-MP from the Cray 1 and doubled (?) the performance. Of course, the story goes on to describe how Cray ended up appreciating the new design.

Anyway, I have nothing but the utmost respect for the man and his accomplishments. R.I.P, Mr. Cray.

April 12, 2005

Visual BASIC

There's been some 'controversy' in the blog world about a petition that's circulating to ask Microsoft to continue supporting "Classic" Visual BASIC in addition to the replacement VB.Net. A month ago, I had a pretty long post dedicated to the topic, but due to technical problems I wasn't able to get it online. Therefore, I'll keep this sweet and to the point.

The core problem VB6 developers are facing is that they sank lots of development money into a closed, one-vendor language. Choosing VB6 basically amounted to a gamble that Microsoft would continue to support and develop the language for the duration of a project's active life. That gamble hasn't paid off for some developers, and companies with sizable investments in VB6 code now need to figure out how to make the most of that investment while still evolving their software.

With standardized languages like C, languages with multiple tool vendors, the risk is significantly lower. If one vendor drops their version of a language, switching to another implementation is going to be a lot easier than porting to an entirely different platform (particularly if you've avoiced or isolated vendor-specific features).

So... what's the moral of this story? Before you base your business on a particular language or tool, make sure you know what happens if that platform ever loses support. Pick something standardized, with multiple viable vendors. Or alternatively pick something open source, where you can take over platform development yourself (if you absolutely need to). Whatever you do, don't pick a one vendor tool and complain when the vendor decides to drop it. Commercial vendors, particularly, have no legal obligation to their customers.

April 12, 2005

Programming Well: Global Variables

Global variables tend get a bad rap, kind of like goto and pointers. Personally, I think they can be pretty useful if you are careful. Here are the guidelines I use to determine if a global variable is an appropriate solution:

  • Will there ever be a need for more than one instance of the variable?
  • How much complexity does passing the variable to all its accessors entail?
  • Does the variable represent global state? (A heap free list, configuration information, a pool of threads, a global mutex, etc.)
  • Can the data be more effectively modeled as a static variable in a function or private member variable in a singleton object? (Both of these are other forms of global storage, but they wrap the variable accesses in accessor functions.)
  • Can you support the lifecycle you need for the variable any other way? Global variables exist for the duration of your program's run-time. Local variables exist for the duration of a function. If you don't have heap allocated variables, or if your heap allocator sucks, then a global variable might be the best way to get to storage that lasts longer than any one function invocation.
  • Do you need to use environment features that are specific to globals? In MSVC++, this can mean things like specifying the segment in which a global is stored or declaring a variable as thread-local.

If all that leads you to the decision that a global variable is the best choice, you can then take steps to mitigate some of the risks involved. The first thing i'd do is prefix global variable names with a unique qualifier, maybe something like g_. This lowers the risk of namespace collisions as well as clearely denotes what variables are global, when you have to read or alter your code. If you have multiple global variables, I'd also be tempted to wrap them all up in a structure, for some of the same reasons.

Older Articles...