Skip to content

Commit 44ab447

Browse files
Copilotlaeubi
authored andcommitted
Add PageSize record and PDFDocument constructor accepting PageSize
Introduce a new PageSize record in the common printing package that holds page dimensions (width and height) in points (1/72 inch). The record includes predefined constants for common paper sizes: LETTER, LEGAL, A3, A4, A5, EXECUTIVE, and TABLOID supported across platforms.
1 parent ca459f1 commit 44ab447

5 files changed

Lines changed: 255 additions & 3 deletions

File tree

bundles/org.eclipse.swt/Eclipse SWT Printing/cocoa/org/eclipse/swt/printing/PDFDocument.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,30 @@ static class PDFDocumentData extends DeviceData {
7373
double heightInPoints;
7474
}
7575

76+
/**
77+
* Constructs a new PDFDocument with the specified filename and page size.
78+
* <p>
79+
* You must dispose the PDFDocument when it is no longer required.
80+
* </p>
81+
*
82+
* @param filename the path to the PDF file to create
83+
* @param pageSize the page size specifying width and height in points (1/72 inch)
84+
*
85+
* @exception IllegalArgumentException <ul>
86+
* <li>ERROR_NULL_ARGUMENT - if filename or pageSize is null</li>
87+
* <li>ERROR_INVALID_ARGUMENT - if width or height is not positive</li>
88+
* </ul>
89+
* @exception SWTError <ul>
90+
* <li>ERROR_NO_HANDLES - if the PDF context could not be created</li>
91+
* </ul>
92+
*
93+
* @see PageSize
94+
* @see #dispose()
95+
*/
96+
public PDFDocument(String filename, PageSize pageSize) {
97+
super(checkData(filename, pageSize));
98+
}
99+
76100
/**
77101
* Constructs a new PDFDocument with the specified filename and page dimensions.
78102
* <p>
@@ -94,7 +118,15 @@ static class PDFDocumentData extends DeviceData {
94118
* @see #dispose()
95119
*/
96120
public PDFDocument(String filename, double widthInPoints, double heightInPoints) {
97-
super(checkData(filename, widthInPoints, heightInPoints));
121+
this(filename, new PageSize(widthInPoints, heightInPoints));
122+
}
123+
124+
/**
125+
* Validates and prepares the data for construction.
126+
*/
127+
static PDFDocumentData checkData(String filename, PageSize pageSize) {
128+
if (pageSize == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
129+
return checkData(filename, pageSize.width(), pageSize.height());
98130
}
99131

100132
/**
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Eclipse Platform Contributors and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Eclipse Platform Contributors - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.swt.printing;
15+
16+
/**
17+
* A {@code PageSize} represents the dimensions of a page in points
18+
* (1 point = 1/72 inch), as used in PDF documents and printing.
19+
* <p>
20+
* This record provides predefined constants for common paper sizes
21+
* that are supported across all platforms (Windows, GTK, macOS).
22+
* Using these constants avoids confusion between points and pixels
23+
* and ensures consistent page dimensions.
24+
* </p>
25+
* <p>
26+
* Example usage:
27+
* </p>
28+
* <pre>
29+
* PDFDocument pdf = new PDFDocument("output.pdf", PageSize.A4);
30+
* GC gc = new GC(pdf);
31+
* gc.drawText("Hello, PDF!", 100, 100);
32+
* gc.dispose();
33+
* pdf.dispose();
34+
* </pre>
35+
*
36+
* @param width the width of the page in points (1/72 inch)
37+
* @param height the height of the page in points (1/72 inch)
38+
*
39+
* @since 3.133
40+
*
41+
* @noreference This class is provisional API and subject to change. It is being made available to gather early feedback. The API or behavior may change in future releases as the implementation evolves based on user feedback.
42+
*/
43+
public record PageSize(double width, double height) {
44+
45+
/** US Letter size: 8.5 x 11 inches (612 x 792 points) */
46+
public static final PageSize LETTER = new PageSize(612, 792);
47+
48+
/** US Legal size: 8.5 x 14 inches (612 x 1008 points) */
49+
public static final PageSize LEGAL = new PageSize(612, 1008);
50+
51+
/** ISO A3 size: 297 x 420 mm (842 x 1191 points) */
52+
public static final PageSize A3 = new PageSize(842, 1191);
53+
54+
/** ISO A4 size: 210 x 297 mm (595 x 842 points) */
55+
public static final PageSize A4 = new PageSize(595, 842);
56+
57+
/** ISO A5 size: 148 x 210 mm (420 x 595 points) */
58+
public static final PageSize A5 = new PageSize(420, 595);
59+
60+
/** US Executive size: 7.25 x 10.5 inches (522 x 756 points) */
61+
public static final PageSize EXECUTIVE = new PageSize(522, 756);
62+
63+
/** US Tabloid size: 11 x 17 inches (792 x 1224 points) */
64+
public static final PageSize TABLOID = new PageSize(792, 1224);
65+
}

bundles/org.eclipse.swt/Eclipse SWT Printing/gtk/org/eclipse/swt/printing/PDFDocument.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,30 @@ static class PDFDocumentData extends DeviceData {
7373
double heightInPoints;
7474
}
7575

76+
/**
77+
* Constructs a new PDFDocument with the specified filename and page size.
78+
* <p>
79+
* You must dispose the PDFDocument when it is no longer required.
80+
* </p>
81+
*
82+
* @param filename the path to the PDF file to create
83+
* @param pageSize the page size specifying width and height in points (1/72 inch)
84+
*
85+
* @exception IllegalArgumentException <ul>
86+
* <li>ERROR_NULL_ARGUMENT - if filename or pageSize is null</li>
87+
* <li>ERROR_INVALID_ARGUMENT - if width or height is not positive</li>
88+
* </ul>
89+
* @exception SWTError <ul>
90+
* <li>ERROR_NO_HANDLES - if the PDF surface could not be created</li>
91+
* </ul>
92+
*
93+
* @see PageSize
94+
* @see #dispose()
95+
*/
96+
public PDFDocument(String filename, PageSize pageSize) {
97+
super(checkData(filename, pageSize));
98+
}
99+
76100
/**
77101
* Constructs a new PDFDocument with the specified filename and page dimensions.
78102
* <p>
@@ -94,7 +118,15 @@ static class PDFDocumentData extends DeviceData {
94118
* @see #dispose()
95119
*/
96120
public PDFDocument(String filename, double widthInPoints, double heightInPoints) {
97-
super(checkData(filename, widthInPoints, heightInPoints));
121+
this(filename, new PageSize(widthInPoints, heightInPoints));
122+
}
123+
124+
/**
125+
* Validates and prepares the data for construction.
126+
*/
127+
static PDFDocumentData checkData(String filename, PageSize pageSize) {
128+
if (pageSize == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
129+
return checkData(filename, pageSize.width(), pageSize.height());
98130
}
99131

100132
/**

bundles/org.eclipse.swt/Eclipse SWT Printing/win32/org/eclipse/swt/printing/PDFDocument.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,37 @@ private static PaperSize findBestPaperSize(double widthInPoints, double heightIn
161161
return bestMatch;
162162
}
163163

164+
/**
165+
* Constructs a new PDFDocument with the specified filename and page size.
166+
* <p>
167+
* The page size specifies the preferred dimensions in points (1/72 inch). On Windows,
168+
* the Microsoft Print to PDF driver only supports standard paper sizes, so the actual
169+
* page size may be larger than requested. Use {@link #getBounds()} to query the actual
170+
* page dimensions after construction.
171+
* </p>
172+
* <p>
173+
* You must dispose the PDFDocument when it is no longer required.
174+
* </p>
175+
*
176+
* @param filename the path to the PDF file to create
177+
* @param pageSize the page size specifying width and height in points (1/72 inch)
178+
*
179+
* @exception IllegalArgumentException <ul>
180+
* <li>ERROR_NULL_ARGUMENT - if filename or pageSize is null</li>
181+
* <li>ERROR_INVALID_ARGUMENT - if width or height is not positive</li>
182+
* </ul>
183+
* @exception SWTError <ul>
184+
* <li>ERROR_NO_HANDLES - if the PDF printer is not available</li>
185+
* </ul>
186+
*
187+
* @see PageSize
188+
* @see #dispose()
189+
* @see #getBounds()
190+
*/
191+
public PDFDocument(String filename, PageSize pageSize) {
192+
super(checkData(filename, pageSize));
193+
}
194+
164195
/**
165196
* Constructs a new PDFDocument with the specified filename and preferred page dimensions.
166197
* <p>
@@ -189,7 +220,15 @@ private static PaperSize findBestPaperSize(double widthInPoints, double heightIn
189220
* @see #getBounds()
190221
*/
191222
public PDFDocument(String filename, double widthInPoints, double heightInPoints) {
192-
super(checkData(filename, widthInPoints, heightInPoints));
223+
this(filename, new PageSize(widthInPoints, heightInPoints));
224+
}
225+
226+
/**
227+
* Validates and prepares the data for construction.
228+
*/
229+
static PDFDocumentData checkData(String filename, PageSize pageSize) {
230+
if (pageSize == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
231+
return checkData(filename, pageSize.width(), pageSize.height());
193232
}
194233

195234
/**

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_printing_PDFDocument.java

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
*******************************************************************************/
1414
package org.eclipse.swt.tests.junit;
1515

16+
import static org.junit.jupiter.api.Assertions.assertEquals;
1617
import static org.junit.jupiter.api.Assertions.assertNotNull;
18+
import static org.junit.jupiter.api.Assertions.assertThrows;
1719
import static org.junit.jupiter.api.Assertions.assertTrue;
1820

1921
import java.io.File;
@@ -23,6 +25,7 @@
2325

2426
import org.eclipse.swt.graphics.GC;
2527
import org.eclipse.swt.printing.PDFDocument;
28+
import org.eclipse.swt.printing.PageSize;
2629
import org.eclipse.swt.widgets.Display;
2730
import org.junit.jupiter.api.AfterEach;
2831
import org.junit.jupiter.api.BeforeEach;
@@ -99,4 +102,85 @@ public void test_createPDFDocumentWithHelloWorld() throws IOException {
99102
"PDF file should start with %PDF- magic bytes, but got: " + headerString);
100103
}
101104

105+
@Test
106+
public void test_createPDFDocumentWithPageSize() throws IOException {
107+
// Create a temporary file for the PDF
108+
tempFile = Files.createTempFile(tempDir, "test_pagesize", ".pdf").toFile();
109+
String filename = tempFile.getAbsolutePath();
110+
111+
// Create PDF document using PageSize constant
112+
pdfDocument = new PDFDocument(filename, PageSize.A4);
113+
assertNotNull(pdfDocument, "PDFDocument should be created with PageSize");
114+
115+
// Create a GC on the PDF document
116+
gc = new GC(pdfDocument);
117+
assertNotNull(gc, "GC should be created on PDFDocument");
118+
119+
// Draw text
120+
gc.drawText("Hello from PageSize.A4!", 100, 100);
121+
122+
// Dispose of resources to finalize the PDF
123+
gc.dispose();
124+
gc = null;
125+
pdfDocument.dispose();
126+
pdfDocument = null;
127+
128+
// Verify the PDF file was created and is not empty
129+
assertTrue(tempFile.exists(), "PDF file should exist");
130+
assertTrue(tempFile.length() > 0, "PDF file should not be empty");
131+
132+
// Verify PDF magic bytes
133+
byte[] fileContent = Files.readAllBytes(tempFile.toPath());
134+
String headerString = new String(fileContent, 0, Math.min(5, fileContent.length));
135+
assertTrue(headerString.startsWith("%PDF-"),
136+
"PDF file should start with %PDF- magic bytes, but got: " + headerString);
137+
}
138+
139+
@Test
140+
public void test_pageSizePredefinedConstants() {
141+
// Verify predefined paper sizes have correct dimensions
142+
assertEquals(612, PageSize.LETTER.width());
143+
assertEquals(792, PageSize.LETTER.height());
144+
145+
assertEquals(612, PageSize.LEGAL.width());
146+
assertEquals(1008, PageSize.LEGAL.height());
147+
148+
assertEquals(595, PageSize.A4.width());
149+
assertEquals(842, PageSize.A4.height());
150+
151+
assertEquals(842, PageSize.A3.width());
152+
assertEquals(1191, PageSize.A3.height());
153+
154+
assertEquals(420, PageSize.A5.width());
155+
assertEquals(595, PageSize.A5.height());
156+
157+
assertEquals(522, PageSize.EXECUTIVE.width());
158+
assertEquals(756, PageSize.EXECUTIVE.height());
159+
160+
assertEquals(792, PageSize.TABLOID.width());
161+
assertEquals(1224, PageSize.TABLOID.height());
162+
}
163+
164+
@Test
165+
public void test_pageSizeCustom() {
166+
// Verify custom page sizes can be created
167+
PageSize custom = new PageSize(300, 400);
168+
assertEquals(300, custom.width());
169+
assertEquals(400, custom.height());
170+
}
171+
172+
@Test
173+
public void test_createPDFDocumentWithNullPageSize() {
174+
assertThrows(IllegalArgumentException.class, () -> {
175+
new PDFDocument("test.pdf", (PageSize) null);
176+
});
177+
}
178+
179+
@Test
180+
public void test_pageSizeEquality() {
181+
// Records should have value-based equality
182+
PageSize a4Copy = new PageSize(595, 842);
183+
assertEquals(PageSize.A4, a4Copy);
184+
}
185+
102186
}

0 commit comments

Comments
 (0)