Thursday, February 18, 2010

Notepad stories part III

When Notepad was converted to be a Unicode application in 1993 for Windows NT, there were no fixed width fonts available. This meant that the code for printing was pretty broken. The old code assumed that all the characters were the same width and, as I remember, used the average character width as the width. This leads to truncated lines or undersized lines.

The first fix involved the GetTextExtentExPoint() API which computes how many characters fit into device context (i.e. a video display or printer) for a given string. This calculation is not simple because of the different widths of each character and the possibility of kerning. Kerning allows two characters to be squished together and is typically done for aesthetic reasons. For example a V followed by an A may be kerned.

So, each line is printed up to the right margin or the end of the line whichever comes first. If there is anything left over, it will be printed on the next line. One problem with this naive approach is that it may break a line within a word, so it won't look like what Notepad displays on the screen when word-wrap is on. And there are other considerations like what to do with horizontal tabs, right-to-left languages, and any special Unicode control characters. Working out these details is not rocket science, but the resulting code may not track improvements made later in system provided edit control.

Ideally, Notepad would use the same code as the edit control, but instead of displaying on the screen, each page would be "displayed" on the printer. In 1993, there was an API called DrawText() which did this, but it would stop when it filled up the space and not report back where it had stopped. This API would work fine if there was only one page to print, but Notepad wouldn't know where to start for the second page. Windows 2000 introduced the DrawTextEx() API which returns where in the input string it stopped displaying, so now Notepad printing will track any improvements made in the edit control.

Over the years, many of the dialogs in Notepad were implemented in the system, and I would rip them out of Notepad and save some space. I had the advantage that there was no program management telling me what I could or couldn't do. If anyone asked, I would typically just say I was following the new standard. In the mid-90s, there was a UI person who tried to clean up all the hotkeys for various apps in Windows, and Notepad was changed to follow them.

One advantage to using the common print dialog was that the dialog got a lot of usage testing. Print testing has a huge problem because of all the different printers that are supported. Notepad is often used just to test simple printing internally to Microsoft, but it is also used outside of Microsoft too. When N-up printing was added during Windows 2000 development, our test team was having a hard time testing this feature. Hearing about this in a meeting, I volunteered to enable the feature in the Notepad print dialog, and this helped quite a bit. It also put pressure on other apps that printed to enable the same feature.

Someday I'll post about a bug I introduced that only hit Dave Cutler when he was using his MIPS machines.