From 6698267bdabc0abb623f47ab3955c9a6632b4274 Mon Sep 17 00:00:00 2001 From: Andreas Koch Date: Tue, 6 Jan 2026 12:34:44 +0100 Subject: [PATCH] Extend Snippet388 to generate PDF directly drawing on GC Currently Snippet388 showcases the PDF export by using Shell#print. This commit extends it to additionally probide the possibility to export a direct rendering on the GC. --- .../previews/Snippet388.png | Bin 0 -> 29143 bytes .../org/eclipse/swt/snippets/Snippet388.java | 383 +++++++++--------- 2 files changed, 200 insertions(+), 183 deletions(-) create mode 100644 examples/org.eclipse.swt.snippets/previews/Snippet388.png diff --git a/examples/org.eclipse.swt.snippets/previews/Snippet388.png b/examples/org.eclipse.swt.snippets/previews/Snippet388.png new file mode 100644 index 0000000000000000000000000000000000000000..8e681eb92f905d01b3f03b4b40dd67cec70cf0a9 GIT binary patch literal 29143 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 PeSOQo^alFc{h0p&AwmBj literal 0 HcmV?d00001 diff --git a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet388.java b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet388.java index 889100d17c6..ea81dee222a 100644 --- a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet388.java +++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet388.java @@ -13,6 +13,8 @@ *******************************************************************************/ package org.eclipse.swt.snippets; +import java.util.function.*; + /* * PDFDocument example snippet: create a shell with graphics and export to PDF * @@ -43,192 +45,21 @@ public static void main(String[] args) { canvas.setLayoutData(new BorderData(SWT.CENTER)); canvas.addListener(SWT.Paint, e -> { GC gc = e.gc; - Color red = display.getSystemColor(SWT.COLOR_RED); - Color blue = display.getSystemColor(SWT.COLOR_BLUE); - Color green = display.getSystemColor(SWT.COLOR_GREEN); - Color yellow = display.getSystemColor(SWT.COLOR_YELLOW); - Color black = display.getSystemColor(SWT.COLOR_BLACK); - Color darkGray = display.getSystemColor(SWT.COLOR_DARK_GRAY); - - int shapeSpacing = 200; - int shapeY = 20; - int shapeWidth = 100; - int shapeHeight = 80; - int textY = shapeY + shapeHeight + 5; - - int x1 = 50; - gc.setBackground(red); - gc.fillRectangle(x1, shapeY, shapeWidth, shapeHeight); - - int x2 = x1 + shapeSpacing; - gc.setForeground(blue); - gc.setLineWidth(3); - gc.drawRectangle(x2, shapeY, shapeWidth, shapeHeight); - - int x3 = x2 + shapeSpacing; - gc.setBackground(green); - gc.fillOval(x3, shapeY, shapeWidth, shapeHeight); - - int x4 = x3 + shapeSpacing; - gc.setForeground(yellow); - gc.setLineWidth(2); - gc.drawOval(x4, shapeY, shapeWidth, shapeHeight); - - gc.setForeground(black); - gc.setLineWidth(4); - gc.drawLine(20, 150, x4 + shapeWidth, 150); - - gc.setBackground(blue); - gc.fillPolygon(new int[] { 50, 170, 100, 220, 150, 170 }); - - gc.setForeground(red); - gc.setLineWidth(2); - gc.drawPolygon(new int[] { 250, 170, 300, 220, 350, 170, 300, 200 }); - - gc.setForeground(darkGray); - String[] labels = { "Filled Rectangle", "Outlined Rectangle", "Filled Oval", "Outlined Oval" }; - int[] shapeXPositions = { x1, x2, x3, x4 }; - for (int i = 0; i < labels.length; i++) { - Point textExtent = gc.stringExtent(labels[i]); - int centeredX = shapeXPositions[i] + (shapeWidth - textExtent.x) / 2; - gc.drawString(labels[i], centeredX, textY, true); - } - - int row2Y = 240; - - Path path = new Path(display); - try { - path.moveTo(x1, row2Y + 40); - path.lineTo(x1 + 30, row2Y); - path.quadTo(x1 + 50, row2Y + 20, x1 + 70, row2Y); - path.cubicTo(x1 + 90, row2Y, x1 + 100, row2Y + 60, x1 + 50, row2Y + 70); - path.close(); - gc.setBackground(display.getSystemColor(SWT.COLOR_CYAN)); - gc.fillPath(path); - gc.setForeground(black); - gc.setLineWidth(2); - gc.drawPath(path); - } finally { - path.dispose(); - } - - Pattern gradient1 = new Pattern(display, x2, row2Y, x2 + shapeWidth, row2Y + shapeHeight, - display.getSystemColor(SWT.COLOR_MAGENTA), display.getSystemColor(SWT.COLOR_WHITE)); - try { - gc.setBackgroundPattern(gradient1); - gc.fillRoundRectangle(x2, row2Y, shapeWidth, shapeHeight, 20, 20); - } finally { - gradient1.dispose(); - } - - Pattern gradient2 = new Pattern(display, x3 + shapeWidth / 2, row2Y + shapeHeight / 2, - x3 + shapeWidth / 2, row2Y + shapeHeight / 2, red, 0, yellow, 50); - try { - gc.setBackgroundPattern(gradient2); - gc.fillOval(x3, row2Y, shapeWidth, shapeHeight); - } finally { - gradient2.dispose(); - } - - Transform transform = new Transform(display); - try { - transform.translate(x4 + shapeWidth / 2, row2Y + shapeHeight / 2); - transform.rotate(45); - gc.setTransform(transform); - gc.setBackground(green); - gc.fillRectangle(-40, -40, 80, 80); - gc.setForeground(black); - gc.setLineWidth(2); - gc.drawRectangle(-40, -40, 80, 80); - gc.setTransform(null); - } finally { - transform.dispose(); - } - - gc.setForeground(darkGray); - String[] row2Labels = { "Path with Curves", "Linear Gradient", "Radial Gradient", "45° Rotation" }; - int row2TextY = row2Y + shapeHeight + 5; - for (int i = 0; i < row2Labels.length; i++) { - Point textExtent = gc.stringExtent(row2Labels[i]); - int centeredX = shapeXPositions[i] + (shapeWidth - textExtent.x) / 2; - gc.drawString(row2Labels[i], centeredX, row2TextY, true); - } - - int row3Y = 360; - - gc.setAlpha(128); - gc.setBackground(blue); - gc.fillOval(x1, row3Y, 60, 60); - gc.setBackground(red); - gc.fillOval(x1 + 40, row3Y + 20, 60, 60); - gc.setAlpha(255); - - gc.setLineStyle(SWT.LINE_DASH); - gc.setForeground(blue); - gc.setLineWidth(3); - gc.drawRoundRectangle(x2, row3Y, shapeWidth, shapeHeight, 15, 15); - gc.setLineStyle(SWT.LINE_DOT); - gc.setForeground(red); - gc.drawRectangle(x2 + 10, row3Y + 10, shapeWidth - 20, shapeHeight - 20); - gc.setLineStyle(SWT.LINE_SOLID); - - gc.setAntialias(SWT.ON); - gc.setForeground(green); - gc.setLineWidth(3); - for (int i = 0; i < 5; i++) { - int offset = i * 20; - gc.drawLine(x3 + offset, row3Y, x3 + shapeWidth, row3Y + shapeHeight - offset); - } - gc.setAntialias(SWT.OFF); - - Font largeFont = new Font(display, "Arial", 24, SWT.BOLD); - try { - gc.setFont(largeFont); - gc.setForeground(display.getSystemColor(SWT.COLOR_DARK_BLUE)); - String text = "ABC"; - Point extent = gc.stringExtent(text); - gc.drawString(text, x4 + (shapeWidth - extent.x) / 2, row3Y + (shapeHeight - extent.y) / 2, true); - } finally { - largeFont.dispose(); - } - - gc.setForeground(darkGray); - String[] row3Labels = { "Alpha Blending", "Line Styles", "Antialiasing", "Custom Font" }; - int row3TextY = row3Y + shapeHeight + 5; - for (int i = 0; i < row3Labels.length; i++) { - Point textExtent = gc.stringExtent(row3Labels[i]); - int centeredX = shapeXPositions[i] + (shapeWidth - textExtent.x) / 2; - gc.drawString(row3Labels[i], centeredX, row3TextY, true); - } + printContent(display, gc); }); - Button exportButton = new Button(shell, SWT.PUSH); - exportButton.setText("Export to PDF"); - exportButton.setLayoutData(new BorderData(SWT.BOTTOM)); - exportButton.addListener(SWT.Selection, e -> { - try { - String tempDir = System.getProperty("java.io.tmpdir"); - String pdfPath = tempDir + "/swt_graphics_demo.pdf"; - - Rectangle clientArea = shell.getClientArea(); - PDFDocument pdf = new PDFDocument(pdfPath, clientArea.width, clientArea.height); - GC gc = new GC(pdf); - shell.print(gc); - gc.drawString("Exported to PDF...", 0, 0, true); - gc.dispose(); - pdf.dispose(); - System.out.println("PDF has been exported to:\n" + pdfPath + "\n\nOpening..."); - Program.launch(pdfPath); - - } catch (Throwable ex) { - MessageBox errorBox = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK); - errorBox.setText("Error"); - errorBox.setMessage("Failed to export PDF: " + ex.getMessage()); - errorBox.open(); - ex.printStackTrace(); - } + Button exportPrintButton = new Button(shell, SWT.PUSH); + exportPrintButton.setText("Shell#print to PDF"); + exportPrintButton.setLayoutData(new BorderData(SWT.BOTTOM)); + exportPrintButton.addListener(SWT.Selection, e -> { + generatePdf(display, shell, shell::print); + }); + Button exportRenderButton = new Button(shell, SWT.PUSH); + exportRenderButton.setText("Render with GC to PDF"); + exportRenderButton.setLayoutData(new BorderData(SWT.BOTTOM)); + exportRenderButton.addListener(SWT.Selection, e -> { + generatePdf(display, shell, gc -> printContent(display, gc)); }); - shell.setSize(800, 600); shell.open(); while (!shell.isDisposed()) { @@ -237,4 +68,190 @@ public static void main(String[] args) { } display.dispose(); } + + private static void generatePdf(Display display, Shell shell, Consumer printFunction) { + try { + String tempDir = System.getProperty("java.io.tmpdir"); + String pdfPath = tempDir + "/swt_graphics_demo.pdf"; + + Rectangle clientArea = shell.getClientArea(); + PDFDocument pdf = new PDFDocument(pdfPath, clientArea.width, clientArea.height); + GC gc = new GC(pdf); + + printFunction.accept(gc); + + gc.drawString("Exported to PDF...", 0, 0, true); + gc.dispose(); + pdf.dispose(); + System.out.println("PDF has been exported to:\n" + pdfPath + "\n\nOpening..."); + Program.launch(pdfPath); + + } catch (Throwable ex) { + MessageBox errorBox = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK); + errorBox.setText("Error"); + errorBox.setMessage("Failed to export PDF: " + ex.getMessage()); + errorBox.open(); + ex.printStackTrace(); + } + } + + private static void printContent(Display display, GC gc) { + Color red = display.getSystemColor(SWT.COLOR_RED); + Color blue = display.getSystemColor(SWT.COLOR_BLUE); + Color green = display.getSystemColor(SWT.COLOR_GREEN); + Color yellow = display.getSystemColor(SWT.COLOR_YELLOW); + Color black = display.getSystemColor(SWT.COLOR_BLACK); + Color darkGray = display.getSystemColor(SWT.COLOR_DARK_GRAY); + + int shapeSpacing = 200; + int shapeY = 20; + int shapeWidth = 100; + int shapeHeight = 80; + int textY = shapeY + shapeHeight + 5; + + int x1 = 50; + gc.setBackground(red); + gc.fillRectangle(x1, shapeY, shapeWidth, shapeHeight); + + int x2 = x1 + shapeSpacing; + gc.setForeground(blue); + gc.setLineWidth(3); + gc.drawRectangle(x2, shapeY, shapeWidth, shapeHeight); + + int x3 = x2 + shapeSpacing; + gc.setBackground(green); + gc.fillOval(x3, shapeY, shapeWidth, shapeHeight); + + int x4 = x3 + shapeSpacing; + gc.setForeground(yellow); + gc.setLineWidth(2); + gc.drawOval(x4, shapeY, shapeWidth, shapeHeight); + + gc.setForeground(black); + gc.setLineWidth(4); + gc.drawLine(20, 150, x4 + shapeWidth, 150); + + gc.setBackground(blue); + gc.fillPolygon(new int[] { 50, 170, 100, 220, 150, 170 }); + + gc.setForeground(red); + gc.setLineWidth(2); + gc.drawPolygon(new int[] { 250, 170, 300, 220, 350, 170, 300, 200 }); + + gc.setForeground(darkGray); + String[] labels = { "Filled Rectangle", "Outlined Rectangle", "Filled Oval", "Outlined Oval" }; + int[] shapeXPositions = { x1, x2, x3, x4 }; + for (int i = 0; i < labels.length; i++) { + Point textExtent = gc.stringExtent(labels[i]); + int centeredX = shapeXPositions[i] + (shapeWidth - textExtent.x) / 2; + gc.drawString(labels[i], centeredX, textY, true); + } + + int row2Y = 240; + + Path path = new Path(display); + try { + path.moveTo(x1, row2Y + 40); + path.lineTo(x1 + 30, row2Y); + path.quadTo(x1 + 50, row2Y + 20, x1 + 70, row2Y); + path.cubicTo(x1 + 90, row2Y, x1 + 100, row2Y + 60, x1 + 50, row2Y + 70); + path.close(); + gc.setBackground(display.getSystemColor(SWT.COLOR_CYAN)); + gc.fillPath(path); + gc.setForeground(black); + gc.setLineWidth(2); + gc.drawPath(path); + } finally { + path.dispose(); + } + + Pattern gradient1 = new Pattern(display, x2, row2Y, x2 + shapeWidth, row2Y + shapeHeight, + display.getSystemColor(SWT.COLOR_MAGENTA), display.getSystemColor(SWT.COLOR_WHITE)); + try { + gc.setBackgroundPattern(gradient1); + gc.fillRoundRectangle(x2, row2Y, shapeWidth, shapeHeight, 20, 20); + } finally { + gradient1.dispose(); + } + + Pattern gradient2 = new Pattern(display, x3 + shapeWidth / 2, row2Y + shapeHeight / 2, + x3 + shapeWidth / 2, row2Y + shapeHeight / 2, red, 0, yellow, 50); + try { + gc.setBackgroundPattern(gradient2); + gc.fillOval(x3, row2Y, shapeWidth, shapeHeight); + } finally { + gradient2.dispose(); + } + + Transform transform = new Transform(display); + try { + transform.translate(x4 + shapeWidth / 2, row2Y + shapeHeight / 2); + transform.rotate(45); + gc.setTransform(transform); + gc.setBackground(green); + gc.fillRectangle(-40, -40, 80, 80); + gc.setForeground(black); + gc.setLineWidth(2); + gc.drawRectangle(-40, -40, 80, 80); + gc.setTransform(null); + } finally { + transform.dispose(); + } + + gc.setForeground(darkGray); + String[] row2Labels = { "Path with Curves", "Linear Gradient", "Radial Gradient", "45° Rotation" }; + int row2TextY = row2Y + shapeHeight + 5; + for (int i = 0; i < row2Labels.length; i++) { + Point textExtent = gc.stringExtent(row2Labels[i]); + int centeredX = shapeXPositions[i] + (shapeWidth - textExtent.x) / 2; + gc.drawString(row2Labels[i], centeredX, row2TextY, true); + } + + int row3Y = 360; + + gc.setAlpha(128); + gc.setBackground(blue); + gc.fillOval(x1, row3Y, 60, 60); + gc.setBackground(red); + gc.fillOval(x1 + 40, row3Y + 20, 60, 60); + gc.setAlpha(255); + + gc.setLineStyle(SWT.LINE_DASH); + gc.setForeground(blue); + gc.setLineWidth(3); + gc.drawRoundRectangle(x2, row3Y, shapeWidth, shapeHeight, 15, 15); + gc.setLineStyle(SWT.LINE_DOT); + gc.setForeground(red); + gc.drawRectangle(x2 + 10, row3Y + 10, shapeWidth - 20, shapeHeight - 20); + gc.setLineStyle(SWT.LINE_SOLID); + + gc.setAntialias(SWT.ON); + gc.setForeground(green); + gc.setLineWidth(3); + for (int i = 0; i < 5; i++) { + int offset = i * 20; + gc.drawLine(x3 + offset, row3Y, x3 + shapeWidth, row3Y + shapeHeight - offset); + } + gc.setAntialias(SWT.OFF); + + Font largeFont = new Font(display, "Arial", 24, SWT.BOLD); + try { + gc.setFont(largeFont); + gc.setForeground(display.getSystemColor(SWT.COLOR_DARK_BLUE)); + String text = "ABC"; + Point extent = gc.stringExtent(text); + gc.drawString(text, x4 + (shapeWidth - extent.x) / 2, row3Y + (shapeHeight - extent.y) / 2, true); + } finally { + largeFont.dispose(); + } + + gc.setForeground(darkGray); + String[] row3Labels = { "Alpha Blending", "Line Styles", "Antialiasing", "Custom Font" }; + int row3TextY = row3Y + shapeHeight + 5; + for (int i = 0; i < row3Labels.length; i++) { + Point textExtent = gc.stringExtent(row3Labels[i]); + int centeredX = shapeXPositions[i] + (shapeWidth - textExtent.x) / 2; + gc.drawString(row3Labels[i], centeredX, row3TextY, true); + } + } }