Introduction of Graphics Abstraction Layer based rendering for pcbnew.
New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
This commit is contained in:
parent
ef2c94069f
commit
e262b32198
|
@ -56,6 +56,10 @@ option(KICAD_SCRIPTING_MODULES
|
|||
option(KICAD_SCRIPTING_WXPYTHON
|
||||
"set this option ON to build wxpython implementation for wx interface building in python and py.shell"
|
||||
)
|
||||
|
||||
option(KICAD_GAL
|
||||
"set this option ON to build KICAD using Graphics Abstraction Layer as a rendering backend"
|
||||
)
|
||||
|
||||
# when option KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES is enabled:
|
||||
# PYTHON_EXECUTABLE can be defined when invoking cmake
|
||||
|
@ -189,6 +193,10 @@ if(USE_WX_GRAPHICS_CONTEXT)
|
|||
add_definitions(-DUSE_WX_GRAPHICS_CONTEXT)
|
||||
endif()
|
||||
|
||||
if(KICAD_GAL)
|
||||
add_definitions(-DKICAD_GAL)
|
||||
endif()
|
||||
|
||||
# Allow user to override the default settings for adding images to menu items. By default
|
||||
# images in menu items are enabled on all platforms except OSX. This can be over ridden by
|
||||
# defining -DUSE_IMAGES_IN_MENUS=ON/OFF to force the preferred behavior.
|
||||
|
@ -257,6 +265,20 @@ add_definitions(-DWX_COMPATIBILITY)
|
|||
find_package(OpenGL QUIET)
|
||||
check_find_package_result(OPENGL_FOUND "OpenGL")
|
||||
|
||||
if(KICAD_GAL)
|
||||
#####################
|
||||
# Find GLEW library #
|
||||
#####################
|
||||
find_package(GLEW)
|
||||
check_find_package_result(GLEW_FOUND "GLEW")
|
||||
|
||||
######################
|
||||
# Find Cairo library #
|
||||
######################
|
||||
find_package(Cairo 1.8.1 QUIET)
|
||||
check_find_package_result(CAIRO_FOUND "Cairo")
|
||||
endif(KICAD_GAL)
|
||||
|
||||
######################
|
||||
# Find Boost library #
|
||||
######################
|
||||
|
|
|
@ -4,12 +4,29 @@ include_directories(
|
|||
./dialogs
|
||||
./dialog_about
|
||||
${Boost_INCLUDE_DIR}
|
||||
${CAIRO_INCLUDE_DIR}
|
||||
../3d-viewer
|
||||
../pcbnew
|
||||
../polygon
|
||||
${INC_AFTER}
|
||||
)
|
||||
|
||||
if(KICAD_GAL)
|
||||
set(GAL_SRCS
|
||||
drawpanel_gal.cpp
|
||||
painter.cpp
|
||||
gal/graphics_abstraction_layer.cpp
|
||||
gal/stroke_font.cpp
|
||||
gal/color4d.cpp
|
||||
gal/opengl/opengl_gal.cpp
|
||||
gal/opengl/shader.cpp
|
||||
gal/cairo/cairo_gal.cpp
|
||||
view/wx_view_controls.cpp
|
||||
)
|
||||
|
||||
add_library(gal STATIC ${GAL_SRCS})
|
||||
endif(KICAD_GAL)
|
||||
|
||||
set(COMMON_ABOUT_DLG_SRCS
|
||||
dialog_about/AboutDialog_main.cpp
|
||||
dialog_about/dialog_about.cpp
|
||||
|
@ -82,6 +99,14 @@ set(COMMON_SRCS
|
|||
zoom.cpp
|
||||
)
|
||||
|
||||
if(KICAD_GAL)
|
||||
set(COMMON_SRCS
|
||||
${COMMON_SRCS}
|
||||
view/view.cpp
|
||||
view/view_item.cpp
|
||||
)
|
||||
endif(KICAD_GAL)
|
||||
|
||||
add_library(common STATIC ${COMMON_SRCS})
|
||||
|
||||
set(PCB_COMMON_SRCS
|
||||
|
@ -131,6 +156,12 @@ set(PCB_COMMON_SRCS
|
|||
fp_lib_table.cpp
|
||||
)
|
||||
|
||||
if(KICAD_GAL)
|
||||
set(PCB_COMMON_SRCS
|
||||
${PCB_COMMON_SRCS}
|
||||
../pcbnew/pcb_painter.cpp
|
||||
)
|
||||
endif(KICAD_GAL)
|
||||
|
||||
# add -DPCBNEW to compilation of these PCBNEW sources
|
||||
set_source_files_properties( ${PCB_COMMON_SRCS} PROPERTIES
|
||||
|
|
|
@ -222,6 +222,22 @@ EDA_ITEM& EDA_ITEM::operator=( const EDA_ITEM& aItem )
|
|||
}
|
||||
|
||||
|
||||
const BOX2I EDA_ITEM::ViewBBox() const
|
||||
{
|
||||
// Basic fallback
|
||||
return BOX2I( VECTOR2I( GetBoundingBox().GetOrigin() ),
|
||||
VECTOR2I( GetBoundingBox().GetSize() ) );
|
||||
}
|
||||
|
||||
|
||||
void EDA_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
{
|
||||
// Basic fallback
|
||||
aCount = 1;
|
||||
aLayers[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
// A function that should have been in wxWidgets
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <macros.h>
|
||||
#include <id.h>
|
||||
#include <class_drawpanel.h>
|
||||
#include <class_drawpanel_gal.h>
|
||||
#include <class_base_screen.h>
|
||||
#include <msgpanel.h>
|
||||
#include <wxstruct.h>
|
||||
|
@ -66,6 +67,7 @@ BEGIN_EVENT_TABLE( EDA_DRAW_FRAME, EDA_BASE_FRAME )
|
|||
EVT_MENU_OPEN( EDA_DRAW_FRAME::OnMenuOpen )
|
||||
EVT_ACTIVATE( EDA_DRAW_FRAME::OnActivate )
|
||||
EVT_MENU_RANGE( ID_ZOOM_IN, ID_ZOOM_REDRAW, EDA_DRAW_FRAME::OnZoom )
|
||||
EVT_MENU( ID_SWITCH_CANVAS, EDA_DRAW_FRAME::OnZoom )
|
||||
EVT_MENU_RANGE( ID_OFFCENTER_ZOOM_IN, ID_OFFCENTER_ZOOM_OUT, EDA_DRAW_FRAME::OnZoom )
|
||||
EVT_MENU_RANGE( ID_POPUP_ZOOM_START_RANGE, ID_POPUP_ZOOM_END_RANGE,
|
||||
EDA_DRAW_FRAME::OnZoom )
|
||||
|
@ -100,6 +102,8 @@ EDA_DRAW_FRAME::EDA_DRAW_FRAME( wxWindow* aParent,
|
|||
m_HotkeysZoomAndGridList = NULL;
|
||||
|
||||
m_canvas = NULL;
|
||||
m_galCanvas = NULL;
|
||||
m_galCanvasActive = false;
|
||||
m_messagePanel = NULL;
|
||||
m_currentScreen = NULL;
|
||||
m_toolId = ID_NO_TOOL_SELECTED;
|
||||
|
@ -937,3 +941,27 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU )
|
|||
screen->m_ScrollbarPos.x,
|
||||
screen->m_ScrollbarPos.y, noRefresh );
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable )
|
||||
{
|
||||
if( !( aEnable ^ m_galCanvasActive ) )
|
||||
return;
|
||||
|
||||
if( aEnable )
|
||||
{
|
||||
m_canvas->Hide();
|
||||
m_galCanvas->Show();
|
||||
m_galCanvas->Raise();
|
||||
m_galCanvas->Refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_galCanvas->Hide();
|
||||
m_canvas->Show();
|
||||
m_canvas->Raise();
|
||||
m_canvas->Refresh();
|
||||
}
|
||||
|
||||
m_galCanvasActive = aEnable;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <macros.h>
|
||||
#include <id.h>
|
||||
#include <class_drawpanel.h>
|
||||
#include <class_drawpanel_gal.h>
|
||||
#include <class_base_screen.h>
|
||||
#include <wxstruct.h>
|
||||
|
||||
|
@ -74,6 +75,9 @@ BEGIN_EVENT_TABLE( EDA_DRAW_PANEL, wxScrolledWindow )
|
|||
EVT_ERASE_BACKGROUND( EDA_DRAW_PANEL::OnEraseBackground )
|
||||
EVT_SCROLLWIN( EDA_DRAW_PANEL::OnScroll )
|
||||
EVT_ACTIVATE( EDA_DRAW_PANEL::OnActivate )
|
||||
#ifdef KICAD_GAL
|
||||
EVT_SIZE( EDA_DRAW_PANEL::OnSize )
|
||||
#endif
|
||||
EVT_MENU_RANGE( ID_PAN_UP, ID_PAN_RIGHT, EDA_DRAW_PANEL::OnPan )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
@ -1377,6 +1381,18 @@ void EDA_DRAW_PANEL::OnPan( wxCommandEvent& event )
|
|||
}
|
||||
|
||||
|
||||
#ifdef KICAD_GAL
|
||||
void EDA_DRAW_PANEL::OnSize( wxSizeEvent& SizeEv )
|
||||
{
|
||||
if( GetParent()->GetGalCanvas() != NULL )
|
||||
{
|
||||
GetParent()->GetGalCanvas()->SetPosition( GetPosition() );
|
||||
GetParent()->GetGalCanvas()->SetSize( GetSize() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void EDA_DRAW_PANEL::EndMouseCapture( int id, int cursor, const wxString& title,
|
||||
bool aCallEndFunc )
|
||||
{
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/frame.h>
|
||||
#include <wx/window.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/filefn.h>
|
||||
|
||||
#include <class_drawpanel_gal.h>
|
||||
#include <view/view.h>
|
||||
#include <view/wx_view_controls.h>
|
||||
#include <pcb_painter.h>
|
||||
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
#include <gal/opengl/opengl_gal.h>
|
||||
#include <gal/cairo/cairo_gal.h>
|
||||
|
||||
#define METRIC_UNIT_LENGTH (1e9)
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::onPaint( wxEvent& event )
|
||||
{
|
||||
m_gal->BeginDrawing();
|
||||
m_gal->SetBackgroundColor( KiGfx::COLOR4D( 0, 0, 0, 1.0 ) );
|
||||
m_gal->ClearScreen();
|
||||
m_gal->SetGridOrigin( VECTOR2D( 0, 0 ) );
|
||||
m_gal->SetGridOriginMarkerSize( 15 );
|
||||
m_gal->SetGridSize( VECTOR2D( METRIC_UNIT_LENGTH / 10000.0, METRIC_UNIT_LENGTH / 10000.0 ) );
|
||||
m_gal->SetGridDrawThreshold( 10 );
|
||||
m_gal->SetLayerDepth( 0 );
|
||||
|
||||
m_gal->DrawGrid();
|
||||
m_view->Redraw();
|
||||
|
||||
m_gal->EndDrawing();
|
||||
m_gal->Flush();
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::onSize( wxSizeEvent& aEvent )
|
||||
{
|
||||
m_gal->ResizeScreen( aEvent.GetSize().x, aEvent.GetSize().y );
|
||||
}
|
||||
|
||||
|
||||
EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId,
|
||||
const wxPoint& aPosition, const wxSize& aSize,
|
||||
GalType aGalType ) :
|
||||
wxWindow( aParentWindow, aWindowId, aPosition, aSize ),
|
||||
m_screenSize( aSize.x, aSize.y ), m_parentFrame( aParentWindow )
|
||||
{
|
||||
m_gal = NULL;
|
||||
m_view = NULL;
|
||||
|
||||
m_galShaderPath = std::string( ::wxGetCwd().mb_str() ) + "/../../gal/opengl/shader/";
|
||||
|
||||
SwitchBackend( aGalType, false );
|
||||
SetBackgroundStyle( wxBG_STYLE_CUSTOM );
|
||||
|
||||
// Initial display settings
|
||||
m_gal->SetLookAtPoint( VECTOR2D( 0, 0 ) );
|
||||
m_gal->SetZoomFactor( 1.0 );
|
||||
m_gal->ComputeWorldScreenMatrix();
|
||||
|
||||
m_view = new KiGfx::VIEW( true );
|
||||
m_view->SetGAL( m_gal );
|
||||
|
||||
// View uses layers to display EDA_ITEMs (item may be displayed on several layers, for example
|
||||
// pad may be shown on pad, pad hole nad solder paste layers). There are usual copper layers
|
||||
// (eg. F.Cu, B.Cu, internal and so on) and layers for displaying objects such as texts,
|
||||
// silkscreen, pads, vias, etc.
|
||||
for( int i = 0; i < TOTAL_LAYER_COUNT; i++ )
|
||||
{
|
||||
m_view->AddLayer( i );
|
||||
}
|
||||
|
||||
m_viewControls = new KiGfx::WX_VIEW_CONTROLS( m_view, this );
|
||||
|
||||
m_painter = new KiGfx::PCB_PAINTER( m_gal );
|
||||
m_view->SetPainter( m_painter );
|
||||
|
||||
// FIXME Cairo needs this to be uncommented to remove blinking on refreshing
|
||||
// Connect( wxEVT_PAINT, wxEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), NULL, this );
|
||||
Connect(KiGfx::EVT_GAL_REDRAW, wxEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), NULL, this );
|
||||
Connect(wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this );
|
||||
}
|
||||
|
||||
|
||||
EDA_DRAW_PANEL_GAL::~EDA_DRAW_PANEL_GAL()
|
||||
{
|
||||
if( m_painter )
|
||||
delete m_painter;
|
||||
|
||||
if( m_viewControls )
|
||||
delete m_viewControls;
|
||||
|
||||
if( m_view )
|
||||
delete m_view;
|
||||
|
||||
if( m_gal )
|
||||
delete m_gal;
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType, bool aUseShaders )
|
||||
{
|
||||
if( m_gal )
|
||||
delete m_gal;
|
||||
|
||||
switch( aGalType )
|
||||
{
|
||||
case GAL_TYPE_OPENGL:
|
||||
m_gal = new KiGfx::OPENGL_GAL( this, this, this, aUseShaders );
|
||||
static_cast<KiGfx::OPENGL_GAL*> (m_gal)->SetShaderPath( m_galShaderPath );
|
||||
break;
|
||||
|
||||
case GAL_TYPE_CAIRO:
|
||||
m_gal = new KiGfx::CAIRO_GAL( this, this, this );
|
||||
break;
|
||||
}
|
||||
|
||||
m_gal->SetWorldUnitLength( 1.0 / METRIC_UNIT_LENGTH * 2.54 ); // 1 inch in nanometers
|
||||
m_gal->SetScreenDPI( 106 ); // Display resolution setting
|
||||
m_gal->ComputeWorldScreenMatrix();
|
||||
|
||||
if( m_view )
|
||||
m_view->SetGAL( m_gal );
|
||||
}
|
|
@ -0,0 +1,968 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* CAIRO_GAL - Graphics Abstraction Layer for Cairo
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <wx/dcbuffer.h>
|
||||
#include <wx/rawbmp.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
#include <gal/cairo/cairo_gal.h>
|
||||
|
||||
using namespace KiGfx;
|
||||
|
||||
CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
|
||||
wxEvtHandler* aPaintListener, const wxString& aName ) :
|
||||
wxWindow( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND, aName )
|
||||
{
|
||||
// Default values
|
||||
fillColor = COLOR4D( 0, 0, 0, 1 );
|
||||
strokeColor = COLOR4D( 1, 1, 1, 1 );
|
||||
screenSize = VECTOR2D( 20, 20 ); // window will be soon resized
|
||||
|
||||
parentWindow = aParent;
|
||||
mouseListener = aMouseListener;
|
||||
paintListener = aPaintListener;
|
||||
|
||||
isGrouping = false;
|
||||
zoomFactor = 1.0;
|
||||
|
||||
SetSize( aParent->GetSize() );
|
||||
|
||||
// Connecting the event handlers
|
||||
// Mouse events are skipped to the parent
|
||||
this->Connect( wxEVT_SIZE, wxSizeEventHandler( CAIRO_GAL::onSize ) );
|
||||
this->Connect( wxEVT_PAINT, wxPaintEventHandler( CAIRO_GAL::onPaint ) );
|
||||
this->Connect( wxEVT_ERASE_BACKGROUND, wxEraseEventHandler( CAIRO_GAL::onEraseBackground ) );
|
||||
aParent->Connect( wxEVT_ERASE_BACKGROUND,
|
||||
wxEraseEventHandler( CAIRO_GAL::onEraseBackground ) );
|
||||
aParent->GetParent()->Connect( wxEVT_ERASE_BACKGROUND,
|
||||
wxEraseEventHandler( CAIRO_GAL::onEraseBackground ) );
|
||||
|
||||
SetBackgroundStyle( wxBG_STYLE_CUSTOM );
|
||||
aParent->SetBackgroundStyle( wxBG_STYLE_CUSTOM );
|
||||
aParent->GetParent()->SetBackgroundStyle( wxBG_STYLE_CUSTOM );
|
||||
|
||||
this->Connect( wxEVT_MOTION, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||
this->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||
this->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||
this->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||
this->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||
this->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||
|
||||
// Initialize line attributes map
|
||||
lineCapMap[LINE_CAP_BUTT] = CAIRO_LINE_CAP_BUTT;
|
||||
lineCapMap[LINE_CAP_ROUND] = CAIRO_LINE_CAP_ROUND;
|
||||
lineCapMap[LINE_CAP_SQUARED] = CAIRO_LINE_CAP_SQUARE;
|
||||
|
||||
lineJoinMap[LINE_JOIN_BEVEL] = CAIRO_LINE_JOIN_BEVEL;
|
||||
lineJoinMap[LINE_JOIN_ROUND] = CAIRO_LINE_JOIN_ROUND;
|
||||
lineJoinMap[LINE_JOIN_MITER] = CAIRO_LINE_JOIN_MITER;
|
||||
|
||||
isDeleteSavedPixels = false;
|
||||
|
||||
isGrouping = false;
|
||||
|
||||
// Initialize the cursor shape
|
||||
SetCursorColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
|
||||
initCursor( 21 );
|
||||
|
||||
screenSizeY = screenSize.y;
|
||||
|
||||
// Allocate memory
|
||||
allocateBitmaps();
|
||||
|
||||
// Set grid defaults
|
||||
SetGridColor( COLOR4D( 0.5, 0.5, 0.5, 0.3 ) );
|
||||
SetCoarseGrid( 10 );
|
||||
SetGridLineWidth( 0.5 );
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
CAIRO_GAL::~CAIRO_GAL()
|
||||
{
|
||||
// TODO Deleting of list contents like groups and paths
|
||||
delete[] bitmapBuffer;
|
||||
delete[] bitmapBufferBackup;
|
||||
delete wxBitmap_;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::onPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
PostPaint();
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::onEraseBackground( wxEraseEvent& aEvent )
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::ResizeScreen( int aWidth, int aHeight )
|
||||
{
|
||||
deleteBitmaps();
|
||||
|
||||
screenSizeY = aHeight;
|
||||
screenSize = VECTOR2D( aWidth, aHeight );
|
||||
|
||||
// Recreate the bitmaps
|
||||
allocateBitmaps();
|
||||
|
||||
SetSize( wxSize( aWidth, aHeight ) );
|
||||
|
||||
PostPaint();
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::onSize( wxSizeEvent& aEvent )
|
||||
{
|
||||
wxSize newSize = aEvent.GetSize();
|
||||
|
||||
ResizeScreen( newSize.x, newSize.y );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::skipMouseEvent( wxMouseEvent& aEvent )
|
||||
{
|
||||
// Post the mouse event to the event listener registered in constructor, if any
|
||||
if( mouseListener )
|
||||
wxPostEvent( mouseListener, aEvent );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::BeginDrawing() throw( int )
|
||||
{
|
||||
// The size of the client area needs to be greater than zero
|
||||
clientRectangle = parentWindow->GetClientRect();
|
||||
|
||||
if( clientRectangle.width == 0 || clientRectangle.height == 0 )
|
||||
throw EXCEPTION_ZERO_CLIENT_RECTANGLE;
|
||||
|
||||
// clientDC = new wxClientDC( this );
|
||||
|
||||
// Create the CAIRO surface
|
||||
cairoSurface = cairo_image_surface_create_for_data( (unsigned char*) bitmapBuffer,
|
||||
CAIRO_FORMAT_RGB24, clientRectangle.width,
|
||||
clientRectangle.height, stride );
|
||||
cairoImage = cairo_create( cairoSurface );
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
cairo_set_antialias( cairoImage, CAIRO_ANTIALIAS_SUBPIXEL );
|
||||
|
||||
// Clear the screen
|
||||
ClearScreen();
|
||||
|
||||
// Compute the world <-> screen transformations
|
||||
ComputeWorldScreenMatrix();
|
||||
|
||||
cairo_matrix_init( &cairoWorldScreenMatrix, worldScreenMatrix.m_data[0][0],
|
||||
worldScreenMatrix.m_data[1][0], worldScreenMatrix.m_data[0][1],
|
||||
worldScreenMatrix.m_data[1][1], worldScreenMatrix.m_data[0][2],
|
||||
worldScreenMatrix.m_data[1][2] );
|
||||
|
||||
cairo_set_matrix( cairoImage, &cairoWorldScreenMatrix );
|
||||
|
||||
isSetAttributes = false;
|
||||
|
||||
// Start drawing with a new path
|
||||
cairo_new_path( cairoImage );
|
||||
isElementAdded = true;
|
||||
|
||||
cairo_set_line_join( cairoImage, lineJoinMap[lineJoin] );
|
||||
cairo_set_line_cap( cairoImage, lineCapMap[lineCap] );
|
||||
|
||||
lineWidth = 0;
|
||||
|
||||
isDeleteSavedPixels = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::EndDrawing()
|
||||
{
|
||||
// Force remaining objects to be drawn
|
||||
Flush();
|
||||
|
||||
// FIXME Accelerate support for wxWidgets 2.8.10
|
||||
|
||||
#if wxCHECK_VERSION( 2, 9, 0 )
|
||||
// Copy the cairo image contents to the wxBitmap
|
||||
wxNativePixelData pixelData( *wxBitmap_ );
|
||||
|
||||
if( !pixelData )
|
||||
{
|
||||
wxLogError( wxString::FromUTF8( "Can't access pixel data!" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
wxNativePixelData::Iterator pixelIterator( pixelData );
|
||||
|
||||
int offset = 0;
|
||||
|
||||
// Copy the cairo image to the wxDC bitmap
|
||||
for( int j = 0; j < screenSizeY; j++ )
|
||||
{
|
||||
offset = j * (int) screenSize.x;
|
||||
|
||||
for( int column = 0; column < clientRectangle.width; column++ )
|
||||
{
|
||||
unsigned int value = bitmapBuffer[offset + column];
|
||||
pixelIterator.Red() = value >> 16;
|
||||
pixelIterator.Green() = value >> 8;
|
||||
pixelIterator.Blue() = value >> 0;
|
||||
pixelIterator++;
|
||||
}
|
||||
|
||||
pixelIterator.MoveTo( pixelData, 0, j );
|
||||
}
|
||||
|
||||
// Blit the contents to the screen
|
||||
wxClientDC client_dc( this );
|
||||
wxBufferedDC dc( &client_dc );
|
||||
dc.DrawBitmap( *wxBitmap_, 0, 0 );
|
||||
|
||||
#elif wxCHECK_VERSION( 2, 8, 0 )
|
||||
|
||||
// This code was taken from the wxCairo example - it's not the most efficient one
|
||||
// Here is a good place for optimizations
|
||||
|
||||
// Now translate the raw image data from the format stored
|
||||
// by cairo into a format understood by wxImage.
|
||||
unsigned char* wxOutputPtr = wxOutput;
|
||||
for( size_t count = 0; count < bufferSize; count++ )
|
||||
{
|
||||
unsigned int value = bitmapBuffer[count];
|
||||
// Red pixel
|
||||
*wxOutputPtr++ = (value >> 16) & 0xff;
|
||||
// Green pixel
|
||||
*wxOutputPtr++ = (value >> 8) & 0xff;
|
||||
// Blue pixel
|
||||
*wxOutputPtr++ = (value >> 0) & 0xff;
|
||||
}
|
||||
|
||||
wxImage img( (int) screenSize.x, (int) screenSize.y, (unsigned char*) wxOutput, true);
|
||||
wxBitmap bmp( img );
|
||||
wxClientDC client_dc( this );
|
||||
wxBufferedDC dc;
|
||||
// client_dc.DrawBitmap(bmp, 0, 0, false);
|
||||
dc.Init( &client_dc, bmp );
|
||||
|
||||
#else
|
||||
#error "need wxWidgets-2.8 as a minimum"
|
||||
#endif
|
||||
|
||||
// Destroy Cairo objects
|
||||
cairo_destroy( cairoImage );
|
||||
cairo_surface_destroy( cairoSurface );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SaveScreen()
|
||||
{
|
||||
// Copy the current bitmap to the backup buffer
|
||||
int offset = 0;
|
||||
|
||||
for( int j = 0; j < screenSizeY; j++ )
|
||||
{
|
||||
for( int i = 0; i < stride; i++ )
|
||||
{
|
||||
bitmapBufferBackup[offset + i] = bitmapBuffer[offset + i];
|
||||
offset += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::RestoreScreen()
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
for( int j = 0; j < screenSizeY; j++ )
|
||||
{
|
||||
for( int i = 0; i < stride; i++ )
|
||||
{
|
||||
bitmapBuffer[offset + i] = bitmapBufferBackup[offset + i];
|
||||
offset += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawLine( VECTOR2D aStartPoint, VECTOR2D aEndPoint )
|
||||
{
|
||||
cairo_move_to( cairoImage, aStartPoint.x, aStartPoint.y );
|
||||
cairo_line_to( cairoImage, aEndPoint.x, aEndPoint.y );
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawCircle( VECTOR2D aCenterPoint, double aRadius )
|
||||
{
|
||||
// A circle is drawn using an arc
|
||||
cairo_new_sub_path( cairoImage );
|
||||
cairo_arc( cairoImage, aCenterPoint.x, aCenterPoint.y, aRadius, 0.0, 2 * M_PI );
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawArc( VECTOR2D aCenterPoint, double aRadius, double aStartAngle,
|
||||
double aEndAngle )
|
||||
{
|
||||
cairo_new_sub_path( cairoImage );
|
||||
cairo_arc( cairoImage, aCenterPoint.x, aCenterPoint.y, aRadius, aStartAngle, aEndAngle );
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
|
||||
{
|
||||
bool isFirstPoint = true;
|
||||
|
||||
// Iterate over the point list and draw the segments
|
||||
for( std::deque<VECTOR2D>::iterator it = aPointList.begin(); it != aPointList.end(); ++it )
|
||||
{
|
||||
if( isFirstPoint )
|
||||
{
|
||||
cairo_move_to( cairoImage, it->x, it->y );
|
||||
isFirstPoint = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_line_to( cairoImage, it->x, it->y );
|
||||
}
|
||||
}
|
||||
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
|
||||
{
|
||||
bool isFirstPoint = true;
|
||||
|
||||
// Iterate over the point list and draw the polygon
|
||||
for( std::deque<VECTOR2D>::const_iterator it = aPointList.begin(); it != aPointList.end(); ++it )
|
||||
{
|
||||
if( isFirstPoint )
|
||||
{
|
||||
cairo_move_to( cairoImage, it->x, it->y );
|
||||
isFirstPoint = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_line_to( cairoImage, it->x, it->y );
|
||||
}
|
||||
}
|
||||
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawRectangle( VECTOR2D aStartPoint, VECTOR2D aEndPoint )
|
||||
{
|
||||
// Calculate the diagonal points
|
||||
VECTOR2D diagonalPointA( aEndPoint.x, aStartPoint.y );
|
||||
VECTOR2D diagonalPointB( aStartPoint.x, aEndPoint.y );
|
||||
|
||||
// The path is composed from 4 segments
|
||||
cairo_move_to( cairoImage, aStartPoint.x, aStartPoint.y );
|
||||
cairo_line_to( cairoImage, diagonalPointA.x, diagonalPointA.y );
|
||||
cairo_line_to( cairoImage, aEndPoint.x, aEndPoint.y );
|
||||
cairo_line_to( cairoImage, diagonalPointB.x, diagonalPointB.y );
|
||||
cairo_close_path( cairoImage );
|
||||
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawCurve( VECTOR2D aStartPoint, VECTOR2D aControlPointA,
|
||||
VECTOR2D aControlPointB, VECTOR2D aEndPoint )
|
||||
{
|
||||
cairo_move_to( cairoImage, aStartPoint.x, aStartPoint.y );
|
||||
cairo_curve_to( cairoImage, aControlPointA.x, aControlPointA.y, aControlPointB.x,
|
||||
aControlPointB.y, aEndPoint.x, aEndPoint.y );
|
||||
cairo_line_to( cairoImage, aEndPoint.x, aEndPoint.y );
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SetBackgroundColor( COLOR4D aColor )
|
||||
{
|
||||
backgroundColor = aColor;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SetIsFill( bool aIsFillEnabled )
|
||||
{
|
||||
storePath();
|
||||
isFillEnabled = aIsFillEnabled;
|
||||
|
||||
if( isGrouping )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.command = CMD_SET_FILL;
|
||||
groupElement.boolArgument = aIsFillEnabled;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SetIsStroke( bool aIsStrokeEnabled )
|
||||
{
|
||||
storePath();
|
||||
isStrokeEnabled = aIsStrokeEnabled;
|
||||
|
||||
if( isGrouping )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.command = CMD_SET_STROKE;
|
||||
groupElement.boolArgument = aIsStrokeEnabled;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SetStrokeColor( COLOR4D aColor )
|
||||
{
|
||||
storePath();
|
||||
|
||||
strokeColor = aColor;
|
||||
|
||||
if( isGrouping )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.command = CMD_SET_STROKECOLOR;
|
||||
groupElement.arguments[0] = strokeColor.r;
|
||||
groupElement.arguments[1] = strokeColor.g;
|
||||
groupElement.arguments[2] = strokeColor.b;
|
||||
groupElement.arguments[3] = strokeColor.a;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SetFillColor( COLOR4D aColor )
|
||||
{
|
||||
storePath();
|
||||
fillColor = aColor;
|
||||
|
||||
if( isGrouping )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.command = CMD_SET_FILLCOLOR;
|
||||
groupElement.arguments[0] = fillColor.r;
|
||||
groupElement.arguments[1] = fillColor.g;
|
||||
groupElement.arguments[2] = fillColor.b;
|
||||
groupElement.arguments[3] = fillColor.a;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SetLineWidth( double aLineWidth )
|
||||
{
|
||||
storePath();
|
||||
|
||||
lineWidth = aLineWidth;
|
||||
cairo_set_line_width( cairoImage, aLineWidth );
|
||||
|
||||
if( isGrouping )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.command = CMD_SET_LINE_WIDTH;
|
||||
groupElement.arguments[0] = aLineWidth;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SetLineCap( LineCap aLineCap )
|
||||
{
|
||||
storePath();
|
||||
|
||||
lineCap = aLineCap;
|
||||
|
||||
cairo_set_line_cap( cairoImage, lineCapMap[aLineCap] );
|
||||
|
||||
if( isGrouping )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.command = CMD_SET_LINE_CAP;
|
||||
groupElement.intArgument = (int) aLineCap;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::SetLineJoin( LineJoin aLineJoin )
|
||||
{
|
||||
storePath();
|
||||
|
||||
lineJoin = aLineJoin;
|
||||
|
||||
cairo_set_line_join( cairoImage, lineJoinMap[aLineJoin] );
|
||||
|
||||
if( isGrouping )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.command = CMD_SET_LINE_JOIN;
|
||||
groupElement.intArgument = (int) aLineJoin;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::ClearScreen()
|
||||
{
|
||||
// Clear screen
|
||||
cairo_set_source_rgba( cairoImage,
|
||||
backgroundColor.r, backgroundColor.g, backgroundColor.b, 1.0 );
|
||||
cairo_rectangle( cairoImage, 0.0, 0.0, screenSize.x, screenSize.y );
|
||||
cairo_fill( cairoImage );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::Transform( MATRIX3x3D aTransformation )
|
||||
{
|
||||
cairo_matrix_t cairoTransformation;
|
||||
|
||||
cairo_matrix_init( &cairoTransformation,
|
||||
aTransformation.m_data[0][0],
|
||||
aTransformation.m_data[1][0],
|
||||
aTransformation.m_data[0][1],
|
||||
aTransformation.m_data[1][1],
|
||||
aTransformation.m_data[0][2],
|
||||
aTransformation.m_data[1][2] );
|
||||
|
||||
cairo_transform( cairoImage, &cairoTransformation );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::Rotate( double aAngle )
|
||||
{
|
||||
storePath();
|
||||
|
||||
cairo_rotate( cairoImage, aAngle );
|
||||
|
||||
if( isGrouping )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.command = CMD_ROTATE;
|
||||
groupElement.arguments[0] = aAngle;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::Translate( VECTOR2D aTranslation )
|
||||
{
|
||||
storePath();
|
||||
|
||||
cairo_translate( cairoImage, aTranslation.x, aTranslation.y );
|
||||
|
||||
if( isGrouping )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.command = CMD_TRANSLATE;
|
||||
groupElement.arguments[0] = aTranslation.x;
|
||||
groupElement.arguments[1] = aTranslation.y;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::Scale( VECTOR2D aScale )
|
||||
{
|
||||
storePath();
|
||||
|
||||
cairo_scale( cairoImage, aScale.x, aScale.y );
|
||||
|
||||
if( isGrouping )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.command = CMD_SCALE;
|
||||
groupElement.arguments[0] = aScale.x;
|
||||
groupElement.arguments[1] = aScale.y;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::Save()
|
||||
{
|
||||
storePath();
|
||||
|
||||
cairo_save( cairoImage );
|
||||
|
||||
if( isGrouping )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.command = CMD_SAVE;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::Restore()
|
||||
{
|
||||
storePath();
|
||||
|
||||
cairo_restore( cairoImage );
|
||||
|
||||
if( isGrouping )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.command = CMD_RESTORE;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CAIRO_GAL::BeginGroup()
|
||||
{
|
||||
// If the grouping is started: the actual path is stored in the group, when
|
||||
// a attribute was changed or when grouping stops with the end group method.
|
||||
storePath();
|
||||
Group group;
|
||||
groups.push_back( group );
|
||||
isGrouping = true;
|
||||
return groups.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::EndGroup()
|
||||
{
|
||||
storePath();
|
||||
isGrouping = false;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DeleteGroup( int aGroupNumber )
|
||||
{
|
||||
storePath();
|
||||
|
||||
// Delete the Cairo paths
|
||||
for( std::deque<GroupElement>::iterator it = groups[aGroupNumber].begin();
|
||||
it != groups[aGroupNumber].end(); ++it )
|
||||
{
|
||||
if( it->command == CMD_FILL_PATH || it->command == CMD_STROKE_PATH )
|
||||
{
|
||||
cairo_path_destroy( it->cairoPath );
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the group
|
||||
groups.erase( groups.begin() + aGroupNumber );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawGroup( int aGroupNumber )
|
||||
{
|
||||
// This method implements a small Virtual Machine - all stored commands
|
||||
// are executed; nested calling is also possible
|
||||
|
||||
storePath();
|
||||
|
||||
for( Group::iterator it = groups[aGroupNumber].begin();
|
||||
it != groups[aGroupNumber].end(); ++it )
|
||||
{
|
||||
switch( it->command )
|
||||
{
|
||||
case CMD_SET_FILL:
|
||||
isFillEnabled = it->boolArgument;
|
||||
break;
|
||||
|
||||
case CMD_SET_STROKE:
|
||||
isStrokeEnabled = it->boolArgument;
|
||||
break;
|
||||
|
||||
case CMD_SET_FILLCOLOR:
|
||||
fillColor = COLOR4D( it->arguments[0], it->arguments[1], it->arguments[2],
|
||||
it->arguments[3] );
|
||||
break;
|
||||
|
||||
case CMD_SET_STROKECOLOR:
|
||||
strokeColor = COLOR4D( it->arguments[0], it->arguments[1], it->arguments[2],
|
||||
it->arguments[3] );
|
||||
break;
|
||||
|
||||
case CMD_SET_LINE_WIDTH:
|
||||
cairo_set_line_width( cairoImage, it->arguments[0] );
|
||||
break;
|
||||
|
||||
case CMD_SET_LINE_JOIN:
|
||||
cairo_set_line_join( cairoImage, lineJoinMap[(LineJoin) ( it->intArgument )] );
|
||||
break;
|
||||
|
||||
case CMD_SET_LINE_CAP:
|
||||
cairo_set_line_cap( cairoImage, lineCapMap[(LineCap) ( it->intArgument )] );
|
||||
break;
|
||||
|
||||
case CMD_STROKE_PATH:
|
||||
cairo_set_source_rgba( cairoImage, strokeColor.r, strokeColor.g, strokeColor.b,
|
||||
strokeColor.a );
|
||||
cairo_append_path( cairoImage, it->cairoPath );
|
||||
cairo_stroke( cairoImage );
|
||||
break;
|
||||
|
||||
case CMD_FILL_PATH:
|
||||
cairo_set_source_rgba( cairoImage, fillColor.r, fillColor.g, fillColor.b,
|
||||
fillColor.a );
|
||||
cairo_append_path( cairoImage, it->cairoPath );
|
||||
cairo_fill( cairoImage );
|
||||
break;
|
||||
|
||||
case CMD_TRANSFORM:
|
||||
cairo_matrix_t matrix;
|
||||
cairo_matrix_init( &matrix, it->arguments[0], it->arguments[1], it->arguments[2],
|
||||
it->arguments[3], it->arguments[4], it->arguments[5] );
|
||||
cairo_transform( cairoImage, &matrix );
|
||||
break;
|
||||
|
||||
case CMD_ROTATE:
|
||||
cairo_rotate( cairoImage, it->arguments[0] );
|
||||
break;
|
||||
|
||||
case CMD_TRANSLATE:
|
||||
cairo_translate( cairoImage, it->arguments[0], it->arguments[1] );
|
||||
break;
|
||||
|
||||
case CMD_SCALE:
|
||||
cairo_scale( cairoImage, it->arguments[0], it->arguments[1] );
|
||||
break;
|
||||
|
||||
case CMD_SAVE:
|
||||
cairo_save( cairoImage );
|
||||
break;
|
||||
|
||||
case CMD_RESTORE:
|
||||
cairo_restore( cairoImage );
|
||||
break;
|
||||
|
||||
case CMD_CALL_GROUP:
|
||||
DrawGroup( it->intArgument );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::Flush()
|
||||
{
|
||||
storePath();
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::ComputeWorldScreenMatrix()
|
||||
{
|
||||
ComputeWorldScale();
|
||||
|
||||
worldScreenMatrix.SetIdentity();
|
||||
|
||||
MATRIX3x3D translation;
|
||||
translation.SetIdentity();
|
||||
translation.SetTranslation( 0.5 * VECTOR2D( screenSize.x, screenSize.y ) );
|
||||
|
||||
MATRIX3x3D scale;
|
||||
scale.SetIdentity();
|
||||
scale.SetScale( VECTOR2D( worldScale, -worldScale ) );
|
||||
|
||||
MATRIX3x3D lookat;
|
||||
lookat.SetIdentity();
|
||||
lookat.SetTranslation( -lookAtPoint );
|
||||
|
||||
worldScreenMatrix = translation * scale * lookat * worldScreenMatrix;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::storePath()
|
||||
{
|
||||
if( isElementAdded )
|
||||
{
|
||||
isElementAdded = false;
|
||||
|
||||
if( !isGrouping )
|
||||
{
|
||||
if( isFillEnabled )
|
||||
{
|
||||
cairo_set_source_rgba( cairoImage, fillColor.r, fillColor.g, fillColor.b,
|
||||
fillColor.a );
|
||||
cairo_fill_preserve( cairoImage );
|
||||
}
|
||||
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
cairo_set_source_rgba( cairoImage, strokeColor.r, strokeColor.g, strokeColor.b,
|
||||
strokeColor.a );
|
||||
cairo_stroke_preserve( cairoImage );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the actual path, append it to the global path list
|
||||
// then check, if the path needs to be stroked/filled and
|
||||
// add this command to the group list;
|
||||
|
||||
cairo_path_t* path = cairo_copy_path( cairoImage );
|
||||
pathList.push_back( path );
|
||||
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.cairoPath = path;
|
||||
groupElement.command = CMD_STROKE_PATH;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
|
||||
if( isFillEnabled )
|
||||
{
|
||||
GroupElement groupElement;
|
||||
groupElement.cairoPath = path;
|
||||
groupElement.command = CMD_FILL_PATH;
|
||||
groups.back().push_back( groupElement );
|
||||
}
|
||||
}
|
||||
|
||||
cairo_new_path( cairoImage );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------
|
||||
// Cursor handling
|
||||
// ---------------
|
||||
|
||||
|
||||
void CAIRO_GAL::initCursor( int aCursorSize )
|
||||
{
|
||||
cursorPixels = new wxBitmap( aCursorSize, aCursorSize );
|
||||
cursorPixelsSaved = new wxBitmap( aCursorSize, aCursorSize );
|
||||
cursorSize = aCursorSize;
|
||||
|
||||
wxMemoryDC cursorShape( *cursorPixels );
|
||||
|
||||
cursorShape.SetBackground( *wxTRANSPARENT_BRUSH );
|
||||
wxColour color( cursorColor.r * cursorColor.a * 255, cursorColor.g * cursorColor.a * 255,
|
||||
cursorColor.b * cursorColor.a * 255, 255 );
|
||||
wxPen pen = wxPen( color );
|
||||
cursorShape.SetPen( pen );
|
||||
cursorShape.Clear();
|
||||
|
||||
cursorShape.DrawLine( 0, aCursorSize / 2, aCursorSize, aCursorSize / 2 );
|
||||
cursorShape.DrawLine( aCursorSize / 2, 0, aCursorSize / 2, aCursorSize );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2D CAIRO_GAL::ComputeCursorToWorld( VECTOR2D aCursorPosition )
|
||||
{
|
||||
|
||||
MATRIX3x3D inverseMatrix = worldScreenMatrix.Inverse();
|
||||
VECTOR2D cursorPositionWorld = inverseMatrix * aCursorPosition;
|
||||
|
||||
return cursorPositionWorld;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawCursor( VECTOR2D aCursorPosition )
|
||||
{
|
||||
if( !IsShownOnScreen() )
|
||||
return;
|
||||
|
||||
wxClientDC clientDC( this );
|
||||
wxMemoryDC cursorSave( *cursorPixelsSaved );
|
||||
wxMemoryDC cursorShape( *cursorPixels );
|
||||
|
||||
// Snap to grid
|
||||
VECTOR2D cursorPositionWorld = ComputeCursorToWorld( aCursorPosition );
|
||||
|
||||
cursorPositionWorld.x = round( cursorPositionWorld.x / gridSize.x ) * gridSize.x;
|
||||
cursorPositionWorld.y = round( cursorPositionWorld.y / gridSize.y ) * gridSize.y;
|
||||
aCursorPosition = worldScreenMatrix * cursorPositionWorld;
|
||||
aCursorPosition = aCursorPosition - VECTOR2D( cursorSize / 2, cursorSize / 2 );
|
||||
|
||||
if( !isDeleteSavedPixels )
|
||||
{
|
||||
clientDC.Blit( savedCursorPosition.x, savedCursorPosition.y, cursorSize, cursorSize,
|
||||
&cursorSave, 0, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
isDeleteSavedPixels = false;
|
||||
}
|
||||
|
||||
cursorSave.Blit( 0, 0, cursorSize, cursorSize, &clientDC, aCursorPosition.x,
|
||||
aCursorPosition.y );
|
||||
|
||||
clientDC.Blit( aCursorPosition.x, aCursorPosition.y, cursorSize, cursorSize, &cursorShape, 0,
|
||||
0, wxOR );
|
||||
|
||||
savedCursorPosition.x = (wxCoord) aCursorPosition.x;
|
||||
savedCursorPosition.y = (wxCoord) aCursorPosition.y;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawGridLine( VECTOR2D aStartPoint, VECTOR2D aEndPoint )
|
||||
{
|
||||
cairo_move_to( cairoImage, aStartPoint.x, aStartPoint.y );
|
||||
cairo_line_to( cairoImage, aEndPoint.x, aEndPoint.y );
|
||||
cairo_set_source_rgba( cairoImage, gridColor.r, gridColor.g, gridColor.b, gridColor.a );
|
||||
cairo_stroke( cairoImage );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::allocateBitmaps()
|
||||
{
|
||||
// Create buffer, use the system independent CAIRO image back end
|
||||
stride = cairo_format_stride_for_width( CAIRO_FORMAT_RGB24, screenSize.x );
|
||||
bufferSize = stride * screenSize.y;
|
||||
|
||||
bitmapBuffer = new unsigned int[bufferSize];
|
||||
bitmapBufferBackup = new unsigned int[bufferSize];
|
||||
wxOutput = new unsigned char[bufferSize * 4];
|
||||
wxBitmap_ = new wxBitmap( screenSize.x, screenSize.y, SCREEN_DEPTH );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::deleteBitmaps()
|
||||
{
|
||||
delete[] bitmapBuffer;
|
||||
delete[] bitmapBufferBackup;
|
||||
delete[] wxOutput;
|
||||
delete wxBitmap_;
|
||||
}
|
||||
|
||||
|
||||
bool CAIRO_GAL::Show( bool aShow )
|
||||
{
|
||||
bool s = wxWindow::Show( aShow );
|
||||
|
||||
if( aShow )
|
||||
wxWindow::Raise();
|
||||
|
||||
return s;
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Graphics Abstraction Layer (GAL) - base class
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <wx/log.h>
|
||||
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
#include <gal/definitions.h>
|
||||
#include <gal/color4d.h>
|
||||
|
||||
|
||||
using namespace KiGfx;
|
||||
|
||||
const wxEventType KiGfx::EVT_GAL_REDRAW = wxNewEventType();
|
||||
|
||||
GAL::GAL()
|
||||
{
|
||||
// Set the default values for the internal variables
|
||||
SetIsFill( false );
|
||||
SetIsStroke( true );
|
||||
SetLineJoin( LINE_JOIN_ROUND );
|
||||
SetLineCap( LINE_CAP_ROUND );
|
||||
SetIsCursorEnabled( false );
|
||||
SetZoomFactor( 1.0 );
|
||||
SetFillColor( COLOR4D( 0.0, 0.0, 0.0, 0.0 ) );
|
||||
SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
|
||||
SetGridColor( COLOR4D( 1, 1, 1, 0.1 ) );
|
||||
SetCoarseGrid( 5 );
|
||||
SetLineWidth( 1.0 );
|
||||
SetDepthRange( VECTOR2D( -2048, 2047 ) );
|
||||
}
|
||||
|
||||
|
||||
GAL::~GAL()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GAL::DrawGrid()
|
||||
{
|
||||
// The grid consists of lines
|
||||
// For the drawing the start points, end points and increments have to be calculated in world coordinates
|
||||
VECTOR2D screenStartPoint( 0, 0 );
|
||||
VECTOR2D screenEndPoint( screenSize.x, screenSize.y );
|
||||
MATRIX3x3D inverseMatrix = worldScreenMatrix.Inverse();
|
||||
VECTOR2D worldStartPoint = inverseMatrix * screenStartPoint;
|
||||
VECTOR2D worldEndPoint = inverseMatrix * screenEndPoint;
|
||||
|
||||
// Compute grid variables
|
||||
int gridStartX = round( worldStartPoint.x / gridSize.x );
|
||||
int gridEndX = round( worldEndPoint.x / gridSize.x );
|
||||
int gridStartY = round( worldStartPoint.y / gridSize.y );
|
||||
int gridEndY = round( worldEndPoint.y / gridSize.y );
|
||||
|
||||
int gridScreenSizeDense = round( gridSize.x * worldScale );
|
||||
int gridScreenSizeCoarse = round( gridSize.x * (double) gridTick * worldScale );
|
||||
|
||||
// Swap the coordinates, if they have not the right order
|
||||
SWAP( gridEndX, <, gridStartX );
|
||||
SWAP( gridEndY, <, gridStartY );
|
||||
|
||||
// Correct the index, else some lines are not correctly painted
|
||||
gridStartX -= 1;
|
||||
gridStartY -= 1;
|
||||
gridEndX += 1;
|
||||
gridEndY += 1;
|
||||
|
||||
double savedLineWidth = GetLineWidth();
|
||||
COLOR4D savedColor = GetStrokeColor();
|
||||
|
||||
// Compute the line width of the grid
|
||||
ComputeWorldScale();
|
||||
double width = gridLineWidth / worldScale;
|
||||
double doubleWidth = 2 * width;
|
||||
|
||||
// Set line width & color
|
||||
SetLineWidth( width );
|
||||
|
||||
double origSize = (double) gridOriginMarkerSize / worldScale;
|
||||
|
||||
SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
|
||||
SetIsFill( false );
|
||||
DrawLine( gridOrigin + VECTOR2D( -origSize, -origSize ), gridOrigin + VECTOR2D( origSize, origSize ) );
|
||||
DrawLine( gridOrigin + VECTOR2D( -origSize, origSize ), gridOrigin + VECTOR2D( origSize, -origSize ) );
|
||||
DrawCircle( gridOrigin, origSize * 0.7 );
|
||||
|
||||
SetStrokeColor( gridColor );
|
||||
|
||||
if( std::max( gridScreenSizeDense, gridScreenSizeCoarse ) < gridDrawThreshold )
|
||||
return;
|
||||
|
||||
// Now draw the grid, every coarse grid line gets the double width
|
||||
for( int j = gridStartY; j < gridEndY; j += 1 )
|
||||
{
|
||||
if( j % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold )
|
||||
{
|
||||
SetLineWidth( doubleWidth );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLineWidth( width );
|
||||
}
|
||||
|
||||
if( ( j % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold )
|
||||
|| gridScreenSizeDense > gridDrawThreshold )
|
||||
{
|
||||
DrawGridLine( VECTOR2D( gridStartX * gridSize.x, j * gridSize.y ),
|
||||
VECTOR2D( gridEndX * gridSize.x, j * gridSize.y ) );
|
||||
}
|
||||
}
|
||||
|
||||
for( int i = gridStartX; i < gridEndX; i += 1 )
|
||||
{
|
||||
if( i % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold )
|
||||
{
|
||||
SetLineWidth( doubleWidth );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLineWidth( width );
|
||||
}
|
||||
|
||||
if( ( i % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold )
|
||||
|| gridScreenSizeDense > gridDrawThreshold )
|
||||
{
|
||||
DrawGridLine( VECTOR2D( i * gridSize.x, gridStartY * gridSize.y ),
|
||||
VECTOR2D( i * gridSize.x, gridEndY * gridSize.y ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Restore old values
|
||||
SetLineWidth( savedLineWidth );
|
||||
SetStrokeColor( savedColor );
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Graphics Abstraction Layer (GAL) for OpenGL
|
||||
*
|
||||
* Shader class
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <wx/log.h>
|
||||
|
||||
#include <gal/opengl/shader.h>
|
||||
|
||||
using namespace KiGfx;
|
||||
|
||||
SHADER::SHADER()
|
||||
{
|
||||
isProgramCreated = false;
|
||||
isShaderLinked = false;
|
||||
maximumVertices = 4;
|
||||
geomInputType = GL_LINES;
|
||||
geomOutputType = GL_LINES;
|
||||
}
|
||||
|
||||
|
||||
SHADER::~SHADER()
|
||||
{
|
||||
if( isProgramCreated )
|
||||
{
|
||||
// Delete the shaders and the program
|
||||
for( std::deque<GLuint>::iterator it = shaderNumbers.begin(); it != shaderNumbers.end();
|
||||
it++ )
|
||||
{
|
||||
glDeleteShader( *it );
|
||||
}
|
||||
|
||||
glDeleteProgram( programNumber );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SHADER::ProgramInfo( GLuint aProgram )
|
||||
{
|
||||
GLint glInfoLogLength = 0;
|
||||
GLint writtenChars = 0;
|
||||
|
||||
// Get the length of the info string
|
||||
glGetProgramiv( aProgram, GL_INFO_LOG_LENGTH, &glInfoLogLength );
|
||||
|
||||
// Print the information
|
||||
if( glInfoLogLength > 2 )
|
||||
{
|
||||
GLchar* glInfoLog = new GLchar[glInfoLogLength];
|
||||
glGetProgramInfoLog( aProgram, glInfoLogLength, &writtenChars, glInfoLog );
|
||||
|
||||
wxLogInfo( wxString::FromUTF8( (char*) glInfoLog ) );
|
||||
|
||||
delete glInfoLog;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string SHADER::ReadSource( std::string aShaderSourceName )
|
||||
{
|
||||
// Open the shader source for reading
|
||||
std::ifstream inputFile( aShaderSourceName.c_str(), std::ifstream::in );
|
||||
std::string shaderSource;
|
||||
|
||||
if( !inputFile )
|
||||
{
|
||||
wxLogError( wxString::FromUTF8( "Can't read the shader source: " ) +
|
||||
wxString( aShaderSourceName.c_str(), wxConvUTF8 ) );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
std::string shaderSourceLine;
|
||||
|
||||
// Read all lines from the text file
|
||||
while( getline( inputFile, shaderSourceLine ) )
|
||||
{
|
||||
shaderSource += shaderSourceLine;
|
||||
shaderSource += "\n";
|
||||
}
|
||||
|
||||
return shaderSource;
|
||||
}
|
||||
|
||||
|
||||
void SHADER::AddSource( std::string aShaderSourceName, ShaderType aShaderType )
|
||||
{
|
||||
if( isShaderLinked )
|
||||
{
|
||||
wxLogError( wxString::FromUTF8( "Shader is already linked!" ) );
|
||||
}
|
||||
|
||||
// Create the program
|
||||
if( !isProgramCreated )
|
||||
{
|
||||
programNumber = glCreateProgram();
|
||||
isProgramCreated = true;
|
||||
}
|
||||
|
||||
// Load shader sources
|
||||
std::string shaderSource = ReadSource( aShaderSourceName );
|
||||
|
||||
// Create a shader
|
||||
GLuint shaderNumber = glCreateShader( aShaderType );
|
||||
shaderNumbers.push_back( shaderNumber );
|
||||
|
||||
// Get the program info
|
||||
ProgramInfo( programNumber );
|
||||
|
||||
// Copy to char array
|
||||
char* source = new char[shaderSource.size() + 1];
|
||||
strcpy( source, shaderSource.c_str() );
|
||||
const char** source_ = (const char**) ( &source );
|
||||
|
||||
// Attach the source
|
||||
glShaderSource( shaderNumber, 1, source_, NULL );
|
||||
ProgramInfo( programNumber );
|
||||
|
||||
// Compile and attach shader to the program
|
||||
glCompileShader( shaderNumber );
|
||||
glAttachShader( programNumber, shaderNumber );
|
||||
ProgramInfo( programNumber );
|
||||
|
||||
// Special handling for the geometry shader
|
||||
if( aShaderType == SHADER_TYPE_GEOMETRY )
|
||||
{
|
||||
glProgramParameteriEXT( programNumber, GL_GEOMETRY_VERTICES_OUT_EXT, maximumVertices );
|
||||
glProgramParameteriEXT( programNumber, GL_GEOMETRY_INPUT_TYPE_EXT, geomInputType );
|
||||
glProgramParameteriEXT( programNumber, GL_GEOMETRY_OUTPUT_TYPE_EXT, geomOutputType );
|
||||
}
|
||||
|
||||
// Delete the allocated char array
|
||||
delete[] source;
|
||||
}
|
||||
|
||||
|
||||
void SHADER::ConfigureGeometryShader( GLuint maxVertices, GLuint geometryInputType,
|
||||
GLuint geometryOutputType )
|
||||
{
|
||||
maximumVertices = maxVertices;
|
||||
geomInputType = geometryInputType;
|
||||
geomOutputType = geometryOutputType;
|
||||
}
|
||||
|
||||
|
||||
void SHADER::Link()
|
||||
{
|
||||
// Shader linking
|
||||
glLinkProgram( programNumber );
|
||||
ProgramInfo( programNumber );
|
||||
|
||||
// Check the Link state
|
||||
GLint linkStatus = 0;
|
||||
glGetObjectParameterivARB( programNumber, GL_OBJECT_LINK_STATUS_ARB, &linkStatus );
|
||||
|
||||
if( !linkStatus )
|
||||
{
|
||||
wxLogError( wxString::FromUTF8( "Can't link the shaders!" ) );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
isShaderLinked = true;
|
||||
}
|
||||
|
||||
|
||||
void SHADER::Use()
|
||||
{
|
||||
glUseProgram( programNumber );
|
||||
}
|
||||
|
||||
|
||||
void SHADER::Deactivate()
|
||||
{
|
||||
glUseProgram( 0 );
|
||||
}
|
||||
|
||||
|
||||
void SHADER::AddParameter( std::string aParameterName )
|
||||
{
|
||||
GLint location = glGetUniformLocation( programNumber, aParameterName.c_str() );
|
||||
|
||||
if( location != -1 )
|
||||
{
|
||||
parameterLocation.push_back( location );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SHADER::SetParameter( int parameterNumber, float value )
|
||||
{
|
||||
glUniform1f( parameterLocation[parameterNumber], value );
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Fragment shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
// This shader requires GLSL 1.2
|
||||
#version 120
|
||||
|
||||
// Input variables
|
||||
flat varying vec4 center_;
|
||||
flat varying vec2 radius_;
|
||||
flat varying vec4 colorA_;
|
||||
flat varying vec4 colorB_;
|
||||
|
||||
void main( void )
|
||||
{
|
||||
// Compute the distance from the circle edge
|
||||
float distA = distance( center_, gl_FragCoord ) - radius_.y;
|
||||
float distB = radius_.x - distance( center_, gl_FragCoord );
|
||||
|
||||
// Limit the range to [ 0 .. 1 ]
|
||||
if( distA < 0 ) distA = 0;
|
||||
if( distA > 1 ) distA = 1;
|
||||
if( distB < 0 ) distB = 0;
|
||||
if( distB > 1 ) distB = 1;
|
||||
|
||||
// Points with a larger distance from the edge are set deeper
|
||||
gl_FragDepth = gl_FragCoord.z + distA * 0.001 + distB * 0.001;
|
||||
|
||||
// Compute the color
|
||||
vec4 color;
|
||||
color.r = colorA_.r;
|
||||
color.g = colorA_.g;
|
||||
color.b = colorA_.b;
|
||||
color.a = colorA_.a * ( 1 - distA ) * ( 1 - distB );
|
||||
|
||||
// Now output the edge fragment color
|
||||
gl_FragColor = color;
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Geometry shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
// This shader requires GLSL 1.2
|
||||
#version 120
|
||||
#extension GL_EXT_geometry_shader4: enable
|
||||
#extension GL_EXT_gpu_shader4: enable
|
||||
|
||||
uniform float viewPortX2;
|
||||
uniform float viewPortY2;
|
||||
|
||||
flat varying vec4 center_;
|
||||
flat varying vec2 radius_;
|
||||
flat varying vec4 colorA_;
|
||||
|
||||
const float PI = 3.141592654;
|
||||
const float EPSILON = 0.01;
|
||||
const float smallestValue = 1.175494351e-38;
|
||||
const int SEGMENTS = 16;
|
||||
|
||||
const float PIXEL_EXTEND = 1.5;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 center = gl_PositionIn[0];
|
||||
vec4 radius = gl_PositionIn[1];
|
||||
|
||||
center_ = gl_ModelViewProjectionMatrix * center;
|
||||
|
||||
// Compute the outer and inner radius in screen coordinates
|
||||
// This could be further optimized
|
||||
radius_.x = ( gl_ModelViewProjectionMatrix * vec4(radius.x, 0, 0, 1) ).x;
|
||||
radius_.x = abs( radius_.x - (gl_ModelViewProjectionMatrix * vec4(0, 0, 0, 1) ).x ) * viewPortX2;
|
||||
radius_.y = ( gl_ModelViewProjectionMatrix * vec4(radius.y, 0, 0, 1) ).x;
|
||||
radius_.y = abs( radius_.y - (gl_ModelViewProjectionMatrix * vec4(0, 0, 0, 1) ).x ) * viewPortX2;
|
||||
|
||||
// Compute the center point in screen coordinates
|
||||
center_.x = center_.x * viewPortX2 + viewPortX2;
|
||||
center_.y = center_.y * viewPortY2 + viewPortY2;
|
||||
|
||||
// Compute the extend value, first make sure that the outline is inside the triangles and second add
|
||||
// a margin for one pixel for smooth edges
|
||||
float extendInner = 1.0;
|
||||
float extendOuter = 0;
|
||||
if( radius_.y > smallestValue )
|
||||
{
|
||||
extendOuter += PIXEL_EXTEND / radius_.y;
|
||||
}
|
||||
extendOuter += 1.0 / cos( PI / SEGMENTS );
|
||||
|
||||
colorA_ = gl_FrontColorIn[0];
|
||||
|
||||
// Create a quad strip for the outer circle edge
|
||||
for( float alpha = 0, inc = 2 * PI / SEGMENTS, limit = 2 * PI + EPSILON;
|
||||
alpha < limit; alpha += inc )
|
||||
{
|
||||
gl_Position = gl_ModelViewProjectionMatrix *
|
||||
vec4( center.x + extendInner * radius.y * cos( alpha ),
|
||||
center.y + extendInner * radius.y * sin( alpha ), center.zw );
|
||||
EmitVertex();
|
||||
gl_Position = gl_ModelViewProjectionMatrix *
|
||||
vec4( center.x + extendOuter * radius.y * cos( alpha ),
|
||||
center.y + extendOuter * radius.y * sin( alpha ), center.zw );
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
|
||||
if( radius.x > 0 )
|
||||
{
|
||||
extendInner = cos( PI / SEGMENTS ) - PIXEL_EXTEND / radius_.x;
|
||||
if( extendInner < 0.0 )
|
||||
{
|
||||
extendInner = 0;
|
||||
}
|
||||
extendOuter = 1.0 / cos( PI / SEGMENTS);
|
||||
|
||||
// Create a quad strip for the inner circle edge
|
||||
for( float alpha = 0, inc = 2 * PI / SEGMENTS, limit = 2 * PI + EPSILON;
|
||||
alpha < limit; alpha += inc )
|
||||
{
|
||||
gl_Position = gl_ModelViewProjectionMatrix *
|
||||
vec4( center.x + extendOuter * radius.x * cos( alpha ),
|
||||
center.y + extendOuter * radius.x * sin( alpha ), center.zw );
|
||||
EmitVertex();
|
||||
gl_Position = gl_ModelViewProjectionMatrix *
|
||||
vec4( center.x + extendInner * radius.x * cos( alpha ),
|
||||
center.y + extendInner * radius.x * sin( alpha ), center.zw );
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Vertex shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
// This shader requires GLSL 1.2
|
||||
#version 120
|
||||
|
||||
void main()
|
||||
{
|
||||
// Simple pass-through
|
||||
gl_Position = gl_Vertex;
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Fragment shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#version 120
|
||||
#extension GL_EXT_gpu_shader4: enable
|
||||
|
||||
varying float dist;
|
||||
|
||||
void main()
|
||||
{
|
||||
float d = dist;
|
||||
gl_FragDepth = gl_FragCoord.z + d * 0.001;
|
||||
gl_FragColor = vec4( gl_Color.rgb, gl_Color.a * ( 1 - d ) );
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Geometry shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#version 120
|
||||
#extension GL_EXT_geometry_shader4: enable
|
||||
#extension GL_EXT_gpu_shader4: enable
|
||||
|
||||
uniform float viewPortX2;
|
||||
uniform float viewPortY2;
|
||||
varying float dist;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Compute the transformed start and end points
|
||||
vec2 startPoint = gl_PositionIn[0].xy;
|
||||
vec2 endPoint = gl_PositionIn[1].xy;
|
||||
float lineWidth = gl_PositionIn[1].z;
|
||||
|
||||
// Compute vector start -> end
|
||||
vec2 startEndVector = endPoint.xy - startPoint.xy;
|
||||
float lineLength = distance( startPoint, endPoint );
|
||||
float scale = 0.0;
|
||||
|
||||
if( lineLength > 0.0 )
|
||||
{
|
||||
scale = 0.5 * lineWidth / lineLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = 0.0;
|
||||
}
|
||||
|
||||
// Compute the edge points of the line
|
||||
vec2 perpendicularVector = scale * vec2( -startEndVector.y, startEndVector.x );
|
||||
vec2 point1 = startPoint + perpendicularVector;
|
||||
vec2 point2 = startPoint - perpendicularVector;
|
||||
vec2 point3 = endPoint + perpendicularVector;
|
||||
vec2 point4 = endPoint - perpendicularVector;
|
||||
|
||||
vec4 point1T = gl_ModelViewProjectionMatrix * vec4( point1, gl_PositionIn[0].zw );
|
||||
vec4 point2T = gl_ModelViewProjectionMatrix * vec4( point2, gl_PositionIn[0].zw );
|
||||
vec4 point3T = gl_ModelViewProjectionMatrix * vec4( point3, gl_PositionIn[0].zw );
|
||||
vec4 point4T = gl_ModelViewProjectionMatrix * vec4( point4, gl_PositionIn[0].zw );
|
||||
|
||||
// Construct the quad for the middle
|
||||
gl_FrontColor = gl_FrontColorIn[0];
|
||||
dist = 0;
|
||||
gl_Position = point1T;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point2T;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point3T;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point4T;
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
|
||||
// Compute the perpendicular vector with 1 pixel width
|
||||
vec2 v = point1T.xy - point3T.xy;
|
||||
vec4 onePix = 0.5 * vec4( -v.y, v.x, 0, 0 );
|
||||
onePix *= 1.0 / sqrt( dot( onePix, onePix ) );
|
||||
onePix.x *= 1.0 / viewPortX2;
|
||||
onePix.y *= 1.0 / viewPortY2;
|
||||
|
||||
gl_FrontColor = gl_FrontColorIn[0];
|
||||
|
||||
dist = 1;
|
||||
gl_Position = point1T + onePix;
|
||||
EmitVertex();
|
||||
dist = 1;
|
||||
gl_Position = point3T + onePix;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point1T;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point3T;
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
|
||||
dist = 1;
|
||||
gl_Position = point2T - onePix;
|
||||
EmitVertex();
|
||||
dist = 1;
|
||||
gl_Position = point4T - onePix;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point2T;
|
||||
EmitVertex();
|
||||
dist = 0;
|
||||
gl_Position = point4T;
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Vertex shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
// This shader requires GLSL 1.2
|
||||
#version 120
|
||||
|
||||
void main()
|
||||
{
|
||||
// Simple pass-through
|
||||
gl_Position = gl_Vertex;
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* Fragment shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
varying float aspect;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 v = abs( gl_TexCoord[0].xy - vec2( 0.5, 0.5 ) ) * 2.0 - vec2( aspect, 0.0 );
|
||||
vec2 d = vec2( v.x / ( 1.0 - aspect ), v.y );
|
||||
|
||||
if( v.x <= 0.0 || (dot( d, d ) < 1.0 ) )
|
||||
gl_FragColor = gl_Color;
|
||||
else
|
||||
discard;
|
||||
|
||||
// gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* Vertex shader
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#version 120
|
||||
|
||||
varying float aspect;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_FrontColor = gl_Color;
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
aspect = gl_Normal.x;
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Stroke font class
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <gal/stroke_font.h>
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
|
||||
using namespace KiGfx;
|
||||
|
||||
STROKE_FONT::STROKE_FONT( GAL* aGal ) :
|
||||
m_gal( aGal ),
|
||||
m_bold( false ),
|
||||
m_italic( false ),
|
||||
m_mirrored( false )
|
||||
{
|
||||
// Default values
|
||||
m_scaleFactor = 1.0 / 21.0;
|
||||
m_glyphSize = VECTOR2D( 10.0, 10.0 );
|
||||
m_verticalJustify = GR_TEXT_VJUSTIFY_BOTTOM;
|
||||
m_horizontalJustify = GR_TEXT_HJUSTIFY_LEFT;
|
||||
}
|
||||
|
||||
|
||||
STROKE_FONT::~STROKE_FONT()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool STROKE_FONT::LoadNewStrokeFont( const char* const aNewStrokeFont[], int aNewStrokeFontSize )
|
||||
{
|
||||
m_glyphs.clear();
|
||||
m_glyphBoundingBoxes.clear();
|
||||
|
||||
for( int j = 0; j < aNewStrokeFontSize; j++ )
|
||||
{
|
||||
Glyph glyph;
|
||||
double glyphStartX;
|
||||
double glyphEndX;
|
||||
VECTOR2D glyphBoundingX;
|
||||
|
||||
std::deque<VECTOR2D> pointList;
|
||||
|
||||
int i = 0;
|
||||
|
||||
while( aNewStrokeFont[j][i] )
|
||||
{
|
||||
VECTOR2D point;
|
||||
char coordinate[2];
|
||||
|
||||
for( int k = 0; k < 2; k++ )
|
||||
{
|
||||
coordinate[k] = aNewStrokeFont[j][i + k];
|
||||
}
|
||||
|
||||
if( i < 2 )
|
||||
{
|
||||
// The first two values contain the width of the char
|
||||
glyphStartX = coordinate[0] - 'R';
|
||||
glyphEndX = coordinate[1] - 'R';
|
||||
glyphBoundingX = VECTOR2D( 0, glyphEndX - glyphStartX );
|
||||
}
|
||||
else if( ( coordinate[0] == ' ' ) && ( coordinate[1] == 'R' ) )
|
||||
{
|
||||
// Raise pen
|
||||
if( pointList.size() > 0 )
|
||||
glyph.push_back( pointList );
|
||||
|
||||
pointList.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Every coordinate description of the Hershey format has an offset,
|
||||
// it has to be subtracted
|
||||
point.x = (double) ( coordinate[0] - 'R' ) - glyphStartX;
|
||||
point.y = (double) ( coordinate[1] - 'R' ) - 11.0;
|
||||
pointList.push_back( point );
|
||||
}
|
||||
|
||||
i += 2;
|
||||
}
|
||||
|
||||
if( pointList.size() > 0 )
|
||||
glyph.push_back( pointList );
|
||||
|
||||
m_glyphs.push_back( glyph );
|
||||
|
||||
// Compute the bounding box of the glyph
|
||||
m_glyphBoundingBoxes.push_back( computeBoundingBox( glyph, glyphBoundingX ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void STROKE_FONT::LoadAttributes( const EDA_TEXT* aText )
|
||||
{
|
||||
SetGlyphSize( VECTOR2D( aText->GetSize() ) );
|
||||
SetHorizontalJustify( aText->GetHorizJustify() );
|
||||
SetVerticalJustify( aText->GetVertJustify() );
|
||||
SetBold( aText->IsBold() );
|
||||
SetItalic( aText->IsItalic() );
|
||||
SetMirrored( aText->IsMirrored() );
|
||||
}
|
||||
|
||||
|
||||
BOX2D STROKE_FONT::computeBoundingBox( Glyph aGlyph, VECTOR2D aGlyphBoundingX )
|
||||
{
|
||||
BOX2D boundingBox;
|
||||
|
||||
std::deque<VECTOR2D> boundingPoints;
|
||||
|
||||
boundingPoints.push_back( VECTOR2D( aGlyphBoundingX.x, 0 ) );
|
||||
boundingPoints.push_back( VECTOR2D( aGlyphBoundingX.y, 0 ) );
|
||||
|
||||
for( Glyph::iterator pointListIt = aGlyph.begin(); pointListIt != aGlyph.end(); ++pointListIt )
|
||||
{
|
||||
for( std::deque<VECTOR2D>::iterator pointIt = pointListIt->begin();
|
||||
pointIt != pointListIt->end(); ++pointIt )
|
||||
{
|
||||
boundingPoints.push_back( VECTOR2D( aGlyphBoundingX.x, pointIt->y ) );
|
||||
}
|
||||
}
|
||||
|
||||
boundingBox.Compute( boundingPoints );
|
||||
|
||||
return boundingBox;
|
||||
}
|
||||
|
||||
|
||||
void STROKE_FONT::Draw( std::string aText, VECTOR2D aPosition, double aRotationAngle )
|
||||
{
|
||||
// Compute the text size
|
||||
VECTOR2D textsize = computeTextSize( aText );
|
||||
|
||||
// Context needs to be saved before any transformations
|
||||
m_gal->Save();
|
||||
|
||||
m_gal->Translate( aPosition );
|
||||
m_gal->Rotate( -aRotationAngle );
|
||||
|
||||
// Adjust the text position to the given alignment
|
||||
switch( m_horizontalJustify )
|
||||
{
|
||||
case GR_TEXT_HJUSTIFY_CENTER:
|
||||
m_gal->Translate( VECTOR2D( -textsize.x / 2, 0 ) );
|
||||
break;
|
||||
|
||||
case GR_TEXT_HJUSTIFY_RIGHT:
|
||||
m_gal->Translate( VECTOR2D( -textsize.x, 0 ) );
|
||||
break;
|
||||
|
||||
case GR_TEXT_HJUSTIFY_LEFT:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch( m_verticalJustify )
|
||||
{
|
||||
case GR_TEXT_VJUSTIFY_CENTER:
|
||||
m_gal->Translate( VECTOR2D( 0, textsize.y / 2 ) );
|
||||
break;
|
||||
|
||||
case GR_TEXT_VJUSTIFY_TOP:
|
||||
m_gal->Translate( VECTOR2D( 0, textsize.y ) );
|
||||
break;
|
||||
|
||||
case GR_TEXT_VJUSTIFY_BOTTOM:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
double xOffset, glyphSizeX;
|
||||
|
||||
if( m_mirrored )
|
||||
{
|
||||
// In case of mirrored text invert the X scale of points and their X direction
|
||||
// (m_glyphSize.x) and start drawing from the position where text normally should end
|
||||
// (textsize.x)
|
||||
xOffset = textsize.x;
|
||||
glyphSizeX = -m_glyphSize.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
xOffset = 0.0;
|
||||
glyphSizeX = m_glyphSize.x;
|
||||
}
|
||||
double scaleY = m_scaleFactor * m_glyphSize.y;
|
||||
double scaleX = m_scaleFactor * glyphSizeX;
|
||||
|
||||
if( m_bold )
|
||||
{
|
||||
m_gal->SetLineWidth( m_gal->GetLineWidth() * 1.3 );
|
||||
}
|
||||
|
||||
for( std::string::iterator chIt = aText.begin(); chIt != aText.end(); chIt++ )
|
||||
{
|
||||
GlyphList::iterator glyphIt = m_glyphs.begin();
|
||||
std::deque<BOX2D>::iterator bbIt = m_glyphBoundingBoxes.begin();
|
||||
|
||||
advance( glyphIt, (int) ( *chIt ) - (int) ' ' );
|
||||
advance( bbIt, (int) ( *chIt ) - (int) ' ' );
|
||||
|
||||
Glyph glyph = *glyphIt;
|
||||
|
||||
for( Glyph::iterator pointListIt = glyph.begin(); pointListIt != glyph.end();
|
||||
pointListIt++ )
|
||||
{
|
||||
std::deque<VECTOR2D> pointListScaled;
|
||||
|
||||
for( std::deque<VECTOR2D>::iterator pointIt = pointListIt->begin();
|
||||
pointIt != pointListIt->end(); pointIt++ )
|
||||
{
|
||||
VECTOR2D pointPos( pointIt->x * scaleX + xOffset, pointIt->y * scaleY );
|
||||
|
||||
if( m_italic )
|
||||
{
|
||||
// FIXME should be done other way - referring to the lowest Y value of point
|
||||
// because now italic fonts are translated a bit
|
||||
pointPos.x += pointPos.y * 0.1;
|
||||
}
|
||||
|
||||
pointListScaled.push_back( pointPos );
|
||||
}
|
||||
|
||||
m_gal->DrawPolyline( pointListScaled );
|
||||
}
|
||||
|
||||
xOffset += m_scaleFactor * glyphSizeX *
|
||||
( bbIt->GetEnd().x - bbIt->GetOrigin().x );
|
||||
}
|
||||
|
||||
m_gal->Restore();
|
||||
}
|
||||
|
||||
|
||||
VECTOR2D STROKE_FONT::computeTextSize( std::string aText )
|
||||
{
|
||||
VECTOR2D result = VECTOR2D( 0.0, 0.0 );
|
||||
|
||||
for( std::string::iterator chIt = aText.begin(); chIt != aText.end(); chIt++ )
|
||||
{
|
||||
std::deque<BOX2D>::iterator bbIt = m_glyphBoundingBoxes.begin();
|
||||
advance( bbIt, (int) ( *chIt ) - (int) ' ' );
|
||||
result.x += m_scaleFactor * m_glyphSize.x * ( bbIt->GetEnd().x - bbIt->GetOrigin().x );
|
||||
}
|
||||
|
||||
result.y = m_glyphSize.y;
|
||||
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <eda_text.h>
|
||||
#include <view/view.h>
|
||||
#include <painter.h>
|
||||
#include <gal/stroke_font.h>
|
||||
#include <newstroke_font.h>
|
||||
|
||||
using namespace KiGfx;
|
||||
|
||||
RENDER_SETTINGS::RENDER_SETTINGS()
|
||||
{
|
||||
// Set the default initial values
|
||||
m_selectionBorderColor = COLOR4D( 1.0, 1.0, 1.0, 1.0 );
|
||||
m_netLabelColor = COLOR4D( 1.0, 1.0, 1.0, 0.7 );
|
||||
|
||||
m_highlightFactor = 0.5;
|
||||
m_selectFactor = 0.5;
|
||||
m_layerOpacity = 0.8;
|
||||
m_highlightEnabled = false;
|
||||
m_hiContrastEnabled = false;
|
||||
m_hiContrastFactor = 0.2;
|
||||
|
||||
// Store the predefined colors used in KiCad in format used by GAL
|
||||
for( int i = 0; i < NBCOLOR; i++ )
|
||||
{
|
||||
m_legacyColorMap[ColorRefs[i].m_Numcolor] = COLOR4D( (double) ColorRefs[i].m_Red / 255.0,
|
||||
(double) ColorRefs[i].m_Green / 255.0,
|
||||
(double) ColorRefs[i].m_Blue / 255.0,
|
||||
m_layerOpacity );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RENDER_SETTINGS::~RENDER_SETTINGS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void RENDER_SETTINGS::Update()
|
||||
{
|
||||
m_hiContrastColor = COLOR4D( m_hiContrastFactor, m_hiContrastFactor, m_highlightFactor,
|
||||
m_layerOpacity );
|
||||
}
|
||||
|
||||
|
||||
PAINTER::PAINTER( GAL* aGal ) :
|
||||
m_gal( aGal ), m_settings( NULL )
|
||||
{
|
||||
m_stroke_font = new STROKE_FONT( aGal );
|
||||
m_stroke_font->LoadNewStrokeFont( newstroke_font, newstroke_font_bufsize );
|
||||
}
|
||||
|
||||
|
||||
PAINTER::~PAINTER()
|
||||
{
|
||||
delete m_stroke_font;
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file profile.h:
|
||||
* @brief Simple profiling functions for measuring code execution time. Currently only Linux is
|
||||
* supported.
|
||||
*/
|
||||
|
||||
#ifndef __PROFILE_H
|
||||
#define __PROFILE_H
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Function rdtsc
|
||||
* Returns processor's time-stamp counter. Main purpose is precise time measuring of code
|
||||
* execution time.
|
||||
* @return unsigned long long - Value of time-stamp counter.
|
||||
*/
|
||||
#if defined(__i386__)
|
||||
static __inline__ unsigned long long rdtsc()
|
||||
{
|
||||
unsigned long long int x;
|
||||
__asm__ volatile ( ".byte 0x0f, 0x31" : "=A" ( x ) );
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
#elif defined(__x86_64__)
|
||||
static __inline__ unsigned long long rdtsc()
|
||||
{
|
||||
unsigned hi, lo;
|
||||
__asm__ __volatile__ ( "rdtsc" : "=a" ( lo ), "=d" ( hi ) );
|
||||
|
||||
return ( (unsigned long long) lo ) | ( ( (unsigned long long) hi ) << 32 );
|
||||
}
|
||||
|
||||
|
||||
#elif defined(__powerpc__)
|
||||
static __inline__ unsigned long long rdtsc()
|
||||
{
|
||||
unsigned long long int result = 0;
|
||||
unsigned long int upper, lower, tmp;
|
||||
__asm__ volatile (
|
||||
"0: \n"
|
||||
"\tmftbu %0 \n"
|
||||
"\tmftb %1 \n"
|
||||
"\tmftbu %2 \n"
|
||||
"\tcmpw %2,%0 \n"
|
||||
"\tbne 0b \n"
|
||||
: "=r" ( upper ), "=r" ( lower ), "=r" ( tmp )
|
||||
);
|
||||
|
||||
result = upper;
|
||||
result = result << 32;
|
||||
result = result | lower;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#endif /* __powerpc__ */
|
||||
|
||||
// Fixme: OS X version
|
||||
/**
|
||||
* Function get_tics
|
||||
* Returns the number of milliseconds that have elapsed since the system was started.
|
||||
* @return uint64_t Number of milliseconds.
|
||||
*/
|
||||
static inline uint64_t get_tics()
|
||||
{
|
||||
#if defined(__linux__)
|
||||
struct timezone tz = { 0, 0 };
|
||||
struct timeval tv;
|
||||
gettimeofday( &tv, &tz );
|
||||
|
||||
return (uint64_t) tv.tv_sec * 1000000ULL + (uint64_t) tv.tv_usec;
|
||||
#elif defined _WIN32 || defined _WIN64
|
||||
// TODO to be tested
|
||||
return GetTickCount();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Structure for storing data related to profiling counters.
|
||||
*/
|
||||
struct prof_counter
|
||||
{
|
||||
uint64_t value; /// Stored timer value
|
||||
bool use_rdtsc; /// Method of time measuring (rdtsc or tics)
|
||||
};
|
||||
|
||||
/**
|
||||
* Function prof_start
|
||||
* Begins code execution time counting for a given profiling counter.
|
||||
* @param cnt is the counter which should be started.
|
||||
* @param use_rdtsc tells if processor's time-stamp counter should be used for time counting.
|
||||
* Otherwise is system tics method will be used.
|
||||
*/
|
||||
static inline void prof_start( prof_counter* cnt, bool use_rdtsc )
|
||||
{
|
||||
cnt->use_rdtsc = use_rdtsc;
|
||||
|
||||
if( use_rdtsc )
|
||||
{
|
||||
cnt->value = rdtsc();
|
||||
}
|
||||
else
|
||||
{
|
||||
cnt->value = get_tics();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function prof_stop
|
||||
* Ends code execution time counting for a given profiling counter.
|
||||
* @param cnt is the counter which should be stopped.
|
||||
*/
|
||||
static inline void prof_end( prof_counter* cnt )
|
||||
{
|
||||
if( cnt->use_rdtsc )
|
||||
cnt->value = rdtsc() - cnt->value;
|
||||
else
|
||||
cnt->value = get_tics() - cnt->value;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,486 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <base_struct.h>
|
||||
#include <layers_id_colors_and_visibility.h>
|
||||
|
||||
#include <view/view.h>
|
||||
#include <view/view_rtree.h>
|
||||
#include <gal/definitions.h>
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
#include <painter.h>
|
||||
|
||||
#include <profile.h>
|
||||
|
||||
using namespace KiGfx;
|
||||
|
||||
const unsigned int VIEW::VIEW_MAX_LAYERS = 64;
|
||||
|
||||
void VIEW::AddLayer( int aLayer, bool aDisplayOnly )
|
||||
{
|
||||
if( m_layers.find( aLayer ) == m_layers.end() )
|
||||
{
|
||||
m_layers[aLayer] = VIEW_LAYER();
|
||||
m_layers[aLayer].id = aLayer;
|
||||
m_layers[aLayer].items = new VIEW_RTREE();
|
||||
m_layers[aLayer].renderingOrder = aLayer;
|
||||
m_layers[aLayer].enabled = true;
|
||||
m_layers[aLayer].isDirty = false;
|
||||
m_layers[aLayer].displayOnly = aDisplayOnly;
|
||||
}
|
||||
|
||||
sortLayers();
|
||||
}
|
||||
|
||||
|
||||
void VIEW::Add( VIEW_ITEM* aItem )
|
||||
{
|
||||
int layers[VIEW_MAX_LAYERS], layers_count;
|
||||
|
||||
aItem->ViewGetLayers( layers, layers_count );
|
||||
|
||||
for( int i = 0; i < layers_count; i++ )
|
||||
{
|
||||
VIEW_LAYER* l = &m_layers[layers[i]];
|
||||
l->items->Insert( aItem );
|
||||
l->dirtyExtents.Merge( aItem->ViewBBox() );
|
||||
}
|
||||
|
||||
if( m_dynamic )
|
||||
aItem->viewAssign( this );
|
||||
}
|
||||
|
||||
|
||||
void VIEW::Remove( VIEW_ITEM* aItem )
|
||||
{
|
||||
if( m_dynamic )
|
||||
aItem->m_view = NULL;
|
||||
|
||||
// fixme: this is so sloooow!
|
||||
for( LayerMapIter i = m_layers.begin(); i != m_layers.end(); ++i )
|
||||
{
|
||||
VIEW_LAYER* l = & ( ( *i ).second );
|
||||
l->items->Remove( aItem );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// stupid C++... python lamda would do this in one line
|
||||
template <class Container>
|
||||
struct queryVisitor
|
||||
{
|
||||
typedef typename Container::value_type item_type;
|
||||
|
||||
queryVisitor( Container& aCont, int aLayer ) :
|
||||
m_cont( aCont ), m_layer( aLayer )
|
||||
{
|
||||
}
|
||||
|
||||
void operator()( VIEW_ITEM* aItem )
|
||||
{
|
||||
if( aItem->ViewIsVisible() )
|
||||
m_cont.push_back( VIEW::LayerItemPair( aItem, m_layer ) );
|
||||
}
|
||||
|
||||
Container& m_cont;
|
||||
int m_layer;
|
||||
};
|
||||
|
||||
|
||||
int VIEW::Query( const BOX2I& aRect, std::vector<LayerItemPair>& aResult )
|
||||
{
|
||||
if( m_orderedLayers.empty() )
|
||||
return 0;
|
||||
|
||||
std::vector<VIEW_LAYER*>::reverse_iterator i;
|
||||
|
||||
// execute queries in reverse direction, so that items that are on the top of
|
||||
// the rendering stack are returned first.
|
||||
for( i = m_orderedLayers.rbegin(); i != m_orderedLayers.rend(); ++i )
|
||||
{
|
||||
// ignore layers that do not contain actual items (i.e. the selection box, menus, floats)
|
||||
if( ( *i )->displayOnly )
|
||||
continue;
|
||||
|
||||
queryVisitor<std::vector<LayerItemPair> > visitor( aResult, ( *i )->id );
|
||||
( *i )->items->Query( aRect, visitor );
|
||||
}
|
||||
|
||||
return aResult.size();
|
||||
}
|
||||
|
||||
|
||||
VIEW::VIEW( bool aIsDynamic, bool aUseGroups ) :
|
||||
m_scale ( 1.0 ),
|
||||
m_painter( NULL ),
|
||||
m_gal( NULL ),
|
||||
m_dynamic( aIsDynamic ),
|
||||
m_useGroups( aUseGroups )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
VIEW::~VIEW()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const
|
||||
{
|
||||
MATRIX3x3D matrix = m_gal->GetWorldScreenMatrix().Inverse();
|
||||
|
||||
if( aAbsolute )
|
||||
{
|
||||
return VECTOR2D( matrix * aCoord );
|
||||
}
|
||||
else
|
||||
{
|
||||
return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VECTOR2D VIEW::ToScreen( const VECTOR2D& aCoord, bool aAbsolute ) const
|
||||
{
|
||||
MATRIX3x3D matrix = m_gal->GetWorldScreenMatrix();
|
||||
|
||||
if( aAbsolute )
|
||||
{
|
||||
return VECTOR2D( matrix * aCoord );
|
||||
}
|
||||
else
|
||||
{
|
||||
return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double VIEW::ToScreen( double aCoord, bool aAbsolute ) const
|
||||
{
|
||||
VECTOR2D t( aCoord, 0 );
|
||||
|
||||
return ToScreen( t, aAbsolute ).x;
|
||||
}
|
||||
|
||||
|
||||
void VIEW::CopySettings( const VIEW* aOtherView )
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
|
||||
void VIEW::SetGAL( GAL* aGal )
|
||||
{
|
||||
m_gal = aGal;
|
||||
|
||||
// force the new GAL to display the current viewport.
|
||||
SetCenter( m_center );
|
||||
SetScale( m_scale );
|
||||
}
|
||||
|
||||
|
||||
void VIEW::SetPainter( PAINTER* aPainter )
|
||||
{
|
||||
m_painter = aPainter;
|
||||
}
|
||||
|
||||
|
||||
BOX2D VIEW::GetViewport() const
|
||||
{
|
||||
BOX2D rect;
|
||||
VECTOR2D screenSize = m_gal->GetScreenPixelSize();
|
||||
|
||||
rect.SetOrigin( ToWorld( VECTOR2D( 0, 0 ) ) );
|
||||
rect.SetEnd( ToWorld( screenSize ) );
|
||||
|
||||
return rect.Normalize();
|
||||
}
|
||||
|
||||
|
||||
void VIEW::SetViewport( const BOX2D& aViewport, bool aKeepAspect )
|
||||
{
|
||||
VECTOR2D ssize = ToWorld( m_gal->GetScreenPixelSize(), false );
|
||||
VECTOR2D centre = aViewport.Centre();
|
||||
VECTOR2D vsize = aViewport.GetSize();
|
||||
double zoom = 1.0 / std::min( fabs( vsize.x / ssize.x ), fabs( vsize.y / ssize.y ) );
|
||||
|
||||
SetCenter( centre );
|
||||
SetScale( GetScale() * zoom );
|
||||
}
|
||||
|
||||
|
||||
void VIEW::SetMirror( bool aMirrorX, bool aMirrorY )
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
|
||||
void VIEW::SetScale( double aScale )
|
||||
{
|
||||
SetScale( aScale, m_center );
|
||||
}
|
||||
|
||||
|
||||
void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor )
|
||||
{
|
||||
VECTOR2D a = ToScreen( aAnchor );
|
||||
|
||||
m_gal->SetZoomFactor( aScale );
|
||||
m_gal->ComputeWorldScreenMatrix();
|
||||
|
||||
VECTOR2D delta = ToWorld( a ) - aAnchor;
|
||||
|
||||
SetCenter( m_center - delta );
|
||||
m_scale = aScale;
|
||||
}
|
||||
|
||||
|
||||
void VIEW::SetCenter( const VECTOR2D& aCenter )
|
||||
{
|
||||
m_center = aCenter;
|
||||
m_gal->SetLookAtPoint( m_center );
|
||||
m_gal->ComputeWorldScreenMatrix();
|
||||
}
|
||||
|
||||
|
||||
void VIEW::SetLayerVisible( int aLayer, bool aVisible )
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
|
||||
void VIEW::sortLayers()
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
m_orderedLayers.resize( m_layers.size() );
|
||||
|
||||
for( LayerMapIter i = m_layers.begin(); i != m_layers.end(); ++i )
|
||||
m_orderedLayers[n++] = &i->second;
|
||||
|
||||
sort( m_orderedLayers.begin(), m_orderedLayers.end(), compareRenderingOrder );
|
||||
}
|
||||
|
||||
|
||||
void VIEW::SetLayerOrder( int aLayer, int aRenderingOrder )
|
||||
{
|
||||
m_layers[aLayer].renderingOrder = aRenderingOrder;
|
||||
sortLayers();
|
||||
}
|
||||
|
||||
|
||||
struct VIEW::drawItem
|
||||
{
|
||||
drawItem( VIEW* aView, int aCurrentLayer ) :
|
||||
count( 0 ), countCached( 0 ), currentLayer( aCurrentLayer ), time( 0 ), view( aView )
|
||||
{
|
||||
}
|
||||
|
||||
void operator()( VIEW_ITEM* aItem )
|
||||
{
|
||||
BOX2I tmp;
|
||||
uint64_t ts = rdtsc();
|
||||
GAL* gal = view->GetGAL();
|
||||
|
||||
if( view->m_useGroups )
|
||||
{
|
||||
int group = aItem->m_cachedGroup;
|
||||
|
||||
if( group >= 0 && aItem->ViewIsVisible() )
|
||||
{
|
||||
gal->DrawGroup( group );
|
||||
countCached++;
|
||||
}
|
||||
else
|
||||
{
|
||||
group = gal->BeginGroup();
|
||||
aItem->m_cachedGroup = group;
|
||||
aItem->ViewDraw( 0, gal, tmp );
|
||||
gal->EndGroup();
|
||||
gal->DrawGroup( group );
|
||||
}
|
||||
}
|
||||
else if( aItem->ViewIsVisible() )
|
||||
{
|
||||
if( !( view->m_painter
|
||||
&& view->m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), currentLayer ) ) )
|
||||
{
|
||||
// Fallback, if there is no painter or painter does not know how to draw aItem
|
||||
aItem->ViewDraw( currentLayer, gal, tmp );
|
||||
}
|
||||
}
|
||||
|
||||
time += rdtsc() - ts;
|
||||
count++;
|
||||
}
|
||||
|
||||
int count;
|
||||
int countCached;
|
||||
int currentLayer;
|
||||
uint64_t time;
|
||||
VIEW* view;
|
||||
};
|
||||
|
||||
void VIEW::redrawRect( const BOX2I& aRect )
|
||||
{
|
||||
int totalItems = 0, totalCached = 0;
|
||||
uint64_t totalDrawTime = 0;
|
||||
prof_counter totalCycles, totalRealTime;
|
||||
|
||||
prof_start( &totalRealTime, false );
|
||||
prof_start( &totalCycles, true );
|
||||
|
||||
BOOST_FOREACH( VIEW_LAYER* l, m_orderedLayers )
|
||||
{
|
||||
drawItem drawFunc( this, l->id );
|
||||
|
||||
m_gal->SetLayerDepth( (double) l->renderingOrder );
|
||||
l->items->Query( aRect, drawFunc );
|
||||
l->isDirty = false;
|
||||
|
||||
totalItems += drawFunc.count;
|
||||
totalDrawTime += drawFunc.time;
|
||||
totalCached += drawFunc.countCached;
|
||||
}
|
||||
|
||||
prof_end( &totalCycles );
|
||||
prof_end( &totalRealTime );
|
||||
|
||||
wxLogDebug( "Redraw::items %d (%d cached), %.1f ms/frame (%.0f FPS), draw/geometry ratio: %.1f%%",
|
||||
totalItems, totalCached, (double) totalRealTime.value / 1000.0,
|
||||
1000000.0 / (double) totalRealTime.value,
|
||||
(double) totalDrawTime / (double) totalCycles.value * 100.0 );
|
||||
}
|
||||
|
||||
|
||||
struct VIEW::unlinkItem
|
||||
{
|
||||
void operator()( VIEW_ITEM* aItem )
|
||||
{
|
||||
aItem->m_view = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void VIEW::Clear()
|
||||
{
|
||||
BOX2I r;
|
||||
|
||||
r.SetMaximum();
|
||||
|
||||
for( LayerMapIter i = m_layers.begin(); i != m_layers.end(); ++i )
|
||||
{
|
||||
VIEW_LAYER* l = &( ( *i ).second );
|
||||
unlinkItem v;
|
||||
if( m_dynamic )
|
||||
l->items->Query( r, v );
|
||||
|
||||
l->items->RemoveAll();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void VIEW::Redraw()
|
||||
{
|
||||
VECTOR2D screenSize = m_gal->GetScreenPixelSize();
|
||||
BOX2I rect( ToWorld( VECTOR2D( 0, 0 ) ),
|
||||
ToWorld( screenSize ) - ToWorld( VECTOR2D( 0, 0 ) ) );
|
||||
|
||||
rect.Normalize();
|
||||
redrawRect( rect );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2D VIEW::GetScreenPixelSize() const
|
||||
{
|
||||
return m_gal->GetScreenPixelSize();
|
||||
}
|
||||
|
||||
|
||||
void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
|
||||
{
|
||||
int layer_indices[VIEW_MAX_LAYERS], layer_count;
|
||||
|
||||
aItem->ViewGetLayers( layer_indices, layer_count );
|
||||
|
||||
for( int i = 0; i < layer_count; i++ )
|
||||
{
|
||||
VIEW_LAYER* l = &m_layers[layer_indices[i]];
|
||||
|
||||
l->dirtyExtents =
|
||||
l->isDirty ? aItem->ViewBBox() : l->dirtyExtents.Merge( aItem->ViewBBox() );
|
||||
|
||||
if( aUpdateFlags & VIEW_ITEM::GEOMETRY )
|
||||
{
|
||||
l->items->Remove( aItem );
|
||||
l->items->Insert( aItem ); /* reinsert */
|
||||
|
||||
if( m_useGroups )
|
||||
aItem->m_cachedGroup = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_useGroups && aItem->m_cachedGroup >= 0 )
|
||||
{
|
||||
m_gal->DeleteGroup( aItem->m_cachedGroup );
|
||||
aItem->m_cachedGroup = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct VIEW::clearItemCache
|
||||
{
|
||||
clearItemCache( VIEW* aView ) :
|
||||
view( aView )
|
||||
{
|
||||
}
|
||||
|
||||
void operator()( VIEW_ITEM* aItem )
|
||||
{
|
||||
if( aItem->m_cachedGroup >= 0 )
|
||||
{
|
||||
view->GetGAL()->DeleteGroup( aItem->m_cachedGroup );
|
||||
aItem->m_cachedGroup = -1;
|
||||
}
|
||||
}
|
||||
|
||||
VIEW* view;
|
||||
};
|
||||
|
||||
|
||||
void VIEW::clearGroupCache()
|
||||
{
|
||||
BOX2I r;
|
||||
|
||||
r.SetMaximum();
|
||||
|
||||
for( LayerMapIter i = m_layers.begin(); i != m_layers.end(); ++i )
|
||||
{
|
||||
VIEW_LAYER* l = & ( ( *i ).second );
|
||||
clearItemCache visitor( this );
|
||||
l->items->Query( r, visitor );
|
||||
};
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <gal/definitions.h>
|
||||
|
||||
#include <view/view_item.h>
|
||||
#include <view/view.h>
|
||||
|
||||
using namespace KiGfx;
|
||||
|
||||
void VIEW_ITEM::ViewSetVisible( bool aIsVisible )
|
||||
{
|
||||
bool update = false;
|
||||
|
||||
if( m_viewVisible != aIsVisible )
|
||||
{
|
||||
update = true;
|
||||
}
|
||||
|
||||
m_viewVisible = aIsVisible;
|
||||
|
||||
// update only if the visibility has really changed
|
||||
if( update )
|
||||
{
|
||||
ViewUpdate( APPEARANCE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VIEW_ITEM::ViewUpdate( int aUpdateFlags, bool aForceImmediateRedraw )
|
||||
{
|
||||
m_view->invalidateItem( this, aUpdateFlags );
|
||||
|
||||
if( aForceImmediateRedraw )
|
||||
{
|
||||
m_view->Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VIEW_ITEM::ViewRelease()
|
||||
{
|
||||
if( m_view && m_view->IsDynamic() )
|
||||
{
|
||||
m_view->Remove( this );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
#include <view/view.h>
|
||||
#include <view/wx_view_controls.h>
|
||||
|
||||
using namespace KiGfx;
|
||||
|
||||
WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel ) :
|
||||
VIEW_CONTROLS( aView ),
|
||||
m_autoPanMargin( 0.1 ),
|
||||
m_autoPanSpeed( 0.15 ),
|
||||
m_autoPanCornerRatio( 0.1 ),
|
||||
m_parentPanel( aParentPanel )
|
||||
{
|
||||
m_parentPanel->Connect( wxEVT_MOTION, wxMouseEventHandler(
|
||||
WX_VIEW_CONTROLS::onMotion ), NULL, this );
|
||||
m_parentPanel->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler(
|
||||
WX_VIEW_CONTROLS::onWheel ), NULL, this );
|
||||
m_parentPanel->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler(
|
||||
WX_VIEW_CONTROLS::onButton ), NULL, this );
|
||||
m_parentPanel->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler(
|
||||
WX_VIEW_CONTROLS::onButton ), NULL, this );
|
||||
}
|
||||
|
||||
|
||||
void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& event )
|
||||
{
|
||||
VECTOR2D mousePoint( event.GetX(), event.GetY() );
|
||||
|
||||
if( event.Dragging() )
|
||||
{
|
||||
if( m_isDragPanning )
|
||||
{
|
||||
VECTOR2D d = m_dragStartPoint - mousePoint;
|
||||
VECTOR2D delta = m_view->ToWorld( d, false );
|
||||
|
||||
m_view->SetCenter( m_lookStartPoint + delta );
|
||||
m_parentPanel->Refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& event )
|
||||
{
|
||||
const double wheelPanSpeed = 0.001;
|
||||
|
||||
if( event.ControlDown() )
|
||||
{
|
||||
wxLongLong timeStamp = wxGetLocalTimeMillis();
|
||||
double timeDiff = timeStamp.ToDouble() - m_timeStamp.ToDouble();
|
||||
|
||||
m_timeStamp = timeStamp;
|
||||
double zoomScale;
|
||||
|
||||
// Set scaling speed depending on scroll wheel event interval
|
||||
if( timeDiff < 500 && timeDiff > 0 )
|
||||
{
|
||||
zoomScale = ( event.GetWheelRotation() > 0.0 ) ? 2.05 - timeDiff / 500 :
|
||||
1.0 / ( 2.05 - timeDiff / 500 );
|
||||
}
|
||||
else
|
||||
{
|
||||
zoomScale = ( event.GetWheelRotation() > 0.0 ) ? 1.05 : 0.95;
|
||||
}
|
||||
|
||||
|
||||
VECTOR2D anchor = m_view->ToWorld( VECTOR2D( event.GetX(), event.GetY() ) );
|
||||
m_view->SetScale( m_view->GetScale() * zoomScale, anchor );
|
||||
m_parentPanel->Refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
VECTOR2D scrollVec = m_view->ToWorld( m_view->GetScreenPixelSize() *
|
||||
( (double) event.GetWheelRotation() * wheelPanSpeed ), false );
|
||||
double scrollSpeed;
|
||||
|
||||
if( abs( scrollVec.x ) > abs( scrollVec.y ) )
|
||||
scrollSpeed = scrollVec.x;
|
||||
else
|
||||
scrollSpeed = scrollVec.y;
|
||||
|
||||
VECTOR2D t = m_view->GetScreenPixelSize();
|
||||
VECTOR2D delta( event.ShiftDown() ? scrollSpeed : 0.0,
|
||||
!event.ShiftDown() ? scrollSpeed : 0.0 );
|
||||
|
||||
m_view->SetCenter( m_view->GetCenter() + delta );
|
||||
m_parentPanel->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WX_VIEW_CONTROLS::onButton( wxMouseEvent& event )
|
||||
{
|
||||
if( event.RightDown() )
|
||||
{
|
||||
m_isDragPanning = true;
|
||||
m_dragStartPoint = VECTOR2D( event.GetX(), event.GetY() );
|
||||
m_lookStartPoint = m_view->GetCenter(); // ookAtPoint();
|
||||
}
|
||||
else if( event.RightUp() )
|
||||
{
|
||||
m_isDragPanning = false;
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
|
@ -39,7 +39,11 @@
|
|||
#include <hotkeys_basic.h>
|
||||
#include <menus_helpers.h>
|
||||
#include <base_units.h>
|
||||
|
||||
#ifdef KICAD_GAL
|
||||
#include <class_drawpanel_gal.h>
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
#include <view/view.h>
|
||||
#endif
|
||||
|
||||
|
||||
void EDA_DRAW_FRAME::RedrawScreen( const wxPoint& aCenterPoint, bool aWarpPointer )
|
||||
|
@ -82,7 +86,10 @@ void EDA_DRAW_FRAME::Zoom_Automatique( bool aWarpPointer )
|
|||
if( screen->m_FirstRedraw )
|
||||
screen->SetCrossHairPosition( screen->GetScrollCenterPosition() );
|
||||
|
||||
RedrawScreen( screen->GetScrollCenterPosition(), aWarpPointer );
|
||||
if( !m_galCanvasActive )
|
||||
RedrawScreen( screen->GetScrollCenterPosition(), aWarpPointer );
|
||||
else
|
||||
m_canvas->Hide();
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,6 +167,36 @@ void EDA_DRAW_FRAME::OnZoom( wxCommandEvent& event )
|
|||
m_canvas->Refresh();
|
||||
break;
|
||||
|
||||
#ifdef KICAD_GAL
|
||||
// Switch canvas between standard and GAL-based
|
||||
case ID_SWITCH_CANVAS:
|
||||
{
|
||||
UseGalCanvas( !m_galCanvasActive );
|
||||
|
||||
KiGfx::VIEW* view = m_galCanvas->GetView();
|
||||
KiGfx::GAL* gal = m_galCanvas->GetGAL();
|
||||
double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor();
|
||||
|
||||
// Display the same view after canvas switching
|
||||
if( m_galCanvasActive )
|
||||
{
|
||||
double zoom = 1 / ( zoomFactor * m_canvas->GetZoom() );
|
||||
view->SetScale( zoom );
|
||||
|
||||
view->SetCenter( VECTOR2D( m_canvas->GetScreenCenterLogicalPosition() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
double zoom = 1 / ( zoomFactor * view->GetScale() );
|
||||
m_canvas->SetZoom( zoom );
|
||||
|
||||
VECTOR2D center = view->GetCenter();
|
||||
RedrawScreen( wxPoint( center.x, center.y ), false );
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ID_POPUP_ZOOM_CENTER:
|
||||
center = screen->GetCrossHairPosition();
|
||||
RedrawScreen( center, true );
|
||||
|
|
|
@ -104,6 +104,13 @@ target_link_libraries(cvpcb
|
|||
${GDI_PLUS_LIBRARIES}
|
||||
)
|
||||
|
||||
if(KICAD_GAL)
|
||||
target_link_libraries(cvpcb
|
||||
gal
|
||||
${GLEW_LIBRARIES}
|
||||
)
|
||||
endif(KICAD_GAL)
|
||||
|
||||
###
|
||||
# Add cvpcb as install target
|
||||
###
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <colors.h>
|
||||
#include <bitmaps.h>
|
||||
#include <richio.h>
|
||||
#include <view/view_item.h>
|
||||
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
|
||||
|
@ -389,7 +390,11 @@ public:
|
|||
* is a base class for most all the KiCad significant classes, used in
|
||||
* schematics and boards.
|
||||
*/
|
||||
#ifdef KICAD_GAL
|
||||
class EDA_ITEM : public KiGfx::VIEW_ITEM
|
||||
#else
|
||||
class EDA_ITEM
|
||||
#endif
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -740,6 +745,12 @@ public:
|
|||
*/
|
||||
virtual EDA_ITEM& operator=( const EDA_ITEM& aItem );
|
||||
|
||||
/// @copydoc VIEW_ITEM::ViewBBox()
|
||||
virtual const BOX2I ViewBBox() const;
|
||||
|
||||
/// @copydoc VIEW_ITEM::ViewGetLayers()
|
||||
virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
/**
|
||||
|
|
|
@ -248,6 +248,9 @@ public:
|
|||
static std::string FormatInternalUnits( const wxPoint& aPoint );
|
||||
|
||||
static std::string FormatInternalUnits( const wxSize& aSize );
|
||||
|
||||
/// @copydoc VIEW_ITEM::ViewGetLayers()
|
||||
virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
|
||||
};
|
||||
|
||||
#endif /* BOARD_ITEM_STRUCT_H */
|
||||
|
|
|
@ -258,6 +258,9 @@ public:
|
|||
void OnCharHook( wxKeyEvent& event );
|
||||
|
||||
void OnPan( wxCommandEvent& event );
|
||||
#ifdef KICAD_GAL
|
||||
void OnSize( wxSizeEvent& event );
|
||||
#endif
|
||||
|
||||
void EraseScreen( wxDC* DC );
|
||||
void OnScrollWin( wxCommandEvent& event );
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file class_drawpanel_gal.h:
|
||||
* @brief EDA_DRAW_PANEL_GAL class definition.
|
||||
*/
|
||||
|
||||
#ifndef PANELGAL_WXSTRUCT_H
|
||||
#define PANELGAL_WXSTRUCT_H
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
#include <math/vector2d.h>
|
||||
|
||||
class BOARD;
|
||||
|
||||
namespace KiGfx
|
||||
{
|
||||
class GAL;
|
||||
class VIEW;
|
||||
class WX_VIEW_CONTROLS;
|
||||
class PAINTER;
|
||||
};
|
||||
|
||||
|
||||
class EDA_DRAW_PANEL_GAL : public wxWindow
|
||||
{
|
||||
public:
|
||||
enum GalType {
|
||||
GAL_TYPE_OPENGL, ///< OpenGL implementation
|
||||
GAL_TYPE_CAIRO, ///< Cairo implementation
|
||||
GAL_TYPE_WXDC ///< WXDC implementation
|
||||
};
|
||||
|
||||
EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId, const wxPoint& aPosition,
|
||||
const wxSize& aSize, GalType aGalType = GAL_TYPE_OPENGL );
|
||||
~EDA_DRAW_PANEL_GAL();
|
||||
|
||||
/**
|
||||
* Function SwitchBackend
|
||||
* Switches method of rendering graphics.
|
||||
* @param aGalType is a type of rendering engine that you want to use.
|
||||
*/
|
||||
void SwitchBackend( GalType aGalType, bool aUseShaders = false );
|
||||
|
||||
/**
|
||||
* Function GetGAL
|
||||
* Returns a pointer to the GAL instance used in the panel.
|
||||
* @return KiGfx::GAL* Instance of GAL.
|
||||
*/
|
||||
KiGfx::GAL* GetGAL() { return m_gal; }
|
||||
|
||||
void SetView( KiGfx::VIEW* aView ) { m_view = aView; }
|
||||
KiGfx::VIEW* GetView() const { return m_view; }
|
||||
|
||||
protected:
|
||||
void onPaint( wxEvent& event );
|
||||
void onSize( wxSizeEvent& aEvent );
|
||||
void onMotion( wxMouseEvent& event );
|
||||
void onButton( wxMouseEvent& event );
|
||||
void onEraseBackground( wxEvent& event );
|
||||
|
||||
KiGfx::GAL* m_gal; ///< Interface for drawing objects on a 2D-surface
|
||||
KiGfx::VIEW* m_view; ///< Stores view settings (scale, center, etc.)
|
||||
///< and items to be drawn
|
||||
KiGfx::PAINTER* m_painter; ///< Contains information about how to draw items
|
||||
///< using GAL
|
||||
KiGfx::WX_VIEW_CONTROLS* m_viewControls; ///< Control for VIEW (moving, zooming, etc.)
|
||||
|
||||
VECTOR2D m_screenSize; ///< Stores current screen size
|
||||
wxWindow* m_parentFrame; ///< Pointer to the parent frame
|
||||
|
||||
std::string m_galShaderPath; ///< Path to shader files, used in OpenGL mode
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,411 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* CairoGal - Graphics Abstraction Layer for Cairo
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef CAIROGAL_H_
|
||||
#define CAIROGAL_H_
|
||||
|
||||
#include <map>
|
||||
#include <iterator>
|
||||
|
||||
#include <cairo.h>
|
||||
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
|
||||
|
||||
#if defined(__WXMSW__)
|
||||
#define SCREEN_DEPTH 24
|
||||
#else
|
||||
#if wxCHECK_VERSION( 2, 9, 0 )
|
||||
#define SCREEN_DEPTH wxBITMAP_SCREEN_DEPTH
|
||||
#else
|
||||
#define SCREEN_DEPTH 32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define EXCEPTION_ZERO_CLIENT_RECTANGLE 0
|
||||
#define EXCEPTION_ZERO_CONTEXT 1
|
||||
|
||||
/**
|
||||
* @brief Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
|
||||
*
|
||||
* Quote from Wikipedia:
|
||||
* " Cairo is a software library used to provide a vector graphics-based, device-independent
|
||||
* API for software developers. It is designed to provide primitives for 2-dimensional
|
||||
* drawing across a number of different backends. "
|
||||
* <br>
|
||||
* Cairo offers also backends for Postscript and PDF surfaces. So it can be used for printing
|
||||
* of KiCad graphics surfaces as well.
|
||||
*
|
||||
*/
|
||||
namespace KiGfx
|
||||
{
|
||||
class CAIRO_GAL : public GAL, public wxWindow
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor CAIRO_GAL
|
||||
*
|
||||
* @param aParent is the wxWidgets immediate wxWindow parent of this object.
|
||||
*
|
||||
* @param aMouseListener is the wxEvtHandler that should receive the mouse events,
|
||||
* this can be can be any wxWindow, but is often a wxFrame container.
|
||||
*
|
||||
* @param aPaintListener is the wxEvtHandler that should receive the paint
|
||||
* event. This can be any wxWindow, but is often a derived instance
|
||||
* of this class or a containing wxFrame. The "paint event" here is
|
||||
* a wxCommandEvent holding EVT_GAL_REDRAW, as sent by PostPaint().
|
||||
*
|
||||
* @param aName is the name of this window for use by wxWindow::FindWindowByName()
|
||||
*/
|
||||
CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener = NULL,
|
||||
wxEvtHandler* aPaintListener = NULL, const wxString& aName = wxT("CairoCanvas") );
|
||||
|
||||
virtual ~CAIRO_GAL();
|
||||
|
||||
// ---------------
|
||||
// Drawing methods
|
||||
// ---------------
|
||||
|
||||
/// @copydoc GAL::BeginDrawing()
|
||||
virtual void BeginDrawing() throw (int);
|
||||
|
||||
/// @copydoc GAL::EndDrawing()
|
||||
virtual void EndDrawing();
|
||||
|
||||
/// @copydoc GAL::DrawLine()
|
||||
virtual void DrawLine( VECTOR2D aStartPoint, VECTOR2D aEndPoint );
|
||||
|
||||
/// @copydoc GAL::DrawPolyline()
|
||||
virtual void DrawPolyline( std::deque<VECTOR2D>& aPointList );
|
||||
|
||||
/// @copydoc GAL::DrawCircle()
|
||||
virtual void DrawCircle( VECTOR2D aCenterPoint, double aRadius );
|
||||
|
||||
/// @copydoc GAL::DrawArc()
|
||||
virtual void
|
||||
DrawArc( VECTOR2D aCenterPoint, double aRadius, double aStartAngle, double aEndAngle );
|
||||
|
||||
/// @copydoc GAL::DrawRectangle()
|
||||
virtual void DrawRectangle( VECTOR2D aStartPoint, VECTOR2D aEndPoint );
|
||||
|
||||
/// @copydoc GAL::DrawPolygon()
|
||||
virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList );
|
||||
|
||||
/// @copydoc GAL::DrawCurve()
|
||||
virtual void DrawCurve( VECTOR2D startPoint, VECTOR2D controlPointA, VECTOR2D controlPointB,
|
||||
VECTOR2D endPoint );
|
||||
|
||||
// --------------
|
||||
// Screen methods
|
||||
// --------------
|
||||
|
||||
/// @brief Resizes the canvas.
|
||||
virtual void ResizeScreen ( int aWidth, int aHeight );
|
||||
|
||||
/// @brief Shows/hides the GAL canvas
|
||||
virtual bool Show( bool aShow );
|
||||
|
||||
/// @copydoc GAL::Flush()
|
||||
virtual void Flush();
|
||||
|
||||
/// @copydoc GAL::ClearScreen()
|
||||
virtual void ClearScreen();
|
||||
|
||||
// -----------------
|
||||
// Attribute setting
|
||||
// -----------------
|
||||
|
||||
/// @copydoc GAL::SetIsFill()
|
||||
virtual void SetIsFill( bool aIsFillEnabled );
|
||||
|
||||
/// @copydoc GAL::SetIsStroke()
|
||||
virtual void SetIsStroke( bool aIsStrokeEnabled );
|
||||
|
||||
/// @copydoc GAL::SetFillColor()
|
||||
virtual void SetFillColor( COLOR4D aColor );
|
||||
|
||||
/// @copydoc GAL::SetStrokeColor()
|
||||
virtual void SetStrokeColor( COLOR4D aColor );
|
||||
|
||||
/// @copydoc GAL::GetStrokeColor()
|
||||
COLOR4D GetStrokeColor();
|
||||
|
||||
/// @copydoc GAL::SetBackgroundColor()
|
||||
virtual void SetBackgroundColor( COLOR4D aColor );
|
||||
|
||||
/// @copydoc GAL::SetLineCap()
|
||||
virtual void SetLineCap( LineCap aLineCap );
|
||||
|
||||
/// @copydoc GAL::SetLineJoin()
|
||||
virtual void SetLineJoin( LineJoin aLineJoin );
|
||||
|
||||
/// @copydoc GAL::SetLineWidth()
|
||||
virtual void SetLineWidth( double aLineWidth );
|
||||
|
||||
/// @copydoc GAL::GetLineWidth()
|
||||
double GetLineWidth();
|
||||
|
||||
/// @copydoc GAL::SetLayerDepth()
|
||||
virtual void SetLayerDepth( double aLayerDepth )
|
||||
{
|
||||
super::SetLayerDepth( aLayerDepth );
|
||||
}
|
||||
|
||||
// --------------
|
||||
// Transformation
|
||||
// --------------
|
||||
|
||||
/// @copydoc GAL::Transform()
|
||||
virtual void Transform( MATRIX3x3D aTransformation );
|
||||
|
||||
/// @copydoc GAL::Rotate()
|
||||
virtual void Rotate( double aAngle );
|
||||
|
||||
/// @copydoc GAL::Translate()
|
||||
virtual void Translate( VECTOR2D aTranslation );
|
||||
|
||||
/// @copydoc GAL::Scale()
|
||||
virtual void Scale( VECTOR2D aScale );
|
||||
|
||||
/// @copydoc GAL::Save()
|
||||
virtual void Save();
|
||||
|
||||
/// @copydoc GAL::Restore()
|
||||
virtual void Restore();
|
||||
|
||||
// --------------------------------------------
|
||||
// Group methods
|
||||
// ---------------------------------------------
|
||||
|
||||
/// @copydoc GAL::BeginGroup()
|
||||
virtual int BeginGroup();
|
||||
|
||||
/// @copydoc GAL::EndGroup()
|
||||
virtual void EndGroup();
|
||||
|
||||
/// @copydoc GAL::DrawGroup()
|
||||
virtual void DrawGroup( int aGroupNumber );
|
||||
|
||||
/// @copydoc GAL::DeleteGroup()
|
||||
virtual void DeleteGroup( int aGroupNumber );
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Handling the world <-> screen transformation
|
||||
// --------------------------------------------------------
|
||||
|
||||
/// @copydoc GAL::ComputeWorldScreenMatrix()
|
||||
virtual void ComputeWorldScreenMatrix();
|
||||
|
||||
/// @copydoc GAL::GetWorldScreenMatrix()
|
||||
MATRIX3x3D GetWorldScreenMatrix();
|
||||
|
||||
/// @copydoc GAL::SetWorldScreenMatrix()
|
||||
void SetWorldScreenMatrix( MATRIX3x3D aMatrix );
|
||||
|
||||
/// @copydoc GAL::SetWorldUnitLength()
|
||||
void SetWorldUnitLength( double aWorldUnitLength );
|
||||
|
||||
/// @copydoc GAL::SetScreenDPI()
|
||||
void SetScreenDPI( double aScreenDPI );
|
||||
|
||||
/// @copydoc GAL::SetLookAtPoint()
|
||||
void SetLookAtPoint( VECTOR2D aPoint );
|
||||
|
||||
/// @copydoc GAL::GetLookAtPoint()
|
||||
VECTOR2D GetLookAtPoint();
|
||||
|
||||
/// @copydoc GAL::SetZoomFactor()
|
||||
void SetZoomFactor( double aZoomFactor );
|
||||
|
||||
/// @copydoc GAL::GetZoomFactor()
|
||||
double GetZoomFactor();
|
||||
|
||||
/// @copydoc GAL::SaveScreen()
|
||||
virtual void SaveScreen();
|
||||
|
||||
/// @copydoc GAL::RestoreScreen()
|
||||
virtual void RestoreScreen();
|
||||
|
||||
// -------
|
||||
// Cursor
|
||||
// -------
|
||||
|
||||
/// @copydoc GAL::ComputeCursorToWorld()
|
||||
virtual VECTOR2D ComputeCursorToWorld( VECTOR2D aCursorPosition );
|
||||
|
||||
/// @copydoc GAL::SetIsCursorEnabled()
|
||||
void SetIsCursorEnabled( bool aIsCursorEnabled );
|
||||
|
||||
/// @copydoc GAL::DrawCursor()
|
||||
virtual void DrawCursor( VECTOR2D aCursorPosition );
|
||||
|
||||
/**
|
||||
* Function PostPaint
|
||||
* posts an event to m_paint_listener. A post is used so that the actual drawing
|
||||
* function can use a device context type that is not specific to the wxEVT_PAINT event.
|
||||
*/
|
||||
void PostPaint()
|
||||
{
|
||||
if( paintListener )
|
||||
{
|
||||
wxCommandEvent redrawEvent( EVT_GAL_REDRAW );
|
||||
wxPostEvent( paintListener, redrawEvent );
|
||||
}
|
||||
}
|
||||
|
||||
void SetMouseListener( wxEvtHandler* aMouseListener )
|
||||
{
|
||||
mouseListener = aMouseListener;
|
||||
}
|
||||
|
||||
void SetPaintListener( wxEvtHandler* aPaintListener )
|
||||
{
|
||||
paintListener = aPaintListener;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void DrawGridLine(VECTOR2D aStartPoint, VECTOR2D aEndPoint);
|
||||
|
||||
private:
|
||||
/// Super class definition
|
||||
typedef GAL super;
|
||||
|
||||
// Variables related to wxWidgets
|
||||
wxWindow* parentWindow; ///< Parent window
|
||||
wxEvtHandler* mouseListener; ///< Mouse listener
|
||||
wxEvtHandler* paintListener; ///< Paint listener
|
||||
wxRect clientRectangle; ///< Area definition of the surface
|
||||
unsigned int bufferSize; ///< Size of buffers cairoOutput, bitmapBuffers
|
||||
unsigned char* wxOutput; ///< wxImage comaptible buffer
|
||||
|
||||
// Cursor variables
|
||||
std::deque<wxColour> savedCursorPixels; ///< Saved pixels of the cursor
|
||||
bool isDeleteSavedPixels; ///< True, if the saved pixels can be discarded
|
||||
wxPoint savedCursorPosition; ///< The last cursor position
|
||||
wxBitmap* cursorPixels; ///< Cursor pixels
|
||||
wxBitmap* cursorPixelsSaved; ///< Saved cursor pixels
|
||||
int cursorSize; ///< Cursor size
|
||||
|
||||
// Variables for the grouping function
|
||||
int actualGroupIndex; ///< The index of the actual group
|
||||
bool isGrouping; ///< Is grouping enabled ?
|
||||
bool isElementAdded; ///< Was an graphic element added ?
|
||||
std::deque<cairo_path_t*> pathList; ///< List of stored paths
|
||||
|
||||
/// Maximum number of arguments for one command
|
||||
static const int MAX_CAIRO_ARGUMENTS = 6;
|
||||
|
||||
/// Definitions for the command recorder
|
||||
enum GraphicsCommand
|
||||
{
|
||||
CMD_SET_FILL, ///< Enable/disable filling
|
||||
CMD_SET_STROKE, ///< Enable/disable stroking
|
||||
CMD_SET_FILLCOLOR, ///< Set the fill color
|
||||
CMD_SET_STROKECOLOR, ///< Set the stroke color
|
||||
CMD_SET_LINE_WIDTH, ///< Set the line width
|
||||
CMD_SET_LINE_CAP, ///< Set the line cap style
|
||||
CMD_SET_LINE_JOIN, ///< Set the line join style
|
||||
CMD_STROKE_PATH, ///< Set the stroke path
|
||||
CMD_FILL_PATH, ///< Set the fill path
|
||||
CMD_TRANSFORM, ///< Transform the actual context
|
||||
CMD_ROTATE, ///< Rotate the context
|
||||
CMD_TRANSLATE, ///< Translate the context
|
||||
CMD_SCALE, ///< Scale the context
|
||||
CMD_SAVE, ///< Save the transformation matrix
|
||||
CMD_RESTORE, ///< Restore the transformation matrix
|
||||
CMD_CALL_GROUP ///< Call a group
|
||||
};
|
||||
|
||||
/// Type definition for an graphics group element
|
||||
typedef struct
|
||||
{
|
||||
GraphicsCommand command; ///< Command to execute
|
||||
double arguments[MAX_CAIRO_ARGUMENTS]; ///< Arguments for Cairo commands
|
||||
bool boolArgument; ///< A bool argument
|
||||
int intArgument; ///< An int argument
|
||||
cairo_path_t* cairoPath; ///< Pointer to a Cairo path
|
||||
} GroupElement;
|
||||
|
||||
typedef std::deque<GroupElement> Group; ///< A graphic group type definition
|
||||
std::deque<Group> groups; ///< List of graphic groups
|
||||
|
||||
// Variables related to Cairo <-> wxWidgets
|
||||
cairo_matrix_t cairoWorldScreenMatrix; ///< Cairo world to screen transformation matrix
|
||||
cairo_t* cairoImage; ///< Cairo image
|
||||
cairo_surface_t* cairoSurface; ///< Cairo surface
|
||||
unsigned int* bitmapBuffer; ///< Storage of the cairo image
|
||||
unsigned int* bitmapBufferBackup; ///< Backup storage of the cairo image
|
||||
wxBitmap* wxBitmap_; ///< Pointer to the wxWidgets bitmap
|
||||
int stride; ///< Stride value for Cairo
|
||||
// wxClientDC* clientDC; ///< Pointer to the clientDC
|
||||
int screenSizeY; ///< Vertical size of the actual surface
|
||||
|
||||
// Mapping between Cairo and GAL line attributes
|
||||
std::map<LineCap, cairo_line_cap_t> lineCapMap; ///< Line cap style mapping
|
||||
std::map<LineJoin, cairo_line_join_t> lineJoinMap; ///< Line join style mapping
|
||||
|
||||
// Methods
|
||||
void storePath(); ///< Store the actual path
|
||||
|
||||
// Event handlers
|
||||
/**
|
||||
* @brief Paint event handler.
|
||||
*
|
||||
* @param aEvent is the paint event.
|
||||
*/
|
||||
void onPaint( wxPaintEvent& aEvent );
|
||||
void onEraseBackground( wxEraseEvent& aEvent );
|
||||
|
||||
/**
|
||||
* @brief Window resizing event handler.
|
||||
*
|
||||
* @param aEvent is the resizing event.
|
||||
*/
|
||||
void onSize( wxSizeEvent& aEvent );
|
||||
|
||||
/**
|
||||
* @brief Mouse event handler, forwards the event to the child.
|
||||
*
|
||||
* @param aEvent is the mouse event to be forwarded.
|
||||
*/
|
||||
void skipMouseEvent( wxMouseEvent& aEvent );
|
||||
|
||||
/**
|
||||
* @brief Initialize the cursor.
|
||||
*
|
||||
* @param aCursorSize is the size of the cursor.
|
||||
*/
|
||||
void initCursor( int aCursorSize );
|
||||
|
||||
/// Allocate the bitmaps for drawing
|
||||
void allocateBitmaps();
|
||||
|
||||
/// Allocate the bitmaps for drawing
|
||||
void deleteBitmaps();
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif // CAIROGAL_H_
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Macro definitions
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef DEFINITIONS_H_
|
||||
#define DEFINITIONS_H_
|
||||
|
||||
/// Swap the variables if a condition is met.
|
||||
#define SWAP( varA, condition, varB ) if( varA condition varB ) { double tmp = varA; varA = varB; \
|
||||
varB = tmp; }
|
||||
|
||||
#endif /* DEFINITIONS_H_ */
|
|
@ -0,0 +1,694 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Graphics Abstraction Layer (GAL) - base class
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef GRAPHICSABSTRACTIONLAYER_H_
|
||||
#define GRAPHICSABSTRACTIONLAYER_H_
|
||||
|
||||
#include <deque>
|
||||
#include <stack>
|
||||
|
||||
#include <wx/event.h>
|
||||
|
||||
#include <math/matrix3x3.h>
|
||||
#include <gal/color4d.h>
|
||||
|
||||
|
||||
namespace KiGfx
|
||||
{
|
||||
// Event declaration
|
||||
extern const wxEventType EVT_GAL_REDRAW;
|
||||
|
||||
/**
|
||||
* LineCap: Type definition of the line end point style
|
||||
*/
|
||||
enum LineCap
|
||||
{
|
||||
LINE_CAP_BUTT, ///< Stop line at the end point
|
||||
LINE_CAP_ROUND, ///< Draw a circle at the end point
|
||||
LINE_CAP_SQUARED ///< Draw a square at the end point
|
||||
};
|
||||
|
||||
/**
|
||||
* LineJoin: Type definition of the line joint style
|
||||
*/
|
||||
enum LineJoin
|
||||
{
|
||||
LINE_JOIN_MITER, ///< Use sharp corners
|
||||
LINE_JOIN_ROUND, ///< Insert a circle at the joints
|
||||
LINE_JOIN_BEVEL ///< Diagonal corner
|
||||
};
|
||||
|
||||
/**
|
||||
* GridStyle: Type definition of the grid style
|
||||
*/
|
||||
enum GridStyle
|
||||
{
|
||||
GRID_STYLE_LINES, ///< Use lines for the grid
|
||||
GRID_STYLE_DOTS ///< Use dots for the grid
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Class GAL is the abstract interface for drawing on a 2D-surface.
|
||||
*
|
||||
* The functions are optimized for drawing shapes of an EDA-program such as KiCad. Most methods
|
||||
* are abstract and need to be implemented by a lower layer, for example by a cairo or OpenGL implementation.
|
||||
* <br>
|
||||
* Almost all methods use world coordinates as arguments. The board design is defined in world space units;
|
||||
* for drawing purposes these are transformed to screen units with this layer. So zooming is handled here as well.
|
||||
*
|
||||
*/
|
||||
class GAL
|
||||
{
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
GAL();
|
||||
virtual ~GAL();
|
||||
|
||||
// ---------------
|
||||
// Drawing methods
|
||||
// ---------------
|
||||
|
||||
/// @brief Begin the drawing, needs to be called for every new frame.
|
||||
virtual void BeginDrawing() = 0;
|
||||
|
||||
/// @brief End the drawing, needs to be called for every new frame.
|
||||
virtual void EndDrawing() = 0;
|
||||
|
||||
/**
|
||||
* @brief Draw a line.
|
||||
*
|
||||
* Start and end points are defined as 2D-Vectors.
|
||||
*
|
||||
* @param aStartPoint is the start point of the line.
|
||||
* @param aEndPoint is the end point of the line.
|
||||
*/
|
||||
virtual void DrawLine( VECTOR2D aStartPoint, VECTOR2D aEndPoint ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Draw a polyline
|
||||
*
|
||||
* @param aPointList is a list of 2D-Vectors containing the polyline points.
|
||||
*/
|
||||
virtual void DrawPolyline( std::deque<VECTOR2D>& aPointList ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Draw a circle using world coordinates.
|
||||
*
|
||||
* @param aCenterPoint is the center point of the circle.
|
||||
* @param aRadius is the radius of the circle.
|
||||
*/
|
||||
virtual void DrawCircle( VECTOR2D aCenterPoint, double aRadius ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Draw an arc.
|
||||
*
|
||||
* @param aCenterPoint is the center point of the arc.
|
||||
* @param aRadius is the arc radius.
|
||||
* @param aStartAngle is the start angle of the arc.
|
||||
* @param aEndAngle is the end angle of the arc.
|
||||
*/
|
||||
virtual void
|
||||
DrawArc( VECTOR2D aCenterPoint, double aRadius, double aStartAngle, double aEndAngle ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Draw a rectangle.
|
||||
*
|
||||
* @param aStartPoint is the start point of the rectangle.
|
||||
* @param aEndPoint is the end point of the rectangle.
|
||||
*/
|
||||
virtual void DrawRectangle( VECTOR2D aStartPoint, VECTOR2D aEndPoint ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Draw a polygon.
|
||||
*
|
||||
* @param aPointList is the list of the polygon points.
|
||||
*/
|
||||
virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Draw a cubic bezier spline.
|
||||
*
|
||||
* @param startPoint is the start point of the spline.
|
||||
* @param controlPointA is the first control point.
|
||||
* @param controlPointB is the second control point.
|
||||
* @param endPoint is the end point of the spline.
|
||||
*/
|
||||
virtual void DrawCurve( VECTOR2D startPoint, VECTOR2D controlPointA,
|
||||
VECTOR2D controlPointB, VECTOR2D endPoint ) = 0;
|
||||
|
||||
// --------------
|
||||
// Screen methods
|
||||
// --------------
|
||||
|
||||
/// @brief Resizes the canvas.
|
||||
virtual void ResizeScreen( int aWidth, int aHeight ) = 0;
|
||||
|
||||
/// @brief Shows/hides the GAL canvas
|
||||
virtual bool Show( bool aShow ) = 0;
|
||||
|
||||
/// @brief Returns GAL canvas size in pixels
|
||||
VECTOR2D GetScreenPixelSize() const
|
||||
{
|
||||
return screenSize;
|
||||
}
|
||||
|
||||
/// @brief Force all remaining objects to be drawn.
|
||||
virtual void Flush() = 0;
|
||||
|
||||
/// @brief Clear the screen.
|
||||
virtual void ClearScreen() = 0;
|
||||
|
||||
// -----------------
|
||||
// Attribute setting
|
||||
// -----------------
|
||||
|
||||
/**
|
||||
* @brief Enable/disable fill.
|
||||
*
|
||||
* @param aIsFillEnabled is true, when the graphics objects should be filled, else false.
|
||||
*/
|
||||
inline virtual void SetIsFill( bool aIsFillEnabled )
|
||||
{
|
||||
isFillEnabled = aIsFillEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable/disable stroked outlines.
|
||||
*
|
||||
* @param aIsStrokeEnabled is true, if the outline of an object should be stroked.
|
||||
*/
|
||||
inline virtual void SetIsStroke( bool aIsStrokeEnabled )
|
||||
{
|
||||
isStrokeEnabled = aIsStrokeEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the fill color.
|
||||
*
|
||||
* @param aColor is the color for filling.
|
||||
*/
|
||||
inline virtual void SetFillColor( COLOR4D aColor )
|
||||
{
|
||||
fillColor = aColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the stroke color.
|
||||
*
|
||||
* @param aColor is the color for stroking the outline.
|
||||
*/
|
||||
inline virtual void SetStrokeColor( COLOR4D aColor )
|
||||
{
|
||||
strokeColor = aColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the stroke color.
|
||||
*
|
||||
* @return the color for stroking the outline.
|
||||
*/
|
||||
inline COLOR4D GetStrokeColor()
|
||||
{
|
||||
return strokeColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the background color.
|
||||
*
|
||||
* @param aColor is the color for background filling.
|
||||
*/
|
||||
virtual void SetBackgroundColor( COLOR4D aColor ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Set the style of the line caps.
|
||||
*
|
||||
* @param aLineCap is the line cap style.
|
||||
*/
|
||||
inline virtual void SetLineCap( LineCap aLineCap )
|
||||
{
|
||||
lineCap = aLineCap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the line join style.
|
||||
*
|
||||
* @param aLineJoin is the line join style.
|
||||
*/
|
||||
inline virtual void SetLineJoin( LineJoin aLineJoin )
|
||||
{
|
||||
lineJoin = aLineJoin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the line width.
|
||||
*
|
||||
* @param aLineWidth is the line width.
|
||||
*/
|
||||
inline virtual void SetLineWidth( double aLineWidth )
|
||||
{
|
||||
lineWidth = aLineWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the line width.
|
||||
*
|
||||
* @return the actual line width.
|
||||
*/
|
||||
inline double GetLineWidth()
|
||||
{
|
||||
return lineWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the depth of the layer (position on the z-axis)
|
||||
*
|
||||
* @param aLayerDepth the layer depth for the objects.
|
||||
*/
|
||||
inline virtual void SetLayerDepth( double aLayerDepth )
|
||||
{
|
||||
layerDepth = aLayerDepth;
|
||||
}
|
||||
|
||||
// --------------
|
||||
// Transformation
|
||||
// --------------
|
||||
|
||||
/**
|
||||
* @brief Transform the context.
|
||||
*
|
||||
* @param aTransformation is the ransformation matrix.
|
||||
*/
|
||||
virtual void Transform( MATRIX3x3D aTransformation ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Rotate the context.
|
||||
*
|
||||
* @param aAngle is the rotation angle in radians.
|
||||
*/
|
||||
virtual void Rotate( double aAngle ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Translate the context.
|
||||
*
|
||||
* @param aTranslation is the translation vector.
|
||||
*/
|
||||
virtual void Translate( VECTOR2D aTranslation ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Scale the context.
|
||||
*
|
||||
* @param aScale is the scale factor for the x- and y-axis.
|
||||
*/
|
||||
virtual void Scale( VECTOR2D aScale ) = 0;
|
||||
|
||||
/// @brief Save the context.
|
||||
virtual void Save() = 0;
|
||||
|
||||
/// @brief Restore the context.
|
||||
virtual void Restore() = 0;
|
||||
|
||||
// --------------------------------------------
|
||||
// Group methods
|
||||
// ---------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Begin a group.
|
||||
*
|
||||
* A group is a collection of graphic items.
|
||||
* Hierarchical groups are possible, attributes and transformations can be used.
|
||||
*
|
||||
* @return the number of the group.
|
||||
*/
|
||||
virtual int BeginGroup() = 0;
|
||||
|
||||
/// @brief End the group.
|
||||
virtual void EndGroup() = 0;
|
||||
|
||||
/**
|
||||
* @brief Draw the stored group.
|
||||
*
|
||||
* @param aGroupNumber is the group number.
|
||||
*/
|
||||
virtual void DrawGroup( int aGroupNumber ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Delete the group from the memory.
|
||||
*
|
||||
* @param aGroupNumber is the group number.
|
||||
*/
|
||||
virtual void DeleteGroup( int aGroupNumber ) = 0;
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Handling the world <-> screen transformation
|
||||
// --------------------------------------------------------
|
||||
|
||||
/// @brief Compute the world <-> screen transformation matrix
|
||||
virtual void ComputeWorldScreenMatrix() = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the world <-> screen transformation matrix.
|
||||
*
|
||||
* @return the transformation matrix.
|
||||
*/
|
||||
MATRIX3x3D GetWorldScreenMatrix()
|
||||
{
|
||||
return worldScreenMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the world <-> screen transformation matrix.
|
||||
*
|
||||
* @param aMatrix is the 3x3 world <-> screen transformation matrix.
|
||||
*/
|
||||
inline void SetWorldScreenMatrix( const MATRIX3x3D& aMatrix )
|
||||
{
|
||||
worldScreenMatrix = aMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the unit length.
|
||||
*
|
||||
* This defines the length [inch] per one integer. For instance a value 0.001 means
|
||||
* that the coordinate [1000, 1000] corresponds with a point at (1 inch, 1 inch) or
|
||||
* 1 mil resolution per integer.
|
||||
*
|
||||
* @param aWorldUnitLength is the world Unit length.
|
||||
*/
|
||||
inline void SetWorldUnitLength( double aWorldUnitLength )
|
||||
{
|
||||
worldUnitLength = aWorldUnitLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the dots per inch of the screen.
|
||||
*
|
||||
* This value depends on the user screen, it should be configurable by the application.
|
||||
* For instance a typical notebook with HD+ resolution (1600x900) has 106 DPI.
|
||||
*
|
||||
* @param aScreenDPI are the screen DPI.
|
||||
*/
|
||||
inline void SetScreenDPI( double aScreenDPI )
|
||||
{
|
||||
screenDPI = aScreenDPI;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Point in world space to look at.
|
||||
*
|
||||
* This point corresponds with the center of the actual drawing area.
|
||||
*
|
||||
* @param aPoint is the look at point (center of the actual drawing area).
|
||||
*/
|
||||
inline void SetLookAtPoint( const VECTOR2D& aPoint )
|
||||
{
|
||||
lookAtPoint = aPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the look at point.
|
||||
*
|
||||
* @return the look at point.
|
||||
*/
|
||||
inline VECTOR2D GetLookAtPoint()
|
||||
{
|
||||
return lookAtPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the zoom factor of the scene.
|
||||
*
|
||||
* @param aZoomFactor is the zoom factor.
|
||||
*/
|
||||
inline void SetZoomFactor( double aZoomFactor )
|
||||
{
|
||||
zoomFactor = aZoomFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the zoom factor
|
||||
*
|
||||
* @return the zoom factor.
|
||||
*/
|
||||
inline double GetZoomFactor()
|
||||
{
|
||||
return zoomFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the range of the layer depth.
|
||||
*
|
||||
* Usually required for the OpenGL implementation, any object outside this range is not drawn.
|
||||
*
|
||||
* @param aDepthRange is the depth range where component x is the near clipping plane and y
|
||||
* is the far clipping plane.
|
||||
*/
|
||||
inline void SetDepthRange( VECTOR2D aDepthRange )
|
||||
{
|
||||
depthRange = aDepthRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the world scale.
|
||||
*
|
||||
* @return the actual world scale factor.
|
||||
*/
|
||||
inline double GetWorldScale()
|
||||
{
|
||||
return worldScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Save the screen contents.
|
||||
*/
|
||||
virtual void SaveScreen() = 0;
|
||||
|
||||
/**
|
||||
* @brief Save the screen contents.
|
||||
*/
|
||||
virtual void RestoreScreen() = 0;
|
||||
|
||||
// -------------
|
||||
// Grid methods
|
||||
// -------------
|
||||
|
||||
/**
|
||||
* @brief Set the origin point for the grid.
|
||||
*
|
||||
* @param aGridOrigin is a vector containing the grid origin point, in world coordinates.
|
||||
*/
|
||||
inline void SetGridOrigin( const VECTOR2D& aGridOrigin )
|
||||
{
|
||||
gridOrigin = aGridOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the screen size of the grid origin marker
|
||||
*
|
||||
* @param aSize is the radius of the origin marker, in pixels.
|
||||
*/
|
||||
inline void SetGridOriginMarkerSize( int aSize )
|
||||
{
|
||||
gridOriginMarkerSize = aSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the threshold for grid drawing.
|
||||
*
|
||||
* @param aThreshold is the minimum grid cell size (in pixels) for which the grid is drawn.
|
||||
*/
|
||||
inline void SetGridDrawThreshold( int aThreshold )
|
||||
{
|
||||
gridDrawThreshold = aThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the grid size.
|
||||
*
|
||||
* @param aGridSize is a vector containing the grid size in x- and y direction.
|
||||
*/
|
||||
inline void SetGridSize( const VECTOR2D& aGridSize )
|
||||
{
|
||||
gridSize = aGridSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the grid color.
|
||||
*
|
||||
* @param aGridColor is the grid color, it should have a low alpha value for the best effect.
|
||||
*/
|
||||
inline void SetGridColor( COLOR4D aGridColor )
|
||||
{
|
||||
gridColor = aGridColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draw every tick line wider.
|
||||
*
|
||||
* @param aInterval increase the width of every aInterval line, if 0 do not use this feature.
|
||||
*/
|
||||
inline void SetCoarseGrid( int aInterval )
|
||||
{
|
||||
gridTick = aInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the grid line width.
|
||||
*
|
||||
* @return the grid line width
|
||||
*/
|
||||
inline double GetGridLineWidth()
|
||||
{
|
||||
return gridLineWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the grid line width.
|
||||
*
|
||||
* @param aGridLineWidth is the rid line width.
|
||||
*/
|
||||
inline void SetGridLineWidth( double aGridLineWidth )
|
||||
{
|
||||
gridLineWidth = aGridLineWidth;
|
||||
}
|
||||
|
||||
/// @brief Draw the grid
|
||||
void DrawGrid();
|
||||
|
||||
// TODO Not yet implemented
|
||||
// virtual void SetGridStyle(GridStyle gridStyle);
|
||||
|
||||
// -------
|
||||
// Cursor
|
||||
// -------
|
||||
|
||||
/**
|
||||
* @brief Compute the cursor position in world coordinates from given screen coordinates.
|
||||
*
|
||||
* @param aCursorPosition is the cursor position in screen coordinates.
|
||||
* @return the cursor position in world coordinates.
|
||||
*/
|
||||
virtual VECTOR2D ComputeCursorToWorld( VECTOR2D aCursorPosition ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Enable/Disable cursor.
|
||||
*
|
||||
* @param aIsCursorEnabled is true if the cursor should be enabled, else false.
|
||||
*/
|
||||
inline void SetIsCursorEnabled( bool aIsCursorEnabled )
|
||||
{
|
||||
isCursorEnabled = aIsCursorEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the cursor color.
|
||||
*
|
||||
* @param aCursorColor is the color of the cursor.
|
||||
*/
|
||||
inline void SetCursorColor( COLOR4D aCursorColor )
|
||||
{
|
||||
cursorColor = aCursorColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draw the cursor.
|
||||
*
|
||||
* @param aCursorPosition is the cursor position in screen coordinates.
|
||||
*/
|
||||
virtual void DrawCursor( VECTOR2D aCursorPosition ) = 0;
|
||||
|
||||
void AdvanceDepth()
|
||||
{
|
||||
layerDepth -= 0.1; // fixme: there should be a minimum step
|
||||
}
|
||||
|
||||
void PushDepth()
|
||||
{
|
||||
depthStack.push( layerDepth );
|
||||
}
|
||||
|
||||
void PopDepth()
|
||||
{
|
||||
layerDepth = depthStack.top();
|
||||
depthStack.pop();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::stack<double> depthStack; ///< Stored depth values
|
||||
VECTOR2D screenSize; ///< Screen size in screen coordinates
|
||||
|
||||
double worldUnitLength; ///< The unit length of the world coordinates [inch]
|
||||
double screenDPI; ///< The dots per inch of the screen
|
||||
VECTOR2D lookAtPoint; ///< Point to be looked at in world space
|
||||
|
||||
double zoomFactor; ///< The zoom factor
|
||||
MATRIX3x3D worldScreenMatrix; ///< World transformation
|
||||
double worldScale; ///< The scale factor world->screen
|
||||
|
||||
double lineWidth; ///< The line width
|
||||
LineCap lineCap; ///< Line end style
|
||||
LineJoin lineJoin; ///< Style of the line joints
|
||||
|
||||
bool isFillEnabled; ///< Is filling of graphic objects enabled ?
|
||||
bool isStrokeEnabled; ///< Are the outlines stroked ?
|
||||
bool isSetAttributes; ///< True, if the attributes have been set
|
||||
|
||||
COLOR4D backgroundColor; ///< The background color
|
||||
COLOR4D fillColor; ///< The fill color
|
||||
COLOR4D strokeColor; ///< The color of the outlines
|
||||
|
||||
double layerDepth; ///< The actual layer depth
|
||||
VECTOR2D depthRange; ///< Range of the depth
|
||||
|
||||
VECTOR2D gridSize; ///< The grid size
|
||||
VECTOR2D gridOrigin; ///< The grid origin
|
||||
COLOR4D gridColor; ///< Color of the grid
|
||||
int gridTick; ///< Every tick line gets the double width
|
||||
double gridLineWidth; ///< Line width of the grid
|
||||
int gridDrawThreshold; ///< Minimum screen size of the grid (pixels)
|
||||
///< below which the grid is not drawn
|
||||
int gridOriginMarkerSize; ///< Grid origin indicator size (pixels)
|
||||
|
||||
bool isCursorEnabled; ///< Is the cursor enabled?
|
||||
VECTOR2D cursorPosition; ///< The cursor position
|
||||
COLOR4D cursorColor; ///< Cursor color
|
||||
|
||||
/// Compute the scaling factor for the world->screen matrix
|
||||
inline void ComputeWorldScale()
|
||||
{
|
||||
worldScale = screenDPI * worldUnitLength * zoomFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Draw a grid line (usually a simplified line function).
|
||||
*
|
||||
* @param aStartPoint is the start point of the line.
|
||||
* @param aEndPoint is the end point of the line.
|
||||
*/
|
||||
virtual void DrawGridLine( VECTOR2D aStartPoint, VECTOR2D aEndPoint ) = 0;
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif /* GRAPHICSABSTRACTIONLAYER_H_ */
|
|
@ -0,0 +1,547 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Graphics Abstraction Layer (GAL) for OpenGL
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef OPENGLGAL_H_
|
||||
#define OPENGLGAL_H_
|
||||
|
||||
// GAL imports
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
#include <GL/glew.h>
|
||||
|
||||
// wxWidgets imports
|
||||
#include <wx/wx.h>
|
||||
#include <wx/glcanvas.h>
|
||||
|
||||
// STL imports
|
||||
#include <cmath>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define D(x) x
|
||||
#else
|
||||
#define D(x)
|
||||
#endif
|
||||
|
||||
namespace KiGfx
|
||||
{
|
||||
class SHADER;
|
||||
|
||||
/**
|
||||
* @brief Class OpenGL_GAL is the OpenGL implementation of the Graphics Abstraction Layer.
|
||||
*
|
||||
* This is a direct OpenGL-implementation and uses low-level graphics primitives like triangles
|
||||
* and quads. The purpuse is to provide a fast graphics interface, that takes advantage of modern
|
||||
* graphics card GPUs. All methods here benefit thus from the hardware acceleration.
|
||||
*/
|
||||
class OPENGL_GAL : public GAL, public wxGLCanvas
|
||||
{
|
||||
public:
|
||||
|
||||
/// Current drawing mode
|
||||
enum DrawMode {
|
||||
DRAW_MODE_NORMAL, ///< Normal drawing mode
|
||||
DRAW_MODE_PREPARE_EDGES, ///< Prepare the object edges
|
||||
DRAW_MODE_DRAW_EDGES ///< Draw anti-aliased object edges
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor OPENGL_GAL
|
||||
*
|
||||
* @param aParent is the wxWidgets immediate wxWindow parent of this object.
|
||||
*
|
||||
* @param aMouseListener is the wxEvtHandler that should receive the mouse events,
|
||||
* this can be can be any wxWindow, but is often a wxFrame container.
|
||||
*
|
||||
* @param aPaintListener is the wxEvtHandler that should receive the paint
|
||||
* event. This can be any wxWindow, but is often a derived instance
|
||||
* of this class or a containing wxFrame. The "paint event" here is
|
||||
* a wxCommandEvent holding EVT_GAL_REDRAW, as sent by PostPaint().
|
||||
*
|
||||
* @param aName is the name of this window for use by wxWindow::FindWindowByName()
|
||||
*
|
||||
* @param isUseShaders is a flag, that indicates, if shaders should be used
|
||||
* for higher quality rendering.
|
||||
*
|
||||
*/
|
||||
OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener = NULL,
|
||||
wxEvtHandler* aPaintListener = NULL, bool isUseShaders = false,
|
||||
const wxString& aName = wxT("GLCanvas") );
|
||||
|
||||
virtual ~OPENGL_GAL();
|
||||
|
||||
// ---------------
|
||||
// Drawing methods
|
||||
// ---------------
|
||||
|
||||
/// @copydoc GAL::BeginDrawing()
|
||||
virtual void BeginDrawing();
|
||||
|
||||
/// @copydoc GAL::EndDrawing()
|
||||
virtual void EndDrawing();
|
||||
|
||||
/// @copydoc GAL::DrawLine()
|
||||
virtual void DrawLine( VECTOR2D aStartPoint, VECTOR2D aEndPoint );
|
||||
|
||||
/// @copydoc GAL::DrawPolyline()
|
||||
virtual void DrawPolyline( std::deque<VECTOR2D>& aPointList );
|
||||
|
||||
/// @copydoc GAL::DrawCircle()
|
||||
virtual void DrawCircle( VECTOR2D aCenterPoint, double aRadius );
|
||||
|
||||
/// @copydoc GAL::DrawArc()
|
||||
virtual void
|
||||
DrawArc( VECTOR2D aCenterPoint, double aRadius, double aStartAngle, double aEndAngle );
|
||||
|
||||
/// @copydoc GAL::DrawRectangle()
|
||||
virtual void DrawRectangle( VECTOR2D aStartPoint, VECTOR2D aEndPoint );
|
||||
|
||||
/// @copydoc GAL::DrawPolygon()
|
||||
virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList );
|
||||
|
||||
/// @copydoc GAL::DrawCurve()
|
||||
virtual void DrawCurve( VECTOR2D startPoint, VECTOR2D controlPointA, VECTOR2D controlPointB,
|
||||
VECTOR2D endPoint );
|
||||
|
||||
// --------------
|
||||
// Screen methods
|
||||
// --------------
|
||||
|
||||
/// @brief Resizes the canvas.
|
||||
virtual void ResizeScreen ( int aWidth, int aHeight );
|
||||
|
||||
/// @brief Shows/hides the GAL canvas
|
||||
virtual bool Show( bool aShow );
|
||||
|
||||
/// @copydoc GAL::Flush()
|
||||
virtual void Flush();
|
||||
|
||||
/// @copydoc GAL::ClearScreen()
|
||||
virtual void ClearScreen();
|
||||
|
||||
// -----------------
|
||||
// Attribute setting
|
||||
// -----------------
|
||||
|
||||
/// @copydoc GAL::SetIsFill()
|
||||
virtual void SetIsFill( bool aIsFillEnabled )
|
||||
{
|
||||
isFillEnabled = aIsFillEnabled;
|
||||
}
|
||||
|
||||
/// @copydoc GAL::SetIsStroke()
|
||||
virtual void SetIsStroke( bool aIsStrokeEnabled )
|
||||
{
|
||||
isStrokeEnabled = aIsStrokeEnabled;
|
||||
}
|
||||
|
||||
/// @copydoc GAL::SetFillColor()
|
||||
virtual void SetFillColor( COLOR4D aColor );
|
||||
|
||||
/// @copydoc GAL::SetStrokeColor()
|
||||
virtual void SetStrokeColor( COLOR4D aColor );
|
||||
|
||||
/// @copydoc GAL::GetStrokeColor()
|
||||
COLOR4D GetStrokeColor();
|
||||
|
||||
/// @copydoc GAL::SetBackgroundColor()
|
||||
virtual void SetBackgroundColor( COLOR4D aColor );
|
||||
|
||||
/// @copydoc GAL::SetLineCap()
|
||||
virtual void SetLineCap( LineCap aLineCap )
|
||||
{
|
||||
lineCap = aLineCap;
|
||||
}
|
||||
|
||||
/// @copydoc GAL::SetLineJoin()
|
||||
virtual void SetLineJoin( LineJoin aLineJoin )
|
||||
{
|
||||
lineJoin = aLineJoin;
|
||||
}
|
||||
|
||||
/// @copydoc GAL::SetLineWidth()
|
||||
virtual void SetLineWidth( double aLineWidth );
|
||||
|
||||
/// @copydoc GAL::GetLineWidth()
|
||||
double GetLineWidth();
|
||||
|
||||
/// @copydoc GAL::SetLayerDepth()
|
||||
virtual void SetLayerDepth( double aLayerDepth ){
|
||||
super::SetLayerDepth( aLayerDepth );
|
||||
}
|
||||
|
||||
// --------------
|
||||
// Transformation
|
||||
// --------------
|
||||
|
||||
/// @copydoc GAL::Transform()
|
||||
virtual void Transform( MATRIX3x3D aTransformation );
|
||||
|
||||
/// @copydoc GAL::Rotate()
|
||||
virtual void Rotate( double aAngle );
|
||||
|
||||
/// @copydoc GAL::Translate()
|
||||
virtual void Translate( VECTOR2D aTranslation );
|
||||
|
||||
/// @copydoc GAL::Scale()
|
||||
virtual void Scale( VECTOR2D aScale );
|
||||
|
||||
/// @copydoc GAL::Save()
|
||||
virtual void Save();
|
||||
|
||||
/// @copydoc GAL::Restore()
|
||||
virtual void Restore();
|
||||
|
||||
// --------------------------------------------
|
||||
// Group methods
|
||||
// ---------------------------------------------
|
||||
|
||||
/// @copydoc GAL::BeginGroup()
|
||||
virtual int BeginGroup();
|
||||
|
||||
/// @copydoc GAL::EndGroup()
|
||||
virtual void EndGroup();
|
||||
|
||||
/// @copydoc GAL::DrawGroup()
|
||||
virtual void DrawGroup( int aGroupNumber );
|
||||
|
||||
/// @copydoc GAL::DeleteGroup()
|
||||
virtual void DeleteGroup( int aGroupNumber );
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Handling the world <-> screen transformation
|
||||
// --------------------------------------------------------
|
||||
|
||||
/// @copydoc GAL::ComputeWorldScreenMatrix()
|
||||
virtual void ComputeWorldScreenMatrix();
|
||||
|
||||
/// @copydoc GAL::GetWorldScreenMatrix()
|
||||
MATRIX3x3D GetWorldScreenMatrix();
|
||||
|
||||
/// @copydoc GAL::SetWorldScreenMatrix()
|
||||
void SetWorldScreenMatrix( MATRIX3x3D aMatrix );
|
||||
|
||||
/// @copydoc GAL::SetWorldUnitLength()
|
||||
void SetWorldUnitLength( double aWorldUnitLength );
|
||||
|
||||
/// @copydoc GAL::SetScreenDPI()
|
||||
void SetScreenDPI( double aScreenDPI );
|
||||
|
||||
/// @copydoc GAL::SetLookAtPoint()
|
||||
void SetLookAtPoint( VECTOR2D aPoint );
|
||||
|
||||
/// @copydoc GAL::GetLookAtPoint()
|
||||
VECTOR2D GetLookAtPoint();
|
||||
|
||||
/// @copydoc GAL::SetZoomFactor()
|
||||
void SetZoomFactor( double aZoomFactor );
|
||||
|
||||
/// @copydoc GAL::GetZoomFactor()
|
||||
double GetZoomFactor();
|
||||
|
||||
/// @copydoc GAL::SaveScreen()
|
||||
virtual void SaveScreen();
|
||||
|
||||
/// @copydoc GAL::RestoreScreen()
|
||||
virtual void RestoreScreen();
|
||||
|
||||
// -------
|
||||
// Cursor
|
||||
// -------
|
||||
|
||||
/// @copydoc GAL::ComputeCursorToWorld()
|
||||
virtual VECTOR2D ComputeCursorToWorld( VECTOR2D aCursorPosition );
|
||||
|
||||
/// @copydoc GAL::SetIsCursorEnabled()
|
||||
void SetIsCursorEnabled( bool aIsCursorEnabled );
|
||||
|
||||
/// @copydoc GAL::DrawCursor()
|
||||
virtual void DrawCursor( VECTOR2D aCursorPosition );
|
||||
|
||||
/**
|
||||
* @brief Function PostPaint
|
||||
* posts an event to m_paint_listener. A post is used so that the actual drawing
|
||||
* function can use a device context type that is not specific to the wxEVT_PAINT event.
|
||||
*/
|
||||
void PostPaint()
|
||||
{
|
||||
if( paintListener )
|
||||
{
|
||||
wxCommandEvent redrawEvent( EVT_GAL_REDRAW );
|
||||
wxPostEvent( paintListener, redrawEvent );
|
||||
}
|
||||
}
|
||||
|
||||
void SetMouseListener( wxEvtHandler* aMouseListener )
|
||||
{
|
||||
mouseListener = aMouseListener;
|
||||
}
|
||||
|
||||
void SetPaintListener( wxEvtHandler* aPaintListener )
|
||||
{
|
||||
paintListener = aPaintListener;
|
||||
}
|
||||
|
||||
// Special methods for OpenGL only
|
||||
void SetDrawMode( DrawMode aDrawMode )
|
||||
{
|
||||
m_drawMode = aDrawMode;
|
||||
|
||||
switch( aDrawMode )
|
||||
{
|
||||
case DRAW_MODE_NORMAL:
|
||||
glColorMask( true, true, true, true );
|
||||
glEnable( GL_DEPTH_TEST );
|
||||
glDepthFunc( GL_LESS );
|
||||
break;
|
||||
|
||||
case DRAW_MODE_PREPARE_EDGES:
|
||||
// We just manipulate the Z-buffer in this mode
|
||||
glColorMask( false, false, false, false );
|
||||
glEnable( GL_DEPTH_TEST );
|
||||
glDepthFunc( GL_LESS );
|
||||
// Shift the depth of the edge points a very small value deeper
|
||||
// this way we prevent that overlapping edge points are not drawn twice
|
||||
// and brighter, if we have used transparency.
|
||||
glTranslated( 0, 0, (depthRange.y - depthRange.x) * DEPTH_ADJUST_FACTOR );
|
||||
break;
|
||||
|
||||
case DRAW_MODE_DRAW_EDGES:
|
||||
glColorMask( true, true, true, true );
|
||||
glEnable( GL_DEPTH_TEST );
|
||||
glDepthFunc( GL_LESS );
|
||||
// Restore the shifted position
|
||||
glTranslated( 0, 0, -(depthRange.y - depthRange.x) * DEPTH_ADJUST_FACTOR );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetShaderPath( const std::string& aPath )
|
||||
{
|
||||
shaderPath = aPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current drawing mode.
|
||||
*
|
||||
* @return the current drawing mode.
|
||||
*/
|
||||
DrawMode GetDrawMode()
|
||||
{
|
||||
return m_drawMode;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void DrawGridLine( VECTOR2D aStartPoint, VECTOR2D aEndPoint );
|
||||
|
||||
private:
|
||||
/// Super class definition
|
||||
typedef GAL super;
|
||||
|
||||
DrawMode m_drawMode; ///< Current drawing mode
|
||||
|
||||
static const int CIRCLE_POINTS = 64; ///< The number of points for circle approximation
|
||||
static const int CURVE_POINTS = 32; ///< The number of points for curve approximation
|
||||
static const int SHADER_NUMBER = 2; ///< Number of the used shaders
|
||||
static const double MITER_LIMIT = 1.5; ///< Limit for mitered edges ( * lineWidth )
|
||||
|
||||
/// This factor is used to for correct merging of antialiased edges,
|
||||
/// a very small value is required
|
||||
static const double DEPTH_ADJUST_FACTOR = ( 1.0 / (1 << 23) );
|
||||
|
||||
wxClientDC* clientDC; ///< Drawing context
|
||||
wxGLContext* glContext; ///< OpenGL context of wxWidgets
|
||||
wxWindow* parentWindow; ///< Parent window
|
||||
wxEvtHandler* mouseListener;
|
||||
wxEvtHandler* paintListener;
|
||||
|
||||
// Display lists
|
||||
GLuint displayListsArcs; ///< Arc display list
|
||||
GLuint displayListCircle; ///< Circle display list
|
||||
GLuint displayListSemiCircle; ///< Semi circle display list
|
||||
std::deque<GLuint> displayListsGroup; ///< List of display lists used for groups
|
||||
|
||||
double curvePoints[12]; ///< Coefficients for curves
|
||||
std::deque<VECTOR2D> unitCirclePoints; ///< List of the points on a unit circle
|
||||
|
||||
// Polygon tesselation
|
||||
GLUtesselator* tesselator; ///< Pointer to the tesselator
|
||||
|
||||
// Shader
|
||||
std::deque<SHADER> shaderList; ///< List of the shaders
|
||||
|
||||
// Cursor
|
||||
int cursorSize; ///< Size of the cursor in pixels
|
||||
GLubyte* cursorShape; ///< Cursor pixel storage
|
||||
GLubyte* cursorSave; ///< Saved cursor pixels
|
||||
bool isDeleteSavedPixels; ///< Flag for deleting saved pixels
|
||||
VECTOR2D savedCursorPosition; ///< Last saved cursor position
|
||||
|
||||
// Frame buffer
|
||||
GLuint frameBuffer; ///< Main FBO handle
|
||||
GLuint depthBuffer; ///< Depth buffer handle
|
||||
GLuint texture; ///< Main texture handle
|
||||
GLuint frameBufferBackup; ///< Backup FBO handle
|
||||
GLuint depthBufferBackup; ///< Backup depth buffer handle
|
||||
GLuint textureBackup; ///< Backup texture handle
|
||||
|
||||
// Internal flags
|
||||
bool isCreated;
|
||||
bool isGlewInitialized; ///< Is GLEW initialized?
|
||||
bool isFrameBufferInitialized; ///< Are the frame buffers initialized?
|
||||
bool isShaderInitialized; ///< Was the shader initialized?
|
||||
bool isShaderEnabled; ///< Are the shaders enabled?
|
||||
bool isUseShader; ///< Should the shaders be used?
|
||||
bool isGroupStarted; ///< Was a group started?
|
||||
int currentShader; ///< ID of the shader currently in use
|
||||
std::string shaderPath;
|
||||
|
||||
/**
|
||||
* @brief Draw a semi circle (used for line caps).
|
||||
*
|
||||
* @param aCenterPoint is the center point.
|
||||
* @param aRadius is the radius of the semi-circle.
|
||||
* @param aAngle is the angle of the semi-circle.
|
||||
* @param ADepthOffset is the relative depth of the semi-circle.
|
||||
*
|
||||
*/
|
||||
void drawSemiCircle( VECTOR2D aCenterPoint, double aRadius, double aAngle,
|
||||
double aDepthOffset );
|
||||
|
||||
/// Compute the points of a unit circle.
|
||||
void computeUnitCircle();
|
||||
|
||||
/// Compute the points of a unit semi circle.
|
||||
void computeUnitSemiCircle();
|
||||
|
||||
/// Compute the points of a unit arc.
|
||||
void computeUnitArcs();
|
||||
|
||||
// Event handling
|
||||
/**
|
||||
* @brief This is the window creation event handler.
|
||||
*
|
||||
* @param aEvent is the window creation event.
|
||||
*/
|
||||
void onCreate( wxWindowCreateEvent& aEvent );
|
||||
|
||||
/**
|
||||
* @brief This is the OnPaint event handler.
|
||||
*
|
||||
* @param aEvent is the OnPaint event.
|
||||
*/
|
||||
void onPaint( wxPaintEvent& aEvent );
|
||||
|
||||
/**
|
||||
* @brief Window resizing event handler.
|
||||
*
|
||||
* @param aEvent is the window resizing event.
|
||||
*/
|
||||
void onSize( wxSizeEvent& aEvent );
|
||||
|
||||
/**
|
||||
* @brief Skip the mouse event to the parent.
|
||||
*
|
||||
* @param aEvent is the mouse event.
|
||||
*/
|
||||
void skipMouseEvent( wxMouseEvent& aEvent );
|
||||
|
||||
/// Initialize GLEW.
|
||||
void initGlew();
|
||||
|
||||
/**
|
||||
* @brief Initialize the cursor.
|
||||
*
|
||||
* @param aCursorSize is the cursor size in pixels (screen coordinates).
|
||||
*/
|
||||
void initCursor( int aCursorSize );
|
||||
|
||||
/**
|
||||
* @brief Blit the main texture to the screen.
|
||||
*
|
||||
* @param aIsClearFrameBuffer if true, the frame buffer is cleared as well.
|
||||
*
|
||||
*/
|
||||
void blitMainTexture( bool aIsClearFrameBuffer );
|
||||
|
||||
/// @brief Initialize the frame buffers for main contents and backup storage.
|
||||
void initFrameBuffers();
|
||||
|
||||
/**
|
||||
* @brief Generate a frame buffer for the screen contents.
|
||||
*
|
||||
* @param aFrameBuffer is the pointer to the frame buffer handle.
|
||||
* @param aDepthBuffer is the pointer to the depth buffer handle.
|
||||
* @param aTexture is the pointer to the texture handle.
|
||||
*/
|
||||
void generateFrameBuffer( GLuint* aFrameBuffer, GLuint* aDepthBuffer, GLuint* aTexture );
|
||||
|
||||
/**
|
||||
* @brief Delete the frame buffer for the screen contents.
|
||||
*
|
||||
* @param aFrameBuffer is the pointer to the frame buffer handle.
|
||||
* @param aDepthBuffer is the pointer to the depth buffer handle.
|
||||
* @param aTexture is the pointer to the texture handle.
|
||||
*/
|
||||
void deleteFrameBuffer( GLuint* aFrameBuffer, GLuint* aDepthBuffer, GLuint* aTexture );
|
||||
|
||||
/**
|
||||
* @brief Draw a quad for the line.
|
||||
*
|
||||
* @param aStartPoint is the start point of the line.
|
||||
* @param aEndPoint is the end point of the line.
|
||||
*/
|
||||
inline void drawLineQuad( VECTOR2D aStartPoint, VECTOR2D aEndPoint );
|
||||
|
||||
/**
|
||||
* @brief Draw the line cap
|
||||
*
|
||||
* @param aStartPoint is the start point of the line.
|
||||
* @param aEndPoint is the end point of the line.
|
||||
* @param aDepthOffset is the relative depth of the line cap.
|
||||
*/
|
||||
inline void drawLineCap( VECTOR2D aStartPoint, VECTOR2D aEndPoint, double aDepthOffset );
|
||||
|
||||
inline void selectShader( int aIndex );
|
||||
|
||||
/// @copydoc GAL::DrawRoundedSegment()
|
||||
void drawRoundedSegment( VECTOR2D aStartPoint, VECTOR2D aEndPoint, double aWidth,
|
||||
bool aStroke = false, bool aGlBegin = false );
|
||||
|
||||
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif // OPENGLGAL_H_
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Graphics Abstraction Layer (GAL) for OpenGL
|
||||
*
|
||||
* Shader class
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef SHADER_H_
|
||||
#define SHADER_H_
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <string>
|
||||
#include <deque>
|
||||
|
||||
namespace KiGfx
|
||||
{
|
||||
class OPENGL_GAL;
|
||||
|
||||
/// Type definition for the shader
|
||||
enum ShaderType
|
||||
{
|
||||
SHADER_TYPE_VERTEX = GL_VERTEX_SHADER, ///< Vertex shader
|
||||
SHADER_TYPE_FRAGMENT = GL_FRAGMENT_SHADER, ///< Fragment shader
|
||||
SHADER_TYPE_GEOMETRY = GL_GEOMETRY_SHADER ///< Geometry shader
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Class SHADER provides the access to the OpenGL shaders.
|
||||
*
|
||||
* The purpose of this class is advanced drawing with OpenGL. One example is using the pixel
|
||||
* shader for drawing exact circles or for anti-aliasing. This class supports vertex, geometry
|
||||
* and fragment shaders.
|
||||
* <br>
|
||||
* Make sure that the hardware supports these features. This can be identified with the "GLEW"
|
||||
* library.
|
||||
*/
|
||||
class SHADER
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
SHADER();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~SHADER();
|
||||
|
||||
/**
|
||||
* @brief Add a shader and compile the shader sources.
|
||||
*
|
||||
* @param aShaderSourceName is the shader source file name.
|
||||
* @param aShaderType is the type of the shader.
|
||||
*/
|
||||
void AddSource( std::string aShaderSourceName, ShaderType aShaderType );
|
||||
|
||||
/**
|
||||
* Link the shaders.
|
||||
*/
|
||||
void Link();
|
||||
|
||||
/**
|
||||
* Use the shader.
|
||||
*/
|
||||
void Use();
|
||||
|
||||
/**
|
||||
* @brief Deactivate the shader and use the default OpenGL program.
|
||||
*/
|
||||
void Deactivate();
|
||||
|
||||
/**
|
||||
* @brief Configure the geometry shader - has to be done before linking!
|
||||
*
|
||||
* @param maxVertices is the maximum of vertices to be generated.
|
||||
* @param geometryInputType is the input type [e.g. GL_LINES, GL_TRIANGLES, GL_QUADS etc.]
|
||||
* @param geometryOutputType is the output type [e.g. GL_LINES, GL_TRIANGLES, GL_QUADS etc.]
|
||||
*/
|
||||
void ConfigureGeometryShader( GLuint maxVertices, GLuint geometryInputType,
|
||||
GLuint geometryOutputType );
|
||||
|
||||
/**
|
||||
* @brief Add a parameter to the parameter queue.
|
||||
*
|
||||
* To communicate with the shader use this function to set up the names for the uniform
|
||||
* variables. These are queued in a list and can be assigned with the SetParameter(..)
|
||||
* method using the queue position.
|
||||
*
|
||||
* @param aParameterName is the name of the parameter.
|
||||
*/
|
||||
void AddParameter( std::string aParameterName );
|
||||
|
||||
/**
|
||||
* @brief Set a parameter of the shader.
|
||||
*
|
||||
* @param aParameterNumber is the number of the parameter.
|
||||
* @param aValue is the value of the parameter.
|
||||
*/
|
||||
void SetParameter( int aParameterNumber, float aValue );
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Get the shader program information.
|
||||
*
|
||||
* @param aProgram is the program number.
|
||||
*/
|
||||
void ProgramInfo( GLuint aProgram );
|
||||
|
||||
/**
|
||||
* @brief Read the shader source file
|
||||
*
|
||||
* @param aShaderSourceName is the shader source file name.
|
||||
* @return the source as string
|
||||
*/
|
||||
std::string ReadSource( std::string aShaderSourceName );
|
||||
|
||||
std::deque<GLuint> shaderNumbers; ///< Shader number list
|
||||
GLuint programNumber; ///< Shader program number
|
||||
bool isProgramCreated; ///< Flag for program creation
|
||||
bool isShaderLinked; ///< Is the shader linked?
|
||||
GLuint maximumVertices; ///< The maximum of vertices to be generated
|
||||
GLuint geomInputType; ///< Input type [e.g. GL_LINES, GL_TRIANGLES, GL_QUADS etc.]
|
||||
GLuint geomOutputType; ///< Output type [e.g. GL_LINES, GL_TRIANGLES, GL_QUADS etc.]
|
||||
std::deque<GLint> parameterLocation; ///< Location of the parameter
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif /* SHADER_H_ */
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* Stroke font class
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef STROKE_FONT_H_
|
||||
#define STROKE_FONT_H_
|
||||
|
||||
#include <string>
|
||||
#include <deque>
|
||||
|
||||
#include <eda_text.h>
|
||||
|
||||
#include <math/box2.h>
|
||||
|
||||
namespace KiGfx
|
||||
{
|
||||
class GAL;
|
||||
|
||||
typedef std::deque< std::deque<VECTOR2D> > Glyph;
|
||||
typedef std::deque<Glyph> GlyphList;
|
||||
|
||||
/**
|
||||
* @brief Class STROKE_FONT implements stroke font drawing.
|
||||
*
|
||||
* A stroke font is composed of lines.
|
||||
*/
|
||||
class STROKE_FONT
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
STROKE_FONT( GAL* aGal );
|
||||
|
||||
/// Destructor
|
||||
~STROKE_FONT();
|
||||
|
||||
// TODO Load font from a text file
|
||||
|
||||
/**
|
||||
* @brief Load the new stroke font.
|
||||
*
|
||||
* @param aNewStrokeFont is the pointer to the font data.
|
||||
* @param aNewStrokeFontSize is the size of the font data.
|
||||
* @return True, if the font was successfully loaded, else false.
|
||||
*/
|
||||
bool LoadNewStrokeFont( const char* const aNewStrokeFont[], int aNewStrokeFontSize );
|
||||
|
||||
/**
|
||||
* @brief Load attributes of a given text, in order to be used during drawing.
|
||||
*
|
||||
* @param aText is the text string.
|
||||
*/
|
||||
void LoadAttributes( const EDA_TEXT* aText );
|
||||
|
||||
/**
|
||||
* @brief Draw a string.
|
||||
*
|
||||
* @param aText is the text to be drawn.
|
||||
* @param aPosition is the text position in world coordinates.
|
||||
* @param aRotationAngle is the text rotation angle.
|
||||
*/
|
||||
void Draw( std::string aText, VECTOR2D aPosition, double aRotationAngle );
|
||||
|
||||
/**
|
||||
* @brief Set the scale factor of the font for the glyph size.
|
||||
*
|
||||
* @param aScaleFactor is the scale factor of the font.
|
||||
*/
|
||||
inline void SetScaleFactor( const double aScaleFactor )
|
||||
{
|
||||
m_scaleFactor = aScaleFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the glyph size.
|
||||
*
|
||||
* @param aGlyphSize is the glyph size.
|
||||
*/
|
||||
inline void SetGlyphSize( const VECTOR2D aGlyphSize )
|
||||
{
|
||||
m_glyphSize = aGlyphSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set a bold property of current font.
|
||||
*
|
||||
* @param aBold tells if the font should be bold or not.
|
||||
*/
|
||||
inline void SetBold( const bool aBold )
|
||||
{
|
||||
m_bold = aBold;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set an italic property of current font.
|
||||
*
|
||||
* @param aItalic tells if the font should be italic or not.
|
||||
*/
|
||||
inline void SetItalic( const bool aItalic )
|
||||
{
|
||||
m_italic = aItalic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set a mirrored property of text.
|
||||
*
|
||||
* @param aMirrored tells if the text should be mirrored or not.
|
||||
*/
|
||||
inline void SetMirrored( const bool aMirrored )
|
||||
{
|
||||
m_mirrored = aMirrored;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the horizontal justify for text drawing.
|
||||
*
|
||||
* @param aHorizontalJustify is the horizontal justify value.
|
||||
*/
|
||||
inline void SetHorizontalJustify( const EDA_TEXT_HJUSTIFY_T aHorizontalJustify )
|
||||
{
|
||||
m_horizontalJustify = aHorizontalJustify;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the vertical justify for text drawing.
|
||||
*
|
||||
* @param aVerticalJustify is the vertical justify value.
|
||||
*/
|
||||
inline void SetVerticalJustify( const EDA_TEXT_VJUSTIFY_T aVerticalJustify )
|
||||
{
|
||||
m_verticalJustify = aVerticalJustify;
|
||||
}
|
||||
|
||||
private:
|
||||
GAL* m_gal; ///< Pointer to the GAL
|
||||
|
||||
GlyphList m_glyphs; ///< Glyph list
|
||||
std::deque<BOX2D> m_glyphBoundingBoxes; ///< Bounding boxes of the glyphs
|
||||
double m_scaleFactor; ///< Scale factor for the glyph
|
||||
VECTOR2D m_glyphSize; ///< Size of the glyphs
|
||||
EDA_TEXT_HJUSTIFY_T m_horizontalJustify; ///< Horizontal justification
|
||||
EDA_TEXT_VJUSTIFY_T m_verticalJustify; ///< Vertical justification
|
||||
bool m_bold, m_italic, m_mirrored; ///< Properties of text
|
||||
|
||||
/**
|
||||
* @brief Compute the bounding box of a given glyph.
|
||||
*
|
||||
* @param aGlyph is the glyph.
|
||||
* @param aGlyphBoundingX is the x-component of the bounding box size.
|
||||
* @return is the complete bounding box size.
|
||||
*/
|
||||
BOX2D computeBoundingBox( Glyph aGlyph, VECTOR2D aGlyphBoundingX );
|
||||
|
||||
/**
|
||||
* @brief Compute the size of a given text.
|
||||
*
|
||||
* @param aText is the text string.
|
||||
* @return is the text size.
|
||||
*/
|
||||
VECTOR2D computeTextSize( const std::string aText );
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif /* STROKE_FONT_H_ */
|
|
@ -213,6 +213,7 @@ enum main_id
|
|||
ID_ZOOM_OUT,
|
||||
ID_ZOOM_PAGE,
|
||||
ID_ZOOM_REDRAW,
|
||||
ID_SWITCH_CANVAS,
|
||||
|
||||
/* Panning command event IDs. */
|
||||
ID_PAN_UP,
|
||||
|
|
|
@ -143,9 +143,19 @@ enum PCB_VISIBLE
|
|||
MOD_VALUES_VISIBLE, ///< show modules values (when texts are visibles)
|
||||
MOD_REFERENCES_VISIBLE, ///< show modules references (when texts are visibles)
|
||||
|
||||
TRACKS_VISIBLE,
|
||||
PADS_VISIBLE,
|
||||
VIA_HOLES_VISIBLE,
|
||||
PAD_HOLES_VISIBLE,
|
||||
|
||||
END_PCB_VISIBLE_LIST // sentinel
|
||||
};
|
||||
|
||||
/// macro for obtaining layer number for specific item (eg. pad or text)
|
||||
#define ITEM_GAL_LAYER(layer) (LAYER_COUNT + layer)
|
||||
|
||||
/// number of *all* layers including PCB and item layers
|
||||
#define TOTAL_LAYER_COUNT (LAYER_COUNT + END_PCB_VISIBLE_LIST)
|
||||
|
||||
/**
|
||||
* Function IsValidLayerIndex
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __CLASS_PAINTER_H
|
||||
#define __CLASS_PAINTER_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <gal/color4d.h>
|
||||
#include <colors.h>
|
||||
|
||||
|
||||
class EDA_ITEM;
|
||||
class COLORS_DESIGN_SETTINGS;
|
||||
|
||||
namespace KiGfx
|
||||
{
|
||||
class GAL;
|
||||
class STROKE_FONT;
|
||||
|
||||
/**
|
||||
* Class RENDER_SETTINGS
|
||||
* Contains all the knowledge about how graphical objects are drawn on
|
||||
* any output surface/device. This includes:
|
||||
* - color/transparency settings
|
||||
* - highlighting and high contrast mode control
|
||||
* - drawing quality control (sketch/outline mode)
|
||||
* The class acts as an interface between the PAINTER object and the GUI (i.e. Layers/Items
|
||||
* widget or display options dialog).
|
||||
*
|
||||
* Todo: properties/introspection
|
||||
*/
|
||||
class RENDER_SETTINGS
|
||||
{
|
||||
public:
|
||||
|
||||
RENDER_SETTINGS();
|
||||
virtual ~RENDER_SETTINGS();
|
||||
|
||||
/**
|
||||
* Function Update
|
||||
* Precalculates extra colors for layers (eg. highlighted, darkened and any needed version
|
||||
* of base colors).
|
||||
*/
|
||||
virtual void Update();
|
||||
|
||||
/**
|
||||
* Function ImportLegacyColors
|
||||
* Loads a list of color settings for layers.
|
||||
* @param aSettings is a list of color settings.
|
||||
*/
|
||||
virtual void ImportLegacyColors( COLORS_DESIGN_SETTINGS* aSettings ) = 0;
|
||||
|
||||
/**
|
||||
* Function SetActiveLayer
|
||||
* Sets the specified layer as active - it means that it can be drawn in a specific mode
|
||||
* (eg. highlighted, so it differs from other layers).
|
||||
* @param aLayerId is a layer number that should be displayed in a specific mode.
|
||||
*/
|
||||
void SetActiveLayer( int aLayerId )
|
||||
{
|
||||
m_activeLayer = aLayerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetHighlight
|
||||
* Turns on/off highlighting - it may be done for the active layer or the specified net.
|
||||
* @param aEnabled tells if highlighting should be enabled.
|
||||
* @param aNetCode is optional and if specified, turns on higlighting only for the net with
|
||||
* number given as the parameter.
|
||||
*/
|
||||
void SetHighlight( bool aEnabled, int aNetcode = -1 )
|
||||
{
|
||||
m_highlightEnabled = aEnabled;
|
||||
|
||||
if( aNetcode > 0 )
|
||||
m_highlightNetcode = aNetcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetHighContrast
|
||||
* Turns on/off high contrast display mode.
|
||||
* @param aEnabled determines if high contrast display mode should be enabled or not.
|
||||
*/
|
||||
void SetHighContrast( bool aEnabled )
|
||||
{
|
||||
m_hiContrastEnabled = aEnabled;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
int m_activeLayer; /// Stores active layer number
|
||||
|
||||
/// Parameters for display modes
|
||||
bool m_hiContrastEnabled; /// High contrast display mode on/off
|
||||
COLOR4D m_hiContrastColor; /// Color used for high contrast display mode
|
||||
float m_hiContrastFactor; /// Factor used for computing high contrast color
|
||||
|
||||
bool m_highlightEnabled; /// Highlight display mode on/off
|
||||
int m_highlightNetcode; /// Net number that is displayed in highlight
|
||||
/// -1 means that there is no specific net, and whole active
|
||||
/// layer is highlighted
|
||||
float m_highlightFactor; /// Factor used for computing hightlight color
|
||||
|
||||
COLOR4D m_selectionBorderColor; /// Color of selection box border
|
||||
COLOR4D m_netLabelColor; /// Color of net labels
|
||||
|
||||
float m_selectFactor; /// Specifies how color of selected items is changed
|
||||
float m_layerOpacity; /// Determines opacity of all layers, so every can be seen
|
||||
/// at the same time
|
||||
|
||||
/// Map of colors that were usually used for display
|
||||
std::map<EDA_COLOR_T, COLOR4D> m_legacyColorMap;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class PAINTER
|
||||
* contains all the knowledge about how to draw graphical object onto
|
||||
* any particular output device.
|
||||
* This knowledge is held outside the individual graphical objects so that
|
||||
* alternative output devices may be used, and so that the graphical objects
|
||||
* themselves to not contain drawing routines. Drawing routines in the objects
|
||||
* cause problems with usages of the objects as simple container objects in
|
||||
* DLL/DSOs.
|
||||
* PAINTER is an abstract layer, because every module (pcbnew, eeschema, etc.)
|
||||
* has to draw different kinds of objects.
|
||||
*/
|
||||
class PAINTER
|
||||
{
|
||||
public:
|
||||
|
||||
/*
|
||||
* Constructor PAINTER( GAL* )
|
||||
* initializes this object for painting on any of the polymorphic
|
||||
* GRAPHICS_ABSTRACTION_LAYER* derivatives.
|
||||
*
|
||||
* @param aGal is a pointer to a polymorphic GAL device on which
|
||||
* to draw (i.e. Cairo, OpenGL, wxDC)
|
||||
* No ownership is given to this PAINTER of aGal.
|
||||
*/
|
||||
PAINTER( GAL* aGal );
|
||||
virtual ~PAINTER();
|
||||
|
||||
/**
|
||||
* Function ApplySettings
|
||||
* Loads colors and display modes settings that are going to be used when drawing items.
|
||||
* @param aSettings are settings to be applied.
|
||||
*/
|
||||
virtual void ApplySettings( RENDER_SETTINGS* aSettings )
|
||||
{
|
||||
if( m_settings )
|
||||
delete m_settings;
|
||||
|
||||
m_settings = aSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Draw
|
||||
* Takes an instance of EDA_ITEM and passes it to a function that know how to draw the item.
|
||||
* @param aItem is an item to be drawn.
|
||||
* @param aLayer tells which layer is currently rendered so that draw functions
|
||||
* may know what to draw (eg. for pads there are separate layers for holes, because they
|
||||
* have other dimensions then the pad itself.
|
||||
*/
|
||||
virtual bool Draw( const EDA_ITEM* aItem, int aLayer ) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Function getLayerColor
|
||||
* is used for obtaining color that should be used for specific layer/net
|
||||
* combination using stored color settings.
|
||||
* @param aLayer is the layer number that is being drawn.
|
||||
* @param aNetCode is a number of the net that is being drawn.
|
||||
*/
|
||||
virtual const COLOR4D& getLayerColor( int aLayer, int aNetCode ) const = 0;
|
||||
|
||||
/// Instance of graphic abstraction layer that gives an interface to call
|
||||
/// commands used to draw (eg. DrawLine, DrawCircle, etc.)
|
||||
GAL* m_gal;
|
||||
|
||||
/// Instance of object that stores information about how to draw texts (including different
|
||||
/// font display modes [bold/italic/mirror]).
|
||||
STROKE_FONT* m_stroke_font;
|
||||
|
||||
/// Colors and display modes settings that are going to be used when drawing items.
|
||||
RENDER_SETTINGS* m_settings;
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif /* __CLASS_PAINTER_H */
|
|
@ -0,0 +1,361 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __VIEW_H
|
||||
#define __VIEW_H
|
||||
|
||||
#include <vector>
|
||||
#include <boost/unordered/unordered_map.hpp>
|
||||
|
||||
#include <math/box2.h>
|
||||
|
||||
namespace KiGfx
|
||||
{
|
||||
class PAINTER;
|
||||
class GAL;
|
||||
class VIEW_ITEM;
|
||||
class VIEW_RTREE;
|
||||
|
||||
/**
|
||||
* Class VIEW.
|
||||
* Holds a (potentially large) number of VIEW_ITEMs and renders them on a graphics device
|
||||
* provided by the GAL. VIEWs can exist in two flavors:
|
||||
* - dynamic - where items can be added, removed or changed anytime, intended for the main
|
||||
* editing panel. Each VIEW_ITEM can be added to a single dynamic view.
|
||||
* - static - where items are added once at the startup and are not linked with the VIEW.
|
||||
* Foreseen for preview windows and printing.
|
||||
* Items in a view are grouped in layers (not to be confused with Kicad's PCB layers). Each layer is
|
||||
* identified by an integer number. Visibility and rendering order can be set individually for each
|
||||
* of the layers. Future versions of the VIEW will also allow to assign different layers to different
|
||||
* rendering targets, which will be composited at the final stage by the GAL.
|
||||
* The VIEW class also provides fast methods for finding all visible objects that are within a given
|
||||
* rectangular area, useful for object selection/hit testing.
|
||||
*/
|
||||
class VIEW
|
||||
{
|
||||
public:
|
||||
friend class VIEW_ITEM;
|
||||
|
||||
typedef std::pair<VIEW_ITEM*, int> LayerItemPair;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param aIsDynamic: decides whether we are creating a static or a dynamic VIEW.
|
||||
* @param aUseGroups: fixme
|
||||
*/
|
||||
VIEW( bool aIsDynamic = true, bool aUseGroups = false );
|
||||
|
||||
~VIEW();
|
||||
|
||||
/**
|
||||
* Function Add()
|
||||
* Adds a VIEW_ITEM to the view.
|
||||
* @param aItem: item to be added. No ownership is given
|
||||
*/
|
||||
void Add( VIEW_ITEM* aItem );
|
||||
|
||||
/**
|
||||
* Function Remove()
|
||||
* Removes a VIEW_ITEM from the view.
|
||||
* @param aItem: item to be removed. Caller must dispose the removed item if necessary
|
||||
*/
|
||||
void Remove( VIEW_ITEM* aItem );
|
||||
|
||||
/** Function Query()
|
||||
* Finds all visible items that touch or are within the rectangle aRect.
|
||||
* @param aRect area to search for items
|
||||
* @param aResult result of the search, containing VIEW_ITEMs associated with their layers.
|
||||
* Sorted according to the rendering order (items that are on top of the rendering stack as first).
|
||||
* @return Number of found items.
|
||||
*/
|
||||
int Query( const BOX2I& aRect, std::vector<LayerItemPair>& aResult );
|
||||
|
||||
/**
|
||||
* Function CopySettings()
|
||||
* Copies layers and visibility settings from another view.
|
||||
* @param aOtherView: view from which settings will be copied.
|
||||
*/
|
||||
void CopySettings( const VIEW* aOtherView );
|
||||
|
||||
/*
|
||||
* Convenience wrappers for adding multiple items
|
||||
* template<class T> void AddItems( const T& aItems );
|
||||
* template<class T> void RemoveItems( const T& aItems );
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function SetGAL()
|
||||
* Assigns a rendering device for the VIEW.
|
||||
* @param aGal: pointer to the GAL output device
|
||||
*/
|
||||
void SetGAL( GAL* aGal );
|
||||
|
||||
/**
|
||||
* Function GetGAL()
|
||||
* Returns the GAL this view is using to draw graphical primitives.
|
||||
* @return Pointer to the currently used GAL instance.
|
||||
*/
|
||||
GAL* GetGAL() const { return m_gal; }
|
||||
|
||||
/**
|
||||
* Function SetPainter()
|
||||
* Sets the painter object used by the view for drawing VIEW_ITEMS.
|
||||
*/
|
||||
void SetPainter( PAINTER* aPainter );
|
||||
|
||||
/**
|
||||
* Function GetPainter()
|
||||
* Returns the painter object used by the view for drawing VIEW_ITEMS.
|
||||
* @return Pointer to the currently used Painter instance.
|
||||
*/
|
||||
PAINTER* GetPainter() const { return m_painter; };
|
||||
|
||||
/**
|
||||
* Function SetViewport()
|
||||
* Sets the visible area of the VIEW.
|
||||
* @param aViewport: desired visible area, in world space coordinates.
|
||||
* @param aKeepProportions: when true, the X/Y size proportions are kept.
|
||||
*/
|
||||
void SetViewport( const BOX2D& aViewport, bool aKeepProportions = true );
|
||||
|
||||
/**
|
||||
* Function GetViewport()
|
||||
* Returns the current viewport visible area rectangle.
|
||||
* @return Current viewport rectangle
|
||||
*/
|
||||
BOX2D GetViewport() const;
|
||||
|
||||
/**
|
||||
* Function SetMirror()
|
||||
* Controls the mirroring of the VIEW.
|
||||
* @param aMirrorX: when true, the X axis is mirrored
|
||||
* @param aMirrorY: when true, the Y axis is mirrored.
|
||||
*/
|
||||
void SetMirror( bool aMirrorX, bool aMirrorY );
|
||||
|
||||
/**
|
||||
* Function SetScale()
|
||||
* Sets the scaling factor. Scale = 1 corresponds to the real world size of the objects
|
||||
* (depending on correct GAL unit length & DPI settings).
|
||||
* @param aScale: the scalefactor
|
||||
*/
|
||||
void SetScale( double aScale );
|
||||
|
||||
/**
|
||||
* Function SetScale()
|
||||
* Sets the scaling factor, zooming around a given anchor point.
|
||||
* (depending on correct GAL unit length & DPI settings).
|
||||
* @param aScale: the scale factor
|
||||
*/
|
||||
void SetScale( double aScale, const VECTOR2D& aAnchor );
|
||||
|
||||
/**
|
||||
* Function GetScale()
|
||||
* @return Current scalefactor of this VIEW
|
||||
*/
|
||||
double GetScale() const { return m_scale; }
|
||||
|
||||
/**
|
||||
* Function SetCenter()
|
||||
* Sets the center point of the VIEW (i.e. the point in world space that will be drawn in the middle
|
||||
* of the screen).
|
||||
* @param aCenter: the new center point, in world space coordinates.
|
||||
*/
|
||||
void SetCenter( const VECTOR2D& aCenter );
|
||||
|
||||
/**
|
||||
* Function GetCenter()
|
||||
* Returns the center point of this VIEW (in world space coordinates)
|
||||
* @return center point of the view
|
||||
*/
|
||||
const VECTOR2D& GetCenter() const { return m_center; }
|
||||
|
||||
/**
|
||||
* Function ToWorld()
|
||||
* Converts a screen space point/vector to a point/vector in world space coordinates.
|
||||
* @param aCoord: the point/vector to be converted
|
||||
* @param aAbsolute: when true, aCoord is treated as a point, otherwise - as a direction (vector)
|
||||
*/
|
||||
VECTOR2D ToWorld( const VECTOR2D& aCoord, bool aAbsolute = true ) const;
|
||||
|
||||
/**
|
||||
* Function ToScreen()
|
||||
* Converts a world space point/vector to a point/vector in screen space coordinates.
|
||||
* @param aCoord: the point/vector to be converted
|
||||
* @param aAbsolute: when true, aCoord is treated as a point, otherwise - as a direction (vector)
|
||||
*/
|
||||
VECTOR2D ToScreen( const VECTOR2D& aCoord, bool aAbsolute = true ) const;
|
||||
|
||||
/**
|
||||
* Function ToScreen()
|
||||
* Converts a world space coordinate to a coordinate in screen space coordinates.
|
||||
* @param aCoord: the coordinate to be transformed.
|
||||
* @param aAbsolute: when true, aCoord is treated as a point, otherwise - as a direction (vector)
|
||||
*/
|
||||
double ToScreen( double aCoord, bool aAbsolute = true ) const;
|
||||
|
||||
|
||||
/**
|
||||
* Function GetScreenPixelSize()
|
||||
* Returns the size of the our rendering area, in pixels.
|
||||
* @return viewport screen size
|
||||
*/
|
||||
VECTOR2D GetScreenPixelSize() const;
|
||||
|
||||
/**
|
||||
* Function AddLayer()
|
||||
* Adds a new layer to the view.
|
||||
* @param aLayer: unique ID of the layer to be added.
|
||||
* @param aDisplayOnly: layer is display-only (example: selection boxes, floating hints/menus).
|
||||
* Objects belonging to this layer are not taken into account by Query() method.
|
||||
*/
|
||||
void AddLayer( int aLayer, bool aDisplayOnly = false );
|
||||
|
||||
|
||||
/**
|
||||
* Function ClearLayer()
|
||||
* Removes all items from a given layer.
|
||||
* @param aLayer: ID of the layer to be cleared
|
||||
*/
|
||||
void ClearLayer( int aLayer );
|
||||
|
||||
/**
|
||||
* Function Clear()
|
||||
* Removes all items from the view.
|
||||
*/
|
||||
void Clear();
|
||||
|
||||
/**
|
||||
* Function SetLayerVisible()
|
||||
* Controls the visibility of a particular layer.
|
||||
* @param aLayer: the layer to show/hide. When ALL_LAYERS constant is given, all layers'
|
||||
* visibility is updated
|
||||
* @param aVisible: the obivous
|
||||
*/
|
||||
void SetLayerVisible( int aLayer, bool aVisible = true );
|
||||
|
||||
/**
|
||||
* Function SetLayerOrder()
|
||||
* Sets rendering order of a particular layer.
|
||||
* @param aLayer: the layer
|
||||
* @param aRenderingOrder: arbitrary number denoting the rendering order.
|
||||
* Lower values are rendered first.
|
||||
*/
|
||||
void SetLayerOrder( int aLayer, int aRenderingOrder );
|
||||
|
||||
/**
|
||||
* Function Redraw()
|
||||
* Immediately redraws the whole view.
|
||||
*/
|
||||
void Redraw();
|
||||
|
||||
/**
|
||||
* Function PartialRedraw()
|
||||
* Redraws only the parts of the view that have been affected by items
|
||||
* for which ViewUpdate() function has been called since last redraw.
|
||||
*/
|
||||
void PartialRedraw();
|
||||
|
||||
/**
|
||||
* Function IsDynamic()
|
||||
* Tells if the VIEW is dynamic (ie. can be changed, for example displaying PCBs in a window)
|
||||
* or static (that cannot be modified, eg. displaying image/PDF).
|
||||
*/
|
||||
bool IsDynamic() const { return m_dynamic; }
|
||||
|
||||
static const unsigned int VIEW_MAX_LAYERS; ///* maximum number of layers that may be shown
|
||||
|
||||
private:
|
||||
|
||||
struct VIEW_LAYER
|
||||
{
|
||||
bool enabled; ///* is the layer to be rendered?
|
||||
bool isDirty; ///* does it contain any dirty items (updated since last redraw)
|
||||
bool displayOnly; ///* is the layer display only?
|
||||
VIEW_RTREE* items; ///* R-tree indexing all items on this layer.
|
||||
std::vector<VIEW_ITEM*> dirtyItems; ///* set of dirty items collected since last redraw
|
||||
int renderingOrder; ///* rendering order of this layer
|
||||
int id; ///* layer ID
|
||||
BOX2I extents; ///* sum of bboxes of all items on the layer
|
||||
BOX2I dirtyExtents; ///* sum of bboxes of all dirty items on the layer
|
||||
};
|
||||
|
||||
// Convenience typedefs
|
||||
typedef boost::unordered_map<int, VIEW_LAYER> LayerMap;
|
||||
typedef LayerMap::iterator LayerMapIter;
|
||||
typedef std::vector<VIEW_LAYER*> LayerOrder;
|
||||
typedef std::vector<VIEW_LAYER*>::iterator LayerOrderIter;
|
||||
|
||||
// Function objects that need to access VIEW/VIEW_ITEM private/protected members
|
||||
struct clearItemCache;
|
||||
struct unlinkItem;
|
||||
struct drawItem;
|
||||
|
||||
///* Redraws contents within rect aRect
|
||||
void redrawRect( const BOX2I& aRect );
|
||||
|
||||
///* Manages dirty flags & redraw queueing when updating an item. Called internally
|
||||
/// via VIEW_ITEM::ViewUpdate()
|
||||
void invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags );
|
||||
|
||||
///* Sorts m_orderedLayers when layer rendering order has changed
|
||||
void sortLayers();
|
||||
|
||||
///* Clears cached GAL display lists
|
||||
void clearGroupCache();
|
||||
|
||||
/// Determines rendering order of layers. Used in display order sorting function.
|
||||
static bool compareRenderingOrder( VIEW_LAYER* i, VIEW_LAYER* j )
|
||||
{
|
||||
return i->renderingOrder > j->renderingOrder;
|
||||
};
|
||||
|
||||
/// Contains set of possible displayed layers and its properties
|
||||
LayerMap m_layers;
|
||||
|
||||
/// Sorted list of pointers to members of m_layers.
|
||||
LayerOrder m_orderedLayers;
|
||||
|
||||
/// Center point of the VIEW (the point at which we are looking at)
|
||||
VECTOR2D m_center;
|
||||
|
||||
/// Scale of displayed VIEW_ITEMs
|
||||
double m_scale;
|
||||
|
||||
/// PAINTER contains information how do draw items
|
||||
PAINTER* m_painter;
|
||||
|
||||
/// Gives interface to PAINTER, that is used to draw items
|
||||
GAL* m_gal;
|
||||
|
||||
/// Dynamic VIEW (eg. display PCB in window) allows changes once it is built,
|
||||
/// static (eg. image/PDF) - does not.
|
||||
bool m_dynamic;
|
||||
|
||||
/// Determines whether to use cached groups of objects for displaying.
|
||||
bool m_useGroups;
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file view_controls.h
|
||||
* @brief VIEW_CONTROLS class definition.
|
||||
*/
|
||||
|
||||
#ifndef __VIEW_CONTROLS_H
|
||||
#define __VIEW_CONTROLS_H
|
||||
|
||||
#include <math/box2.h>
|
||||
|
||||
namespace KiGfx
|
||||
{
|
||||
class VIEW;
|
||||
|
||||
/**
|
||||
* Class VIEW_CONTROLS
|
||||
* is an interface for classes handling user events controlling the view behaviour
|
||||
* (such as zooming, panning, mouse grab, etc.)
|
||||
*/
|
||||
class VIEW_CONTROLS
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Possible modes for panning (JUMP means that view is updated less often, resulting in
|
||||
* not so responsive user interface).
|
||||
*/
|
||||
enum PanMode {
|
||||
SMOOTH = 1,
|
||||
JUMP = 2
|
||||
};
|
||||
|
||||
VIEW_CONTROLS( VIEW* aView ) : m_view( aView ) {};
|
||||
virtual ~VIEW_CONTROLS() {};
|
||||
|
||||
/**
|
||||
* Function Activate
|
||||
* Determines if all view related events (mouse wheel, right click panning, etc.), should be
|
||||
* handled or not. If not - they can be processed by the legacy view.
|
||||
* @param aEnabled tells if events should be handled.
|
||||
*/
|
||||
virtual void Activate( bool aEnabled ) {};
|
||||
|
||||
/**
|
||||
* Function SetGrabMouse
|
||||
* Turns on/off mouse grabbing. When the mouse is grabbed, it cannot go outside the VIEW.
|
||||
* @param aEnabled tells if mouse should be grabbed or not.
|
||||
*/
|
||||
virtual void SetGrabMouse( bool aEnabled ) {};
|
||||
|
||||
/**
|
||||
* Function SetGrabMouse
|
||||
* Turns on/off auto panning (this feature is used when there is a tool active (eg. drawing a
|
||||
* track) and user moves mouse to the VIEW edge - then the view can be translated or not).
|
||||
* @param aEnabled tells if the autopanning should be active.
|
||||
*/
|
||||
virtual void SetAutoPan( bool aEnabled ) {}
|
||||
|
||||
/**
|
||||
* Function SetPanSpeed
|
||||
* Sets speed of panning.
|
||||
* @param aSpeed is a new speed for panning.
|
||||
*/
|
||||
virtual void SetPanSpeed( float aSpeed ) {};
|
||||
|
||||
/**
|
||||
* Function SetPanMode
|
||||
* Enables specified mode for panning.
|
||||
* @param aMode is a new mode used for VIEW panning.
|
||||
*/
|
||||
virtual void SetPanMode( PanMode aMode ) {};
|
||||
|
||||
/**
|
||||
* Function SetZoomSpeed
|
||||
* Determines how much zoom factor should be affected on one zoom event (eg. mouse wheel).
|
||||
* @param aSpeed is a new zooming speed.
|
||||
*/
|
||||
virtual void SetZoomSpeed( float aSpeed ) {};
|
||||
|
||||
/**
|
||||
* Function AnimatedZoom
|
||||
* // TODO
|
||||
*/
|
||||
virtual void AnimatedZoom( const BOX2I& aExtents ) {};
|
||||
|
||||
protected:
|
||||
/// Pointer to controlled VIEW.
|
||||
VIEW* m_view;
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file view_item.h
|
||||
* @brief VIEW_ITEM class definition.
|
||||
*/
|
||||
|
||||
#ifndef __VIEW_ITEM_H
|
||||
#define __VIEW_ITEM_H
|
||||
|
||||
#include <math/box2.h>
|
||||
|
||||
namespace KiGfx
|
||||
{
|
||||
// Forward declarations
|
||||
class GAL;
|
||||
class PAINTER;
|
||||
class VIEW;
|
||||
|
||||
/**
|
||||
* Class VIEW_ITEM -
|
||||
* is an abstract base class for deriving all objects that can be added to a VIEW.
|
||||
* It's role is to:
|
||||
* - communicte geometry, appearance and visibility updates to the associated dynamic VIEW,
|
||||
* - provide a bounding box for redraw area calculation,
|
||||
* - (optional) draw the object using the GAL API functions for PAINTER-less implementations.
|
||||
* VIEW_ITEM objects are never owned by a VIEW. A single VIEW_ITEM can belong to any number of
|
||||
* static VIEWs, but only one dynamic VIEW due to storage of only one VIEW reference.
|
||||
*/
|
||||
class VIEW_ITEM
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Enum ViewUpdateFlags.
|
||||
* Defines the how severely the shape/appearance of the item has been changed:
|
||||
* - APPEARANCE: shape or layer set of the item have not been affected,
|
||||
* only colors or visibility.
|
||||
* - GEOMETRY: shape or layer set of the item have changed, VIEW may need to reindex it.
|
||||
* - ALL: all flags above */
|
||||
|
||||
enum ViewUpdateFlags {
|
||||
APPEARANCE = 0x1,
|
||||
GEOMETRY = 0x2,
|
||||
ALL = 0xff
|
||||
};
|
||||
|
||||
VIEW_ITEM() : m_view( NULL ), m_viewVisible( true ), m_cachedGroup( -1 ) {}
|
||||
|
||||
/**
|
||||
* Destructor. For dynamic views, removes the item from the view.
|
||||
*/
|
||||
virtual ~VIEW_ITEM()
|
||||
{
|
||||
ViewRelease();
|
||||
};
|
||||
|
||||
/**
|
||||
* Function ViewBBox()
|
||||
* returns the bounding box of the item covering all its layers.
|
||||
* @return BOX2I - the current bounding box
|
||||
*/
|
||||
virtual const BOX2I ViewBBox() const = 0;
|
||||
|
||||
/**
|
||||
* Function ViewDraw()
|
||||
* Draws the parts of the object belonging to layer aLayer.
|
||||
* viewDraw() is an alternative way for drawing objects if
|
||||
* if there is no PAINTER assigned for the view or if the PAINTER
|
||||
* doesn't know how to paint this particular implementation of
|
||||
* VIEW_ITEM. The preferred way of drawing is to design an
|
||||
* appropriate PAINTER object, the method below is intended only
|
||||
* for quick hacks and debugging purposes.
|
||||
*
|
||||
* @param aLayer: current drawing layer
|
||||
* @param aGal: pointer to the GAL device we are drawing on
|
||||
* @param aVisibleArea: area (in world space coordinates) that is relevant for drawing. For
|
||||
* example, when drawing a bitmap, one can clip the blitting area to aVisibleArea, reducing
|
||||
* drawing time.
|
||||
*/
|
||||
virtual void ViewDraw( int aLayer, GAL* aGal, const BOX2I& aVisibleArea ) const { };
|
||||
|
||||
/**
|
||||
* Function ViewGetLayers()
|
||||
* Returns the all the layers within the VIEW the object is painted on. For instance, a D_PAD
|
||||
* spans one or more copper layers and a few technical layers. ViewDraw() or PAINTER::Draw() is
|
||||
* repeatedly called for each of the layers returned by ViewGetLayers(), depending on the
|
||||
* rendering order.
|
||||
* @param aLayers[]: output layer index array
|
||||
* @param aCount: number of layer indices in aLayers[]
|
||||
*/
|
||||
|
||||
virtual void ViewGetLayers( int aLayers[], int& aCount ) const = 0;
|
||||
|
||||
/**
|
||||
* Function ViewSetVisible()
|
||||
* Sets the item visibility.
|
||||
*
|
||||
* @param aIsVisible: whether the item is visible (on all layers), or not.
|
||||
*/
|
||||
void ViewSetVisible( bool aIsVisible = true );
|
||||
|
||||
|
||||
/**
|
||||
* Function ViewIsVisible()
|
||||
* Returns if the item is visible (or not).
|
||||
*
|
||||
* @return when true, the item is visible (i.e. to be displayed, not visible in the
|
||||
* *current* viewport)
|
||||
*/
|
||||
bool ViewIsVisible() const
|
||||
{
|
||||
return m_viewVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ViewUpdate()
|
||||
* For dynamic VIEWs, informs the associated VIEW that the graphical representation of
|
||||
* this item has changed. For static views calling has no effect.
|
||||
*
|
||||
* @param aUpdateFlags: how much the object has changed
|
||||
* @param aForceImmediateRedraw: when true, the VIEW is redrawn immediately,
|
||||
* otherwise, it will be redrawn upon next call of VIEW::Update()
|
||||
*/
|
||||
virtual void ViewUpdate( int aUpdateFlags = ALL, bool aForceImmediateRedraw = false );
|
||||
|
||||
/**
|
||||
* Function ViewRelease()
|
||||
* Releases the item from an associated dynamic VIEW. For static views calling has no effect.
|
||||
*/
|
||||
void ViewRelease();
|
||||
|
||||
protected:
|
||||
friend class VIEW;
|
||||
|
||||
/**
|
||||
* Function viewAssign()
|
||||
* Assigns the item to a given dynamic VIEW. Called internally by the VIEW.
|
||||
*
|
||||
* @param aView[]: dynamic VIEW instance the item is being added to.
|
||||
*/
|
||||
|
||||
void viewAssign( VIEW* aView )
|
||||
{
|
||||
// release the item from a previously assigned dynamic view (if there is any)
|
||||
ViewRelease();
|
||||
m_view = aView;
|
||||
m_cachedGroup = -1;
|
||||
}
|
||||
|
||||
VIEW* m_view; ///* Current dynamic view the item is assigned to.
|
||||
bool m_viewVisible; ///* Are we visible in the current dynamic VIEW.
|
||||
private:
|
||||
int m_cachedGroup; ///* Index of cached GAL display list corresponding to the item
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file wx_view_controls.h
|
||||
* @brief WX_VIEW_CONTROLS class definition.
|
||||
*/
|
||||
|
||||
#ifndef __WX_VIEW_CONTROLS_H
|
||||
#define __WX_VIEW_CONTROLS_H
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
|
||||
#include <view/view_controls.h>
|
||||
|
||||
class EDA_DRAW_PANEL_GAL;
|
||||
|
||||
namespace KiGfx
|
||||
{
|
||||
/**
|
||||
* Class WX_VIEW_CONTROLS
|
||||
* is a specific implementation of class VIEW_CONTROLS for wxWidgets library.
|
||||
*/
|
||||
class WX_VIEW_CONTROLS : public VIEW_CONTROLS, public wxEvtHandler
|
||||
{
|
||||
public:
|
||||
|
||||
WX_VIEW_CONTROLS( VIEW* aView, wxWindow* aParentPanel );
|
||||
~WX_VIEW_CONTROLS() {};
|
||||
|
||||
void onWheel( wxMouseEvent& event );
|
||||
void onMotion( wxMouseEvent& event );
|
||||
void onButton( wxMouseEvent& event );
|
||||
|
||||
private:
|
||||
|
||||
/// Options for WX_VIEW_CONTROLS
|
||||
bool m_isDragPanning;
|
||||
bool m_isAutoPanning;
|
||||
bool m_autoPanEnabled;
|
||||
bool m_needRedraw;
|
||||
|
||||
/// Distance from cursor to VIEW edge when panning is active.
|
||||
double m_autoPanMargin;
|
||||
/// How fast is panning when in auto mode.
|
||||
double m_autoPanSpeed;
|
||||
/// TODO
|
||||
double m_autoPanCornerRatio;
|
||||
|
||||
/// Panel that is affected by VIEW_CONTROLS
|
||||
wxWindow* m_parentPanel;
|
||||
|
||||
/// Stores information about point where event started.
|
||||
VECTOR2D m_dragStartPoint;
|
||||
VECTOR2D m_lookStartPoint;
|
||||
|
||||
/// Used for determining time intervals between events.
|
||||
wxLongLong m_timeStamp;
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif
|
|
@ -68,6 +68,7 @@
|
|||
class EDA_ITEM;
|
||||
class EDA_RECT;
|
||||
class EDA_DRAW_PANEL;
|
||||
class EDA_DRAW_PANEL_GAL;
|
||||
class EDA_MSG_PANEL;
|
||||
class BASE_SCREEN;
|
||||
class PARAM_CFG_BASE;
|
||||
|
@ -391,11 +392,15 @@ protected:
|
|||
EDA_HOTKEY_CONFIG* m_HotkeysZoomAndGridList;
|
||||
int m_LastGridSizeId;
|
||||
bool m_DrawGrid; // hide/Show grid
|
||||
bool m_galCanvasActive; // whether to use new GAL engine
|
||||
EDA_COLOR_T m_GridColor; // Grid color
|
||||
|
||||
/// The area to draw on.
|
||||
EDA_DRAW_PANEL* m_canvas;
|
||||
|
||||
/// New type of area (GAL-based) to draw on.
|
||||
EDA_DRAW_PANEL_GAL* m_galCanvas;
|
||||
|
||||
/// Tool ID of previously active draw tool bar button.
|
||||
int m_lastDrawToolId;
|
||||
|
||||
|
@ -904,6 +909,30 @@ public:
|
|||
*/
|
||||
wxString LengthDoubleToString( double aValue, bool aConvertToMils = false ) const;
|
||||
|
||||
/**
|
||||
* Function UseGalCanvas
|
||||
* used to switch between standard and GAL-based canvas.
|
||||
*
|
||||
* @param aEnable True for GAL-based canvas, false for standard canvas.
|
||||
*/
|
||||
void UseGalCanvas( bool aEnable );
|
||||
|
||||
/**
|
||||
* Function IsNewCanvasActive
|
||||
* is used to check which canvas (GAL-based or standard) is currently in use.
|
||||
*
|
||||
* @return True for GAL-based canvas, false for standard canvas.
|
||||
*/
|
||||
bool IsGalCanvasActive() { return m_galCanvasActive; }
|
||||
|
||||
/**
|
||||
* Function GetCalCanvas
|
||||
* returns a pointer to GAL-based canvas of given EDA draw frame.
|
||||
*
|
||||
* @return Pointer to GAL-based canvas.
|
||||
*/
|
||||
EDA_DRAW_PANEL_GAL* GetGalCanvas() { return m_galCanvas; }
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
|
|
|
@ -426,6 +426,13 @@ target_link_libraries(pcbnew
|
|||
${PCBNEW_EXTRA_LIBS}
|
||||
)
|
||||
|
||||
if(KICAD_GAL)
|
||||
target_link_libraries(pcbnew
|
||||
gal
|
||||
${GLEW_LIBRARIES}
|
||||
)
|
||||
endif(KICAD_GAL)
|
||||
|
||||
###
|
||||
# Add pcbnew as install target
|
||||
###
|
||||
|
|
|
@ -42,10 +42,18 @@
|
|||
#include <pcbnew.h>
|
||||
#include <pcbnew_id.h>
|
||||
#include <class_board.h>
|
||||
#include <class_track.h>
|
||||
#include <class_module.h>
|
||||
#include <class_drawsegment.h>
|
||||
|
||||
#include <collectors.h>
|
||||
#include <class_drawpanel.h>
|
||||
#include <class_drawpanel_gal.h>
|
||||
#include <view/view.h>
|
||||
#include <math/vector2d.h>
|
||||
#ifdef KICAD_GAL
|
||||
#include <pcb_painter.h>
|
||||
#endif
|
||||
|
||||
|
||||
// Configuration entry names.
|
||||
|
@ -77,6 +85,27 @@ BEGIN_EVENT_TABLE( PCB_BASE_FRAME, EDA_DRAW_FRAME )
|
|||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
/// Rendering order of layers on GAL-based canvas (lower index in the array
|
||||
/// means that layer is displayed closer to the user, ie. on the top).
|
||||
const int m_galLayerOrder[] =
|
||||
{
|
||||
DRAW_N, COMMENT_N, ECO1_N, ECO2_N, EDGE_N,
|
||||
UNUSED_LAYER_29, UNUSED_LAYER_30, UNUSED_LAYER_31,
|
||||
ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ),
|
||||
SILKSCREEN_N_FRONT, SOLDERPASTE_N_FRONT, ADHESIVE_N_FRONT, SOLDERMASK_N_FRONT,
|
||||
|
||||
ITEM_GAL_LAYER( VIA_HOLES_VISIBLE ), ITEM_GAL_LAYER( PAD_HOLES_VISIBLE ),
|
||||
ITEM_GAL_LAYER( VIAS_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
|
||||
|
||||
LAYER_N_FRONT, LAYER_N_15, LAYER_N_14, LAYER_N_13, LAYER_N_12, LAYER_N_11,
|
||||
LAYER_N_10, LAYER_N_9, LAYER_N_8, LAYER_N_7, LAYER_N_6, LAYER_N_5, LAYER_N_4,
|
||||
LAYER_N_3, LAYER_N_2, LAYER_N_BACK,
|
||||
|
||||
SOLDERMASK_N_BACK, ADHESIVE_N_BACK, SOLDERPASTE_N_BACK, SILKSCREEN_N_BACK,
|
||||
ITEM_GAL_LAYER( MOD_TEXT_BK_VISIBLE )
|
||||
};
|
||||
|
||||
|
||||
PCB_BASE_FRAME::PCB_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType,
|
||||
const wxString& aTitle,
|
||||
const wxPoint& aPos, const wxSize& aSize,
|
||||
|
@ -101,6 +130,12 @@ PCB_BASE_FRAME::PCB_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType,
|
|||
m_FastGrid1 = 0;
|
||||
m_FastGrid2 = 0;
|
||||
|
||||
#ifdef KICAD_GAL
|
||||
m_galCanvas = new EDA_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize,
|
||||
EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL );
|
||||
m_galCanvas->Hide();
|
||||
#endif /* KICAD_GAL */
|
||||
|
||||
m_auxiliaryToolBar = NULL;
|
||||
}
|
||||
|
||||
|
@ -110,6 +145,9 @@ PCB_BASE_FRAME::~PCB_BASE_FRAME()
|
|||
delete m_Collector;
|
||||
|
||||
delete m_Pcb; // is already NULL for FOOTPRINT_EDIT_FRAME
|
||||
#ifdef KICAD_GAL
|
||||
delete m_galCanvas;
|
||||
#endif /* KICAD_GAL */
|
||||
}
|
||||
|
||||
|
||||
|
@ -117,6 +155,78 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard )
|
|||
{
|
||||
delete m_Pcb;
|
||||
m_Pcb = aBoard;
|
||||
|
||||
#ifdef KICAD_GAL
|
||||
if( m_galCanvas )
|
||||
{
|
||||
KiGfx::VIEW* view = m_galCanvas->GetView();
|
||||
view->Clear();
|
||||
|
||||
// All of PCB drawing elements should be added to the VIEW
|
||||
// in order to be displayed
|
||||
|
||||
// Load zones
|
||||
for( int i = 0; i < m_Pcb->GetAreaCount(); ++i )
|
||||
{
|
||||
view->Add( (KiGfx::VIEW_ITEM*) ( m_Pcb->GetArea( i ) ) );
|
||||
}
|
||||
|
||||
// Load drawings
|
||||
for( BOARD_ITEM* drawing = m_Pcb->m_Drawings; drawing; drawing = drawing->Next() )
|
||||
{
|
||||
view->Add( drawing );
|
||||
}
|
||||
|
||||
// Load tracks
|
||||
for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() )
|
||||
{
|
||||
view->Add( track );
|
||||
}
|
||||
|
||||
// Load modules and its additional elements
|
||||
for( MODULE* module = m_Pcb->m_Modules; module; module = module->Next() )
|
||||
{
|
||||
// Load module's pads
|
||||
for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
|
||||
{
|
||||
view->Add( pad );
|
||||
}
|
||||
|
||||
// Load module's drawing (mostly silkscreen)
|
||||
for( BOARD_ITEM* drawing = module->GraphicalItems().GetFirst(); drawing;
|
||||
drawing = drawing->Next() )
|
||||
{
|
||||
view->Add( drawing );
|
||||
}
|
||||
|
||||
// Load module's texts (name and value)
|
||||
view->Add( &module->Reference() );
|
||||
view->Add( &module->Value() );
|
||||
}
|
||||
|
||||
// Segzones (equivalent of ZONE_CONTAINER for legacy boards)
|
||||
for( SEGZONE* zone = m_Pcb->m_Zone; zone; zone = zone->Next() )
|
||||
{
|
||||
view->Add( zone );
|
||||
}
|
||||
|
||||
// Apply layer coloring scheme
|
||||
if( view->GetPainter() )
|
||||
{
|
||||
KiGfx::PCB_RENDER_SETTINGS* colorSettings = new KiGfx::PCB_RENDER_SETTINGS();
|
||||
|
||||
// Load layers' colors from PCB data
|
||||
colorSettings->ImportLegacyColors( m_Pcb->GetColorsSettings() );
|
||||
view->GetPainter()->ApplySettings( colorSettings );
|
||||
}
|
||||
|
||||
// Set rendering order of layers (check m_galLayerOrder to see the order)
|
||||
for( unsigned int i = 0; i < sizeof( m_galLayerOrder ) / sizeof( int ); ++i )
|
||||
{
|
||||
view->SetLayerOrder( m_galLayerOrder[i], i );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -132,3 +132,11 @@ std::string BOARD_ITEM::FormatInternalUnits( const wxSize& aSize )
|
|||
{
|
||||
return FormatInternalUnits( aSize.GetWidth() ) + " " + FormatInternalUnits( aSize.GetHeight() );
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
{
|
||||
// Basic fallback
|
||||
aCount = 1;
|
||||
aLayers[0] = m_Layer;
|
||||
}
|
||||
|
|
|
@ -850,6 +850,24 @@ EDA_ITEM* D_PAD::Clone() const
|
|||
}
|
||||
|
||||
|
||||
void D_PAD::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
{
|
||||
if( m_Attribute == PAD_SMD || m_Attribute == PAD_CONN)
|
||||
{
|
||||
// Single layer pad (smd) without hole
|
||||
aLayers[0] = GetParent()->GetLayer();
|
||||
aCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Multi layer pad with hole - pad is shown on one common layer, hole on the other
|
||||
aLayers[0] = ITEM_GAL_LAYER( PADS_VISIBLE );
|
||||
aLayers[1] = ITEM_GAL_LAYER( PAD_HOLES_VISIBLE );
|
||||
aCount = 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
void D_PAD::Show( int nestLevel, std::ostream& os ) const
|
||||
|
|
|
@ -395,6 +395,9 @@ public:
|
|||
|
||||
EDA_ITEM* Clone() const;
|
||||
|
||||
/// @copydoc VIEW_ITEM::ViewGetLayers()
|
||||
virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const; // overload
|
||||
#endif
|
||||
|
|
|
@ -488,6 +488,23 @@ EDA_ITEM* TEXTE_MODULE::Clone() const
|
|||
}
|
||||
|
||||
|
||||
void TEXTE_MODULE::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
{
|
||||
switch( GetParent()->GetLayer() )
|
||||
{
|
||||
case LAYER_N_BACK:
|
||||
aLayers[0] = ITEM_GAL_LAYER( MOD_TEXT_BK_VISIBLE ); // how about SILKSCREEN_N_BACK?
|
||||
break;
|
||||
|
||||
case LAYER_N_FRONT:
|
||||
aLayers[0] = ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ); // how about SILKSCREEN_N_FRONT?
|
||||
break;
|
||||
}
|
||||
|
||||
aCount = 1;
|
||||
}
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
void TEXTE_MODULE::Show( int nestLevel, std::ostream& os ) const
|
||||
|
|
|
@ -156,6 +156,9 @@ public:
|
|||
|
||||
EDA_ITEM* Clone() const;
|
||||
|
||||
/// @copydoc VIEW_ITEM::ViewGetLayers()
|
||||
virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const; // overload
|
||||
#endif
|
||||
|
|
|
@ -958,6 +958,25 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
|
|||
}
|
||||
|
||||
|
||||
void SEGVIA::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
{
|
||||
/*int top_layer, bottom_layer;
|
||||
ReturnLayerPair( &top_layer, &bottom_layer );
|
||||
|
||||
// We can add vias to all layers they belong, but then they are drawn this many times
|
||||
aCount = 0;
|
||||
for( int i = bottom_layer; i <= top_layer; ++i )
|
||||
{
|
||||
aLayers[aCount++] = i;
|
||||
}*/
|
||||
|
||||
// Just show it on common via & via holes layers
|
||||
aLayers[0] = ITEM_GAL_LAYER( VIAS_VISIBLE );
|
||||
aLayers[1] = ITEM_GAL_LAYER( VIA_HOLES_VISIBLE );
|
||||
aCount = 2;
|
||||
}
|
||||
|
||||
|
||||
// see class_track.h
|
||||
void TRACK::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
|
||||
{
|
||||
|
|
|
@ -414,6 +414,9 @@ public:
|
|||
|
||||
EDA_ITEM* Clone() const;
|
||||
|
||||
/// @copydoc VIEW_ITEM::ViewGetLayers()
|
||||
virtual void ViewGetLayers( int aLayers[], int& aCount ) const;
|
||||
|
||||
#if defined (DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const; // overload
|
||||
#endif
|
||||
|
|
|
@ -82,6 +82,9 @@ static EDA_HOTKEY HkResetLocalCoord( wxT( "Reset Local Coordinates" ),
|
|||
HK_RESET_LOCAL_COORD, ' ' );
|
||||
static EDA_HOTKEY HkSwitchHighContrastMode( wxT("Switch Highcontrast mode"),
|
||||
HK_SWITCH_HIGHCONTRAST_MODE,'H');
|
||||
#ifdef KICAD_GAL
|
||||
static EDA_HOTKEY HkSwitchCanvas( wxT( "Switch canvas" ), HK_SWITCH_CANVAS, WXK_F12 );
|
||||
#endif
|
||||
/* Fit on Screen */
|
||||
#if !defined( __WXMAC__ )
|
||||
static EDA_HOTKEY HkZoomAuto( wxT( "Zoom Auto" ), HK_ZOOM_AUTO, WXK_HOME );
|
||||
|
@ -228,6 +231,9 @@ EDA_HOTKEY* board_edit_Hotkey_List[] =
|
|||
&HkRecordMacros6, &HkCallMacros6, &HkRecordMacros7, &HkCallMacros7,
|
||||
&HkRecordMacros8, &HkCallMacros8, &HkRecordMacros9, &HkCallMacros9,
|
||||
&HkSwitchHighContrastMode,
|
||||
#ifdef KICAD_GAL
|
||||
&HkSwitchCanvas,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -82,6 +82,9 @@ enum hotkey_id_commnand {
|
|||
HK_CALL_MACROS_9,
|
||||
HK_MACRO_ID_END,
|
||||
HK_SWITCH_HIGHCONTRAST_MODE,
|
||||
#ifdef KICAD_GAL
|
||||
HK_SWITCH_CANVAS,
|
||||
#endif
|
||||
};
|
||||
|
||||
// Full list of hotkey descriptors for board editor and footprint editor
|
||||
|
|
|
@ -348,6 +348,17 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
|
|||
_( "&List Nets" ), _( "View a list of nets with names and id's" ),
|
||||
KiBitmap( tools_xpm ) );
|
||||
|
||||
#ifdef KICAD_GAL
|
||||
// Switching GAL-based canvas on/off
|
||||
viewMenu->AppendSeparator();
|
||||
|
||||
text = AddHotkeyName( _( "&Switch canvas" ), g_Pcbnew_Editor_Hokeys_Descr, HK_SWITCH_CANVAS, IS_ACCELERATOR );
|
||||
|
||||
AddMenuItem( viewMenu, ID_SWITCH_CANVAS,
|
||||
text, _( "Switch the canvas implementation between old (XOR-based) and new (GAL-based)" ),
|
||||
KiBitmap( tools_xpm ) );
|
||||
#endif
|
||||
|
||||
/** Create Place Menu **/
|
||||
wxMenu* placeMenu = new wxMenu;
|
||||
|
||||
|
|
|
@ -0,0 +1,421 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <class_track.h>
|
||||
#include <class_module.h>
|
||||
#include <class_pad.h>
|
||||
#include <class_drawsegment.h>
|
||||
#include <class_zone.h>
|
||||
#include <class_pcb_text.h>
|
||||
#include <class_colors_design_settings.h>
|
||||
#include <class_marker_pcb.h>
|
||||
#include <class_dimension.h>
|
||||
#include <eda_text.h>
|
||||
|
||||
#include <view/view.h>
|
||||
#include <pcb_painter.h>
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
#include <gal/stroke_font.h>
|
||||
#include <newstroke_font.h>
|
||||
|
||||
using namespace KiGfx;
|
||||
|
||||
PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS()
|
||||
{
|
||||
Update();
|
||||
}
|
||||
|
||||
|
||||
void PCB_RENDER_SETTINGS::ImportLegacyColors( COLORS_DESIGN_SETTINGS* aSettings )
|
||||
{
|
||||
for( int i = 0; i < LAYER_COUNT; i++ )
|
||||
{
|
||||
m_layerColors[i] = m_legacyColorMap[aSettings->GetLayerColor( i )];
|
||||
}
|
||||
|
||||
for( int i = 0; i < END_PCB_VISIBLE_LIST; i++ )
|
||||
{
|
||||
m_itemColors[i] = m_legacyColorMap[aSettings->GetItemColor( i )];
|
||||
}
|
||||
|
||||
m_itemColors[VIA_HOLES_VISIBLE] = COLOR4D( 0.5f, 0.4f, 0.0f, 1.0f );
|
||||
m_itemColors[PAD_HOLES_VISIBLE] = COLOR4D( 0.0f, 0.5f, 0.5f, 1.0f );
|
||||
m_itemColors[VIAS_VISIBLE] = COLOR4D( 0.7f, 0.7f, 0.7f, 1.0f );
|
||||
m_itemColors[PADS_VISIBLE] = COLOR4D( 0.7f, 0.7f, 0.7f, 1.0f );
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
|
||||
void PCB_RENDER_SETTINGS::Update()
|
||||
{
|
||||
// Calculate darkened/highlighted variants of layer colors
|
||||
for( int i = 0; i < LAYER_COUNT; i++ )
|
||||
{
|
||||
m_layerColors[i].a = m_layerOpacity;
|
||||
m_layerColorsHi[i] = m_layerColors[i].Highlighted( m_highlightFactor );
|
||||
m_layerColorsDark[i] = m_layerColors[i].Darkened( 1.0 - m_highlightFactor );
|
||||
m_layerColorsSel[i] = m_layerColors[i].Highlighted( m_selectFactor );
|
||||
}
|
||||
|
||||
for( int i = 0; i < END_PCB_VISIBLE_LIST; i++ )
|
||||
{
|
||||
m_itemColors[i].a = m_layerOpacity;
|
||||
m_itemColorsHi[i] = m_itemColors[i].Highlighted( m_highlightFactor );
|
||||
m_itemColorsDark[i] = m_itemColors[i].Darkened( 1.0 - m_highlightFactor );
|
||||
m_itemColorsSel[i] = m_itemColors[i].Highlighted( m_selectFactor );
|
||||
}
|
||||
|
||||
m_hiContrastColor = COLOR4D( m_hiContrastFactor, m_hiContrastFactor, m_highlightFactor,
|
||||
m_layerOpacity );
|
||||
}
|
||||
|
||||
|
||||
PCB_PAINTER::PCB_PAINTER( GAL* aGal ) :
|
||||
PAINTER( aGal )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const COLOR4D& PCB_PAINTER::getLayerColor( int aLayer, int aNetCode ) const
|
||||
{
|
||||
// For item layers (vias, texts, and so on)
|
||||
if( aLayer >= LAYER_COUNT )
|
||||
return getItemColor( aLayer - LAYER_COUNT, aNetCode );
|
||||
|
||||
if( m_pcbSettings->m_hiContrastEnabled && m_pcbSettings->m_activeLayer != aLayer )
|
||||
{
|
||||
return m_pcbSettings->m_hiContrastColor;
|
||||
}
|
||||
else if( m_pcbSettings->m_highlightEnabled )
|
||||
{
|
||||
if( aNetCode == m_pcbSettings->m_highlightNetcode )
|
||||
{
|
||||
return m_pcbSettings->m_layerColorsHi[aLayer];
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_pcbSettings->m_layerColorsDark[aLayer];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_pcbSettings->m_layerColors[aLayer];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const COLOR4D& PCB_PAINTER::getItemColor( int aItemType, int aNetCode ) const
|
||||
{
|
||||
// if(aNetCode == m_settings->m_hiContrastEnabled)
|
||||
// return m_settings->m_itemColorsHi[ aItemType ];
|
||||
if( m_pcbSettings->m_highlightEnabled )
|
||||
{
|
||||
if( aNetCode == m_pcbSettings->m_highlightNetcode )
|
||||
{
|
||||
return m_pcbSettings->m_itemColorsHi[aItemType];
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_pcbSettings->m_itemColorsDark[aItemType];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_pcbSettings->m_itemColors[aItemType];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PCB_PAINTER::Draw( const EDA_ITEM* aItem, int aLayer )
|
||||
{
|
||||
// the "cast" applied in here clarifies which overloaded draw() is called
|
||||
switch( aItem->Type() )
|
||||
{
|
||||
case PCB_ZONE_T:
|
||||
case PCB_TRACE_T:
|
||||
draw( (TRACK*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_VIA_T:
|
||||
draw( (SEGVIA*) aItem, aLayer );
|
||||
break;
|
||||
|
||||
case PCB_PAD_T:
|
||||
draw( (D_PAD*) aItem, aLayer );
|
||||
break;
|
||||
|
||||
case PCB_LINE_T:
|
||||
case PCB_MODULE_EDGE_T:
|
||||
draw( (DRAWSEGMENT*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_TEXT_T:
|
||||
draw( (TEXTE_PCB*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_MODULE_TEXT_T:
|
||||
draw( (TEXTE_MODULE*) aItem, aLayer );
|
||||
break;
|
||||
|
||||
case PCB_ZONE_AREA_T:
|
||||
draw( (ZONE_CONTAINER*) aItem );
|
||||
break;
|
||||
|
||||
default:
|
||||
// Painter does not know how to draw the object
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PCB_PAINTER::draw( const TRACK* aTrack )
|
||||
{
|
||||
VECTOR2D start( aTrack->GetStart() );
|
||||
VECTOR2D end( aTrack->GetEnd() );
|
||||
COLOR4D strokeColor = getLayerColor( aTrack->GetLayer(), aTrack->GetNet() );
|
||||
|
||||
m_gal->SetLineCap( LINE_CAP_ROUND );
|
||||
m_gal->SetLineJoin( LINE_JOIN_ROUND );
|
||||
m_gal->SetLineWidth( aTrack->GetWidth() );
|
||||
m_gal->SetStrokeColor( strokeColor );
|
||||
m_gal->DrawLine( start, end );
|
||||
}
|
||||
|
||||
|
||||
void PCB_PAINTER::draw( const SEGVIA* aVia, int aLayer )
|
||||
{
|
||||
VECTOR2D center( aVia->GetStart() );
|
||||
double radius;
|
||||
COLOR4D fillColor;
|
||||
|
||||
// Choose drawing settings depending on if we are drawing via's pad or hole
|
||||
if( aLayer == ITEM_GAL_LAYER( VIAS_VISIBLE ) )
|
||||
{
|
||||
radius = aVia->GetWidth() / 2.0f;
|
||||
}
|
||||
else if( aLayer == ITEM_GAL_LAYER( VIA_HOLES_VISIBLE ) )
|
||||
{
|
||||
radius = aVia->GetDrillValue() / 2.0f;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
fillColor = getLayerColor( aLayer, aVia->GetNet() );
|
||||
|
||||
m_gal->SetIsStroke( false );
|
||||
m_gal->SetIsFill( true );
|
||||
m_gal->SetFillColor( fillColor );
|
||||
m_gal->DrawCircle( center, radius );
|
||||
}
|
||||
|
||||
|
||||
void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
|
||||
{
|
||||
COLOR4D fillColor;
|
||||
VECTOR2D size;
|
||||
PAD_SHAPE_T shape;
|
||||
double m, n;
|
||||
|
||||
m_gal->Save();
|
||||
m_gal->Translate( VECTOR2D( aPad->GetPosition() ) );
|
||||
m_gal->Rotate( -aPad->GetOrientation() * M_PI / 1800.0 ); // orientation is in tenths of degree
|
||||
|
||||
// Choose drawing settings depending on if we are drawing a pad itself or a hole
|
||||
if( aLayer == ITEM_GAL_LAYER( PAD_HOLES_VISIBLE ) )
|
||||
{
|
||||
// Drawing hole
|
||||
size = VECTOR2D( aPad->GetDrillSize() ) / 2.0f;
|
||||
shape = aPad->GetDrillShape();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Drawing every kind of pad
|
||||
m_gal->Translate( VECTOR2D( aPad->GetOffset() ) );
|
||||
size = VECTOR2D( aPad->GetSize() ) / 2.0f;
|
||||
shape = aPad->GetShape();
|
||||
}
|
||||
|
||||
fillColor = getLayerColor( aLayer, aPad->GetNet() );
|
||||
|
||||
m_gal->SetIsFill( true );
|
||||
m_gal->SetIsStroke( false );
|
||||
m_gal->SetFillColor( fillColor );
|
||||
|
||||
switch( shape )
|
||||
{
|
||||
case PAD_OVAL:
|
||||
if( size.y >= size.x )
|
||||
{
|
||||
m = ( size.y - size.x );
|
||||
n = size.x;
|
||||
|
||||
m_gal->DrawCircle( VECTOR2D( 0, -m ), n );
|
||||
m_gal->DrawCircle( VECTOR2D( 0, m ), n );
|
||||
m_gal->DrawRectangle( VECTOR2D( -n, -m ), VECTOR2D( n, m ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m = ( size.x - size.y );
|
||||
n = size.y;
|
||||
|
||||
m_gal->DrawCircle( VECTOR2D( -m, 0 ), n );
|
||||
m_gal->DrawCircle( VECTOR2D( m, 0 ), n );
|
||||
m_gal->DrawRectangle( VECTOR2D( -m, -n ), VECTOR2D( m, n ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_RECT:
|
||||
case PAD_TRAPEZOID:
|
||||
m_gal->DrawRectangle( VECTOR2D( -size.x, -size.y ), VECTOR2D( size.x, size.y ) );
|
||||
break;
|
||||
|
||||
case PAD_CIRCLE:
|
||||
m_gal->DrawCircle( VECTOR2D( 0.0, 0.0 ), size.x );
|
||||
break;
|
||||
|
||||
case PAD_OCTAGON: // it is not used anywhere, neither you can set it using pcbnew..
|
||||
case PAD_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
m_gal->Restore();
|
||||
}
|
||||
|
||||
|
||||
void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment )
|
||||
{
|
||||
COLOR4D strokeColor = getLayerColor( aSegment->GetLayer(), 0 );
|
||||
std::deque<VECTOR2D> pointsList;
|
||||
|
||||
m_gal->SetIsFill( false );
|
||||
m_gal->SetIsStroke( true );
|
||||
m_gal->SetStrokeColor( strokeColor );
|
||||
m_gal->SetLineWidth( aSegment->GetWidth() );
|
||||
m_gal->SetLineCap( LINE_CAP_ROUND );
|
||||
m_gal->SetLineJoin( LINE_JOIN_ROUND );
|
||||
|
||||
switch( aSegment->GetShape() )
|
||||
{
|
||||
case S_SEGMENT:
|
||||
m_gal->DrawLine( VECTOR2D( aSegment->GetStart() ), VECTOR2D( aSegment->GetEnd() ) );
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
m_gal->SetLineCap( LINE_CAP_SQUARED );
|
||||
m_gal->SetLineJoin( LINE_JOIN_BEVEL );
|
||||
m_gal->DrawLine( VECTOR2D( aSegment->GetStart() ), VECTOR2D( aSegment->GetEnd() ) );
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
m_gal->DrawArc( VECTOR2D( aSegment->GetCenter() ), aSegment->GetRadius(),
|
||||
aSegment->GetArcAngleStart() * M_PI / 1800.0,
|
||||
( aSegment->GetArcAngleStart() + aSegment->GetAngle() ) * M_PI / 1800.0 );
|
||||
break;
|
||||
|
||||
case S_CIRCLE:
|
||||
m_gal->DrawCircle( VECTOR2D( aSegment->GetCenter() ), aSegment->GetRadius() );
|
||||
break;
|
||||
|
||||
case S_POLYGON:
|
||||
std::copy( aSegment->GetPolyPoints().begin(), aSegment->GetPolyPoints().end(),
|
||||
std::back_inserter( pointsList ) );
|
||||
m_gal->DrawPolygon( pointsList );
|
||||
break;
|
||||
|
||||
case S_CURVE:
|
||||
m_gal->DrawCurve( VECTOR2D( aSegment->GetStart() ),
|
||||
VECTOR2D( aSegment->GetBezControl1() ),
|
||||
VECTOR2D( aSegment->GetBezControl2() ),
|
||||
VECTOR2D( aSegment->GetEnd() ) );
|
||||
break;
|
||||
|
||||
case S_LAST:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PCB_PAINTER::draw( const TEXTE_PCB* aText )
|
||||
{
|
||||
COLOR4D strokeColor = getLayerColor( aText->GetLayer(), 0 );
|
||||
VECTOR2D position( aText->GetTextPosition().x, aText->GetTextPosition().y );
|
||||
double orientation = aText->GetOrientation() * M_PI / 1800.0;
|
||||
|
||||
m_gal->SetStrokeColor( strokeColor );
|
||||
m_gal->SetLineWidth( aText->GetThickness() );
|
||||
m_stroke_font->LoadAttributes( aText );
|
||||
m_stroke_font->Draw( std::string( aText->GetText().mb_str() ), position, orientation );
|
||||
}
|
||||
|
||||
|
||||
void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer )
|
||||
{
|
||||
COLOR4D strokeColor = getLayerColor( aLayer, 0 );
|
||||
|
||||
m_gal->SetStrokeColor( strokeColor );
|
||||
m_gal->SetLineWidth( aText->GetThickness() );
|
||||
m_stroke_font->LoadAttributes( aText );
|
||||
m_stroke_font->Draw( std::string( aText->GetText().mb_str() ),
|
||||
VECTOR2D( aText->GetTextPosition().x, aText->GetTextPosition().y),
|
||||
aText->GetDrawRotation() * M_PI / 1800.0 );
|
||||
}
|
||||
|
||||
|
||||
void PCB_PAINTER::draw( const ZONE_CONTAINER* aContainer )
|
||||
{
|
||||
COLOR4D fillColor = getLayerColor( aContainer->GetLayer(), aContainer->GetNet() );
|
||||
std::vector<CPolyPt>::iterator polyIterator;
|
||||
std::vector<CPolyPt> polyPoints = aContainer->GetFilledPolysList();
|
||||
std::deque<VECTOR2D> corners;
|
||||
|
||||
m_gal->SetLineCap( LINE_CAP_ROUND );
|
||||
m_gal->SetLineJoin( LINE_JOIN_ROUND );
|
||||
m_gal->SetFillColor( fillColor );
|
||||
m_gal->SetStrokeColor( fillColor );
|
||||
m_gal->SetIsFill( aContainer->IsFilled() );
|
||||
m_gal->SetIsStroke( true );
|
||||
m_gal->SetLineWidth( aContainer->GetThermalReliefCopperBridge() / 2.0 );
|
||||
|
||||
// FIXME implement hatch mode
|
||||
|
||||
for( polyIterator = polyPoints.begin(); polyIterator != polyPoints.end(); polyIterator++ )
|
||||
{
|
||||
// Find out all of polygons and then draw them
|
||||
if( !polyIterator->end_contour )
|
||||
{
|
||||
corners.push_back( VECTOR2D( *polyIterator ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gal->DrawPolygon( corners );
|
||||
m_gal->DrawPolyline( corners );
|
||||
corners.clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __CLASS_PCB_PAINTER_H
|
||||
#define __CLASS_PCB_PAINTER_H
|
||||
|
||||
#include <layers_id_colors_and_visibility.h>
|
||||
|
||||
#include <painter.h>
|
||||
|
||||
|
||||
class EDA_ITEM;
|
||||
class COLORS_DESIGN_SETTINGS;
|
||||
class BOARD_ITEM;
|
||||
class BOARD;
|
||||
class SEGVIA;
|
||||
class TRACK;
|
||||
class D_PAD;
|
||||
class DRAWSEGMENT;
|
||||
class MODULE;
|
||||
class SEGZONE;
|
||||
class ZONE_CONTAINER;
|
||||
class TEXTE_PCB;
|
||||
class TEXTE_MODULE;
|
||||
|
||||
namespace KiGfx
|
||||
{
|
||||
class GAL;
|
||||
class STROKE_FONT;
|
||||
|
||||
/**
|
||||
* Class PCB_RENDER_SETTINGS
|
||||
* Stores PCB specific render settings.
|
||||
*/
|
||||
class PCB_RENDER_SETTINGS : public RENDER_SETTINGS
|
||||
{
|
||||
public:
|
||||
|
||||
friend class PCB_PAINTER;
|
||||
|
||||
enum ClearanceMode {
|
||||
CL_VIAS = 0x1,
|
||||
CL_PADS = 0x2,
|
||||
CL_TRACKS = 0x4
|
||||
};
|
||||
|
||||
PCB_RENDER_SETTINGS();
|
||||
|
||||
/// @copydoc RENDER_SETTINGS::Update()
|
||||
void Update();
|
||||
|
||||
/// @copydoc RENDER_SETTINGS::ImportLegacyColors()
|
||||
void ImportLegacyColors( COLORS_DESIGN_SETTINGS* aSettings );
|
||||
|
||||
protected:
|
||||
|
||||
/// Colors for all layers (including special, highlighted & darkened versions)
|
||||
COLOR4D m_layerColors [LAYER_COUNT];
|
||||
COLOR4D m_layerColorsHi [LAYER_COUNT];
|
||||
COLOR4D m_layerColorsSel [LAYER_COUNT];
|
||||
COLOR4D m_layerColorsDark[LAYER_COUNT];
|
||||
COLOR4D m_itemColors [END_PCB_VISIBLE_LIST];
|
||||
COLOR4D m_itemColorsHi [END_PCB_VISIBLE_LIST];
|
||||
COLOR4D m_itemColorsSel [END_PCB_VISIBLE_LIST];
|
||||
COLOR4D m_itemColorsDark [END_PCB_VISIBLE_LIST];
|
||||
|
||||
bool m_sketchModeSelect[END_PCB_VISIBLE_LIST];
|
||||
bool m_visibleLayers [LAYER_COUNT];
|
||||
bool m_visibleItems [END_PCB_VISIBLE_LIST];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class PCB_PAINTER
|
||||
* Contains methods for drawing PCB-specific items.
|
||||
*/
|
||||
class PCB_PAINTER : public PAINTER
|
||||
{
|
||||
public:
|
||||
|
||||
PCB_PAINTER( GAL* aGal );
|
||||
|
||||
/// @copydoc PAINTER::Draw()
|
||||
virtual bool Draw( const EDA_ITEM*, int );
|
||||
|
||||
/// @copydoc PAINTER::ApplySettings()
|
||||
virtual void ApplySettings( RENDER_SETTINGS* aSettings )
|
||||
{
|
||||
PAINTER::ApplySettings( aSettings );
|
||||
|
||||
// Store PCB specific render settings
|
||||
m_pcbSettings = dynamic_cast<PCB_RENDER_SETTINGS*> ( aSettings );
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
PCB_RENDER_SETTINGS* m_pcbSettings;
|
||||
|
||||
/// @copydoc PAINTER::getLayerColor()
|
||||
const COLOR4D& getLayerColor( int aLayer, int aNetCode ) const;
|
||||
|
||||
/**
|
||||
* Function getItemColor
|
||||
* Returns color for a special layer (eg. vias/pads holes, texts on front/bottom layer, etc.)
|
||||
* @param aItemType Layer number of the item to be drawn.
|
||||
* @param aNetCode Net number of the item to be drawn.
|
||||
*/
|
||||
const COLOR4D& getItemColor( int aItemType, int aNetCode ) const;
|
||||
|
||||
// Drawing functions for various types of PCB-specific items
|
||||
void draw( const TRACK* );
|
||||
void draw( const SEGVIA*, int );
|
||||
void draw( const D_PAD*, int );
|
||||
void draw( const DRAWSEGMENT* );
|
||||
void draw( const TEXTE_PCB* );
|
||||
void draw( const TEXTE_MODULE*, int );
|
||||
void draw( const ZONE_CONTAINER* );
|
||||
};
|
||||
} // namespace KiGfx
|
||||
|
||||
#endif /* __CLASS_PAINTER_H */
|
|
@ -1,172 +0,0 @@
|
|||
|
||||
|
||||
#if defined(PCBNEW)
|
||||
|
||||
class BOARD;
|
||||
class TRACK;
|
||||
class ZONE_CONTAINER;
|
||||
|
||||
//:
|
||||
|
||||
#elif defined(EESCHEMA)
|
||||
|
||||
class SCH_SHEET;
|
||||
//:
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Class PAINTER
|
||||
* contains all the knowledge about how to draw any graphical object onto
|
||||
* any particular output device.
|
||||
* This knowledge is held outside the individual graphical objects so that
|
||||
* alternative output devices may be used, and so that the graphical objects
|
||||
* themselves to not contain drawing routines. Drawing routines in the objects
|
||||
* cause problems with usages of the objects as simple container objects in
|
||||
* DLL/DSOs.
|
||||
*/
|
||||
class PAINTER
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
/**
|
||||
* Constructor PAINTER( wxDC& )
|
||||
* initializes this object for painting on any of the polymorphic
|
||||
* wxDC derivatives.
|
||||
*
|
||||
* @param aDC is a reference to a polymorphic wx device context on which
|
||||
* to draw. It can be any of the wxDC derivatives.
|
||||
* No ownership is given to this PAINTER of aDC.
|
||||
*/
|
||||
PAINTER( wxDC& aDC ) :
|
||||
m_dc( aDC ),
|
||||
m_highlight( false ),
|
||||
m_grayed( false )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined(PCBNEW)
|
||||
|
||||
void Draw( const BOARD_ITEM* );
|
||||
|
||||
#elif defined(EESCHEMA)
|
||||
|
||||
void Draw( const SCH_ITEM* );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
|
||||
wxDC& m_dc;
|
||||
|
||||
// drawing state information.
|
||||
bool m_highlite;
|
||||
bool m_grayed;
|
||||
|
||||
|
||||
#if defined(PCBNEW)
|
||||
|
||||
void draw( const TRACK* );
|
||||
void draw( const MODULE* );
|
||||
void draw( const EDGE_MODULE* );
|
||||
// :
|
||||
|
||||
#elif defined(EESCHEMA)
|
||||
void draw( const SCH_WIRE* );
|
||||
// :
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(PCBNEW)
|
||||
|
||||
void PAINTER::Draw( const BOARD_ITEM* aItem )
|
||||
{
|
||||
// the "cast" applied in here clarifies which overloaded draw() is called
|
||||
|
||||
switch( aItem->Type() )
|
||||
{
|
||||
case PCB_MODULE_T:
|
||||
draw( (MODULE*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_PAD_T:
|
||||
draw( (D_PAD*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_LINE_T:
|
||||
draw( (TEXTE_PCB*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_TEXT_T:
|
||||
draw( (TEXTE_PCB*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_MODULE_TEXT_T:
|
||||
draw( (TEXTE_PCB*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_MODULE_EDGE_T:
|
||||
draw( (EDGE_MODULE*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_TRACE_T:
|
||||
draw( (TRACKE*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_VIA_T:
|
||||
draw( (VIA*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_ZONE_T:
|
||||
draw( (SEGZONE*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_MARKER_T:
|
||||
draw( (MARKER_PCB*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_DIMENSION_T:
|
||||
draw( (DIMENSION*) aItem );
|
||||
break;
|
||||
|
||||
case PCB_TARGET_T:
|
||||
draw( (TARGET*) aItem );
|
||||
break;
|
||||
|
||||
|
||||
case PCB_ZONE_AREA_T:
|
||||
draw( (ZONE_CONTAINER*) aItem );
|
||||
break;
|
||||
|
||||
/* not used
|
||||
case PCB_ITEM_LIST_T:
|
||||
draw( (BOARD_ITEM_LIST*) aItem );
|
||||
break;
|
||||
*/
|
||||
|
||||
default:
|
||||
; // nothing
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(EESCHEMA)
|
||||
|
||||
void PAINTER::Draw( const SCH_ITEM* aItem )
|
||||
{
|
||||
// the "cast" applied in here clarifies which overloaded draw() is called
|
||||
|
||||
switch( aItem->Type() )
|
||||
{
|
||||
//:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue