Skip to content

Commit 6259036

Browse files
jjlauermagreenblatt
authored andcommitted
Add PrintToPDF support (issue chromiumembedded#255)
1 parent e9a0b2c commit 6259036

16 files changed

Lines changed: 422 additions & 0 deletions

java/org/cef/browser/CefBrowser.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
import java.awt.Point;
99
import java.util.Vector;
1010

11+
import org.cef.callback.CefPdfPrintCallback;
1112
import org.cef.callback.CefRunFileDialogCallback;
1213
import org.cef.callback.CefStringVisitor;
1314
import org.cef.handler.CefDialogHandler.FileDialogMode;
1415
import org.cef.handler.CefRenderHandler;
1516
import org.cef.handler.CefWindowHandler;
17+
import org.cef.misc.CefPdfPrintSettings;
1618
import org.cef.network.CefRequest;
1719

1820
/**
@@ -241,6 +243,17 @@ public void runFileDialog(FileDialogMode mode, String title, String defaultFileP
241243
* Print the current browser contents.
242244
*/
243245
public void print();
246+
247+
/**
248+
* Print the current browser contents to a PDF.
249+
*
250+
* @param path The path of the file to write to (will be overwritten if it
251+
* already exists). Cannot be null.
252+
* @param settings The pdf print settings to use. If null then defaults
253+
* will be used.
254+
* @param callback Called when the pdf print job has completed.
255+
*/
256+
public void printToPDF(String path, CefPdfPrintSettings settings, CefPdfPrintCallback callback);
244257

245258
/**
246259
* Search for some kind of text on the page.

java/org/cef/browser/CefBrowser_N.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414

1515
import org.cef.callback.CefDragData;
1616
import org.cef.callback.CefNativeAdapter;
17+
import org.cef.callback.CefPdfPrintCallback;
1718
import org.cef.callback.CefRunFileDialogCallback;
1819
import org.cef.callback.CefStringVisitor;
1920
import org.cef.handler.CefClientHandler;
2021
import org.cef.handler.CefRenderHandler;
2122
import org.cef.handler.CefDialogHandler.FileDialogMode;
2223
import org.cef.handler.CefWindowHandler;
24+
import org.cef.misc.CefPdfPrintSettings;
2325
import org.cef.network.CefRequest;
2426

2527
/**
@@ -339,6 +341,18 @@ public void print() {
339341
ule.printStackTrace();
340342
}
341343
}
344+
345+
@Override
346+
public void printToPDF(String path, CefPdfPrintSettings settings, CefPdfPrintCallback callback) {
347+
if (path == null || path.isEmpty()) {
348+
throw new IllegalArgumentException("path was null or empty");
349+
}
350+
try {
351+
N_PrintToPDF(path, settings, callback);
352+
} catch (UnsatisfiedLinkError ule) {
353+
ule.printStackTrace();
354+
}
355+
}
342356

343357
@Override
344358
public void find(int identifier, String searchText, boolean forward, boolean matchCase,
@@ -572,6 +586,7 @@ private final native void N_RunFileDialog(FileDialogMode mode, String title,
572586
CefRunFileDialogCallback callback);
573587
private final native void N_StartDownload(String url);
574588
private final native void N_Print();
589+
private final native void N_PrintToPDF(String path, CefPdfPrintSettings settings, CefPdfPrintCallback callback);
575590
private final native void N_Find(int identifier, String searchText, boolean forward,
576591
boolean matchCase, boolean findNext);
577592
private final native void N_StopFinding(boolean clearSelection);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
2+
// reserved. Use of this source code is governed by a BSD-style license that
3+
// can be found in the LICENSE file.
4+
5+
package org.cef.callback;
6+
7+
/**
8+
* Callback interface for CefBrowser.PrintToPDF(). The methods of this class
9+
* will be called on the browser process UI thread.
10+
*/
11+
public interface CefPdfPrintCallback {
12+
13+
/**
14+
* Method that will be executed when the PDF printing has completed. |path|
15+
* is the output path. |ok| will be true if the printing completed
16+
* successfully or false otherwise.
17+
* @param path The path of the PDF file that was written.
18+
* @param ok True if printing completed or false otherwise.
19+
*/
20+
public abstract void onPdfPrintFinished(String path, boolean ok);
21+
22+
}

java/org/cef/handler/CefPrintHandler.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
package org.cef.handler;
66

7+
import java.awt.Dimension;
78
import org.cef.browser.CefBrowser;
89
import org.cef.callback.CefNative;
910
import org.cef.callback.CefPrintDialogCallback;
@@ -49,4 +50,14 @@ public interface CefPrintHandler extends CefNative {
4950
* Reset client state related to printing.
5051
*/
5152
void onPrintReset();
53+
54+
/**
55+
* Called when PrintToPDF is requested for a browser. Returns the page size
56+
* (as measured in microns) to use.
57+
* @param deviceUnitsPerInch The DPI of the print. Use this to calculate
58+
* the page size to use.
59+
* @return The page size
60+
*/
61+
Dimension getPdfPaperSize(int deviceUnitsPerInch);
62+
5263
}

java/org/cef/handler/CefPrintHandlerAdapter.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
package org.cef.handler;
66

7+
import java.awt.Dimension;
78
import org.cef.browser.CefBrowser;
89
import org.cef.callback.CefNativeAdapter;
910
import org.cef.callback.CefPrintDialogCallback;
@@ -43,4 +44,14 @@ public boolean onPrintJob(
4344
public void onPrintReset() {
4445
// The default implementation does nothing
4546
}
47+
48+
@Override
49+
public Dimension getPdfPaperSize(int deviceUnitsPerInch) {
50+
// default implementation is A4 letter size
51+
// @ 300 DPI, A4 is 2480 x 3508
52+
// @ 150 DPI, A4 is 1240 x 1754
53+
int adjustedWidth = (int)(((double)deviceUnitsPerInch/300d)*2480d);
54+
int adjustedHeight = (int)(((double)deviceUnitsPerInch/300d)*3508d);
55+
return new Dimension(adjustedWidth, adjustedHeight);
56+
}
4657
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
2+
// reserved. Use of this source code is governed by a BSD-style license that
3+
// can be found in the LICENSE file.
4+
5+
package org.cef.misc;
6+
7+
/**
8+
* PDF print settings for browser.printToPDF()
9+
*/
10+
public class CefPdfPrintSettings {
11+
12+
public enum MarginType {
13+
// Default margins.
14+
DEFAULT,
15+
16+
// No margins
17+
NONE,
18+
19+
// Minimum margins.
20+
MINIMUM,
21+
22+
// Custom margins using the values from CefPdfPrintSettings
23+
CUSTOM
24+
}
25+
26+
/**
27+
* Set to true to print headers and footers or false to not print
28+
* headers and footers.
29+
*/
30+
public boolean header_footer_enabled;
31+
32+
/**
33+
* Page title to display in the header. Only used if header_footer_enabled
34+
* is set to true.
35+
*/
36+
public String header_footer_title;
37+
38+
/**
39+
* URL to display in the footer. Only used if header_footer_enabled is set
40+
* to true.
41+
*/
42+
public String header_footer_url;
43+
44+
/**
45+
* Set to true for landscape mode or false for portrait mode.
46+
*/
47+
public boolean landscape;
48+
49+
/**
50+
* Set to true to print background graphics or false to not print
51+
* background graphics.
52+
*/
53+
public boolean backgrounds_enabled;
54+
55+
/**
56+
* Output page size in microns (1 millimeter = 1000 microns). If either of these
57+
* values is less than or equal to zero then the default paper size will be
58+
* used as returned by the print_handler. A4 is 210 × 297 mm which would
59+
* be 210000 x 297000 microns. US Letter is 215.9 × 279.4 mm which would
60+
* be 215900 x 279400 microns.
61+
*/
62+
public int page_width;
63+
public int page_height;
64+
65+
/**
66+
* Set to true to print the selection only or false to print all.
67+
*/
68+
public boolean selection_only;
69+
70+
/**
71+
* The percentage to scale the PDF by before printing (e.g. 50 is 50%).
72+
* If this value is less than or equal to zero the default value of 100
73+
* will be used.
74+
*/
75+
public int scale_factor;
76+
77+
/**
78+
* Margins in millimeters. Only used if |margin_type| is set to
79+
* PDF_PRINT_MARGIN_CUSTOM.
80+
*/
81+
public double margin_top;
82+
public double margin_right;
83+
public double margin_bottom;
84+
public double margin_left;
85+
86+
/**
87+
* Margin type.
88+
*/
89+
public MarginType margin_type;
90+
91+
public CefPdfPrintSettings() {}
92+
93+
@Override
94+
public CefPdfPrintSettings clone() {
95+
CefPdfPrintSettings tmp = new CefPdfPrintSettings();
96+
tmp.header_footer_enabled = this.header_footer_enabled;
97+
tmp.header_footer_title = this.header_footer_title;
98+
tmp.header_footer_url = this.header_footer_url;
99+
tmp.landscape = this.landscape;
100+
tmp.backgrounds_enabled = this.backgrounds_enabled;
101+
tmp.page_width = this.page_width;
102+
tmp.page_height = this.page_height;
103+
tmp.selection_only = this.selection_only;
104+
tmp.scale_factor = this.scale_factor;
105+
tmp.margin_top = this.margin_top;
106+
tmp.margin_right = this.margin_right;
107+
tmp.margin_bottom = this.margin_bottom;
108+
tmp.margin_left = this.margin_left;
109+
tmp.margin_type = this.margin_type;
110+
return tmp;
111+
}
112+
}

java/tests/detailed/ui/MenuBar.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
import javax.swing.JMenuBar;
2323
import javax.swing.JMenuItem;
2424
import javax.swing.JOptionPane;
25+
import javax.swing.SwingUtilities;
2526

2627
import org.cef.browser.CefBrowser;
28+
import org.cef.callback.CefPdfPrintCallback;
2729
import org.cef.callback.CefRunFileDialogCallback;
2830
import org.cef.callback.CefStringVisitor;
2931
import org.cef.handler.CefDialogHandler.FileDialogMode;
32+
import org.cef.misc.CefPdfPrintSettings;
3033
import org.cef.network.CefCookieManager;
3134
import org.cef.network.CefRequest;
3235

@@ -123,6 +126,41 @@ public void actionPerformed(ActionEvent e) {
123126
}
124127
});
125128
fileMenu.add(printItem);
129+
130+
JMenuItem printToPdfItem = new JMenuItem("Print to PDF");
131+
printToPdfItem.addActionListener(new ActionListener() {
132+
@Override
133+
public void actionPerformed(ActionEvent e) {
134+
JFileChooser fc = new JFileChooser();
135+
fc.showSaveDialog(owner_);
136+
File selectedFile = fc.getSelectedFile();
137+
if (selectedFile != null) {
138+
CefPdfPrintSettings pdfSettings = new CefPdfPrintSettings();
139+
pdfSettings.header_footer_enabled = true;
140+
// A4 page size
141+
pdfSettings.page_width = 210000;
142+
pdfSettings.page_height = 297000;
143+
browser.printToPDF(selectedFile.getAbsolutePath(), pdfSettings, new CefPdfPrintCallback() {
144+
@Override
145+
public void onPdfPrintFinished(String path, boolean ok) {
146+
SwingUtilities.invokeLater(new Runnable() {
147+
@Override
148+
public void run() {
149+
if (ok) {
150+
JOptionPane.showMessageDialog(
151+
owner_, "PDF saved to " + path, "Success", JOptionPane.INFORMATION_MESSAGE);
152+
} else {
153+
JOptionPane.showMessageDialog(
154+
owner_, "PDF failed", "Failed", JOptionPane.ERROR_MESSAGE);
155+
}
156+
}
157+
});
158+
}
159+
});
160+
}
161+
}
162+
});
163+
fileMenu.add(printToPdfItem);
126164

