esternin / eXtrema

https://www.physics.brocku.ca/Labs/extrema/
GNU General Public License v2.0
6 stars 1 forks source link

Print to file using wxWidgets dialog only reproduces some of the elements on the canvas #65

Closed esternin closed 1 year ago

esternin commented 1 year ago

This is a weirdly inconsistent problem, and seems triggered by the use of plotting symbols. For example, a graph of a few discrete points plus a graph\overlay of a line renders both on the pdf output, just like on the screen for symbols -2,-3,-4,-6: image and completely messes up for symbols -1,-5,-15,-14 - and others: image while the screen canvas looks normal: image

The typical (but not always, e..g. symbols -1) screw-up is that that only the outline of the filled symbol is drawn, and any line drawn after that is likely to not appear, whether curves, or axes from other windows, text strings, or symbols.

This is using the system Print dialog, and redirecting "Print to file" to a .pdf.

Since redraw works, we are keeping track of everything that goes on the canvas, but somehow print dialog does not get a full canvas content. Seems like a wxWidgets issue @vadz ?

At the same time, canvas snapshots (Save drawing to .png or .jpg, or our own .eps generator) render things normally: what's on the screen is fully in .png, .jpg, or .eps files.

clear
defaults

ps=-{1;5;15;14}
x=[0:10]
xx=[0:10:0.05]

do i=[1:4]
  window 4+i
  set xlabel `<i1>t<i0>, s'
  set ylabel `<i1>x(t)<i0>, m'
  scales 0 12 2 -2 2 4
  set plotsymbol ps[i]
  gra x,sin(x)
  set plotsymbol 0
  gra\overlay xx,cos(xx)
enddo
esternin commented 1 year ago

The comprehensive list:

! bad symbols
ps=-{1;5;8;9;10;12;13;14;15;16;18}
! good symbols
ps=-{17;11;7;6;4;3;2}

For reference: image

What is common is that the good symbols are drawn using GRA_multiLineFigure and the bad ones using GRA_polygon

esternin commented 1 year ago

@vadz : could you take a look at the GRA_polygon.cpp ? I think the std::out stuff is mishandling fillColor_ if there isn't any. Just like GRA_ellipse.cpp which draws symbol -17 (filled circle) fine, and chokes on -9 (open circle).

esternin commented 1 year ago

Aha! I figured it out, and as far as I'm concerned, it's a wx bug/undocumented feature. The order of dc.SetBrush() and dc.SetPen() matters. Whether you separately set colour and style of brush (like for the pen below) or do it shorthand (like for the brush below), no difference, but pen must come last.

This works properly:

 if( fillColor_ ) 
    dc.SetBrush( ExGlobals::GetwxColor(fillColor_) );
 else
    dc.SetBrush( wxTransparentColour );

 wxPen wxpen( dc.GetPen() );
 wxpen.SetWidth( std::max(1,lineWidth_) );
 wxpen.SetColour( ExGlobals::GetwxColor(lineColor_) );
 dc.SetPen( wxpen );

 dc.DrawPolygon( static_cast<int>(size), pArray );

but if the order is reversed, it fails:

 wxPen wxpen( dc.GetPen() );
 wxpen.SetWidth( std::max(1,lineWidth_) );
 wxpen.SetColour( ExGlobals::GetwxColor(lineColor_) );
 dc.SetPen( wxpen );

 if( fillColor_ ) 
    dc.SetBrush( ExGlobals::GetwxColor(fillColor_) );
 else
    dc.SetBrush( wxTransparentColour );

 dc.DrawPolygon( static_cast<int>(size), pArray );
vadz commented 1 year ago

Glad to hear that you could make it work, but this is definitely a bug in wx in this case as there should be no order dependency between SetPen() and SetBrush().

What is the type of wxDC here?

esternin commented 1 year ago

Oh, yes: the rendering on the screen was fine either way, but when system dialog was used to "Print to File" (I was using .pdf), all polygon and ellipse symbols would mess up, as above.

I am not sure how to answer your question, as I do not know what context gets called when re-directing the canvas to the print function, but in wxForms/VisualizationSpeedButtonPanel.cpp we have :

bool MyPrintout::OnPrintPage( int page )
{
  wxDC *dc = GetDC();
...

if this tells you anything.

esternin commented 1 year ago

As we now have a workaround (https://github.com/esternin/eXtrema/commit/0a052f9fdbc4788a49adfd72a6997105cfc389da) for the wx bug, we do not need to wait until that gets fixed, so I think we can close this issue.