GAL: also scope layer depth push/pops

This means that an early return or an exception between
a manual Push/Pop (or an omission of the Pop) cannot
corrupt the layer stack.

It also means the GAL doesn't have to maintain its own
stack (with the in-scope GAL_SCOPED_ATTRS taking that role).

Reomve the Push/PopDepth functions, as they're only ever
used in pairs, and doing it manually needs more care.
This commit is contained in:
John Beard 2024-11-03 23:59:34 +08:00
parent 3549b77530
commit dbf68a80b8
8 changed files with 48 additions and 58 deletions

View File

@ -1417,9 +1417,7 @@ void OPENGL_GAL::drawTriangulatedPolyset( const SHAPE_POLY_SET& aPolySet,
if( aStrokeTriangulation ) if( aStrokeTriangulation )
{ {
COLOR4D oldStrokeColor = m_strokeColor; GAL_SCOPED_ATTRS( *this, GAL_SCOPED_ATTRS::STROKE_COLOR | GAL_SCOPED_ATTRS::LAYER_DEPTH );
double oldLayerDepth = m_layerDepth;
SetLayerDepth( m_layerDepth - 1 ); SetLayerDepth( m_layerDepth - 1 );
for( unsigned int j = 0; j < aPolySet.TriangulatedPolyCount(); ++j ) for( unsigned int j = 0; j < aPolySet.TriangulatedPolyCount(); ++j )
@ -1435,9 +1433,6 @@ void OPENGL_GAL::drawTriangulatedPolyset( const SHAPE_POLY_SET& aPolySet,
DrawLine( c, a ); DrawLine( c, a );
} }
} }
SetStrokeColor( oldStrokeColor );
SetLayerDepth( oldLayerDepth );
} }
} }

View File

@ -122,7 +122,7 @@ void KIGFX::PREVIEW::DrawTextNextToCursor( KIGFX::VIEW* aView, const VECTOR2D& a
{ {
KIGFX::GAL* gal = aView->GetGAL(); KIGFX::GAL* gal = aView->GetGAL();
GAL_SCOPED_ATTRS settings( *gal ); GAL_SCOPED_ATTRS settings( *gal, GAL_SCOPED_ATTRS::STROKE_FILL );
KIFONT::FONT* font = KIFONT::FONT::GetFont(); KIFONT::FONT* font = KIFONT::FONT::GetFont();

View File

@ -306,7 +306,7 @@ void RULER_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
RENDER_SETTINGS* rs = aView->GetPainter()->GetSettings(); RENDER_SETTINGS* rs = aView->GetPainter()->GetSettings();
bool drawingDropShadows = ( aLayer == getShadowLayer( gal ) ); bool drawingDropShadows = ( aLayer == getShadowLayer( gal ) );
gal->PushDepth(); GAL_SCOPED_ATTRS scopedAttrs( *gal, GAL_SCOPED_ATTRS::ALL );
gal->SetLayerDepth( gal->GetMinDepth() ); gal->SetLayerDepth( gal->GetMinDepth() );
VECTOR2D origin = m_geomMgr.GetOrigin(); VECTOR2D origin = m_geomMgr.GetOrigin();
@ -368,7 +368,6 @@ void RULER_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
// draw the back of the origin "crosshair" // draw the back of the origin "crosshair"
gal->DrawLine( origin, origin + rulerVec.Resize( -minorTickLen * midTickLengthFactor ) ); gal->DrawLine( origin, origin + rulerVec.Resize( -minorTickLen * midTickLengthFactor ) );
} }
gal->PopDepth();
} }

View File

@ -278,11 +278,11 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
highlightColor = drawColor.Brightened( 0.5 ).WithAlpha( 0.8 ); highlightColor = drawColor.Brightened( 0.5 ).WithAlpha( 0.8 );
} }
KIGFX::GAL_SCOPED_ATTRS scopedAttrs( *gal, KIGFX::GAL_SCOPED_ATTRS::ALL );
gal->SetFillColor( drawColor ); gal->SetFillColor( drawColor );
gal->SetStrokeColor( borderColor ); gal->SetStrokeColor( borderColor );
gal->SetIsFill( true ); gal->SetIsFill( true );
gal->SetIsStroke( true ); gal->SetIsStroke( true );
gal->PushDepth();
gal->SetLayerDepth( gal->GetMinDepth() ); gal->SetLayerDepth( gal->GetMinDepth() );
double size = aView->ToWorld( EDIT_POINT::POINT_SIZE ) / 2.0; double size = aView->ToWorld( EDIT_POINT::POINT_SIZE ) / 2.0;
@ -328,6 +328,4 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
gal->DrawLine( line.GetOrigin().GetPosition(), line.GetEnd().GetPosition() ); gal->DrawLine( line.GetOrigin().GetPosition(), line.GetEnd().GetPosition() );
} }
} }
gal->PopDepth();
} }

View File

