What is the task of NullEncoder?

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

What is the task of NullEncoder?

Hannes Hirzel
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'')'

Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Hannes Hirzel
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 <[hidden email]> 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'')'
>

Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Hannes Hirzel
We have

NullEncoder
    FlattenEncoder
        Canvas

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 <[hidden email]> 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 <[hidden email]> 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'')'
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Hannes Hirzel
And there is no 'FlattenEncoder' in Pharo 6.


On 9/29/17, H. Hirzel <[hidden email]> wrote:

> We have
>
> NullEncoder
>     FlattenEncoder
>         Canvas
>
> 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 <[hidden email]> 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 <[hidden email]> 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'')'
>>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Tobias Pape
Hi Hannes

> On 29.09.2017, at 15:21, H. Hirzel <[hidden email]> wrote:
>
> And there is no 'FlattenEncoder' in Pharo 6

>
>
> On 9/29/17, H. Hirzel <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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'')'
>>>>
>>>
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Hannes Hirzel
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@200.
        canvas fillColor: (Color black).
        canvas line: 10@10 to: 50@30 width: 1 color: (Color red).
        canvas frameRectangle: ((20@20) corner: (120@120)) width: 4 color:
(Color green).
        canvas point: 100@100 color: (Color black).
        canvas drawString: 'Hello, World!' at: 40@40 font: nil color: (Color cyan).
        canvas fillRectangle: ((10@80) corner: (31@121)) color: (Color magenta).
        canvas fillOval: ((10@80) corner: (31@121)) color: (Color cyan).
        canvas frameOval: ((40@80) corner: (61@121)) color: (Color blue).
        canvas frameOval: ((70@80) corner: (91@121)) width: 3 color: (Color
red alpha: 0.2).
        canvas fillRectangle: ((130@30) corner: (170@80)) color: (Color lightYellow).
        canvas showAt: 0@0.


This works fine in an MVC project

--Hannes

On 9/29/17, Tobias Pape <[hidden email]> wrote:

> Hi Hannes
>
>> On 29.09.2017, at 15:21, H. Hirzel <[hidden email]> wrote:
>>
>> And there is no 'FlattenEncoder' in Pharo 6
>
>>
>>
>> On 9/29/17, H. Hirzel <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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'')'
>>>>>
>>>>
>>>
>>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Hannes Hirzel
And also note that we have

    Canvas subclass: #PostscriptCanvas

which is in another category 'MorphicExtras-Postscript Canvases'.

Not in the category 'Morphic-Support' in which NullEncoder and Canvas is.

And PostscriptCanvas is for the use in Morphic as it has an instance
variable 'topLevelMorph'.



On 9/29/17, H. Hirzel <[hidden email]> wrote:

> 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@200.
> canvas fillColor: (Color black).
> canvas line: 10@10 to: 50@30 width: 1 color: (Color red).
> canvas frameRectangle: ((20@20) corner: (120@120)) width: 4 color:
> (Color green).
> canvas point: 100@100 color: (Color black).
> canvas drawString: 'Hello, World!' at: 40@40 font: nil color: (Color
> cyan).
> canvas fillRectangle: ((10@80) corner: (31@121)) color: (Color magenta).
> canvas fillOval: ((10@80) corner: (31@121)) color: (Color cyan).
> canvas frameOval: ((40@80) corner: (61@121)) color: (Color blue).
> canvas frameOval: ((70@80) corner: (91@121)) width: 3 color: (Color
> red alpha: 0.2).
> canvas fillRectangle: ((130@30) corner: (170@80)) color: (Color
> lightYellow).
> canvas showAt: 0@0.
>
>
> This works fine in an MVC project
>
> --Hannes
>
> On 9/29/17, Tobias Pape <[hidden email]> wrote:
>> Hi Hannes
>>
>>> On 29.09.2017, at 15:21, H. Hirzel <[hidden email]> wrote:
>>>
>>> And there is no 'FlattenEncoder' in Pharo 6
>>
>>>
>>>
>>> On 9/29/17, H. Hirzel <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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'')'
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Tobias Pape

