wxPdfDC - DrawRectangle() uses black pen instead of mine

Talk here about issues with one of the components hosted at wxCode, or suggest features for it.
Post Reply
User avatar
cutecode
Super wx Problem Solver
Super wx Problem Solver
Posts: 425
Joined: Fri Dec 09, 2016 7:28 am
Contact:

wxPdfDC - DrawRectangle() uses black pen instead of mine

Post by cutecode »

Hello, utelle
Could you help me?

At first I thought I had wrong code in my drawings.
But after simplifing my code I found that DrawRectangle() uses always BLACK PEN started from second page
On first page pen is ok, but starting from page 2 it always black
Here is my code

Code: Select all

	for (int nPage = 1; nPage <= 3; nPage++)
	{
		dc.StartPage();

		wxColour backgroundColour = RGB(255, 255, 255);
		dc.SetBrush(wxBrush(backgroundColour));
		dc.SetPen(wxPen(backgroundColour, 1));

		wxRect windowRect;
		windowRect.SetPosition(wxPoint(10, 10));
		windowRect.SetSize(wxSize(100, 100));

		dc.DrawRectangle(windowRect);

		dc.EndPage();
		dc.SetUserScale(1, 1);
	}

    dc.EndDoc();
On first page I see empty page, as expected. But pages 2 and 3 are not blank, but should be
See attachments

Thank you
Attachments
pdf.zip
(101.69 KiB) Downloaded 214 times
wx 3.1.6 win/mac/linux

regards,
Alexander Saprykin
https://v2.dental-soft.ru
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxPdfDC - DrawRectangle() uses black pen instead of mine

Post by utelle »

cutecode wrote: Thu Dec 03, 2020 10:07 am At first I thought I had wrong code in my drawings.
But after simplifing my code I found that DrawRectangle() uses always BLACK PEN started from second page
On first page pen is ok, but starting from page 2 it always black
At first, I thought it might have to do with the fact that method StartPage resets the drawing color to black. However, looking at your code I see that you explicitly set the pen color each time after method StartPage was called. So, the pen color should be set correctly. Internally, a black pen color is only set it the current pen is the null pen - which shouldn't be the case here.
cutecode wrote: Thu Dec 03, 2020 10:07 am Here is my code

Code: Select all

	for (int nPage = 1; nPage <= 3; nPage++)
	{
		dc.StartPage();

		wxColour backgroundColour = RGB(255, 255, 255);
		dc.SetBrush(wxBrush(backgroundColour));
		dc.SetPen(wxPen(backgroundColour, 1));

		wxRect windowRect;
		windowRect.SetPosition(wxPoint(10, 10));
		windowRect.SetSize(wxSize(100, 100));

		dc.DrawRectangle(windowRect);

		dc.EndPage();
		dc.SetUserScale(1, 1);
	}

    dc.EndDoc();
On first page I see empty page, as expected. But pages 2 and 3 are not blank, but should be
See attachments
At first glance, your code seems to be alright. I will take a closer look later today or tomorrow to find out what's going on.
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxPdfDC - DrawRectangle() uses black pen instead of mine

Post by utelle »

The problem was that pen and brush were not explicitly set after a new page was started, if they happened to be equal to the last pen and brush used on the previous page. Since on page start a default pen color of black is set, this resulted in the effect you observed.

I have applied a quick fix to method StartPage of wxPdfDC, so that pen and brush used for PDF output are now always synchronized with the DC pen and brush. This should solve your issue.

Please try the latest version from the wxPdfDocument GitHub repository.
User avatar
cutecode
Super wx Problem Solver
Super wx Problem Solver
Posts: 425
Joined: Fri Dec 09, 2016 7:28 am
Contact:

Re: wxPdfDC - DrawRectangle() uses black pen instead of mine

Post by cutecode »

Thank you, now it is ok.
But now I have an assertion

Code: Select all

ASSERT INFO:
../src/common/unichar.cpp(52): assert ""Assert failure"" failed in FromHi8bit(): invalid multibyte character

BACKTRACE:
[1] wxUniChar::FromHi8bit(char)
[2] wxPdfEncrypt::CreateDocumentId()
[3] wxPdfDocument::PutTrailer()
[4] wxPdfDocument::EndDoc()
[5] wxPdfDocument::SaveAsFile(wxString const&)
[6] wxPdfDCImpl::EndDoc()
[7] wxDC::EndDoc()
[8] CGrid::ToPDF(wchar_t const*)
[9] CGridCtrl::ToPDF(wchar_t const*)
[10] CReportPanel::DecideHowToSave()
[11] CReportPanel::OnFileSaveAs_()
[12] CReportPanel::OnFileSaveAs(wxCommandEvent&)
[13] wxAppConsoleBase::HandleEvent(wxEvtHandler*, void (wxEvtHandler::*)(wxEvent&), wxEvent&) const
[14] wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) const
[15] wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&)
[16] wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*)
[17] wxEvtHandler::TryHereOnly(wxEvent&)
[18] wxEvtHandler::ProcessEvent(wxEvent&)
[19] wxEvtHandler::DoTryChain(wxEvent&)
[20] wxEvtHandler::ProcessEventLocally(wxEvent&)
[21] wxEvtHandler::ProcessEvent(wxEvent&)
[22] wxWindowBase::TryAfter(wxEvent&)
[23] wxEvtHandler::ProcessEvent(wxEvent&)
[24] wxAuiToolBar::OnLeftUp(wxMouseEvent&)
[25] wxAppConsoleBase::HandleEvent(wxEvtHandler*, void (wxEvtHandler::*)(wxEvent&), wxEvent&) const
[26] wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) const
[27] wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&)
[28] wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*)
[29] wxEvtHandler::TryHereOnly(wxEvent&)
[30] wxEvtHandler::ProcessEventLocally(wxEvent&)
[31] wxEvtHandler::ProcessEvent(wxEvent&)
[32] wxEvtHandler::SafelyProcessEvent(wxEvent&)
[33] wxWindowBase::HandleWindowEvent(wxEvent&) const
[34] wxWindow::GTKProcessEvent(wxEvent&) const
[35] g_closure_invoke
[36] g_signal_emit_valist
[37] g_signal_emit
[38] gtk_main_do_event
[39] g_main_context_dispatch
[40] g_main_loop_run
[41] gtk_main
[42] wxGUIEventLoop::DoRun()
[43] wxEventLoopBase::Run()
[44] wxAppConsoleBase::MainLoop()
[45] wxAppConsoleBase::OnRun()
[46] wxAppBase::OnRun()
[47] wxEntry(int&, wchar_t**)
[48] wxEntry(int&, char**)
[49] main
[50] __libc_start_main
Should I ignore this assertion?

