Gerbview: try to fix a crash (hard to reproduce) which someting happens when closing gerbview. Fix incorrect calculation of bounding boxes.
This commit is contained in:
parent
7ff3dd0807
commit
947c73f23b
|
@ -59,6 +59,7 @@ bool GBR_LAYOUT::IsLayerPrintable( int aLayer ) const
|
||||||
EDA_RECT GBR_LAYOUT::ComputeBoundingBox()
|
EDA_RECT GBR_LAYOUT::ComputeBoundingBox()
|
||||||
{
|
{
|
||||||
EDA_RECT bbox;
|
EDA_RECT bbox;
|
||||||
|
bool first_item = true;
|
||||||
|
|
||||||
for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
|
for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
|
||||||
{
|
{
|
||||||
|
@ -68,7 +69,15 @@ EDA_RECT GBR_LAYOUT::ComputeBoundingBox()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for( GERBER_DRAW_ITEM* item = gerber->GetItemsList(); item; item = item->Next() )
|
for( GERBER_DRAW_ITEM* item = gerber->GetItemsList(); item; item = item->Next() )
|
||||||
bbox.Merge( item->GetBoundingBox() );
|
{
|
||||||
|
if( first_item )
|
||||||
|
{
|
||||||
|
bbox = item->GetBoundingBox();
|
||||||
|
first_item = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bbox.Merge( item->GetBoundingBox() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetBoundingBox( bbox );
|
SetBoundingBox( bbox );
|
||||||
|
|
|
@ -207,8 +207,15 @@ const EDA_RECT GERBER_DRAW_ITEM::GetBoundingBox() const
|
||||||
|
|
||||||
bbox.Inflate( m_Size.x / 2, m_Size.y / 2 );
|
bbox.Inflate( m_Size.x / 2, m_Size.y / 2 );
|
||||||
|
|
||||||
bbox.SetOrigin( GetABPosition( bbox.GetOrigin() ) );
|
// calculate the corners coordinates in current gerber axis orientations
|
||||||
bbox.SetEnd( GetABPosition( bbox.GetEnd() ) );
|
wxPoint org = GetABPosition( bbox.GetOrigin() );
|
||||||
|
wxPoint end = GetABPosition( bbox.GetEnd() );
|
||||||
|
|
||||||
|
// Set the corners position:
|
||||||
|
bbox.SetOrigin( org );
|
||||||
|
bbox.SetEnd( end );
|
||||||
|
bbox.Normalize();
|
||||||
|
|
||||||
return bbox;
|
return bbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,8 @@ GERBER_FILE_IMAGE::GERBER_FILE_IMAGE( int aLayer )
|
||||||
|
|
||||||
GERBER_FILE_IMAGE::~GERBER_FILE_IMAGE()
|
GERBER_FILE_IMAGE::~GERBER_FILE_IMAGE()
|
||||||
{
|
{
|
||||||
|
m_Drawings.DeleteAll();
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
|
for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
|
||||||
{
|
{
|
||||||
delete m_Aperture_List[ii];
|
delete m_Aperture_List[ii];
|
||||||
|
|
|
@ -47,17 +47,13 @@ GERBER_FILE_IMAGE_LIST::GERBER_FILE_IMAGE_LIST()
|
||||||
m_GERBER_List.push_back( NULL );
|
m_GERBER_List.push_back( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GERBER_FILE_IMAGE_LIST::~GERBER_FILE_IMAGE_LIST()
|
GERBER_FILE_IMAGE_LIST::~GERBER_FILE_IMAGE_LIST()
|
||||||
{
|
{
|
||||||
ClearList();
|
DeleteAllImages();
|
||||||
|
|
||||||
for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
|
|
||||||
{
|
|
||||||
delete m_GERBER_List[layer];
|
|
||||||
m_GERBER_List[layer] = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GERBER_FILE_IMAGE* GERBER_FILE_IMAGE_LIST::GetGbrImage( int aIdx )
|
GERBER_FILE_IMAGE* GERBER_FILE_IMAGE_LIST::GetGbrImage( int aIdx )
|
||||||
{
|
{
|
||||||
if( (unsigned)aIdx < m_GERBER_List.size() )
|
if( (unsigned)aIdx < m_GERBER_List.size() )
|
||||||
|
@ -66,11 +62,10 @@ GERBER_FILE_IMAGE* GERBER_FILE_IMAGE_LIST::GetGbrImage( int aIdx )
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* creates a new, empty GERBER_FILE_IMAGE* at index aIdx
|
||||||
* creates a new, empty GERBER_FILE_IMAGE* at index aIdx
|
|
||||||
* or at the first free location if aIdx < 0
|
* or at the first free location if aIdx < 0
|
||||||
* @param aIdx = the location to use ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
|
* aIdx = the index of graphic layer to use, or -1 to uses the first free graphic layer
|
||||||
* @return true if the index used, or -1 if no room to add image
|
* return the index actually used, or -1 if no room to add image
|
||||||
*/
|
*/
|
||||||
int GERBER_FILE_IMAGE_LIST::AddGbrImage( GERBER_FILE_IMAGE* aGbrImage, int aIdx )
|
int GERBER_FILE_IMAGE_LIST::AddGbrImage( GERBER_FILE_IMAGE* aGbrImage, int aIdx )
|
||||||
{
|
{
|
||||||
|
@ -80,7 +75,7 @@ int GERBER_FILE_IMAGE_LIST::AddGbrImage( GERBER_FILE_IMAGE* aGbrImage, int aIdx
|
||||||
{
|
{
|
||||||
for( idx = 0; idx < (int)m_GERBER_List.size(); idx++ )
|
for( idx = 0; idx < (int)m_GERBER_List.size(); idx++ )
|
||||||
{
|
{
|
||||||
if( !IsUsed( idx ) )
|
if( m_GERBER_List[idx] == NULL )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,23 +89,24 @@ int GERBER_FILE_IMAGE_LIST::AddGbrImage( GERBER_FILE_IMAGE* aGbrImage, int aIdx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// remove all loaded data in list, but do not delete empty images
|
void GERBER_FILE_IMAGE_LIST::DeleteAllImages()
|
||||||
// (can be reused)
|
|
||||||
void GERBER_FILE_IMAGE_LIST::ClearList()
|
|
||||||
{
|
{
|
||||||
for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
|
for( unsigned idx = 0; idx < m_GERBER_List.size(); ++idx )
|
||||||
ClearImage( layer );
|
DeleteImage( idx );
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove the loaded data of image aIdx, but do not delete it
|
|
||||||
void GERBER_FILE_IMAGE_LIST::ClearImage( int aIdx )
|
void GERBER_FILE_IMAGE_LIST::DeleteImage( int aIdx )
|
||||||
{
|
{
|
||||||
if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() && m_GERBER_List[aIdx] )
|
// Ensure the index is valid:
|
||||||
{
|
if( aIdx < 0 || aIdx >= int( m_GERBER_List.size() ) )
|
||||||
m_GERBER_List[aIdx]->InitToolTable();
|
return;
|
||||||
m_GERBER_List[aIdx]->ResetDefaultValues();
|
|
||||||
m_GERBER_List[aIdx]->m_InUse = false;
|
// delete image aIdx
|
||||||
}
|
GERBER_FILE_IMAGE* gbr_image = GetGbrImage( aIdx );
|
||||||
|
|
||||||
|
delete gbr_image;
|
||||||
|
m_GERBER_List[ aIdx ] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a name for image aIdx which can be used in layers manager
|
// Build a name for image aIdx which can be used in layers manager
|
||||||
|
@ -127,7 +123,7 @@ const wxString GERBER_FILE_IMAGE_LIST::GetDisplayName( int aIdx )
|
||||||
// <id> <short filename> <X2 FileFunction info> if a X2 FileFunction info is found
|
// <id> <short filename> <X2 FileFunction info> if a X2 FileFunction info is found
|
||||||
// or (if no FileFunction info)
|
// or (if no FileFunction info)
|
||||||
// <id> <short filename> *
|
// <id> <short filename> *
|
||||||
if( gerber && IsUsed(aIdx ) )
|
if( gerber )
|
||||||
{
|
{
|
||||||
wxFileName fn( gerber->m_FileName );
|
wxFileName fn( gerber->m_FileName );
|
||||||
wxString filename = fn.GetFullName();
|
wxString filename = fn.GetFullName();
|
||||||
|
@ -168,14 +164,7 @@ const wxString GERBER_FILE_IMAGE_LIST::GetDisplayName( int aIdx )
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true if image is used (loaded and not cleared)
|
|
||||||
bool GERBER_FILE_IMAGE_LIST::IsUsed( int aIdx )
|
|
||||||
{
|
|
||||||
if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() )
|
|
||||||
return m_GERBER_List[aIdx] != NULL && m_GERBER_List[aIdx]->m_InUse;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function, for std::sort.
|
// Helper function, for std::sort.
|
||||||
// Sort loaded images by Z order priority, if they have the X2 FileFormat info
|
// Sort loaded images by Z order priority, if they have the X2 FileFormat info
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
//#include <dcode.h>
|
|
||||||
#include <class_gerber_draw_item.h>
|
#include <class_gerber_draw_item.h>
|
||||||
#include <class_aperture_macro.h>
|
#include <class_aperture_macro.h>
|
||||||
|
|
||||||
|
@ -83,15 +82,15 @@ public:
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove all loaded data in list
|
* remove all loaded data in list, and delete all images. Memory is freed
|
||||||
*/
|
*/
|
||||||
void ClearList();
|
void DeleteAllImages();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove the loaded data of image aIdx
|
* delete the loaded data of image aIdx. Memory is freed
|
||||||
* @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
|
* @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
|
||||||
*/
|
*/
|
||||||
void ClearImage( int aIdx );
|
void DeleteImage( int aIdx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a name for image aIdx which can be used in layers manager
|
* @return a name for image aIdx which can be used in layers manager
|
||||||
|
@ -106,12 +105,6 @@ public:
|
||||||
*/
|
*/
|
||||||
const wxString GetDisplayName( int aIdx );
|
const wxString GetDisplayName( int aIdx );
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if image is used (loaded and with items)
|
|
||||||
* @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
|
|
||||||
*/
|
|
||||||
bool IsUsed( int aIdx );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort loaded images by Z order priority, if they have the X2 FileFormat info
|
* Sort loaded images by Z order priority, if they have the X2 FileFormat info
|
||||||
* (SortImagesByZOrder updates the graphic layer of these items)
|
* (SortImagesByZOrder updates the graphic layer of these items)
|
||||||
|
|
|
@ -307,11 +307,11 @@ void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
|
||||||
/*
|
/*
|
||||||
* Virtual Function useAlternateBitmap
|
* Virtual Function useAlternateBitmap
|
||||||
* return true if bitmaps shown in Render layer list
|
* return true if bitmaps shown in Render layer list
|
||||||
* must be alternate bitmaps, or false to use "normal" bitmaps
|
* must be alternate bitmap (when a gerber iùmage is loaded), or false to use "normal" bitmap
|
||||||
*/
|
*/
|
||||||
bool GERBER_LAYER_WIDGET::useAlternateBitmap(int aRow)
|
bool GERBER_LAYER_WIDGET::useAlternateBitmap(int aRow)
|
||||||
{
|
{
|
||||||
return g_GERBER_List.IsUsed( aRow );
|
return g_GERBER_List.GetGbrImage( aRow ) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -47,22 +47,10 @@ bool GERBVIEW_FRAME::Clear_DrawLayers( bool query )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
|
g_GERBER_List.DeleteAllImages();
|
||||||
{
|
|
||||||
GERBER_FILE_IMAGE* gerber = g_GERBER_List.GetGbrImage( layer );
|
|
||||||
|
|
||||||
if( gerber == NULL ) // Graphic layer not yet used
|
|
||||||
continue;
|
|
||||||
|
|
||||||
gerber->m_Drawings.DeleteAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
g_GERBER_List.ClearList();
|
|
||||||
|
|
||||||
GetGerberLayout()->SetBoundingBox( EDA_RECT() );
|
GetGerberLayout()->SetBoundingBox( EDA_RECT() );
|
||||||
|
|
||||||
SetScreen( new GBR_SCREEN( GetPageSettings().GetSizeIU() ) );
|
|
||||||
|
|
||||||
setActiveLayer( 0 );
|
setActiveLayer( 0 );
|
||||||
m_LayersManager->UpdateLayerIcons();
|
m_LayersManager->UpdateLayerIcons();
|
||||||
syncLayerBox();
|
syncLayerBox();
|
||||||
|
@ -82,15 +70,9 @@ void GERBVIEW_FRAME::Erase_Current_DrawLayer( bool query )
|
||||||
|
|
||||||
SetCurItem( NULL );
|
SetCurItem( NULL );
|
||||||
|
|
||||||
GERBER_FILE_IMAGE* gerber = g_GERBER_List.GetGbrImage( layer );
|
g_GERBER_List.DeleteImage( layer );
|
||||||
|
|
||||||
if( gerber ) // gerber == NULL should not occur
|
|
||||||
gerber->m_Drawings.DeleteAll();
|
|
||||||
|
|
||||||
g_GERBER_List.ClearImage( layer );
|
|
||||||
|
|
||||||
GetScreen()->SetModify();
|
|
||||||
m_canvas->Refresh();
|
|
||||||
m_LayersManager->UpdateLayerIcons();
|
m_LayersManager->UpdateLayerIcons();
|
||||||
syncLayerBox();
|
syncLayerBox();
|
||||||
|
m_canvas->Refresh();
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,8 +144,4 @@ void GERBVIEW_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
|
||||||
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
|
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
|
||||||
|
|
||||||
m_canvas->DrawCrossHair( DC );
|
m_canvas->DrawCrossHair( DC );
|
||||||
|
|
||||||
// Display the filename and the layer name (found in the gerber files, if any)
|
|
||||||
// relative to the active layer
|
|
||||||
UpdateTitleAndInfo();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,11 +247,11 @@ double GERBVIEW_FRAME::BestZoom()
|
||||||
bbox.SetSize( wxSize( Mils2iu( pagesize.x ), Mils2iu( pagesize.y ) ) );
|
bbox.SetSize( wxSize( Mils2iu( pagesize.x ), Mils2iu( pagesize.y ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute best zoom:
|
||||||
wxSize size = m_canvas->GetClientSize();
|
wxSize size = m_canvas->GetClientSize();
|
||||||
|
double x = (double) bbox.GetWidth() / (double) size.x;
|
||||||
double x = (double) bbox.GetWidth() * 1.1 / (double) size.x;
|
double y = (double) bbox.GetHeight() / (double) size.y;
|
||||||
double y = (double) bbox.GetHeight() * 1.1 / (double) size.y;
|
double best_zoom = std::max( x, y ) * 1.1;
|
||||||
double best_zoom = std::max( x, y );
|
|
||||||
|
|
||||||
SetScrollCenterPosition( bbox.Centre() );
|
SetScrollCenterPosition( bbox.Centre() );
|
||||||
|
|
||||||
|
@ -373,10 +373,10 @@ int GERBVIEW_FRAME::getNextAvailableLayer( int aLayer ) const
|
||||||
{
|
{
|
||||||
GERBER_FILE_IMAGE* gerber = g_GERBER_List.GetGbrImage( layer );
|
GERBER_FILE_IMAGE* gerber = g_GERBER_List.GetGbrImage( layer );
|
||||||
|
|
||||||
if( gerber == NULL || gerber->m_FileName.IsEmpty() )
|
if( gerber == NULL ) // this graphic layer is available: use it
|
||||||
return layer;
|
return layer;
|
||||||
|
|
||||||
++layer;
|
++layer; // try next graphic layer
|
||||||
|
|
||||||
if( layer >= GERBER_DRAWLAYERS_COUNT )
|
if( layer >= GERBER_DRAWLAYERS_COUNT )
|
||||||
layer = 0;
|
layer = 0;
|
||||||
|
|
|
@ -319,7 +319,7 @@ void GERBVIEW_FRAME::OnUpdateSelectDCode( wxUpdateUIEvent& aEvent )
|
||||||
|
|
||||||
void GERBVIEW_FRAME::OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent )
|
void GERBVIEW_FRAME::OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent )
|
||||||
{
|
{
|
||||||
if( m_SelLayerBox && (m_SelLayerBox->GetSelection() != getActiveLayer()) )
|
if( m_SelLayerBox->GetSelection() != getActiveLayer() )
|
||||||
{
|
{
|
||||||
m_SelLayerBox->SetSelection( getActiveLayer() );
|
m_SelLayerBox->SetSelection( getActiveLayer() );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue