summaryrefslogtreecommitdiff
path: root/include/gal/cairo
diff options
context:
space:
mode:
Diffstat (limited to 'include/gal/cairo')
-rw-r--r--include/gal/cairo/cairo_compositor.h127
-rw-r--r--include/gal/cairo/cairo_gal.h405
2 files changed, 532 insertions, 0 deletions
diff --git a/include/gal/cairo/cairo_compositor.h b/include/gal/cairo/cairo_compositor.h
new file mode 100644
index 0000000..6d5d74a
--- /dev/null
+++ b/include/gal/cairo/cairo_compositor.h
@@ -0,0 +1,127 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 CERN
+ * @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
+ */
+
+/**
+ * @file cairo_compositor.h
+ * @brief Class that handles multitarget rendering (ie. to different textures/surfaces) and
+ * later compositing into a single image (Cairo flavour).
+ */
+
+#ifndef CAIRO_COMPOSITOR_H_
+#define CAIRO_COMPOSITOR_H_
+
+#include <gal/compositor.h>
+#include <cairo.h>
+#include <boost/smart_ptr/shared_array.hpp>
+#include <deque>
+
+namespace KIGFX
+{
+class CAIRO_COMPOSITOR : public COMPOSITOR
+{
+public:
+ CAIRO_COMPOSITOR( cairo_t** aMainContext );
+ virtual ~CAIRO_COMPOSITOR();
+
+ /// @copydoc COMPOSITOR::Initialize()
+ virtual void Initialize();
+
+ /// @copydoc COMPOSITOR::Resize()
+ virtual void Resize( unsigned int aWidth, unsigned int aHeight );
+
+ /// @copydoc COMPOSITOR::CreateBuffer()
+ virtual unsigned int CreateBuffer();
+
+ /// @copydoc COMPOSITOR::GetBuffer()
+ inline virtual unsigned int GetBuffer() const
+ {
+ return m_current + 1;
+ }
+
+ /// @copydoc COMPOSITOR::SetBuffer()
+ virtual void SetBuffer( unsigned int aBufferHandle );
+
+ /// @copydoc COMPOSITOR::ClearBuffer()
+ virtual void ClearBuffer();
+
+ /// @copydoc COMPOSITOR::DrawBuffer()
+ virtual void DrawBuffer( unsigned int aBufferHandle );
+
+ /**
+ * Function SetMainContext()
+ * Sets a context to be treated as the main context (ie. as a target of buffers rendering and
+ * as a source of settings for newly created buffers).
+ *
+ * @param aMainContext is the context that should be treated as the main one.
+ */
+ inline virtual void SetMainContext( cairo_t* aMainContext )
+ {
+ m_mainContext = aMainContext;
+
+ // Use the context's transformation matrix
+ cairo_get_matrix( m_mainContext, &m_matrix );
+ }
+
+protected:
+ typedef boost::shared_array<unsigned int> BitmapPtr;
+ typedef struct
+ {
+ cairo_t* context; ///< Main texture handle
+ cairo_surface_t* surface; ///< Point to which an image from texture is attached
+ BitmapPtr bitmap; ///< Pixel storage
+ } CAIRO_BUFFER;
+
+ unsigned int m_current; ///< Currently used buffer handle
+ typedef std::deque<CAIRO_BUFFER> CAIRO_BUFFERS;
+
+ /// Pointer to the current context, so it can be changed
+ cairo_t** m_currentContext;
+
+ /// Rendering target used for compositing (the main display)
+ cairo_t* m_mainContext;
+
+ /// Transformation matrix
+ cairo_matrix_t m_matrix;
+
+ /// Stores information about initialized buffers
+ CAIRO_BUFFERS m_buffers;
+
+ unsigned int m_stride; ///< Stride to use given the desired format and width
+ unsigned int m_bufferSize; ///< Amount of memory needed to store a buffer
+
+ /**
+ * Function clean()
+ * performs freeing of resources.
+ */
+ void clean();
+
+ /// Returns number of currently used buffers
+ unsigned int usedBuffers()
+ {
+ return m_buffers.size();
+ }
+};
+} // namespace KIGFX
+
+#endif /* COMPOSITOR_H_ */
diff --git a/include/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h
new file mode 100644
index 0000000..1f395f7
--- /dev/null
+++ b/include/gal/cairo/cairo_gal.h
@@ -0,0 +1,405 @@
+/*
+ * 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>
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <wx/dcbuffer.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
+
+/**
+ * @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_COMPOSITOR;
+
+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();
+
+ /// @copydoc GAL::EndDrawing()
+ virtual void EndDrawing();
+
+ /// @copydoc GAL::DrawLine()
+ virtual void DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
+
+ /// @copydoc GAL::DrawSegment()
+ virtual void DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, double aWidth );
+
+ /// @copydoc GAL::DrawCircle()
+ virtual void DrawCircle( const VECTOR2D& aCenterPoint, double aRadius );
+
+ /// @copydoc GAL::DrawArc()
+ virtual void DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
+ double aStartAngle, double aEndAngle );
+
+ /// @copydoc GAL::DrawRectangle()
+ virtual void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
+
+ /// @copydoc GAL::DrawPolyline()
+ virtual void DrawPolyline( const std::deque<VECTOR2D>& aPointList ) { drawPoly( aPointList ); }
+ virtual void DrawPolyline( const VECTOR2D aPointList[], int aListSize ) { drawPoly( aPointList, aListSize ); }
+
+ /// @copydoc GAL::DrawPolygon()
+ virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList ) { drawPoly( aPointList ); }
+ virtual void DrawPolygon( const VECTOR2D aPointList[], int aListSize ) { drawPoly( aPointList, aListSize ); }
+
+ /// @copydoc GAL::DrawCurve()
+ virtual void DrawCurve( const VECTOR2D& startPoint, const VECTOR2D& controlPointA,
+ const VECTOR2D& controlPointB, const 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( const COLOR4D& aColor );
+
+ // -----------------
+ // Attribute setting
+ // -----------------
+
+ /// @copydoc GAL::SetIsFill()
+ virtual void SetIsFill( bool aIsFillEnabled );
+
+ /// @copydoc GAL::SetIsStroke()
+ virtual void SetIsStroke( bool aIsStrokeEnabled );
+
+ /// @copydoc GAL::SetStrokeColor()
+ virtual void SetStrokeColor( const COLOR4D& aColor );
+
+ /// @copydoc GAL::SetFillColor()
+ virtual void SetFillColor( const COLOR4D& aColor );
+
+ /// @copydoc GAL::SetLineWidth()
+ virtual void SetLineWidth( double aLineWidth );
+
+ /// @copydoc GAL::SetLayerDepth()
+ virtual void SetLayerDepth( double aLayerDepth );
+
+ // --------------
+ // Transformation
+ // --------------
+
+ /// @copydoc GAL::Transform()
+ virtual void Transform( const MATRIX3x3D& aTransformation );
+
+ /// @copydoc GAL::Rotate()
+ virtual void Rotate( double aAngle );
+
+ /// @copydoc GAL::Translate()
+ virtual void Translate( const VECTOR2D& aTranslation );
+
+ /// @copydoc GAL::Scale()
+ virtual void Scale( const 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::ChangeGroupColor()
+ virtual void ChangeGroupColor( int aGroupNumber, const COLOR4D& aNewColor );
+
+ /// @copydoc GAL::ChangeGroupDepth()
+ virtual void ChangeGroupDepth( int aGroupNumber, int aDepth );
+
+ /// @copydoc GAL::DeleteGroup()
+ virtual void DeleteGroup( int aGroupNumber );
+
+ /// @copydoc GAL::ClearCache()
+ virtual void ClearCache();
+
+ // --------------------------------------------------------
+ // Handling the world <-> screen transformation
+ // --------------------------------------------------------
+
+ /// @copydoc GAL::SaveScreen()
+ virtual void SaveScreen();
+
+ /// @copydoc GAL::RestoreScreen()
+ virtual void RestoreScreen();
+
+ /// @copydoc GAL::SetTarget()
+ virtual void SetTarget( RENDER_TARGET aTarget );
+
+ /// @copydoc GAL::GetTarget()
+ virtual RENDER_TARGET GetTarget() const;
+
+ /// @copydoc GAL::ClearTarget()
+ virtual void ClearTarget( RENDER_TARGET aTarget );
+
+ // -------
+ // Cursor
+ // -------
+
+ /// @copydoc GAL::SetCursorSize()
+ virtual void SetCursorSize( unsigned int aCursorSize );
+
+ /// @copydoc GAL::DrawCursor()
+ virtual void DrawCursor( const 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 )
+ {
+ wxPaintEvent redrawEvent;
+ wxPostEvent( paintListener, redrawEvent );
+ }
+ }
+
+ void SetMouseListener( wxEvtHandler* aMouseListener )
+ {
+ mouseListener = aMouseListener;
+ }
+
+ void SetPaintListener( wxEvtHandler* aPaintListener )
+ {
+ paintListener = aPaintListener;
+ }
+
+protected:
+ virtual void drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
+
+private:
+ /// Super class definition
+ typedef GAL super;
+
+ // Compositing variables
+ boost::shared_ptr<CAIRO_COMPOSITOR> compositor; ///< Object for layers compositing
+ unsigned int mainBuffer; ///< Handle to the main buffer
+ unsigned int overlayBuffer; ///< Handle to the overlay buffer
+ RENDER_TARGET currentTarget; ///< Current rendering target
+ bool validCompositor; ///< Compositor initialization flag
+
+ // Variables related to wxWidgets
+ wxWindow* parentWindow; ///< Parent window
+ wxEvtHandler* mouseListener; ///< Mouse listener
+ wxEvtHandler* paintListener; ///< Paint listener
+ 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
+
+ /// Maximum number of arguments for one command
+ static const int MAX_CAIRO_ARGUMENTS = 6;
+
+ /// Definitions for the command recorder
+ enum GRAPHICS_COMMAND
+ {
+ 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_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
+ {
+ GRAPHICS_COMMAND 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
+ } GROUP_ELEMENT;
+
+ // Variables for the grouping function
+ bool isGrouping; ///< Is grouping enabled ?
+ bool isElementAdded; ///< Was an graphic element added ?
+ typedef std::deque<GROUP_ELEMENT> GROUP; ///< A graphic group type definition
+ std::map<int, GROUP> groups; ///< List of graphic groups
+ unsigned int groupCounter; ///< Counter used for generating keys for groups
+ GROUP* currentGroup; ///< Currently used group
+
+ // Variables related to Cairo <-> wxWidgets
+ cairo_matrix_t cairoWorldScreenMatrix; ///< Cairo world to screen transformation matrix
+ cairo_t* currentContext; ///< Currently used Cairo context for drawing
+ cairo_t* context; ///< Cairo image
+ cairo_surface_t* surface; ///< Cairo surface
+ unsigned int* bitmapBuffer; ///< Storage of the cairo image
+ unsigned int* bitmapBufferBackup; ///< Backup storage of the cairo image
+ int stride; ///< Stride value for Cairo
+ bool isInitialized; ///< Are Cairo image & surface ready to use
+ COLOR4D backgroundColor; ///< Background color
+
+ // Methods
+ void storePath(); ///< Store the actual path
+
+ // Event handlers
+ /**
+ * @brief Paint event handler.
+ *
+ * @param aEvent is the paint event.
+ */
+ void onPaint( wxPaintEvent& 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 Prepares cursor bitmap.
+ */
+ virtual void initCursor();
+
+ /**
+ * @brief Blits cursor into the current screen.
+ */
+ virtual void blitCursor( wxBufferedDC& clientDC );
+
+ /// Prepare Cairo surfaces for drawing
+ void initSurface();
+
+ /// Destroy Cairo surfaces when are not needed anymore
+ void deinitSurface();
+
+ /// Allocate the bitmaps for drawing
+ void allocateBitmaps();
+
+ /// Allocate the bitmaps for drawing
+ void deleteBitmaps();
+
+ /// Prepare the compositor
+ void setCompositor();
+
+ /// Drawing polygons & polylines is the same in cairo, so here is the common code
+ void drawPoly( const std::deque<VECTOR2D>& aPointList );
+ void drawPoly( const VECTOR2D aPointList[], int aListSize );
+
+ /**
+ * @brief Returns a valid key that can be used as a new group number.
+ *
+ * @return An unique group number that is not used by any other group.
+ */
+ unsigned int getNewGroupNumber();
+
+ /// Format used to store pixels
+ static const cairo_format_t GAL_FORMAT = CAIRO_FORMAT_RGB24;
+
+ ///> Opacity of a single layer
+ static const float LAYER_ALPHA;
+};
+} // namespace KIGFX
+
+#endif // CAIROGAL_H_