2014-05-26 18:01 GMT+02:00 Tomasz Boczkowski <penginsbacon@...400...>:
Hi!
Tavmjonh Bah has suggested me to contact you and consult SPPaintServer class refactoring I would like to do.
Currently SPPaintServer contains pattern_new method. Since it directly handles rendering and uses cairo, I think it could be moved outside of SP tree.
My idea is to implement paint server drawing routines in a parallel hierarchy of classes belonging to New Renderer. Image [1] contains the class diagram. Common base for them would be NRPaintServer, containing pure virtual method pattern_new. Concrete NRPaintServer derivatives would contain a reference to corresponding SPTree items and use it while rendering.
This is not the correct solution - see below. The current design of pattern rendering is broken and needs to be significantly changed, instead of transferring this brokenness to the display (NR) tree
To choose an appropriate NRPaintServer for given SPPaintServer I thought about a factory method in NRPaintServer class. Example interfaces and their usage are shown at [2]
The tricky part can be the implementation of NRPaintServer::create method. I have thought about two solutions: a) using a battery of dynamic_cast if statements like this: NRPaintServer* NRPaintServer::create(SPPaintServer* ps) { SPPattern* pattern = dynamic_cast<SPPattern*>ps; if (pattern != 0) { return new NRPattern(&pattern); } //and so on for gradients }
This design has a major problem: it introduces a dependency of the display tree on the SP tree. Until now, the display tree had no awareness of the SP tree beyond storing a few opaque pointers.
b) using double-dispatch strategy. There would be an .cpp file internal class NRPaintServerFactory. class NRPaintServerFactory { public: virtual NRPaintServer* create(SPPaintServer*); virtual NRPaintServer* create(SPLinearGradient*); virtual NRPaintServer* create(SPRadialGradient*); //and so on }
And NRPaintServer::create implementation would look like this: NRPaintServer* NRPaintServer::create(SPPaintServer* ps) { static NRPaintServerFactory *factory = new NRPaintServerFactory; return factory->create(ps); }
This suffers from the same problem.
The correct solution is not to copy the SP tree hierarchy to the display tree, but to add patterns as another kind of child node, just like it is done for masks and clipping paths. This will also fix some performance problems we have with large bitmaps inside patterns. I will provide more details later this week.
Regards, Krzysztof