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 zoomFactor = m_gal->GetWorldScale() / m_gal->GetZoomFactor();
return ( 1.0 / ( zoomFactor * m_view->GetScale() ) );
return m_edaFrame->GetZoomLevelCoeff() / m_gal->GetZoomFactor();
}

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 )
{
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 );

View File

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

View File

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

View File

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

View File

@ -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 )
{

View File

@ -297,9 +297,6 @@ int COMMON_TOOLS::doZoomToPreset( int idx, bool aCenterOnCursor )
{
std::vector<double>& 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;
}

View File

@ -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 ),

View File

@ -1019,8 +1019,6 @@ public:
virtual void EnableDepthTest( bool aEnabled = false ) {};
static const double METRIC_UNIT_LENGTH;
protected:
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 );
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;
}