> On 29.09.2017, at 17:50, H. Hirzel <[hidden email]> wrote:
>
> And also note that we have
>
>    Canvas subclass: #PostscriptCanvas
>
> which is in another category 'MorphicExtras-Postscript Canvases'.
>
> Not in the category 'Morphic-Support' in which NullEncoder and Canvas is.
>

Yea, but it used to be different, only Canvas in Morphic-Support.

Object
NullEncoder - Morphic-Postscript Filters
 FlattenEncoder - Morphic-Postscript Filters
  Canvas - Morphic-Support
   PostscriptCanvas - Morphic-Postscript Canvases


We would probably have to ask Dan or so on the whys and wherefores…


> And PostscriptCanvas is for the use in Morphic as it has an instance
> variable 'topLevelMorph'.
>
>
>
> On 9/29/17, H. Hirzel <[hidden email]> wrote:
>> 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@200.
>> canvas fillColor: (Color black).
>> canvas line: 10@10 to: 50@30 width: 1 color: (Color red).
>> canvas frameRectangle: ((20@20) corner: (120@120)) width: 4 color:
>> (Color green).
>> canvas point: 100@100 color: (Color black).
>> canvas drawString: 'Hello, World!' at: 40@40 font: nil color: (Color
>> cyan).
>> canvas fillRectangle: ((10@80) corner: (31@121)) color: (Color magenta).
>> canvas fillOval: ((10@80) corner: (31@121)) color: (Color cyan).
>> canvas frameOval: ((40@80) corner: (61@121)) color: (Color blue).
>> canvas frameOval: ((70@80) corner: (91@121)) width: 3 color: (Color
>> red alpha: 0.2).
>> canvas fillRectangle: ((130@30) corner: (170@80)) color: (Color
>> lightYellow).
>> canvas showAt: 0@0.
>>
>>
>> This works fine in an MVC project
>>
>> --Hannes
>>
>> On 9/29/17, Tobias Pape <[hidden email]> wrote:
>>> Hi Hannes
>>>
>>>> On 29.09.2017, at 15:21, H. Hirzel <[hidden email]> wrote:
>>>>
>>>> And there is no 'FlattenEncoder' in Pharo 6
>>>
>>>>
>>>>
>>>> On 9/29/17, H. Hirzel <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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'')'
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>>
>>>
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Nicolas Cellier
In reply to this post by Hannes Hirzel
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 <[hidden email]>:
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@200.
        canvas fillColor: (Color black).
        canvas line: 10@10 to: 50@30 width: 1 color: (Color red).
        canvas frameRectangle: ((20@20) corner: (120@120)) width: 4 color:
(Color green).
        canvas point: 100@100 color: (Color black).
        canvas drawString: 'Hello, World!' at: 40@40 font: nil color: (Color cyan).
        canvas fillRectangle: ((10@80) corner: (31@121)) color: (Color magenta).
        canvas fillOval: ((10@80) corner: (31@121)) color: (Color cyan).
        canvas frameOval: ((40@80) corner: (61@121)) color: (Color blue).
        canvas frameOval: ((70@80) corner: (91@121)) width: 3 color: (Color
red alpha: 0.2).
        canvas fillRectangle: ((130@30) corner: (170@80)) color: (Color lightYellow).
        canvas showAt: 0@0.


This works fine in an MVC project

--Hannes

