Add support for reversed draw order and Cairo negative draw mode

This commit is contained in:
Jon Evans 2017-09-17 18:36:18 -04:00 committed by Maciej Suminski
parent e46fdb0115
commit 0b9b8d3e93
7 changed files with 69 additions and 9 deletions

View File

@ -391,7 +391,11 @@ bool EDA_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
m_painter->SetGAL( m_gal );
if( m_view )
{
m_view->SetGAL( m_gal );
// Note: OpenGL requires reverse draw order when draw priority is enabled
m_view->ReverseDrawOrder( aGalType == GAL_TYPE_OPENGL );
}
m_backend = aGalType;

View File

@ -857,6 +857,12 @@ void CAIRO_GAL::ClearTarget( RENDER_TARGET aTarget )
}
void CAIRO_GAL::SetNegativeDrawMode( bool aSetting )
{
cairo_set_operator( currentContext, aSetting ? CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_OVER );
}
void CAIRO_GAL::DrawCursor( const VECTOR2D& aCursorPosition )
{
cursorPosition = aCursorPosition;

View File

@ -267,7 +267,8 @@ VIEW::VIEW( bool aIsDynamic ) :
m_gal( NULL ),
m_dynamic( aIsDynamic ),
m_useDrawPriority( false ),
m_nextDrawPriority( 0 )
m_nextDrawPriority( 0 ),
m_reverseDrawOrder( false )
{
m_boundary.SetMaximum();
m_allItems.reserve( 32768 );
@ -815,8 +816,10 @@ void VIEW::UpdateAllLayersOrder()
struct VIEW::drawItem
{
drawItem( VIEW* aView, int aLayer, bool aUseDrawPriority ) :
view( aView ), layer( aLayer ), useDrawPriority( aUseDrawPriority )
drawItem( VIEW* aView, int aLayer, bool aUseDrawPriority, bool aReverseDrawOrder ) :
view( aView ), layer( aLayer ),
useDrawPriority( aUseDrawPriority ),
reverseDrawOrder( aReverseDrawOrder )
{
}
@ -840,10 +843,16 @@ struct VIEW::drawItem
void deferredDraw()
{
std::sort( drawItems.begin(), drawItems.end(),
[]( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
return b->viewPrivData()->m_drawPriority < a->viewPrivData()->m_drawPriority;
});
if( reverseDrawOrder )
std::sort( drawItems.begin(), drawItems.end(),
[]( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
return b->viewPrivData()->m_drawPriority < a->viewPrivData()->m_drawPriority;
});
else
std::sort( drawItems.begin(), drawItems.end(),
[]( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
return a->viewPrivData()->m_drawPriority < b->viewPrivData()->m_drawPriority;
});
for( auto item : drawItems )
view->draw( item, layer );
@ -851,7 +860,7 @@ struct VIEW::drawItem
VIEW* view;
int layer, layers[VIEW_MAX_LAYERS];
bool useDrawPriority;
bool useDrawPriority, reverseDrawOrder;
std::vector<VIEW_ITEM*> drawItems;
};
@ -862,7 +871,7 @@ void VIEW::redrawRect( const BOX2I& aRect )
{
if( l->visible && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
{
drawItem drawFunc( this, l->id, m_useDrawPriority );
drawItem drawFunc( this, l->id, m_useDrawPriority, m_reverseDrawOrder );
m_gal->SetTarget( l->target );
m_gal->SetLayerDepth( l->renderingOrder );

View File

@ -240,6 +240,9 @@ public:
/// @copydoc GAL::ClearTarget()
virtual void ClearTarget( RENDER_TARGET aTarget ) override;
/// @copydoc GAL::SetNegativeDrawMode()
virtual void SetNegativeDrawMode( bool aSetting ) override;
// -------
// Cursor
// -------

View File

@ -772,6 +772,19 @@ public:
*/
virtual void ClearTarget( RENDER_TARGET aTarget ) {};
/**
* @brief Sets negative draw mode in the renderer
*
* When negative mode is enabled, drawn items will subtract from
* previously drawn items. This is mainly needed for Gerber
* negative item support in Cairo, since unlike in OpenGL, objects
* drawn with zero opacity on top of other objects would not normally
* mask objects in Cairo. This method is a no-op in OpenGL.
*
* @param aSetting is true if negative mode should be enabled
*/
virtual void SetNegativeDrawMode( bool aSetting ) {};
// -------------
// Grid methods
// -------------

View File

@ -239,6 +239,9 @@ public:
/// @copydoc GAL::ClearTarget()
virtual void ClearTarget( RENDER_TARGET aTarget ) override;
/// @copydoc GAL::SetNegativeDrawMode()
virtual void SetNegativeDrawMode( bool aSetting ) override {}
// -------
// Cursor
// -------

View File

@ -630,6 +630,25 @@ public:
m_useDrawPriority = aFlag;
}
/**
* Function IsDrawOrderReversed()
* @return true if draw order is reversed
*/
bool IsDrawOrderReversed() const
{
return m_reverseDrawOrder;
}
/**
* Function ReverseDrawOrder()
* Only takes effect if UseDrawPriority is true.
* @param aFlag is true if draw order should be reversed
*/
void ReverseDrawOrder( bool aFlag )
{
m_reverseDrawOrder = aFlag;
}
static const int VIEW_MAX_LAYERS = 512; ///< maximum number of layers that may be shown
@ -796,6 +815,9 @@ private:
/// The next sequential drawing priority
int m_nextDrawPriority;
/// Flag to reverse the draw order when using draw priority
bool m_reverseDrawOrder;
};
} // namespace KIGFX