KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Maciej Suminski <[email protected]>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
28
30#include <wx/log.h>
31
32using namespace KIGFX;
33
34CAIRO_COMPOSITOR::CAIRO_COMPOSITOR( cairo_t** aMainContext ) :
35 m_current( 0 ),
36 m_currentContext( aMainContext ),
37 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
51
52
54{
55 // Nothing has to be done
56}
57
58
60{
61 switch( aMode )
62 {
63 case GAL_ANTIALIASING_MODE::AA_FAST: m_currentAntialiasingMode = CAIRO_ANTIALIAS_FAST; break;
64 case GAL_ANTIALIASING_MODE::AA_HIGHQUALITY: m_currentAntialiasingMode = CAIRO_ANTIALIAS_GOOD; break;
65 default: m_currentAntialiasingMode = CAIRO_ANTIALIAS_NONE;
66 }
67
68 clean();
69}
70
71
72void CAIRO_COMPOSITOR::Resize( unsigned int aWidth, unsigned int aHeight )
73{
74 clean();
75
76 m_width = aWidth;
77 m_height = aHeight;
78
79 m_stride = cairo_format_stride_for_width( CAIRO_FORMAT_ARGB32, m_width );
81}
82
83
85{
86 // Pixel storage
87 BitmapPtr bitmap = new uint8_t[m_bufferSize]();
88
89 // Create the Cairo surface
90 cairo_surface_t* surface = cairo_image_surface_create_for_data(
91 (unsigned char*) bitmap, CAIRO_FORMAT_ARGB32, m_width, m_height, m_stride );
92 cairo_t* context = cairo_create( surface );
93
94#ifdef DEBUG
95 cairo_status_t status = cairo_status( context );
96 wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, wxT( "Cairo context creation error" ) );
97#endif /* DEBUG */
98
99 // Set default settings for the buffer
100 cairo_set_antialias( context, m_currentAntialiasingMode );
101
102 // Use the same transformation matrix as the main context
103 cairo_get_matrix( m_mainContext, &m_matrix );
104 cairo_set_matrix( context, &m_matrix );
105
106 // Store the new buffer
107 CAIRO_BUFFER buffer = { context, surface, bitmap };
108 m_buffers.push_back( buffer );
109
110 return usedBuffers();
111}
112
113
114void CAIRO_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
115{
116 wxASSERT_MSG( aBufferHandle <= usedBuffers(), wxT( "Tried to use a not existing buffer" ) );
117
118 // Get currently used transformation matrix, so it can be applied to the new buffer
119 cairo_get_matrix( *m_currentContext, &m_matrix );
120
121 m_current = aBufferHandle - 1;
123
124 // Apply the current transformation matrix
125 cairo_set_matrix( *m_currentContext, &m_matrix );
126}
127
128
130{
131}
132
133
135{
136 // Clear the pixel storage
137 memset( m_buffers[m_current].bitmap, 0x00, m_bufferSize );
138}
139
140
141void CAIRO_COMPOSITOR::DrawBuffer( unsigned int aSourceHandle, unsigned int aDestHandle,
142 cairo_operator_t op )
143{
144 wxASSERT_MSG( aSourceHandle <= usedBuffers() && aDestHandle <= usedBuffers(),
145 wxT( "Tried to use a not existing buffer" ) );
146
147 // Reset the transformation matrix, so it is possible to composite images using
148 // screen coordinates instead of world coordinates
149 cairo_get_matrix( m_mainContext, &m_matrix );
150 cairo_identity_matrix( m_mainContext );
151
152 // Draw the selected buffer contents
153 cairo_t* ct = cairo_create( m_buffers[aDestHandle - 1].surface );
154 cairo_set_operator( ct, op );
155 cairo_set_source_surface( ct, m_buffers[aSourceHandle - 1].surface, 0.0, 0.0 );
156 cairo_paint( ct );
157 cairo_destroy( ct );
158
159 // Restore the transformation matrix
160 cairo_set_matrix( m_mainContext, &m_matrix );
161}
162
163
164void CAIRO_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
165{
166 wxASSERT_MSG( aBufferHandle <= usedBuffers(), wxT( "Tried to use a not existing buffer" ) );
167
168 // Reset the transformation matrix, so it is possible to composite images using
169 // screen coordinates instead of world coordinates
170 cairo_get_matrix( m_mainContext, &m_matrix );
171 cairo_identity_matrix( m_mainContext );
172
173 // Draw the selected buffer contents
174 cairo_set_source_surface( m_mainContext, m_buffers[aBufferHandle - 1].surface, 0.0, 0.0 );
175 cairo_paint( m_mainContext );
176
177 // Restore the transformation matrix
178 cairo_set_matrix( m_mainContext, &m_matrix );
179}
180
181
185
186
188{
189 CAIRO_BUFFERS::const_iterator it;
190
191 for( it = m_buffers.begin(); it != m_buffers.end(); ++it )
192 {
193 cairo_destroy( it->context );
194 cairo_surface_destroy( it->surface );
195 delete[] it->bitmap;
196 }
197
198 m_buffers.clear();
199}
Class that handles multitarget rendering (ie.
unsigned int m_bufferSize
Amount of memory needed to store a buffer.
virtual void Present() override
Call this to present the output buffer to the screen.
unsigned int m_stride
Stride to use given the desired format and width.
CAIRO_COMPOSITOR(cairo_t **aMainContext)
cairo_antialias_t m_currentAntialiasingMode
virtual unsigned int CreateBuffer() override
Prepare a new buffer that may be used as a rendering target.
void SetAntialiasingMode(GAL_ANTIALIASING_MODE aMode)
cairo_t * m_mainContext
Rendering target used for compositing (the main display)
virtual void ClearBuffer(const COLOR4D &aColor) override
Clear the selected buffer (set by the SetBuffer() function).
virtual void Begin() override
Call this at the beginning of each frame.
void clean()
Perform freeing of resources.
void DrawBuffer(unsigned int aSourceHandle, unsigned int aDestHandle, cairo_operator_t op)
Paints source to destination using the cairo operator.
unsigned int usedBuffers()
Return number of currently used buffers.
cairo_matrix_t m_matrix
Transformation matrix.
cairo_t ** m_currentContext
Pointer to the current context, so it can be changed.
unsigned int m_current
Currently used buffer handle.
CAIRO_BUFFERS m_buffers
Stores information about initialized buffers.
virtual void Resize(unsigned int aWidth, unsigned int aHeight) override
Clear the state of COMPOSITOR, so it has to be reinitialized again with the new dimensions.
virtual void SetBuffer(unsigned int aBufferHandle) override
Set the selected buffer as the rendering target.
virtual void Initialize() override
Perform primary initialization, necessary to use the object.
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
unsigned int m_height
Height of the buffer (in pixels)
Definition compositor.h:109
unsigned int m_width
Width of the buffer (in pixels)
Definition compositor.h:108
The Cairo implementation of the graphics abstraction layer.
Definition eda_group.h:29