On 9/29/17, Tobias Pape <[hidden email]> wrote:
> Hi Hannes
>
>> On 29.09.2017, at 15:21, H. Hirzel <[hidden email]> wrote:
>>
>> And there is no 'FlattenEncoder' in Pharo 6
>
>>
>>
>> On 9/29/17, H. Hirzel <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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'')'
>>>>>
>>>>
>>>
>>
>
>
>




Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Hannes Hirzel
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.


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 <[hidden email]> 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 <[hidden email]>:
>
>> 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@200.
>>         canvas fillColor: (Color black).
>>         canvas line: 10@10 to: 50@30 width: 1 color: (Color red).
>>         canvas frameRectangle: ((20@20) corner: (120@120)) width: 4
>> color:
>> (Color green).
>>         canvas point: 100@100 color: (Color black).
>>         canvas drawString: 'Hello, World!' at: 40@40 font: nil color:
>> (Color cyan).
>>         canvas fillRectangle: ((10@80) corner: (31@121)) color: (Color
>> magenta).
>>         canvas fillOval: ((10@80) corner: (31@121)) color: (Color cyan).
>>         canvas frameOval: ((40@80) corner: (61@121)) color: (Color blue).
>>         canvas frameOval: ((70@80) corner: (91@121)) width: 3 color:
>> (Color
>> red alpha: 0.2).
>>         canvas fillRectangle: ((130@30) corner: (170@80)) color: (Color
>> lightYellow).
>>         canvas showAt: 0@0.
>>
>>
>> This works fine in an MVC project
>>
>> --Hannes
>>
>> On 9/29/17, Tobias Pape <[hidden email]> wrote:
>> > Hi Hannes
>> >
>> >> On 29.09.2017, at 15:21, H. Hirzel <[hidden email]> wrote:
>> >>
>> >> And there is no 'FlattenEncoder' in Pharo 6
>> >
>> >>
>> >>
>> >> On 9/29/17, H. Hirzel <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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'')'
>> >>>>>
>> >>>>
>> >>>
>> >>
>> >
>> >
>> >
>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Nicolas Cellier


2017-09-29 18:12 GMT+02:00 H. Hirzel <[hidden email]>:
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 <[hidden email]> 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 <[hidden email]>:
>
>> 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@200.
>>         canvas fillColor: (Color black).
>>         canvas line: 10@10 to: 50@30 width: 1 color: (Color red).
>>         canvas frameRectangle: ((20@20) corner: (120@120)) width: 4
>> color:
>> (Color green).
>>         canvas point: 100@100 color: (Color black).
>>         canvas drawString: 'Hello, World!' at: 40@40 font: nil color:
>> (Color cyan).
>>         canvas fillRectangle: ((10@80) corner: (31@121)) color: (Color
>> magenta).
>>         canvas fillOval: ((10@80) corner: (31@121)) color: (Color cyan).
>>         canvas frameOval: ((40@80) corner: (61@121)) color: (Color blue).
>>         canvas frameOval: ((70@80) corner: (91@121)) width: 3 color:
>> (Color
>> red alpha: 0.2).
>>         canvas fillRectangle: ((130@30) corner: (170@80)) color: (Color
>> lightYellow).
>>         canvas showAt: 0@0.
>>
>>
>> This works fine in an MVC project
>>
>> --Hannes
>>
>> On 9/29/17, Tobias Pape <[hidden email]> wrote:
>> > Hi Hannes
>> >
>> >> On 29.09.2017, at 15:21, H. Hirzel <[hidden email]> wrote:
>> >>
>> >> And there is no 'FlattenEncoder' in Pharo 6
>> >
>> >>
>> >>
>> >> On 9/29/17, H. Hirzel <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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'')'
>> >>>>>
>> >>>>
>> >>>
>> >>
>> >
>> >
>> >
>>
>>
>




Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

David T. Lewis
In reply to this post by Tobias Pape
On Fri, Sep 29, 2017 at 04:37:16PM +0200, Tobias Pape wrote:

> Hi Hannes
>
> > On 29.09.2017, at 15:21, H. Hirzel <[hidden email]> wrote:
> >
> > And there is no 'FlattenEncoder' in Pharo 6
>
> >
> > On 9/29/17, H. Hirzel <[hidden email]> 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
>

