Commit bd1e5270 authored by Erwan Tulou's avatar Erwan Tulou

skins(x11): improve boundaries check

parent ab72243a
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "x11_graphics.hpp" #include "x11_graphics.hpp"
#include "x11_window.hpp" #include "x11_window.hpp"
#include "../src/generic_bitmap.hpp" #include "../src/generic_bitmap.hpp"
#include "../utils/position.hpp"
X11Graphics::X11Graphics( intf_thread_t *pIntf, X11Display &rDisplay, X11Graphics::X11Graphics( intf_thread_t *pIntf, X11Display &rDisplay,
...@@ -101,17 +102,26 @@ void X11Graphics::drawGraphics( const OSGraphics &rGraphics, int xSrc, ...@@ -101,17 +102,26 @@ void X11Graphics::drawGraphics( const OSGraphics &rGraphics, int xSrc,
int ySrc, int xDest, int yDest, int width, int ySrc, int xDest, int yDest, int width,
int height ) 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 // Source drawable
Drawable src = ((X11Graphics&)rGraphics).getDrawable(); Drawable src = rGraph.getDrawable();
// Create the mask for transparency // Create the mask for transparency
Region voidMask = XCreateRegion(); Region voidMask = XCreateRegion();
...@@ -123,7 +133,7 @@ void X11Graphics::drawGraphics( const OSGraphics &rGraphics, int xSrc, ...@@ -123,7 +133,7 @@ void X11Graphics::drawGraphics( const OSGraphics &rGraphics, int xSrc,
Region clipMask = XCreateRegion(); Region clipMask = XCreateRegion();
XUnionRectWithRegion( &rect, voidMask, clipMask ); XUnionRectWithRegion( &rect, voidMask, clipMask );
Region mask = XCreateRegion(); Region mask = XCreateRegion();
XIntersectRegion( ((X11Graphics&)rGraphics).getMask(), clipMask, mask ); XIntersectRegion( rGraph.getMask(), clipMask, mask );
XDestroyRegion( clipMask ); XDestroyRegion( clipMask );
XDestroyRegion( voidMask ); XDestroyRegion( voidMask );
XOffsetRegion( mask, xDest - xSrc, yDest - ySrc ); XOffsetRegion( mask, xDest - xSrc, yDest - ySrc );
...@@ -146,37 +156,19 @@ void X11Graphics::drawBitmap( const GenericBitmap &rBitmap, int xSrc, ...@@ -146,37 +156,19 @@ void X11Graphics::drawBitmap( const GenericBitmap &rBitmap, int xSrc,
int ySrc, int xDest, int yDest, int width, int ySrc, int xDest, int yDest, int width,
int height, bool blend ) int height, bool blend )
{ {
// Get the bitmap size if necessary // check and adapt to source if needed
if( width == -1 ) if( !checkBoundaries( 0, 0, rBitmap.getWidth(), rBitmap.getHeight(),
{ xSrc, ySrc, width, height ) )
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 )
{ {
msg_Err( getIntf(), "empty source! pls, debug your skin" );
return; return;
} }
// Safety check for debugging purpose // check destination
if( xDest + width > m_width || yDest + height > m_height ) 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; return;
} }
...@@ -381,4 +373,28 @@ inline void X11Graphics::addVSegmentInRegion( Region &rMask, int yStart, ...@@ -381,4 +373,28 @@ inline void X11Graphics::addVSegmentInRegion( Region &rMask, int yStart,
rMask = newMask; 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 #endif
...@@ -102,6 +102,10 @@ private: ...@@ -102,6 +102,10 @@ private:
void addHSegmentInRegion( Region &rMask, int xStart, int xEnd, int y ); void addHSegmentInRegion( Region &rMask, int xStart, int xEnd, int y );
/// Add a vertical segment in a region /// Add a vertical segment in a region
void addVSegmentInRegion( Region &rMask, int yStart, int yEnd, int x ); 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 );
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment