The Long View
The Long View
MacPaint
On July 20 of this year, Apple Computer (oops, I mean Apple, Inc.) released the source code of Bill Atkinson’s classic program MacPaint to the Computer History Museum. Quickdraw, the version of the library embedded into the ROM Toolbox of the first Macintoshes, and used by MacPaint, was also released. Apparently, Andy Hertzfeld has been working on getting these things released since 2004, and finally succeeded by enlisting the direct help of Steve Jobs. A sincere thank you to Andy and everyone else involved. It is wonderful to get a clear view of Macintosh programming style from the program that defined the genre.
MacPaint was the first Killer App for the Macintosh. It was a Killer App before the term Killer App was invented. People bought the Macintosh because of MacPaint, and the Macintosh at that time cost a lot of money. Remember that the Macintosh came with basically 3 regular programs (not including the desk accessories or the two games on the Guided Tour disk). They were, Finder, MacWrite, and MacPaint. There would be more programs later, of course, but in 1984 that’s what you were looking at when you decided whether you wanted to buy a Macintosh or an IBM PC. The Finder was cool, and most people had never seen anything quite like that. You could copy files just by dragging icons from one disk to another, and stuff like that. But in those days, when disks were small and the complexity of your file system was low, the things that the Finder did could be done just as easily from a command line. The Finder was fun and interesting, but didn’t really enable you to do anything new. It was the solution to a problem that didn’t exist yet. I feel bad saying it, but MacWrite was a serious disappointment. Don’t get me wrong, it was a cool program, and a ground-breaking one from a user interface point of view. It was enormously influential. You can see the image of MacWrite in every word processor in use today, on every platform. But it was a demo, not the real thing. It was a memory-based program. That is, it tried to hold an entire document in memory. Word processors in those days didn’t try to do that, because memory was so limited on computers at the time. They kept documents in an open file, and when the user scrolled around in the document, the program would swap in the part of the document that was visible on the screen, and swap the rest back to disk. That way, documents could be way bigger than the available memory of the computer. The distinction between memory-resident and disk-resident data has mostly disappeared these days, but it was a huge thing then. MacWrite didn’t do it, so basically you could only work on little short documents. Looking back on it, MacWrite is seen as a historic milestone, but at the time it only seemed to prove that the Macintosh’s critics were right, and the Macintosh was not the computer of choice for serious people who wanted to do something real.
In contrast, MacPaint was like nothing you had ever seen. A few people, who had used the Lisa Office System, had used LisaDraw, a great vector graphics editor. This was a great program, and everybody who knew about it was waiting for MacDraw, which we knew was certainly coming. As it turned out, it took several months for MacDraw to arrive. But MacPaint wasn’t anything like LisaDraw. Instead of emulating a drafting system or pencil and paper, MacPaint embraced the bit-mapped nature of the Macintosh screen and the ImageWriter printer. It was a little bit like drawing with ink (not paint), and a little like black and white photography, but really it was not a metaphor for anything old. It was something new. During the months waiting for MacDraw, I decided to try to use MacPaint to create the schematics I was drawing for a set of custom electronic circuits I was building for my lab. At that time, this was done on paper using stencils for electronic circuit elements. I drew the elements in MacPaint and put them in the Scrapbook. I was skeptical, but was won over as soon as I got started in earnest. The shrinking lasso would grab a circuit element and put it right in place, with wires connected, in one move. Pixels were better than vectors!
Because it was the Macintosh program that caught people’s imagination, MacPaint became the model for the Macintosh user interface. In 2004, Andy Hertzfeld and Bill Atkinson discussed the history of the Macintosh Toolbox and MacPaint with object-oriented software giant Grady Booch, who now works at IBM’s Thomas J Watson Research Center and is also a member of the Board of Trustees of the Computer History Museum. In that interview, Atkinson discusses how he observed untrained users attempting to use prototypes of his programs, and discovered practical solutions to the conflict between the necessities of computer program design and the emerging theory of user interface design that was under development at SRI, Xerox, and Apple. Atkinson’s improvements to user interface design, developed for his own programs, were embedded in the Macintosh Toolbox, and became the standard for all Macintosh programs. They were copied by all other mouse-and-keyboard operating systems and programs, and were so insanely great that they defined our computer experiences for three decades. Only now touch-based user interfaces are requiring a re-thinking of user interface design.
It is meaningful that MacPaint violated several superficial aspects of the Macintosh user interface guidelines. It did so in a creative way that set an important example for Macintosh programmers. Starting with MacPaint (day 1), programmers were implicitly told that you should follow Apple’s rules for programmers, unless they conflicted with your creative design goals. And then it was okay to disregard them. Maybe not everybody at Apple wanted to send that message. But MacPaint was the way Atkinson made it, and it was great and so there it was.
Embrace the Pixel
User Interface
The big palette that ran vertically at the left was the tool palette. Computer programs have to have states. States, called Modes at Apple, were the biggest problem for computer users in the early 1980s. The state you are in determines the interpretation of your actions. For example, in MacPaint, holding down the mouse button and dragging in the drawing window might draw a line, move the existing drawing around in the window, erase something already there, define a selection, or draw a shape like a rectangle or oval. There’s no way to avoid this kind of state-dependent action. You just have one mouse and one button. You have to somehow enter a state, to tell the program what you want to do next, and then use the mouse or keyboard to do it. And you need a way out of that state when you are done. Finally, you need a reminder about what state you are in, and what the choices of states are. Atkinson’s solution for MacPaint was the tool palette. MacPaint’s major states number 20, and there is an entry in the palette for each. The current state of the program is indicated by which palette entry is highlighted (inverted). Clicking in the palette changes the tool selection. The user always knows what state he is in, because the palette is always visible. The only thing that has to be learned is the meaning of the tools, and which palette icon goes with which tool. MacPaint introduced some great palette icons, designed by Atkinson with the help of Susan Kare (see Busy Being Born Part 2 at http://www.folklore.org). The images in the palette are actually characters in a custom font, stored in MacPaint’s resource fork. They represent an important component of the Macintosh design. The hope was that the tool icon’s meaning would be obvious so no memorization of commands would be required. For the most part, this was accomplished. It’s a little harder to do make obvious icons than you might think, and many subsequent programs have tried and failed. This failure is illustrated by the need for tool-tips in practically all Windows, and many Macintosh programs. Application programmers using Windows XP (and its linux imitators) have cluttered up their screens with toolbars packed with incomprehensible little icon buttons that make no sense at all, to the point that Microsoft was moved to abandon their trademark tool bars. But MacPaint’s pencil, brush spray paint can and eraser were images people recognized. If you needed a little help, it was available from a couple of help screens that could be brought up from the Goodies menu. The paint can was easily recognized, but what would a paint can do? The solution was obvious the first time you tried it. The paint can did a seed fill.
The letter A represented text. Text was a little confusing in MacPaint, because it wasn’t text. It was a picture of text. But while you were drawing it, it was text. You were actually working in a little temporary line editor. So you could make a mistake and backspace to fix it. You could change typeface or size. But once you clicked the mouse somewhere (even within the line of text you were editing), the text editor was no more, and the text was turned into some black pixels that could only be edited as a picture. A little practice and some thinking about what the program was doing made this behavior understandable. But it always seemed strange. In his interview with Grady Booch and Andy Hertzfeld, Atkinson said that he had written code for MacPaint that could convert images of text back into editable text, and later thought better of it and removed it. This feature would have been great for advanced users. Later, the ability to re-edit painted text would be added to Photoshop, and would be a very popular feature. Still, I guess he was right to remove it from MacPaint. Nobody was an advanced user in those days, and editable text would have broken the metaphor. We had to learn the difference between vector drawing and paint programs. MacPaint was a pure paint program.
It only took a minute to learn about scrolling, and the little scrolling hand was a great tool icon. Why didn’t MacPaint use scroll bars? Scroll bars were the official Apple method for scrolling. Although scroll bars later became ubiquitous, they were less uniformly used in those days. In his early (pre-Multifinder) Multifinder-like program Servant, Andy Hertzfeld omitted scrollbars from Finder windows, and substituted the hand-scroller. He added inertial scrolling, a feature MacPaint did not include. Give the window a push with the little hand, and it would keep going. Hmm, that’s a good idea. Maybe Apple should use that for something now.
Drawing shapes was also obvious, but the selection tools were surprising. I don’t think anybody had seen anything like them before. On a black and white screen, how do you indicate a selection? You need to draw something around the boundary of the selection, but it shouldn’t look like the thing being selected. The idea of using a moving image to represent the selection boundary was genius. It only could have occurred to the guy who wrote Quickdraw, and knew that he could draw a moving image fast enough to do the job. Officially called the marquee, after the moving lights often seen on those, it was called marching ants by most programmers. The method was imitated and used on nearly all graphics programs thereafter, and much was written on how to implement it. The other delightful surprise was the lasso. I would never have known what this was without trying it. When I saw that it made an irregular selection, I assumed that was it. But after you drew your selection it did a special miracle that made it deserving of the lasso image. The selection tightened after you made it, to grip only the black pixels within the selection region. This made very delicate selections easy, and allowed the most amazing kinds of editing. For example, it was a breeze to put a library of irregular shapes in the scrapbook (say a set of schematic electronic circuit elements), paste them into a MacPaint document, and place them in the most non-destructive way among other elements. Selections could be moved around on the page without destroying the other (non-selected) items, until the selection was dropped in place (by clicking outside the selection). Pasted elements were placed in a selection, so that you could move them around to where you wanted them.
MacPaint’s Secrets
Having the source code is an amazing opportunity, albeit a little late for some purposes. When trying to do some common Macintosh programming thing, I often used to wonder how it was done in the programs written by the grand masters. When the source code was released a few days ago, I had my questions ready. MacPaint is basically on two files, the main one written in Pascal and and another with utility routines in 68k assembly. There are also a couple of files that define toolbox traps, and an RMaker resource file, but the answers to my questions were in MacPaint.p and PaintAsm.a. The best way to read code is never the order in which it is written in the files, but rather the order in which it executes, so I needed to get it compiled and running in a debugger so I could step (and skip) around in it. The source files were in Lisa Workshop format. Of course they would be. That doesn’t work for me, because I don’t have a Lisa, and the extra stuff needed to compile a Macintosh program on a Lisa is mostly lost to history anyway. But I have MPW 3.1 working on both my Mac Plus and in Mini vMac, and it has a Pascal compiler and assembler. This is close, but I had to make some small changes in directives and things to get it to compile. I used the Workshop on a colleague’s Lisa briefly in 1984 (before my 512K arrived), but I didn’t remember details about the assembler or compiler. Luckily, I was able to get the pages on assembly and compilation directives from the Lisa Workshop 2.0 Users Guide by going to the Lisa Emulator Project website. In addition to a great Lisa Emulator, that site has a great collection of documentation, although in a slightly inconvenient format. That was enough to work out the translation between directives. Two of the files in the MacPaint release from Apple (MyHeapAsm.a and MyTools.a) are unnecessary for an MPW build because their purposes are served by the standard Pascal interfaces files. The changes required to MacPaint.p and PaintAsm.a were really minor, but if you want to see them, they are here and here, respectively. The resource source file released by Apple (MacPaint.r) was also in Lisa Workshop RMaker format, of course. And as you know, there has never been a reliable way to compile those on the Mac. So I just extracted the CODE resources from the executable version of my original copy of the MacPaint executable using ResEdit, and used the rest for my build. Anyway, the released MacPaint.r is missing some key things. It doesn’t include the PICT resources for the two help screens, or the font that is used to draw the icon buttons in the tool palette. All the files have unix (instead of classic Macintosh) newline characters, and so needed converting. I guess Andy and Bill didn’t go to the trouble of trying to build the program before they released the sources [heh].
Anyway, this got me to the point that I could start to explore the code the way I wanted to, using SADE at runtime. I have a pretty long list of questions. Here are answers to just three of them. It will take a while to get answers to them all.
Question #1: Memory Monitoring and Support for Desk Accessories
When the user selects a menu item, it may be a desk accessory. Apple documentation was very clear on how to find what desk accessory the user wanted and how to launch it. What wasn’t clear was the best way to tell whether or not your program could afford the memory required for the Desk Accessory in question. Remember, desk accessories would launch into your program’s heap. Basically, if you don’t have enough memory to launch an Desk Accessory and you launch it anyway, you could find yourself in an error state without enough memory to even put up an alert apologizing to the user about what was about to happen next. Because Desk Accessories were resources, you could ask the Resource Manager to fake-load (SetResLoad to False) it and report on its size. You could then see if you had enough memory. Of course some desk accessories would load stuff into your heap themselves once the got their foot in the door, but there was nothing you could do about that. I read about the SetResLoad(False) method somewhere and used it, but never saw a definitive word from Apple about the right way to safely load a Desk Accessory. How did MacPaint do it, given that it written to be very careful about memory as it ran beautifully on the 128k? Well, it only takes a second to see that MacPaint just flat out didn’t worry about it. It compacted the heap to make maximal space for whatever was coming, and then just opened the desk accessory. This seems especially odd to me, given that MacPaint unloaded a bunch of its code segments each time through the event loop. If the user loaded MacPaint’s application heap full of desk accessories, it seems to me it might have been unable to load the code it needed to print or edit brushes or something else. The lesson here is that maybe I worried too much about memory taken up by Desk Accessories.
Otherwise, MacPaint was careful about memory. Essential functions of the program didn’t rely much on dynamic memory allocation with NewHandle or NewPointer. There were two windows (one for the entire desktop and the one you draw in), and their WindowRecords were stored as globals. Even the EventRecord handed to GetNextEvent was a statically allocated global. There were two screen buffers (big enough to represent the drawing window), and both of them were statically allocated. NewHandle appears only 8 times in the entire program, and DisposHandle only 9 times. Most of them are for tiny allocations. There is one that makes a temporary screen buffer to hold a mask (12480 bytes), once makes a 21 line buffer during writing to disk. MacPaint’s heap does not change much during execution of the program. And the program won’t open a second file without closing the first. That’s what usually causes programs to crank up their memory needs. On the original Macintosh, there was no hope of that, and so the memory requirements of the program were relatively predictable.
Question #2: The working files Paint1 and Paint2, and Rescue
Of course, Paint1 and Paint2 were the backing store for the document. Every time the user scrolled the image around using the hand tool, the current contents of the document were written to disk, in one of the two files. Within the program, the files are referred to as workTo and workFrom. The files Paint1 and Paint2 can change roles, but upon updating the backing store, the previous contents are copied from workFrom, the most recent changes since the last changes are added, and the result is written to workTo. After a crash, the program opens the most recently modified of these two files (the last workTo), loads it into memory, and calls it Rescue. If your crash happened right after a scroll, the rescue file includes all of your most recent changes. You didn’t lose a thing. If not, you lost only the changes you made since the last time you scrolled the image. Scrolling isn’t the only thing that triggers a file update. Basically anything that is going to cause the contents of the screen to change will trigger a refresh of the disk image. That includes the Show Page function, that shows a thumbnail sketch of the entire document and navigation function like the one in Adobe Illustrator.
Question #3: How do you do undo?
The MacPaint Story
I wouldn’t have seen it if I hadn’t believed it -- Marshall McLuhan
The story of MacPaint is the story of the Macintosh. It was a carefully designed, clever, but simple program that was like nothing anybody had ever seen before. The very fact that it was revolutionary made it hard to appreciate at first glance. You had to use it for a while to realize how great it was. If you never caused it to crash, you never saw its clever rescue file. If you didn’t try to do something serious with it, you might have not seen that it could do serious things, like electronic schematics or advertising graphics for print. If you did not have a Macintosh, how would you get a chance to do that? In 1984, the Macintosh was sold in a lot of retail channels, including private computer stores, large department stores, and university bookstores. These places often had machines available to use, and you could have a try at making something in MacPaint and printing it out. Those places were crowded with people messing around with the computers, and the Macintosh gained mind share like mad during that time. Over the next couple of years, the number of places you could go to see and use a Macintosh shrank away to almost nothing. I don’t know why. At the same time, cheesy imitations of MacPaint appeared on IBM PCs running DOS retro-fit with a serial mouse. I don’t know how many times I talked to a DOS user about the Mac, to have them tell me that they had a MacPaint equivalent on their computer, and that they were not impressed. They were sure their DOS knockoff version was the same as MacPaint, or even better because it drew in (16) colors. Occasionally I would get a chance to look at those programs, and they were always unusable junk. The PC user had an investment in his computer (computers were expensive then) and wanted to believe that there was nothing to the Macintosh. Without a chance to really make the comparison doing serious graphics work, there was no way for them to overcome the energy of activation required to see the difference between MacPaint and the useless imitation they were comparing it with. Ironically, because the paint program they were using on DOS was a toy, and they knew that it was a Macintosh knockoff, they concluded that the Macintosh was a toy. I don’t know anything about marketing, but I could see this is was a bad situation for Apple. Advertising, whether in print or on television, could not overcome it.
What Apple needed back then was a place where people could try out the machines. It would also have helped to have these places full of enthusiastic young employees who could show customers the extraordinary capabilities of the Macintosh computer, rather than just talk about them. It also would have been great if potential customers could take little mini-courses in how to use MacPaint, or other Macintosh software. And if they already had a Macintosh but it wasn’t working right, there were some really smart people they could ask about their problems. Things might have worked out differently.
-- BG (basalgangster@macGUI.com)
Saturday, July 31, 2010