According to the update stream history at http://files.squeak.org/history,
NullEncoder and friends were added in  1466EncodingFilters-MPW.cs by MPW:

   Object subclass: #NullEncoder
   NullEncoder subclass: #FlattenEncoder
   FlattenEncoder subclass: #ByteEncoder
   ByteEncoder subclass: #PrintableEncoder
   PrintableEncoder subclass: #PrintEncoder
   PrintableEncoder subclass: #PropertyListEncoder
   PrintableEncoder subclass: #StoreEncoder

According to SqueakMap, MPW is Mark McCahill ([hidden email]).

According to Wikipedia, Mark McCahill at Duke is this guy: https://en.wikipedia.org/wiki/Mark_P._McCahill

According to the method time stamps, these classes date back to January 1901, so probably actually 2001.

Dave


Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Tobias Pape

> On 30.09.2017, at 01:42, David T. Lewis <[hidden email]> wrote:
>
> According to the update stream history at http://files.squeak.org/history,
> NullEncoder and friends were added in  1466EncodingFilters-MPW.cs by MPW:
>
>   Object subclass: #NullEncoder
>   NullEncoder subclass: #FlattenEncoder
>   FlattenEncoder subclass: #ByteEncoder
>   ByteEncoder subclass: #PrintableEncoder
>   PrintableEncoder subclass: #PrintEncoder
>   PrintableEncoder subclass: #PropertyListEncoder
>   PrintableEncoder subclass: #StoreEncoder
>
> According to SqueakMap, MPW is Mark McCahill ([hidden email]).

No, thats Marcel Weiher. He did a quite a lot Squeak/Postscript Stuff.
I CC'ed him.

Marcel, can you comment on the Encoder Hierarchie?
(Full thread here)

Best regards
        -Tobias


>
> According to Wikipedia, Mark McCahill at Duke is this guy: https://en.wikipedia.org/wiki/Mark_P._McCahill
>
> According to the method time stamps, these classes date back to January 1901, so probably actually 2001.
>
> Dave



Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Hannes Hirzel
Tobias, thank you for referring to Marcel Weiher as the author of the
Postscript support in Squeak.
This helped me to find the following email with comments about the
Encoder hierarchy

<citation>
Marcel Weiher
<[hidden email]> Wed, Feb 27, 2013 at 9:14 PM
To: The general-purpose Squeak developers list
<[hidden email]>

On Feb 25, 2013, at 20:22 , Nicolas Cellier
<[hidden email]> wrote:
>
> Great, that confirms my own analyze.
> But the parallel hierarchy PrintEncoder StoreEncoder and
> PropertyListEncoder are presumably not used, and were just experiments
> right?

Pretty sure, yes.

</citation>


So it seems that

NullEncoder
    FlattenEncoder
        ByteEncoder
            PrintableEncoder

are  a means to structure the code for the subclass PostscriptEncoder
and thus to help to understand how the code works (see attached screen
shot).

NullEncoder
    FlattenEncoder
        ByteEncoder
            PrintableEncoder
                PostscriptEncoder


Note that Canvas and thus then PostscriptCanvas is a subclass of FlattenEncoder.
As Nicolas Cellier points out only PostscriptCanvas and subclasses use
the NullEncoder and FlattenEncoder protocols. For example
    aMorph asEPS
calls
    ^ EPSCanvas morphAsPostscript: self rotated: false.
which at the end does
    ^target contents.
which is implemented in NullEncoder.

The question thus is how much does PostScriptCanvas rely on the
NullEncoder and FlattenEncoder protocols?

It might be quite easily possible  to reimplement the necessary
methods in PostScriptEncoder and then make Canvas a subclass of
Object.

This will allow Canvas and subclasses to be put into a separate
category 'Graphics-Canvas' in the base system.

PostScript support would then be something added on top of it.


To summarize:
--------------------

The refactoring idea brought up for discussion is thus

1. Push the necessary NullEncoder and FlattenEncoder instance variable
'target' and the necessary methods down to PostscriptCanvas

