On 16.09.06, andrea valle wrote:
> (maybe I have to move it to the list)
Yeah, I think so. Let me cross-post my answer to the PyX users list,
since it might be of interest for others as well.
> Just a curiosity.
> I'm having some design difficulties with PyX.
> In fact, typically I have to create some objects (i.e. boxes) and then
> to stroke them on a canvas passing color and other attributes (e.g.
> So I have to define stroking function in order to pass them my objects.
> The main idea in PyX is that you have geometrical info in the object
> and other "layout" info is provided by canvas methods.
> This way of working is substantially procedural.
> To say in pseudo-code:
> canvas.stroke(object, red)
> It would be nice to write in a OO way:
> object.color = red
> So you can have thousands of object with all their layout properties
> (e.g. color, smoothing, rotation), and you decide to paint them calling
> a stroke method and passing the canvas.
> Probably in a data plotting/graphing perspective is an unrelevant
> problem, but in graphical one it would be really nice.
> What do you think?
What you're talking about is that the canvas is an object which has
some intrinsic attributes attached with. While this is an resonable
approach, the PyX development is going to go into a very different
direction. We do not want some huge lists of global properties in our
objects. Consider the graphs in PyX: They have all kind of (indirect)
properties (like axes and data and whatever), but instead of
collecting everything within the graph itself, we're trying to move
all the properties further into the parts the graph is constructed of,
for example into the axes, or even into the painters of the axes. To
my mind it's not a good idea to have huge objects with all kind of
attributes they somehow have to know about. (For example most graph
systems are misdesigned in that sense.) Instead, in PyX a canvas is a
very "thin object". I like that and it nicely fits into the idea of
being able to add features to the PyX framework without touching
any of the existing parts. For example, when we added patterns, we
could just do so. There is for example not place in the canvas which
has to know about fill patterns ...
Beside that I do understand your point in wanting to set global
properties. But this is something different. In former versions of PyX
there was the functionality of setting attributes of a canvas. You
could have said: canvas.set([color.rgb.red]). But we never focused on
this feature and finally removed it already (IIRC). But there's still
the option to set some attributes in the canvas constructor (like
canvas.canvas([color.rgb.red])). I'm not sure whether this is still
working, but if it is, it's not going to stay either. We don't want
to have a (changeable) attribute state (or any internal state at all)
within a canvas instance. Instead, the canvas instance should become
However (and this may surprise you), this does *not* mean that we
don't want to be able to set attributes "globally". Here's how you can
do that (and that's the prefered way in the long term, at least as far
as I am concerned and I can confirm that my opinion has some weight in
the PyX development):
c = canvas.canvas()
c2 = canvas.canvas()
c2.stroke(path.line(0, 0, 1, 1))
c2.stroke(path.line(0, 1, 1, 0))
The code is untested, but I hope there's not typo. Anyway, you get an
idea of what I'm talking about, right? The key point is that we want
to have a canvas to be a very simplistic object ... to be just a
collection of canvas items *together* with attributes *each* (a canvas
item is a combination of an object and some attributes, compare to the
difference between a path and a decoratored path). So attributes are
properties of canvas items but not of the canvas itself. The only
feature is that a canvas can become a canvas item itself: you can
insert a canvas into another canvas.
I do know this might lead to a little more lines of code, but it has
certain structural advantages. For example a canvas does not need to
take care of its graphic state and no gsave/grestore operations are
needed to ensure this (as it's done at the moment, but as I said, we
are about to remove that and by that we will get rid of all the
unnecessary gsave/grestore statements and only keep the needed ones).
And it's a very simple and clean concept. I like it ...
by _ _ _ Dr. André Wobst
/ \ \ / ) wobsta@..., http://www.wobsta.de/
/ _ \ \/\/ / PyX - High quality PostScript and PDF figures
(_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/