Skip to content

Commit 9112e41

Browse files
Copilotlaeubi
authored andcommitted
Make PDFDocument extend Device instead of implementing Drawable
Change PDFDocument to subclass Device rather than implement Drawable to centralize resource management, align with Device lifecycle, and simplify drawing logic. This also fixes some complication with the windows implementation that possibly chooses bad defaults and confuses screen DPI with PDF defaults (72 DPI). Further the classes are made final and marked as experimental.
1 parent 1a6e82c commit 9112e41

File tree

3 files changed

+407
-357
lines changed

3 files changed

+407
-357
lines changed

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

Lines changed: 87 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@
4343
*
4444
* @see GC
4545
* @since 3.133
46+
*
47+
* @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.
4648
*/
47-
public class PDFDocument implements Drawable {
48-
Device device;
49+
public final class PDFDocument extends Device {
4950
long pdfContext;
5051
NSGraphicsContext graphicsContext;
5152
boolean isGCCreated = false;
52-
boolean disposed = false;
5353
boolean pageStarted = false;
54+
String filename;
5455

5556
/**
5657
* Width of the page in points (1/72 inch)
@@ -62,6 +63,16 @@ public class PDFDocument implements Drawable {
6263
*/
6364
double heightInPoints;
6465

66+
/**
67+
* Internal data class to pass PDF document parameters through
68+
* the Device constructor.
69+
*/
70+
static class PDFDocumentData extends DeviceData {
71+
String filename;
72+
double widthInPoints;
73+
double heightInPoints;
74+
}
75+
6576
/**
6677
* Constructs a new PDFDocument with the specified filename and page dimensions.
6778
* <p>
@@ -83,52 +94,38 @@ public class PDFDocument implements Drawable {
8394
* @see #dispose()
8495
*/
8596
public PDFDocument(String filename, double widthInPoints, double heightInPoints) {
86-
this(null, filename, widthInPoints, heightInPoints);
97+
super(checkData(filename, widthInPoints, heightInPoints));
8798
}
8899

89100
/**
90-
* Constructs a new PDFDocument with the specified filename and page dimensions,
91-
* associated with the given device.
92-
* <p>
93-
* You must dispose the PDFDocument when it is no longer required.
94-
* </p>
95-
*
96-
* @param device the device to associate with this PDFDocument
97-
* @param filename the path to the PDF file to create
98-
* @param widthInPoints the width of each page in points (1/72 inch)
99-
* @param heightInPoints the height of each page in points (1/72 inch)
100-
*
101-
* @exception IllegalArgumentException <ul>
102-
* <li>ERROR_NULL_ARGUMENT - if filename is null</li>
103-
* <li>ERROR_INVALID_ARGUMENT - if width or height is not positive</li>
104-
* </ul>
105-
* @exception SWTError <ul>
106-
* <li>ERROR_NO_HANDLES - if the PDF context could not be created</li>
107-
* </ul>
108-
*
109-
* @see #dispose()
101+
* Validates and prepares the data for construction.
110102
*/
111-
public PDFDocument(Device device, String filename, double widthInPoints, double heightInPoints) {
103+
static PDFDocumentData checkData(String filename, double widthInPoints, double heightInPoints) {
112104
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
113105
if (widthInPoints <= 0 || heightInPoints <= 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
106+
PDFDocumentData data = new PDFDocumentData();
107+
data.filename = filename;
108+
data.widthInPoints = widthInPoints;
109+
data.heightInPoints = heightInPoints;
110+
return data;
111+
}
112+
113+
/**
114+
* Creates the PDF device in the operating system.
115+
* This method is called before <code>init</code>.
116+
*
117+
* @param data the DeviceData which describes the receiver
118+
*/
119+
@Override
120+
protected void create(DeviceData data) {
121+
PDFDocumentData pdfData = (PDFDocumentData) data;
122+
this.filename = pdfData.filename;
123+
this.widthInPoints = pdfData.widthInPoints;
124+
this.heightInPoints = pdfData.heightInPoints;
114125

115126
NSAutoreleasePool pool = null;
116127
if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
117128
try {
118-
this.widthInPoints = widthInPoints;
119-
this.heightInPoints = heightInPoints;
120-
121-
// Get device from the current display if not provided
122-
if (device == null) {
123-
try {
124-
this.device = org.eclipse.swt.widgets.Display.getDefault();
125-
} catch (Exception e) {
126-
this.device = null;
127-
}
128-
} else {
129-
this.device = device;
130-
}
131-
132129
// Create CFURL from the filename
133130
NSString path = NSString.stringWith(filename);
134131
NSURL fileURL = NSURL.fileURLWithPath(path);
@@ -184,11 +181,11 @@ private void ensurePageStarted() {
184181
* </p>
185182
*
186183
* @exception SWTException <ul>
187-
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
184+
* <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
188185
* </ul>
189186
*/
190187
public void newPage() {
191-
if (disposed) SWT.error(SWT.ERROR_WIDGET_DISPOSED);
188+
checkDevice();
192189
NSAutoreleasePool pool = null;
193190
if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
194191
try {
@@ -216,11 +213,11 @@ public void newPage() {
216213
* <li>ERROR_INVALID_ARGUMENT - if width or height is not positive</li>
217214
* </ul>
218215
* @exception SWTException <ul>
219-
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
216+
* <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
220217
* </ul>
221218
*/
222219
public void newPage(double widthInPoints, double heightInPoints) {
223-
if (disposed) SWT.error(SWT.ERROR_WIDGET_DISPOSED);
220+
checkDevice();
224221
if (widthInPoints <= 0 || heightInPoints <= 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
225222

226223
this.widthInPoints = widthInPoints;
@@ -234,11 +231,11 @@ public void newPage(double widthInPoints, double heightInPoints) {
234231
* @return the width in points (1/72 inch)
235232
*
236233
* @exception SWTException <ul>
237-
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
234+
* <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
238235
* </ul>
239236
*/
240237
public double getWidth() {
241-
if (disposed) SWT.error(SWT.ERROR_WIDGET_DISPOSED);
238+
checkDevice();
242239
return widthInPoints;
243240
}
244241

@@ -248,14 +245,47 @@ public double getWidth() {
248245
* @return the height in points (1/72 inch)
249246
*
250247
* @exception SWTException <ul>
251-
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
248+
* <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
252249
* </ul>
253250
*/
254251
public double getHeight() {
255-
if (disposed) SWT.error(SWT.ERROR_WIDGET_DISPOSED);
252+
checkDevice();
256253
return heightInPoints;
257254
}
258255

256+
/**
257+
* Returns the DPI (dots per inch) of the PDF document.
258+
* PDF documents work in points where 1 point = 1/72 inch,
259+
* so the DPI is always 72.
260+
*
261+
* @return a point whose x coordinate is the horizontal DPI and whose y coordinate is the vertical DPI
262+
*
263+
* @exception SWTException <ul>
264+
* <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
265+
* </ul>
266+
*/
267+
@Override
268+
public Point getDPI() {
269+
checkDevice();
270+
return new Point(72, 72);
271+
}
272+
273+
/**
274+
* Returns a rectangle describing the receiver's size and location.
275+
* The rectangle dimensions are in points (1/72 inch).
276+
*
277+
* @return the bounding rectangle
278+
*
279+
* @exception SWTException <ul>
280+
* <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
281+
* </ul>
282+
*/
283+
@Override
284+
public Rectangle getBounds() {
285+
checkDevice();
286+
return new Rectangle(0, 0, (int) widthInPoints, (int) heightInPoints);
287+
}
288+
259289
/**
260290
* Invokes platform specific functionality to allocate a new GC handle.
261291
* <p>
@@ -273,7 +303,7 @@ public double getHeight() {
273303
*/
274304
@Override
275305
public long internal_new_GC(GCData data) {
276-
if (disposed) SWT.error(SWT.ERROR_WIDGET_DISPOSED);
306+
checkDevice();
277307
if (isGCCreated) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
278308

279309
NSAutoreleasePool pool = null;
@@ -290,18 +320,16 @@ public long internal_new_GC(GCData data) {
290320
if ((data.style & mask) == 0) {
291321
data.style |= SWT.LEFT_TO_RIGHT;
292322
}
293-
data.device = device;
323+
data.device = this;
294324
data.flippedContext = graphicsContext;
295325
data.restoreContext = true;
296326
NSSize size = new NSSize();
297327
size.width = widthInPoints;
298328
size.height = heightInPoints;
299329
data.size = size;
300-
if (device != null) {
301-
data.background = device.getSystemColor(SWT.COLOR_WHITE).handle;
302-
data.foreground = device.getSystemColor(SWT.COLOR_BLACK).handle;
303-
data.font = device.getSystemFont();
304-
}
330+
data.background = getSystemColor(SWT.COLOR_WHITE).handle;
331+
data.foreground = getSystemColor(SWT.COLOR_BLACK).handle;
332+
data.font = getSystemFont();
305333
}
306334
isGCCreated = true;
307335
return graphicsContext.id;
@@ -350,27 +378,12 @@ public boolean isAutoScalable() {
350378
}
351379

352380
/**
353-
* Returns <code>true</code> if the PDFDocument has been disposed,
354-
* and <code>false</code> otherwise.
355-
*
356-
* @return <code>true</code> when the PDFDocument is disposed and <code>false</code> otherwise
381+
* Destroys the PDF document handle.
382+
* This method is called internally by the dispose
383+
* mechanism of the <code>Device</code> class.
357384
*/
358-
public boolean isDisposed() {
359-
return disposed;
360-
}
361-
362-
/**
363-
* Disposes of the operating system resources associated with
364-
* the PDFDocument. Applications must dispose of all PDFDocuments
365-
* that they allocate.
366-
* <p>
367-
* This method finalizes the PDF file and writes it to disk.
368-
* </p>
369-
*/
370-
public void dispose() {
371-
if (disposed) return;
372-
disposed = true;
373-
385+
@Override
386+
protected void destroy() {
374387
NSAutoreleasePool pool = null;
375388
if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
376389
try {

0 commit comments

Comments
 (0)