2. Make Canvas a subclass of object thus separating then Encoder
hierarchy from the Canvas hierarchy.

3. Put Canvas and some subclasses into a category 'Graphics-Canvas'

Regards

Hannes Hirzel


--Hannes

On 9/30/17, Tobias Pape <[hidden email]> wrote:

>
>> On 30.09.2017, at 01:42, David T. Lewis <[hidden email]> wrote:
>>
>> According to the update stream history at http://files.squeak.org/history,
>> NullEncoder and friends were added in  1466EncodingFilters-MPW.cs by MPW:
>>
>>   Object subclass: #NullEncoder
>>   NullEncoder subclass: #FlattenEncoder
>>   FlattenEncoder subclass: #ByteEncoder
>>   ByteEncoder subclass: #PrintableEncoder
>>   PrintableEncoder subclass: #PrintEncoder
>>   PrintableEncoder subclass: #PropertyListEncoder
>>   PrintableEncoder subclass: #StoreEncoder
>>
>> According to SqueakMap, MPW is Mark McCahill ([hidden email]).
>
> No, thats Marcel Weiher. He did a quite a lot Squeak/Postscript Stuff.
> I CC'ed him.
>
> Marcel, can you comment on the Encoder Hierarchie?
> (Full thread here)
>
> Best regards
> -Tobias
>
>
>>
>> According to Wikipedia, Mark McCahill at Duke is this guy:
>> https://en.wikipedia.org/wiki/Mark_P._McCahill
>>
>> According to the method time stamps, these classes date back to January
>> 1901, so probably actually 2001.
>>
>> Dave
>
>
>
>



