diff --git a/synfig-core/src/synfig/canvas.h b/synfig-core/src/synfig/canvas.h index 899b522..7fc9e91 100644 --- a/synfig-core/src/synfig/canvas.h +++ b/synfig-core/src/synfig/canvas.h @@ -122,9 +122,13 @@ * * Added gamma into a canvas rend_desc * + * 1.2 + * + * Added 'alpha' blend method + * */ -#define CURRENT_CANVAS_VERSION "1.1" +#define CURRENT_CANVAS_VERSION "1.2" /* === T Y P E D E F S ===================================================== */ diff --git a/synfig-core/src/synfig/color/cairocolor.cpp b/synfig-core/src/synfig/color/cairocolor.cpp index 6fad65c..36b3f9f 100644 --- a/synfig-core/src/synfig/color/cairocolor.cpp +++ b/synfig-core/src/synfig/color/cairocolor.cpp @@ -119,6 +119,8 @@ CairoColor::blend(CairoColor a, CairoColor b, float amount, Color::BlendMethod t blendfunc_ALPHA_OVER, blendfunc_OVERLAY, // 20 blendfunc_STRAIGHT_ONTO, + blendfunc_STRAIGHT_ONTO, // dummy instead of new blend method + blendfunc_STRAIGHT_ONTO // dummy instead of new blend method }; return vtable[type](a,b,amount); diff --git a/synfig-core/src/synfig/color/color.cpp b/synfig-core/src/synfig/color/color.cpp index 6023ce9..6f1a35b 100644 --- a/synfig-core/src/synfig/color/color.cpp +++ b/synfig-core/src/synfig/color/color.cpp @@ -241,6 +241,7 @@ Color::blend(Color a, Color b, float amount, Color::BlendMethod type) blendfunc_OVERLAY, // 20 blendfunc_STRAIGHT_ONTO, blendfunc_ADD_COMPOSITE, + blendfunc_ALPHA, }; return vtable[type](a,b,amount); diff --git a/synfig-core/src/synfig/color/color.h b/synfig-core/src/synfig/color/color.h index 29d15c5..68eb83d 100644 --- a/synfig-core/src/synfig/color/color.h +++ b/synfig-core/src/synfig/color/color.h @@ -274,8 +274,9 @@ public: BLEND_ALPHA_BRIGHTEN=14, //!< \deprecated If A is less opaque than B, use A BLEND_ALPHA_DARKEN=15, //!< \deprecated If A is more opaque than B, use B BLEND_ALPHA_OVER=19, //!< \deprecated multiply alphas and then straight blends using the amount + BLEND_ALPHA=23, //!< multiply alphas - BLEND_END=23, //!< \internal + BLEND_END=24, //!< \internal BLEND_BY_LAYER=999 //! Used to let the layer decides what Blend Method use by //! default when the layer is created }; @@ -296,12 +297,14 @@ public: | (1 << BLEND_STRAIGHT_ONTO) | (1 << BLEND_SCREEN) | (1 << BLEND_OVERLAY) - | (1 << BLEND_HARD_LIGHT), + | (1 << BLEND_HARD_LIGHT) + | (1 << BLEND_ALPHA), BLEND_METHODS_STRAIGHT = 0 | (1 << BLEND_STRAIGHT) | (1 << BLEND_STRAIGHT_ONTO) - | (1 << BLEND_ALPHA_BRIGHTEN), + | (1 << BLEND_ALPHA_BRIGHTEN) + | (1 << BLEND_ALPHA), BLEND_METHODS_OVERWRITE_ON_ALPHA_ONE = 0 | (1 << BLEND_COMPOSITE), diff --git a/synfig-core/src/synfig/color/colorblendingfunctions.h b/synfig-core/src/synfig/color/colorblendingfunctions.h index bf692af..5345278 100644 --- a/synfig-core/src/synfig/color/colorblendingfunctions.h +++ b/synfig-core/src/synfig/color/colorblendingfunctions.h @@ -373,6 +373,18 @@ C blendfunc_HARD_LIGHT(C &a,C &b,float amount) } template +C blendfunc_ALPHA(C &a,C &b,float amount) +{ + const float one(C::ceil); + C rm(b); + + //multiply the alpha channel with the one below us + rm.set_a(a.get_a()*b.get_a()); + + return blendfunc_STRAIGHT(rm,b,amount); +} + +template C blendfunc_ALPHA_OVER(C &a,C &b,float amount) { const float one(C::ceil); diff --git a/synfig-core/src/synfig/paramdesc.cpp b/synfig-core/src/synfig/paramdesc.cpp index 37b0f15..c96528d 100644 --- a/synfig-core/src/synfig/paramdesc.cpp +++ b/synfig-core/src/synfig/paramdesc.cpp @@ -93,7 +93,7 @@ ParamDesc::ParamDesc(const ValueBase&, const String &a): .add_enum_value(Color::BLEND_ALPHA_OVER, "alphaover", _("Alpha Over")) .add_enum_value(Color::BLEND_ALPHA_BRIGHTEN, "alphabrighten",_("Alpha Brighten")) .add_enum_value(Color::BLEND_ALPHA_DARKEN, "alphadarken", _("Alpha Darken")) + .add_enum_value(Color::BLEND_ALPHA, "alpha", _("Alpha")) ; // end of enums - } } diff --git a/synfig-core/src/synfig/rendering/common/optimizer/optimizertransformation.cpp b/synfig-core/src/synfig/rendering/common/optimizer/optimizertransformation.cpp index 1916d9e..83085a2 100644 --- a/synfig-core/src/synfig/rendering/common/optimizer/optimizertransformation.cpp +++ b/synfig-core/src/synfig/rendering/common/optimizer/optimizertransformation.cpp @@ -62,11 +62,22 @@ OptimizerTransformation::run(const RunParams& params) const TaskTransformation::Handle transformation = TaskTransformation::Handle::cast_dynamic(params.ref_task); if (!transformation || !transformation->is_simple()) return; - // transformation of none in none - Task::Handle sub_task = transformation->sub_task(); - if (!sub_task || !transformation->get_transformation()) + // no trasgormation + if (!transformation->get_transformation()) + { apply(params, Task::Handle()); return; } + + const Task::List &sub_tasks = transformation->sub_tasks; + int count = 0; + for(Task::List::const_iterator i = sub_tasks.begin(); i != sub_tasks.end(); ++i) + if (*i) ++count; + if (!count) { apply(params, Task::Handle()); return; } + // transformation of none in none + Task::Handle sub_task = transformation->sub_task(); + if (!sub_task || count > 1) + return; + // transformation of solid is solid if (TaskInterfaceConstant *constant = sub_task.type_pointer()) { diff --git a/synfig-core/src/synfig/rendering/common/task/taskblend.cpp b/synfig-core/src/synfig/rendering/common/task/taskblend.cpp index 419120f..6de1c22 100644 --- a/synfig-core/src/synfig/rendering/common/task/taskblend.cpp +++ b/synfig-core/src/synfig/rendering/common/task/taskblend.cpp @@ -73,18 +73,11 @@ TaskBlend::calc_bounds() const { Rect ra = sub_task_a() ? sub_task_a()->get_bounds() : Rect::zero(); Rect rb = sub_task_b() ? sub_task_b()->get_bounds() : Rect::zero(); - Rect bounds = Rect::zero(); + Rect bounds = ra | rb; if (Color::is_onto(blend_method)) - bounds = ra; - else - if (ra.valid() && rb.valid()) - set_union(bounds, ra, rb); - else - if (ra.valid()) - bounds = ra; - else - if (rb.valid()) - bounds = rb; + bounds &= ra; + if (approximate_equal(amount, Color::value_type(1)) && Color::is_straight(blend_method)) + bounds &= rb; return bounds; } diff --git a/synfig-core/src/synfig/rendering/common/task/tasktransformation.cpp b/synfig-core/src/synfig/rendering/common/task/tasktransformation.cpp index 3f5faf1..1f0b8fa 100644 --- a/synfig-core/src/synfig/rendering/common/task/tasktransformation.cpp +++ b/synfig-core/src/synfig/rendering/common/task/tasktransformation.cpp @@ -65,8 +65,11 @@ TaskTransformation::is_simple() const { int TaskTransformation::get_pass_subtask_index() const { - return sub_task() && get_transformation() - ? PASSTO_THIS_TASK : PASSTO_NO_TASK; + if (!get_transformation()) + return PASSTO_NO_TASK; + for(Task::List::const_iterator i = sub_tasks.begin(); i != sub_tasks.end(); ++i) + if (*i) return PASSTO_THIS_TASK; + return PASSTO_NO_TASK; } diff --git a/synfig-core/src/synfig/rendering/opengl/internal/shaders.cpp b/synfig-core/src/synfig/rendering/opengl/internal/shaders.cpp index 2eb1352..df5cb61 100644 --- a/synfig-core/src/synfig/rendering/opengl/internal/shaders.cpp +++ b/synfig-core/src/synfig/rendering/opengl/internal/shaders.cpp @@ -110,6 +110,9 @@ gl::Shaders::Shaders(Context &context): load_blend(Color::BLEND_ALPHA_OVER, "alphaover"); load_blend(Color::BLEND_ALPHA_BRIGHTEN, "alphabrighten"); load_blend(Color::BLEND_ALPHA_DARKEN, "alphadarken"); +#error implement add_composite and alpha + load_blend(Color::BLEND_ADD_COMPOSITE, "add_composite"); + load_blend(Color::BLEND_ALPHA, "alpha"); #ifndef NDEBUG for(int i = 0; i < Color::BLEND_END; ++i) assert(blend_programs[i].id);