cool post Stef
On May 30, 2010, at 8:53 PM, Igor Stasenko wrote: > On 30 May 2010 17:26, Stéphane Ducasse <[email protected]> wrote: >>> Hi, >>> >>> i found rome API very close to OpenVG. >>> Still OpenVG is a bit superior :) >>> So, i'm using it as a guide to model/implement Rome interfaces. >> >> Excellent! >> >>> So, here is my thoughts (i also having a draft class skeleton for them): >> >> frankly consider that we are working on Rome because we need something >> to get access to Cairo/ whatever but we are newbie at the level. >> Now the good point for us is that we are smart newbies :) >> and ready to learn fast. >> >> So our first idea is >> - make it work (romePluginCanvas) >> - make all romeReferenceCanvas >> >> Get feedback, improve it improve it improve it >> as well as make all the code use it make all the code use it . >> >> So thanks for your brainstorming/ideas/wishes >> >> >>> Because, we could simply do: >>> >>> canvas fill: myPath with: myPaint >>> >>> instead of: >>> >>> canvas selectFill: myPaint. >>> canvas fill: myPath. >>> >>> Because you anyways can't draw a paths without paints, i don't see why >>> canvas should have a notion of 'current fill' or 'current paint'. >>> I think that with paint's encapsulation, its not necessary. >>> >>> >>> I'd like to hear your thoughts about it. >> >> No idea. Now at the back end level or "reference level" >> is there a value to separate? >> because like that you can do >> >>> canvas selectFill: myPaint. >>> canvas fill: myPath. >>> canvas fill: myPath.canvas fill: myPath.canvas fill: myPath.canvas fill: >>> myPath.canvas fill: myPath.canvas fill: myPath.canvas fill: myPath. >> > > Right. I considered that too, before proposing ;) > Selecting a paint and then drawing multiple paths using it may look > like having some value. > > But the point is, that in practice you barely will use such feature. > > For instance, lets take a morph: > > Morph>>romeDrawOn: aCanvas > aCanvas > selectFill: self fillStyle; > selectPen: self borderStyle; > drawRectangle: self bounds > > Do you seen how you can reuse a previously selected paints here? I don't. > You can't reuse, because you don't know what was selected previously > (and querying it will cost you more cycles > than just selecting a right one). > > So, that's how you will use it in 99% of cases: > > select > fill > select > fill.. > > But not > > select > fill fill fill .. > > One more example. A Tiger demo, which i did in OpenVG binding. > A Tiger takes it roots from an SVG file, so it is right to say, that > it covers the use of SVG for drawings. > In SVG, each particular path it having own stroke/fill parameters. > There is no way how you can reuse a previously selected paints, > because each unique fragment having own settings, > and even if a whole scene (as big as Tiger) using similar paints > multiple times, you still can't reuse them because you need to follow > the order of drawing (iterating over a collection of paths, but not a > collection of paints), otherwise you won't get what you expecting to > see. > > You can reuse paints by creating them, and then caching , so it won't > cost you a conversion, each time you using it. > (For instance you can convert a GradientFillStyle to appropriate paint > object, and cache it somewhere). > But selecting the paint costs nothing, and buys nothing in terms of > speed (at least in my implementation, and i suspect in every other ;) > ). > > I think that 'selection' and 'binding' mechanism in those APIs serve > only one purpose: to minimize the number of arguments > for function calls and as a workaround of having no OO. > But in smalltalk world, we having objects, which can represent any > kind of our domain objects (paths, paints etc), > and so, from OO perspective binding/selecting looks like a useless thing. > > A big downside of such selection mechanism can be illustrated by taking > OpenGL. > It is cool, when you having one window, one context, one texture and > one pencil to rule them all. > But in practice, you often need more than one canvas, window, texture etc. > And this is where such 'selection' mechanism starts standing in your way. > For instance, if you working with multiple GL contexts in squeak, the > only way how to ensure that you _always_ > working with right context is to prepend each api call with: > makeCurrent(myContextHandle). > by literally turning every gl function like: func(a, b, c) into > func(context, a, b, c) > otherwise, you can't ensure a correct behavior, when you working with > multiple contexts in multiple processes, > having high chances being interrupted by each other. > > This is where passing an extra argument(s) is preferable, because it > tells directly, with what object you wanna work with and so it > minimizes the chances to make a mess. :) > >> >> Stef >> >> >>> Paints: >>> >>> Paint is an object, which when applied to path, renders(draws) the >>> path using paint's unique properties. >>> >>> I defined two methods in paint's base class: >>> >>> fillPath: aPath on: aCanvas >>> >>> self subclassResponsibility >>> >>> strokePath: aPath on: aCanvas >>> >>> self subclassResponsibility >>> >>> So, to draw a path, one should use a concrete paint to either fill it >>> or stroke it (or both, if you want, but its handled by canvas and >>> still will end up with separate fill & stroke requests to paint). >>> >>> I started from a quite basic things: >>> >>> NullPaint >>> Paint which does not performs any drawing. >>> Applying this paint to any path won't lead to any >>> changes/processing. A simple OO approach to define 'nothing' :) >>> >>> SolidColorPaint >>> instanceVariableNames: 'color' >>> >>> Paint with solid color. Most trivial thing which can be done :) >>> >>> RomePen >>> instanceVariableNames: 'paint capStyle joinStyle width dash' >>> >>> A 'pen' paint is just encapsulating a set of properties, which is used >>> for stroke. >>> It is using another paint, which should handle the fills (in 'paint' >>> ivar), while various stroke properties should be handled by itself. >>> Filling with pen, will be the same as filling with its paint. While >>> doing a stoke is different (includes path processing, given the values >>> of pen's properties etc etc). >>> I'm not sure with this part. Maybe stroke properties would be better >>> to leave in canvas? Both OpenVG and Rome seems like following this >>> road, >>> but i don't quite like that stroke properties is global for canvas and >>> lacking a proper encapsulation. >>> >>> CompositePaint >>> Quite dumb thing. Holds a list of paints. When asked to fill or >>> stroke the path, applies paints from own list. >>> >>> GradientPaint (abstract) >>> LinearGradient >>> RadialGradient >>> etc.. >>> paints which will use gradients for fills. Nothing fancy :) >>> >>> >>> Canvas protocol: >>> >>> selectFill: anObject >>> >>> fill := anObject asRomePaintOn: self >>> >>> - selects a paint which will be used for fills. >>> >>> selectPen: anObject >>> >>> pen := anObject asRomePaintOn: self >>> >>> - selects a paint which will be used for stokes. >>> >>> >>> stroke: anObject >>> | path | >>> path := anObject asRomePathOn: self. >>> >>> fill strokePath: path on: self. >>> >>> - stroke a path using currently selected 'pen' paint >>> >>> fill: anObject >>> | path | >>> path := anObject asRomePathOn: self. >>> >>> fill fillPath: path on: self. >>> >>> - fill path using paint for fills >>> >>> >>> fillAndStroke: anObject >>> | path | >>> path := anObject asRomePathOn: self. >>> >>> fill fillPath: path on: self. >>> pen strokePath: path on: self >>> >>> - fill and stroke path. >>> >>> And from that point, i wonder, do we need to have a paint's selection >>> mechanisms at all? >>> >>> Because, we could simply do: >>> >>> canvas fill: myPath with: myPaint >>> >>> instead of: >>> >>> canvas selectFill: myPaint. >>> canvas fill: myPath. >>> >>> Because you anyways can't draw a paths without paints, i don't see why >>> canvas should have a notion of 'current fill' or 'current paint'. >>> I think that with paint's encapsulation, its not necessary. >>> >>> >>> I'd like to hear your thoughts about it. >>> >>> >>> -- >>> Best regards, >>> Igor Stasenko AKA sig. >>> >>> _______________________________________________ >>> Pharo-project mailing list >>> [email protected] >>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project >> >> >> _______________________________________________ >> Pharo-project mailing list >> [email protected] >> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project >> > > > > -- > Best regards, > Igor Stasenko AKA sig. > > _______________________________________________ > Pharo-project mailing list > [email protected] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project _______________________________________________ Pharo-project mailing list [email protected] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
