Jim, >> Few ideas to discuss: >> 1/ I wonder now if the gridding = ceil (x/y - 0.5) should be done >> differently: why not apply the offset to - 0.5 to points before curve >> decimation or adding lines: it may saves a lot of substractions: >> AddLine (x1,y1,x2,y2) implies 4 substractions whereas lineTo (x2,y2) >> only needs to adjust the last point. >> Idem for curve decimation, shifting points may help. > > > I like this idea - you can bake the translation into the transform that is applied prior to the rasterizer so there is no added work being done.
Will try asap, maybe tonight. I mean I will shift coordinates early in tosubpixx() and tosubpixy () by -0.5f. >> - do you know if the breakCurveAndAddLines (quad or cubic) really takes >> into account the supersampling scale to generate only segments needed >> and no more ? > > > I don't remember. I'd have to read the code and figure it out. Thanks, it seems there are some thresholds BND... but I am unable to find out what it is related to ? >> - I use fixed-point (32.32 + error) as you did but it is maybe too >> precise: the slope, bumpx and error could be determined from integer >> coordinates for starting / ending points = ceil (x1 - 0.5), ceil (y - >> 0.5) directly > > > I don't understand what you are getting at here...? I wonder if Renderer class could use 24.8 fixed point coordinates early in tosubpixx() and tosubpixy () to have 1/256 precision in lineTo, curveTo, quadTo before addLine and curve culling to get rid of floating-point maths early. int (24.8) = (int) ( float * 256f) It is less correct than ceil ( float * 256f - 0.5) but surely enough to maintain 1/8 precision. Of course, it will limit the output image to 2^24 = 16M pixel in both directions but is is large enough. I will make some experiments in the PathConsumer implemented by Renderer: private static float tosubpixx(final float pix_x) { return f_SUBPIXEL_POSITIONS_X * pix_x; } private static float tosubpixy(final float pix_y) { return f_SUBPIXEL_POSITIONS_Y * pix_y; } @Override public void moveTo(float pix_x0, float pix_y0) { closePath(); this.pix_sx0 = pix_x0; this.pix_sy0 = pix_y0; this.y0 = tosubpixy(pix_y0); this.x0 = tosubpixx(pix_x0); } @Override public void lineTo(float pix_x1, float pix_y1) { float x1 = tosubpixx(pix_x1); float y1 = tosubpixy(pix_y1); addLine(x0, y0, x1, y1); x0 = x1; y0 = y1; } @Override public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) { final float xe = tosubpixx(x3); final float ye = tosubpixy(y3); curve.set(x0, y0, tosubpixx(x1), tosubpixy(y1), tosubpixx(x2), tosubpixy(y2), xe, ye); curveBreakIntoLinesAndAdd(x0, y0, curve, xe, ye); x0 = xe; y0 = ye; } @Override public void quadTo(float x1, float y1, float x2, float y2) { final float xe = tosubpixx(x2); final float ye = tosubpixy(y2); curve.set(x0, y0, tosubpixx(x1), tosubpixy(y1), xe, ye); quadBreakIntoLinesAndAdd(x0, y0, curve, xe, ye); x0 = xe; y0 = ye; } @Override public void closePath() { // lineTo expects its input in pixel coordinates. lineTo(pix_sx0, pix_sy0); } @Override public void pathDone() { closePath(); } Cheers, Laurent