[squeak-dev] What is the task of NullEncoder?

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Fri Sep 29 17:09:40 UTC 2017


2017-09-29 18:12 GMT+02:00 H. Hirzel <hannes.hirzel at gmail.com>:

> For the question
>    "Do we really want to do that, have a stream of Morphs (or other
> graphical objects)?"
> I think an interesting article to read is
> https://smalltalkrenaissance.wordpress.com/2015/06/29/silk-
> is-just-too-flexible/
>
> A hierarchy of morphs (elements) may be regarded as well as a stream.
>
>
>
Sorry, my question was bad. If streaming consist of a simple do: loop, an
Encoder isn't really necessary.
The right question is why would we need a generic stream transform pattern
like Encoder is?

The canvas other than PostscriptCanvas don't use the target, they are sinks.
So there's no reason to use an Encoder pattern here.

But PostscriptCanvas uses a different filterSelector.
That means that we can differentiate drawing commands for some specific
morph.
And indeed, a BookMorph has a specific way to render on a PostscriptCanvas:
it will render all the pages.

And a DSCPostscriptCanvas yet another: it will produces those Document
Structuring Conventions
which are meta informations on contents such as chapters, page numbers
etc... encoded after double comments '%%'.

Thus using an Encoder permits a differentiation in rendering.

But I'm not at all convinced by this Encoder usage. It's not composable.
What if I embed 1 or several BookMorph into another Morph? Won't the
rendering and DSC be kind of broken?

What if we want to render this BookMorph with a specific target layout?
Won't we need to recompose?
Composing is more than rendering, so a Canvas would not be the right
abstraction...

Rendering the whole book contents is a different operation specific to a
BookMorph.
It's not be a problem to have a specific menu/halo for this specific
operation.
This specific rendering is not composable. And maybe not the Canvas
responsibility.
So I don't see the point in using this Encoder pattern here.



