1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /** @file 3 * @brief Windows Metafile Input/Output 4 */ 5 /* Authors: 6 * Ulf Erikson <ulferikson@users.sf.net> 7 * 8 * Copyright (C) 2006-2008 Authors 9 * 10 * Released under GNU GPL v2+, read the file 'COPYING' for more information. 11 */ 12 #ifndef SEEN_EXTENSION_INTERNAL_WMF_H 13 #define SEEN_EXTENSION_INTERNAL_WMF_H 14 15 #include <3rdparty/libuemf/uwmf.h> 16 #include "extension/internal/metafile-inout.h" // picks up PNG 17 #include "extension/implementation/implementation.h" 18 #include "style.h" 19 #include "text_reassemble.h" 20 21 namespace Inkscape { 22 namespace Extension { 23 namespace Internal { 24 25 #define DIRTY_NONE 0x00 26 #define DIRTY_TEXT 0x01 27 #define DIRTY_FILL 0x02 28 #define DIRTY_STROKE 0x04 // not used currently 29 30 struct WMF_OBJECT { 31 int type = 0; 32 int level = 0; 33 char *record = nullptr; 34 }; 35 using PWMF_OBJECT = WMF_OBJECT *; 36 37 struct WMF_STRINGS { 38 int size = 0; // number of slots allocated in strings 39 int count = 0; // number of slots used in strings 40 char **strings = nullptr; // place to store strings 41 }; 42 using PWMF_STRINGS = WMF_STRINGS *; 43 44 struct WMF_DEVICE_CONTEXT { WMF_DEVICE_CONTEXTWMF_DEVICE_CONTEXT45 WMF_DEVICE_CONTEXT() : 46 // SPStyle: class with constructor 47 font_name(nullptr), 48 clip_id(0), 49 stroke_set(false), stroke_mode(0), stroke_idx(0), stroke_recidx(0), 50 fill_set(false), fill_mode(0), fill_idx(0), fill_recidx(0), 51 dirty(0), 52 active_pen(-1), active_brush(-1), active_font(-1), // -1 when the default is used 53 // sizeWnd, sizeView, winorg, vieworg, 54 ScaleInX(0), ScaleInY(0), 55 ScaleOutX(0), ScaleOutY(0), 56 bkMode(U_TRANSPARENT), 57 // bkColor, textColor 58 textAlign(0) 59 // worldTransform, cur 60 { 61 font_name = nullptr; 62 sizeWnd = point16_set( 0.0, 0.0 ); 63 sizeView = point16_set( 0.0, 0.0 ); 64 winorg = point16_set( 0.0, 0.0 ); 65 vieworg = point16_set( 0.0, 0.0 ); 66 bkColor = U_RGB(255, 255, 255); // default foreground color (white) 67 textColor = U_RGB(0, 0, 0); // default foreground color (black) 68 cur = point16_set( 0.0, 0.0 ); 69 }; 70 SPStyle style; 71 char *font_name; 72 int clip_id; // 0 if none, else 1 + index into clips 73 bool stroke_set; 74 int stroke_mode; // enumeration from drawmode, not used if fill_set is not True 75 int stroke_idx; // used with DRAW_PATTERN and DRAW_IMAGE to return the appropriate fill 76 int stroke_recidx;// record used to regenerate hatch when it needs to be redone due to bkmode, textmode, etc. change 77 bool fill_set; 78 int fill_mode; // enumeration from drawmode, not used if fill_set is not True 79 int fill_idx; // used with DRAW_PATTERN and DRAW_IMAGE to return the appropriate fill 80 int fill_recidx; // record used to regenerate hatch when it needs to be redone due to bkmode, textmode, etc. change 81 int dirty; // holds the dirty bits for text, stroke, fill 82 int active_pen; // used when the active object is deleted to set the default values, -1 is none active 83 int active_brush; // ditto 84 int active_font; // ditto. also used to hold object number in case font needs to be remade due to textcolor change. 85 U_POINT16 sizeWnd; 86 U_POINT16 sizeView; 87 U_POINT16 winorg; 88 U_POINT16 vieworg; 89 double ScaleInX, ScaleInY; 90 double ScaleOutX, ScaleOutY; 91 uint16_t bkMode; 92 U_COLORREF bkColor; 93 U_COLORREF textColor; 94 uint16_t textAlign; 95 U_POINT16 cur; 96 }; 97 using PWMF_DEVICE_CONTEXT = WMF_DEVICE_CONTEXT *; 98 99 #define WMF_MAX_DC 128 100 101 102 // like this causes a mysterious crash on the return from Wmf::open 103 //typedef struct emf_callback_data { 104 // this fixes it, so some confusion between this struct and the one in emf-inout??? 105 //typedef struct wmf_callback_data { 106 // as does this 107 struct WMF_CALLBACK_DATA { 108 WMF_CALLBACK_DATAWMF_CALLBACK_DATA109 WMF_CALLBACK_DATA() : 110 // dc: array, structure w/ constructor 111 level(0), 112 E2IdirY(1.0), 113 D2PscaleX(1.0), D2PscaleY(1.0), 114 PixelsInX(0), PixelsInY(0), 115 PixelsOutX(0), PixelsOutY(0), 116 ulCornerInX(0), ulCornerInY(0), 117 ulCornerOutX(0), ulCornerOutY(0), 118 mask(0), 119 arcdir(U_AD_COUNTERCLOCKWISE), 120 dwRop2(U_R2_COPYPEN), dwRop3(0), 121 id(0), drawtype(0), 122 // hatches, images, gradients, struct w/ constructor 123 tri(nullptr), 124 n_obj(0), 125 low_water(0) 126 //wmf_obj 127 {}; 128 129 Glib::ustring outsvg; 130 Glib::ustring path; 131 Glib::ustring outdef; 132 Glib::ustring defs; 133 134 WMF_DEVICE_CONTEXT dc[WMF_MAX_DC+1]; // FIXME: This should be dynamic.. 135 int level; 136 137 double E2IdirY; // WMF Y direction relative to Inkscape Y direction. Will be negative for MM_LOMETRIC etc. 138 double D2PscaleX,D2PscaleY; // WMF device to Inkscape Page scale. 139 float PixelsInX, PixelsInY; // size of the drawing, in WMF device pixels 140 float PixelsOutX, PixelsOutY; // size of the drawing, in Inkscape pixels 141 double ulCornerInX,ulCornerInY; // Upper left corner, from header rclBounds, in logical units 142 double ulCornerOutX,ulCornerOutY; // Upper left corner, in Inkscape pixels 143 uint32_t mask; // Draw properties 144 int arcdir; // U_AD_COUNTERCLOCKWISE 1 or U_AD_CLOCKWISE 2 145 146 uint32_t dwRop2; // Binary raster operation, 0 if none (use brush/pen unmolested) 147 uint32_t dwRop3; // Ternary raster operation, 0 if none (use brush/pen unmolested) 148 149 unsigned int id; 150 unsigned int drawtype; // one of 0 or U_WMR_FILLPATH, U_WMR_STROKEPATH, U_WMR_STROKEANDFILLPATH 151 // both of these end up in <defs> under the names shown here. These structures allow duplicates to be avoided. 152 WMF_STRINGS hatches; // hold pattern names, all like WMFhatch#_$$$$$$ where # is the WMF hatch code and $$$$$$ is the color 153 WMF_STRINGS images; // hold images, all like Image#, where # is the slot the image lives. 154 WMF_STRINGS clips; // hold clipping paths, referred to be the slot where the clipping path lives 155 TR_INFO *tri; // Text Reassembly data structure 156 157 158 int n_obj; 159 int low_water; // first object slot which _might_ be unoccupied. Everything below is filled. 160 PWMF_OBJECT wmf_obj; 161 }; 162 using PWMF_CALLBACK_DATA = WMF_CALLBACK_DATA *; 163 164 class Wmf : public Metafile 165 { 166 167 public: 168 Wmf(); // Empty constructor 169 170 ~Wmf() override;//Destructor 171 172 bool check(Inkscape::Extension::Extension *module) override; //Can this module load (always yes for now) 173 174 void save(Inkscape::Extension::Output *mod, // Save the given document to the given filename 175 SPDocument *doc, 176 gchar const *filename) override; 177 178 SPDocument *open( Inkscape::Extension::Input *mod, 179 const gchar *uri ) override; 180 181 static void init();//Initialize the class 182 183 private: 184 protected: 185 static void print_document_to_file(SPDocument *doc, const gchar *filename); 186 static double current_scale(PWMF_CALLBACK_DATA d); 187 static std::string current_matrix(PWMF_CALLBACK_DATA d, double x, double y, int useoffset); 188 static double current_rotation(PWMF_CALLBACK_DATA d); 189 static void enlarge_hatches(PWMF_CALLBACK_DATA d); 190 static int in_hatches(PWMF_CALLBACK_DATA d, char *test); 191 static uint32_t add_hatch(PWMF_CALLBACK_DATA d, uint32_t hatchType, U_COLORREF hatchColor); 192 static void enlarge_images(PWMF_CALLBACK_DATA d); 193 static int in_images(PWMF_CALLBACK_DATA d, char *test); 194 static uint32_t add_dib_image(PWMF_CALLBACK_DATA d, const char *dib, uint32_t iUsage); 195 static uint32_t add_bm16_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char *px); 196 197 static void enlarge_clips(PWMF_CALLBACK_DATA d); 198 static int in_clips(PWMF_CALLBACK_DATA d, const char *test); 199 static void add_clips(PWMF_CALLBACK_DATA d, const char *clippath, unsigned int logic); 200 201 static void output_style(PWMF_CALLBACK_DATA d); 202 static double _pix_x_to_point(PWMF_CALLBACK_DATA d, double px); 203 static double _pix_y_to_point(PWMF_CALLBACK_DATA d, double py); 204 static double pix_to_x_point(PWMF_CALLBACK_DATA d, double px, double py); 205 static double pix_to_y_point(PWMF_CALLBACK_DATA d, double px, double py); 206 static double pix_to_abs_size(PWMF_CALLBACK_DATA d, double px); 207 static std::string pix_to_xy(PWMF_CALLBACK_DATA d, double x, double y); 208 static void select_brush(PWMF_CALLBACK_DATA d, int index); 209 static void select_font(PWMF_CALLBACK_DATA d, int index); 210 static void select_pen(PWMF_CALLBACK_DATA d, int index); 211 static int insertable_object(PWMF_CALLBACK_DATA d); 212 static void delete_object(PWMF_CALLBACK_DATA d, int index); 213 static int insert_object(PWMF_CALLBACK_DATA d, int type, const char *record); 214 static uint32_t *unknown_chars(size_t count); 215 static void common_dib_to_image(PWMF_CALLBACK_DATA d, const char *dib, 216 double dx, double dy, double dw, double dh, int sx, int sy, int sw, int sh, uint32_t iUsage); 217 static void common_bm16_to_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char *px, 218 double dx, double dy, double dw, double dh, int sx, int sy, int sw, int sh); 219 static int myMetaFileProc(const char *contents, unsigned int length, PWMF_CALLBACK_DATA d); 220 static void free_wmf_strings(WMF_STRINGS name); 221 222 }; 223 224 } } } /* namespace Inkscape, Extension, Implementation */ 225 226 227 #endif /* EXTENSION_INTERNAL_WMF_H */ 228 229 /* 230 Local Variables: 231 mode:c++ 232 c-file-style:"stroustrup" 233 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) 234 indent-tabs-mode:nil 235 fill-column:99 236 End: 237 */ 238 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : 239