Thank you
Attachments
1.pdf.zip
(109.87 KiB) Downloaded 203 times
wx 3.1.6 win/mac/linux

regards,
Alexander Saprykin
https://v2.dental-soft.ru
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxPdfDC - DrawRectangle() uses black pen instead of mine

Post by utelle »

cutecode wrote: Thu Dec 03, 2020 11:30 pm Thank you, now it is ok.
Good news.
cutecode wrote: Thu Dec 03, 2020 11:30 pm But now I have an assertion

Code: Select all

ASSERT INFO:
../src/common/unichar.cpp(52): assert ""Assert failure"" failed in FromHi8bit(): invalid multibyte character

BACKTRACE:
[1] wxUniChar::FromHi8bit(char)
[2] wxPdfEncrypt::CreateDocumentId()
[3] wxPdfDocument::PutTrailer()
[4] wxPdfDocument::EndDoc()
[5] wxPdfDocument::SaveAsFile(wxString const&)
[6] wxPdfDCImpl::EndDoc()
[7] wxDC::EndDoc()
[8] CGrid::ToPDF(wchar_t const*)
[9] CGridCtrl::ToPDF(wchar_t const*)
[10] CReportPanel::DecideHowToSave()
[11] CReportPanel::OnFileSaveAs_()
[12] CReportPanel::OnFileSaveAs(wxCommandEvent&)
[13] wxAppConsoleBase::HandleEvent(wxEvtHandler*, void (wxEvtHandler::*)(wxEvent&), wxEvent&) const
[14] wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) const
[15] wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&)
[16] wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*)
[17] wxEvtHandler::TryHereOnly(wxEvent&)
[18] wxEvtHandler::ProcessEvent(wxEvent&)
[19] wxEvtHandler::DoTryChain(wxEvent&)
[20] wxEvtHandler::ProcessEventLocally(wxEvent&)
[21] wxEvtHandler::ProcessEvent(wxEvent&)
[22] wxWindowBase::TryAfter(wxEvent&)
[23] wxEvtHandler::ProcessEvent(wxEvent&)
[24] wxAuiToolBar::OnLeftUp(wxMouseEvent&)
[25] wxAppConsoleBase::HandleEvent(wxEvtHandler*, void (wxEvtHandler::*)(wxEvent&), wxEvent&) const
[26] wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) const
[27] wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&)
[28] wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*)
[29] wxEvtHandler::TryHereOnly(wxEvent&)
[30] wxEvtHandler::ProcessEventLocally(wxEvent&)
[31] wxEvtHandler::ProcessEvent(wxEvent&)
[32] wxEvtHandler::SafelyProcessEvent(wxEvent&)
[33] wxWindowBase::HandleWindowEvent(wxEvent&) const
[34] wxWindow::GTKProcessEvent(wxEvent&) const
[35] g_closure_invoke
[36] g_signal_emit_valist
[37] g_signal_emit
[38] gtk_main_do_event
[39] g_main_context_dispatch
[40] g_main_loop_run
[41] gtk_main
[42] wxGUIEventLoop::DoRun()
[43] wxEventLoopBase::Run()
[44] wxAppConsoleBase::MainLoop()
[45] wxAppConsoleBase::OnRun()
[46] wxAppBase::OnRun()
[47] wxEntry(int&, wchar_t**)
[48] wxEntry(int&, char**)
[49] main
[50] __libc_start_main
Thanks for reporting. It certainly has something to do with my recent changes replacing the use of the wxChar type by type wxUniChar. The document id is created from a random sequence of bytes. Therefore an assertion does not happen all the time. However, obviously the wxUniChar constructor works differently than I thought it would. I will look into it and will fix it somehow.
cutecode wrote: Thu Dec 03, 2020 11:30 pm Should I ignore this assertion?
The created PDF is ok. So, you can ignore it for now. Nevertheless I will adjust the wxPdfDocument code, so that no longer an assertion will be produced. I will drop a note here as soon as the issue is fixed.
User avatar
cutecode
Super wx Problem Solver
Super wx Problem Solver
Posts: 425
Joined: Fri Dec 09, 2016 7:28 am
Contact:

Re: wxPdfDC - DrawRectangle() uses black pen instead of mine

Post by cutecode »

Greate thanks for your job.
wx 3.1.6 win/mac/linux

regards,
Alexander Saprykin
https://v2.dental-soft.ru
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxPdfDC - DrawRectangle() uses black pen instead of mine

Post by utelle »

cutecode wrote: Fri Dec 04, 2020 9:28 am Greate thanks for your job.
You are welcome.

I applied a fix a few minutes ago. Now an assertion should no longer occur.
Post Reply