Inkscape
Vector Graphics Editor
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages Concepts
metafile-inout.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
/*
5 * Authors:
6 * David Mathog
7 *
8 * Copyright (C) 2013 Authors
9 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
10 */
11
12#include <cstring>
13#include <fstream>
14#include <glib.h>
15#include <glibmm/miscutils.h>
16
17#include "display/curve.h"
18#include "extension/internal/metafile-inout.h" // picks up PNG
19#include "extension/print.h"
20#include "path-prefix.h"
21#include "document.h"
22#include "util/units.h"
23#include "ui/shape-editor.h"
24#include "document-undo.h"
25#include "inkscape.h"
26#include "preferences.h"
27
28#include "livarot/LivarotDefs.h"
29#include "object/sp-root.h"
30#include "object/sp-namedview.h"
31#include "svg/stringstream.h"
32
33namespace Inkscape {
34namespace Extension {
35namespace Internal {
36
38{
39 return;
40}
41
61/* Given "bitmap", this returns the pixel of bitmap at the point
62 ("x", "y"). */
63
64pixel_t * Metafile::pixel_at (bitmap_t * bitmap, int x, int y)
65{
66 return bitmap->pixels + bitmap->width * y + x;
67}
68
69
70/* Write "bitmap" to a PNG file specified by "path"; returns 0 on
71 success, non-zero on error. */
72
73void
74Metafile::my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
75{
76 PMEMPNG p=(PMEMPNG)png_get_io_ptr(png_ptr);
77
78 size_t nsize = p->size + length;
79
80 /* allocate or grow buffer */
81 if(p->buffer){ p->buffer = (char *) realloc(p->buffer, nsize); }
82 else{ p->buffer = (char *) malloc(nsize); }
83
84 if(!p->buffer){ png_error(png_ptr, "Write Error"); }
85
86 /* copy new bytes to end of buffer */
87 memcpy(p->buffer + p->size, data, length);
88 p->size += length;
89}
90
91void Metafile::toPNG(PMEMPNG accum, int width, int height, const char *px){
92 bitmap_t bmStore;
93 bitmap_t *bitmap = &bmStore;
94 accum->buffer=nullptr; // PNG constructed in memory will end up here, caller must free().
95 accum->size=0;
96 bitmap->pixels=(pixel_t *)px;
97 bitmap->width = width;
98 bitmap->height = height;
99
100 png_structp png_ptr = nullptr;
101 png_infop info_ptr = nullptr;
102 size_t x, y;
103 png_byte ** row_pointers = nullptr;
104 /* The following number is set by trial and error only. I cannot
105 see where it it is documented in the libpng manual.
106 */
107 int pixel_size = 3;
108 int depth = 8;
109
110 png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
111 if (png_ptr == nullptr){
112 accum->buffer=nullptr;
113 return;
114 }
115
116 info_ptr = png_create_info_struct (png_ptr);
117 if (info_ptr == nullptr){
118 png_destroy_write_struct (&png_ptr, &info_ptr);
119 accum->buffer=nullptr;
120 return;
121 }
122
123 /* Set up error handling. */
124
125 if (setjmp (png_jmpbuf (png_ptr))) {
126 png_destroy_write_struct (&png_ptr, &info_ptr);
127 accum->buffer=nullptr;
128 return;
129 }
130
131 /* Set image attributes. */
132
133 png_set_IHDR (
134 png_ptr,
135 info_ptr,
136 bitmap->width,
137 bitmap->height,
138 depth,
139 PNG_COLOR_TYPE_RGB,
140 PNG_INTERLACE_NONE,
141 PNG_COMPRESSION_TYPE_DEFAULT,
142 PNG_FILTER_TYPE_DEFAULT
143 );
144
145 /* Initialize rows of PNG. */
146
147 row_pointers = (png_byte **) png_malloc (png_ptr, bitmap->height * sizeof (png_byte *));
148 for (y = 0; y < bitmap->height; ++y) {
149 png_byte *row =
150 (png_byte *) png_malloc (png_ptr, sizeof (uint8_t) * bitmap->width * pixel_size);
151 row_pointers[bitmap->height - y - 1] = row; // Row order in EMF is reversed.
152 for (x = 0; x < bitmap->width; ++x) {
153 pixel_t * pixel = pixel_at (bitmap, x, y);
154 *row++ = pixel->red; // R & B channels were set correctly by DIB_to_RGB
155 *row++ = pixel->green;
156 *row++ = pixel->blue;
157 }
158 }
159
160 /* Write the image data to memory */
161
162 png_set_rows (png_ptr, info_ptr, row_pointers);
163
164 png_set_write_fn(png_ptr, accum, my_png_write_data, nullptr);
165
166 png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr);
167
168 for (y = 0; y < bitmap->height; y++) {
169 png_free (png_ptr, row_pointers[y]);
170 }
171 png_free (png_ptr, row_pointers);
172 png_destroy_write_struct(&png_ptr, &info_ptr);
173
174}
175
176/* If the viewBox is missing, set one
177*/
179
180 if (doc && !doc->getRoot()->viewBox_set) {
182
183 doc->ensureUpToDate();
184
185 // Set document unit
186 Inkscape::XML::Node *repr = doc->getNamedView()->getRepr();
188 Inkscape::Util::Unit const* doc_unit = doc->getWidth().unit;
189 os << doc_unit->abbr;
190 repr->setAttribute("inkscape:document-units", os.str());
191
192 // Set viewBox
193 doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc_unit), doc->getHeight().value(doc_unit)));
194 doc->ensureUpToDate();
195
196 // Scale and translate objects
197 double scale = Inkscape::Util::Quantity::convert(1, "px", doc_unit);
199 double dh;
200 if(SP_ACTIVE_DOCUMENT){ // for file menu open or import, or paste from clipboard
201 dh = SP_ACTIVE_DOCUMENT->getHeight().value("px");
202 }
203 else { // for open via --file on command line
204 dh = doc->getHeight().value("px");
205 }
206
207 // These should not affect input, but they do, so set them to a neutral state
209 bool transform_stroke = prefs->getBool("/options/transform/stroke", true);
210 bool transform_rectcorners = prefs->getBool("/options/transform/rectcorners", true);
211 bool transform_pattern = prefs->getBool("/options/transform/pattern", true);
212 bool transform_gradient = prefs->getBool("/options/transform/gradient", true);
213 prefs->setBool("/options/transform/stroke", true);
214 prefs->setBool("/options/transform/rectcorners", true);
215 prefs->setBool("/options/transform/pattern", true);
216 prefs->setBool("/options/transform/gradient", true);
217
220
221 // restore options
222 prefs->setBool("/options/transform/stroke", transform_stroke);
223 prefs->setBool("/options/transform/rectcorners", transform_rectcorners);
224 prefs->setBool("/options/transform/pattern", transform_pattern);
225 prefs->setBool("/options/transform/gradient", transform_gradient);
226 }
227}
228
235{
236 int ret = -1;
237 switch(op) {
238 case U_RGN_AND:
239 ret = bool_op_inters;
240 break;
241 case U_RGN_OR:
242 ret = bool_op_union;
243 break;
244 case U_RGN_XOR:
245 ret = bool_op_symdiff;
246 break;
247 case U_RGN_DIFF:
248 ret = bool_op_diff;
249 break;
250 }
251 return(ret);
252}
253
254
255
256/* convert an EMF RGB(A) color to 0RGB
257inverse of gethexcolor() in emf-print.cpp
258*/
260
261 uint32_t out;
262 out = (U_RGBAGetR(color) << 16) +
263 (U_RGBAGetG(color) << 8 ) +
264 (U_RGBAGetB(color) );
265 return(out);
266}
267
268/* Return the base64 encoded png which is shown for all bad images.
269Currently a random 3x4 blotch.
270Caller must free.
271*/
273 gchar *gstring = g_strdup("iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAA3NCSVQICAjb4U/gAAAALElEQVQImQXBQQ2AMAAAsUJQMSWI2H8qME1yMshojwrvGB8XcHKvR1XtOTc/8HENumHCsOMAAAAASUVORK5CYII=");
274 return(gstring);
275}
276
277
278
279} // namespace Internal
280} // namespace Extension
281} // namespace Inkscape
282
283/*
284 Local Variables:
285 mode:c++
286 c-file-style:"stroustrup"
287 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
288 indent-tabs-mode:nil
289 fill-column:99
290 End:
291*/
292// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
TODO: insert short description here.
@ bool_op_symdiff
Definition LivarotDefs.h:80
@ bool_op_diff
Definition LivarotDefs.h:79
@ bool_op_inters
Definition LivarotDefs.h:78
@ bool_op_union
Definition LivarotDefs.h:77
double scale
Definition aa.cpp:228
static CRect from_xywh(Coord x, Coord y, Coord w, Coord h)
Create rectangle from origin and dimensions.
Two-dimensional point that doubles as a vector.
Definition point.h:66
Scaling from the origin.
Definition transforms.h:150
RAII-style mechanism for creating a temporary undo-insensitive context.
static void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
static pixel_t * pixel_at(bitmap_t *bitmap, int x, int y)
Construct a PNG in memory from an RGB from the EMF file.
static void toPNG(PMEMPNG accum, int width, int height, const char *px)
static void setViewBoxIfMissing(SPDocument *doc)
static int combine_ops_to_livarot(const int op)
static uint32_t sethexcolor(U_COLORREF color)
Preference storage class.
Definition preferences.h:66
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
static Preferences * get()
Access the singleton Preferences object.
void setBool(Glib::ustring const &pref_path, bool value)
Set a Boolean value.
std::string str() const
static void blockSetItem(bool b)
double value(Unit const *u) const
Return the quantity's value in the specified unit.
Definition units.cpp:502
Unit const * unit
Definition units.h:95
static double convert(double from_dist, Unit const *from, Unit const *to)
Convert distances.
Definition units.cpp:525
Glib::ustring abbr
Definition units.h:76
Interface for refcounted XML nodes.
Definition node.h:80
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
Definition node.cpp:25
Typed SVG document implementation.
Definition document.h:102
SPRoot * getRoot()
Returns our SPRoot.
Definition document.h:201
Inkscape::Util::Quantity getWidth() const
Definition document.cpp:857
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 ...
SPNamedView * getNamedView()
Get the namedview for this document, creates it if it's not found.
Definition document.cpp:233
void setViewBox()
Set default viewbox calculated from document properties.
Definition document.cpp:958
Inkscape::Util::Quantity getHeight() const
Definition document.cpp:896
void scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bool noRecurse)
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
bool viewBox_set
Definition viewbox.h:34
TODO: insert short description here.
Metafile input - common functions.
Helper class to stream background task notifications as a series of messages.
TODO: insert short description here.
Singleton class to access the preferences file in a convenient way.
Inkscape::ShapeEditor This is a container class which contains a knotholder for shapes.
SPRoot: SVG <svg> implementation.
static const Point data[]
WMF manual 2.2.2.8.
Definition uemf.h:474
TODO: insert short description here.
double height
double width