Author: Carlos Lopez <genet...@gmail.com> Date: Sat Dec 31 13:16:31 2011 +0100
Fix several bugs and crashes related to dashed outlines --- .../src/modules/mod_geometry/advanced_outline.cpp | 46 ++++++++++++++----- 1 files changed, 34 insertions(+), 12 deletions(-) diff --git a/synfig-core/src/modules/mod_geometry/advanced_outline.cpp b/synfig-core/src/modules/mod_geometry/advanced_outline.cpp index 03b6aaa..4e71676 100644 --- a/synfig-core/src/modules/mod_geometry/advanced_outline.cpp +++ b/synfig-core/src/modules/mod_geometry/advanced_outline.cpp @@ -351,9 +351,6 @@ Advanced_Outline::sync() Real blinelength(bline_length(bline, blineloop, NULL)); if(blinelength > EPSILON) { - // Put dash_offset in the [-blinelength,blinelength] interval - if (fabs(dash_offset) > blinelength) dash_offset=fmod(dash_offset, blinelength); - Real dpos=dash_offset; Real dashes_length(0.0); vector<DashItem>::iterator diter(dilist.begin()); vector<DashItem>::reverse_iterator rditer(dilist.rbegin()); @@ -363,11 +360,15 @@ Advanced_Outline::sync() { dashes_length+=diter->get_length()+diter->get_offset(); } - diter=dilist.begin(); if(dashes_length>EPSILON) { - // Insert the widthpoints from Dash Offset to 1.0 - int inserted(0); + // Put dash_offset in the [-dashes_length,dashes_length] interval + if (fabs(dash_offset) > dashes_length) dash_offset=fmod(dash_offset, dashes_length); + // dpos is always >= 0 + Real dpos=dash_offset>=0?dash_offset:(dashes_length+dash_offset); + diter=dilist.begin(); + // Insert the widthpoints from Dash Offset to blinelength + int inserted_to_blinelength(0); while(dpos < blinelength) { // dash widthpoints should have the same homogeneous or standard comparable positions. @@ -381,12 +382,12 @@ Advanced_Outline::sync() dwplist.push_back(after); dpos+=diter->get_offset() + diter->get_length(); diter++; - inserted++; + inserted_to_blinelength++; if(diter==dilist.end()) diter=dilist.begin(); }; // Correct the two last widthpoints triming its position to be <= 1.0 - if(inserted) + if(inserted_to_blinelength) { after=dwplist.back(); // if the if the 'after' widthpoint passed 1.0 @@ -398,8 +399,12 @@ Advanced_Outline::sync() before=dwplist.back(); // then watch the before one and if it passeed 1.0 if(before.get_position() >= 1.0) + { // discard it (and also the 'after' one) dwplist.pop_back(); + // and decrease the number of inserted dash items + inserted_to_blinelength--; + } else // restore the 'after' widthpoint { @@ -408,10 +413,10 @@ Advanced_Outline::sync() } } } - inserted=0; + int inserted_to_zero(0); // // Now insert the widhtpoints from Dash Offset to 0.0 - dpos=dash_offset; + dpos=dash_offset>=0?dash_offset:dashes_length+dash_offset;; while(dpos > 0.0) { // dash widthpoints should have the same homogeneous or standard comparable positions. @@ -425,12 +430,12 @@ Advanced_Outline::sync() dwplist.insert(dwplist.begin(),before); dpos-=rditer->get_offset() + rditer->get_length(); rditer++; - inserted++; + inserted_to_zero++; if(rditer==dilist.rend()) rditer=dilist.rbegin(); }; // Correct the two first widthpoints triming its position to be >= 0.0 - if(inserted) + if(inserted_to_zero) { before=dwplist.front(); // if the dash is cutted in the middle then trim the 'before' widthpoint @@ -442,8 +447,12 @@ Advanced_Outline::sync() after=dwplist.front(); // then watch the after one and if it passed 0.0 if(after.get_position() <= 0.0) + { // discard the 'after' one (and the 'before' one too) dwplist.erase(dwplist.begin()); + // and decrease the number of inserted dash items + inserted_to_zero--; + } else // restore the 'before' widthpoint { @@ -452,6 +461,19 @@ Advanced_Outline::sync() } } } + // Let's check that we have one dash widthpoint at last + // inside the bline interval + if(inserted_to_blinelength == 0 && inserted_to_zero==0) + { + // all the dash items widthpoints were outside the bline + // so the bline is an empty interval + // let's insert two dash widthpoints that would + // 'clean' the bline area + before=WidthPoint(0.5, 1.0, WidthPoint::TYPE_FLAT, WidthPoint::TYPE_INTERPOLATE, true); + after=WidthPoint(0.5, 1.0, WidthPoint::TYPE_INTERPOLATE, WidthPoint::TYPE_FLAT, true); + dwplist.push_back(before); + dwplist.push_back(after); + } // now let's remove those dash widthpoints that doesn't // lie on a drawable place // first prepare the widthpoint iterators ------------------------------------------------------------------------------ Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex infrastructure or vast IT resources to deliver seamless, secure access to virtual desktops. With this all-in-one solution, easily deploy virtual desktops for less than the cost of PCs and save 60% on VDI infrastructure costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox _______________________________________________ Synfig-devl mailing list Synfig-devl@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/synfig-devl