From 64da77538f7a47545011dcb35d21b0be7bdbc82d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 22 Oct 2018 00:16:15 +0200 Subject: [PATCH] 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. --- common/draw_panel_gal.cpp | 3 +-- common/gal/cairo/cairo_gal.cpp | 22 ++++++----------- common/gal/graphics_abstraction_layer.cpp | 9 +++---- common/gal/opengl/opengl_gal.cpp | 30 +++++++++-------------- common/legacy_gal/eda_draw_frame.cpp | 22 +++++++---------- common/legacy_wx/eda_draw_frame.cpp | 18 ++++++-------- common/tool/common_tools.cpp | 11 ++++----- common/view/view.cpp | 2 +- include/gal/graphics_abstraction_layer.h | 2 -- pcbnew/pcb_draw_panel_gal.cpp | 2 +- 10 files changed, 48 insertions(+), 73 deletions(-) diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index 4a95a46bfb..a051f622cc 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -353,8 +353,7 @@ void EDA_DRAW_PANEL_GAL::SetTopLayer( int aLayer ) double EDA_DRAW_PANEL_GAL::GetLegacyZoom() const { - double zoomFactor = m_gal->GetWorldScale() / m_gal->GetZoomFactor(); - return ( 1.0 / ( zoomFactor * m_view->GetScale() ) ); + return m_edaFrame->GetZoomLevelCoeff() / m_gal->GetZoomFactor(); } diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index a7068a2469..6afec36fca 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -274,27 +274,21 @@ void CAIRO_GAL_BASE::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aCo 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 ); - // Set the pixel scaling factor: - cairo_scale( currentContext, pix_size_iu, pix_size_iu ); + // We have to calculate the pixel size in users units to draw the image. + // 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. // 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_new_path( currentContext ); - cairo_surface_t *image; - image = cairo_image_surface_create( CAIRO_FORMAT_RGB24, w, h ); + cairo_surface_t* image = cairo_image_surface_create( CAIRO_FORMAT_RGB24, w, h ); cairo_surface_flush( image ); unsigned char* pix_buffer = cairo_image_surface_get_data( image ); diff --git a/common/gal/graphics_abstraction_layer.cpp b/common/gal/graphics_abstraction_layer.cpp index db4c1ad412..5104f8fd6f 100644 --- a/common/gal/graphics_abstraction_layer.cpp +++ b/common/gal/graphics_abstraction_layer.cpp @@ -34,9 +34,6 @@ using namespace KIGFX; -const double GAL::METRIC_UNIT_LENGTH = 1e9; - - GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) : options( aDisplayOptions ), strokeFont( this ) @@ -49,8 +46,10 @@ GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) : SetLookAtPoint( VECTOR2D( 0, 0 ) ); SetZoomFactor( 1.0 ); SetRotation( 0.0 ); - SetWorldUnitLength( 1.0 / METRIC_UNIT_LENGTH * 2.54 ); // 1 inch in nanometers - SetScreenDPI( 106 ); // Display resolution setting + SetWorldUnitLength( 1e-9 /* 1 nm */ / 0.0254 /* 1 inch in meters */ ); + // 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 ) ); SetLayerDepth( 0.0 ); SetFlip( false, false ); diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 5123ce32be..63d6627ec1 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -1020,17 +1020,11 @@ void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aContro 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. - // worldUnitLength is the user unit in GAL unit value - // (GAL unit = 2.54/1e9 in meter). - // worldUnitLength * 1000 / 2.54 is the user unit in mm - double worldIU_per_mm = 1.0 / ( worldUnitLength / 0.00254 ); - 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; + // worldUnitLength is a factor used for converting IU to inches + double scale = 1.0 / ( aBitmap.GetPPI() * worldUnitLength ); + double w = (double) aBitmap.GetSizePixels().x * scale; + double h = (double) aBitmap.GetSizePixels().y * scale; auto xform = currentManager->GetTransformation(); @@ -1051,17 +1045,17 @@ void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap ) glBindTexture( GL_TEXTURE_2D, id ); glBegin( GL_QUADS ); - glColor4f(1.0, 1.0, 1.0, 1.0); - glTexCoord2f(0.0, 0.0); + glColor4f( 1.0, 1.0, 1.0, 1.0 ); + glTexCoord2f( 0.0, 0.0 ); glVertex3f( v0.x, v0.y, layerDepth ); - glColor4f(1.0, 1.0, 1.0, 1.0); - glTexCoord2f(1.0, 0.0); + glColor4f( 1.0, 1.0, 1.0, 1.0 ); + glTexCoord2f( 1.0, 0.0 ); glVertex3f( v1.x, v0.y, layerDepth ); - glColor4f(1.0, 1.0, 1.0, 1.0); - glTexCoord2f(1.0, 1.0); + glColor4f( 1.0, 1.0, 1.0, 1.0 ); + glTexCoord2f( 1.0, 1.0 ); glVertex3f( v1.x, v1.y, layerDepth ); - glColor4f(1.0, 1.0, 1.0, 1.0); - glTexCoord2f(0.0, 1.0); + glColor4f( 1.0, 1.0, 1.0, 1.0 ); + glTexCoord2f( 0.0, 1.0 ); glVertex3f( v0.x, v1.y, layerDepth ); glEnd(); diff --git a/common/legacy_gal/eda_draw_frame.cpp b/common/legacy_gal/eda_draw_frame.cpp index 2befd25907..c7fea04927 100644 --- a/common/legacy_gal/eda_draw_frame.cpp +++ b/common/legacy_gal/eda_draw_frame.cpp @@ -760,10 +760,7 @@ const wxString EDA_DRAW_FRAME::GetZoomLevelIndicator() const if( IsGalCanvasActive() ) { - KIGFX::GAL* gal = m_galCanvas->GetGAL(); - KIGFX::VIEW* view = m_galCanvas->GetView(); - double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); - level = m_zoomLevelCoeff * zoomFactor * view->GetScale(); + level = m_galCanvas->GetGAL()->GetZoomFactor(); } 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 ) { - KIGFX::VIEW* view = GetGalCanvas()->GetView(); - KIGFX::GAL* gal = GetGalCanvas()->GetGAL(); + EDA_DRAW_PANEL_GAL* galCanvas = GetGalCanvas(); // Display the same view after canvas switching if( aEnable ) @@ -997,19 +993,19 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable ) if( !m_galCanvasActive ) { // Set up viewport - double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); - double zoom = 1.0 / ( zoomFactor * m_canvas->GetZoom() ); - view->SetScale( zoom ); + KIGFX::VIEW* view = galCanvas->GetView(); + view->SetScale( GetZoomLevelCoeff() / m_canvas->GetZoom() ); view->SetCenter( VECTOR2D( m_canvas->GetScreenCenterLogicalPosition() ) ); } // Transfer EDA_DRAW_PANEL settings - GetGalCanvas()->GetViewControls()->EnableCursorWarping( !m_canvas->GetEnableZoomNoCenter() ); - GetGalCanvas()->GetViewControls()->EnableMousewheelPan( m_canvas->GetEnableMousewheelPan() ); - GetGalCanvas()->GetViewControls()->EnableAutoPan( m_canvas->GetEnableAutoPan() ); + KIGFX::VIEW_CONTROLS* viewControls = galCanvas->GetViewControls(); + viewControls->EnableCursorWarping( !m_canvas->GetEnableZoomNoCenter() ); + viewControls->EnableMousewheelPan( m_canvas->GetEnableMousewheelPan() ); + viewControls->EnableAutoPan( m_canvas->GetEnableAutoPan() ); } - GetGalCanvas()->SetEvtHandlerEnabled( aEnable ); + galCanvas->SetEvtHandlerEnabled( aEnable ); // Reset current tool on switch(); SetNoToolSelected(); diff --git a/common/legacy_wx/eda_draw_frame.cpp b/common/legacy_wx/eda_draw_frame.cpp index f5a36d9f7d..b94504550b 100644 --- a/common/legacy_wx/eda_draw_frame.cpp +++ b/common/legacy_wx/eda_draw_frame.cpp @@ -779,10 +779,7 @@ const wxString EDA_DRAW_FRAME::GetZoomLevelIndicator() const if( IsGalCanvasActive() ) { - KIGFX::GAL* gal = m_galCanvas->GetGAL(); - KIGFX::VIEW* view = m_galCanvas->GetView(); - double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); - level = m_zoomLevelCoeff * zoomFactor * view->GetScale(); + level = m_galCanvas->GetGAL()->GetZoomFactor(); } else if( BASE_SCREEN* screen = GetScreen() ) { @@ -1231,10 +1228,8 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable ) if( !m_galCanvasActive ) { // Set up viewport - double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); - double zoom = 1.0 / ( zoomFactor * m_canvas->GetZoom() ); - view->SetScale( zoom ); - view->SetCenter( VECTOR2D( m_canvas->GetScreenCenterLogicalPosition() ) ); + view->SetScale( GetZoomLevelCoeff() / m_canvas->GetZoom() ); + view->SetCenter(VECTOR2D( m_canvas->GetScreenCenterLogicalPosition() ) ); } // Set up grid settings @@ -1243,9 +1238,10 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable ) gal->SetGridOrigin( VECTOR2D( GetGridOrigin() ) ); // Transfer EDA_DRAW_PANEL settings - GetGalCanvas()->GetViewControls()->EnableCursorWarping( !m_canvas->GetEnableZoomNoCenter() ); - GetGalCanvas()->GetViewControls()->EnableMousewheelPan( m_canvas->GetEnableMousewheelPan() ); - GetGalCanvas()->GetViewControls()->EnableAutoPan( m_canvas->GetEnableAutoPan() ); + KIGFX::VIEW_CONTROLS* viewControls = GetGalCanvas()->GetViewControls(); + viewControls->EnableCursorWarping( !m_canvas->GetEnableZoomNoCenter() ); + viewControls->EnableMousewheelPan( m_canvas->GetEnableMousewheelPan() ); + viewControls->EnableAutoPan( m_canvas->GetEnableAutoPan() ); } else if( m_galCanvasActive ) { diff --git a/common/tool/common_tools.cpp b/common/tool/common_tools.cpp index 8fbdec58b5..0a4eb49522 100644 --- a/common/tool/common_tools.cpp +++ b/common/tool/common_tools.cpp @@ -297,9 +297,6 @@ int COMMON_TOOLS::doZoomToPreset( int idx, bool aCenterOnCursor ) { std::vector& zoomList = m_frame->GetScreen()->m_ZoomList; KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView(); - KIGFX::GAL* gal = m_frame->GetGalCanvas()->GetGAL(); - - m_frame->SetPresetZoom( idx ); if( idx == 0 ) // Zoom Auto { @@ -307,11 +304,11 @@ int COMMON_TOOLS::doZoomToPreset( int idx, bool aCenterOnCursor ) return ZoomFitScreen( dummy ); } else + { idx--; + } - double selectedZoom = zoomList[idx]; - double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); - double scale = 1.0 / ( zoomFactor * selectedZoom ); + double scale = m_frame->GetZoomLevelCoeff() / zoomList[idx]; if( aCenterOnCursor ) { @@ -321,7 +318,9 @@ int COMMON_TOOLS::doZoomToPreset( int idx, bool aCenterOnCursor ) getViewControls()->CenterOnCursor(); } else + { view->SetScale( scale ); + } return 0; } diff --git a/common/view/view.cpp b/common/view/view.cpp index 3e8f5a001d..b6c83bb5e6 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -285,7 +285,7 @@ void VIEW::OnDestroy( VIEW_ITEM* aItem ) VIEW::VIEW( bool aIsDynamic ) : m_enableOrderModifier( true ), 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_painter( NULL ), m_gal( NULL ), diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index c7eb1affde..a033846d17 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -1019,8 +1019,6 @@ public: virtual void EnableDepthTest( bool aEnabled = false ) {}; - static const double METRIC_UNIT_LENGTH; - protected: GAL_DISPLAY_OPTIONS& options; diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp index b7a17389e7..8843e07137 100644 --- a/pcbnew/pcb_draw_panel_gal.cpp +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -418,7 +418,7 @@ bool PCB_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType ) { bool rv = EDA_DRAW_PANEL_GAL::SwitchBackend( aGalType ); 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; }