NullEncoder_FlattenEncoder_ByteEncoder_PrintableEncoder_Screenshot_2017-09-30.png (372K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Hannes Hirzel
The test case in EPSCanvasTest (introduced today with MorphicExtras-hjh.210.mcz)

shows what happens if you move

     FlattenEncoder subclass: #Canvas

to
    Object subclass: Canvas

See comment there.

--Hannes

On 9/30/17, H. Hirzel <[hidden email]> wrote:

> Tobias, thank you for referring to Marcel Weiher as the author of the
> Postscript support in Squeak.
> This helped me to find the following email with comments about the
> Encoder hierarchy
>
> <citation>
> Marcel Weiher
> <[hidden email]> Wed, Feb 27, 2013 at 9:14 PM
> To: The general-purpose Squeak developers list
> <[hidden email]>
>
> On Feb 25, 2013, at 20:22 , Nicolas Cellier
> <[hidden email]> wrote:
>>
>> Great, that confirms my own analyze.
>> But the parallel hierarchy PrintEncoder StoreEncoder and
>> PropertyListEncoder are presumably not used, and were just experiments
>> right?
>
> Pretty sure, yes.
>
> </citation>
>
>
> So it seems that
>
> NullEncoder
>     FlattenEncoder
>         ByteEncoder
>             PrintableEncoder
>
> are  a means to structure the code for the subclass PostscriptEncoder
> and thus to help to understand how the code works (see attached screen
> shot).
>
> NullEncoder
>     FlattenEncoder
>         ByteEncoder
>             PrintableEncoder
>                 PostscriptEncoder
>
>
> Note that Canvas and thus then PostscriptCanvas is a subclass of
> FlattenEncoder.
> As Nicolas Cellier points out only PostscriptCanvas and subclasses use
> the NullEncoder and FlattenEncoder protocols. For example
>     aMorph asEPS
> calls
>     ^ EPSCanvas morphAsPostscript: self rotated: false.
> which at the end does
>     ^target contents.
> which is implemented in NullEncoder.
>
> The question thus is how much does PostScriptCanvas rely on the
> NullEncoder and FlattenEncoder protocols?
>
> It might be quite easily possible  to reimplement the necessary
> methods in PostScriptEncoder and then make Canvas a subclass of
> Object.
>
> This will allow Canvas and subclasses to be put into a separate
> category 'Graphics-Canvas' in the base system.
>
> PostScript support would then be something added on top of it.
>
>
> To summarize:
> --------------------
>
> The refactoring idea brought up for discussion is thus
>
> 1. Push the necessary NullEncoder and FlattenEncoder instance variable
> 'target' and the necessary methods down to PostscriptCanvas
>
> 2. Make Canvas a subclass of object thus separating then Encoder
> hierarchy from the Canvas hierarchy.
>
> 3. Put Canvas and some subclasses into a category 'Graphics-Canvas'
>
> Regards
>
> Hannes Hirzel
>
>
> --Hannes
>
> On 9/30/17, Tobias Pape <[hidden email]> wrote:
>>
>>> On 30.09.2017, at 01:42, David T. Lewis <[hidden email]> wrote:
>>>
>>> According to the update stream history at
>>> http://files.squeak.org/history,
>>> NullEncoder and friends were added in  1466EncodingFilters-MPW.cs by
>>> MPW:
>>>
>>>   Object subclass: #NullEncoder
>>>   NullEncoder subclass: #FlattenEncoder
>>>   FlattenEncoder subclass: #ByteEncoder
>>>   ByteEncoder subclass: #PrintableEncoder
>>>   PrintableEncoder subclass: #PrintEncoder
>>>   PrintableEncoder subclass: #PropertyListEncoder
>>>   PrintableEncoder subclass: #StoreEncoder
>>>
>>> According to SqueakMap, MPW is Mark McCahill ([hidden email]).
>>
>> No, thats Marcel Weiher. He did a quite a lot Squeak/Postscript Stuff.
>> I CC'ed him.
>>
>> Marcel, can you comment on the Encoder Hierarchie?
>> (Full thread here)
>>
>> Best regards
>> -Tobias
>>
>>
>>>
>>> According to Wikipedia, Mark McCahill at Duke is this guy:
>>> https://en.wikipedia.org/wiki/Mark_P._McCahill
>>>
>>> According to the method time stamps, these classes date back to January
>>> 1901, so probably actually 2001.
>>>
>>> Dave
>>
>>
>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Marcel Weiher
In reply to this post by Tobias Pape
On Sep 30, 2017, at 7:34 , Tobias Pape <[hidden email]> wrote:


No, thats Marcel Weiher. He did a quite a lot Squeak/Postscript Stuff.
I CC'ed him.

Marcel, can you comment on the Encoder Hierarchie?
(Full thread here)

Hi Tobias et al,

thanks for tagging me.  :-)

The “Encoder” classes are a Squeak version of an “object oriented pipes and filters” system I implemented in Objective-C in the late 90s:  https://github.com/mpw/MPWFoundation/tree/master/Streams.subproj

