(I have gripes that I need to get out of my system. I think that documenting my approach to a coding task could demonstrate some points I want to make, and help me give some ideas solid grounding.)
Existing solutions for drawing graphics suffer from numerous technical, performance and usability flaws. (probably—I didn’t bother to check.) But I want to be able to draw things using a computer. I have an itch, so to speak, and I’m going to make a tool to scratch it.
So, I have decided to write a “useful tool” for building basic raster graphics. Like any “useful tool” worth its salt, it shall be designed for the environment of the 1970’s teletype. Might I just remark, that we are so lucky that the pinnacle of human-computer interaction was reached so early on in computing. No other technological invention can boast of such rapid mastery! For the decades since, we’ve been able to avoid wasting time on solved problems like “how to use the new-fangled computing devices”, letting us focus instead on what really matters—like writing “useful tools” to solve the real-world problems that we face right now.
It Must Have A Name
Because the tech of 1970, despite all its glory, made it undesirable to type very much, its name must be short and sweet. I’ll call it:
Wait, hmm, that looks odd. Verbose, perhaps. I don’t want to be typing four characters every time I want to paint a pretty picture! Ah, I know, I have to use some inexplicable abbreviation—how about:
drw. Yeah, that’ll do it.
I’m going to begin by considering how my life would be different after creating the
drw utility. What do I want to happen? First of all, I am faced with a blank line of paper. (well, such was the case for my spiritual ancestors back in the ’70s; sadly we have to make do with simulated paper these days.) I feel like I might type:
$ drw > smiley.png
What happens then? Interactive mode, I guess. I want to draw a simple smiley face, so probably start with something like…
$ drw > smiley.png # c 100 100 50
c stands for “circle” (obviously). The first two numbers are the x- and y- co-ordinates of the centre (obviously), in pixels, from the top left-hand corner (duh). The third parameter is the radius expressed in pixels (what else?). Oh, and the
# is the prompt for input. (it just felt like the right character to use.)
Hm, I should probably have that information easily accessible from the application itself. Here’s what my printout should look like after requesting
# h c c: circle Usage: c x y r #
Yeah, that should do it. I also realise something else I missed out. How is
drw going to do anything without knowing the dimensions of the image? They should have been passed in at the start.
$ drw -w 640 -h 480 > smiley.png # c 100 100 50 % outline of the head # c 85 85 8 % left eye # c 115 85 8 % right eye # bz 85 215 100 230 115 215 % mouth
Of course, any sensible language needs support for comments. This isn’t some hacker system where obscurity is a goal; no, far from it. We must always remember that code is used by humans to communicate their intentions to the computer.
Can you imagine how user-unfriendly computing would be, if we had to adapt ourselves to fit the machine instead of the other way round? Madness!
Next, if I want curvy shapes like the mouth, then there ought to be a command for Bézier curves. The three pairs of co-ordinates are just the three control points for a quadratic curve. There could be an optional extra argument for a cubic or something.
# h bz bz: Bezier curve Usage: bz x0 y0 x1 y1 x2 y2 [x3 y3] #
Great. But one huge thing I forgot about: colours! Ah well, there can easily be defaults. Initially the background is black and the foreground is white, just like my beloved teletype emulator! ❤
Then I should be able to send End-Of-File via Ctrl-D and see my picture in all its artistic brilliance!
... # c 115 85 8 % right eye # bz 85 215 100 230 115 215 % mouth # ^D Output written to stdout. $ pngvwr smiley.png
Ha! That’s funny. The mouth is all the way down there? Come to think of it, the face only goes from y=50 to y=150 (assuming I did my mental maths correctly—such clerical work is inappropriate for a scientific instrument), so why the hell did I think 215 and 230 were a good idea? And the scale is way too small. I want to make some adjustments…
Damn. I’ll have to go back and enter all the commands again! But wait: I could just write them in a file and pipe that to
stdin; I get scripting for free! Now that’s the power of the command line. Can you imagine how cumbersome this stuff would be in a GUI? Or with pencil and paper? 🙂
$ cat smiley.drw s 2.5 % scale the coord sys by 2.5 c 100 100 50 % outline of the head c 85 85 8 % left eye c 115 85 8 % right eye bz 85 115 100 130 115 115 % mouth (fixed!)
Commands to alter the coordinate system would be useful too. At minimum,
translate. (I was going to use
rectangle, but I still have capital R!)
$ drw -w 640 -h 480 < smiley.drw > smiley.png Output written to stdout. $ ls smiley.drw smiley.png $ pngvwr smiley.png
Right, that’s enough design for now. The next installments will use the coding of
drw as a springboard for concrete demonstrations of some ideas. And of course, more “features” will be tacked on as they come up. But regardless of how far this goes, some things are guaranteed:
- There will never be immediate feedback between creator and creation. The “spec” for the picture is written and compiled, and the result “viewed”, in separate, batch-mode stages; completely unlike “drawing” in any sense of the word.
- The program will be its own little untouchable universe. Functionality can only be added during the “fabrication process” of the next version. It will be as brittle as pottery.
- Worst of all, fundamentally visual concepts like position, size, shape, colour, angle etc. will remain brutally stuffed into the Language Box. The whole point of such a command-line utility is to use a thousand words to describe a picture. How is this anything other than outrageous?