From 198038f5ea5b1ce891deb9171850c3ffd316d401 Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Sat, 1 Feb 2020 18:06:48 +0000 Subject: [PATCH] Add support for Chrome scaling. --- build/docs/content/04-html.md | 7 ++- docs/index.html | 15 ++++--- internal/app/xhttp/option.go | 5 +++ internal/app/xhttp/pkg/resource/arg.go | 28 ++++++++++++ internal/app/xhttp/pkg/resource/arg_test.go | 48 +++++++++++++++++++++ internal/pkg/printer/chrome.go | 5 ++- 6 files changed, 99 insertions(+), 9 deletions(-) diff --git a/build/docs/content/04-html.md b/build/docs/content/04-html.md index 85c426d5..a2501ae6 100644 --- a/build/docs/content/04-html.md +++ b/build/docs/content/04-html.md @@ -243,11 +243,11 @@ $dest = 'result.pdf'; $client->store($request, $dest); ``` -## Paper size, margins, orientation +## Paper size, margins, orientation, scaling You may also customize the resulting PDF format. -By default, it will be rendered with `A4` size, `1 inch` margins and `portrait` orientation. +By default, it will be rendered with `A4` size, `1 inch` margins and `portrait` orientation and 100% (`1.0`) page scale. > Paper size and margins have to be provided in `inches`. Same for margins. @@ -265,6 +265,7 @@ $ curl --request POST \ --form marginLeft=0 \ --form marginRight=0 \ --form landscape=true \ + --form scale=0.75 \ -o result.pdf ``` @@ -279,6 +280,7 @@ req := gotenberg.NewHTMLRequest(index) req.PaperSize(gotenberg.A4) req.Margins(gotenberg.NoMargins) req.Landscape(true) +req.Scale(0.75) dest := "result.pdf" c.Store(req, dest) ``` @@ -297,6 +299,7 @@ $request = new HTMLRequest($index); $request->setPaperSize(Request::A4); $request->setMargins(Request::NO_MARGINS); $request->setLandscape(true); +$request->setScale(0.75); $dest = 'result.pdf'; $client->store($request, $dest); ``` diff --git a/docs/index.html b/docs/index.html index 4853baa6..b5599191 100755 --- a/docs/index.html +++ b/docs/index.html @@ -675,19 +675,19 @@ $dest = 'result.pdf'; $client->store($request, $dest); -

Paper size, margins, orientation

+Paper size, margins, orientation, scaling

You may also customize the resulting PDF format.

-

By default, it will be rendered with A4 size, 1 inch margins and portrait orientation.

+

By default, it will be rendered with A4 size, 1 inch margins and portrait orientation and 100% (1.0) page scale.

Paper size and margins have to be provided in inches. Same for margins.

-

cURL

@@ -702,10 +702,11 @@ $client->store($request, $dest); --form marginLeft=0 \ --form marginRight=0 \ --form landscape=true \ + --form scale=0.75 \ -o result.pdf -

Go

@@ -717,11 +718,12 @@ $client->store($request, $dest); req.PaperSize(gotenberg.A4) req.Margins(gotenberg.NoMargins) req.Landscape(true) +req.Scale(0.75) dest := "result.pdf" c.Store(req, dest) -

PHP

