Morphic, Canvas, and Drawing Polygon Borders

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Morphic, Canvas, and Drawing Polygon Borders

darth-cheney
I am having some trouble accurately drawing polygons using Morphic and the various Canvas types.

My task is to recreate the Mac OS Platinum style buttons, and do be as pixel-accurate as I can. For the basic button, this involves creating a rectangle whose corners are always fattened by 2px on each side, no matter the extent of the underlying morph:


I can achieve this kind of outline when drawing individual lines one at a time with a Canvas:

```smalltalk
canvas := FormCanvas extent: 150@30.

rect := Rectangle point: (0@0) point: (150@30).

vertices := { 
    (rect left)@(rect top + 2).
    (rect left + 2)@(rect top).
    (rect right - 3)@(rect top).
    (rect right - 1)@(rect top + 2).
    (rect right -1)@(rect bottom - 3).
    (rect right - 3)@(rect bottom -1).
    (rect left + 2)@(rect bottom - 1).
    (rect left)@(rect bottom - 3).
    "(rect left)@(rect top + 2)" }.

canvas
    line: (vertices at: 1) to: (vertices at: 2) color: Color black;
    line: (vertices at: 2) to: (vertices at: 3) color: Color black;
    line: (vertices at: 3) to: (vertices at: 4) color: Color black;
    line: (vertices at: 4) to: (vertices at: 5) color: Color black;
    line: (vertices at: 5) to: (vertices at: 6) color: Color black;
    line: (vertices at: 6) to: (vertices at: 7) color: Color black;
    line: (vertices at: 7) to: (vertices at: 8) color: Color black;
    line: (vertices at: 8) to: (vertices at: 1) color: Color black.

canvas form asMorph openInWindow.
```

Which gives me:

But using the native Polygon drawing features of Canvas yield a different, and incorrect, result:

```smalltalk
canvas := FormCanvas extent: 150@30.

rect := Rectangle point: (0@0) point: (150@30).

vertices := { 
    (rect left)@(rect top + 2).
    (rect left + 2)@(rect top).
    (rect right - 3)@(rect top).
    (rect right - 1)@(rect top + 2).
    (rect right -1)@(rect bottom - 3).
    (rect right - 3)@(rect bottom -1).
    (rect left + 2)@(rect bottom - 1).
    (rect left)@(rect bottom - 3).
    "(rect left)@(rect top + 2)" }.
    
canvas drawPolygon: vertices fillStyle: Color transparent borderWidth: 1 borderColor: Color black.

canvas form asMorph openInHand.
```



Either this is some kind of limitation in BalloonCanvas/BalloonEngine (which "becomes" the canvas for polygon draw operations) or I am doing something terribly wrong.

Ideally I can trace this shape as a border, since I'll need to trace yet more additional borders around it (like the "default" button in Platinum, which has a fat complex border).

Borders are already kind of complicated, so any help you all can provide would be much appreciated.

FYI this same behavior is present in Squeak.

--
Eric
Reply | Threaded
Open this post in threaded view
|

Re: Morphic, Canvas, and Drawing Polygon Borders

Nicolai Hess-3-2
Hi Eric,

I don't know exactly how Borders (BorderdMorphs) are drawn, but a simple way to create that kind of 1px border with 2px round edges may be using the a borderd morph:

BorderedMorph new
        fillStyle: Color transparent;
        borderStyle:
                        (RoundedBorder new
                                    cornerRadius: 2;
                                    width: 1;
                                    baseColor: Color red)



Combining this with a Complex border to create that button with different colors for  left-up/right-bottom edges is maybe more difficult.




2018-05-16 20:48 GMT+02:00 Eric Gade <[hidden email]>:
I am having some trouble accurately drawing polygons using Morphic and the various Canvas types.

My task is to recreate the Mac OS Platinum style buttons, and do be as pixel-accurate as I can. For the basic button, this involves creating a rectangle whose corners are always fattened by 2px on each side, no matter the extent of the underlying morph:


I can achieve this kind of outline when drawing individual lines one at a time with a Canvas:

```smalltalk
canvas := FormCanvas extent: 150@30.

rect := Rectangle point: (0@0) point: (150@30).

vertices := { 
    (rect left)@(rect top + 2).
    (rect left + 2)@(rect top).
    (rect right - 3)@(rect top).
    (rect right - 1)@(rect top + 2).
    (rect right -1)@(rect bottom - 3).
    (rect right - 3)@(rect bottom -1).
    (rect left + 2)@(rect bottom - 1).
    (rect left)@(rect bottom - 3).
    "(rect left)@(rect top + 2)" }.

canvas
    line: (vertices at: 1) to: (vertices at: 2) color: Color black;
    line: (vertices at: 2) to: (vertices at: 3) color: Color black;
    line: (vertices at: 3) to: (vertices at: 4) color: Color black;
    line: (vertices at: 4) to: (vertices at: 5) color: Color black;
    line: (vertices at: 5) to: (vertices at: 6) color: Color black;
    line: (vertices at: 6) to: (vertices at: 7) color: Color black;
    line: (vertices at: 7) to: (vertices at: 8) color: Color black;
    line: (vertices at: 8) to: (vertices at: 1) color: Color black.

canvas form asMorph openInWindow.
```

Which gives me:

But using the native Polygon drawing features of Canvas yield a different, and incorrect, result:

```smalltalk
canvas := FormCanvas extent: 150@30.

rect := Rectangle point: (0@0) point: (150@30).

vertices := { 
    (rect left)@(rect top + 2).
    (rect left + 2)@(rect top).
    (rect right - 3)@(rect top).
    (rect right - 1)@(rect top + 2).
    (rect right -1)@(rect bottom - 3).
    (rect right - 3)@(rect bottom -1).
    (rect left + 2)@(rect bottom - 1).
    (rect left)@(rect bottom - 3).
    "(rect left)@(rect top + 2)" }.
    
canvas drawPolygon: vertices fillStyle: Color transparent borderWidth: 1 borderColor: Color black.

canvas form asMorph openInHand.
```



Either this is some kind of limitation in BalloonCanvas/BalloonEngine (which "becomes" the canvas for polygon draw operations) or I am doing something terribly wrong.

Ideally I can trace this shape as a border, since I'll need to trace yet more additional borders around it (like the "default" button in Platinum, which has a fat complex border).

Borders are already kind of complicated, so any help you all can provide would be much appreciated.

FYI this same behavior is present in Squeak.

--
Eric