Hi Petr,
I flipped your functions, because I need to discuss them in reverted
order... :-)
> void RasterPainterDevice::_renderPath(const Path& path, bool stroke) {
> AggPath aggPath(path);
> ConvCurve curvesPath(aggPath);
>
> _ras.reset();
> _ras.filling_rule(static_cast<agg::filling_rule_e>(_fillMode));
> _ras.clip_box(
> (double)_clipBox.x1(),
> (double)_clipBox.y1(),
> (double)_clipBox.x2()-0.000001,
> (double)_clipBox.y2()-0.000001);
[...]
If your _clipBox is in pixel indices, ie. x1() refers to the index of the
left pixel and x2() refers to the index of the right pixel, then it needs
to be like this:
_ras.clip_box(
(double)_clipBox.x1(),
(double)_clipBox.y1(),
(double)_clipBox.x2() + 1,
(double)_clipBox.y2() + 1);
That's because the rasterizer clipping is still at a "geometry level". If
your clipBox can be non-integer, but you still want pixel based clipping,
then it needs to be like this:
_ras.clip_box(
floor(_clipBox.x1()),
floor(_clipBox.y1(),
ceil(_clipBox.x2()),
ceil(_clipBox.y2()));
In any case, you need to include the pixels at the last colum/row by
rounding up or adding "+ 1" for integer based pixel indices clipping boxen.
> template<int BytesPerPixel, class Rasterizer, class Scanline> static void
> FOG_OPTIMIZEDCALL AggRenderScanlines(RasterPainterDevice* d, Rasterizer&
> ras, Scanline& sl)
> {
> if (!ras.rewind_scanlines()) return;
>
> uint8_t* pBase = d->_workRaster;
> uint8_t* pRas;
> uint8_t* pCur;
> sysint_t stride = d->_stride;
>
> sl.reset(ras.min_x(), ras.max_x());
>
> // TODO: Not needed ?
> // int extx1 = painter_d->_realRegion.extents().x1();
> // int exty1 = d->_clipBox.y1();
> // int extx2 = painter_d->_realRegion.extents().x2();
> // int exty2 = d->_clipBox.y2();
>
> FillSpan fillSpan = d->_fillFuncs.fillSpan;
> FillSpanM fillSpanM_A8 = d->_fillFuncs.fillSpanM_A8;
>
> // solid source
> if (1)
> {
> while (ras.sweep_scanline(sl))
> {
> unsigned num_spans = sl.num_spans();
> typename Scanline::const_iterator span = sl.begin();
>
> sysint_t y = sl.y();
>
> // TODO: Not needed ?
> // Vertical clipping to extents.
> // if (y < exty1) continue;
> // if (y >= exty2) break;
>
> pRas = pBase + y * stride;
>
> for (;;)
> {
> int x = span->x;
> int len = span->len;
>
> pCur = pRas + Raster::mul<int, BytesPerPixel>(x);
>
> if (len > 0)
> {
> fillSpanM_A8(pCur, &d->_source, span->covers, (unsigned)len);
> }
> else
> {
> len = -len;
> FOG_ASSERT(len > 0);
>
> uint32_t cover = (uint32_t)*(span->covers);
> if (cover == 0xFF)
> {
> fillSpan(pCur, &d->_source, len);
> }
> else
> {
> uint32_t t = Raster::bytemul(d->_source.i, cover);
> fillSpan(pCur, &t, len);
> }
> }
>
> if (--num_spans == 0) break;
> ++span;
> }
> }
> }
> }
Since you are doing your own rendering, I suspect that the error is
somewhere there. I am not 100% sure that if you setup rasterizer clipping,
that it will never render outside that box. I think it doesn't, but it
would be thinkable that it still touches outside pixels with cover of 0.
But I find that highly unlikely. At least I have never seen any problems in
this regard, but I also usually setup clipping on the renderer as well. In
your place, I would simply add the necessary debugging facilities to make
sure of this. My first suspicion would be that the out of bounds access
happens somewhere in your code. Possibly the fillSpan routines.
Best regards,
-Stephan
------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image
processing features enabled.
http://p.sf.net/sfu/kodak-com_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general