wxPDF wxBRUSHSTYLE substitude Topic is solved

Talk here about issues with one of the components hosted at wxCode, or suggest features for it.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

wxPDF wxBRUSHSTYLE substitude

Post by mael15 »

So I found in some other post that wxBRUSHSTYLE is not supported in wxPDFDoc and that wxPdfPattern might be an alternative? I could not find an example on how to do that.
I need to mark an area on a bitmap and a simple rectangle is not an option. The inside of the rectangle has to have some sort of pattern. How can I achieve something similar to wxBRUSHSTYLE_BDIAGONAL_HATCH?
Thanx!
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxPDF wxBRUSHSTYLE substitude

Post by utelle »

mael15 wrote: Fri Sep 03, 2021 7:44 am So I found in some other post that wxBRUSHSTYLE is not supported in wxPDFDoc
Yes, that is correct. Support for wxBRUSHSTYLEs in wxPdfDC is currently not implemented.
mael15 wrote: Fri Sep 03, 2021 7:44 am and that wxPdfPattern might be an alternative? I could not find an example on how to do that.
Currently only the use of bitmap images as patterns is supported. I will consider to add extended pattern support in the future. However, there is not yet a release schedule for this feature.

A sample on how patterns can be applied can be found in samples/minimal/drawing.cpp.
mael15 wrote: Fri Sep 03, 2021 7:44 am I need to mark an area on a bitmap and a simple rectangle is not an option. The inside of the rectangle has to have some sort of pattern. How can I achieve something similar to wxBRUSHSTYLE_BDIAGONAL_HATCH?
One option would be to create a small bitmap graphics (i.e. .png file) with a suitable pattern, and then to use method SetFillPattern of wxPdfDocument to establish the pattern for the next drawing operation.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: wxPDF wxBRUSHSTYLE substitude

Post by mael15 »

thank you! i tried it but only get an empty page without any error message. what I am doing is this after successfully loading via wxImage::LoadFile(path)
pdfDcmt.AddPattern(wxS("bluehatch"), img, 32, 32);
...
pdfDcmt.SetFillPattern(wxS("bluehatch"));
pdfDcmt.Rect(pnt.x, pnt.y, sz.GetWidth(), sz.GetHeight(), wxPDF_STYLE_FILLDRAW);
what might be wrong? i have attached the png image.
Attachments
pdfhatch.png
pdfhatch.png (998 Bytes) Viewed 10334 times
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxPDF wxBRUSHSTYLE substitude

Post by utelle »

mael15 wrote: Tue Sep 07, 2021 9:04 am thank you! i tried it but only get an empty page without any error message. what I am doing is this after successfully loading via wxImage::LoadFile(path)
pdfDcmt.AddPattern(wxS("bluehatch"), img, 32, 32);
...
pdfDcmt.SetFillPattern(wxS("bluehatch"));
pdfDcmt.Rect(pnt.x, pnt.y, sz.GetWidth(), sz.GetHeight(), wxPDF_STYLE_FILLDRAW);
what might be wrong? i have attached the png image.
In principle, the steps you took are correct. However, I think there is a misunderstanding of the parameters width and height of method AddPattern. These parameters do not describe the width and height of the pattern image in pixel; instead, they describe the width and height of the pattern in the base unit of the PDF document (for example millimeters). The given graphics image will be scaled accordingly.

If the current line color is white (or transparent) there will be no outline of the rectangle, and if the width and height of the rectangle are relatively small (compared to 32) the blue line of the pattern will be outside the rectangle resulting in an invisible rectangle. So, instead of the value 32 for width and height you could try for example the value 2 or 4 or any other value which seems to be appropriate. This should then result in the intended visual effect.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: wxPDF wxBRUSHSTYLE substitude

Post by mael15 »

okay, thank you! i changed the code like this:

Code: Select all

