Gerbview: fix cairo negative items and implement real differential mode
Layers with negative objects need to be drawn in a subsurface before copying so they don't _CLEAR the draw items below them when a negative object is drawn. Differential layers are basically the same thing only they use a different copying operation onto the layers below. Fixes https://gitlab.com/kicad/code/kicad/-/issues/1863 Fixes https://gitlab.com/kicad/code/kicad/-/issues/4495
This commit is contained in:
parent
21365fff3e
commit
30987cebfe
|
@ -142,6 +142,29 @@ void CAIRO_COMPOSITOR::ClearBuffer( const COLOR4D& aColor )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CAIRO_COMPOSITOR::DrawBuffer( unsigned int aSourceHandle, unsigned int aDestHandle,
|
||||||
|
cairo_operator_t op )
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( aSourceHandle <= usedBuffers() && aDestHandle <= usedBuffers(),
|
||||||
|
wxT( "Tried to use a not existing buffer" ) );
|
||||||
|
|
||||||
|
// Reset the transformation matrix, so it is possible to composite images using
|
||||||
|
// screen coordinates instead of world coordinates
|
||||||
|
cairo_get_matrix( m_mainContext, &m_matrix );
|
||||||
|
cairo_identity_matrix( m_mainContext );
|
||||||
|
|
||||||
|
// Draw the selected buffer contents
|
||||||
|
cairo_t* ct = cairo_create( m_buffers[aDestHandle - 1].surface );
|
||||||
|
cairo_set_operator( ct, op );
|
||||||
|
cairo_set_source_surface( ct, m_buffers[aSourceHandle - 1].surface, 0.0, 0.0 );
|
||||||
|
cairo_paint( ct );
|
||||||
|
cairo_destroy( ct );
|
||||||
|
|
||||||
|
// Restore the transformation matrix
|
||||||
|
cairo_set_matrix( m_mainContext, &m_matrix );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
|
void CAIRO_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( aBufferHandle <= usedBuffers(), wxT( "Tried to use a not existing buffer" ) );
|
wxASSERT_MSG( aBufferHandle <= usedBuffers(), wxT( "Tried to use a not existing buffer" ) );
|
||||||
|
|
|
@ -925,6 +925,32 @@ void CAIRO_GAL_BASE::SetNegativeDrawMode( bool aSetting )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CAIRO_GAL::StartDiffLayer()
|
||||||
|
{
|
||||||
|
SetTarget( TARGET_TEMP );
|
||||||
|
ClearTarget( TARGET_TEMP );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CAIRO_GAL::EndDiffLayer()
|
||||||
|
{
|
||||||
|
m_compositor->DrawBuffer( m_tempBuffer, m_mainBuffer, CAIRO_OPERATOR_ADD );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CAIRO_GAL::StartNegativesLayer()
|
||||||
|
{
|
||||||
|
SetTarget( TARGET_TEMP );
|
||||||
|
ClearTarget( TARGET_TEMP );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CAIRO_GAL::EndNegativesLayer()
|
||||||
|
{
|
||||||
|
m_compositor->DrawBuffer( m_tempBuffer, m_mainBuffer, CAIRO_OPERATOR_OVER );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL_BASE::DrawCursor( const VECTOR2D& aCursorPosition )
|
void CAIRO_GAL_BASE::DrawCursor( const VECTOR2D& aCursorPosition )
|
||||||
{
|
{
|
||||||
m_cursorPosition = aCursorPosition;
|
m_cursorPosition = aCursorPosition;
|
||||||
|
@ -1222,6 +1248,7 @@ CAIRO_GAL::CAIRO_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
|
||||||
// Initialise compositing state
|
// Initialise compositing state
|
||||||
m_mainBuffer = 0;
|
m_mainBuffer = 0;
|
||||||
m_overlayBuffer = 0;
|
m_overlayBuffer = 0;
|
||||||
|
m_tempBuffer = 0;
|
||||||
m_validCompositor = false;
|
m_validCompositor = false;
|
||||||
SetTarget( TARGET_NONCACHED );
|
SetTarget( TARGET_NONCACHED );
|
||||||
|
|
||||||
|
@ -1391,6 +1418,7 @@ void CAIRO_GAL::SetTarget( RENDER_TARGET aTarget )
|
||||||
case TARGET_CACHED:
|
case TARGET_CACHED:
|
||||||
case TARGET_NONCACHED: m_compositor->SetBuffer( m_mainBuffer ); break;
|
case TARGET_NONCACHED: m_compositor->SetBuffer( m_mainBuffer ); break;
|
||||||
case TARGET_OVERLAY: m_compositor->SetBuffer( m_overlayBuffer ); break;
|
case TARGET_OVERLAY: m_compositor->SetBuffer( m_overlayBuffer ); break;
|
||||||
|
case TARGET_TEMP: m_compositor->SetBuffer( m_tempBuffer ); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentTarget = aTarget;
|
m_currentTarget = aTarget;
|
||||||
|
@ -1415,6 +1443,7 @@ void CAIRO_GAL::ClearTarget( RENDER_TARGET aTarget )
|
||||||
case TARGET_CACHED:
|
case TARGET_CACHED:
|
||||||
case TARGET_NONCACHED: m_compositor->SetBuffer( m_mainBuffer ); break;
|
case TARGET_NONCACHED: m_compositor->SetBuffer( m_mainBuffer ); break;
|
||||||
case TARGET_OVERLAY: m_compositor->SetBuffer( m_overlayBuffer ); break;
|
case TARGET_OVERLAY: m_compositor->SetBuffer( m_overlayBuffer ); break;
|
||||||
|
case TARGET_TEMP: m_compositor->SetBuffer( m_tempBuffer ); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_compositor->ClearBuffer( COLOR4D::BLACK );
|
m_compositor->ClearBuffer( COLOR4D::BLACK );
|
||||||
|
@ -1498,6 +1527,7 @@ void CAIRO_GAL::setCompositor()
|
||||||
// Prepare buffers
|
// Prepare buffers
|
||||||
m_mainBuffer = m_compositor->CreateBuffer();
|
m_mainBuffer = m_compositor->CreateBuffer();
|
||||||
m_overlayBuffer = m_compositor->CreateBuffer();
|
m_overlayBuffer = m_compositor->CreateBuffer();
|
||||||
|
m_tempBuffer = m_compositor->CreateBuffer();
|
||||||
|
|
||||||
m_validCompositor = true;
|
m_validCompositor = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1739,6 +1739,20 @@ bool OPENGL_GAL::HasTarget( RENDER_TARGET aTarget )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OPENGL_GAL::StartDiffLayer()
|
||||||
|
{
|
||||||
|
m_currentManager->EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OPENGL_GAL::EndDiffLayer()
|
||||||
|
{
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
||||||
|
m_currentManager->EndDrawing();
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool OPENGL_GAL::SetNativeCursorStyle( KICURSOR aCursor )
|
bool OPENGL_GAL::SetNativeCursorStyle( KICURSOR aCursor )
|
||||||
{
|
{
|
||||||
// Store the current cursor type and get the wxCursor for it
|
// Store the current cursor type and get the wxCursor for it
|
||||||
|
|
|
@ -302,6 +302,8 @@ VIEW::VIEW( bool aIsDynamic ) :
|
||||||
m_layers[ii].renderingOrder = ii;
|
m_layers[ii].renderingOrder = ii;
|
||||||
m_layers[ii].visible = true;
|
m_layers[ii].visible = true;
|
||||||
m_layers[ii].displayOnly = false;
|
m_layers[ii].displayOnly = false;
|
||||||
|
m_layers[ii].diffLayer = false;
|
||||||
|
m_layers[ii].hasNegatives = false;
|
||||||
m_layers[ii].target = TARGET_CACHED;
|
m_layers[ii].target = TARGET_CACHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -995,10 +997,24 @@ void VIEW::redrawRect( const BOX2I& aRect )
|
||||||
|
|
||||||
m_gal->SetTarget( l->target );
|
m_gal->SetTarget( l->target );
|
||||||
m_gal->SetLayerDepth( l->renderingOrder );
|
m_gal->SetLayerDepth( l->renderingOrder );
|
||||||
|
|
||||||
|
// Differential layer also work for the negatives, since both special layer types
|
||||||
|
// will composite on separate layers (at least in Cairo)
|
||||||
|
if( l->diffLayer )
|
||||||
|
m_gal->StartDiffLayer();
|
||||||
|
else if( l->hasNegatives )
|
||||||
|
m_gal->StartNegativesLayer();
|
||||||
|
|
||||||
|
|
||||||
l->items->Query( aRect, drawFunc );
|
l->items->Query( aRect, drawFunc );
|
||||||
|
|
||||||
if( m_useDrawPriority )
|
if( m_useDrawPriority )
|
||||||
drawFunc.deferredDraw();
|
drawFunc.deferredDraw();
|
||||||
|
|
||||||
|
if( l->diffLayer )
|
||||||
|
m_gal->EndDiffLayer();
|
||||||
|
else if( l->hasNegatives )
|
||||||
|
m_gal->EndNegativesLayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1142,10 +1158,9 @@ void VIEW::Redraw()
|
||||||
recti.SetMaximum();
|
recti.SetMaximum();
|
||||||
|
|
||||||
redrawRect( recti );
|
redrawRect( recti );
|
||||||
|
|
||||||
// All targets were redrawn, so nothing is dirty
|
// All targets were redrawn, so nothing is dirty
|
||||||
markTargetClean( TARGET_CACHED );
|
MarkClean();
|
||||||
markTargetClean( TARGET_NONCACHED );
|
|
||||||
markTargetClean( TARGET_OVERLAY );
|
|
||||||
|
|
||||||
#ifdef KICAD_GAL_PROFILE
|
#ifdef KICAD_GAL_PROFILE
|
||||||
totalRealTime.Stop();
|
totalRealTime.Stop();
|
||||||
|
|
|
@ -86,6 +86,9 @@ bool PANEL_GERBVIEW_DISPLAY_OPTIONS::TransferDataFromWindow()
|
||||||
|
|
||||||
m_galOptsPanel->TransferDataFromWindow();
|
m_galOptsPanel->TransferDataFromWindow();
|
||||||
|
|
||||||
|
if( displayOptions.m_DiffMode )
|
||||||
|
m_Parent->UpdateDiffLayers();
|
||||||
|
|
||||||
// Apply changes to the GAL
|
// Apply changes to the GAL
|
||||||
auto view = m_Parent->GetCanvas()->GetView();
|
auto view = m_Parent->GetCanvas()->GetView();
|
||||||
auto painter = static_cast<KIGFX::GERBVIEW_PAINTER*>( view->GetPainter() );
|
auto painter = static_cast<KIGFX::GERBVIEW_PAINTER*>( view->GetPainter() );
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <gerber_file_image_list.h>
|
#include <gerber_file_image_list.h>
|
||||||
#include <excellon_image.h>
|
#include <excellon_image.h>
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
|
#include <view/view.h>
|
||||||
#include <widgets/wx_progress_reporters.h>
|
#include <widgets/wx_progress_reporters.h>
|
||||||
#include "widgets/gerbview_layer_widget.h"
|
#include "widgets/gerbview_layer_widget.h"
|
||||||
|
|
||||||
|
@ -293,6 +294,9 @@ bool GERBVIEW_FRAME::LoadListOfGerberAndDrillFiles( const wxString& aPath,
|
||||||
{
|
{
|
||||||
UpdateFileHistory( m_lastFileName );
|
UpdateFileHistory( m_lastFileName );
|
||||||
|
|
||||||
|
GetCanvas()->GetView()->SetLayerHasNegatives(
|
||||||
|
GERBER_DRAW_LAYER( layer ), GetGbrImage( layer )->HasNegativeItems() );
|
||||||
|
|
||||||
layer = getNextAvailableLayer( layer );
|
layer = getNextAvailableLayer( layer );
|
||||||
|
|
||||||
if( layer == NO_AVAILABLE_LAYERS && ii < aFilenameList.GetCount() - 1 )
|
if( layer == NO_AVAILABLE_LAYERS && ii < aFilenameList.GetCount() - 1 )
|
||||||
|
@ -584,6 +588,10 @@ bool GERBVIEW_FRAME::unarchiveFiles( const wxString& aFullFileName, REPORTER* aR
|
||||||
{
|
{
|
||||||
// Read gerber files: each file is loaded on a new GerbView layer
|
// Read gerber files: each file is loaded on a new GerbView layer
|
||||||
read_ok = Read_GERBER_File( unzipped_tempfile );
|
read_ok = Read_GERBER_File( unzipped_tempfile );
|
||||||
|
|
||||||
|
if( read_ok )
|
||||||
|
GetCanvas()->GetView()->SetLayerHasNegatives(
|
||||||
|
GERBER_DRAW_LAYER( layer ), GetGbrImage( layer )->HasNegativeItems() );
|
||||||
}
|
}
|
||||||
else // if( curr_ext == "drl" )
|
else // if( curr_ext == "drl" )
|
||||||
{
|
{
|
||||||
|
|
|
@ -534,6 +534,38 @@ void GERBVIEW_FRAME::SortLayersByX2Attributes()
|
||||||
GetCanvas()->Refresh();
|
GetCanvas()->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GERBVIEW_FRAME::UpdateDiffLayers()
|
||||||
|
{
|
||||||
|
auto target = GetCanvas()->GetBackend() == GERBVIEW_DRAW_PANEL_GAL::GAL_TYPE::GAL_TYPE_OPENGL
|
||||||
|
? KIGFX::TARGET_CACHED
|
||||||
|
: KIGFX::TARGET_NONCACHED;
|
||||||
|
auto view = GetCanvas()->GetView();
|
||||||
|
|
||||||
|
int lastVisibleLayer = -1;
|
||||||
|
for( int i = 0; i < GERBER_DRAWLAYERS_COUNT; i++ )
|
||||||
|
{
|
||||||
|
view->SetLayerDiff( GERBER_DRAW_LAYER( i ), m_DisplayOptions.m_DiffMode );
|
||||||
|
// Caching doesn't work with layered rendering of diff'd layers
|
||||||
|
view->SetLayerTarget( GERBER_DRAW_LAYER( i ),
|
||||||
|
m_DisplayOptions.m_DiffMode ? KIGFX::TARGET_NONCACHED : target );
|
||||||
|
//We want the last visible layer, but deprioritize the active layer unless it's the only layer
|
||||||
|
if( ( lastVisibleLayer == -1 )
|
||||||
|
|| ( view->IsLayerVisible( GERBER_DRAW_LAYER( i ) ) && i != GetActiveLayer() ) )
|
||||||
|
lastVisibleLayer = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//We don't want to diff the last visible layer onto the background, etc.
|
||||||
|
if( lastVisibleLayer != -1 )
|
||||||
|
{
|
||||||
|
view->SetLayerTarget( GERBER_DRAW_LAYER( lastVisibleLayer ), target );
|
||||||
|
view->SetLayerDiff( GERBER_DRAW_LAYER( lastVisibleLayer ), false );
|
||||||
|
}
|
||||||
|
|
||||||
|
view->RecacheAllItems();
|
||||||
|
view->MarkDirty();
|
||||||
|
view->UpdateAllItems( KIGFX::ALL );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GERBVIEW_FRAME::UpdateDisplayOptions( const GBR_DISPLAY_OPTIONS& aOptions )
|
void GERBVIEW_FRAME::UpdateDisplayOptions( const GBR_DISPLAY_OPTIONS& aOptions )
|
||||||
{
|
{
|
||||||
|
@ -543,12 +575,16 @@ void GERBVIEW_FRAME::UpdateDisplayOptions( const GBR_DISPLAY_OPTIONS& aOptions )
|
||||||
aOptions.m_DisplayLinesFill );
|
aOptions.m_DisplayLinesFill );
|
||||||
bool update_polygons = ( m_DisplayOptions.m_DisplayPolygonsFill !=
|
bool update_polygons = ( m_DisplayOptions.m_DisplayPolygonsFill !=
|
||||||
aOptions.m_DisplayPolygonsFill );
|
aOptions.m_DisplayPolygonsFill );
|
||||||
|
bool update_diff_mode = ( m_DisplayOptions.m_DiffMode != aOptions.m_DiffMode );
|
||||||
|
|
||||||
|
auto view = GetCanvas()->GetView();
|
||||||
|
|
||||||
m_DisplayOptions = aOptions;
|
m_DisplayOptions = aOptions;
|
||||||
|
|
||||||
applyDisplaySettingsToGAL();
|
applyDisplaySettingsToGAL();
|
||||||
|
|
||||||
auto view = GetCanvas()->GetView();
|
if( update_diff_mode )
|
||||||
|
UpdateDiffLayers();
|
||||||
|
|
||||||
if( update_flashed )
|
if( update_flashed )
|
||||||
{
|
{
|
||||||
|
@ -819,6 +855,9 @@ void GERBVIEW_FRAME::SetActiveLayer( int aLayer, bool doLayerWidgetUpdate )
|
||||||
{
|
{
|
||||||
m_activeLayer = aLayer;
|
m_activeLayer = aLayer;
|
||||||
|
|
||||||
|
if( m_DisplayOptions.m_DiffMode )
|
||||||
|
UpdateDiffLayers();
|
||||||
|
|
||||||
if( doLayerWidgetUpdate )
|
if( doLayerWidgetUpdate )
|
||||||
m_LayersManager->SelectLayer( aLayer );
|
m_LayersManager->SelectLayer( aLayer );
|
||||||
|
|
||||||
|
|
|
@ -345,6 +345,12 @@ public:
|
||||||
|
|
||||||
void SortLayersByX2Attributes();
|
void SortLayersByX2Attributes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update each layers' differential option. Needed when diff mode changes or the active layer
|
||||||
|
* changes (due to changing rendering order) which matters for diff mode but not otherwise.
|
||||||
|
*/
|
||||||
|
void UpdateDiffLayers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the display options and refreshes the view as needed.
|
* Update the display options and refreshes the view as needed.
|
||||||
*
|
*
|
||||||
|
|
|
@ -66,9 +66,6 @@ void GERBVIEW_RENDER_SETTINGS::LoadColors( const COLOR_SETTINGS* aSettings )
|
||||||
if( baseColor == COLOR4D::UNSPECIFIED )
|
if( baseColor == COLOR4D::UNSPECIFIED )
|
||||||
baseColor = aSettings->m_Palette[ ( palette_idx++ ) % palette_size ];
|
baseColor = aSettings->m_Palette[ ( palette_idx++ ) % palette_size ];
|
||||||
|
|
||||||
if( m_diffMode )
|
|
||||||
baseColor.a = 0.75;
|
|
||||||
|
|
||||||
m_layerColors[i] = baseColor;
|
m_layerColors[i] = baseColor;
|
||||||
m_layerColorsHi[i] = baseColor.Brightened( 0.5 );
|
m_layerColorsHi[i] = baseColor.Brightened( 0.5 );
|
||||||
m_layerColorsSel[i] = baseColor.Brightened( 0.8 );
|
m_layerColorsSel[i] = baseColor.Brightened( 0.8 );
|
||||||
|
|
|
@ -71,6 +71,15 @@ public:
|
||||||
/// @copydoc COMPOSITOR::ClearBuffer()
|
/// @copydoc COMPOSITOR::ClearBuffer()
|
||||||
virtual void ClearBuffer( const COLOR4D& aColor ) override;
|
virtual void ClearBuffer( const COLOR4D& aColor ) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paints source to destination using the cairo operator. Useful for differential mode.
|
||||||
|
*
|
||||||
|
* @param aSourceHandle Source buffer to paint
|
||||||
|
* @param aDestHandle Destination buffer to paint on to
|
||||||
|
* @param op Painting operation
|
||||||
|
*/
|
||||||
|
void DrawBuffer( unsigned int aSourceHandle, unsigned int aDestHandle, cairo_operator_t op );
|
||||||
|
|
||||||
/// @copydoc COMPOSITOR::DrawBuffer()
|
/// @copydoc COMPOSITOR::DrawBuffer()
|
||||||
virtual void DrawBuffer( unsigned int aBufferHandle ) override;
|
virtual void DrawBuffer( unsigned int aBufferHandle ) override;
|
||||||
|
|
||||||
|
|
|
@ -389,6 +389,18 @@ public:
|
||||||
|
|
||||||
void ClearTarget( RENDER_TARGET aTarget ) override;
|
void ClearTarget( RENDER_TARGET aTarget ) override;
|
||||||
|
|
||||||
|
/// @copydoc GAL::StartDiffLayer()
|
||||||
|
void StartDiffLayer() override;
|
||||||
|
|
||||||
|
/// @copydoc GAL::EndDiffLayer()
|
||||||
|
void EndDiffLayer() override;
|
||||||
|
|
||||||
|
/// @copydoc GAL::StartNegativesLayer()
|
||||||
|
void StartNegativesLayer() override;
|
||||||
|
|
||||||
|
/// @copydoc GAL::EndNegativesLayer()
|
||||||
|
void EndNegativesLayer() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post an event to m_paint_listener.
|
* Post an event to m_paint_listener.
|
||||||
*
|
*
|
||||||
|
@ -461,6 +473,8 @@ protected:
|
||||||
std::shared_ptr<CAIRO_COMPOSITOR> m_compositor; ///< Object for layers compositing
|
std::shared_ptr<CAIRO_COMPOSITOR> m_compositor; ///< Object for layers compositing
|
||||||
unsigned int m_mainBuffer; ///< Handle to the main buffer
|
unsigned int m_mainBuffer; ///< Handle to the main buffer
|
||||||
unsigned int m_overlayBuffer; ///< Handle to the overlay buffer
|
unsigned int m_overlayBuffer; ///< Handle to the overlay buffer
|
||||||
|
unsigned int m_tempBuffer; ///< Handle to the temp buffer
|
||||||
|
unsigned int m_savedBuffer; ///< Handle to buffer to restore after rendering to temp buffer
|
||||||
RENDER_TARGET m_currentTarget; ///< Current rendering target
|
RENDER_TARGET m_currentTarget; ///< Current rendering target
|
||||||
bool m_validCompositor; ///< Compositor initialization flag
|
bool m_validCompositor; ///< Compositor initialization flag
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ enum RENDER_TARGET
|
||||||
TARGET_CACHED = 0, ///< Main rendering target (cached)
|
TARGET_CACHED = 0, ///< Main rendering target (cached)
|
||||||
TARGET_NONCACHED, ///< Auxiliary rendering target (noncached)
|
TARGET_NONCACHED, ///< Auxiliary rendering target (noncached)
|
||||||
TARGET_OVERLAY, ///< Items that may change while the view stays the same (noncached)
|
TARGET_OVERLAY, ///< Items that may change while the view stays the same (noncached)
|
||||||
|
TARGET_TEMP, ///< Temporary target for drawing in separate layer
|
||||||
TARGETS_NUMBER ///< Number of available rendering targets
|
TARGETS_NUMBER ///< Number of available rendering targets
|
||||||
};
|
};
|
||||||
} // namespace KIGFX
|
} // namespace KIGFX
|
||||||
|
|
|
@ -818,6 +818,38 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void SetNegativeDrawMode( bool aSetting ) {};
|
virtual void SetNegativeDrawMode( bool aSetting ) {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins rendering of a differential layer. Used by gerbview's differential mode.
|
||||||
|
*
|
||||||
|
* Differential layers have their drawn objects blended onto the lower layers
|
||||||
|
* differently so we need to end drawing of current objects and start a new
|
||||||
|
* set to be completed with a different blend mode.
|
||||||
|
*/
|
||||||
|
virtual void StartDiffLayer() {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends rendering of a differential layer. Objects drawn after the StartDiffLayer()
|
||||||
|
* will be drawn and composited with a differential blend mode, then drawing is
|
||||||
|
* returned to normal.
|
||||||
|
*/
|
||||||
|
virtual void EndDiffLayer() {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins rendering in a new layer that will be copied to the main
|
||||||
|
* layer in EndNegativesLayer().
|
||||||
|
*
|
||||||
|
* For Cairo, layers with negative items need a new layer so when
|
||||||
|
* negative layers _CLEAR sections it doesn't delete drawings on layers
|
||||||
|
* below them. No-op in OpenGL
|
||||||
|
*/
|
||||||
|
virtual void StartNegativesLayer(){};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends rendering of a negatives layer and draws it to the main layer.
|
||||||
|
* No-op in OpenGL.
|
||||||
|
*/
|
||||||
|
virtual void EndNegativesLayer(){};
|
||||||
|
|
||||||
// -------------
|
// -------------
|
||||||
// Grid methods
|
// Grid methods
|
||||||
// -------------
|
// -------------
|
||||||
|
|
|
@ -241,6 +241,12 @@ public:
|
||||||
/// @copydoc GAL::SetNegativeDrawMode()
|
/// @copydoc GAL::SetNegativeDrawMode()
|
||||||
void SetNegativeDrawMode( bool aSetting ) override {}
|
void SetNegativeDrawMode( bool aSetting ) override {}
|
||||||
|
|
||||||
|
/// @copydoc GAL::StartDiffLayer()
|
||||||
|
void StartDiffLayer() override;
|
||||||
|
//
|
||||||
|
/// @copydoc GAL::EndDiffLayer()
|
||||||
|
void EndDiffLayer() override;
|
||||||
|
|
||||||
void ComputeWorldScreenMatrix() override;
|
void ComputeWorldScreenMatrix() override;
|
||||||
|
|
||||||
// -------
|
// -------
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <gal/definitions.h>
|
#include <gal/definitions.h>
|
||||||
|
|
||||||
#include <view/view_overlay.h>
|
#include <view/view_overlay.h>
|
||||||
|
#include <view/view.h>
|
||||||
|
|
||||||
class EDA_ITEM;
|
class EDA_ITEM;
|
||||||
|
|
||||||
|
@ -409,6 +410,42 @@ public:
|
||||||
return m_layers.at( aLayer ).visible;
|
return m_layers.at( aLayer ).visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the whether the layer should drawn differentially.
|
||||||
|
*
|
||||||
|
* @param aLayer is the layer to set to be draw differentially
|
||||||
|
* @param aDiff is the layer diff'ing state.
|
||||||
|
*/
|
||||||
|
inline void SetLayerDiff( int aLayer, bool aDiff = true )
|
||||||
|
{
|
||||||
|
wxCHECK( aLayer < (int) m_layers.size(), /*void*/ );
|
||||||
|
|
||||||
|
if( m_layers[aLayer].diffLayer != aDiff )
|
||||||
|
{
|
||||||
|
// Target has to be redrawn after changing its layers' diff status
|
||||||
|
MarkTargetDirty( m_layers[aLayer].target );
|
||||||
|
m_layers[aLayer].diffLayer = aDiff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the status of negatives presense in a particular layer.
|
||||||
|
*
|
||||||
|
* @param aLayer is the layer to set as containing negatives (or not).
|
||||||
|
* @param aNegatives is the layer negatives state.
|
||||||
|
*/
|
||||||
|
inline void SetLayerHasNegatives( int aLayer, bool aNegatives = true )
|
||||||
|
{
|
||||||
|
wxCHECK( aLayer < (int) m_layers.size(), /*void*/ );
|
||||||
|
|
||||||
|
if( m_layers[aLayer].hasNegatives != aNegatives )
|
||||||
|
{
|
||||||
|
// Target has to be redrawn after changing a layers' negatives
|
||||||
|
MarkTargetDirty( m_layers[aLayer].target );
|
||||||
|
m_layers[aLayer].hasNegatives = aNegatives;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void SetLayerDisplayOnly( int aLayer, bool aDisplayOnly = true )
|
inline void SetLayerDisplayOnly( int aLayer, bool aDisplayOnly = true )
|
||||||
{
|
{
|
||||||
wxCHECK( aLayer < (int) m_layers.size(), /*void*/ );
|
wxCHECK( aLayer < (int) m_layers.size(), /*void*/ );
|
||||||
|
@ -599,6 +636,15 @@ public:
|
||||||
m_dirtyTargets[i] = true;
|
m_dirtyTargets[i] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force redraw of view on the next rendering.
|
||||||
|
*/
|
||||||
|
void MarkClean()
|
||||||
|
{
|
||||||
|
for( int i = 0; i < TARGETS_NUMBER; ++i )
|
||||||
|
m_dirtyTargets[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an item to a list of items that are going to be refreshed upon the next frame rendering.
|
* Add an item to a list of items that are going to be refreshed upon the next frame rendering.
|
||||||
*
|
*
|
||||||
|
@ -684,6 +730,8 @@ protected:
|
||||||
{
|
{
|
||||||
bool visible; ///< Is the layer to be rendered?
|
bool visible; ///< Is the layer to be rendered?
|
||||||
bool displayOnly; ///< Is the layer display only?
|
bool displayOnly; ///< Is the layer display only?
|
||||||
|
bool diffLayer; ///< Layer should be drawn differentially over lower layers
|
||||||
|
bool hasNegatives; ///< Layer should be drawn separately to not delete lower layers
|
||||||
std::shared_ptr<VIEW_RTREE> items; ///< R-tree indexing all items on this layer.
|
std::shared_ptr<VIEW_RTREE> items; ///< R-tree indexing all items on this layer.
|
||||||
int renderingOrder; ///< Rendering order of this layer.
|
int renderingOrder; ///< Rendering order of this layer.
|
||||||
int id; ///< Layer ID.
|
int id; ///< Layer ID.
|
||||||
|
|
Loading…
Reference in New Issue