X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftrunk%2Fsrc%2Fmodules%2Fmod_geometry%2Frectangle.cpp;h=21fa4d2e07efde4513c5aee74de3ce3be20c4983;hb=756c0d29ac1742f231e6615f9a577e574e35a4af;hp=55029df2d493491cd3255e2894ecdf4a4496a3bc;hpb=cc54c38609ee9745ad678e5e9b9d7d2912be9c95;p=synfig.git diff --git a/synfig-core/trunk/src/modules/mod_geometry/rectangle.cpp b/synfig-core/trunk/src/modules/mod_geometry/rectangle.cpp index 55029df..21fa4d2 100644 --- a/synfig-core/trunk/src/modules/mod_geometry/rectangle.cpp +++ b/synfig-core/trunk/src/modules/mod_geometry/rectangle.cpp @@ -1,11 +1,12 @@ /* === S Y N F I G ========================================================= */ /*! \file rectangle.cpp -** \brief Template Header +** \brief Implementation of the "Rectangle" layer ** ** $Id$ ** ** \legal ** Copyright (c) 2002 Robert B. Quattlebaum Jr. +** 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 @@ -54,8 +55,8 @@ using namespace synfig; SYNFIG_LAYER_INIT(Rectangle); SYNFIG_LAYER_SET_NAME(Rectangle,"rectangle"); -SYNFIG_LAYER_SET_LOCAL_NAME(Rectangle,_("Rectangle")); -SYNFIG_LAYER_SET_CATEGORY(Rectangle,_("Geometry")); +SYNFIG_LAYER_SET_LOCAL_NAME(Rectangle,N_("Rectangle")); +SYNFIG_LAYER_SET_CATEGORY(Rectangle,N_("Geometry")); SYNFIG_LAYER_SET_VERSION(Rectangle,"0.2"); SYNFIG_LAYER_SET_CVS_ID(Rectangle,"$Id$"); @@ -86,7 +87,9 @@ Rectangle::Rectangle(): bool Rectangle::set_param(const String & param, const ValueBase &value) { - IMPORT(color); + 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(point1); IMPORT(point2); IMPORT(expand); @@ -177,6 +180,15 @@ Rectangle::hit_check(synfig::Context context, const synfig::Point &pos)const return context.hit_check(pos); } +bool +Rectangle::is_solid_color()const +{ + return Layer_Composite::is_solid_color() || + (get_blend_method() == Color::BLEND_COMPOSITE && + get_amount() == 1.0f && + color.get_a() == 1.0f); +} + Color Rectangle::get_color(Context context, const Point &pos)const { @@ -377,7 +389,7 @@ Rectangle::accelerated_render(Context context,Surface *surface,int quality, cons surface->fill(color); // Check for the case where there is nothing to render - if(right-left<=0||bottom-top<=0) + if (right <= left || bottom <= top) return true; desc.set_subwindow(left,top,right-left,bottom-top); @@ -400,25 +412,31 @@ Rectangle::accelerated_render(Context context,Surface *surface,int quality, cons if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__)); return false; } + Surface subimage; - // Check for the case where there is nothing to render - if(!(right-left<=0||bottom-top<=0)) + // Check for the case where there is something to render + if (right > left && bottom > top) { + // save a copy of the overlapping region from surface into subimage subimage.set_wh(right-left,bottom-top); Surface::pen subimage_pen(subimage.begin()); surface->blit_to(subimage_pen,left,top,right-left,bottom-top); } + // fill surface with the rectangle's color Surface::alpha_pen surface_pen(surface->begin(),get_amount(),get_blend_method()); - surface->fill(color,surface_pen,w,h); - if(subimage) + if (subimage) { + // copy the saved overlapping region back from subimage into surface Surface::pen pen(surface->get_pen(left,top)); subimage.blit_to(pen); } + else + // if there's no overlapping region, return now of the following code corrupts memory + return true; } Surface::alpha_pen pen; @@ -450,12 +468,7 @@ Rectangle::accelerated_render(Context context,Surface *surface,int quality, cons return true; } - // Render what is behind us - if(!context.accelerated_render(surface,quality,renddesc,cb)) - { - if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__)); - return false; - } + // not inverted int left(ceil_to_int((min[0]-tl[0])/pw)); int right(floor_to_int((max[0]-tl[0])/pw)); @@ -479,12 +492,29 @@ Rectangle::accelerated_render(Context context,Surface *surface,int quality, cons right = std::min(w,right); */ - Surface::alpha_pen pen; + // optimization - if the whole tile is covered by this rectangle, + // and the rectangle is a solid color, we don't need to render + // what's behind us + if (is_solid_color() && top == 0 && left == 0 && bottom == h && right == w) + { + surface->set_wh(w,h); + surface->fill(color); + return true; + } + + // Render what is behind us + if(!context.accelerated_render(surface,quality,renddesc,cb)) + { + if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__)); + return false; + } // In the case where there is nothing to render... - if(right-left<0||bottom-top<0) + if (right < left || bottom < top) return true; + Surface::alpha_pen pen; + if(right-left>0&&bottom-top>0) { if(is_solid_color())