3 ms·
I am curious why the rounded rectangle would be hard to draw. The circle primitive is already going to exploit symmetry and draw four (or eight) symmetric point
by bonzini 5y ago
I am curious why the rounded rectangle would be hard to draw. The circle primitive is already going to exploit symmetry and draw four (or eight) symmetric points at a time, computing them centered at (0,0) and shifting them to the center of the circle. Why would it be hard to shift those four pixels by four different centers (the four corners of the rectangle plus/minus the radius)? Filling them would not be any harder, either, and drawing thick lines would be harder but---again---just as hard as drawing a circle with thick lines.
- Someone 5y agoTo draw a rounded rect, you don’t want to draw four lines and four quarter circles. That will run into problems if you want to use transfer modes such as XOR, fill with a pattern (phases of the patterns won’t match), etc. On the Mac, you also needed to do clipping against arbitrary regions (https://www.folklore.org/StoryView.py?project=Macintosh&story=I_Still_Remember_Regions.txt https://www.folklore.org/StoryView.py?project=Macintosh&stor...). Doing that at reasonable speed wasn’t easy at the time. I didn’t check the source (https://computerhistory.org/blog/macpaint-and-quickdraw-source-code/ https://computerhistory.org/blog/macpaint-and-quickdraw-sour...) but I guess the drawing routines created scanlines top-to-bottom (that’s how regions worked on the Mac), and Bill tweaked a copy of the oval drawing code to insert extra pixels in each line and extra identical lines for the straight vertical parts.
- bonzini 5y agoYes, you'd do it in a single routine to not mess up patterns etc., but the math to find the start and end for each scanline is the same as for Bresenham-style ovals.
- Jyaif 5y agoYou don't write a routine that draws circles and then think that rounded rectangles are going to be hard, that's just not going to happen. Either this part of the story is made up, or Bill Atkinson was playing mind games with Steve Jobs.
- hnlmorg 5y agoI put it down to the limitation of the hardware at the time. Drawing a circle is the same math throughout the shape. Same with the square. But a rounded rectangle requires breaking the routine into two distinct mathematical operations at 8 different intervals. Doing so on a system with highly constrained resources might not be as simple as "I figured circles and squares out, so rounded rectangles must be a bit of both". Baring in mind the goal of this was to create a performant production-ready routine rather than a pretty tech demo that isn't really suitable for everyday use. I remember my days working on similar (and older hardware too) and stuff that was conceptually simple would often be much harder to implement in practice. And not always just because of hardware limitations, some of the algorithms we take for granted today hadn't been invented back then either, so we were having to figure all sorts of things out for the first time.
- hutzlibu 5y agoThe hard part was to do it in a efficient, fast way with the hardware of that time. The solution you propose, seems to work, too, but has a hacky feel. If you work with fixed pixels, it is hard to increase border-radius at will for example.
- bonzini 5y agoLooking at the QuickDraw source, it's exactly what he did[1]. Ovals and roundrects, both solid and hollow, are all handled by a single DrawArc function. Essentially an oval _is_ a round rect whose border radiuses are the entirety of the oval's radiuses. Arcs are also handled by DrawArc, but of course there's a fast path for when start=0 and end=360. [1] https://d1yx3ys82bpsa0.cloudfront.net/102658076_quickdraw_acc.zip https://d1yx3ys82bpsa0.cloudfront.net/102658076_quickdraw_ac...