@ -145,7 +145,7 @@ void VIEW_GROUP::ViewDraw( int aLayer, VIEW* aView ) const
// Now draw the layers in sorted order // Now draw the layers in sorted order
gal->PushDepth(); GAL_SCOPED_ATTRS scopedAttrs( *gal, GAL_SCOPED_ATTRS::LAYER_DEPTH );
for( int i = 0; i < layers_count; i++ ) for( int i = 0; i < layers_count; i++ )
{ {
@ -188,8 +188,6 @@ void VIEW_GROUP::ViewDraw( int aLayer, VIEW* aView ) const
} }
} }
} }
gal->PopDepth();
} }

View File

@ -298,14 +298,13 @@ const BOX2I VIEW_OVERLAY::ViewBBox() const
void VIEW_OVERLAY::ViewDraw( int aLayer, VIEW* aView ) const void VIEW_OVERLAY::ViewDraw( int aLayer, VIEW* aView ) const
{ {
auto gal = aView->GetGAL(); GAL& gal = *aView->GetGAL();
gal->PushDepth();
gal->SetLayerDepth( gal->GetMinDepth() ); GAL_SCOPED_ATTRS scopedAttrs( gal, GAL_SCOPED_ATTRS::LAYER_DEPTH );
gal.SetLayerDepth( gal.GetMinDepth() );
for( const VIEW_OVERLAY::COMMAND* cmd : m_commands ) for( const VIEW_OVERLAY::COMMAND* cmd : m_commands )
cmd->Execute( aView ); cmd->Execute( aView );
gal->PopDepth();
} }

View File

@ -2283,7 +2283,7 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
VECTOR2I pt1 = bbox.GetOrigin(); VECTOR2I pt1 = bbox.GetOrigin();
VECTOR2I pt2 = bbox.GetEnd(); VECTOR2I pt2 = bbox.GetEnd();
m_gal->PushDepth(); GAL_SCOPED_ATTRS scopedAttrs( *m_gal, GAL_SCOPED_ATTRS::ALL );
m_gal->AdvanceDepth(); m_gal->AdvanceDepth();
m_gal->SetIsStroke( true ); m_gal->SetIsStroke( true );
m_gal->SetIsFill( true ); m_gal->SetIsFill( true );
@ -2293,7 +2293,6 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
m_gal->DrawSegment( pt1, pt2, strokeWidth ); m_gal->DrawSegment( pt1, pt2, strokeWidth );
std::swap( pt1.x, pt2.x ); std::swap( pt1.x, pt2.x );
m_gal->DrawSegment( pt1, pt2, strokeWidth ); m_gal->DrawSegment( pt1, pt2, strokeWidth );
m_gal->PopDepth();
} }
} }
@ -2758,8 +2757,7 @@ void SCH_PAINTER::draw( const SCH_SHEET* aSheet, int aLayer )
VECTOR2I pt1 = bbox.GetOrigin(); VECTOR2I pt1 = bbox.GetOrigin();
VECTOR2I pt2 = bbox.GetEnd(); VECTOR2I pt2 = bbox.GetEnd();
m_gal->PushDepth(); GAL_SCOPED_ATTRS scopedAttrs( *m_gal, GAL_SCOPED_ATTRS::ALL );
m_gal->AdvanceDepth();
m_gal->SetIsStroke( true ); m_gal->SetIsStroke( true );
m_gal->SetIsFill( true ); m_gal->SetIsFill( true );
m_gal->SetStrokeColor( m_schSettings.GetLayerColor( layer ) ); m_gal->SetStrokeColor( m_schSettings.GetLayerColor( layer ) );
@ -2768,7 +2766,6 @@ void SCH_PAINTER::draw( const SCH_SHEET* aSheet, int aLayer )
m_gal->DrawSegment( pt1, pt2, strokeWidth ); m_gal->DrawSegment( pt1, pt2, strokeWidth );
std::swap( pt1.x, pt2.x ); std::swap( pt1.x, pt2.x );
m_gal->DrawSegment( pt1, pt2, strokeWidth ); m_gal->DrawSegment( pt1, pt2, strokeWidth );
m_gal->PopDepth();
} }
} }

View File

