GAL canvases: add DrawBitmap(), using a basic brute force algo for OpenGL, and a optimized code for Cairo. In this fix the brute force means draw each pixel as a rectangle. It works fine, but could be optimized.

This commit is contained in:
jean-pierre charras 2018-06-06 18:59:16 +02:00 committed by Tomasz Wlostowski
parent e750382e75
commit fefc7b8172
8 changed files with 125 additions and 1 deletions

View File

@ -33,6 +33,7 @@
#include <gal/cairo/cairo_compositor.h>
#include <gal/definitions.h>
#include <geometry/shape_poly_set.h>
#include <bitmap_base.h>
#include <limits>
@ -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 );

View File

@ -32,6 +32,7 @@
#include <gl_context_mgr.h>
#include <geometry/shape_poly_set.h>
#include <text_utils.h>
#include <bitmap_base.h>
#include <macros.h>
@ -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 )
{

View File

@ -29,6 +29,7 @@
#include <worksheet_viewitem.h>
#include <worksheet_shape_builder.h>
#include <worksheet_dataitem.h>
#include <gal/graphics_abstraction_layer.h>
#include <painter.h>
#include <layers_id_colors_and_visibility.h>
@ -119,6 +120,7 @@ void WORKSHEET_VIEWITEM::ViewDraw( int aLayer, VIEW* aView ) const
break;
case WS_DRAW_ITEM_BASE::wsg_bitmap:
draw( static_cast<const WS_DRAW_ITEM_BITMAP*>( item ), gal );
break;
}
@ -199,6 +201,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<WORKSHEET_DATAITEM_BITMAP*>( aItem->GetParent() );
aGal->DrawBitmap( *parent->m_ImageBitmap );
aGal->Restore();
}
void WORKSHEET_VIEWITEM::drawBorder( GAL* aGal ) const
{
VECTOR2D origin = VECTOR2D( 0.0, 0.0 );

View File

@ -136,6 +136,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
// --------------

View File

@ -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
// --------------

View File

@ -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;

View File

@ -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; }
};
/*

View File

@ -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;