wxImage img = SystemState::loadImage(wxT("images/pdfhatch.png"));
pdfDcmt.AddPattern(wxS("bluehatch"), img, 2, 2);
wxPdfArrayDouble dash2;
wxPdfLineStyle style2(0.5, wxPDF_LINECAP_BUTT, wxPDF_LINEJOIN_MITER, dash2, 0., wxColour(255, 0, 0));
pdfDcmt.SetLineStyle(style2);
....
// a lot of levels deeper, maybe this is the problem?
wxPdfDC* pdc = dynamic_cast<wxPdfDC*>(&dc);
if (pdc) {
	wxPdfDocument* doc = pdc->GetPdfDocument();
	doc->SetFillPattern(wxS("bluehatch"));
	doc->Rect(pnt.x, pnt.y, sz.GetWidth(), sz.GetHeight(), wxPDF_STYLE_FILLDRAW);
}
I get an unspecified error from Acrobat reader when opening the pdf. I attached it in case you can debug it? There still only is a white page.
Attachments
notOpeningAfterFillPattern.zip
(174.72 KiB) Downloaded 122 times
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxPDF wxBRUSHSTYLE substitude

Post by utelle »

mael15 wrote: Thu Sep 09, 2021 1:07 pm okay, thank you! i changed the code like this:

Code: Select all

wxImage img = SystemState::loadImage(wxT("images/pdfhatch.png"));
pdfDcmt.AddPattern(wxS("bluehatch"), img, 2, 2);
wxPdfArrayDouble dash2;
wxPdfLineStyle style2(0.5, wxPDF_LINECAP_BUTT, wxPDF_LINEJOIN_MITER, dash2, 0., wxColour(255, 0, 0));
pdfDcmt.SetLineStyle(style2);
....
// a lot of levels deeper, maybe this is the problem?
wxPdfDC* pdc = dynamic_cast<wxPdfDC*>(&dc);
if (pdc) {
	wxPdfDocument* doc = pdc->GetPdfDocument();
	doc->SetFillPattern(wxS("bluehatch"));
	doc->Rect(pnt.x, pnt.y, sz.GetWidth(), sz.GetHeight(), wxPDF_STYLE_FILLDRAW);
}
I get an unspecified error from Acrobat reader when opening the pdf. I attached it in case you can debug it? There still only is a white page.
Most likely the rectangle with fill pattern is drawn to PDF incorrectly nested in respect to the content drawn by the wxPdfDC instance. Without seeing the code how you instantiate wxPdfDC it is very difficult to tell what exactly goes wrong. For example, if you use the template mode of wxPdfDC, the order of operations is very important to get things right.

Could you please call pdfDcmt.SetCompression(false) immediately after instantiating pdfDcmt and recreate the sample PDF file? This would make it much easier for me to analyze the PDF content streams.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: wxPDF wxBRUSHSTYLE substitude

Post by mael15 »

this is the basic level of creating the pdf, the actual drawing happens depp within printToDC

Code: Select all

wxPdfDocument pdfDcmt;
			pdfDcmt.SetCompression(false);
			wxFont defaultFont(wxFontInfo(10).Family(wxFONTFAMILY_DEFAULT).Underlined(false));
			wxPdfFont pdfArialFont = wxPdfFontManager::GetFontManager()->RegisterFont(defaultFont, wxT("Arial"));
			bool ok = pdfDcmt.SetFont(pdfArialFont); 
			
			wxImage img = SystemState::loadImage(wxT("images/pdfhatch.png"));
			pdfDcmt.AddPattern(wxS("bluehatch"), img, 2, 2);
			wxPdfArrayDouble dash2;
			wxPdfLineStyle style2(0.5, wxPDF_LINECAP_BUTT, wxPDF_LINEJOIN_MITER, dash2, 0., wxColour(255, 0, 0));
			pdfDcmt.SetLineStyle(style2);
			
			int tpl = -1;

			wxProgressDialog *prog = new wxProgressDialog(_i("PDF speichern"), _i("Das PDF wird erstellt."), 100, ss->getMainFrame(), wxPD_AUTO_HIDE | wxPD_SMOOTH);
			//prog.ShowModal();
			double progPerPage = 100.0 / numPrintPages, totalProg = 0;
			
			//TimeStopperMilli stopper;
			wxSize pageSzMM = wxDefaultSize;
			for (unsigned int i = 1; i < pagesToPrint.size(); i++){
				if (pagesToPrint.at(i)){
					page = pageCont->getPage(i - 1);
					orient = page->isLayoutPortait() ? wxPORTRAIT : wxLANDSCAPE;
					papSize = page->isLayoutA4() ? wxPAPER_A4 : wxPAPER_A3;
					pdfDcmt.AddPage(orient, papSize);
					tpl = pdfDcmt.BeginTemplate();

					pageSzMM = page->getPageSizeMM(papSize, orient);
					if (dc)
						delete dc;
					dc = new wxPdfDC(&pdfDcmt, pageSzMM.x, pageSzMM.y);
					dc->SetResolution(600);
					dc->SetBackground(*wxWHITE_BRUSH);

					if (dc->StartDoc(wxT("Printing ...")))
					{
						//OutputDebugString(wxString::Format(wxT("Seite %i wird gedruckt\n"), i));
						libClientOutput::TubeDataPrintout::printToDC(*dc, i - 1);
						dc->EndDoc();
					}

					pdfDcmt.EndTemplate();
					pdfDcmt.UseTemplate(tpl);

					totalProg += progPerPage;
					prog->Update(totalProg);
				}
			}

			delete prog;
