7.6 Bridge

The Cuis-Smalltalk graphic system is organized in two hierarchies of classes:

The MorphicCanvas hierarchy represents the Abstraction part and the VectorEngine hierarchy is the Implementation part of the graphic system. It is an example of the Bridge pattern in the Cuis-Smalltalk system.

The abstraction part represents the public protocol used for drawing the Morphs on the screen. Depending on the type of canvas, different rendering engine is then used.

The AbstractVectorCanvas is the default abstraction used in the Cuis-Smalltalk system. Observe its protocol largely inspired by SVG:

Sample01Star>>drawOn: aCanvas
aCanvas strokeWidth: 12 color: `Color lightOrange` do: [
   aCanvas
      moveTo: `(Point rho: 100 theta: 90 degreesToRadians)`;
      lineTo: `(Point rho: 100 theta: (360/5*2+90) degreesToRadians)`;
      lineTo: `(Point rho: 100 theta: (360/5*4+90) degreesToRadians)`;
      lineTo: `(Point rho: 100 theta: (360/5*6+90) degreesToRadians)`;
      lineTo: `(Point rho: 100 theta: (360/5*8+90) degreesToRadians)`;
      lineTo: `(Point rho: 100 theta: 90 degreesToRadians)` ]

DrGeo uses this abstraction to implement its own canvas (DrGSvgCanvas) to render a sketch in a SVG file. It follows the public protocol of AbstractVectorCanvas. The choice was made to make an implementation from the Abstraction hierarchy and not the Implementation one because the former is used as a parameter in the Morph’s drawOn: method.

In See Sample01Star drawing method, the used protocol to implement in DrGSvgCanvas is #strokeWidth:color:do:, #moveTo: and #lineTo:.

Observe the implementations, in AbstractVectorCanvas:

strokeWidth: strokeWidth color: aStrokeColor do: pathCommandsBlock
"Prepare parameters for drawing stroke."
self initForPath.
engine
   strokeWidth: strokeWidth
   color: aStrokeColor
   do: pathCommandsBlock

then in DrGSvgCanvas:

strokeWidth: strokeWidth color: strokeColor do: pathCommandsBlock
self pathStrokeWidth: strokeWidth color: strokeColor fillColor: nil.
self doPath: pathCommandsBlock ensureClosePath: false

and at some point operations occur in XML tree:

pathStrokeWidth: strokeWidth color: strokeColor strokeDashArray: sda fillColor: fillColor
pathNode := XMLElement named: #path.
self
   styleOf: pathNode
   StrokeWidth: strokeWidth
   color: strokeColor
   strokeDashArray: sda
   fillColor: fillColor.
^ pathNode

Same goes for lineTo:

AbstractVectorCanvas>>lineTo: aPoint
engine lineTo: aPoint.
currentPoint := aPoint.
lastControlPoint := currentPoint
DrGSvgCanvas>>lineTo: point
firstPoint ifNil: [^ self].
self addPathCommands: 'L ', point printMini.
currentPoint := point 

DrGSvgCanvas implements partially the public protocol of AbstractVectorCanvas, restricted to the part used by DrGeo. It weights only 33 methods and among them only 17 are from the canvas abstraction.