mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-14 19:32:15 +01:00
fix(chromium): fit the page to content for landscape single-page (#1390)
This commit is contained in:
@@ -55,6 +55,7 @@ func printToPdfActionFunc(reqCtx context.Context, logger *slog.Logger, outputPat
|
|||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
err := func() error {
|
err := func() error {
|
||||||
|
paperWidth := options.PaperWidth
|
||||||
paperHeight := options.PaperHeight
|
paperHeight := options.PaperHeight
|
||||||
pageRanges := options.PageRanges
|
pageRanges := options.PageRanges
|
||||||
|
|
||||||
@@ -68,9 +69,20 @@ func printToPdfActionFunc(reqCtx context.Context, logger *slog.Logger, outputPat
|
|||||||
|
|
||||||
// There are 96 CSS pixels per inch.
|
// There are 96 CSS pixels per inch.
|
||||||
// See https://issues.chromium.org/issues/40267771#comment14.
|
// See https://issues.chromium.org/issues/40267771#comment14.
|
||||||
|
if options.Landscape {
|
||||||
|
// Landscape swaps the paper dimensions, so the page is
|
||||||
|
// WithPaperHeight wide by WithPaperWidth tall. Size both to
|
||||||
|
// the content so the width expands to fit a wide document
|
||||||
|
// (e.g. a table) instead of the height-only expansion
|
||||||
|
// landing on the width axis and truncating it.
|
||||||
|
// See https://github.com/gotenberg/gotenberg/issues/1390.
|
||||||
|
paperWidth = (cssContentSize.Height / 96) + options.MarginTop + options.MarginBottom
|
||||||
|
paperHeight = (cssContentSize.Width / 96) + options.MarginLeft + options.MarginRight
|
||||||
|
} else {
|
||||||
// We add top and bottom margins so that the content area
|
// We add top and bottom margins so that the content area
|
||||||
// is large enough to fit the entire content.
|
// is large enough to fit the entire content.
|
||||||
paperHeight = (cssContentSize.Height / 96) + options.MarginTop + options.MarginBottom
|
paperHeight = (cssContentSize.Height / 96) + options.MarginTop + options.MarginBottom
|
||||||
|
}
|
||||||
pageRanges = "1" // little dirty hack to avoid leftovers.
|
pageRanges = "1" // little dirty hack to avoid leftovers.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +91,7 @@ func printToPdfActionFunc(reqCtx context.Context, logger *slog.Logger, outputPat
|
|||||||
WithLandscape(options.Landscape).
|
WithLandscape(options.Landscape).
|
||||||
WithPrintBackground(options.PrintBackground).
|
WithPrintBackground(options.PrintBackground).
|
||||||
WithScale(options.Scale).
|
WithScale(options.Scale).
|
||||||
WithPaperWidth(options.PaperWidth).
|
WithPaperWidth(paperWidth).
|
||||||
WithPaperHeight(paperHeight).
|
WithPaperHeight(paperHeight).
|
||||||
WithMarginTop(options.MarginTop).
|
WithMarginTop(options.MarginTop).
|
||||||
WithMarginBottom(options.MarginBottom).
|
WithMarginBottom(options.MarginBottom).
|
||||||
|
|||||||
@@ -62,6 +62,24 @@ Feature: /forms/chromium/convert/html
|
|||||||
Page 12
|
Page 12
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# A wide table on one landscape page: the page must expand its width to the
|
||||||
|
# content, so the rightmost column is not truncated and the page comes out
|
||||||
|
# landscape instead of the narrow-tall strip the height-only expansion used
|
||||||
|
# to produce. See https://github.com/gotenberg/gotenberg/issues/1390.
|
||||||
|
Scenario: POST /forms/chromium/convert/html (Single Page Landscape)
|
||||||
|
Given I have a default Gotenberg container
|
||||||
|
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||||
|
| files | testdata/wide-table-html/index.html | file |
|
||||||
|
| singlePage | true | field |
|
||||||
|
| landscape | true | field |
|
||||||
|
| Gotenberg-Output-Filename | foo | header |
|
||||||
|
Then the response status code should be 200
|
||||||
|
Then the response header "Content-Type" should be "application/pdf"
|
||||||
|
Then there should be 1 PDF(s) in the response
|
||||||
|
Then the "foo.pdf" PDF should have 1 page(s)
|
||||||
|
Then the "foo.pdf" PDF should be set to landscape orientation
|
||||||
|
Then the "foo.pdf" PDF should have content matching "Column 12" at page 1
|
||||||
|
|
||||||
Scenario: POST /forms/chromium/convert/html (Landscape)
|
Scenario: POST /forms/chromium/convert/html (Landscape)
|
||||||
Given I have a default Gotenberg container
|
Given I have a default Gotenberg container
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||||
|
|||||||
@@ -1094,7 +1094,9 @@ func (s *scenario) thePdfShouldBeSetToLandscapeOrientation(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
output = strings.ReplaceAll(output, " ", "")
|
output = strings.ReplaceAll(output, " ", "")
|
||||||
re := regexp.MustCompile(`Pagesize:(\d+)x(\d+).*`)
|
// The dimensions can be fractional (e.g. a content-sized single page),
|
||||||
|
// so match floats, not just integers.
|
||||||
|
re := regexp.MustCompile(`Pagesize:([\d.]+)x([\d.]+)`)
|
||||||
matches := re.FindStringSubmatch(output)
|
matches := re.FindStringSubmatch(output)
|
||||||
|
|
||||||
if len(matches) < 3 {
|
if len(matches) < 3 {
|
||||||
@@ -1103,22 +1105,22 @@ func (s *scenario) thePdfShouldBeSetToLandscapeOrientation(ctx context.Context,
|
|||||||
|
|
||||||
invert := kind == "should NOT"
|
invert := kind == "should NOT"
|
||||||
|
|
||||||
width, err := strconv.Atoi(matches[1])
|
width, err := strconv.ParseFloat(matches[1], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("convert width value %q to integer: %w", matches[1], err)
|
return fmt.Errorf("convert width value %q to float: %w", matches[1], err)
|
||||||
}
|
}
|
||||||
|
|
||||||
height, err := strconv.Atoi(matches[2])
|
height, err := strconv.ParseFloat(matches[2], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("convert height value %q to integer: %w", matches[2], err)
|
return fmt.Errorf("convert height value %q to float: %w", matches[2], err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if invert && height < width {
|
if invert && height < width {
|
||||||
return fmt.Errorf("expected height %d to be greater than width %d", height, width)
|
return fmt.Errorf("expected height %g to be greater than width %g", height, width)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !invert && width < height {
|
if !invert && width < height {
|
||||||
return fmt.Errorf("expected width %d to be greater than height %d", width, height)
|
return fmt.Errorf("expected width %g to be greater than height %g", width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
43
test/integration/testdata/wide-table-html/index.html
vendored
Normal file
43
test/integration/testdata/wide-table-html/index.html
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Wide table</title>
|
||||||
|
<style>
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
border: 1px solid #000;
|
||||||
|
padding: 8px 24px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- A single wide row: much wider than tall, so a correct single page is
|
||||||
|
landscape, and the rightmost column only survives if the width was
|
||||||
|
expanded to the content instead of truncated. -->
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Column 1</td>
|
||||||
|
<td>Column 2</td>
|
||||||
|
<td>Column 3</td>
|
||||||
|
<td>Column 4</td>
|
||||||
|
<td>Column 5</td>
|
||||||
|
<td>Column 6</td>
|
||||||
|
<td>Column 7</td>
|
||||||
|
<td>Column 8</td>
|
||||||
|
<td>Column 9</td>
|
||||||
|
<td>Column 10</td>
|
||||||
|
<td>Column 11</td>
|
||||||
|
<td>Column 12</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user