diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 0f3efa3fc4..53593c3cc9 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -347,6 +348,61 @@ void CAIRO_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControl } +void CAIRO_GAL::DrawBitmap( const BITMAP_BASE& aBitmap ) +{ + int ppi = aBitmap.GetPPI(); + double worldIU_per_mm = 1/(worldUnitLength/2.54)/1000; + double pix_size_iu = worldIU_per_mm * ( 25.4 / ppi ); + int w = aBitmap.GetSizePixels().x; + int h = aBitmap.GetSizePixels().y; + + cairo_save( currentContext ); + + // Set the pixel scaling factor: + cairo_scale( currentContext, pix_size_iu, pix_size_iu ); + // The position of the bitmap is the bitmap center. + // move the draw origin to the top left bitmap corner: + cairo_translate( currentContext, -w/2, -h/2 ); + + cairo_new_path( currentContext ); + cairo_surface_t *image; + image = cairo_image_surface_create( CAIRO_FORMAT_RGB24, w, h ); + cairo_surface_flush( image ); + + unsigned char* pix_buffer = cairo_image_surface_get_data( image ); + // The pixel buffer of the initial bitmap: + auto bm_pix_buffer = (( BITMAP_BASE&)aBitmap).GetImageData(); + + // Copy the source bitmap to the cairo bitmap buffer. + // In cairo bitmap buffer, a RGB24 bitmap is a RGB pixel packed into a uint_32 + // 24 low bits only are used. + for( int row = 0; row < h; row++ ) + { + for( int col = 0; col < w; col++ ) + { + // Build the RGB24 pixel: + uint32_t pixel = bm_pix_buffer->GetRed( col, row ) << 16; + pixel += bm_pix_buffer->GetGreen( col, row ) << 8; + pixel += bm_pix_buffer->GetBlue( col, row ); + + // Write the pixel to the cairo image buffer: + uint32_t* pix_ptr = (uint32_t*) pix_buffer; + *pix_ptr = pixel; + pix_buffer += 4; + } + } + + cairo_surface_mark_dirty( image ); + cairo_set_source_surface( currentContext, image, 0, 0 ); + cairo_paint( currentContext ); + cairo_surface_destroy( image ); + + isElementAdded = true; + + cairo_restore( currentContext ); +} + + void CAIRO_GAL::ResizeScreen( int aWidth, int aHeight ) { screenSize = VECTOR2I( aWidth, aHeight ); diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 159d5a2f9c..ff68a59942 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -899,6 +900,46 @@ void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aContro } +void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap ) +{ + int ppi = aBitmap.GetPPI(); + double worldIU_per_mm = 1/(worldUnitLength/2.54)/1000; + double pix_size_iu = worldIU_per_mm * ( 25.4 / ppi ); + + Save(); + + // Set the pixel scaling factor: + currentManager->Scale( pix_size_iu, pix_size_iu, 0 ); + // The position of the bitmap is the bitmap center. + // move the draw origin to the top left bitmap corner: + currentManager->Translate( -aBitmap.GetSizePixels().x/2, -aBitmap.GetSizePixels().y/2, 0 ); + + isFillEnabled = true; + isStrokeEnabled = false; + + // The pixel buffer of the initial bitmap: + auto bm_pix_buffer = (( BITMAP_BASE&)aBitmap).GetImageData(); + + for( int row = 0; row < aBitmap.GetSizePixels().y; row++ ) + { + VECTOR2D pos( 0, row ); + + for( int col = 0; col < aBitmap.GetSizePixels().x; col++ ) + { + pos.x = col; + SetFillColor( COLOR4D( bm_pix_buffer->GetRed( col, row )/255.0, + bm_pix_buffer->GetGreen( col, row )/255.0, + bm_pix_buffer->GetBlue( col, row )/255.0, + 1.0 ) ); + VECTOR2D end = pos + 1.0; // Size of the rectangle = 1 pixel + DrawRectangle( pos, end ); + } + } + + Restore(); +} + + void OPENGL_GAL::BitmapText( const wxString& aText, const VECTOR2D& aPosition, double aRotationAngle ) { diff --git a/common/worksheet_viewitem.cpp b/common/worksheet_viewitem.cpp index 15924033ab..2910d3d01f 100644 --- a/common/worksheet_viewitem.cpp +++ b/common/worksheet_viewitem.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -119,6 +120,7 @@ void WORKSHEET_VIEWITEM::ViewDraw( int aLayer, VIEW* aView ) const break; case WS_DRAW_ITEM_BASE::wsg_bitmap: + draw( static_cast( item ), gal ); break; } @@ -198,6 +200,17 @@ void WORKSHEET_VIEWITEM::draw( const WS_DRAW_ITEM_TEXT* aItem, GAL* aGal ) const } +void WORKSHEET_VIEWITEM::draw( const WS_DRAW_ITEM_BITMAP* aItem, GAL* aGal ) const +{ + aGal->Save(); + VECTOR2D position = aItem->GetPosition(); + aGal->Translate( position ); + WORKSHEET_DATAITEM_BITMAP* parent = static_cast( aItem->GetParent() ); + aGal->DrawBitmap( *parent->m_ImageBitmap ); + aGal->Restore(); +} + + void WORKSHEET_VIEWITEM::drawBorder( GAL* aGal ) const { VECTOR2D origin = VECTOR2D( 0.0, 0.0 ); diff --git a/include/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h index 331794fe46..bd4e63a9b1 100644 --- a/include/gal/cairo/cairo_gal.h +++ b/include/gal/cairo/cairo_gal.h @@ -137,6 +137,9 @@ public: virtual void DrawCurve( const VECTOR2D& startPoint, const VECTOR2D& controlPointA, const VECTOR2D& controlPointB, const VECTOR2D& endPoint ) override; + /// @copydoc GAL::DrawBitmap() + virtual void DrawBitmap( const BITMAP_BASE& aBitmap ) override; + // -------------- // Screen methods // -------------- diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index b3d571a34e..1cca778d10 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -41,6 +41,7 @@ class SHAPE_LINE_CHAIN; class SHAPE_POLY_SET; +class BITMAP_BASE; namespace KIGFX { @@ -179,6 +180,11 @@ public: virtual void DrawCurve( const VECTOR2D& startPoint, const VECTOR2D& controlPointA, const VECTOR2D& controlPointB, const VECTOR2D& endPoint ) {}; + /** + * @brief Draw a bitmap image. + */ + virtual void DrawBitmap( const BITMAP_BASE& aBitmap ) {}; + // -------------- // Screen methods // -------------- diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index c82f9fe4e5..b02f27f7a5 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -149,6 +149,9 @@ public: virtual void DrawCurve( const VECTOR2D& startPoint, const VECTOR2D& controlPointA, const VECTOR2D& controlPointB, const VECTOR2D& endPoint ) override; + /// @copydoc GAL::DrawBitmap() + virtual void DrawBitmap( const BITMAP_BASE& aBitmap ) override; + /// @copydoc GAL::BitmapText() virtual void BitmapText( const wxString& aText, const VECTOR2D& aPosition, double aRotationAngle ) override; diff --git a/include/worksheet_shape_builder.h b/include/worksheet_shape_builder.h index cd65ae6c01..c30f58fc88 100644 --- a/include/worksheet_shape_builder.h +++ b/include/worksheet_shape_builder.h @@ -361,7 +361,7 @@ public: */ virtual bool HitTestStartPoint( const wxPoint& aPosition) override; - const wxPoint GetPosition() { return m_pos; } + const wxPoint GetPosition() const { return m_pos; } }; /* diff --git a/include/worksheet_viewitem.h b/include/worksheet_viewitem.h index 2a6115e705..c2edb866d8 100644 --- a/include/worksheet_viewitem.h +++ b/include/worksheet_viewitem.h @@ -39,6 +39,7 @@ class WS_DRAW_ITEM_LINE; class WS_DRAW_ITEM_RECT; class WS_DRAW_ITEM_POLYGON; class WS_DRAW_ITEM_TEXT; +class WS_DRAW_ITEM_BITMAP; namespace KIGFX { @@ -163,6 +164,7 @@ protected: void draw( const WS_DRAW_ITEM_RECT* aItem, GAL* aGal ) const; void draw( const WS_DRAW_ITEM_POLYGON* aItem, GAL* aGal ) const; void draw( const WS_DRAW_ITEM_TEXT* aItem, GAL* aGal ) const; + void draw( const WS_DRAW_ITEM_BITMAP* aItem, GAL* aGal ) const; /// Draws a border that determines the page size. void drawBorder( GAL* aGal ) const;