> Canvas has a useful class comment [3]
>
> It could be that
>     NullEncoder
>         FlattenEncoder
> are just helper classes to structure the code.
>
>
>
> FlattenEncoder has the comment
>
>     "The simplest possible encoding:  leave the objects as is."
>
>
> Maybe the simplest thing for the class comment of NullEncoder is just
> to refer to the class comment of FlattenEncoder and Canvas.
>
> [3] Class comment of 'Canvas'
> A canvas is a two-dimensional medium on which morphs are drawn in a
> device-independent manner. Canvases keep track of the origin and
> clipping rectangle, as well as the underlying drawing medium (such as
> a window, pixmap, or postscript script).
>
> Subclasses must implement (at least) the following methods:
>         * Drawing:
>                 #fillOval:color:borderWidth:borderColor:
>                 #frameAndFillRectangle:fillColor:borderWidth:borderColor:
>                 #drawPolygon:color:borderWidth:borderColor:
>                 #image:at:sourceRect:rule:
>                 #stencil:at:sourceRect:rule:
>                 #line:to:width:color:
>                 #paragraph:bounds:color:
>                 #text:bounds:font:color:
>         * Support
>                 #clipBy:during:
>                 #translateBy:during:
>                 #translateBy:clippingTo:during:
>                 #transformBy:clippingTo:during:
>
> On 9/29/17, Nicolas Cellier <nicolas.cellier.aka.nice at gmail.com> wrote:
> > The target inst. var. is used exclusively by the PostscriptCanvas.
> > And IMO it is a classical mistake of inheritance versus composition.
> >
> > A PostScript canvas will have to encode the sequence of graphics
> > instruction into a stream of PostScript instructions written into a
> > PostScript file.
> > For this purpose, it has a target PostscriptEncoder, which is itself an
> > encoder already.
> >
> > An Encoder implements a processing unit that transform a stream by using
> a
> > kind of generic double dispatching.
> >
> > Why the PostscriptCanvas has to be considered as an Encoder itself is
> very
> > suspect, unless we ask
> >
> >     canvas write: aMorph.
> >
> > Do we really want to do that, have a stream of Morphs (or other graphical
> > objects)?
> >
> > 2017-09-29 17:33 GMT+02:00 H. Hirzel <hannes.hirzel at gmail.com>:
> >
> >> Tobias
> >>
> >> You write that NullEncoder and subclasses could be summarized as
> >>
> >>     "Put objects onto another thing with encoding inbetween".
> >>
> >> which I think is helpful for understanding.
> >>
> >> Maybe we consider for the class comment of NullEncoder
> >>
> >>     "Put objects onto another thing with encoding/transformation
> >> inbetween".
> >>
> >>
> >> But also note that this is not only related to PostscriptCanvas as we
> >> have
> >>
> >>
> >> NullEncoder
> >>     FlattenEncoder
> >>          Canvas
> >>              FormCanvas
> >>
> >> FormCanvas has some nice usage examples.
> >>
> >> #test1 is
> >>
> >> test1
> >>         "FormCanvas test1"
> >>
> >>         | canvas |
> >>         canvas := FormCanvas extent: 200 at 200.
> >>         canvas fillColor: (Color black).
> >>         canvas line: 10 at 10 to: 50 at 30 width: 1 color: (Color red).
> >>         canvas frameRectangle: ((20 at 20) corner: (120 at 120)) width: 4
> >> color:
> >> (Color green).
> >>         canvas point: 100 at 100 color: (Color black).
> >>         canvas drawString: 'Hello, World!' at: 40 at 40 font: nil color:
> >> (Color cyan).
> >>         canvas fillRectangle: ((10 at 80) corner: (31 at 121)) color: (Color
> >> magenta).
> >>         canvas fillOval: ((10 at 80) corner: (31 at 121)) color: (Color
> cyan).
> >>         canvas frameOval: ((40 at 80) corner: (61 at 121)) color: (Color
> blue).
> >>         canvas frameOval: ((70 at 80) corner: (91 at 121)) width: 3 color:
> >> (Color
> >> red alpha: 0.2).
> >>         canvas fillRectangle: ((130 at 30) corner: (170 at 80)) color: (Color
> >> lightYellow).
> >>         canvas showAt: 0 at 0.
> >>
> >>
> >> This works fine in an MVC project
> >>
> >> --Hannes
> >>
> >> On 9/29/17, Tobias Pape <Das.Linux at gmx.de> wrote:
> >> > Hi Hannes
> >> >
> >> >> On 29.09.2017, at 15:21, H. Hirzel <hannes.hirzel at gmail.com> wrote:
> >> >>
> >> >> And there is no 'FlattenEncoder' in Pharo 6
> >> >
> >> >>
> >> >>
> >> >> On 9/29/17, H. Hirzel <hannes.hirzel at gmail.com> wrote:
> >> >>> We have
> >> >>>
> >> >>> NullEncoder
> >> >>>    FlattenEncoder
> >> >>>        Canvas
> >> >
> >> > So here's the Thing: I looked in 3.8, and there's:
> >> >
> >> > Object
> >> >  NullEncoder          - Morphic-Postscript Filters
> >> >   FlattenEncoder      - Morphic-Postscript Filters
> >> >    Canvas             - Morphic-Support
> >> >     PostscriptCanvas  - Morphic-Postscript Canvases
> >> >
> >> > But also note that they all have a callback via class>>filterSelector:
> >> >
> >> > NullEncoder>>filterSelector           ^ #writeOnFilterStream:
> >> > FlattenEncoder>>filterSelector                ^ #flattenOnStream:
> >> > Canvas>>filterSelector                        ^ #drawOnCanvas:
> >> > PostscriptCanvas>>filterSelector      ^ #fullDrawPostscriptOn:
> >> >
> >> > I think part of that happened because this all shared common
> >> functionallity,
> >> > In the sense that all those things "Put objects onto another thing
> with
> >> > encoding inbetween".
> >> > Thinking of things like a n-dimensonal stream or so…
> >> >
> >> > I checked and It is like that even in Squeak 3.6, 3.0, 2.8.
> >> > Squeak 1.13 does not have any of those, and it has no Morphic.
> >> >
> >> > Self Morphic does not have such Encoders, tho.
> >> >
> >> > In the end it all seems to be related to the PostScript Canvas, which,
> >> > understandably, has to have access to certain objects and actually has
> >> > to
> >> > "encode" them into a file.
> >> >
> >> > Best regards
> >> >       -Tobias
> >> >
> >> >
> >> >
> >> >>>
> >> >>> there are no direct users of NullEncoder and FlattenEncoder.
> >> >>>
> >> >>> FlattenEncoder class comment is just
> >> >>>
> >> >>>    'The simplest possible encoding:  leave the objects as is.'
> >> >>>
> >> >>> a bit terse. Does not really say what the issue is about.
> >> >>>
> >> >>>
> >> >>>
> >> >>> On 9/29/17, H. Hirzel <hannes.hirzel at gmail.com> wrote:
> >> >>>> P.S.
> >> >>>>
> >> >>>> There is no NullEncoder in Pharo.
> >> >>>>
> >> >>>> The class Canvas is not in a package 'Morphic-Support' but in a
> >> >>>> package 'Graphics-Canvas'.
> >> >>>>
> >> >>>> There is no 'Graphics-Canvas' package in Squeak. [2]
> >> >>>>
> >> >>>> Seems like a good idea to move Canvas and subclasses to a package
> >> >>>> 'Graphics-Canvas' as well.
> >> >>>>
> >> >>>>
> >> >>>> [2] Graphics package in Squeak 6.0a-17405
> >> >>>>
> >> >>>> Graphics-Display Objects
> >> >>>> Graphics-External-Ffenestri
> >> >>>> Graphics-Files
> >> >>>> Graphics-Fonts
> >> >>>> Graphics-Primitives
> >> >>>> Graphics-Text
> >> >>>> Graphics-Transformations
> >> >>>> GraphicsTests-Files
> >> >>>> GraphicsTests-Primitives
> >> >>>> GraphicsTests-Text
> >> >>>>
> >> >>>> On 9/29/17, H. Hirzel <hannes.hirzel at gmail.com> wrote:
> >> >>>>> Hello
> >> >>>>>
> >> >>>>> NullEncoder is subclass of object ([1] for full hierachy). It is a
> >> >>>>> superclass of Canvas.
> >> >>>>>
> >> >>>>> What is the function of NullEncoder. No class comment so far?
> >> >>>>>
> >> >>>>> Regards
> >> >>>>> Hannes
> >> >>>>>
> >> >>>>>
> >> >>>>> ------------------------------------------------------------
> >> -------------------------------------------------------------------
> >> >>>>>
> >> >>>>> [1] NullEncoder printHierarchy '
> >> >>>>> ProtoObject #()
> >> >>>>>   Object #()
> >> >>>>>           NullEncoder #(''target'' ''filterSelector'')
> >> >>>>>                   FlattenEncoder #()
> >> >>>>>                           ByteEncoder #()
> >> >>>>>                                   PrintableEncoder #()
> >> >>>>>                                           PostscriptEncoder #()
> >> >>>>>
> >>  PostscriptEncoderToDisk #()
> >> >>>>>                                           PropertyListEncoder #()
> >> >>>>>                           Canvas #()
> >> >>>>>                                   ColorMappingCanvas
> >> >>>>> #(''myCanvas'')
> >> >>>>>                                           AlphaBlendingCanvas
> >> #(''alpha'')
> >> >>>>>                                           ShadowDrawingCanvas
> >> #(''shadowColor'')
> >> >>>>>                                   FormCanvas #(''origin''
> >> ''clipRect'' ''form'' ''port''
> >> >>>>> ''shadowColor'')
> >> >>>>>                                           BalloonCanvas
> >> #(''transform'' ''colorTransform'' ''engine''
> >> >>>>> ''aaLevel'' ''deferred'')
> >> >>>>>                                           BlueFormCanvas #()
> >> >>>>>                                           ColorPatchCanvas
> >> #(''stopMorph'' ''foundMorph'' ''doStop'')
> >> >>>>>                                           MultiResolutionCanvas
> >> #(''deferredMorphs'')
> >> >>>>>                                   PluggableCanvas #()
> >> >>>>>                                           BufferedCanvas
> >> #(''remote'' ''previousVersion'' ''lastTick''
> >> >>>>> ''dirtyRect'' ''mirrorOfScreen'')
> >> >>>>>                                           CachingCanvas
> >> #(''cacheCanvas'' ''mainCanvas'')
> >> >>>>>                                           ClippingCanvas
> >> #(''canvas'' ''clipRect'')
> >> >>>>>                                           MultiCanvas
> >> >>>>> #(''canvases''
> >> ''extent'' ''depth'')
> >> >>>>>                                           NullCanvas #()
> >> >>>>>                                   PostscriptCanvas #(''origin''
> >> ''clipRect'' ''currentColor''
> >> >>>>> ''shadowColor'' ''currentFont'' ''morphLevel'' ''gstateStack''
> >> >>>>> ''fontMap'' ''usedFonts'' ''psBounds'' ''topLevelMorph''
> >> >>>>> ''initialScale'' ''savedMorphExtent'' ''currentTransformation''
> >> >>>>> ''printSpecs'' ''pages'')
> >> >>>>>                                           DSCPostscriptCanvas #()
> >> >>>>>
> >>  DSCPostscriptCanvasToDisk #()
> >> >>>>>                                           EPSCanvas #()
> >> >>>>>                                   RemoteCanvas #(''innerClipRect''
> >> ''outerClipRect'' ''transform''
> >> >>>>> ''connection'' ''shadowColor'')'
> >> >>>>>
> >> >>>>
> >> >>>
> >> >>
> >> >
> >> >
> >> >
> >>
> >>
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20170929/7f5dca29/attachment.html>


More information about the Squeak-dev mailing list