Fix bitmap scale in printouts

Display GALs had an incorrect world unit value set. Now the world unit
value says how many internal units are in an inch, in accord with the comments
in the GAL header. Bitmap drawing code relied on the information about DPI,
so scaling worked differently for display and print GALs.
This commit is contained in:
Maciej Suminski 2018-10-22 00:16:15 +02:00
parent 7ab8171422
commit 64da77538f
10 changed files with 48 additions and 73 deletions

View File

@ -353,8 +353,7 @@ void EDA_DRAW_PANEL_GAL::SetTopLayer( int aLayer )
double EDA_DRAW_PANEL_GAL::GetLegacyZoom() const double EDA_DRAW_PANEL_GAL::GetLegacyZoom() const
{ {
double zoomFactor = m_gal->GetWorldScale() / m_gal->GetZoomFactor(); return m_edaFrame->GetZoomLevelCoeff() / m_gal->GetZoomFactor();
return ( 1.0 / ( zoomFactor * m_view->GetScale() ) );
} }

View File

@ -274,27 +274,21 @@ void CAIRO_GAL_BASE::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aCo
void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap ) void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap )
{ {
int ppi = aBitmap.GetPPI();
// We have to calculate the pixel size in users units to draw the image.
// worldUnitLength is the user unit in GAL unit value
// (GAL unit = 0.1 inch in nanometer = 2.54/1000 in mm).
// worldUnitLength * 1000 / 2.54 is the user unit in mm
double worldIU_per_mm = 1/( worldUnitLength / 0.00254 );
double pix_size_iu = worldIU_per_mm * ( 25.4 / ppi );
int w = aBitmap.GetSizePixels().x;
int h = aBitmap.GetSizePixels().y;
cairo_save( currentContext ); cairo_save( currentContext );
// Set the pixel scaling factor: // We have to calculate the pixel size in users units to draw the image.
cairo_scale( currentContext, pix_size_iu, pix_size_iu ); // worldUnitLength is a factor used for converting IU to inches
double scale = 1.0 / ( aBitmap.GetPPI() * worldUnitLength );
cairo_scale( currentContext, scale, scale );
// The position of the bitmap is the bitmap center. // The position of the bitmap is the bitmap center.
// move the draw origin to the top left bitmap corner: // move the draw origin to the top left bitmap corner:
int w = aBitmap.GetSizePixels().x;
int h = aBitmap.GetSizePixels().y;
cairo_translate( currentContext, -w/2, -h/2 ); cairo_translate( currentContext, -w/2, -h/2 );
cairo_new_path( currentContext ); cairo_new_path( currentContext );
cairo_surface_t *image; cairo_surface_t* image = cairo_image_surface_create( CAIRO_FORMAT_RGB24, w, h );
image = cairo_image_surface_create( CAIRO_FORMAT_RGB24, w, h );
cairo_surface_flush( image ); cairo_surface_flush( image );
unsigned char* pix_buffer = cairo_image_surface_get_data( image ); unsigned char* pix_buffer = cairo_image_surface_get_data( image );

View File

@ -34,9 +34,6 @@
using namespace KIGFX; using namespace KIGFX;
const double GAL::METRIC_UNIT_LENGTH = 1e9;
GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) : GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
options( aDisplayOptions ), options( aDisplayOptions ),
strokeFont( this ) strokeFont( this )
@ -49,8 +46,10 @@ GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
SetLookAtPoint( VECTOR2D( 0, 0 ) ); SetLookAtPoint( VECTOR2D( 0, 0 ) );
SetZoomFactor( 1.0 ); SetZoomFactor( 1.0 );
SetRotation( 0.0 ); SetRotation( 0.0 );
SetWorldUnitLength( 1.0 / METRIC_UNIT_LENGTH * 2.54 ); // 1 inch in nanometers SetWorldUnitLength( 1e-9 /* 1 nm */ / 0.0254 /* 1 inch in meters */ );
SetScreenDPI( 106 ); // Display resolution setting // wxDC::GetPPI() reports 96 DPI, but somehow this value
// is the closest match to the legacy renderer
SetScreenDPI( 91 );
SetDepthRange( VECTOR2D( GAL::MIN_DEPTH, GAL::MAX_DEPTH ) ); SetDepthRange( VECTOR2D( GAL::MIN_DEPTH, GAL::MAX_DEPTH ) );
SetLayerDepth( 0.0 ); SetLayerDepth( 0.0 );
SetFlip( false, false ); SetFlip( false, false );

View File

@ -1020,17 +1020,11 @@ void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aContro
void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap ) void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap )
{ {
int ppi = aBitmap.GetPPI();
// We have to calculate the pixel size in users units to draw the image. // We have to calculate the pixel size in users units to draw the image.
// worldUnitLength is the user unit in GAL unit value // worldUnitLength is a factor used for converting IU to inches
// (GAL unit = 2.54/1e9 in meter). double scale = 1.0 / ( aBitmap.GetPPI() * worldUnitLength );
// worldUnitLength * 1000 / 2.54 is the user unit in mm double w = (double) aBitmap.GetSizePixels().x * scale;
double worldIU_per_mm = 1.0 / ( worldUnitLength / 0.00254 ); double h = (double) aBitmap.GetSizePixels().y * scale;
double pix_size_iu = worldIU_per_mm * ( 25.4 / ppi );
double w = (double) aBitmap.GetSizePixels().x * pix_size_iu;
double h = (double) aBitmap.GetSizePixels().y * pix_size_iu;
auto xform = currentManager->GetTransformation(); auto xform = currentManager->GetTransformation();
@ -1051,17 +1045,17 @@ void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap )
glBindTexture( GL_TEXTURE_2D, id ); glBindTexture( GL_TEXTURE_2D, id );
glBegin( GL_QUADS ); glBegin( GL_QUADS );
glColor4f(1.0, 1.0, 1.0, 1.0); glColor4f( 1.0, 1.0, 1.0, 1.0 );
glTexCoord2f(0.0, 0.0); glTexCoord2f( 0.0, 0.0 );
glVertex3f( v0.x, v0.y, layerDepth ); glVertex3f( v0.x, v0.y, layerDepth );
glColor4f(1.0, 1.0, 1.0, 1.0); glColor4f( 1.0, 1.0, 1.0, 1.0 );
glTexCoord2f(1.0, 0.0); glTexCoord2f( 1.0, 0.0 );
glVertex3f( v1.x, v0.y, layerDepth ); glVertex3f( v1.x, v0.y, layerDepth );
glColor4f(1.0, 1.0, 1.0, 1.0); glColor4f( 1.0, 1.0, 1.0, 1.0 );
glTexCoord2f(1.0, 1.0); glTexCoord2f( 1.0, 1.0 );
glVertex3f( v1.x, v1.y, layerDepth ); glVertex3f( v1.x, v1.y, layerDepth );
glColor4f(1.0, 1.0, 1.0, 1.0); glColor4f( 1.0, 1.0, 1.0, 1.0 );
glTexCoord2f(0.0, 1.0); glTexCoord2f( 0.0, 1.0 );
glVertex3f( v0.x, v1.y, layerDepth ); glVertex3f( v0.x, v1.y, layerDepth );
glEnd(); glEnd();

View File

@ -760,10 +760,7 @@ const wxString EDA_DRAW_FRAME::GetZoomLevelIndicator() const
if( IsGalCanvasActive() ) if( IsGalCanvasActive() )
{ {
KIGFX::GAL* gal = m_galCanvas->GetGAL(); level = m_galCanvas->GetGAL()->GetZoomFactor();
KIGFX::VIEW* view = m_galCanvas->GetView();
double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor();
level = m_zoomLevelCoeff * zoomFactor * view->GetScale();
} }
else if( BASE_SCREEN* screen = GetScreen() ) else if( BASE_SCREEN* screen = GetScreen() )
{ {
@ -987,8 +984,7 @@ void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU )
void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable ) void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable )
{ {
KIGFX::VIEW* view = GetGalCanvas()->GetView(); EDA_DRAW_PANEL_GAL* galCanvas = GetGalCanvas();
KIGFX::GAL* gal = GetGalCanvas()->GetGAL();
// Display the same view after canvas switching // Display the same view after canvas switching
if( aEnable ) if( aEnable )
@ -997,19 +993,19 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable )
if( !m_galCanvasActive ) if( !m_galCanvasActive )
{ {
// Set up viewport // Set up viewport
double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); KIGFX::VIEW* view = galCanvas->GetView();
double zoom = 1.0 / ( zoomFactor * m_canvas->GetZoom() ); view->SetScale( GetZoomLevelCoeff() / m_canvas->GetZoom() );
view->SetScale( zoom );
view->SetCenter( VECTOR2D( m_canvas->GetScreenCenterLogicalPosition() ) ); view->SetCenter( VECTOR2D( m_canvas->GetScreenCenterLogicalPosition() ) );
} }
// Transfer EDA_DRAW_PANEL settings // Transfer EDA_DRAW_PANEL settings
GetGalCanvas()->GetViewControls()->EnableCursorWarping( !m_canvas->GetEnableZoomNoCenter() ); KIGFX::VIEW_CONTROLS* viewControls = galCanvas->GetViewControls();
GetGalCanvas()->GetViewControls()->EnableMousewheelPan( m_canvas->GetEnableMousewheelPan() ); viewControls->EnableCursorWarping( !m_canvas->GetEnableZoomNoCenter() );
GetGalCanvas()->GetViewControls()->EnableAutoPan( m_canvas->GetEnableAutoPan() ); viewControls->EnableMousewheelPan( m_canvas->GetEnableMousewheelPan() );
viewControls->EnableAutoPan( m_canvas->GetEnableAutoPan() );
} }
GetGalCanvas()->SetEvtHandlerEnabled( aEnable ); galCanvas->SetEvtHandlerEnabled( aEnable );
// Reset current tool on switch(); // Reset current tool on switch();
SetNoToolSelected(); SetNoToolSelected();