Why?  Well, because the Postscript generation code was based on my Objective-C Postscript processing code (http://www.metaobject.com/Technology/#EGOS), which is heavily based on these filters.

I have found the filters to be incredibly useful over the last 20 years, partly because they compose so well:  just like Unix pipes and filters, they are symmetric so that their input protocol ( #writeObject: ) is the same as their output protocol ( #writeObject:).  The filterSelector is there to allow filter-specific processing using double dispatch, but once the processing is done the result is once again normalized to a #writeObject:  You can therefore combine these filters any way you want.  




Another feature is that they are, like Unix filters, fundamentally incremental, so multiple processing steps are interleaved and both input and output can stream directly to/from disk/network.  When doing pre-press in the early 90ies (file sizes >> memory sizes) this was a useful feature, and it is still helpful today, see for example the first part of my UIKonf talk:


More recently, the fact that filters are dataflow-oriented and therefore don’t care much about the control flow has made them useful in implementing asynchronous processing pipelines  Think “FRP” just simpler, more readable and faster.  The Microsoft To-Do network stack is implemented using this.

With all the references to Unix P/F, it is probably no surprise that this also subsumes Unix I/O, just with the advantage of an OO hierarchy of shareable behavior.  Oh, and also the interesting feature of subsuming both filters and (output) streams, so ‘stdout’ in Objective-Smalltalk is one of these, a ByteStream that knows how to serialize objects and output them to some target that expects bytes.  And in ‘stsh’ it’s a slight variant of MPWByteStream that is more helpful to a human interacting.













filterstreams.pdf (46K) Download Attachment
filterstream-hierarchy.pdf (52K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Marcel Weiher-3
In reply to this post by Nicolas Cellier


On Sep 29, 2017, at 19:09 , Nicolas Cellier <[hidden email]> wrote:

The canvas other than PostscriptCanvas don't use the target, they are sinks.

That’s only technically true, and really an oversight.  All canvases write their output somewhere, be it a bitmap, native display surface or other ‘DisplayMedium'.  A canvas is a filter for converting morphs to this target ‘DisplayMedium’.

And having filter-canvases would be really cool :-)

Marcel



Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Tobias Pape

> On 01.10.2017, at 11:38, Marcel Weiher <[hidden email]> wrote:
>
>
>
>> On Sep 29, 2017, at 19:09 , Nicolas Cellier <[hidden email]> wrote:
>>
>> The canvas other than PostscriptCanvas don't use the target, they are sinks.
>
> That’s only technically true, and really an oversight.  All canvases write their output somewhere, be it a bitmap, native display surface or other ‘DisplayMedium'.  A canvas is a filter for converting morphs to this target ‘DisplayMedium’.
>
> And having filter-canvases would be really cool :-)

You mean like ColorMappingCanvas, AlphaBlendingCanvas, and ShadowDrawingCanvas?
(Which, by your account, should not have an own myCanvas but rather reuse target…)?

Best regards
        -Tobias

>
> Marcel
>
>


Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Nicolas Cellier


2017-10-01 12:57 GMT+02:00 Tobias Pape <[hidden email]>:

> On 01.10.2017, at 11:38, Marcel Weiher <[hidden email]> wrote:
>
>
>
>> On Sep 29, 2017, at 19:09 , Nicolas Cellier <[hidden email]> wrote:
>>
>> The canvas other than PostscriptCanvas don't use the target, they are sinks.
>
> That’s only technically true, and really an oversight.  All canvases write their output somewhere, be it a bitmap, native display surface or other ‘DisplayMedium'.  A canvas is a filter for converting morphs to this target ‘DisplayMedium’.
>
> And having filter-canvases would be really cool :-)

You mean like ColorMappingCanvas, AlphaBlendingCanvas, and ShadowDrawingCanvas?
(Which, by your account, should not have an own myCanvas but rather reuse target…)?

Best regards
        -Tobias


Hi Marcel, Tobias,
I perfectly understand what an Encoder is. OK I said it transforms stream instead of filters stream because I'm not academic enough ;).
I agree that the pattern has a lot of potential, though parallelism still is a problem in Smalltalk processing model.

But:
In a sense, the canvas did handle a stream of graphics instructions (draw a line, a circle, fill a rectangle etc...).
Even, if we don't really reify those instructions, and tell (canvas write: (Line from: ... to: ....)) but rather use a more direct (canvas drawLineFrom:to:...) send.
By making it an Encoder, it now handles both a stream of graphics instructions and a stream of objects (that can appropriately convert themselves to a stream of graphic instructions thru double dispatching).
This is a metonymy.

I will repeat why it does not sound legitimate to me:
First, a metonymy is obscuring responsibilities.
Either that's an un-necessary indirection, because objects already know how to draw themselves, and it composes well already, because an object will ask the objects that it is composed of to render themselves.
Or once we want to use it as a filter for a stream of arbitrary objects, we get a problem of composability (understand composing as giving a specific layout to the objects we want to render).
So we have to give greater responsabilities to the dumb canvas for this composition to happen.