127165
JMenuItem searchItem = new JMenuItem("Search...");
128166
searchItem.addActionListener(new ActionListener() {

native/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ set(JCEF_SRCS
110110
load_handler.h
111111
message_router_handler.cpp
112112
message_router_handler.h
113+
pdf_print_callback.cpp
114+
pdf_print_callback.h
113115
print_handler.cpp
114116
print_handler.h
115117
render_handler.cpp

native/CefBrowser_N.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "critical_wait.h"
1414
#include "jni_util.h"
1515
#include "life_span_handler.h"
16+
#include "pdf_print_callback.h"
1617
#include "render_handler.h"
1718
#include "run_file_dialog_callback.h"
1819
#include "string_visitor.h"
@@ -1311,6 +1312,22 @@ Java_org_cef_browser_CefBrowser_1N_N_1Print(JNIEnv* env, jobject obj) {
13111312
browser->GetHost()->Print();
13121313
}
13131314

1315+
JNIEXPORT void JNICALL
1316+
Java_org_cef_browser_CefBrowser_1N_N_1PrintToPDF(JNIEnv* env,
1317+
jobject obj,
1318+
jstring jpath,
1319+
jobject jsettings,
1320+
jobject jcallback) {
1321+
CefRefPtr<CefBrowser> browser = JNI_GET_BROWSER_OR_RETURN(env, obj);
1322+
1323+
CefPdfPrintSettings settings = GetJNIPdfPrintSettings(env, jsettings);
1324+
1325+
browser->GetHost()->PrintToPDF(
1326+
GetJNIString(env, jpath),
1327+
settings,
1328+
new PdfPrintCallback(env, jcallback));
1329+
}
1330+
13141331
JNIEXPORT void JNICALL
13151332
Java_org_cef_browser_CefBrowser_1N_N_1Find(JNIEnv* env,
13161333
jobject obj,

native/CefBrowser_N.h

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)