@@ -736,6 +738,7 @@ $request = new HTMLRequest($index); $request->setPaperSize(Request::A4); $request->setMargins(Request::NO_MARGINS); $request->setLandscape(true); +$request->setScale(0.75); $dest = 'result.pdf'; $client->store($request, $dest); diff --git a/internal/app/xhttp/option.go b/internal/app/xhttp/option.go index 5a9a3759..335c7cd0 100644 --- a/internal/app/xhttp/option.go +++ b/internal/app/xhttp/option.go @@ -56,6 +56,10 @@ func chromePrinterOptions(r resource.Resource, config conf.Config) (printer.Chro if err != nil { return printer.ChromePrinterOptions{}, err } + scale, err := resource.ScaleArg(r, config) + if err != nil { + return printer.ChromePrinterOptions{}, err + } return printer.ChromePrinterOptions{ WaitTimeout: waitTimeout, WaitDelay: waitDelay, @@ -71,6 +75,7 @@ func chromePrinterOptions(r resource.Resource, config conf.Config) (printer.Chro PageRanges: pageRanges, RpccBufferSize: googleChromeRpccBufferSize, CustomHTTPHeaders: make(map[string]string), + Scale: scale, }, nil } opts, err := resolver() diff --git a/internal/app/xhttp/pkg/resource/arg.go b/internal/app/xhttp/pkg/resource/arg.go index 80063925..9c5f5cd7 100644 --- a/internal/app/xhttp/pkg/resource/arg.go +++ b/internal/app/xhttp/pkg/resource/arg.go @@ -57,6 +57,9 @@ const ( // GoogleChromeRpccBufferSizeArgKey is the key // of the argument "googleChromeRpccBufferSize". GoogleChromeRpccBufferSizeArgKey ArgKey = "googleChromeRpccBufferSize" + // ScaleArgKey is the key + // of the argument "scale". + ScaleArgKey ArgKey = "scale" ) /* @@ -81,6 +84,7 @@ func ArgKeys() []ArgKey { LandscapeArgKey, PageRangesArgKey, GoogleChromeRpccBufferSizeArgKey, + ScaleArgKey, } } @@ -294,3 +298,27 @@ func GoogleChromeRpccBufferSizeArg(r Resource, config conf.Config) (int64, error } return result, nil } + +/* +ScaleArg is a helper for retrieving +the "scale" argument as float64. + +It also validates it against the application +configuration. +*/ +func ScaleArg(r Resource, config conf.Config) (float64, error) { + const ( + op string = "resource.ScaleArg" + defaultScale float64 = 1.0 + ) + result, err := r.Float64Arg( + ScaleArgKey, + defaultScale, + xassert.Float64NotInferiorTo(0.1), + xassert.Float64NotSuperiorTo(2.0), + ) + if err != nil { + return result, xerror.New(op, err) + } + return result, nil +} diff --git a/internal/app/xhttp/pkg/resource/arg_test.go b/internal/app/xhttp/pkg/resource/arg_test.go index 230add46..0fefba18 100644 --- a/internal/app/xhttp/pkg/resource/arg_test.go +++ b/internal/app/xhttp/pkg/resource/arg_test.go @@ -26,6 +26,7 @@ func TestArgKeys(t *testing.T) { LandscapeArgKey, PageRangesArgKey, GoogleChromeRpccBufferSizeArgKey, + ScaleArgKey, } assert.Equal(t, expected, ArgKeys()) } @@ -346,3 +347,50 @@ func TestGoogleChromeRpccBufferSizeArg(t *testing.T) { err = r.Close() assert.Nil(t, err) } + +func TestScaleArg(t *testing.T) { + const ( + resourceDirectoryName string = "foo" + defaultValue float64 = 1.0 + ) + var expected float64 + logger := test.DebugLogger() + config := conf.DefaultConfig() + r, err := New(logger, resourceDirectoryName) + assert.Nil(t, err) + // argument does not exist. + expected = defaultValue + v, err := ScaleArg(r, config) + assert.Nil(t, err) + assert.Equal(t, expected, v) + // argument exist. + expected = 0.5 + r.WithArg(ScaleArgKey, "0.5") + v, err = ScaleArg(r, config) + assert.Nil(t, err) + assert.Equal(t, expected, v) + // should not be OK as argument + // value is < 0.1. + expected = defaultValue + r.WithArg(ScaleArgKey, "-1.0") + v, err = ScaleArg(r, config) + test.AssertError(t, err) + assert.Equal(t, expected, v) + // should not be OK as argument + // value is > 2.0. + expected = defaultValue + r.WithArg(ScaleArgKey, "2.1") + v, err = ScaleArg(r, config) + test.AssertError(t, err) + assert.Equal(t, expected, v) + // should not be OK as + // argument value is invalid. + expected = defaultValue + r.WithArg(ScaleArgKey, "foo") + v, err = ScaleArg(r, config) + test.AssertError(t, err) + assert.Equal(t, expected, v) + // finally... + err = r.Close() + assert.Nil(t, err) +} diff --git a/internal/pkg/printer/chrome.go b/internal/pkg/printer/chrome.go index 4fe79d33..745e3232 100644 --- a/internal/pkg/printer/chrome.go +++ b/internal/pkg/printer/chrome.go @@ -45,6 +45,7 @@ type ChromePrinterOptions struct { PageRanges string RpccBufferSize int64 CustomHTTPHeaders map[string]string + Scale float64 } // DefaultChromePrinterOptions returns the default @@ -66,6 +67,7 @@ func DefaultChromePrinterOptions(config conf.Config) ChromePrinterOptions { PageRanges: "", RpccBufferSize: config.DefaultGoogleChromeRpccBufferSize(), CustomHTTPHeaders: make(map[string]string), + Scale: 1.0, } } @@ -176,7 +178,8 @@ func (p chromePrinter) Print(destination string) error { SetDisplayHeaderFooter(true). SetHeaderTemplate(p.opts.HeaderHTML). SetFooterTemplate(p.opts.FooterHTML). - SetPrintBackground(true) + SetPrintBackground(true). + SetScale(p.opts.Scale) if p.opts.PageRanges != "" { printToPdfArgs.SetPageRanges(p.opts.PageRanges) }