I showed that the only place where we make use of the double dispatching technic exhibit this problem of composability (we can't render in PostScript a Morph composed of BookMorph, because we can't put several pages into a page...).

If we really want to keep the Encoder pattern, then yes, we must use the target where possible. But I'm not convinced.

--------

Note about text rendering: we generally have to recompose the layout for different target (for example, if we want to render a BookMorph on A4 paper with specific margins...). For this composition to take place, we need to know the font metrics, and use some specific rules for margins, alignment, tab stops, etc... That's what a CompositionScanner does.
I fail to see where those PostScript font metrics are in Squeak?

Rendering on PostScript is not an exception. If we are able to share some fonts then we can omit the composition step for most simple cases (like generating an EPS figure). But if we start with a bitmap font, rendering in PostScript will be very rough indeed.

For this reason, generating the PostScript in VW smalltalk goes thru a higher level indirection, the Document, which is somehow responsible for composing the layout for an arbitrary input stream of objects.
It has to cooperate with a GraphicsContext (the quivalent of our Canvas) for transforming fonts to nearest PostScript equivalent, measuring, etc...
VW has a PostScriptContext which is a specific GraphicsContext for low level rendering instructions, but that's not where everything takes place. The Document would handle the DSC for example (that sounds quite logical no?).
Also note that a Document is not conceptually bound to a Postscript target, it could be anything, even LaTeX or Word backend, in which case it could eventually delegate the composition phase (which could work for a flow of text and small graphics, but would be more delicate for math expressions, tables and figures though).

>
> Marcel
>
>





Reply | Threaded
Open this post in threaded view
|

Re: What is the task of NullEncoder?

Marcel Weiher-3
In reply to this post by Tobias Pape
On Sep 30, 2017, at 7:34 , Tobias Pape <[hidden email]> wrote:


No, thats Marcel Weiher. He did a quite a lot Squeak/Postscript Stuff.
I CC'ed him.

Marcel, can you comment on the Encoder Hierarchie?
(Full thread here)

Hi Tobias et al,

thanks for tagging me.  :-)

The “Encoder” classes are a Squeak version of an “object oriented pipes and filters” system I implemented in Objective-C in the late 90s:  https://github.com/mpw/MPWFoundation/tree/master/Streams.subproj

Why?  Well, because the Postscript generation code was based on my Objective-C Postscript processing code (http://www.metaobject.com/Technology/#EGOS), which is heavily based on these filters.

I have found the filters to be incredibly useful over the last 20 years, partly because they compose so well:  just like Unix pipes and filters, they are symmetric so that their input protocol ( #writeObject: ) is the same as their output protocol ( #writeObject:).  The filterSelector is there to allow filter-specific processing using double dispatch, but once the processing is done the result is once again normalized to a #writeObject:  You can therefore combine these filters any way you want.  




Another feature is that they are, like Unix filters, fundamentally incremental, so multiple processing steps are interleaved and both input and output can stream directly to/from disk/network.  When doing pre-press in the early 90ies (file sizes >> memory sizes) this was a useful feature, and it is still helpful today, see for example the first part of my UIKonf talk:


More recently, the fact that filters are dataflow-oriented and therefore don’t care much about the control flow has made them useful in implementing asynchronous processing pipelines  Think “FRP” just simpler, more readable and faster.  The Microsoft To-Do network stack is implemented using this.

With all the references to Unix P/F, it is probably no surprise that this also subsumes Unix I/O, just with the advantage of an OO hierarchy of shareable behavior.  Oh, and also the interesting feature of subsuming both filters and (output) streams, so ‘stdout’ in Objective-Smalltalk is one of these, a ByteStream that knows how to serialize objects and output them to some target that expects bytes.  And in ‘stsh’ it’s a slight variant of MPWByteStream that is more helpful to a human interacting.













filterstreams.pdf (46K) Download Attachment
filterstream-hierarchy.pdf (52K) Download Attachment
12