parallax / jsPDF

Client-side JavaScript PDF generation for everyone.
https://parall.ax/products/jspdf
MIT License
29.29k stars 4.68k forks source link

broken API for pageformat supplied as array, Add API to set cropBox, trimBox, bleedBox, artBox, mediaBox #2152

Closed maxiplay closed 5 years ago

maxiplay commented 5 years ago

Hello !

How to do it ?

I don't find any reference in documentation. Is it implemented ? Is there is jsPDF the notion of "rectangles" zone ?

Uzlopak commented 5 years ago

We wanted to release tomorrow a the next version and today you come with this useful feature request :-D

Right now I wonder what the best place for putting the getter and setters could be. I guess I put them as an option parameter in addPage.

maxiplay commented 5 years ago

It would very useful to have the possibility to add rectangles zones to an existing page without the need to "addPage" for this.

Here you can find a java sample implementation by the library org.apache.pdfbox

` String sourceFile = "C:\Users\Maxime\Downloads\pdf.pdf"; String destinationFile = "C:\Users\Maxime\Downloads\pdf.pdf";

    PDDocument doc = PDDocument.load(new File(sourceFile));
    File destFile = new File(destinationFile);

    PDPageTree pages = doc.getPages();
    for (int i = 0; i < pages.getCount(); i++) {

        PDPage p = pages.get(i);

        p.setTrimBox(new PDRectangle(10, 300, 200, 200));
        p.setBleedBox(new PDRectangle(400, 300, 200, 200));
        p.setArtBox(new PDRectangle(200, 500, 200, 200));
        p.setCropBox(new PDRectangle(100, 200, 200, 200));
        p.setMediaBox(new PDRectangle(150, 250, 200, 200));
    }

    doc.save(destFile);
    doc.close();`
Uzlopak commented 5 years ago

Unfortunately we have no class/object structure in jsPDF. Right now i have a very hacky solution for the issue. Have to think how to make it better...

Uzlopak commented 5 years ago

Tbh, I dont want to write an API method for it right now, because if I write a not so well thought API method, then people would use it and then complain, when I make a proper API Method replacing it and breaking Userlayer. Would it be enough for now, if I just implement the data structure and tell you how to manipulate the rectangles? If I make the next release I would try to get some useful structures for the boxes.

maxiplay commented 5 years ago

Yes no problem :)

Uzlopak commented 5 years ago

You can get the mediabox and stuff with getPageInfo and because they are objects the data is associated by reference and not by value. So you can manipulate it

maxiplay commented 5 years ago

I test it tomorrow

maxiplay commented 5 years ago

I tried

                var pdf = new jsPDF({
                    orientation: 'landscape',
                    unit: 'mm',
                    format: [pdfWidth, pdfHeight]
                })

                pdf.addImage(imgData, 'JPEG', 0, 0, pdfWidth, pdfHeight, null, 'NONE');

                console.log(pdf.internal.getCurrentPageInfo());

capture

Uzlopak commented 5 years ago

what is in pageContext.mediaBox?

maxiplay commented 5 years ago

pageContext is an empty object {}. There is nothing.

Uzlopak commented 5 years ago

Which version do you use?

maxiplay commented 5 years ago

1.4.1

maxiplay commented 5 years ago

I can test 1.5.2 ?

Uzlopak commented 5 years ago

1.4.1 is six months old. 1.5.2 is the new release with the necessary changes..

maxiplay commented 5 years ago

Ok I tried and seems to have the good object info

capture

BUT the resulted PDF file does not have anymore good dimension with the new version (1.5.2) whereas the 1.4.1 has perfect dimensions (326mm X 230mm)

Uzlopak commented 5 years ago

You are accessing the data with the internal userunits. You have to scale it with the scalefactor, when you want to access it. The internal userunit is usually point. You can get the scalefactor by doing doc.internal.scaleFactor.

If you want to set trimBox and stuff, simply do e.g.

doc.getCurrentPageInfo().trimBox = {bottomLeftX: 0, bottormLeftY: 0, topRightX: 200, topRightY: 200}

maxiplay commented 5 years ago

OK for setting trimBox (And thank you !). I will test it.

But I don't understand why with the same code, the resulted pdf file is different between 1.4.1 and 1.5.2

Here the code i have to generate PDF file :

                var imgData = canvas.toDataURL("image/jpeg", 1.0);

                var pdf = new jsPDF({
                    orientation: 'landscape',
                    unit: 'mm',
                    format: [326, 230]
                })

                pdf.addImage(imgData, 'JPEG', 0, 0, 326, 230, null, 'NONE');

                pdf.save("download.pdf");

With 1.4.1 the resulted PDF has full image

capture1

With 1.5.2 the resulted PDF has rogned image

capture2

Uzlopak commented 5 years ago

Strange

Can you supply sample code.

Seems like that width and height are not scaled

Or can you provide old pdf and new pdf?

Uzlopak commented 5 years ago

Probably solved with #2193

maxiplay commented 5 years ago

Same behavior with 1.5.3.

I will create jsfiddle to show.

maxiplay commented 5 years ago

I created two jsfiddle to show the differents result.

The goal of the code is to generate a PDF from a canvas image.

jsPDF 1.4.1 keep the good size
unit: 'mm', format: [326, 230] https://jsfiddle.net/maxiplay/4k2Lode5/1/

JsPDF 1.5.3 do not adapt to unit: 'mm', format: [326, 230] https://jsfiddle.net/maxiplay/hwz8bm6a/

Uzlopak commented 5 years ago

I made I think the necessary changes in #2200

maxiplay commented 5 years ago

Wait new release version to test it.

kylebebak commented 5 years ago

I just tried this and can confirm that for 1.5.3, the format parameter doesn't work properly for array arguments. It works correctly in 1.4.1.

Seems like the 1.5.0 release broke a few things...

@arasabbasi Will this be fixed in 1.5.4? Any idea when 1.5.4 will be released?

epasquali commented 5 years ago

Seconded, I need the proper units fixed asap, I can't use 1.4.1 because that one doesn't properly do doc.open('dataurlnewwindow'), but I can't use 1.5.3 where dataurlnewwindow works because the format part doesn't work. So I can't use either of the two versions. When will you release 1.5.4 with the fix to the format?

gmv76 commented 5 years ago

Hello, please let us know when broken format-as-array issue will be solved, we want to use your lib on very specific formats (bespoke stationery for print) that dont'fit the standard letter-format provided e.g.: mm/px mm/px
2970 2100 form-A5L 1480 2100 form-A5 2900 2000 form-NLL 1450 2000 form-NLV 2000 1450 form-NL 1530 1100 form-20 1720 1150 form-21 2300 1700 form-21L 1700 2300 form-21LV 1630 1630 form-Q 3260 1630 form-QL 860 540 form-CC 950 560 form-07 1300 850 form-09 1470 980 form-99

Also any news on usage of custom TTF fonts (besides sphilee/jsPDF-CustomFonts-support)??

Uzlopak commented 5 years ago

@gmv76

Custom Fonts are integrated and doesnt need sphilees plugin anymore. I hope soon it will be released. You know... James is from the UK, probably some issues with Brexit right now...