diff --git a/common/bitmap_base.cpp b/common/bitmap_base.cpp index 6eb5c5cf6e..f6851caa54 100644 --- a/common/bitmap_base.cpp +++ b/common/bitmap_base.cpp @@ -37,9 +37,12 @@ BITMAP_BASE::BITMAP_BASE( const VECTOR2I& pos ) m_scale = 1.0; // 1.0 = original bitmap size m_bitmap = nullptr; m_image = nullptr; + m_originalImage = nullptr; m_ppi = 300; // the bitmap definition. the default is 300PPI m_pixelSizeIu = 254000.0 / m_ppi; // a pixel size value OK for bitmaps using 300 PPI // for Eeschema which uses currently 254000PPI + m_isMirrored = false; + m_rotation = ANGLE_0; } @@ -48,14 +51,18 @@ BITMAP_BASE::BITMAP_BASE( const BITMAP_BASE& aSchBitmap ) m_scale = aSchBitmap.m_scale; m_ppi = aSchBitmap.m_ppi; m_pixelSizeIu = aSchBitmap.m_pixelSizeIu; + m_isMirrored = aSchBitmap.m_isMirrored; + m_rotation = aSchBitmap.m_rotation; m_image = nullptr; m_bitmap = nullptr; + m_originalImage = nullptr; if( aSchBitmap.m_image ) { m_image = new wxImage( *aSchBitmap.m_image ); m_bitmap = new wxBitmap( *m_image ); + m_originalImage = new wxImage( *aSchBitmap.m_originalImage ); m_imageId = aSchBitmap.m_imageId; } } @@ -65,17 +72,21 @@ void BITMAP_BASE::SetImage( wxImage* aImage ) { delete m_image; m_image = aImage; + delete m_originalImage; + m_originalImage = new wxImage( *aImage ); rebuildBitmap(); } -void BITMAP_BASE::rebuildBitmap() +void BITMAP_BASE::rebuildBitmap( bool aResetID ) { if( m_bitmap ) delete m_bitmap; m_bitmap = new wxBitmap( *m_image ); - m_imageId = KIID(); + + if( aResetID ) + m_imageId = KIID(); } @@ -83,10 +94,13 @@ void BITMAP_BASE::ImportData( BITMAP_BASE* aItem ) { *m_image = *aItem->m_image; *m_bitmap = *aItem->m_bitmap; + *m_originalImage = *aItem->m_originalImage; m_imageId = aItem->m_imageId; m_scale = aItem->m_scale; m_ppi = aItem->m_ppi; m_pixelSizeIu = aItem->m_pixelSizeIu; + m_isMirrored = aItem->m_isMirrored; + m_rotation = aItem->m_rotation; } @@ -99,6 +113,8 @@ bool BITMAP_BASE::ReadImageFile( wxInputStream& aInStream ) delete m_image; m_image = new_image.release(); + delete m_originalImage; + m_originalImage = new wxImage( *m_image ); rebuildBitmap(); return true; @@ -117,6 +133,8 @@ bool BITMAP_BASE::ReadImageFile( const wxString& aFullFilename ) delete m_image; m_image = new_image; + delete m_originalImage; + m_originalImage = new wxImage( *m_image ); rebuildBitmap(); return true; @@ -352,7 +370,8 @@ void BITMAP_BASE::Mirror( bool aVertically ) if( m_image ) { *m_image = m_image->Mirror( not aVertically ); - rebuildBitmap(); + m_isMirrored = !m_isMirrored; + rebuildBitmap( false ); } } @@ -362,7 +381,8 @@ void BITMAP_BASE::Rotate( bool aRotateCCW ) if( m_image ) { *m_image = m_image->Rotate90( aRotateCCW ); - rebuildBitmap(); + m_rotation += ( aRotateCCW ? -ANGLE_90 : ANGLE_90 ); + rebuildBitmap( false ); } } diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 4d1e38030f..16799a8cbb 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -186,7 +186,7 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap ) bmp.size = ( bmp.w + extra_w ) * bmp.h * 4; auto buf = std::make_unique( bmp.size ); - const wxImage& imgData = *aBitmap->GetImageData(); + const wxImage& imgData = *aBitmap->GetOriginalImageData(); for( int y = 0; y < bmp.h; y++ ) { @@ -1407,6 +1407,13 @@ void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend ) if( !glIsTexture( texture_id ) ) // ensure the bitmap texture is still valid return; + glMatrixMode( GL_TEXTURE ); + glPushMatrix(); + glTranslated( 0.5, 0.5, 0.5 ); + glRotated( aBitmap.Rotation().AsDegrees(), 0, 0, 1 ); + glTranslated( -0.5, -0.5, -0.5 ); + + glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glTranslated( trans.x, trans.y, trans.z ); @@ -1414,18 +1421,21 @@ void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend ) glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, texture_id ); + float texStartX = aBitmap.IsMirrored() ? 1.0 : 0.0; + float texEndX = aBitmap.IsMirrored() ? 0.0 : 1.0; + glBegin( GL_QUADS ); glColor4f( 1.0, 1.0, 1.0, alpha ); - glTexCoord2f( 0.0, 0.0 ); + glTexCoord2f( texStartX, 0.0 ); glVertex3f( v0.x, v0.y, m_layerDepth ); glColor4f( 1.0, 1.0, 1.0, alpha ); - glTexCoord2f( 1.0, 0.0 ); + glTexCoord2f( texEndX, 0.0 ); glVertex3f( v1.x, v0.y, m_layerDepth ); glColor4f( 1.0, 1.0, 1.0, alpha ); - glTexCoord2f( 1.0, 1.0 ); + glTexCoord2f( texEndX, 1.0 ); glVertex3f( v1.x, v1.y, m_layerDepth ); glColor4f( 1.0, 1.0, 1.0, alpha ); - glTexCoord2f( 0.0, 1.0 ); + glTexCoord2f( texStartX, 1.0 ); glVertex3f( v0.x, v1.y, m_layerDepth ); glEnd(); @@ -1436,6 +1446,10 @@ void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend ) #endif glPopMatrix(); + + glMatrixMode( GL_TEXTURE ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); } diff --git a/include/bitmap_base.h b/include/bitmap_base.h index fc68898c28..89c510c710 100644 --- a/include/bitmap_base.h +++ b/include/bitmap_base.h @@ -59,6 +59,7 @@ public: { delete m_bitmap; delete m_image; + delete m_originalImage; } /* @@ -70,6 +71,8 @@ public: wxImage* GetImageData() { return m_image; } const wxImage* GetImageData() const { return m_image; } + const wxImage* GetOriginalImageData() const { return m_originalImage; } + void SetImage( wxImage* aImage ); double GetScale() const { return m_scale; } @@ -207,6 +210,9 @@ public: void ConvertToGreyscale(); + bool IsMirrored() const { return m_isMirrored; } + EDA_ANGLE Rotation() const { return m_rotation; } + /** * Plot bitmap on plotter. * @@ -225,12 +231,15 @@ private: * Rebuild the internal bitmap used to draw/plot image. * * This must be called after a #m_image change. + * + * @param aResetID is used to reset the cache ID used for OpenGL rendering. */ - void rebuildBitmap(); + void rebuildBitmap( bool aResetID = true ); double m_scale; // The scaling factor of the bitmap // With m_pixelSizeIu, controls the actual draw size wxImage* m_image; // the raw image data (png format) + wxImage* m_originalImage; // Raw image data, not transformed by rotate/mirror wxBitmap* m_bitmap; // the bitmap used to draw/plot image double m_pixelSizeIu; // The scaling factor of the bitmap // to convert the bitmap size (in pixels) @@ -238,6 +247,8 @@ private: // Usually does not change int m_ppi; // the bitmap definition. the default is 300PPI KIID m_imageId; + bool m_isMirrored; // Used for OpenGL rendering only + EDA_ANGLE m_rotation; // Used for OpenGL rendering only };