1 /* 2 * This program source code file is part of KiCad, a free EDA CAD application. 3 * 4 * Copyright (C) 2013 CERN 5 * Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors. 6 * @author Maciej Suminski <maciej.suminski@cern.ch> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 2 11 * of the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, you may find one here: 20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 21 * or you may search the http://www.gnu.org website for the version 2 license, 22 * or you may write to the Free Software Foundation, Inc., 23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 24 */ 25 26 /** 27 * @file cairo_compositor.h 28 * Class that handles multitarget rendering (ie. to different textures/surfaces) and 29 * later compositing into a single image (Cairo flavour). 30 */ 31 32 #ifndef CAIRO_COMPOSITOR_H_ 33 #define CAIRO_COMPOSITOR_H_ 34 35 #include <gal/compositor.h> 36 #include <gal/gal_display_options.h> 37 #include <cairo.h> 38 39 #include <cstdint> 40 #include <deque> 41 42 namespace KIGFX 43 { 44 class CAIRO_COMPOSITOR : public COMPOSITOR 45 { 46 public: 47 CAIRO_COMPOSITOR( cairo_t** aMainContext ); 48 virtual ~CAIRO_COMPOSITOR(); 49 50 /// @copydoc COMPOSITOR::Initialize() 51 virtual void Initialize() override; 52 53 /// @copydoc COMPOSITOR::Resize() 54 virtual void Resize( unsigned int aWidth, unsigned int aHeight ) override; 55 56 /// @copydoc COMPOSITOR::CreateBuffer() 57 virtual unsigned int CreateBuffer() override; 58 59 /// @copydoc COMPOSITOR::GetBuffer() GetBuffer()60 inline virtual unsigned int GetBuffer() const override 61 { 62 return m_current + 1; 63 } 64 65 /// @copydoc COMPOSITOR::SetBuffer() 66 virtual void SetBuffer( unsigned int aBufferHandle ) override; 67 68 /// @copydoc COMPOSITOR::Begin() 69 virtual void Begin() override; 70 71 /// @copydoc COMPOSITOR::ClearBuffer() 72 virtual void ClearBuffer( const COLOR4D& aColor ) override; 73 74 /** 75 * Paints source to destination using the cairo operator. Useful for differential mode. 76 * 77 * @param aSourceHandle Source buffer to paint 78 * @param aDestHandle Destination buffer to paint on to 79 * @param op Painting operation 80 */ 81 void DrawBuffer( unsigned int aSourceHandle, unsigned int aDestHandle, cairo_operator_t op ); 82 83 /// @copydoc COMPOSITOR::DrawBuffer() 84 virtual void DrawBuffer( unsigned int aBufferHandle ) override; 85 86 /// @copydoc COMPOSITOR::Present() 87 virtual void Present() override; 88 89 void SetAntialiasingMode( CAIRO_ANTIALIASING_MODE aMode ); // clears all buffers GetAntialiasingMode()90 CAIRO_ANTIALIASING_MODE GetAntialiasingMode() const 91 { 92 switch( m_currentAntialiasingMode ) 93 { 94 case CAIRO_ANTIALIAS_FAST: 95 return CAIRO_ANTIALIASING_MODE::FAST; 96 case CAIRO_ANTIALIAS_GOOD: 97 return CAIRO_ANTIALIASING_MODE::GOOD; 98 default: 99 return CAIRO_ANTIALIASING_MODE::NONE; 100 } 101 } 102 103 /** 104 * Set a context to be treated as the main context (ie. as a target of buffers rendering and 105 * as a source of settings for newly created buffers). 106 * 107 * @param aMainContext is the context that should be treated as the main one. 108 */ SetMainContext(cairo_t * aMainContext)109 inline virtual void SetMainContext( cairo_t* aMainContext ) 110 { 111 m_mainContext = aMainContext; 112 113 // Use the context's transformation matrix 114 cairo_get_matrix( m_mainContext, &m_matrix ); 115 } 116 117 protected: 118 /** 119 * Perform freeing of resources. 120 */ 121 void clean(); 122 123 /// Return number of currently used buffers. usedBuffers()124 unsigned int usedBuffers() 125 { 126 return m_buffers.size(); 127 } 128 129 typedef uint32_t* BitmapPtr; 130 struct CAIRO_BUFFER 131 { 132 cairo_t* context; ///< Main texture handle 133 cairo_surface_t* surface; ///< Point to which an image from texture is attached 134 BitmapPtr bitmap; ///< Pixel storage 135 }; 136 137 unsigned int m_current; ///< Currently used buffer handle 138 typedef std::deque<CAIRO_BUFFER> CAIRO_BUFFERS; 139 140 /// Pointer to the current context, so it can be changed 141 cairo_t** m_currentContext; 142 143 /// Rendering target used for compositing (the main display) 144 cairo_t* m_mainContext; 145 146 /// Transformation matrix 147 cairo_matrix_t m_matrix; 148 149 /// Stores information about initialized buffers 150 CAIRO_BUFFERS m_buffers; 151 152 unsigned int m_stride; ///< Stride to use given the desired format and width 153 unsigned int m_bufferSize; ///< Amount of memory needed to store a buffer 154 155 cairo_antialias_t m_currentAntialiasingMode; 156 }; 157 } // namespace KIGFX 158 159 #endif /* COMPOSITOR_H_ */ 160