[vlc-commits] skins(x11): improve boundaries check

Erwan Tulou git at videolan.org
Thu Apr 4 18:00:14 CEST 2013


vlc | branch: master | Erwan Tulou <erwan10 at videolan.org> | Thu Apr  4 12:47:03 2013 +0200| [bd1e52700431e7b1df3787d0625df044dc2971c2] | committer: Erwan Tulou

skins(x11): improve boundaries check

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=bd1e52700431e7b1df3787d0625df044dc2971c2
---

 modules/gui/skins2/x11/x11_graphics.cpp |   80 ++++++++++++++++++-------------
 modules/gui/skins2/x11/x11_graphics.hpp |    4 ++
 2 files changed, 52 insertions(+), 32 deletions(-)

diff --git a/modules/gui/skins2/x11/x11_graphics.cpp b/modules/gui/skins2/x11/x11_graphics.cpp
index ac51f53..b6e5cbe 100644
--- a/modules/gui/skins2/x11/x11_graphics.cpp
+++ b/modules/gui/skins2/x11/x11_graphics.cpp
@@ -32,6 +32,7 @@
 #include "x11_graphics.hpp"
 #include "x11_window.hpp"
 #include "../src/generic_bitmap.hpp"
+#include "../utils/position.hpp"
 
 
 X11Graphics::X11Graphics( intf_thread_t *pIntf, X11Display &rDisplay,
@@ -101,17 +102,26 @@ void X11Graphics::drawGraphics( const OSGraphics &rGraphics, int xSrc,
                                 int ySrc, int xDest, int yDest, int width,
                                 int height )
 {
-    if( width == -1 )
+    const X11Graphics& rGraph = (X11Graphics&)rGraphics;
+
+    // check and adapt to source if needed
+    if( !checkBoundaries( 0, 0, rGraph.getWidth(), rGraph.getHeight(),
+                          xSrc, ySrc, width, height ) )
     {
-        width = rGraphics.getWidth();
+        msg_Err( getIntf(), "nothing to draw from graphics source" );
+        return;
     }
-    if( height == -1 )
+
+    // check destination
+    if( !checkBoundaries( 0, 0, m_width, m_height,
+                          xDest, yDest, width, height ) )
     {
-        height = rGraphics.getHeight();
+        msg_Err( getIntf(), "out of reach destination! pls, debug your skin" );
+        return;
     }
 
     // Source drawable
-    Drawable src = ((X11Graphics&)rGraphics).getDrawable();
+    Drawable src = rGraph.getDrawable();
 
     // Create the mask for transparency
     Region voidMask = XCreateRegion();
@@ -123,7 +133,7 @@ void X11Graphics::drawGraphics( const OSGraphics &rGraphics, int xSrc,
     Region clipMask = XCreateRegion();
     XUnionRectWithRegion( &rect, voidMask, clipMask );
     Region mask = XCreateRegion();
-    XIntersectRegion( ((X11Graphics&)rGraphics).getMask(), clipMask, mask );
+    XIntersectRegion( rGraph.getMask(), clipMask, mask );
     XDestroyRegion( clipMask );
     XDestroyRegion( voidMask );
     XOffsetRegion( mask, xDest - xSrc, yDest - ySrc );
@@ -146,37 +156,19 @@ void X11Graphics::drawBitmap( const GenericBitmap &rBitmap, int xSrc,
                               int ySrc, int xDest, int yDest, int width,
                               int height, bool blend )
 {
-    // Get the bitmap size if necessary
-    if( width == -1 )
-    {
-        width = rBitmap.getWidth();
-    }
-    else if( width > rBitmap.getWidth() )
-    {
-        msg_Dbg( getIntf(), "bitmap width too small (%i)", rBitmap.getWidth() );
-        width = rBitmap.getWidth();
-    }
-    if( height == -1 )
-    {
-        height = rBitmap.getHeight();
-    }
-    else if( height > rBitmap.getHeight() )
-    {
-        msg_Dbg( getIntf(), "bitmap height too small (%i)", rBitmap.getHeight()
-                                 );
-        height = rBitmap.getHeight();
-    }
-
-    // Nothing to draw if width or height is null
-    if( width == 0 || height == 0 )
+    // check and adapt to source if needed
+    if( !checkBoundaries( 0, 0, rBitmap.getWidth(), rBitmap.getHeight(),
+                          xSrc, ySrc, width, height ) )
     {
+        msg_Err( getIntf(), "empty source! pls, debug your skin" );
         return;
     }
 
-    // Safety check for debugging purpose
-    if( xDest + width > m_width || yDest + height > m_height )
+    // check destination
+    if( !checkBoundaries( 0, 0, m_width, m_height,
+                          xDest, yDest, width, height ) )
     {
-        msg_Dbg( getIntf(), "bitmap too large" );
+        msg_Err( getIntf(), "out of reach destination! pls, debug your skin" );
         return;
     }
 
@@ -381,4 +373,28 @@ inline void X11Graphics::addVSegmentInRegion( Region &rMask, int yStart,
     rMask = newMask;
 }
 
+bool X11Graphics::checkBoundaries( int x_src, int y_src,
+                                   int w_src, int h_src,
+                                   int& x_target, int& y_target,
+                                   int& w_target, int& h_target )
+{
+    // set valid width and height
+    w_target = (w_target > 0) ? w_target : w_src;
+    h_target = (h_target > 0) ? h_target : h_src;
+
+    // clip source if needed
+    rect srcRegion( x_src, y_src, w_src, h_src );
+    rect targetRegion( x_target, y_target, w_target, h_target );
+    rect inter;
+    if( rect::intersect( srcRegion, targetRegion, &inter ) )
+    {
+        x_target = inter.x;
+        y_target = inter.y;
+        w_target = inter.width;
+        h_target = inter.height;
+        return true;
+    }
+    return false;
+}
+
 #endif
diff --git a/modules/gui/skins2/x11/x11_graphics.hpp b/modules/gui/skins2/x11/x11_graphics.hpp
index 63881d3..2a96041 100644
--- a/modules/gui/skins2/x11/x11_graphics.hpp
+++ b/modules/gui/skins2/x11/x11_graphics.hpp
@@ -102,6 +102,10 @@ private:
     void addHSegmentInRegion( Region &rMask, int xStart, int xEnd, int y );
     /// Add a vertical segment in a region
     void addVSegmentInRegion( Region &rMask, int yStart, int yEnd, int x );
+    /// check boundaries for graphics and bitmaps
+    bool checkBoundaries( int x_src, int y_src, int w_src, int h_src,
+                          int& x_target, int& y_target,
+                          int& w_target, int& h_target );
 };
 
 



More information about the vlc-commits mailing list