I fail to be able to use wxGCDC with a wxPdfDC.
When painting to the screen I use
Code: Select all
wxBufferedPaintDC dc(this);
wxGCDC gcdc(dc);
How can I draw using a rotated wxDC?
Code: Select all
wxBufferedPaintDC dc(this);
wxGCDC gcdc(dc);
wxGCDC uses a wxGraphicsContext internally, but provides a wxDC API externally. wxPdfDC is derived from wxDC and therefore lacks support for the wxGraphicsContext API.
wxPdfDC was first created based on wxWidgets 2.8.x. Back then wxDC did not have methods to manipulate a transformation matrix. Up to now support for manipulating the transformation matrix was not added to wxPdfDC. In principal, however, it should be possible to add such support, because the underlying wxPdfDocument instance supports various transformations.mael15 wrote: ↑Fri Jul 19, 2019 3:19 pm When painting to the screen I useand can rotate the wxGCDC as i wish. But the wxPdfDC cannot be used with wxGCDC.Code: Select all
wxBufferedPaintDC dc(this); wxGCDC gcdc(dc);
How can I draw using a rotated wxDC?
What I mean is I cannot create a wxGCDC from a wxPdfDC.
The only two things I do with wxGDC are SetDeviceOrigin and GetGraphicsContext()->Rotate but I guess the later uses a transformation matrix internally? Is there any way to draw after roating the wxPdfDc? Or maybe draw an unrotated bitmap and copy it rotated to the wxPdfDc? Or do I have to draw on a bitmap including rotation and copy to wxPdfDc after?
And it is very unlikely that this will ever be possible, because wxGCDC is part of wxWidgets itself while wxPdfDocument is not.
Correct.
The only approach based on the current implementation of wxPdfDC, I can imagine, is to use the template mode of wxPdfDC. That is, a drawing is created with wxPdfDC in template mode without applying any rotation. Then the generated template can be added to a wxPdfDocument using the rotation as needed (see templates sample coming with wxPdfDocument).
Okay, thank you, I hope it will be possible to use wxGCDC some time in the future. Until then I will draw incl. rotation to a wxMemoryDC and copy it to the wxPdfDc after.
Well, your bitmap seems to be rather large. And unfortunately bitmaps can't be transferred to PDF directly. They have to be converted to a known graphics format like PNG or JPEG. wxPdfDC: DrawBitmap converts a wxBitmap object to a wxImage object first, and then converts the wxImage to JPEG format. Most likely this conversion process is responsible for most of the processing time. If this is the case, there is not much I can do about it, although 7 seconds really sounds very long.
Hmmmm, the pdf hast a 600dpi resolution, so a standard din a 4 page results in this bitmap size. Can I skip some conversions and/or use some other drawing method? What could be relevant details that I can tell you about my application? I use a very fast machine with lots of cpu and ram.utelle wrote: ↑Wed Jul 31, 2019 9:09 am Well, your bitmap seems to be rather large. And unfortunately bitmaps can't be transferred to PDF directly. They have to be converted to a known graphics format like PNG or JPEG. wxPdfDC: DrawBitmap converts a wxBitmap object to a wxImage object first, and then converts the wxImage to JPEG format. Most likely this conversion process is responsible for most of the processing time. If this is the case, there is not much I can do about it, although 7 seconds really sounds very long.
There might be other factors playing a role, but without knowing more details about your application it is hard to tell, why it takes so long.
In fact, PDF files don't have a single DPI value, because PDF is a vector format. That is, vector objects like text have no resolution at all. Only bitmap objects have an associated resolution.
As can be seen from the wxPdfDC sample coming with wxPdfDocument, a wxPdfDC drawing context can be used almost in the same way as an onscreen drawing context. That is, one can place text, draw lines, place bitmaps, and so on.
As I said 7 seconds indeed seem to be a very long time for the task. Therefore the first step would be to track down which step exactly causes the long processing time: (a) conversion from wxBitmap to wxImage, (b) conversion from wxImage to JPEG, or (c) adding the JPEG to PDF. Only (c) can be influenced by the wxPdfDocument implementation.
Well, yes, as we discussed in this thread, I need to rotate everything I draw, but wxPdfDC does not support wxGCDC so I have to use wxGCDC with a wxMemoryDC, draw rotated stuff to a large bitmap and then copy the large bitmap to wxPdfDC.
The visual studio profiler seems to point to png_write_rows as the main problem.
Code: Select all
wxPdfDocument pdfDcmt;
pdfDcmt.AddPage(wxPORTRAIT, wxPAPER_A4);
int tpl = pdfDcmt.BeginTemplate();
wxPdfDC *dc = new wxPdfDC(&pdfDcmt, 210, 297);
dc->SetResolution(600);
dc->SetBackground(*wxWHITE_BRUSH);
if (dc->StartDoc(wxT("Printing ...")))
{
wxBitmap drawBtmp(5000, 5000);
wxMemoryDC mdc(drawBtmp);
mdc.SetBackground(*wxCYAN);
mdc.Clear();
mdc.SelectObject(wxNullBitmap);
wxStopWatch sw;
dc->DrawBitmap(drawBtmp, wxPoint(10, 10));
sw.Pause();
OutputDebugString(wxString::Format(wxT("DrawBitmap took %ldms\n"), sw.Time()));
dc->EndDoc();
}
delete dc;
pdfDcmt.EndTemplate();
pdfDcmt.UseTemplate(tpl);
wxString filename = wxGetUserHome() + wxT("\\Desktop\\pdfTest.pdf");
pdfDcmt.SaveAsFile(filename);
wxLaunchDefaultApplication(filename);
Could you show a sample drawing? I still think that creating a PDF template without applying rotation, and then adding the template to a wxPdfDocument instance directly and applying rotation to the template, should work smoother and faster.
Ah, I see. This is one thing I simply forgot: the default image type wxPdfDC uses as the target format for bitmaps is PNG (not JPEG as I wrote before). Changing the default image type to JPEG with the following line of code after creating the wxPdfDC instance
Code: Select all
dc->SetImageType(wxBITMAP_TYPE_JPEG);
Sorry, I don't know the answer to this question. Most likely this is a question you will have to ask one of the wxWidgets developers. You can do this by posting to the wxWidgets mailing list: [email protected].
Here is one, it is 600dpi, only the circles bitmap took 7.7 seconds to draw to wxPdfDC. As you can see not everything on the page needs to be rotated.
You are absolutely right, I just were too lazy to try this and stuck to the ways I knew. Thanx for mentioning it again. I just have to figure out how to position everything correctly and how transparency works, but that should be managable.