@ -379,7 +379,10 @@ public:
/** /**
* Set the depth of the layer (position on the z-axis) * Set the depth of the layer (position on the z-axis)
* *
* @param aLayerDepth the layer depth for the objects. * If you do this, you should consider using a GAL_SCOPED_ATTR to ensure
* the depth is reset to the original value.
*
* @param aLayerDepth the layer depth for the objects. Smaller is closer to the viewer.
*/ */
virtual void SetLayerDepth( double aLayerDepth ) virtual void SetLayerDepth( double aLayerDepth )
{ {
@ -389,6 +392,18 @@ public:
m_layerDepth = aLayerDepth; m_layerDepth = aLayerDepth;
} }
/**
* Change the current depth to deeper, so it is possible to draw objects right beneath
* other.
*
* If you do this, you should consider using a GAL_SCOPED_ATTR to ensure the depth
* is reset to the original value.
*/
inline void AdvanceDepth()
{
SetLayerDepth( m_layerDepth - 0.1 );
}
// ---- // ----
// Text // Text
// ---- // ----
@ -945,32 +960,6 @@ public:
*/ */
virtual void DrawCursor( const VECTOR2D& aCursorPosition ) {}; virtual void DrawCursor( const VECTOR2D& aCursorPosition ) {};
/**
* Change the current depth to deeper, so it is possible to draw objects right beneath
* other.
*/
inline void AdvanceDepth()
{
m_layerDepth -= 0.1;
}
/**
* Store current drawing depth on the depth stack.
*/
inline void PushDepth()
{
m_depthStack.push( m_layerDepth );
}
/**
* Restore previously stored drawing depth for the depth stack.
*/
inline void PopDepth()
{
m_layerDepth = m_depthStack.top();
m_depthStack.pop();
}
virtual void EnableDepthTest( bool aEnabled = false ) {}; virtual void EnableDepthTest( bool aEnabled = false ) {};
/** /**
@ -1057,7 +1046,6 @@ protected:
GAL_DISPLAY_OPTIONS& m_options; GAL_DISPLAY_OPTIONS& m_options;
UTIL::LINK m_observerLink; UTIL::LINK m_observerLink;
std::stack<double> m_depthStack; ///< Stored depth values
VECTOR2I m_screenSize; ///< Screen size in screen (wx logical) coordinates VECTOR2I m_screenSize; ///< Screen size in screen (wx logical) coordinates
VECTOR2I m_bitmapSize; ///< Bitmap size, in physical pixels VECTOR2I m_bitmapSize; ///< Bitmap size, in physical pixels
@ -1110,7 +1098,15 @@ protected:
KICURSOR m_currentNativeCursor; ///< Current cursor KICURSOR m_currentNativeCursor; ///< Current cursor
private: private:
inline double getLayerDepth() const
{
return m_layerDepth;
}
TEXT_ATTRIBUTES m_attributes; TEXT_ATTRIBUTES m_attributes;
friend class GAL_SCOPED_ATTRS;
}; };
@ -1180,26 +1176,28 @@ public:
IS_STROKE = 4, IS_STROKE = 4,
FILL_COLOR = 8, FILL_COLOR = 8,
IS_FILL = 16, IS_FILL = 16,
LAYER_DEPTH = 32,
// It is not clear to me that GAL needs to save text attributes. // It is not clear to me that GAL needs to save text attributes.
// Only BitmapText uses it, and maybe that should be passed in // Only BitmapText uses it, and maybe that should be passed in
// explicitly (like for Draw) - every caller of BitmapText sets // explicitly (like for Draw) - every caller of BitmapText sets
// the text attributes anyway. // the text attributes anyway.
// TEXT_ATTRS = 32, // TEXT_ATTRS = 64,
// Convenience flags
STROKE = STROKE_WIDTH | STROKE_COLOR | IS_STROKE, STROKE = STROKE_WIDTH | STROKE_COLOR | IS_STROKE,
FILL = FILL_COLOR | IS_FILL, FILL = FILL_COLOR | IS_FILL,
STROKE_FILL = STROKE | FILL,
///< Convenience flag for setting both stroke and fill ALL = STROKE | FILL | LAYER_DEPTH,
ALL = STROKE | FILL,
}; };
/** /**
* Instantiates a GAL_SCOPED_ATTRS object, saving the current attributes of the GAL. * Instantiates a GAL_SCOPED_ATTRS object, saving the current attributes of the GAL.
* *
* By default, all stroke and fill attributes are saved, which is usually what you want. * Specify the flags to save/restore in aFlags.
*/ */
GAL_SCOPED_ATTRS( KIGFX::GAL& aGal, int aFlags = FLAGS::ALL ) GAL_SCOPED_ATTRS( KIGFX::GAL& aGal, int aFlags )
: m_gal( aGal ), m_flags( aFlags ) : m_gal( aGal ), m_flags( aFlags )
{ {
// Save what we need to restore later. // Save what we need to restore later.
@ -1209,6 +1207,7 @@ public:
m_isStroke = aGal.GetIsStroke(); m_isStroke = aGal.GetIsStroke();
m_fillColor = aGal.GetFillColor(); m_fillColor = aGal.GetFillColor();
m_isFill = aGal.GetIsFill(); m_isFill = aGal.GetIsFill();
m_layerDepth = aGal.getLayerDepth();
} }
~GAL_SCOPED_ATTRS() ~GAL_SCOPED_ATTRS()
@ -1227,6 +1226,9 @@ public:
m_gal.SetFillColor( m_fillColor ); m_gal.SetFillColor( m_fillColor );
if( m_flags & IS_FILL ) if( m_flags & IS_FILL )
m_gal.SetIsFill( m_isFill ); m_gal.SetIsFill( m_isFill );
if( m_flags & LAYER_DEPTH )
m_gal.SetLayerDepth( m_layerDepth );
} }
private: private:
@ -1239,6 +1241,8 @@ private:
COLOR4D m_fillColor; COLOR4D m_fillColor;
bool m_isFill; bool m_isFill;
double m_layerDepth;
}; };