X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftrunk%2Fsrc%2Fsynfig%2Flayer_shape.cpp;h=2116d2f4e1229113ba6a59d3be3b5872837df34c;hb=9459638ad6797b8139f1e9f0715c96076dbf0890;hp=c9af3f285ef173155d01926f441b6e7abfe5b9e6;hpb=92397cbcf72385d082daccd6352379a65c12694f;p=synfig.git diff --git a/synfig-core/trunk/src/synfig/layer_shape.cpp b/synfig-core/trunk/src/synfig/layer_shape.cpp index c9af3f2..2116d2f 100644 --- a/synfig-core/trunk/src/synfig/layer_shape.cpp +++ b/synfig-core/trunk/src/synfig/layer_shape.cpp @@ -1,11 +1,12 @@ /* === S Y N F I G ========================================================= */ /*! \file layer_shape.cpp -** \brief Template Header +** \brief Implementation of the "Shape" layer ** ** $Id$ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2007, 2008 Chris Moore ** ** This package is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License as @@ -59,8 +60,8 @@ using namespace etl; SYNFIG_LAYER_INIT(Layer_Shape); SYNFIG_LAYER_SET_NAME(Layer_Shape,"shape"); -SYNFIG_LAYER_SET_LOCAL_NAME(Layer_Shape,_("Shape")); -SYNFIG_LAYER_SET_CATEGORY(Layer_Shape,_("Internal")); +SYNFIG_LAYER_SET_LOCAL_NAME(Layer_Shape,N_("Shape")); +SYNFIG_LAYER_SET_CATEGORY(Layer_Shape,N_("Internal")); SYNFIG_LAYER_SET_VERSION(Layer_Shape,"0.1"); SYNFIG_LAYER_SET_CVS_ID(Layer_Shape,"$Id$"); @@ -233,7 +234,7 @@ struct MonoSegment int intersect(Real x,Real y) const { - if((y < aabb.miny) | (y > aabb.maxy) | (x < aabb.minx)) return 0; + if((y < aabb.miny+EPSILON) || (y > aabb.maxy) || (x < aabb.minx)) return 0; if(x > aabb.maxx) return ydir; //int i = 0; @@ -244,11 +245,13 @@ struct MonoSegment //assumes that the rect culled away anything that would be beyond the edges if(ydir > 0) { - while(y > (*++p)[1]); + while(y > (*++p)[1]) + ; } else { - while(y < (*++p)[1]); + while(y < (*++p)[1]) + ; } //for the loop to break there must have been a slope (straight line would do nothing) @@ -316,7 +319,7 @@ struct CurveArray degrees.push_back(2); } - static int intersect_conic(Real x, Real y, Point *p, int level = 0) + static int intersect_conic(Real x, Real y, Point *p, int /*level*/ = 0) { Real ymin,ymax,xmin,xmax; int intersects = 0; @@ -330,17 +333,17 @@ struct CurveArray //to the left, to the right and out of range y, or completely out of range y if( x < xmin ) return 0; - if( x > xmax & (y > ymax | y < ymin) ) return 0; - if( (y > ymax & y > p[1][1]) | (y < ymin & y < p[1][1]) ) return 0; + if( x > xmax && (y > ymax || y < ymin) ) return 0; + if( (y > ymax && y > p[1][1]) || (y < ymin && y < p[1][1]) ) return 0; //degenerate line max - if(ymin == ymax == p[1][1]) + if(ymin == ymax && ymax == p[1][1]) return 0; //degenerate accept - to the right and crossing the base line if(x > xmax) { - return (y <= ymax & y >= ymin); + return (y <= ymax && y >= ymin); } //solve for curve = y @@ -381,7 +384,7 @@ struct CurveArray } //calculate number of intersections - if(t1 >= 0 & t1 <= 1) + if(t1 >= 0 && t1 <= 1) { const Real t = t1; const Real invt = 1 - t; @@ -396,7 +399,7 @@ struct CurveArray } } - if(t2 >= 0 & t2 <= 1) + if(t2 >= 0 && t2 <= 1) { const Real t = t2; const Real invt = 1 - t; @@ -440,7 +443,7 @@ struct CurveArray const Real cn[4] = {a,b,c,d}; Real p,dp,newt,oldpmag=FLT_MAX; - //eval cubic eqn and it's derivative + //eval cubic eqn and its derivative for(;;) { p = cn[0]*t + cn[1]; @@ -471,7 +474,7 @@ struct CurveArray } } - static int intersect_cubic(Real x, Real y, Point *p, int level = 0) + static int intersect_cubic(Real x, Real y, Point *p, int /*level*/ = 0) { const Real INVALIDROOT = -FLT_MAX; Real ymin,ymax,xmin,xmax; @@ -504,7 +507,7 @@ struct CurveArray //right of curve (and outside base range) if( x > xmax ) { - if( (y > ymax) | (y < ymin) ) return 0; + if( (y > ymax) || (y < ymin) ) return 0; //degenerate accept - to the right and inside the [ymin,ymax] range (already rejected if out of range) const Real n = p[3][1] - p[0][1]; @@ -582,7 +585,7 @@ struct CurveArray t3 = -2.0*sqrt(Q)*cos((theta-2*PI)/3.0) - an/3.0; //don't need to reorder,l just need to eliminate double/triple roots - //if(t3 == t2 & t1 == t2) t2 = t3 = INVALIDROOT; + //if(t3 == t2 && t1 == t2) t2 = t3 = INVALIDROOT; if(t3 == t2) t2 = t3 = INVALIDROOT; if(t1 == t2) t1 = t2 = INVALIDROOT; if(t1 == t3) t1 = t3 = INVALIDROOT; @@ -604,7 +607,7 @@ struct CurveArray //if(t1 != INVALIDROOT) { t = t1;//polish_cubicroot(a,b,c,d,t1,&dydt); - if(t >= 0 & t < 1) + if(t >= 0 && t < 1) { //const Real invt = 1 - t; @@ -622,7 +625,7 @@ struct CurveArray //if(t2 != INVALIDROOT) { t = t2;//polish_cubicroot(a,b,c,d,t2,&dydt); - if(t >= 0 & t < 1) + if(t >= 0 && t < 1) { //const Real invt = 1 - t; @@ -640,7 +643,7 @@ struct CurveArray //if(t3 != INVALIDROOT) { t = t3;//polish_cubicroot(a,b,c,d,t3,&dydt); - if(t >= 0 & t < 1) + if(t >= 0 && t < 1) { //const Real invt = 1 - t; @@ -660,7 +663,7 @@ struct CurveArray int intersect(Real x,Real y, Point *table) const { - if((y < aabb.miny) | (y > aabb.maxy) | (x < aabb.minx)) return 0; + if((y < aabb.miny) || (y > aabb.maxy) || (x < aabb.minx)) return 0; int i, curdeg, intersects = 0; const int numcurves = degrees.size(); @@ -712,7 +715,7 @@ struct Layer_Shape::Intersector { Rect aabb; - //! true iff aabb hasn't been initialised yet + //! true iff aabb hasn't been initialized yet bool initaabb; int flags; @@ -745,7 +748,7 @@ struct Layer_Shape::Intersector bool notclosed() { - return (flags & NotClosed) | (cur_x != close_x) | (cur_y != close_y); + return (flags & NotClosed) || (cur_x != close_x) || (cur_y != close_y); } void move_to(Real x, Real y) @@ -771,7 +774,7 @@ struct Layer_Shape::Intersector int dir = (y > cur_y)*1 + (-1)*(y < cur_y); //check for context (if not line start a new segment) - //if we're not in line mode (cover's 0 set case), or if directions are different (not valid for 0 direction) + //if we're not in line mode (covers 0 set case), or if directions are different (not valid for 0 direction) if(prim != TYPE_LINE || (dir && segs.back().ydir != dir)) { MonoSegment seg(dir,x,x,y,y); @@ -792,7 +795,7 @@ struct Layer_Shape::Intersector cur_x = x; cur_y = y; - aabb.expand(x,y); //expand the entire things bounding box + aabb.expand(x,y); //expand the entire thing's bounding box tangent[0] = x - cur_x; tangent[1] = x - cur_y; @@ -944,7 +947,7 @@ struct PenMark void setcover(Real c, Real a) { cover = c; area = a; } void addcover(Real c, Real a) { cover += c; area += a; } - bool operator < (const PenMark &rhs) const + bool operator<(const PenMark &rhs) const { return y == rhs.y ? x < rhs.x : y < rhs.y; } @@ -994,7 +997,7 @@ public: bool notclosed() const { - return (flags & NotClosed) | (cur_x != close_x) | (cur_y != close_y); + return (flags & NotClosed) || (cur_x != close_x) || (cur_y != close_y); } //0 out all the variables involved in processing @@ -1019,7 +1022,7 @@ public: //move to the next cell (cover values 0 initially), keeping the current if necessary void move_pen(int x, int y) { - if(y != current.y | x != current.x) + if(y != current.y || x != current.x) { addcurrent(); current.set(x,y,0,0); @@ -1089,19 +1092,27 @@ public: void draw_scanline(int y, Real x1, Real y1, Real x2, Real y2); void draw_line(Real x1, Real y1, Real x2, Real y2); - Real ExtractAlpha(Real area) + Real ExtractAlpha(Real area, WindingStyle winding_style) { - //non-zero winding style - if(area < 0) area = -area; - if(area > 1) area = 1; + if (area < 0) + area = -area; - //even-odd winding style - /*if(area < 0) area = -area; + if (winding_style == WINDING_NON_ZERO) + { + // non-zero winding style + if (area > 1) + return 1; + } + else // if (winding_style == WINDING_EVEN_ODD) + { + // even-odd winding style + while (area > 1) + area -= 2; - while(area > 2) area -= 2; - if(area > 1) area = 1-area; //want pyramid like thing - */ - //broken? - yep broken + // want pyramid like thing + if (area < 0) + area = -area; + } return area; } @@ -1113,11 +1124,12 @@ Layer_Shape::Layer_Shape(const Real &a, const Color::BlendMethod m): Layer_Composite (a,m), edge_table (new Intersector), color (Color::black()), - offset (0,0), + origin (0,0), invert (false), antialias (true), blurtype (Blur::FASTGAUSSIAN), feather (0), + winding_style (WINDING_NON_ZERO), bytestream (0), lastbyteop (Primitive::NONE), lastoppos (-1) @@ -1139,12 +1151,17 @@ Layer_Shape::clear() bool Layer_Shape::set_param(const String & param, const ValueBase &value) { - IMPORT(color); - IMPORT(offset); + IMPORT_PLUS(color, { if (color.get_a() == 0) { if (converted_blend_) { + set_blend_method(Color::BLEND_ALPHA_OVER); + color.set_a(1); } else transparent_color_ = true; } }); + IMPORT(origin); IMPORT(invert); IMPORT(antialias); - IMPORT(feather); + IMPORT_PLUS(feather, if(feather<0)feather=0;); IMPORT(blurtype); + IMPORT(winding_style); + + IMPORT_AS(origin,"offset"); return Layer_Composite::set_param(param,value); } @@ -1153,11 +1170,12 @@ ValueBase Layer_Shape::get_param(const String ¶m)const { EXPORT(color); - EXPORT(offset); + EXPORT(origin); EXPORT(invert); EXPORT(antialias); EXPORT(feather); EXPORT(blurtype); + EXPORT(winding_style); EXPORT_NAME(); EXPORT_VERSION(); @@ -1174,8 +1192,8 @@ Layer_Shape::get_param_vocab()const .set_local_name(_("Color")) .set_description(_("Layer_Shape Color")) ); - ret.push_back(ParamDesc("offset") - .set_local_name(_("Position")) + ret.push_back(ParamDesc("origin") + .set_local_name(_("Origin")) ); ret.push_back(ParamDesc("invert") .set_local_name(_("Invert")) @@ -1197,6 +1215,13 @@ Layer_Shape::get_param_vocab()const .add_enum_value(Blur::GAUSSIAN,"gaussian",_("Gaussian Blur")) .add_enum_value(Blur::DISC,"disc",_("Disc Blur")) ); + ret.push_back(ParamDesc("winding_style") + .set_local_name(_("Winding Style")) + .set_description(_("Winding style to use")) + .set_hint("enum") + .add_enum_value(WINDING_NON_ZERO,"nonzero",_("Non Zero")) + .add_enum_value(WINDING_EVEN_ODD,"evenodd",_("Even/Odd")) + ); return ret; } @@ -1204,7 +1229,7 @@ Layer_Shape::get_param_vocab()const synfig::Layer::Handle Layer_Shape::hit_check(synfig::Context context, const synfig::Point &p)const { - Point pos(p-offset); + Point pos(p-origin); int intercepts = edge_table->intersect(pos[0],pos[1]); @@ -1251,7 +1276,7 @@ Layer_Shape::get_color(Context context, const Point &p)const if(feather) pp = Blur(feather,feather,blurtype)(p); - Point pos(pp-offset); + Point pos(pp-origin); int intercepts = edge_table->intersect(pos[0],pos[1]); @@ -1260,7 +1285,7 @@ Layer_Shape::get_color(Context context, const Point &p)const bool intersect = ((!!intercepts) ^ invert); if(!intersect) - return context.get_color(pp); + return Color::blend(Color::alpha(),context.get_color(pp),get_amount(),get_blend_method()); //Ok, we're inside... bummmm ba bum buM... if(get_blend_method() == Color::BLEND_STRAIGHT && get_amount() == 1) @@ -1272,7 +1297,7 @@ Layer_Shape::get_color(Context context, const Point &p)const //************** SCANLINE RENDERING ********************* void Layer_Shape::PolySpan::line_to(Real x, Real y) { - Real n[4]; + Real n[4] = {0,0,0,0}; bool afterx = false; const Real xin(x), yin(y); @@ -1283,8 +1308,8 @@ void Layer_Shape::PolySpan::line_to(Real x, Real y) //CLIP IT!!!! try { //outside y - ignore entirely - if( (cur_y >= window.maxy & y >= window.maxy) - |(cur_y < window.miny & y < window.miny) ) + if( (cur_y >= window.maxy && y >= window.maxy) + ||(cur_y < window.miny && y < window.miny) ) { cur_x = x; cur_y = y; @@ -1309,7 +1334,7 @@ void Layer_Shape::PolySpan::line_to(Real x, Real y) //generate data for the ending clipped info if(y > window.maxy) { - //intial line to intersection (and degenerate) + //initial line to intersection (and degenerate) n[2] = x + (window.maxy - y) * dx / dy; //intersect coords @@ -1333,7 +1358,7 @@ void Layer_Shape::PolySpan::line_to(Real x, Real y) //generate data for the ending clipped info if(y < window.miny) { - //intial line to intersection (and degenerate) + //initial line to intersection (and degenerate) n[2] = x + (window.miny - y) * dx / dy; //intersect coords @@ -1383,7 +1408,7 @@ void Layer_Shape::PolySpan::line_to(Real x, Real y) //generate data for the ending clipped info if(x > window.maxx) { - //intial line to intersection (and degenerate) + //initial line to intersection (and degenerate) n[2] = y + (window.maxx - x) * dy / dx; n[0] = window.maxx; @@ -1412,7 +1437,7 @@ void Layer_Shape::PolySpan::line_to(Real x, Real y) //generate data for the ending clipped info if(x < window.minx) { - //intial line to intersection (and degenerate) + //initial line to intersection (and degenerate) n[2] = y + (window.minx - x) * dy / dx; n[0] = window.minx; @@ -1450,9 +1475,9 @@ static inline bool clip_conic(const Point *const p, const ContextRect &r) const Real maxx = max(max(p[0][0],p[1][0]),p[2][0]); const Real maxy = max(max(p[0][1],p[1][1]),p[2][1]); - return (minx > r.maxx) | - (maxx < r.minx) | - (miny > r.maxy) | + return (minx > r.maxx) || + (maxx < r.minx) || + (miny > r.maxy) || (maxy < r.miny); } @@ -1468,10 +1493,10 @@ static inline bool clip_cubic(const Point *const p, const ContextRect &r) (miny > r.maxy) || (maxy < r.miny);*/ - return ((p[0][0] > r.maxx) & (p[1][0] > r.maxx) & (p[2][0] > r.maxx) & (p[3][0] > r.maxx)) | - ((p[0][0] < r.minx) & (p[1][0] < r.minx) & (p[2][0] < r.minx) & (p[3][0] < r.minx)) | - ((p[0][1] > r.maxy) & (p[1][1] > r.maxy) & (p[2][1] > r.maxy) & (p[3][1] > r.maxy)) | - ((p[0][1] < r.miny) & (p[1][1] < r.miny) & (p[2][1] < r.miny) & (p[3][1] < r.miny)); + return ((p[0][0] > r.maxx) && (p[1][0] > r.maxx) && (p[2][0] > r.maxx) && (p[3][0] > r.maxx)) || + ((p[0][0] < r.minx) && (p[1][0] < r.minx) && (p[2][0] < r.minx) && (p[3][0] < r.minx)) || + ((p[0][1] > r.maxy) && (p[1][1] > r.maxy) && (p[2][1] > r.maxy) && (p[3][1] > r.maxy)) || + ((p[0][1] < r.miny) && (p[1][1] < r.miny) && (p[2][1] < r.miny) && (p[3][1] < r.miny)); } static inline Real max_edges_cubic(const Point *const p) @@ -1529,7 +1554,7 @@ void Layer_Shape::PolySpan::conic_to(Real x1, Real y1, Real x, Real y) { if(num >= MAX_SUBDIVISION_SIZE) { - warning("Curve subdivision somehow ran out of space while tesselating!"); + warning("Curve subdivision somehow ran out of space while tessellating!"); //do something... assert(0); @@ -1602,7 +1627,7 @@ void Layer_Shape::PolySpan::cubic_to(Real x1, Real y1, Real x2, Real y2, Real x, { if(num >= MAX_SUBDIVISION_SIZE) { - warning("Curve subdivision somehow ran out of space while tesselating!"); + warning("Curve subdivision somehow ran out of space while tessellating!"); //do something... assert(0); @@ -1680,7 +1705,7 @@ void Layer_Shape::PolySpan::draw_scanline(int y, Real x1, Real fy1, Real x2, Rea //case all in same pixel if(ix1 == ix2) //impossible for degenerate case (covered by the previous cases) { - current.addcover(dy,(fx1 + fx2)*dy/2); //horizontal trapazoid area + current.addcover(dy,(fx1 + fx2)*dy/2); //horizontal trapezoid area return; } @@ -1694,7 +1719,7 @@ void Layer_Shape::PolySpan::draw_scanline(int y, Real x1, Real fy1, Real x2, Rea mult = (1 - fx1)*dydx; //next y intersection diff value (at 1) //first pixel - current.addcover(mult,(1 + fx1)*mult/2); // fx1,fy1,1,fy@1 - starting trapazoidal area + current.addcover(mult,(1 + fx1)*mult/2); // fx1,fy1,1,fy@1 - starting trapezoidal area //move to the next pixel fy1 += mult; @@ -1730,7 +1755,7 @@ void Layer_Shape::PolySpan::draw_scanline(int y, Real x1, Real fy1, Real x2, Rea mult = fx1*dydx; //next y intersection diff value //first pixel - current.addcover(mult,fx1*mult/2); // fx1,fy1,0,fy@0 - starting trapazoidal area + current.addcover(mult,fx1*mult/2); // fx1,fy1,0,fy@0 - starting trapezoidal area //move to next pixel fy1 += mult; @@ -1858,7 +1883,7 @@ void Layer_Shape::PolySpan::draw_line(Real x1, Real y1, Real x2, Real y2) mult = (1 - fy1) * dxdy; - //x interset scanline + //x intersect scanline x_from = x1 + mult; draw_scanline(iy1,x1,fy1,x_from,1); @@ -1888,7 +1913,7 @@ void Layer_Shape::PolySpan::draw_line(Real x1, Real y1, Real x2, Real y2) mult = fy1 * dxdy; - //x interset scanline + //x intersect scanline x_from = x1 + mult; draw_scanline(iy1,x1,fy1,x_from,0); @@ -1967,7 +1992,7 @@ void Layer_Shape::endpath() op.operation = Primitive::END; op.number = 0; - if(lastbyteop == Primitive::END | lastbyteop == Primitive::NONE) + if(lastbyteop == Primitive::END || lastbyteop == Primitive::NONE) { }else { @@ -1988,7 +2013,7 @@ void Layer_Shape::line_to(Real x, Real y) op.operation = Primitive::LINE_TO; op.number = 1; //one point for now - if(lastbyteop == Primitive::MOVE_TO | lastbyteop == Primitive::LINE_TO) + if(lastbyteop == Primitive::MOVE_TO || lastbyteop == Primitive::LINE_TO) { //only need to insert the point bytestream.insert(bytestream.end(),(char*)&p,(char*)(&p+1)); @@ -2185,7 +2210,7 @@ bool Layer_Shape::render_polyspan(Surface *surface, PolySpan &polyspan, //accumulate for the current pixel while(++cur_mark != polyspan.covers.end()) { - if(y != cur_mark->y | x != cur_mark->x) + if(y != cur_mark->y || x != cur_mark->x) break; area += cur_mark->area; @@ -2195,7 +2220,7 @@ bool Layer_Shape::render_polyspan(Surface *surface, PolySpan &polyspan, //draw pixel - based on covered area if(area) //if we're ok, draw the current pixel { - alpha = polyspan.ExtractAlpha(cover - area); + alpha = polyspan.ExtractAlpha(cover - area, winding_style); if(invert) alpha = 1 - alpha; if(!antialias) @@ -2232,7 +2257,7 @@ bool Layer_Shape::render_polyspan(Surface *surface, PolySpan &polyspan, //draw span to next pixel - based on total amount of pixel cover if(x < cur_mark->x) { - alpha = polyspan.ExtractAlpha(cover); + alpha = polyspan.ExtractAlpha(cover, winding_style); if(invert) alpha = 1 - alpha; if(!antialias) @@ -2311,7 +2336,7 @@ bool Layer_Shape::render_polyspan(etl::surface *surface, PolySpan &polysp //accumulate for the current pixel while(++cur_mark != polyspan.covers.end()) { - if(y != cur_mark->y | x != cur_mark->x) + if(y != cur_mark->y || x != cur_mark->x) break; area += cur_mark->area; @@ -2321,7 +2346,7 @@ bool Layer_Shape::render_polyspan(etl::surface *surface, PolySpan &polysp //draw pixel - based on covered area if(area) //if we're ok, draw the current pixel { - alpha = 1 - polyspan.ExtractAlpha(cover - area); + alpha = 1 - polyspan.ExtractAlpha(cover - area, winding_style); if(!antialias) { if(alpha >= .5) p.put_value(); @@ -2353,7 +2378,7 @@ bool Layer_Shape::render_polyspan(etl::surface *surface, PolySpan &polysp //draw span to next pixel - based on total amount of pixel cover if(x < cur_mark->x) { - alpha = 1 - polyspan.ExtractAlpha(cover); + alpha = 1 - polyspan.ExtractAlpha(cover, winding_style); if(!antialias) { if(alpha >= .5) p.put_hline(cur_mark->x - x); @@ -2383,7 +2408,7 @@ bool Layer_Shape::render_polyspan(etl::surface *surface, PolySpan &polysp //accumulate for the current pixel while(++cur_mark != polyspan.covers.end()) { - if(y != cur_mark->y | x != cur_mark->x) + if(y != cur_mark->y || x != cur_mark->x) break; area += cur_mark->area; @@ -2393,7 +2418,7 @@ bool Layer_Shape::render_polyspan(etl::surface *surface, PolySpan &polysp //draw pixel - based on covered area if(area) //if we're ok, draw the current pixel { - alpha = polyspan.ExtractAlpha(cover - area); + alpha = polyspan.ExtractAlpha(cover - area, winding_style); if(!antialias) { if(alpha >= .5) p.put_value(); @@ -2418,7 +2443,7 @@ bool Layer_Shape::render_polyspan(etl::surface *surface, PolySpan &polysp //draw span to next pixel - based on total amount of pixel cover if(x < cur_mark->x) { - alpha = polyspan.ExtractAlpha(cover); + alpha = polyspan.ExtractAlpha(cover, winding_style); if(!antialias) { if(alpha >= .5) p.put_hline(cur_mark->x - x); @@ -2451,15 +2476,15 @@ Layer_Shape::accelerated_render(Context context,Surface *surface,int quality, co if(is_solid_color() && invert) { Rect aabb = edge_table->aabb; - Point tl = renddesc.get_tl() - offset; + Point tl = renddesc.get_tl() - origin; Real pw = renddesc.get_pw(), ph = renddesc.get_ph(); Rect nrect; - Real pixelfeatherx = abs(feather/pw), - pixelfeathery = abs(feather/ph); + Real pixelfeatherx = quality == 10 ? 0 : abs(feather/pw), + pixelfeathery = quality == 10 ? 0 : abs(feather/ph); nrect.set_point((aabb.minx - tl[0])/pw,(aabb.miny - tl[1])/ph); nrect.expand((aabb.maxx - tl[0])/pw,(aabb.maxy - tl[1])/ph); @@ -2500,7 +2525,7 @@ Layer_Shape::accelerated_render(Context context,Surface *surface,int quality, co if(cb && !cb->amount_complete(10000,10001+renddesc.get_h())) return false; - if(feather) + if(feather && quality != 10) { //we have to blur rather than be crappy @@ -2596,7 +2621,7 @@ Layer_Shape::accelerated_render(Context context,Surface *surface,int quality, co } bool -Layer_Shape::render_shape(Surface *surface,bool useblend,int quality, +Layer_Shape::render_shape(Surface *surface,bool useblend,int /*quality*/, const RendDesc &renddesc, ProgressCallback *cb)const { int tmp(0); @@ -2621,7 +2646,11 @@ Layer_Shape::render_shape(Surface *surface,bool useblend,int quality, PolySpan span; - //optimization for tesselating only inside tiles + // if the pixels are zero sized then we're too zoomed out to see anything + if (pw == 0 || ph == 0) + return true; + + //optimization for tessellating only inside tiles span.window.minx = 0; span.window.miny = 0; span.window.maxx = w; @@ -2696,9 +2725,9 @@ Layer_Shape::render_shape(Surface *surface,bool useblend,int quality, case Primitive::MOVE_TO: { x = data[curnum][0]; - x = (x - tl[0] + offset[0])*pw; + x = (x - tl[0] + origin[0])*pw; y = data[curnum][1]; - y = (y - tl[1] + offset[1])*ph; + y = (y - tl[1] + origin[1])*ph; if(curnum == 0) { @@ -2723,9 +2752,9 @@ Layer_Shape::render_shape(Surface *surface,bool useblend,int quality, case Primitive::LINE_TO: { x = data[curnum][0]; - x = (x - tl[0] + offset[0])*pw; + x = (x - tl[0] + origin[0])*pw; y = data[curnum][1]; - y = (y - tl[1] + offset[1])*ph; + y = (y - tl[1] + origin[1])*ph; tangent[0] = x - span.cur_x; tangent[1] = y - span.cur_y; @@ -2738,14 +2767,14 @@ Layer_Shape::render_shape(Surface *surface,bool useblend,int quality, case Primitive::CONIC_TO: { x = data[curnum+1][0]; - x = (x - tl[0] + offset[0])*pw; + x = (x - tl[0] + origin[0])*pw; y = data[curnum+1][1]; - y = (y - tl[1] + offset[1])*ph; + y = (y - tl[1] + origin[1])*ph; x1 = data[curnum][0]; - x1 = (x1 - tl[0] + offset[0])*pw; + x1 = (x1 - tl[0] + origin[0])*pw; y1 = data[curnum][1]; - y1 = (y1 - tl[1] + offset[1])*ph; + y1 = (y1 - tl[1] + origin[1])*ph; tangent[0] = 2*(x - x1); tangent[1] = 2*(y - y1); @@ -2758,9 +2787,9 @@ Layer_Shape::render_shape(Surface *surface,bool useblend,int quality, case Primitive::CONIC_TO_SMOOTH: { x = data[curnum][0]; - x = (x - tl[0] + offset[0])*pw; + x = (x - tl[0] + origin[0])*pw; y = data[curnum][1]; - y = (y - tl[1] + offset[1])*ph; + y = (y - tl[1] + origin[1])*ph; x1 = span.cur_x + tangent[0]/2; y1 = span.cur_y + tangent[1]/2; @@ -2777,19 +2806,19 @@ Layer_Shape::render_shape(Surface *surface,bool useblend,int quality, case Primitive::CUBIC_TO: { x = data[curnum+2][0]; - x = (x - tl[0] + offset[0])*pw; + x = (x - tl[0] + origin[0])*pw; y = data[curnum+2][1]; - y = (y - tl[1] + offset[1])*ph; + y = (y - tl[1] + origin[1])*ph; x2 = data[curnum+1][0]; - x2 = (x2 - tl[0] + offset[0])*pw; + x2 = (x2 - tl[0] + origin[0])*pw; y2 = data[curnum+1][1]; - y2 = (y2 - tl[1] + offset[1])*ph; + y2 = (y2 - tl[1] + origin[1])*ph; x1 = data[curnum][0]; - x1 = (x1 - tl[0] + offset[0])*pw; + x1 = (x1 - tl[0] + origin[0])*pw; y1 = data[curnum][1]; - y1 = (y1 - tl[1] + offset[1])*ph; + y1 = (y1 - tl[1] + origin[1])*ph; tangent[0] = 2*(x - x2); tangent[1] = 2*(y - y2); @@ -2803,14 +2832,14 @@ Layer_Shape::render_shape(Surface *surface,bool useblend,int quality, case Primitive::CUBIC_TO_SMOOTH: { x = data[curnum+1][0]; - x = (x - tl[0] + offset[0])*pw; + x = (x - tl[0] + origin[0])*pw; y = data[curnum+1][1]; - y = (y - tl[1] + offset[1])*ph; + y = (y - tl[1] + origin[1])*ph; x2 = data[curnum][0]; - x2 = (x2 - tl[0] + offset[0])*pw; + x2 = (x2 - tl[0] + origin[0])*pw; y2 = data[curnum][1]; - y2 = (y2 - tl[1] + offset[1])*ph; + y2 = (y2 - tl[1] + origin[1])*ph; x1 = span.cur_x + tangent[0]/3.0; y1 = span.cur_y + tangent[1]/3.0; @@ -2836,8 +2865,8 @@ Layer_Shape::render_shape(Surface *surface,bool useblend,int quality, } bool -Layer_Shape::render_shape(surface *surface,int quality, - const RendDesc &renddesc, ProgressCallback *cb)const +Layer_Shape::render_shape(etl::surface *surface,int /*quality*/, + const RendDesc &renddesc, ProgressCallback */*cb*/)const { // If our amount is set to zero, no need to render anything if(!get_amount()) @@ -2857,7 +2886,7 @@ Layer_Shape::render_shape(surface *surface,int quality, PolySpan span; - //optimization for tesselating only inside tiles + //optimization for tessellating only inside tiles span.window.minx = 0; span.window.miny = 0; span.window.maxx = w; @@ -2925,9 +2954,9 @@ Layer_Shape::render_shape(surface *surface,int quality, case Primitive::MOVE_TO: { x = data[curnum][0]; - x = (x - tl[0] + offset[0])*pw; + x = (x - tl[0] + origin[0])*pw; y = data[curnum][1]; - y = (y - tl[1] + offset[1])*ph; + y = (y - tl[1] + origin[1])*ph; if(curnum == 0) { @@ -2952,9 +2981,9 @@ Layer_Shape::render_shape(surface *surface,int quality, case Primitive::LINE_TO: { x = data[curnum][0]; - x = (x - tl[0] + offset[0])*pw; + x = (x - tl[0] + origin[0])*pw; y = data[curnum][1]; - y = (y - tl[1] + offset[1])*ph; + y = (y - tl[1] + origin[1])*ph; tangent[0] = x - span.cur_x; tangent[1] = y - span.cur_y; @@ -2967,14 +2996,14 @@ Layer_Shape::render_shape(surface *surface,int quality, case Primitive::CONIC_TO: { x = data[curnum+1][0]; - x = (x - tl[0] + offset[0])*pw; + x = (x - tl[0] + origin[0])*pw; y = data[curnum+1][1]; - y = (y - tl[1] + offset[1])*ph; + y = (y - tl[1] + origin[1])*ph; x1 = data[curnum][0]; - x1 = (x1 - tl[0] + offset[0])*pw; + x1 = (x1 - tl[0] + origin[0])*pw; y1 = data[curnum][1]; - y1 = (y1 - tl[1] + offset[1])*ph; + y1 = (y1 - tl[1] + origin[1])*ph; tangent[0] = 2*(x - x1); tangent[1] = 2*(y - y1); @@ -2987,9 +3016,9 @@ Layer_Shape::render_shape(surface *surface,int quality, case Primitive::CONIC_TO_SMOOTH: { x = data[curnum][0]; - x = (x - tl[0] + offset[0])*pw; + x = (x - tl[0] + origin[0])*pw; y = data[curnum][1]; - y = (y - tl[1] + offset[1])*ph; + y = (y - tl[1] + origin[1])*ph; x1 = span.cur_x + tangent[0]/2; y1 = span.cur_y + tangent[1]/2; @@ -3006,19 +3035,19 @@ Layer_Shape::render_shape(surface *surface,int quality, case Primitive::CUBIC_TO: { x = data[curnum+2][0]; - x = (x - tl[0] + offset[0])*pw; + x = (x - tl[0] + origin[0])*pw; y = data[curnum+2][1]; - y = (y - tl[1] + offset[1])*ph; + y = (y - tl[1] + origin[1])*ph; x2 = data[curnum+1][0]; - x2 = (x2 - tl[0] + offset[0])*pw; + x2 = (x2 - tl[0] + origin[0])*pw; y2 = data[curnum+1][1]; - y2 = (y2 - tl[1] + offset[1])*ph; + y2 = (y2 - tl[1] + origin[1])*ph; x1 = data[curnum][0]; - x1 = (x1 - tl[0] + offset[0])*pw; + x1 = (x1 - tl[0] + origin[0])*pw; y1 = data[curnum][1]; - y1 = (y1 - tl[1] + offset[1])*ph; + y1 = (y1 - tl[1] + origin[1])*ph; tangent[0] = 2*(x - x2); tangent[1] = 2*(y - y2); @@ -3032,14 +3061,14 @@ Layer_Shape::render_shape(surface *surface,int quality, case Primitive::CUBIC_TO_SMOOTH: { x = data[curnum+1][0]; - x = (x - tl[0] + offset[0])*pw; + x = (x - tl[0] + origin[0])*pw; y = data[curnum+1][1]; - y = (y - tl[1] + offset[1])*ph; + y = (y - tl[1] + origin[1])*ph; x2 = data[curnum][0]; - x2 = (x2 - tl[0] + offset[0])*pw; + x2 = (x2 - tl[0] + origin[0])*pw; y2 = data[curnum][1]; - y2 = (y2 - tl[1] + offset[1])*ph; + y2 = (y2 - tl[1] + origin[1])*ph; x1 = span.cur_x + tangent[0]/3.0; y1 = span.cur_y + tangent[1]/3.0; @@ -3071,7 +3100,7 @@ Layer_Shape::get_bounding_rect()const if (edge_table->initaabb) return Rect::zero(); - Rect bounds(edge_table->aabb+offset); + Rect bounds(edge_table->aabb+origin); bounds.expand(max((bounds.get_min() - bounds.get_max()).mag()*0.01, feather));