View File

@ -779,10 +779,7 @@ const wxString EDA_DRAW_FRAME::GetZoomLevelIndicator() const
if( IsGalCanvasActive() ) if( IsGalCanvasActive() )
{ {
KIGFX::GAL* gal = m_galCanvas->GetGAL(); level = m_galCanvas->GetGAL()->GetZoomFactor();
KIGFX::VIEW* view = m_galCanvas->GetView();
double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor();
level = m_zoomLevelCoeff * zoomFactor * view->GetScale();
} }
else if( BASE_SCREEN* screen = GetScreen() ) else if( BASE_SCREEN* screen = GetScreen() )
{ {
@ -1231,10 +1228,8 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable )
if( !m_galCanvasActive ) if( !m_galCanvasActive )
{ {
// Set up viewport // Set up viewport
double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); view->SetScale( GetZoomLevelCoeff() / m_canvas->GetZoom() );
double zoom = 1.0 / ( zoomFactor * m_canvas->GetZoom() ); view->SetCenter(VECTOR2D( m_canvas->GetScreenCenterLogicalPosition() ) );
view->SetScale( zoom );
view->SetCenter( VECTOR2D( m_canvas->GetScreenCenterLogicalPosition() ) );
} }
// Set up grid settings // Set up grid settings
@ -1243,9 +1238,10 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable )
gal->SetGridOrigin( VECTOR2D( GetGridOrigin() ) ); gal->SetGridOrigin( VECTOR2D( GetGridOrigin() ) );
// Transfer EDA_DRAW_PANEL settings // Transfer EDA_DRAW_PANEL settings
GetGalCanvas()->GetViewControls()->EnableCursorWarping( !m_canvas->GetEnableZoomNoCenter() ); KIGFX::VIEW_CONTROLS* viewControls = GetGalCanvas()->GetViewControls();
GetGalCanvas()->GetViewControls()->EnableMousewheelPan( m_canvas->GetEnableMousewheelPan() ); viewControls->EnableCursorWarping( !m_canvas->GetEnableZoomNoCenter() );
GetGalCanvas()->GetViewControls()->EnableAutoPan( m_canvas->GetEnableAutoPan() ); viewControls->EnableMousewheelPan( m_canvas->GetEnableMousewheelPan() );
viewControls->EnableAutoPan( m_canvas->GetEnableAutoPan() );
} }
else if( m_galCanvasActive ) else if( m_galCanvasActive )
{ {

View File

@ -297,9 +297,6 @@ int COMMON_TOOLS::doZoomToPreset( int idx, bool aCenterOnCursor )
{ {
std::vector<double>& zoomList = m_frame->GetScreen()->m_ZoomList; std::vector<double>& zoomList = m_frame->GetScreen()->m_ZoomList;
KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView(); KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView();
KIGFX::GAL* gal = m_frame->GetGalCanvas()->GetGAL();
m_frame->SetPresetZoom( idx );
if( idx == 0 ) // Zoom Auto if( idx == 0 ) // Zoom Auto
{ {
@ -307,11 +304,11 @@ int COMMON_TOOLS::doZoomToPreset( int idx, bool aCenterOnCursor )
return ZoomFitScreen( dummy ); return ZoomFitScreen( dummy );
} }
else else
{
idx--; idx--;
}
double selectedZoom = zoomList[idx]; double scale = m_frame->GetZoomLevelCoeff() / zoomList[idx];
double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor();
double scale = 1.0 / ( zoomFactor * selectedZoom );
if( aCenterOnCursor ) if( aCenterOnCursor )
{ {
@ -321,7 +318,9 @@ int COMMON_TOOLS::doZoomToPreset( int idx, bool aCenterOnCursor )
getViewControls()->CenterOnCursor(); getViewControls()->CenterOnCursor();
} }
else else
{
view->SetScale( scale ); view->SetScale( scale );
}
return 0; return 0;
} }

View File

@ -285,7 +285,7 @@ void VIEW::OnDestroy( VIEW_ITEM* aItem )
VIEW::VIEW( bool aIsDynamic ) : VIEW::VIEW( bool aIsDynamic ) :
m_enableOrderModifier( true ), m_enableOrderModifier( true ),
m_scale( 4.0 ), m_scale( 4.0 ),
m_minScale( 4.0 ), m_maxScale( 75000.0 ), m_minScale( 0.2 ), m_maxScale( 25000.0 ),
m_mirrorX( false ), m_mirrorY( false ), m_mirrorX( false ), m_mirrorY( false ),
m_painter( NULL ), m_painter( NULL ),
m_gal( NULL ), m_gal( NULL ),

View File

@ -1019,8 +1019,6 @@ public:
virtual void EnableDepthTest( bool aEnabled = false ) {}; virtual void EnableDepthTest( bool aEnabled = false ) {};
static const double METRIC_UNIT_LENGTH;
protected: protected:
GAL_DISPLAY_OPTIONS& options; GAL_DISPLAY_OPTIONS& options;

View File

@ -418,7 +418,7 @@ bool PCB_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
{ {
bool rv = EDA_DRAW_PANEL_GAL::SwitchBackend( aGalType ); bool rv = EDA_DRAW_PANEL_GAL::SwitchBackend( aGalType );
setDefaultLayerDeps(); setDefaultLayerDeps();
m_gal->SetWorldUnitLength( 2.54/(IU_PER_MM*1000) ); // world unit is in internal units per inch * 1000 m_gal->SetWorldUnitLength( 1e-9 /* 1 nm */ / 0.0254 /* 1 inch in meters */ );
return rv; return rv;
} }