7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-07 22:05:32 +00:00

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 )
{
COLOR4D oldStrokeColor = m_strokeColor;
double oldLayerDepth = m_layerDepth;
GAL_SCOPED_ATTRS( *this, GAL_SCOPED_ATTRS::STROKE_COLOR | GAL_SCOPED_ATTRS::LAYER_DEPTH );
SetLayerDepth( m_layerDepth - 1 );
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 );
}
}
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();
GAL_SCOPED_ATTRS settings( *gal );
GAL_SCOPED_ATTRS settings( *gal, GAL_SCOPED_ATTRS::STROKE_FILL );
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();
bool drawingDropShadows = ( aLayer == getShadowLayer( gal ) );
gal->PushDepth();
GAL_SCOPED_ATTRS scopedAttrs( *gal, GAL_SCOPED_ATTRS::ALL );
gal->SetLayerDepth( gal->GetMinDepth() );
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"
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 );
}
KIGFX::GAL_SCOPED_ATTRS scopedAttrs( *gal, KIGFX::GAL_SCOPED_ATTRS::ALL );
gal->SetFillColor( drawColor );
gal->SetStrokeColor( borderColor );
gal->SetIsFill( true );
gal->SetIsStroke( true );
gal->PushDepth();
gal->SetLayerDepth( gal->GetMinDepth() );
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->PopDepth();
}

View File

@ -145,7 +145,7 @@ void VIEW_GROUP::ViewDraw( int aLayer, VIEW* aView ) const
// 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++ )
{
@ -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
{
auto gal = aView->GetGAL();
gal->PushDepth();
gal->SetLayerDepth( gal->GetMinDepth() );
GAL& gal = *aView->GetGAL();
GAL_SCOPED_ATTRS scopedAttrs( gal, GAL_SCOPED_ATTRS::LAYER_DEPTH );
gal.SetLayerDepth( gal.GetMinDepth() );
for( const VIEW_OVERLAY::COMMAND* cmd : m_commands )
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 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->SetIsFill( true );
@ -2293,7 +2293,6 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
m_gal->DrawSegment( pt1, pt2, strokeWidth );
std::swap( pt1.x, pt2.x );
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 pt2 = bbox.GetEnd();
m_gal->PushDepth();
m_gal->AdvanceDepth();
GAL_SCOPED_ATTRS scopedAttrs( *m_gal, GAL_SCOPED_ATTRS::ALL );
m_gal->SetIsStroke( true );
m_gal->SetIsFill( true );
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 );
std::swap( pt1.x, pt2.x );
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)
*
* @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 )
{
@ -389,6 +392,18 @@ public:
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
// ----
@ -945,32 +960,6 @@ public:
*/
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 ) {};
/**
@ -1057,7 +1046,6 @@ protected:
GAL_DISPLAY_OPTIONS& m_options;
UTIL::LINK m_observerLink;
std::stack<double> m_depthStack; ///< Stored depth values
VECTOR2I m_screenSize; ///< Screen size in screen (wx logical) coordinates
VECTOR2I m_bitmapSize; ///< Bitmap size, in physical pixels
@ -1110,7 +1098,15 @@ protected:
KICURSOR m_currentNativeCursor; ///< Current cursor
private:
inline double getLayerDepth() const
{
return m_layerDepth;
}
TEXT_ATTRIBUTES m_attributes;
friend class GAL_SCOPED_ATTRS;
};
@ -1180,26 +1176,28 @@ public:
IS_STROKE = 4,
FILL_COLOR = 8,
IS_FILL = 16,
LAYER_DEPTH = 32,
// It is not clear to me that GAL needs to save text attributes.
// Only BitmapText uses it, and maybe that should be passed in
// explicitly (like for Draw) - every caller of BitmapText sets
// the text attributes anyway.
// TEXT_ATTRS = 32,
// TEXT_ATTRS = 64,
// Convenience flags
STROKE = STROKE_WIDTH | STROKE_COLOR | IS_STROKE,
FILL = FILL_COLOR | IS_FILL,
STROKE_FILL = STROKE | FILL,
///< Convenience flag for setting both stroke and fill
ALL = STROKE | FILL,
ALL = STROKE | FILL | LAYER_DEPTH,
};
/**
* 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 )
{
// Save what we need to restore later.
@ -1209,6 +1207,7 @@ public:
m_isStroke = aGal.GetIsStroke();
m_fillColor = aGal.GetFillColor();
m_isFill = aGal.GetIsFill();
m_layerDepth = aGal.getLayerDepth();
}
~GAL_SCOPED_ATTRS()
@ -1227,6 +1226,9 @@ public:
m_gal.SetFillColor( m_fillColor );
if( m_flags & IS_FILL )
m_gal.SetIsFill( m_isFill );
if( m_flags & LAYER_DEPTH )
m_gal.SetLayerDepth( m_layerDepth );
}
private:
@ -1239,6 +1241,8 @@ private:
COLOR4D m_fillColor;
bool m_isFill;
double m_layerDepth;
};