From e03d257b5ef7f62396cbba4cb328026323f317bc Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Oct 13 2018 09:55:45 +0000 Subject: Convert CheckerBoard to new rendering engine --- diff --git a/synfig-core/src/modules/mod_geometry/checkerboard.cpp b/synfig-core/src/modules/mod_geometry/checkerboard.cpp index 046037b..fb77d75 100644 --- a/synfig-core/src/modules/mod_geometry/checkerboard.cpp +++ b/synfig-core/src/modules/mod_geometry/checkerboard.cpp @@ -31,10 +31,7 @@ # include #endif -#include -#include - -#include "checkerboard.h" +#include #include #include @@ -46,11 +43,18 @@ #include #include +#include +#include +#include + +#include "checkerboard.h" + +#include +#include + #endif using namespace synfig; -using namespace std; -using namespace etl; /* === M A C R O S ========================================================= */ @@ -65,6 +69,109 @@ SYNFIG_LAYER_SET_CVS_ID(CheckerBoard,"$Id$"); /* === P R O C E D U R E S ================================================= */ +namespace { + +class TaskCheckerBoard: public rendering::Task, public rendering::TaskInterfaceTransformation +{ +public: + typedef etl::handle Handle; + static Token token; + virtual Token::Handle get_token() const { return token.handle(); } + + Color color; + bool antialias; + rendering::Holder transformation; + + TaskCheckerBoard(): antialias(true) { } + virtual const rendering::Transformation::Handle get_transformation() const + { return transformation.handle(); } +}; + + +class TaskCheckerBoardSW: public TaskCheckerBoard, public rendering::TaskSW, + public rendering::TaskInterfaceBlendToTarget, + public rendering::TaskInterfaceSplit +{ +public: + typedef etl::handle Handle; + static Token token; + virtual Token::Handle get_token() const { return token.handle(); } + + virtual Color::BlendMethodFlags get_supported_blend_methods() const + { return Color::BLEND_METHODS_ALL; } + + virtual bool run(RunParams&) const { + if (!is_valid()) + return true; + + Vector ppu = get_pixels_per_unit(); + + Matrix bounds_transfromation; + bounds_transfromation.m00 = ppu[0]; + bounds_transfromation.m11 = ppu[1]; + bounds_transfromation.m20 = target_rect.minx - ppu[0]*source_rect.minx; + bounds_transfromation.m21 = target_rect.miny - ppu[1]*source_rect.miny; + + Matrix matrix = bounds_transfromation * transformation->matrix; + Matrix inv_matrix = matrix.get_inverted(); + + int tw = target_rect.get_width(); + Vector dx = inv_matrix.axis_x(); + Vector dy = inv_matrix.axis_y() - dx*(Real)tw; + Vector p = inv_matrix.get_transformed( Vector((Real)target_rect.minx, (Real)target_rect.miny) ); + + LockWrite la(this); + if (!la) + return false; + + Surface::alpha_pen apen(la->get_surface().get_pen(target_rect.minx, target_rect.miny)); + apen.set_blend_method(blend_method); + Color c = color; + if (antialias) { + ColorReal kx(matrix.axis_x().mag()*0.5); + ColorReal ky(matrix.axis_y().mag()*0.5); + for(int iy = target_rect.miny; iy < target_rect.maxy; ++iy, p += dy, apen.inc_y(), apen.dec_x(tw)) + for(int ix = target_rect.minx; ix < target_rect.maxx; ++ix, p += dx, apen.inc_x()) { + p[0] -= floor(p[0]); + p[1] -= floor(p[1]); + + ColorReal px = p[0]*ColorReal(2); + px -= floor(px); + px = std::min(px, ColorReal(1) - px)*kx; + + ColorReal py = p[1]*ColorReal(2); + py -= floor(py); + py = std::min(py, ColorReal(1) - py)*ky; + + ColorReal a = std::min(px, py); + if ((p[0] < 0.5) != (p[1] < 0.5)) a = -a; + a = std::max(ColorReal(0), std::min(ColorReal(1), a + ColorReal(0.5))); + + c.set_a(color.get_a()*a); + apen.put_value(c, amount); + } + } else { + for(int iy = target_rect.miny; iy < target_rect.maxy; ++iy, p += dy, apen.inc_y(), apen.dec_x(tw)) + for(int ix = target_rect.minx; ix < target_rect.maxx; ++ix, p += dx, apen.inc_x()) { + p[0] -= floor(p[0]); + p[1] -= floor(p[1]); + ColorReal a((p[0] < 0.5) == (p[1] < 0.5) ? 1.0 : 0.0); + c.set_a(color.get_a()*a); + apen.put_value(c, amount); + } + } + + return true; + } +}; + +rendering::Task::Token TaskCheckerBoard::token( + DescAbstract("TaskCheckerBoard") ); +rendering::Task::Token TaskCheckerBoardSW::token( + DescReal("TaskCheckerBoardSW") ); + +} // namespace + /* === M E T H O D S ======================================================= */ CheckerBoard::CheckerBoard(): @@ -117,7 +224,7 @@ CheckerBoard::set_param(const String ¶m, const ValueBase &value) return set_param("origin", value); for(int i=0;i<2;i++) - if(param==strprintf("pos[%d]",i) && value.get_type()==type_real) + if(param==etl::strprintf("pos[%d]",i) && value.get_type()==type_real) { Point p=param_origin.get(Point()); p[i]=value.get(Real()); @@ -280,7 +387,7 @@ CheckerBoard::accelerated_cairorender(Context context, cairo_t *cr, int quality, if(!context.accelerated_cairorender(cr,quality,renddesc,cb)) { - if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Cairo Renderer Failure",__LINE__)); + if(cb)cb->error(etl::strprintf(__FILE__"%d: Accelerated Cairo Renderer Failure",__LINE__)); return false; } // Now let's render the minimum checkerboard in other surface @@ -335,3 +442,21 @@ CheckerBoard::accelerated_cairorender(Context context, cairo_t *cr, int quality, ////////// +rendering::Task::Handle +CheckerBoard::build_composite_task_vfunc(ContextParams /*context_params*/)const +{ + Color color = param_color.get(Color()); + Point origin = param_origin.get(Point()); + Point size = param_size.get(Point()); + + origin[0] += size[0]; // make first cell empty (by history) + size *= 2.0; // task expects repeat period instead of cell size + + TaskCheckerBoard::Handle task(new TaskCheckerBoard()); + task->color = color; + task->transformation->matrix = Matrix().set_translate(origin) + * Matrix().set_scale(size); + + return task; +} + diff --git a/synfig-core/src/modules/mod_geometry/checkerboard.h b/synfig-core/src/modules/mod_geometry/checkerboard.h index f1f364d..b7f7ad0 100644 --- a/synfig-core/src/modules/mod_geometry/checkerboard.h +++ b/synfig-core/src/modules/mod_geometry/checkerboard.h @@ -69,6 +69,9 @@ public: virtual bool accelerated_render(synfig::Context context,synfig::Surface *surface,int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const; virtual bool accelerated_cairorender(synfig::Context context, cairo_t *cr, int quality, const synfig::RendDesc &renddesc, synfig::ProgressCallback *cb)const; + +protected: + virtual synfig::rendering::Task::Handle build_composite_task_vfunc(synfig::ContextParams context_params)const; }; /* === E N D =============================================================== */ diff --git a/synfig-core/src/synfig/main.cpp b/synfig-core/src/synfig/main.cpp index d68d63d..7e87dc8 100644 --- a/synfig-core/src/synfig/main.cpp +++ b/synfig-core/src/synfig/main.cpp @@ -371,6 +371,9 @@ synfig::Main::Main(const synfig::String& basepath,ProgressCallback *cb): if(cb)cb->amount_complete((i+1)*100,modules_to_load.size()*100); } + // Rebuild tokens data again to include new tokens from modules + Token::rebuild(); + if(cb)cb->amount_complete(100, 100); if(cb)cb->task(_("DONE")); }