1 /**************************************************************************** 2 * Copyright (C) 2008-2011 by Matteo Franchin * 3 * * 4 * This file is part of Box. * 5 * * 6 * Box is free software: you can redistribute it and/or modify it * 7 * under the terms of the GNU Lesser General Public License as published * 8 * by the Free Software Foundation, either version 3 of the License, or * 9 * (at your option) any later version. * 10 * * 11 * Box is distributed in the hope that it will be useful, * 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 * GNU Lesser General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU Lesser General Public * 17 * License along with Box. If not, see <http://www.gnu.org/licenses/>. * 18 ****************************************************************************/ 19 20 /* Questo file contiene le dichiarazioni di strutture, macro e procedure 21 * grafiche non dipendenti dal modo in cui i dati relativi all'immagine 22 * vengono memorizzati(bit per pixel). 23 */ 24 25 #ifndef _BOX_LIBG_GRAPHIC_H 26 # define _BOX_LIBG_GRAPHIC_H 27 28 # include "types.h" 29 # include "gpath.h" 30 # include "obj.h" 31 # include "matrix.h" 32 # include "winmap.h" 33 34 /** Enumeration of possible errors occuring in the graphic library */ 35 typedef enum { 36 BOXGERR_NO_ERR=0, 37 BOXGERR_UNEXPECTED, 38 BOXGERR_NO_MEMORY, 39 BOXGERR_MISS_WIN_TYPE, 40 BOXGERR_CAIRO_MISSES_PS, 41 BOXGERR_CAIRO_MISSES_PDF, 42 BOXGERR_CAIRO_MISSES_SVG, 43 BOXGERR_UNKNOWN_WIN_TYPE, 44 BOXGERR_WIN_SIZE_MISSING, 45 BOXGERR_WIN_RES_MISSING, 46 BOXGERR_WIN_FILENAME_MISSING, 47 BOXGERR_CAIRO_SURFACE_ERR, 48 BOXGERR_CAIRO_CONTEXT_ERR, 49 BOXGERR_CAIRO_PATTERN_ERR, 50 BOXGERR_CMD_BAD_ARGS, 51 BOXGERR_CMD_MISSING_ARGS, 52 BOXGERR_CMD_UNEXPECTED_ARGS, 53 BOXGERR_CMD_EXEC, 54 BOXGERR_CMD_BAD, 55 BOXGERR_CMD_EMPTY, 56 BOXGERR_CMD_BAD_INDEX 57 58 } BoxGErr; 59 60 /** Return a string corresponding to the given error code. */ 61 const char *BoxGErr_To_Str(BoxGErr err); 62 63 typedef enum { 64 FILLSTYLE_VOID=0, 65 FILLSTYLE_PLAIN, 66 FILLSTYLE_EO, 67 FILLSTYLE_CLIP, 68 FILLSTYLE_EOCLIP 69 } FillStyle; 70 71 /* The color type */ 72 typedef struct { 73 BoxReal r, g, b, a; 74 } Color; 75 76 /* Definisce la struttura adatta a contenere il colore di un punto */ 77 typedef struct { 78 unsigned char r; /* Componente rossa */ 79 unsigned char g; /* Componente verde */ 80 unsigned char b; /* Componente blu */ 81 } ColorBytes; 82 83 #define color ColorBytes 84 85 /* Questa e' la struttura di un elemento della palette */ 86 struct palitem { 87 long index; /* Numero del colore nella tavolazza */ 88 ColorBytes c; /* Colore */ 89 struct palitem *next; /* Puntatore al prossimo elemento */ 90 }; 91 92 typedef struct palitem palitem; 93 94 /* Questa e' la struttura di una palette (= tavolazza di colori) */ 95 typedef struct { 96 long dim; /* Dimensione della tavolazza (numero di colori inseribili) */ 97 long num; /* Numero dei colori attualmente inseriti */ 98 long hashdim; /* Dimensione della hash-table */ 99 long hashmul; /* Numero utilizzato dalla hash-function */ 100 int reduce; /* Livello di riduzione (approssimazione) dei colori */ 101 palitem **hashtable; /* Puntatore alla hash-table */ 102 } palette; 103 104 /** This structure is used to make uniform the functions for opening 105 * graphic windows of different types. 106 */ 107 typedef struct { 108 struct { 109 int type : 1, origin : 1, size : 1, 110 resolution : 1, file_name : 1, num_layers: 1; 111 } have; 112 int type; 113 BoxPoint origin, size, 114 resolution; /** Resolution in points per mm */ 115 char *file_name; 116 int num_layers; 117 } BoxGWinPlan; 118 119 /** Font feature: slant */ 120 typedef enum { 121 FONT_SLANT_NORMAL, FONT_SLANT_ITALIC, FONT_SLANT_OBLIQUE 122 } FontSlant; 123 124 /** Font feature: weight */ 125 typedef enum { 126 FONT_WEIGHT_NORMAL, FONT_WEIGHT_BOLD 127 } FontWeight; 128 129 /** Alternatives for joining two segments of a line */ 130 typedef enum { 131 JOIN_STYLE_MITER=0, JOIN_STYLE_ROUND, JOIN_STYLE_BEVEL 132 } JoinStyle; 133 134 /** Alternatives for line endings. */ 135 typedef enum {CAP_STYLE_BUTT=0, CAP_STYLE_ROUND, CAP_STYLE_SQUARE} CapStyle; 136 137 /** All what is needed by the rdraw method */ 138 typedef struct { 139 FillStyle fill_style; 140 BoxReal scale, bord_width, bord_miter_limit; 141 JoinStyle bord_join_style; 142 Color bord_color; 143 CapStyle bord_cap; 144 BoxInt bord_num_dashes; 145 BoxReal *bord_dashes, bord_dash_offset; 146 } DrawStyle; 147 148 /** Enumeration of possible color gradient types */ 149 typedef enum { 150 COLOR_GRAD_TYPE_LINEAR=0, 151 COLOR_GRAD_TYPE_RADIAL 152 } ColorGradType; 153 154 /** Structure used to specify a color in the gradient vector (see ColorGrad) 155 */ 156 typedef struct { 157 BoxReal position; 158 Color color; 159 } ColorGradItem; 160 161 /** Decides what should be done outside the gradient area. */ 162 typedef enum { 163 COLOR_GRAD_EXT_NONE=0, 164 COLOR_GRAD_EXT_REPEAT, 165 COLOR_GRAD_EXT_REFLECT, 166 COLOR_GRAD_EXT_PAD 167 } ColorGradExt; 168 169 /** Structure containing the specification for linear or circular gradients. 170 * the gradient can be linear or circular. In the case of linear gradients 171 * P(t) is a point in the segment point1-point2 which goes linearly from 172 * point1 to point2, for t going from 0 to 1. 173 * The color is constant in each line passing through P(t) and changes as 174 * a function of t. 175 */ 176 typedef struct { 177 ColorGradType type; 178 ColorGradExt extend; 179 BoxPoint point1, point2, ref1, ref2; 180 BoxReal radius1, radius2; 181 BoxInt num_items; 182 ColorGradItem *items; 183 } ColorGrad; 184 185 /** Enumerate all the available method of a BoxGWin object. */ 186 typedef enum { 187 BOXGWIN_METHOD_CREATE_PATH, 188 BOXGWIN_METHOD_BEGIN_DRAWING, 189 BOXGWIN_METHOD_DRAW_PATH, 190 BOXGWIN_METHOD_LINE_PATH, 191 BOXGWIN_METHOD_ADD_LINE_PATH, 192 BOXGWIN_METHOD_ADD_JOIN_PATH, 193 BOXGWIN_METHOD_ADD_CIRCLE_PATH, 194 BOXGWIN_METHOD_ADD_TEXT_PATH, 195 BOXGWIN_METHOD_ADD_FAKE_POINT, 196 BOXGWIN_METHOD_CLOSE_PATH, 197 BOXGWIN_METHOD_SET_FG_COLOR, 198 BOXGWIN_METHOD_SET_BG_COLOR, 199 BOXGWIN_METHOD_SET_GRADIENT, 200 BOXGWIN_METHOD_SET_FONT, 201 BOXGWIN_METHOD_SAVE_TO_FILE, 202 BOXGWIN_METHOD_INTERPRET, 203 BOXGWIN_METHOD_FINISH, 204 BOXGWIN_METHOD_SET_COLOR, 205 BOXGWIN_METHOD_DRAW_POINT, 206 BOXGWIN_METHOD_DRAW_HOR_LINE, 207 BOXGWIN_METHOD_UNBLOCK, 208 BOXGWIN_METHOD_NOTIFY_NOT_IMPLEMENTED 209 210 } BoxGWinMethod; 211 212 /** Return a string describing the method 'm'. */ 213 const char *BoxGWinMethod_To_String(BoxGWinMethod m); 214 215 /** Descriptor of a graphic Window */ 216 typedef struct BoxGWin_struct BoxGWin; 217 218 /* BoxGWin would need some cleaning. At the moment it contains stuff which 219 * is not relevant for all kinds of windows... 220 */ 221 struct BoxGWin_struct { 222 /** String which identifies the type of the window */ 223 char *win_type_str; 224 225 /* High level functions */ 226 227 /** @see BoxGWin_Create_Path */ 228 void (*create_path)(BoxGWin *w); 229 230 /** @see BoxGWin_Begin_Drawing */ 231 void (*begin_drawing)(BoxGWin *w); 232 233 /** @see BoxGWin_Draw_Path */ 234 void (*draw_path)(BoxGWin *w, DrawStyle *style); 235 236 /** @see BoxGWin_Add_Line_Path */ 237 void (*add_line_path)(BoxGWin *w, BoxPoint *a, BoxPoint *b); 238 239 /** @see BoxGWin_Add_Join_Path */ 240 void (*add_join_path)(BoxGWin *w, BoxPoint *a, BoxPoint *b, BoxPoint *c); 241 242 /** @see BoxGWin_Close_Path */ 243 void (*close_path)(BoxGWin *w); 244 245 /** @see BoxGWin_Add_Circle_Path */ 246 void (*add_circle_path)(BoxGWin *w, 247 BoxPoint *ctr, BoxPoint *a, BoxPoint *b); 248 249 /** @see BoxGWin_Set_Fg_Color */ 250 void (*set_fg_color)(BoxGWin *w, Color *c); 251 252 /** @see BoxGWin_Set_Bg_Color */ 253 void (*set_bg_color)(BoxGWin *w, Color *c); 254 255 /** @see BoxGWin_Set_Gradient */ 256 void (*set_gradient)(BoxGWin *w, ColorGrad *cg); 257 258 /** @see BoxGWin_Set_Font */ 259 void (*set_font)(BoxGWin *w, const char *font_name); 260 261 /** @see BoxGWin_Add_Text_Path */ 262 void (*add_text_path)(BoxGWin *w, 263 BoxPoint *ctr, BoxPoint *right, BoxPoint *up, 264 BoxPoint *from, const char *text); 265 266 /** @see BoxGWin_Add_Fake_Point */ 267 void (*add_fake_point)(BoxGWin *w, BoxPoint *p); 268 269 /** @see BoxGWin_Save_To_File */ 270 int (*save_to_file)(BoxGWin *w, const char *file_name); 271 272 /** @see BoxGWin_Interpret_Obj */ 273 BoxTask (*interpret)(BoxGWin *w, BoxGObj *commands, BoxGWinMap *map); 274 275 /** If set to 1, inhibits error messages */ 276 int quiet; 277 278 /* Low level functions (should probably be moved out of here) */ 279 280 /** terminates drawing operations on the window and make it unusable. 281 * @see BoxGWin_Finish, BoxGWin_Destroy 282 */ 283 void (*finish)(BoxGWin *w); 284 285 /** @see BoxGWin_Set_Color */ 286 void (*set_color)(BoxGWin *w, int col); 287 288 /** @see BoxGWin_Draw_Point */ 289 void (*draw_point)(BoxGWin *w, BoxInt ptx, BoxInt pty); 290 291 /** @see BoxGWin_Draw_Hor_Line */ 292 void (*draw_hor_line)(BoxGWin *w, BoxInt y, BoxInt x1, BoxInt x2); 293 294 /** Restore the window methods, which may have been changed after an error 295 * has occurred. 296 */ 297 void (*repair)(BoxGWin *w); 298 299 /** This function is used to notify that a given method has of the window 300 * has not been implemented. 301 */ 302 BoxGWin *(*notify_not_implemented)(BoxGWin *w, BoxGWinMethod method); 303 304 void *ptr; /**< Pointer to the window data */ 305 void *data; /**< Pointer to extra data dependent on the window 306 type */ 307 308 BoxReal 309 ltx, lty, /**< Coordinates of top left-corner (in mm)*/ 310 rdx, rdy, /**< Coordinates of bottom right-corner (in mm) */ 311 minx, miny, /**< Minimum coordinates (in mm) */ 312 maxx, maxy, /**< Maximum coordinates (in mm) */ 313 lx, ly, /**< Width and height (in mm, positive) */ 314 versox, versoy, /**< Unit vectors x and y (either +1 or -1) */ 315 stepx, stepy, /**< Coordinate variations to move a pixel on the left 316 and on the bottom */ 317 resx, resy; /**< x and y resolution (points per mm) */ 318 319 BoxInt numptx, numpty; /**< Number of points in each direction */ 320 palitem *bgcol; /**< Background color */ 321 palitem *fgcol; /**< Current foreground color */ 322 palette *pal; /**< Color palette */ 323 long bitperpixel; /**< Bit necessary to store a single pixel */ 324 long bytesperline; /**< Bytes required for each row */ 325 long dim; /**< Total size (in bytes) of the window */ 326 }; 327 328 #define BoxGWin_Fail(source, msg) 329 330 /* Define some macros to provide functions which can be called as one would 331 * normally expect: Method_Of_Obj(obj, arg1, arg2, ...) rather than 332 * obj->method_name(obj, ...). 333 */ 334 335 /**************************************************************************** 336 * HIGH LEVEL ROUTINES 337 */ 338 339 /** Initialize the window for drawing */ 340 #define BoxGWin_Begin_Drawing(win) ((win)->begin_drawing)(win) 341 342 /** Finalize the window */ 343 void BoxGWin_Finish(BoxGWin *w); 344 345 /** Create a new path (rreset) */ 346 #define BoxGWin_Create_Path(win) ((win)->create_path)(win) 347 348 /** Close the current path (rclose) */ 349 #define BoxGWin_Close_Path(win) ((win)->close_path)(win) 350 351 /** Draw the current path using the given drawing style. (rdraw) */ 352 #define BoxGWin_Draw_Path(win, style) ((win)->draw_path)((win), (style)) 353 354 /** Generate the path for a line connecting the two points 'a' and 'b' */ 355 #define BoxGWin_Add_Line_Path(win, a, b) \ 356 ((win)->add_line_path)((win), (a), (b)) 357 358 /** Generate the join connecting point 'a' to 'c' with corner in 'b'. */ 359 #define BoxGWin_Add_Join_Path(win, a, b, c) \ 360 ((win)->add_join_path)((win), (a), (b), (c)) 361 362 /** Generate the path for a circle in the reference system identified by 363 * the origin 'ctr' and the unit axis points 'a' and 'b'. 364 */ 365 #define BoxGWin_Add_Circle_Path(win, ctr, right, up) \ 366 ((win)->add_circle_path)((win), (ctr), (right), (up)) 367 368 /** Set the foreground color. */ 369 #define BoxGWin_Set_Fg_Color(win, c) \ 370 ((win)->set_fg_color)((win), (c)) 371 372 /** Set the background color. */ 373 #define BoxGWin_Set_Bg_Color(win, c) \ 374 ((win)->set_bg_color)((win), (c)) 375 376 /** Set the gradient as a source for filling. */ 377 #define BoxGWin_Set_Gradient(win, cg) \ 378 ((win)->set_gradient)((win), (cg)) 379 380 /** Add a fake point to the window. Fake points only have an effect on the 381 * bounding box (can be used to make sure a point is visible in the figure). 382 */ 383 #define BoxGWin_Add_Fake_Point(win, p) \ 384 ((win)->add_fake_point)((win), (p)) 385 386 /** Interpret raw commands contained inside an Obj object. */ 387 #define BoxGWin_Interpret_Obj(win, obj, map) \ 388 ((win)->interpret)((win), (obj), (map)) 389 390 /** Set the current font from the font name provided in the string. */ 391 #define BoxGWin_Set_Font(win, name) \ 392 ((win)->set_font)((win), (name)) 393 394 /** Generate the path for the given text on the reference frame 395 * defined by the origin 'ctr' and the two axes ('ctr', 'right' and 'up' 396 * are the point at position (0, 0), (0, 1) and (1, 0), respectively in the 397 * reference frame. The text is printed in the direction (0, 0) -> (1, 0) 398 * with font size 1.0 (meaning that the three points 'ctr', 'right' and 'up' 399 * can be used to magnify the text and transform it in any way). 400 */ 401 #define BoxGWin_Add_Text_Path(win, ctr, right, up, from, text) \ 402 ((win)->add_text_path)((win), (ctr), (right), (up), (from), (text)) 403 404 /** Save the window to a file */ 405 #define BoxGWin_Save_To_File(win, filename) \ 406 ((win)->save_to_file)((win), (filename)) 407 408 /**************************************************************************** 409 * LOW LEVEL ROUTINES 410 */ 411 412 /** Draw a point. */ 413 #define BoxGWin_Draw_Point(win, x, y) \ 414 ((win)->draw_point)((win), (x), (y)) 415 416 /** Draw an horizontal line. */ 417 #define BoxGWin_Draw_Hor_Line(win, y, x1, x2) \ 418 ((win)->draw_hor_line)((win), (y), (x1), (x2)) 419 420 /** Finalize the window */ 421 #define BoxGWin_Set_Color(win, col_index) \ 422 ((win)->set_color)((win), (col_index)) 423 424 /****************************************************************************/ 425 426 /* Per convertire in millimetri, radianti, punti per millimetro */ 427 extern BoxReal grp_tomm; 428 extern BoxReal grp_torad; 429 extern BoxReal grp_toppmm; 430 431 /* Window type (in BoxGWinPlan) */ 432 typedef enum {WT_NONE=-1, WT_BM1=0, WT_BM4, WT_BM8, WT_FIG, 433 WT_PS, WT_EPS, WT_A1, WT_A8, WT_RGB24, WT_ARGB32, 434 WT_PDF, WT_SVG, WT_MAX} WT; 435 436 /** Get the window ID (an integer number) from the window type (a string) */ 437 int BoxGWin_Type_From_String(const char *type_str); 438 439 /** Create a default BoxGWin object. A default BoxGWin window is converted 440 * automatically to a recording (Fig) windows when the window is first used. 441 */ 442 BoxGWin *BoxGWin_Create_Default(void); 443 444 /** Create an invalid BoxGWin object. All BoxGWin object should be constructed 445 * by extending an invalid BoxGWin object (and should thus call the function 446 * below in their constructors). 447 */ 448 BoxGWin *BoxGWin_Create_Invalid(BoxGErr *err); 449 450 /** Destroy a BoxGWin object created with BoxGWin_Create_Invalid. All BoxGWin 451 * destructors should be implemented by calling this function. 452 */ 453 void BoxGWin_Destroy(BoxGWin *w); 454 455 /** Unified function to open any kind of window */ 456 BoxGWin *BoxGWin_Create(BoxGWinPlan *plan); 457 458 /** Make sure the components of 'c' lie inside [0, 1] and correct them, 459 * if needed. 460 */ 461 void Color_Trunc(Color *c); 462 463 464 /** Create a Window which displays the given error message, when someone 465 * tries to use it. The error message is fprinted to the give stream. 466 */ 467 BoxGWin *BoxGWin_Create_Faulty(FILE *out, const char *msg); 468 469 /* Dichiarazioni delle procedure della libreria */ 470 /* Funzioni grafiche di alto livello */ 471 BoxGWin *BoxGWin_Create_BM1(BoxReal ltx, BoxReal lty, BoxReal rdx, BoxReal rdy, 472 BoxReal resx, BoxReal resy); 473 BoxGWin *BoxGWin_Create_BM4(BoxReal ltx, BoxReal lty, BoxReal rdx, BoxReal rdy, 474 BoxReal resx, BoxReal resy); 475 BoxGWin *BoxGWin_Create_BM8(BoxReal ltx, BoxReal lty, BoxReal rdx, BoxReal rdy, 476 BoxReal resx, BoxReal resy); 477 BoxTask BoxGWin_Init_Fig(BoxGWin *w, int numlayers); 478 BoxGWin *BoxGWin_Create_Fig(int numlayers); 479 BoxGWin *BoxGWin_Create_PS(const char *file); 480 BoxGWin *BoxGWin_Create_EPS(const char *file, BoxReal x, BoxReal y); 481 int ps_save_fig(const char *file_name, BoxGWin *figure); 482 int eps_save_fig(const char *file_name, BoxGWin *figure); 483 484 /** Type of function called when BoxGWin_Block_With has been used. */ 485 typedef BoxGWin *(*BoxGOnError)(BoxGWin *w, BoxGWinMethod method); 486 487 /** Block the window 'w', such that it reports errors when used. */ 488 void BoxGWin_Block(BoxGWin *w); 489 490 /** Similar to BoxGWin_Block, but when the window 'w' is used, 491 * the function on_error is called, instead of reporting an error. 492 */ 493 void BoxGWin_Block_With(BoxGWin *w, BoxGOnError on_error); 494 495 /** Restore the window 'w', after it has been blocked with BoxGWin_Block 496 * or BoxGWin_Block_With 497 */ 498 #define BoxGWin_Repair(w) \ 499 do {(w)->repair(w)} while(0) 500 501 /** Returns 1 if the window has been created with BoxGWin_Create_Faulty, 502 * 0 otherwise. 503 */ 504 int BoxGWin_Is_Faulty(BoxGWin *w); 505 506 /* Procedure per la gestione di una palette */ 507 void grp_color_build(Color *cb, ColorBytes *c); 508 void grp_color_reduce(palette *p, ColorBytes *c); 509 palette *grp_palette_build(long numcol, long hashdim, long hashmul, int reduce); 510 palitem *grp_color_find(palette *p, ColorBytes *c); 511 palitem *grp_color_request(palette *p, ColorBytes *c); 512 int grp_palette_transform(palette *p, int (*operation)(palitem *pi)); 513 void grp_palette_destroy(palette *p); 514 515 /** Draw a path encoded inside a GPath object. */ 516 void BoxGWin_Draw_GPath(BoxGWin *w, GPath *gp); 517 518 void rst_repair(BoxGWin *gw); 519 520 /* Costanti per la conversione */ 521 #define grp_mmperinch 25.4 522 #define grp_radperdeg 0.01745329252 523 #define grp_radpergrad 0.01570796327 524 #define grp_ppmmperdpi 0.03937007874 525 #define grp_mm_per_inch 25.4 526 #define grp_inch_per_psunit (1.0/72.0) 527 528 #endif 529