is there an easy way to get rid of these tabs when i insert code? i am tired of manually removing the spaces in each line when posting code.
i attached a pdf without compression.
thank you!
Attachments
noCompression.zip
(177.87 KiB) Downloaded 123 times
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxPDF wxBRUSHSTYLE substitude

Post by utelle »

mael15 wrote: Thu Sep 09, 2021 2:57 pm this is the basic level of creating the pdf, the actual drawing happens depp within printToDC
[...]
is there an easy way to get rid of these tabs when i insert code? i am tired of manually removing the spaces in each line when posting code.
This is an issue of the forum software. Unfortunately, I have no idea whether there exist a secret option for the handling of tabs in code sections.
mael15 wrote: Thu Sep 09, 2021 2:57 pm i attached a pdf without compression.
Thanks.

I fear you detected a deficiency of the current wxPdfDocument version. For templates it is required to list all resources they depend on. This is done for fonts and images, but unfortunately not for patterns. I will try to fix this issue. However, this may take a few days, because I have a rather tight schedule at the moment.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: wxPDF wxBRUSHSTYLE substitude

Post by mael15 »

utelle wrote: Thu Sep 09, 2021 5:12 pmI fear you detected a deficiency of the current wxPdfDocument version. For templates it is required to list all resources they depend on. This is done for fonts and images, but unfortunately not for patterns. I will try to fix this issue. However, this may take a few days, because I have a rather tight schedule at the moment.
Okay, no worries, it is not urgent on my part. I am grateful that you always try and fix issues as fast as you can. O:)
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxPDF wxBRUSHSTYLE substitude

Post by utelle »

utelle wrote: Thu Sep 09, 2021 5:12 pmFor templates it is required to list all resources they depend on. This is done for fonts and images, but unfortunately not for patterns. I will try to fix this issue. However, this may take a few days, because I have a rather tight schedule at the moment.
The latest commit (as of today) in the wxPdfDocument GitHub repository should fix the issue.

Later on I will take a look whether support for hatched brushes can be added.

Update 2021-09-14: Work is in progress to implement support for hatched brushes. I'll drop a note here, when the feature is available.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: wxPDF wxBRUSHSTYLE substitude

Post by mael15 »

i can confirm that it is not a blank page anymore, but there is no pattern using the code posted previously. I can wait for a hatched brush and not worry about the pattern though.
thank you for fixing this so fast! =D>
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxPDF wxBRUSHSTYLE substitude

Post by utelle »

