KiCad PCB EDA Suite
cairo_compositor.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013 CERN
5  * @author Maciej Suminski <maciej.suminski@cern.ch>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http:O//www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
32 #include <wx/log.h>
33 
34 using namespace KIGFX;
35 
36 CAIRO_COMPOSITOR::CAIRO_COMPOSITOR( cairo_t** aMainContext ) :
37  m_current( 0 ), m_currentContext( aMainContext ), m_mainContext( *aMainContext ),
38  m_currentAntialiasingMode( CAIRO_ANTIALIAS_DEFAULT )
39 {
40  // Do not have uninitialized members:
41  cairo_matrix_init_identity( &m_matrix );
42  m_stride = 0;
43  m_bufferSize = 0;
44 }
45 
46 
48 {
49  clean();
50 }
51 
52 
54 {
55  // Nothing has to be done
56 }
57 
58 
60 {
61 
62  switch( aMode )
63  {
65  m_currentAntialiasingMode = CAIRO_ANTIALIAS_FAST;
66  break;
68  m_currentAntialiasingMode = CAIRO_ANTIALIAS_GOOD;
69  break;
71  m_currentAntialiasingMode = CAIRO_ANTIALIAS_BEST;
72  break;
73  default:
74  m_currentAntialiasingMode = CAIRO_ANTIALIAS_NONE;
75  }
76 
77  clean();
78 }
79 
80 
81 void CAIRO_COMPOSITOR::Resize( unsigned int aWidth, unsigned int aHeight )
82 {
83  clean();
84 
85  m_width = aWidth;
86  m_height = aHeight;
87 
88  m_stride = cairo_format_stride_for_width( CAIRO_FORMAT_ARGB32, m_width );
90 }
91 
92 
94 {
95  // Pixel storage
96  BitmapPtr bitmap( new unsigned int[m_bufferSize] );
97 
98  memset( bitmap.get(), 0x00, m_bufferSize * sizeof(int) );
99 
100  // Create the Cairo surface
101  cairo_surface_t* surface = cairo_image_surface_create_for_data(
102  (unsigned char*) bitmap.get(),
103  CAIRO_FORMAT_ARGB32, m_width,
104  m_height, m_stride );
105  cairo_t* context = cairo_create( surface );
106 #ifdef __WXDEBUG__
107  cairo_status_t status = cairo_status( context );
108  wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, wxT( "Cairo context creation error" ) );
109 #endif /* __WXDEBUG__ */
110 
111  // Set default settings for the buffer
112  cairo_set_antialias( context, m_currentAntialiasingMode );
113 
114  // Use the same transformation matrix as the main context
115  cairo_get_matrix( m_mainContext, &m_matrix );
116  cairo_set_matrix( context, &m_matrix );
117 
118  // Store the new buffer
119  CAIRO_BUFFER buffer = { context, surface, bitmap };
120  m_buffers.push_back( buffer );
121 
122  return usedBuffers();
123 }
124 
125 
126 void CAIRO_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
127 {
128  wxASSERT_MSG( aBufferHandle <= usedBuffers(), wxT( "Tried to use a not existing buffer" ) );
129 
130  // Get currently used transformation matrix, so it can be applied to the new buffer
131  cairo_get_matrix( *m_currentContext, &m_matrix );
132 
133  m_current = aBufferHandle - 1;
135 
136  // Apply the current transformation matrix
137  cairo_set_matrix( *m_currentContext, &m_matrix );
138 }
139 
141 {
142 }
143 
145 {
146  // Clear the pixel storage
147  memset( m_buffers[m_current].bitmap.get(), 0x00, m_bufferSize * sizeof(int) );
148 }
149 
150 
151 void CAIRO_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
152 {
153  wxASSERT_MSG( aBufferHandle <= usedBuffers(), wxT( "Tried to use a not existing buffer" ) );
154 
155  // Reset the transformation matrix, so it is possible to composite images using
156  // screen coordinates instead of world coordinates
157  cairo_get_matrix( m_mainContext, &m_matrix );
158  cairo_identity_matrix( m_mainContext );
159 
160  // Draw the selected buffer contents
161  cairo_set_source_surface( m_mainContext, m_buffers[aBufferHandle - 1].surface, 0.0, 0.0 );
162  cairo_paint( m_mainContext );
163 
164  // Restore the transformation matrix
165  cairo_set_matrix( m_mainContext, &m_matrix );
166 }
167 
169 {
170 }
171 
173 {
174  CAIRO_BUFFERS::const_iterator it;
175 
176  for( it = m_buffers.begin(); it != m_buffers.end(); ++it )
177  {
178  cairo_destroy( it->context );
179  cairo_surface_destroy( it->surface );
180  }
181 
182  m_buffers.clear();
183 }
void clean()
Function clean() performs freeing of resources.
unsigned int m_stride
Stride to use given the desired format and width.
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:57
unsigned int m_width
Width of the buffer (in pixels)
Definition: compositor.h:119
virtual void Begin() override
Function Begin() Call this at the beginning of each frame.
virtual void Present() override
Function Present() Call this to present the output buffer to the screen.
unsigned int usedBuffers()
Returns number of currently used buffers.
virtual void ClearBuffer(const COLOR4D &aColor) override
Function ClearBuffer() clears the selected buffer (set by the SetBuffer() function).
virtual void SetBuffer(unsigned int aBufferHandle) override
Function SetBuffer() sets the selected buffer as the rendering target.
unsigned int m_current
Currently used buffer handle.
CAIRO_BUFFERS m_buffers
Stores information about initialized buffers.
Class that handles multitarget rendering (ie.
cairo_antialias_t m_currentAntialiasingMode
cairo_t ** m_currentContext
Pointer to the current context, so it can be changed.
virtual void DrawBuffer(unsigned int aBufferHandle) override
Function DrawBuffer() draws the selected buffer to the output buffer.
void SetAntialiasingMode(CAIRO_ANTIALIASING_MODE aMode)
unsigned int m_bufferSize
Amount of memory needed to store a buffer.
virtual void Initialize() override
Function Reset() performs primary initialiation, necessary to use the object.
boost::shared_array< unsigned int > BitmapPtr
CAIRO_COMPOSITOR(cairo_t **aMainContext)
virtual void Resize(unsigned int aWidth, unsigned int aHeight) override
Function Resize() clears the state of COMPOSITOR, so it has to be reinitialized again with the new di...
cairo_matrix_t m_matrix
Transformation matrix.
cairo_t * m_mainContext
Rendering target used for compositing (the main display)
unsigned int m_height
Height of the buffer (in pixels)
Definition: compositor.h:120
virtual unsigned int CreateBuffer() override
Function CreateBuffer() prepares a new buffer that may be used as a rendering target.
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39