Something special about Cairo glyph draws?
There is something strange going on related to glyph draws through Cairo which I have not been able to figure out. Hopefully fresh eyes will spot the problem.
In drawing-text.cpp this is the code that outputs the series of glyphs which put text on the screen, slightly modified to put a line over the glyphs (my changes all start at the first character on the line and end with "//"):
Geom::Affine aff; // bool aff_set = false; // for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { if(!aff_set){ // aff = g->_ctm; // aff_set=true; // } // DrawingGlyphs *g = dynamic_cast<DrawingGlyphs *>(&*i); if (!g) throw InvalidItemException();
Inkscape::DrawingContext::Save save(ct); if (g->_ctm.isSingular()) continue; ct.transform(g->_ctm); ct.path(*g->_font->PathVector(g->_glyph)); } // draw a rectangle over all of the glyphs, tsp_width_adj has the correct value if(aff_set){ // ct.transform(aff); // ct.rectangle( Geom::Rect(Geom::Point(0.0,0.0),Geom::Point(tsp_width_adj, 0.1)) ); // } //
The strange thing is that the rectangle draw results in an XOR against the underlying glyphs. (Overlaps are not filled.) The reason this is bizarre is that when the code is modified so that the glyphs overlap each other (easy to do, just change the "g->_ctm" in ct.transform() to "aff") the glyphs do not XOR against each other. Use a string like "XO" to see this. Instead they just draw over each other, as one would expect for all of these draws.
I thought the XOR might have something to do with the ct.rectangle() call, so made an alternate version where the rectangle is first converted to a (closed) PathVector "rectpath" and then this is done:
ct.transform(aff); // ct.path(rectpath); //
Unfortunately, this also had the XOR effect.
I am puzzled. Where is the XOR effect coming from? More to the point, what is special about the glyph paths so that if they overlap there is no XOR, but a glyph and a rectangle or another path do XOR?
By placing a DEBUG print statement at the top of _renderItem() one can see that this method is called twice for every string (actually <tspan>) in the document which is updated/changed. I suppose the XOR effect might have something to do with that, but it does not really make sense either, since the glyphs are drawn as many times as the overlapping line.
Thanks,
David Mathog mathog@...1176... Manager, Sequence Analysis Facility, Biology Division, Caltech
2013/3/26 mathog <mathog@...1176...>:
The strange thing is that the rectangle draw results in an XOR against the underlying glyphs. (Overlaps are not filled.) The reason this is bizarre is that when the code is modified so that the glyphs overlap each other (easy to do, just change the "g->_ctm" in ct.transform() to "aff") the glyphs do not XOR against each other. Use a string like "XO" to see this. Instead they just draw over each other, as one would expect for all of these draws.
If changing the fill rule has no effect, it's likely that your rectangle is counterdirectional with respect to the glyphs. Try reversing the order in which rectangle points are addedto the path.
If that doesn't help, you should draw the glyphs and the line in two separate calls to a temporary bitmap, then use it as a mask to paint the fill color.
Regards, Krzysztof
On 26-Mar-2013 13:25, Krzysztof Kosiński wrote:
If changing the fill rule has no effect, it's likely that your rectangle is counterdirectional with respect to the glyphs. Try reversing the order in which rectangle points are addedto the path.
That was it.
David Mathog mathog@...1176... Manager, Sequence Analysis Facility, Biology Division, Caltech
participants (2)
-
Krzysztof Kosiński
-
mathog