Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
cairo-ps-out.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * A quick hack to use the Cairo renderer to write out a file. This
4 * then makes 'save as...' PS.
5 *
6 * Authors:
7 * Ted Gould <ted@gould.cx>
8 * Ulf Erikson <ulferikson@users.sf.net>
9 * Adib Taraben <theAdib@gmail.com>
10 * Jon A. Cruz <jon@joncruz.org>
11 * Abhishek Sharma
12 *
13 * Copyright (C) 2004-2006 Authors
14 *
15 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
16 */
17
18#include <cairo.h>
19#ifdef CAIRO_HAS_PS_SURFACE
20
21#include "cairo-ps.h"
22#include "cairo-ps-out.h"
24#include "cairo-renderer.h"
25#include "latex-text-renderer.h"
26#include "path-chemistry.h"
27#include <print.h>
28#include "extension/system.h"
29#include "extension/print.h"
30#include "extension/db.h"
31#include "extension/output.h"
32#include "display/drawing.h"
33
34#include "display/curve.h"
35
36#include "object/sp-item.h"
37#include "object/sp-root.h"
38
39#include "io/sys.h"
40#include "document.h"
41
42namespace Inkscape {
43namespace Extension {
44namespace Internal {
45
47{
48 if (nullptr == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS)) {
49 return FALSE;
50 } else {
51 return TRUE;
52 }
53}
54
56{
57 if (nullptr == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_EPS)) {
58 return FALSE;
59 } else {
60 return TRUE;
61 }
62}
63
64static bool
65ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, bool texttopath, bool omittext,
66 bool filtertobitmap, int resolution, bool eps = false)
67{
68 if (texttopath) {
69 assert(!omittext);
70 // Cairo's text-to-path method has numerical precision and font matching
71 // issues (https://gitlab.com/inkscape/inkscape/-/issues/1979).
72 // We get better results by using Inkscape's Object-to-Path method.
74 }
75
76 doc->ensureUpToDate();
77
78 SPRoot *root = doc->getRoot();
79 if (!root) {
80 return false;
81 }
82
83 Inkscape::Drawing drawing;
84 unsigned dkey = SPItem::display_key_new(1);
85 root->invoke_show(drawing, dkey, SP_ITEM_SHOW_DISPLAY);
86
87 /* Create renderer and context */
88 CairoRenderer renderer;
89 CairoRenderContext ctx = renderer.createContext();
90 ctx.setPSLevel(level);
91 ctx.setEPS(eps);
92 ctx.setTextToPath(texttopath);
93 ctx.setOmitText(omittext);
94 ctx.setFilterToBitmap(filtertobitmap);
95 ctx.setBitmapResolution(resolution);
96
97 bool ret = ctx.setPsTarget(filename);
98 if (ret) {
99 /* Render document */
100 ret = renderer.setupDocument(&ctx, doc, root);
101 if (ret) {
102 /* Render multiple pages */
103 ret = renderer.renderPages(&ctx, doc, false);
104 ctx.finish();
105 }
106 }
107
108 root->invoke_hide(dkey);
109 return ret;
110}
111
112
119void
121{
123 unsigned int ret;
124
125 ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS);
126 if (ext == nullptr)
127 return;
128
129 int level = CAIRO_PS_LEVEL_2;
130 try {
131 const gchar *new_level = mod->get_param_optiongroup("PSlevel");
132 if((new_level != nullptr) && (g_ascii_strcasecmp("PS3", new_level) == 0)) {
133 level = CAIRO_PS_LEVEL_3;
134 }
135 } catch(...) {}
136
137 bool new_textToPath = FALSE;
138 try {
139 new_textToPath = (strcmp(mod->get_param_optiongroup("textToPath"), "paths") == 0);
140 } catch(...) {}
141
142 bool new_textToLaTeX = FALSE;
143 try {
144 new_textToLaTeX = (strcmp(mod->get_param_optiongroup("textToPath"), "LaTeX") == 0);
145 }
146 catch(...) {
147 g_warning("Parameter <textToLaTeX> might not exist");
148 }
149
150 bool new_blurToBitmap = FALSE;
151 try {
152 new_blurToBitmap = mod->get_param_bool("blurToBitmap");
153 } catch(...) {}
154
155 int new_bitmapResolution = 72;
156 try {
157 new_bitmapResolution = mod->get_param_int("resolution");
158 } catch(...) {}
159
160 // Create PS
161 {
162 gchar * final_name;
163 final_name = g_strdup_printf("> %s", filename);
164 ret = ps_print_document_to_file(doc, final_name, level, new_textToPath,
165 new_textToLaTeX, new_blurToBitmap,
166 new_bitmapResolution);
167 g_free(final_name);
168
169 if (!ret)
171 }
172
173 // Create LaTeX file (if requested)
174 if (new_textToLaTeX) {
175 ret = latex_render_document_text_to_file(doc, filename, false);
176
177 if (!ret)
179 }
180}
181
182
189void
191{
193 unsigned int ret;
194
195 ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_EPS);
196 if (ext == nullptr)
197 return;
198
199 int level = CAIRO_PS_LEVEL_2;
200 try {
201 const gchar *new_level = mod->get_param_optiongroup("PSlevel");
202 if((new_level != nullptr) && (g_ascii_strcasecmp("PS3", new_level) == 0)) {
203 level = CAIRO_PS_LEVEL_3;
204 }
205 } catch(...) {}
206
207 bool new_textToPath = FALSE;
208 try {
209 new_textToPath = (strcmp(mod->get_param_optiongroup("textToPath"), "paths") == 0);
210 } catch(...) {}
211
212 bool new_textToLaTeX = FALSE;
213 try {
214 new_textToLaTeX = (strcmp(mod->get_param_optiongroup("textToPath"), "LaTeX") == 0);
215 }
216 catch(...) {
217 g_warning("Parameter <textToLaTeX> might not exist");
218 }
219
220 bool new_blurToBitmap = FALSE;
221 try {
222 new_blurToBitmap = mod->get_param_bool("blurToBitmap");
223 } catch(...) {}
224
225 int new_bitmapResolution = 72;
226 try {
227 new_bitmapResolution = mod->get_param_int("resolution");
228 } catch(...) {}
229
230 // Create EPS
231 {
232 gchar * final_name;
233 final_name = g_strdup_printf("> %s", filename);
234 ret = ps_print_document_to_file(doc, final_name, level, new_textToPath,
235 new_textToLaTeX, new_blurToBitmap,
236 new_bitmapResolution, true);
237 g_free(final_name);
238
239 if (!ret)
241 }
242
243 // Create LaTeX file (if requested)
244 if (new_textToLaTeX) {
245 ret = latex_render_document_text_to_file(doc, filename, false);
246
247 if (!ret)
249 }
250}
251
252
253bool
255{
256 return ext->get_param_bool("textToPath");
257}
258
259bool
261{
262 return ext->get_param_bool("textToPath");
263}
264
265#include "clear-n_.h"
266
274void
276{
277 // clang-format off
279 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
280 "<name>" N_("PostScript") "</name>\n"
281 "<id>" SP_MODULE_KEY_PRINT_CAIRO_PS "</id>\n"
282 "<param name=\"PSlevel\" gui-text=\"" N_("Restrict to PS level:") "\" type=\"optiongroup\" appearance=\"combo\" >\n"
283 "<option value='PS3'>" N_("PostScript level 3") "</option>\n"
284 "<option value='PS2'>" N_("PostScript level 2") "</option>\n"
285 "</param>\n"
286 "<param name=\"textToPath\" gui-text=\"" N_("Text output options:") "\" type=\"optiongroup\" appearance=\"radio\">\n"
287 "<option value=\"embed\">" N_("Embed fonts") "</option>\n"
288 "<option value=\"paths\">" N_("Convert text to paths") "</option>\n"
289 "<option value=\"LaTeX\">" N_("Omit text in PDF and create LaTeX file") "</option>\n"
290 "</param>\n"
291 "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"bool\">true</param>\n"
292 "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">96</param>\n"
293 "<spacer/>"
294 "<hbox indent=\"1\"><image>info-outline</image><spacer/><vbox><spacer/>"
295 "<label>" N_("When exporting from the Export dialog, you can choose objects to export. 'Save a copy' / 'Save as' will export all pages.") "</label>"
296 "<spacer size=\"5\" />"
297 "<label>" N_("The page bleed can be set with the Page tool.") "</label>"
298 "</vbox></hbox>"
299 "<output>\n"
300 "<extension>.ps</extension>\n"
301 "<mimetype>image/x-postscript</mimetype>\n"
302 "<filetypename>" N_("PostScript (*.ps)") "</filetypename>\n"
303 "<filetypetooltip>" N_("PostScript File") "</filetypetooltip>\n"
304 "</output>\n"
305 "</inkscape-extension>", std::make_unique<CairoPsOutput>());
306 // clang-format on
307
308 return;
309}
310
318void
320{
321 // clang-format off
323 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
324 "<name>" N_("Encapsulated PostScript") "</name>\n"
325 "<id>" SP_MODULE_KEY_PRINT_CAIRO_EPS "</id>\n"
326 "<param name=\"PSlevel\" gui-text=\"" N_("Restrict to PS level:") "\" type=\"optiongroup\" appearance=\"combo\" >\n"
327 "<option value='PS3'>" N_("PostScript level 3") "</option>\n"
328 "<option value='PS2'>" N_("PostScript level 2") "</option>\n"
329 "</param>\n"
330 "<param name=\"textToPath\" gui-text=\"" N_("Text output options:") "\" type=\"optiongroup\" appearance=\"radio\">\n"
331 "<option value=\"embed\">" N_("Embed fonts") "</option>\n"
332 "<option value=\"paths\">" N_("Convert text to paths") "</option>\n"
333 "<option value=\"LaTeX\">" N_("Omit text in PDF and create LaTeX file") "</option>\n"
334 "</param>\n"
335 "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"bool\">true</param>\n"
336 "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">96</param>\n"
337 "<spacer/>"
338 "<hbox indent=\"1\"><image>info-outline</image><spacer/><vbox><spacer/>"
339 "<label>" N_("When exporting from the Export dialog, you can choose objects to export. 'Save a copy' / 'Save as' will export all pages.") "</label>"
340 "<spacer size=\"5\" />"
341 "<label>" N_("The page bleed can be set with the Page tool.") "</label>"
342 "</vbox></hbox>"
343 "<output>\n"
344 "<extension>.eps</extension>\n"
345 "<mimetype>image/x-e-postscript</mimetype>\n"
346 "<filetypename>" N_("Encapsulated PostScript (*.eps)") "</filetypename>\n"
347 "<filetypetooltip>" N_("Encapsulated PostScript File") "</filetypetooltip>\n"
348 "</output>\n"
349 "</inkscape-extension>", std::make_unique<CairoEpsOutput>());
350 // clang-format on
351
352 return;
353}
354
355} } } /* namespace Inkscape, Extension, Implementation */
356
357#endif /* HAVE_CAIRO_PDF */
Declaration of CairoRenderContext, a class used for rendering with Cairo.
Declaration of CairoRenderer, a class used for rendering via a CairoRenderContext.
Extension * get(const gchar *key) const
This function looks up a Inkscape::Extension::Extension by using its unique id. It then returns a ref...
Definition db.cpp:101
The object that is the basis for the Extension system.
Definition extension.h:133
bool get_param_bool(char const *name) const
Gets a parameter identified by name with the bool placed in value.
bool check(Inkscape::Extension::Extension *module) override
Verify any dependencies.
static void init()
A function allocate a copy of this function.
bool textToPath(Inkscape::Extension::Print *ext) override
Tell the printing engine whether text should be text or path.
void save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *uri) override
This function calls the output module with the filename.
bool check(Inkscape::Extension::Extension *module) override
Verify any dependencies.
static void init()
A function allocate a copy of this function.
bool textToPath(Inkscape::Extension::Print *ext) override
Tell the printing engine whether text should be text or path.
void save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename) override
This function calls the output module with the filename.
bool renderPages(CairoRenderContext *ctx, SPDocument *doc, bool stretch_to_fit)
Handle multiple pages, pushing each out to cairo as needed using renderItem()
bool setupDocument(CairoRenderContext *ctx, SPDocument *doc, SPItem const *base=nullptr)
Initializes the CairoRenderContext according to the specified SPDocument.
Generic failure for an undescribed reason.
Definition output.h:34
Typed SVG document implementation.
Definition document.h:101
SPRoot * getRoot()
Returns our SPRoot.
Definition document.h:200
int ensureUpToDate(unsigned int object_modified_tag=0)
Repeatedly works on getting the document updated, since sometimes it takes more than one pass to get ...
static unsigned int display_key_new(unsigned numkeys)
Allocates unique integer keys.
Definition sp-item.cpp:1262
<svg> element
Definition sp-root.h:33
A way to clear the N_ macro, which is defined as an inline function.
RootCluster root
SVG drawing for display.
Declaration of LaTeXTextRenderer, used for rendering the accompanying LaTeX file when exporting to PD...
bool latex_render_document_text_to_file(SPDocument *doc, gchar const *filename, bool pdflatex)
This method is called by the PDF, EPS and PS output extensions.
static bool ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, bool texttopath, bool omittext, bool filtertobitmap, int resolution, bool eps=false)
DB db
This is the actual database object.
Definition db.cpp:32
void build_from_mem(gchar const *buffer, std::unique_ptr< Implementation::Implementation > in_imp)
Create a module from a buffer holding an XML description.
Definition system.cpp:459
Helper class to stream background task notifications as a series of messages.
void convert_text_to_curves(SPDocument *)
Convert all text in the document to path, in-place.
Some things pertinent to all visible shapes: SPItem, SPItemView, SPItemCtx.
SPRoot: SVG <svg> implementation.