mael15 wrote: Tue Sep 14, 2021 12:10 pm i can confirm that it is not a blank page anymore, but there is no pattern using the code posted previously.
I used the graphics pattern file you posted here, and it worked for me. No idea what went wrong in your application. However, it would be nice if you could provide the resulting PDF file (without compression) again, so that I can check it. There is always a chance that I introduced a new bug. :(
mael15 wrote: Tue Sep 14, 2021 12:10 pm I can wait for a hatched brush and not worry about the pattern though.
I made a wxPdfDocument release today, which includes enhanced fill pattern support. The wxBrush hatch pattern styles are now supported, directly as well as via wxPdfDC (see samples/minimal/drawing.cpp and samples/pdfdc/printing.cpp). Additionally, fill patterns can now be based on templates, not only bitmap images. However, via wxPdfDC only the wxBrush stipple style is supported.
mael15 wrote: Tue Sep 14, 2021 12:10 pm thank you for fixing this so fast! =D>
You are welcome.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: wxPDF wxBRUSHSTYLE substitude

Post by mael15 »

hi ulrich,
unfortunately I could not get it to work with the latest version. I attached both failures, one from the png pattern and one with wxPDF_PATTERNSTYLE_BDIAGONAL_HATCH.
Do I understand it correctly that this is not possible, I have to work with wxPDF pattern?

Code: Select all

dc.SetBrush(wxBrush(ecBlue, wxBRUSHSTYLE_BDIAGONAL_HATCH));
dc.DrawRectangle(pnt, sz);
Attachments
noPattern.zip
(350.22 KiB) Downloaded 114 times
utelle
Moderator
Moderator
Posts: 1125
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: wxPDF wxBRUSHSTYLE substitude

Post by utelle »

mael15 wrote: Fri Sep 17, 2021 9:09 am unfortunately I could not get it to work with the latest version.
Well, all I can tell is that the patterns work in the samples coming with wxPdfDocument. So, most likely there is something wrong in your code.
mael15 wrote: Fri Sep 17, 2021 9:09 am I attached both failures, one from the png pattern and one with wxPDF_PATTERNSTYLE_BDIAGONAL_HATCH.
Do I understand it correctly that this is not possible, I have to work with wxPDF pattern?

Code: Select all

dc.SetBrush(wxBrush(ecBlue, wxBRUSHSTYLE_BDIAGONAL_HATCH));
dc.DrawRectangle(pnt, sz);
I inspected the PDF with hatch pattern. IMHO it is a scaling issue. The hatched rectangle is drawn with the coordinates [1720.63 14161.89 1493.86 1904.88] which are outside the bounding box of the page and therefore invisible. Verify that pnt and sz have reasonable values.

In the PDF with image pattern it seems that the pattern wasn't applied at all.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Re: wxPDF wxBRUSHSTYLE substitude

Post by mael15 »

i am confused, so can I use wxDC::DrawRectangle or do I have to use wxPdfDocument::Rect ? The former would be easier, but it does not show wxBRUSHSTYLE_BDIAGONAL_HATCH yet.
I use this code:

Code: Select all

wxPdfDocument pdfDcmt;
pdfDcmt.SetCompression(false);
...
pdfDcmt.AddPage(orient, papSize);
int tpl = pdfDcmt.BeginTemplate();
dc = new wxPdfDC(&pdfDcmt, pageSzMM.x, pageSzMM.y);
dc->SetResolution(600);
dc->SetBackground(*wxWHITE_BRUSH);

if (dc->StartDoc(wxT("Printing ...")))
{
	//OutputDebugString(wxString::Format(wxT("Seite %i wird gedruckt\n"), i));
	libClientOutput::TubeDataPrintout::printToDC(*dc, i - 1);
and deep within printToDC

Code: Select all

dc.SetPen(ecBlue);
dc.SetBrush(wxBrush(ecBlue, wxBRUSHSTYLE_BDIAGONAL_HATCH));
dc.DrawRectangle(pnt, sz);
that results in the attached pdf with only a solid blue rectangle.

I also tried it like in the minimal example with

Code: Select all

pdf.AddPattern(wxS("hatch1"), wxPDF_PATTERNSTYLE_BDIAGONAL_HATCH, 1, 1, wxColour(224, 0, 0));
pdf.SetFillPattern(wxS("hatch1"));
pdf.Rect(25, 30, 25, 25, wxPDF_STYLE_FILLDRAW);
but nothing shows up on the page.
Attachments
solidNoHatch.zip
(178.58 KiB) Downloaded 102 times
Post Reply