Changeset 19 in projects
- Timestamp:
- Sep 22, 2008, 2:12:54 AM (16 years ago)
- Location:
- visualisator
- Files:
-
- 22 added
- 4 deleted
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
visualisator
-
Property
svn:ignore
set to
*.o
gtk
cli
-
Property
svn:ignore
set to
-
visualisator/Makefile
r9 r19 1 CAIRO_CFLAGS=`pkg-config --cflags cairo` 2 GTKMM_CFLAGS=`pkg-config --cflags gtkmm-2.4` 3 CAIRO_LIBS=`pkg-config --libs cairo` 4 GTKMM_LIBS=`pkg-config --libs gtkmm-2.4` 5 CPP=g++ 6 CFLAGS=-Wall 1 7 2 CFLAGS = -Wall 3 CAIRO_CFLAGS = `pkg-config --cflags cairo` 4 GTK_CFLAGS = `pkg-config --cflags gtk+-2.0` 5 CAIRO_LFLAGS = `pkg-config --libs cairo` 6 GTK_LFLAGS = `pkg-config --libs gtk+-2.0` 7 # GTK uses Cairo, therefore $(GTK_FLAGS) doesn't need $(CAIRO_FLAGS), too 8 9 all: cli gtk 8 gtk: gtk.cc gtkpapertape.o gtkpapertapeview.o gtkpapertapefile.o gtkpapertapecolor.o gtkpapertapezoom.o lochstreifen.o gtkpapertapeexporter.o 9 $(CPP) $(GTKMM_CFLAGS) $^ -o $@ $(GTKMM_LIBS) 10 10 11 11 cli: cli.c lochstreifen.o 12 gcc $(CFLAGS) $(CAIRO_LFLAGS) $(CAIRO_CFLAGS) -o cli lochstreifen.o cli.c12 $(CC) $(CAIRO_CFLAGS) $^ $(CAIRO_LIBS) -o $@ 13 13 14 # cli was formerly: 15 #cmd: create-image.c $(BACKEND) 16 # gcc -o binary $(CAIROFLAGS) create-image.c $(BACKEND) 14 gtkpapertape.o: gtkpapertape.cc gtkpapertape.h 15 $(CPP) $(CFLAGS) $(GTKMM_CFLAGS) -c gtkpapertape.cc 17 16 18 gtk : gtk.c gtkpapertape.o19 gcc $(CFLAGS) $(GTK_LFLAGS) $(GTK_CFLAGS) -o gtk gtkpapertape.o lochstreifen.o gtk.c17 gtkpapertapeview.o: gtkpapertapeview.cc gtkpapertapeview.h 18 $(CPP) $(CFLAGS) $(GTKMM_CFLAGS) -c gtkpapertapeview.cc 20 19 20 gtkpapertapefile.o: gtkpapertapefile.cc gtkpapertapefile.h 21 $(CPP) $(CFLAGS) $(GTKMM_CFLAGS) -c gtkpapertapefile.cc 22 23 gtkpapertapeexporter.o: gtkpapertapeexporter.cc gtkpapertapeexporter.h 24 $(CPP) $(CFLAGS) $(GTKMM_CFLAGS) -c gtkpapertapeexporter.cc 21 25 22 gtkpapertape.o: lochstreifen.o gtkpapertape.c gtkpapertape.h 23 gcc $(CFLAGS) $(GTK_CFLAGS) -c gtkpapertape.c 26 gtkpapertapecolor.o: gtkpapertapecolor.cc gtkpapertapecolor.h 27 $(CPP) $(CFLAGS) $(GTKMM_CFLAGS) -c gtkpapertapecolor.cc 28 29 gtkpapertapezoom.o: gtkpapertapezoom.cc gtkpapertapezoom.h 30 $(CPP) $(CFLAGS) $(GTKMM_CFLAGS) -c gtkpapertapezoom.cc 24 31 25 32 lochstreifen.o: lochstreifen.c lochstreifen.h 26 gcc$(CFLAGS) $(CAIRO_CFLAGS) -c lochstreifen.c33 $(CC) $(CFLAGS) $(CAIRO_CFLAGS) -c lochstreifen.c 27 34 28 35 clean: 29 rm *.o gtk cli36 rm -v *.o -
visualisator/gtkpapertape.h
r9 r19 1 #ifndef __GTK_PAPER_TAPE_H__ 2 #define __GTK_PAPER_TAPE_H__ 3 4 #include "gtkmm/box.h" 5 #include "gtk/gtk.h" 6 #include <gtkmm/uimanager.h> 7 #include <gtkmm/dialog.h> 8 9 // predefine for usage in other header files 10 namespace Gtk 11 { class PaperTape; } 12 #include "gtkpapertapeview.h" 13 #include "gtkpapertapefile.h" 14 15 typedef unsigned char byte_t; 16 17 namespace Gtk { 18 1 19 /** 2 * 3 * The paper tape GTK widget 4 * 5 * This widget wraps the pure cairo widget "LOCHSTREIFEN" with some 6 * GTK widgets (which implement scrolling, mouse events, menues for 7 * changing parameters, etc.) and adds events and signals for simple 8 * interaction and use in applications. 9 * 10 * It can produce high quality SVG and PNG files (apart from displaying 11 * the paper tape on the screen) and is highly configurable. With 12 * only a few lines of code you can use this widget in your own 13 * programs, gtk.c shows an exemplar implementation in only about 14 * 160 lines of C code. 15 * 16 * Started 05.06.2008 13:13 (the first new project in the SVN) 17 * Copyright (C) 2008 Sven Köppel 18 * 19 * This program is free software; you can redistribute 20 * it and/or modify it under the terms of the GNU General 21 * Public License as published by the Free Software 22 * Foundation; either version 3 of the License, or (at 23 * your option) any later version. 24 * 25 * This program is distributed in the hope that it will 26 * be useful, but WITHOUT ANY WARRANTY; without even the 27 * implied warranty of MERCHANTABILITY or FITNESS FOR A 28 * PARTICULAR PURPOSE. See the GNU General Public License 29 * for more details. 30 * 31 * You should have received a copy of the GNU General 32 * Public License along with this program; if not, see 33 * <http://www.gnu.org/licenses/>. 20 * Klasse könnte GtkWidget erweitern und dann selbst das Haupt 21 * master drumherumwidget sein, was automatisch richtige Kinder 22 * herzaubert, inkl. Scrolling und beispielsweise greaterzoom-ding. 23 * Oder dann das IO teil, usw. 34 24 * 35 25 **/ 26 class PaperTape : public VBox 27 { 28 29 public: 30 PaperTapeView* view; 31 PaperTapeFile* model; 32 Window* parent_window; 33 34 private: 35 36 static Glib::ustring ui_info; 37 static GtkActionEntry ui_common_entries[]; 38 static GtkActionEntry ui_file_entries[]; 39 static GtkActionEntry ui_editor_entries[]; 40 static GtkToggleActionEntry ui_toggle_entries[]; 41 Glib::RefPtr<Gtk::UIManager> ui_manager; 42 void make_menu(); 43 void menu_actions(const Glib::RefPtr<Action>& action); 36 44 37 #ifndef GTK_PAPER_TAPE_H 38 #define GTK_PAPER_TAPE_H 45 public: 46 PaperTape(Window& parent_window); 47 48 /** 49 * Runs the dialog. This is just like dialog.run(), 50 * but with the correct parent window (modal dialog), 51 * which is saved in this widget. 52 **/ 53 int run_dialog(Dialog& dialog) { 54 dialog.set_transient_for(*this->parent_window); 55 return dialog.run(); 56 } 39 57 40 #include <glib.h> 41 #include <glib-object.h> 42 #include <gtk/gtk.h> 43 #include "lochstreifen.h" 58 /** 59 * Open a blank file. This will ask if user wants to close 60 * file and open, if yes, a new blank file. 61 **/ 62 //void new_file(); 63 /** 64 * Show a file dialog to open an existing file. This will 65 * ask the user if he wants to close the current file. 66 **/ 67 //void open_file(); 68 /** 69 * Ask the user if he wants to close the current file. If so, 70 * close it, leaving with no file opened (splash screen) 71 **/ 72 //void close_file(); 73 /** 74 * Check if a file is opened. 75 * @returns true if a file is opened. 76 **/ 77 //boolean file_is_open(); 78 }; 44 79 45 80 46 G_BEGIN_DECLS 47 48 /*#define GTK_PAPER_TAPE_TYPE (gtk_paper_tape_get_type()) 49 #define GTK_TYPE_PAPER_TAPE (gtk_paper_tape_get_type()) 50 #define GTK_PAPER_TAPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_PAPER_TAPE, GtkPaperTape)) 51 #define GTK_PAPER_TAPE_CLASS(klasse) (G_TYPE_CHECK_CLASS_CAST((klasse), GTK_TYPE_PAPER_TAPE, GtkPaperTapeClass)) 52 #define GTK_IS_PAPER_TAPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_PAPER_TAPE)) 53 #define GTK_IS_PAPER_TAPE_CLASS(klasse) (G_TYPE_CHECK_CLASS_TYPE((klasse), GTK_TYPE_PAPER_TAPE)) 54 #define GTK_PAPER_TAPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_PAPER_TAPE, GtkPaperTapeClass))*/ 55 56 #define GTK_PAPER_TAPE_TYPE (gtk_paper_tape_get_type ()) 57 #define GTK_PAPER_TAPE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_PAPER_TAPE_TYPE, GtkPaperTape)) 58 #define GTK_PAPER_TAPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_PAPER_TAPE_TYPE, GtkPaperTapeClass)) 59 #define GTK_IS_PAPER_TAPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_PAPER_TAPE_TYPE)) 60 #define GTK_IS_PAPER_TAPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_PAPER_TAPE_TYPE)) 61 62 typedef struct _GtkPaperTape GtkPaperTape; 63 typedef struct _GtkPaperTapeClass GtkPaperTapeClass; 64 65 struct _GtkPaperTape { 66 //GObject parent; 67 GtkWidget widget; // was GObject parent; 68 // instance members 69 70 /** Main window where this widget belongs to 71 * (to be used e.g. for modal dialogs) */ 72 GtkWidget *parent_window; 73 74 /** The famous LOCHSTREIFEN widget */ 75 LOCHSTREIFEN *lochstreifen; 76 77 /** The Statusbar where the mouse movement messages appear */ 78 GtkWidget *statusbar; 79 80 /** 81 * The GtkScrolledWindow where the 82 * GtkDrawingArea resides 83 */ 84 GtkWidget *scroll; 85 GtkWidget *draw; 86 87 /*< private >*/ 88 GtkWidget *menu_toggle_fit_screen; 89 GTimer *last_statusbar_update; 90 }; 91 92 struct _GtkPaperTapeClass { 93 GtkWidgetClass parent_class; //GObjectClass parent; 94 }; 95 96 GType gtk_paper_tape_get_type(void); 97 98 GtkWidget* gtk_paper_tape_new(); 99 100 void gtk_paper_tape_menu_export(GtkPaperTape *papertape, GtkWidget *target_menu); 101 void gtk_paper_tape_menu_view(GtkPaperTape *papertape, GtkWidget *target_menu); 102 void gtk_paper_tape_menu_colors(GtkPaperTape *papertape, GtkWidget *target_menu); 103 104 /* fast "almost macro" functions */ 105 GtkWidget *fast_color_menuitem(const GtkWidget *parentmenu, const char *dialog_title, const char *labeltext, GdkColor *initialColor, GtkSizeGroup *label_nice_sizegroup); 106 GtkWidget *fast_stock_menuitem(const GtkWidget *parentmenu, const gchar *stock_id); 107 GtkWidget *fast_menuitem(const GtkWidget *parentmenu, const gchar *label); 108 GtkWidget *fast_menu_tearoff(const GtkWidget *parentmenu); 109 GtkWidget *fast_menu_seperator(const GtkWidget *parentmenu); 110 GdkColor *color_cairo2gdk(cairo_pattern_t *pattern); 111 112 void gtk_paper_tape_set_data(GtkPaperTape* papertape, int length, byte_t *data); 113 void gtk_paper_tape_set_null_bytes(GtkPaperTape *papertape, int beginning, int end); 114 115 gboolean gtk_paper_tape_read_from_file(GtkPaperTape* papertape, char *filename); 116 GtkWidget *gtk_paper_tape_get_whole_box(GtkPaperTape *papertape); 117 118 G_END_DECLS 119 120 #endif /* GTK_PAPER_TAPE_H */ 81 }; // namespace Gtk 82 #endif // __GTK_PAPER_TAPE_H__ -
visualisator/lochstreifen.c
r18 r19 66 66 l->zero_code_hole_color = LOCHSTREIFEN_DEFAULT_ZERO_CODE_HOLE_COLOR; 67 67 l->feed_hole_color = LOCHSTREIFEN_DEFAULT_FEED_HOLE_COLOR; 68 l->matrix = malloc (sizeof(cairo_matrix_t)); 69 // default matrix: 1:1 original. 70 l->matrix->xx = 1; l->matrix->yx = 0; 71 l->matrix->xy = 0; l->matrix->yy = 1; 72 l->matrix->x0 = 0; l->matrix->y0 = 0; 68 cairo_matrix_init(&l->matrix, 1, 0, 0, 1, 0, 0); // default = 1:1 original 69 l->matrix_inverse = l->matrix; 73 70 74 71 return l; 72 } 73 74 /** 75 * Copy everything from the LOCHSTREIFEN template, except the data. They 76 * won't be copied, just set, because LOCHSTREIFEN doesn't manage your 77 * data. If you want to copy them, call something like 78 * LOCHSTREIFEN* copy = lochstreifen_copy(old); 79 * byte_t* new_data = malloc(old->data_length); 80 * memcpy(new_data, old->data, old->data_length); 81 * lochstreifen_set_data(copy, old->data_length, new_data); 82 **/ 83 LOCHSTREIFEN* lochstreifen_copy(const LOCHSTREIFEN* template) { 84 LOCHSTREIFEN *l = malloc (sizeof(LOCHSTREIFEN)); 85 #define COPY_RGBA_PATTERN(name) { double r,g,b,a; \ 86 if(!cairo_pattern_get_rgba(template->name, &r, &g, &b, &a)) \ 87 l->name = cairo_pattern_create_rgba(r,g,b,a); } 88 89 // make it quite verbose ;-) 90 l->data_length = template->data_length; 91 l->data = template->data; 92 l->highlight_region_start = template->highlight_region_start; 93 l->highlight_region_end = template->highlight_region_end; 94 COPY_RGBA_PATTERN(highlight_region_color); 95 l->highlight_row_number = template->highlight_row_number; 96 COPY_RGBA_PATTERN(highlight_row_color); 97 l->highlight_bit_row = template->highlight_bit_row; 98 l->highlight_bit_track = template->highlight_bit_track; 99 COPY_RGBA_PATTERN(highlight_bit_color); 100 l->clip = malloc(sizeof(cairo_rectangle_t)); 101 memcpy(l->clip, template->clip, sizeof(cairo_rectangle_t)); 102 COPY_RGBA_PATTERN(outer_background_color); 103 COPY_RGBA_PATTERN(papertape_background_color); 104 COPY_RGBA_PATTERN(one_code_hole_color); 105 COPY_RGBA_PATTERN(zero_code_hole_color); 106 COPY_RGBA_PATTERN(feed_hole_color); 107 l->matrix = template->matrix; 108 l->matrix_inverse = template->matrix_inverse; 109 110 return l; 111 } 112 113 /** 114 * Delete every mallocated structure in the LOCHSTREIFEN (colors, etc.), 115 * *except* from the data. You have to manage them on your own. 116 * In the end, it will free the LOCHSTREIFEN itself. 117 * @return Nothing, because there's nothing left. Except your data, okay. 118 **/ 119 void lochstreifen_free(LOCHSTREIFEN* l) { 120 if(l->highlight_region_color != NULL) free(l->highlight_region_color); 121 if(l->highlight_row_color != NULL) free(l->highlight_row_color); 122 if(l->highlight_bit_color != NULL) free(l->highlight_bit_color); 123 if(l->clip != NULL) free(l->clip); 124 if(l->outer_background_color != NULL) free(l->outer_background_color); 125 if(l->papertape_background_color != NULL) free(l->papertape_background_color); 126 if(l->one_code_hole_color != NULL) free(l->one_code_hole_color); 127 if(l->zero_code_hole_color != NULL) free(l->zero_code_hole_color); 128 if(l->feed_hole_color != NULL) free(l->feed_hole_color); 75 129 } 76 130 … … 93 147 94 148 if(l != NULL) 95 fprintf(stderr, "Debugging papertape at % x:\n", l);149 fprintf(stderr, "Debugging papertape at %p:\n", l); 96 150 else { 97 151 fprintf(stderr, "Cannot debug: Papertape is NULL!\n"); … … 155 209 156 210 // 5. Point: Affine Matrix 157 if(l->matrix == NULL) 158 fprintf(stderr, " * Matrix: disabled\n"); 159 else { 160 fprintf(stderr, " * Matrix: ENABLED\n"); 161 fprintf(stderr, " x_new = [xx=%f]*x + [xy=%f]*y + [x0=%f]\n", 162 l->matrix->xx, l->matrix->xy, l->matrix->x0); 163 fprintf(stderr, " y_new = [yx=%f]*x + [yy=%f]*y + [y0=%f]\n", 164 l->matrix->yx, l->matrix->yy, l->matrix->y0); 165 fprintf(stderr, " source dimensions: x_max = %f x y_max = %f\n", 166 LOCHSTREIFEN_LENGTH, LOCHSTREIFEN_WIDTH); 167 fprintf(stderr, " target dimensions: width = %i x height = %i\n", 168 lochstreifen_get_target_width(l), 169 lochstreifen_get_target_height(l)); 170 } 211 fprintf(stderr, " * Current transformation matrix:\n"); 212 fprintf(stderr, " x_new = [xx=%f]*x + [xy=%f]*y + [x0=%f]\n", 213 l->matrix.xx, l->matrix.xy, l->matrix.x0); 214 fprintf(stderr, " y_new = [yx=%f]*x + [yy=%f]*y + [y0=%f]\n", 215 l->matrix.yx, l->matrix.yy, l->matrix.y0); 216 fprintf(stderr, " source dimensions: x_max = %f x y_max = %f\n", 217 LOCHSTREIFEN_LENGTH, LOCHSTREIFEN_WIDTH); 218 fprintf(stderr, " target dimensions: width = %i x height = %i\n", 219 lochstreifen_get_target_width(l), 220 lochstreifen_get_target_height(l)); 171 221 172 222 // 6. Point: Debugging … … 185 235 void lochstreifen_set_data(LOCHSTREIFEN *l, int data_length, byte_t *data) { 186 236 l->data_length = data_length; 187 if(l->data != NULL)188 free(l->data);237 //if(l->data != NULL) 238 // free(l->data); 189 239 l->data = data; 190 240 } … … 240 290 * highlight region 241 291 **/ 242 void lochstreifen_set_highlight_region(LOCHSTREIFEN *l, int start, int end) {292 void lochstreifen_set_highlight_region(LOCHSTREIFEN *l, row_t start, row_t end) { 243 293 l->highlight_region_start = start; 244 294 l->highlight_region_end = end; … … 252 302 * @return TRUE if there is an highlight selection, FALSE otherwiese 253 303 **/ 254 int lochstreifen_get_highlight_region(LOCHSTREIFEN *l, int *start, int *end) {255 if(l->highlight_region_color == NULL )304 int lochstreifen_get_highlight_region(LOCHSTREIFEN *l, row_t *start, row_t *end) { 305 if(l->highlight_region_color == NULL || l->highlight_region_start == LOCHSTREIFEN_NO_ROW) 256 306 return 0; 257 307 if(start != NULL) … … 266 316 **/ 267 317 void lochstreifen_remove_highlight_region(LOCHSTREIFEN *l) { 268 l->highlight_region_color = NULL; 318 //l->highlight_region_color = NULL; 319 // was stupid, this is more intelligent: 320 l->highlight_region_start = LOCHSTREIFEN_NO_ROW; 269 321 } 270 322 … … 285 337 * GtkPaperTape. 286 338 **/ 287 void lochstreifen_set_highlight_row(LOCHSTREIFEN *l, int number_of_row) {339 void lochstreifen_set_highlight_row(LOCHSTREIFEN *l, row_t number_of_row) { 288 340 l->highlight_row_number = number_of_row; 289 341 if(l->highlight_row_color == NULL) … … 292 344 293 345 /** 294 * Get the highlighted special row. If there is no highlighted row, it will return a value295 * less than zero (e.g. -1).346 * Get the highlighted special row. If there is no highlighted row, it will return 347 * LOCHSTREIFEN_NO_ROW. 296 348 * @return the number of the special row, counting from zero. 297 349 **/ 298 350 int lochstreifen_get_highlight_row(LOCHSTREIFEN *l) { 299 return (l->highlight_row_color == NULL) ? -1 :l->highlight_row_number;351 return l->highlight_row_number; 300 352 } 301 353 … … 305 357 void lochstreifen_remove_highlight_row(LOCHSTREIFEN *l) { 306 358 //l->highlight_row_color = NULL; /// nein, das ist dumm, weil es den highlight komplett entfernen würde. 307 l->highlight_row_number = -1; // das ist schlau.359 l->highlight_row_number = LOCHSTREIFEN_NO_ROW; // das ist schlau. 308 360 } 309 361 … … 332 384 * row 2 to row 5). 333 385 **/ 334 void lochstreifen_set_highlight_bit(LOCHSTREIFEN *l, int number_of_row, int number_of_bit) {386 void lochstreifen_set_highlight_bit(LOCHSTREIFEN *l, row_t number_of_row, track_t number_of_bit) { 335 387 l->highlight_bit_row = number_of_row; 336 388 l->highlight_bit_track = number_of_bit; … … 344 396 * 345 397 **/ 346 int lochstreifen_get_highlight_bit(LOCHSTREIFEN *l, int *number_of_row, int *number_of_bit) {347 if(l->highlight_bit_ color == NULL)398 int lochstreifen_get_highlight_bit(LOCHSTREIFEN *l, row_t *number_of_row, track_t *number_of_bit) { 399 if(l->highlight_bit_row == LOCHSTREIFEN_NO_ROW) 348 400 return 0; 349 401 if(number_of_row != NULL) … … 358 410 **/ 359 411 void lochstreifen_remove_highlight_bit(LOCHSTREIFEN *l) { 360 l->highlight_bit_color = NULL; 412 //l->highlight_bit_color = NULL; // stupid. 413 l->highlight_bit_row = LOCHSTREIFEN_NO_ROW; // more intelligent. 414 } 415 416 /** 417 * Whenever you change the matrix, call this function. It will just perform some 418 * cleanup work, espacially calculate the inverse matrix for the other-side calculations. 419 **/ 420 void lochstreifen_check_matrix(LOCHSTREIFEN* l) { 421 l->matrix_inverse = l->matrix; // copy matrix 422 if(cairo_matrix_invert(&l->matrix_inverse) != CAIRO_STATUS_SUCCESS) { // invert the copy 423 // there are some matrizes which are not invertable 424 fprintf(stderr, "lochstreifen_check_matrix: Matrix is not invertable!\n"); 425 } 361 426 } 362 427 … … 364 429 * If you want LOCHSTREIFEN only to paint a small area from the whole papertape, this 365 430 * is the function you can call. 431 * If you are using an affine transformation matrix for scaling/rotation/... purpose, 432 * this function will automatically transform these values. So don't give here values 433 * like "LOCHSTREIFEN_WIDTH" or "LOCHSTREIFEN_HEIGHT" ;-) 366 434 * 367 435 **/ … … 369 437 if(l->clip == NULL) 370 438 l->clip = malloc(sizeof(cairo_rectangle_t)); 439 440 cairo_matrix_transform_point(&l->matrix_inverse, &x, &y); 441 cairo_matrix_transform_distance(&l->matrix_inverse, &width, &height); 371 442 l->clip->x = x; 372 443 l->clip->y = y; … … 394 465 printf("Scaling to length=%i, having length=%f, getting %f as scale factor\n", 395 466 length, LOCHSTREIFEN_LENGTH, scale_factor); 396 cairo_matrix_scale(l->matrix, scale_factor, scale_factor); 467 cairo_matrix_scale(&l->matrix, scale_factor, scale_factor); 468 lochstreifen_check_matrix(l); 397 469 } 398 470 399 471 void lochstreifen_set_scaling_by_width(LOCHSTREIFEN *l, int width) { 400 472 double scale_factor = ((double)width) / LOCHSTREIFEN_WIDTH; 401 cairo_matrix_scale(l->matrix, scale_factor, scale_factor); 473 cairo_matrix_scale(&l->matrix, scale_factor, scale_factor); 474 lochstreifen_check_matrix(l); 402 475 } 403 476 404 477 void lochstreifen_set_scaling_by_code_hole(LOCHSTREIFEN *l, int diameter) { 405 478 double scale_factor = ((double)diameter)/2 / LOCHSTREIFEN_RADIUS_CODE_HOLE; 406 cairo_matrix_scale(l->matrix, scale_factor, scale_factor); 479 cairo_matrix_scale(&l->matrix, scale_factor, scale_factor); 480 lochstreifen_check_matrix(l); 407 481 } 408 482 … … 429 503 // transform the "bounding box" throught the matrix 430 504 for(i=0; i < (sizeof(x) / sizeof(double)); i++) { 431 cairo_matrix_transform_point( l->matrix, &x[i], &y[i]);505 cairo_matrix_transform_point(&l->matrix, &x[i], &y[i]); 432 506 // store biggest x/y values 433 507 if(width != NULL && x[i] > *width) … … 459 533 460 534 /** 461 * Get the row number from an x/y target cordinate. That is: At first, translate 535 * Get a bit tuple from the positions on the target surface. This function 536 * translates the points x/y with the inverse current translation matrix. Then 537 * it calculates the row number that equals with the x coordinate and afterwards 538 * the track number that equals with the y coordinate. 539 * 540 * If you need only one dimension, set the other NULL. 541 * 542 * You can use lochstreifen_get_traget_row_from_point and 543 * lochstreifen_get_target_track_from_point if you need only one dimension. Furthermore 544 * they will nicely return the requested data -- no need for call by reference. 545 * 546 * @param bit The target lochstreifen_bit_t (call by reference). Should not be NULL. 547 * @param x The x coordinate you want to check 548 * @param y The y coordinate you want to check 549 **/ 550 void lochstreifen_get_target_bit_from_point(LOCHSTREIFEN* l, row_t* row, track_t* track, double x, double y) { 551 cairo_matrix_transform_point(&l->matrix_inverse, &x, &y); // transform points 552 553 if(y < 0 || y > LOCHSTREIFEN_WIDTH) { 554 // we are not at data, at all 555 if(row != NULL) 556 *row = LOCHSTREIFEN_NO_ROW; 557 if(track != NULL) 558 *track = LOCHSTREIFEN_NO_TRACK; 559 return; 560 } 561 562 if(row == NULL) { 563 // if only the track was requested, create a temporary row buffer, because 564 // we need the row number as a basis for the correct track calculation. 565 row_t row_buffer; 566 row = &row_buffer; 567 } 568 569 // Row calculation is fairly easy: 570 if(x < LOCHSTREIFEN_TEAR_OFF_LENGTH || x > (LOCHSTREIFEN_LENGTH - LOCHSTREIFEN_TEAR_OFF_LENGTH)) { 571 // we are not at data 572 *row = LOCHSTREIFEN_NO_ROW; 573 } else { 574 // getting the row from the x value. This is pretty much the same algorithm 575 // like used in papertape_draw for checking up the rectangle bounding box (clipping). 576 *row = floor( 577 (x - LOCHSTREIFEN_TEAR_OFF_LENGTH) / LOCHSTREIFEN_ROW_DISTANCE 578 ); 579 } 580 581 // Track calculation is much more complex: 582 if(track != NULL) { 583 /* get the track from the y value. This is not simply something like 584 * *track = floor( y / LOCHSTREIFEN_TRACK_DISTANCE ); 585 * because we must take care that a track is a round thing with a 586 * specific height. 587 */ 588 double M_x, M_y; // the centers of the circles 589 int i; // some iterator 590 // The center of this circle, fairly complex to calculate, see lochstreifen_draw. 591 M_x = LOCHSTREIFEN_TEAR_OFF_LENGTH + (*row + 0.5) * LOCHSTREIFEN_ROW_DISTANCE; 592 M_y = LOCHSTREIFEN_TRACK_DISTANCE; // the first track, to get onto papertape 593 // this a genious canidate for loop unrolling: 594 for(i=0; i < 8; i++) { 595 // simple linear algebra: Check if point is in the circle. 596 //fprintf(stderr, "bit %d: (%f|%f) <-> P(%f|%f) <= %f\n", i, M_x, M_y, x, y, LOCHSTREIFEN_RADIUS_CODE_HOLE); 597 if(hypot( (x-M_x) , (y-M_y) ) <= LOCHSTREIFEN_RADIUS_CODE_HOLE) { 598 // the point is in this circle, so we have found the correct track. 599 //fprintf(stderr, "FOUND %d\n", i); 600 *track = i; 601 return; 602 } else { 603 // go on, set M for next circle 604 M_y += LOCHSTREIFEN_TRACK_DISTANCE; 605 // jump over feed track before i == 3. 606 if(i == 2) 607 M_y += LOCHSTREIFEN_TRACK_DISTANCE; 608 } 609 } // for tracks 610 611 // cursor not over circle: 612 *track = LOCHSTREIFEN_NO_TRACK; 613 //fprintf(stderr, "NOT FOUND TRACK.\n"); 614 } // y dimension 615 } // lochstreifen_get_target_bit_on_point 616 617 /** 618 * Get the row number from an x/y target coordinate. That is: At first, translate 462 619 * the points with the current translation matrix, afterwards calculate the row 463 620 * number for the position. … … 465 622 * @returns Row number, counting from zero. Negative value if point not on papertape data chunk. 466 623 **/ 467 int lochstreifen_get_target_row_from_point(LOCHSTREIFEN* l, double x, double y) { 468 // transform points 469 // zunächst ganz blöd: Matrix zur Laufzeit invertieren. 470 cairo_matrix_t invert = *l->matrix; // copy matrix 471 if(cairo_matrix_invert(&invert) != CAIRO_STATUS_SUCCESS) { // invert the copy 472 // there are some matrizes which are not invertable 473 fprintf(stderr, "lochstreifen_get_target_row_from_point: Matrix is not invertable!\n"); 474 return -1; 475 } 476 cairo_matrix_transform_point(&invert, &x, &y); // transform points 477 478 // now calculate position. 479 // check if we are on data: 480 if(y < 0 || y > LOCHSTREIFEN_WIDTH || x < LOCHSTREIFEN_TEAR_OFF_LENGTH || x > (LOCHSTREIFEN_LENGTH - LOCHSTREIFEN_TEAR_OFF_LENGTH)) 481 return -2; 482 // getting the row from the x value. This is pretty much the same algorithm 483 // like used in papertape_draw for checking up the rectangle bounding box (clipping). 484 return floor ( 485 (x - LOCHSTREIFEN_TEAR_OFF_LENGTH) / LOCHSTREIFEN_ROW_DISTANCE 486 ); 487 624 row_t lochstreifen_get_target_row_from_point(LOCHSTREIFEN* l, double x, double y) { 625 row_t row; 626 lochstreifen_get_target_bit_from_point(l, &row, NULL, x, y); 627 return row; 628 } 629 630 track_t lochstreifen_get_target_track_from_point(LOCHSTREIFEN* l, double x, double y) { 631 track_t track; 632 lochstreifen_get_target_bit_from_point(l, NULL, &track, x, y); 633 return track; 634 } 635 636 637 /** 638 * Calculate the rectangle that contains the complete row on the LOCHSTREIFEN, 639 * in target surface dimensions (using the transformation matrix). If the operation 640 * fails (if the row doesn't exist), the rect is not touched at all. 641 * 642 * @param row Number of Row you want 643 * @param rect Call by reference like rectangle type 644 * @return LOCHSTREIFEN_SUCCESS or LOCHSTREIFEN_NO_ROW. 645 **/ 646 int lochstreifen_get_target_rect_from_row(LOCHSTREIFEN* l, row_t row, cairo_rectangle_t* rect) { 647 // check wheter we are in bounds 648 if(row < 0 || row > l->data_length) 649 return LOCHSTREIFEN_NO_ROW; 650 651 // This rectangle is a bit bigger than the real track, so that outlines, etc. 652 // could be drawn there, too. 653 654 rect->x = LOCHSTREIFEN_TEAR_OFF_LENGTH + (row) * LOCHSTREIFEN_ROW_DISTANCE; 655 rect->y = 0; 656 rect->width = LOCHSTREIFEN_ROW_DISTANCE; 657 rect->height = LOCHSTREIFEN_WIDTH; 658 659 // take this as padding: 660 #define TARGET_RECT_HOW_MUCH_BIGGER (LOCHSTREIFEN_ROW_DISTANCE * 0.1) 661 rect->x -= TARGET_RECT_HOW_MUCH_BIGGER; 662 rect->y -= TARGET_RECT_HOW_MUCH_BIGGER; 663 rect->width += 2*TARGET_RECT_HOW_MUCH_BIGGER; 664 rect->height += 2*TARGET_RECT_HOW_MUCH_BIGGER; 665 666 // transform the points 667 cairo_matrix_transform_point(&l->matrix, &rect->x, &rect->y); 668 cairo_matrix_transform_distance(&l->matrix, &rect->width, &rect->height); 669 670 return LOCHSTREIFEN_SUCCESS; 671 } 672 673 /** 674 * This is just the same like lochstreifen_get_target_rect_from_row, just with 675 * bits. This is still a rectangle which contains the complete circle that represents 676 * the bit, useful e.g. for GDK expose events. 677 * 678 * @param row Number of Row 679 * @param track Number of Track 680 * @param rect Call by reference like rectangle type 681 * @return LOCHSTREIFEN_SUCCESS or LOCHSTREIFEN_NO_ROW or LOCHSTREIFEN_NO_TRACK 682 **/ 683 int lochstreifen_get_target_rect_from_bit(LOCHSTREIFEN* l, row_t row, track_t track, cairo_rectangle_t* rect) { 684 // check bounds 685 if(row < 0 || row > l->data_length) 686 return LOCHSTREIFEN_NO_ROW; 687 if(track < 0 || track > 7) 688 return LOCHSTREIFEN_NO_TRACK; 689 690 // the rectangle is doesn't touch the circle, but leaves quite a bit space around 691 // it, so outlines, etc. should not be a problem. 692 693 // this code is quite like the beginning x/y dimensions in lochstreifen_draw(): 694 rect->x = LOCHSTREIFEN_TEAR_OFF_LENGTH + (row) * LOCHSTREIFEN_ROW_DISTANCE; 695 //+ (LOCHSTREIFEN_ROW_DISTANCE - LOCHSTREIFEN_RADIUS_CODE_HOLE*2) / 2; // the center 696 rect->y = LOCHSTREIFEN_TRACK_DISTANCE * (track + (track > 2 ? 1 : 0) ); 697 // The correct values for width/height would be: 698 // rect->width = LOCHSTREIFEN_RADIUS_CODE_HOLE * 2; 699 // but that won't at exposures if the hole is painted e.g. with an outline (cairo_stroke). 700 // We therefore simply take the complete track as width 701 rect->width = LOCHSTREIFEN_ROW_DISTANCE; 702 rect->height = LOCHSTREIFEN_TRACK_DISTANCE * 2; 703 704 // transform to user space 705 cairo_matrix_transform_point(&l->matrix, &rect->x, &rect->y); 706 cairo_matrix_transform_distance(&l->matrix, &rect->width, &rect->height); 707 708 return LOCHSTREIFEN_SUCCESS; 488 709 } 489 710 … … 524 745 //cairo_matrix_rotate(); 525 746 case LOCHSTREIFEN_MOVEMENT_TO_RIGHT: 747 526 748 case LOCHSTREIFEN_MOVEMENT_TO_BOTTOM: 527 case LOCHSTREIFEN_ROTATION_CLOCKWISE: 528 case LOCHSTREIFEN_ROTATION_ANTICLOCKWISE: 749 529 750 case LOCHSTREIFEN_MOVEMENT_NONE: 530 751 default: 531 752 break; 532 753 } 754 lochstreifen_check_matrix(l); 533 755 } 534 756 … … 556 778 557 779 // apply the matrix! 558 cairo_set_matrix(cr, l->matrix); 559 780 cairo_set_matrix(cr, &l->matrix); 781 782 // check if we need to repaint the papertape 783 if(l->clip != NULL && (l->clip->y > LOCHSTREIFEN_WIDTH || l->clip->x > LOCHSTREIFEN_LENGTH) ) { 784 // Clipping region is outside of papertape! 785 //printf("draw: Outside papertape.\n"); 786 return; 787 } 560 788 561 789 // paint outer background color. … … 575 803 cairo_line_to(cr, LOCHSTREIFEN_TEAR_OFF_LENGTH, 0); 576 804 cairo_close_path(cr); 577 805 cairo_fill(cr); 806 578 807 // long rectangular area over complete paper tape 579 cairo_rectangle(cr, LOCHSTREIFEN_TEAR_OFF_LENGTH, 0, 580 length - 2*LOCHSTREIFEN_TEAR_OFF_LENGTH, LOCHSTREIFEN_WIDTH); 808 if(l->clip == NULL) { 809 cairo_rectangle(cr, LOCHSTREIFEN_TEAR_OFF_LENGTH, 0.0, 810 length - 2*LOCHSTREIFEN_TEAR_OFF_LENGTH, LOCHSTREIFEN_WIDTH); 811 // irc.gnome.org, #gtk+: 812 // <owen> sven__: a basic comment is that if you draw a *single* shape with cairo 813 // that's bigger than 32k pixels in any dimension, it's unlikely to work 814 // [17:51] <owen> sven__: for the Xlib backend. this is a lot more fixable now 815 // that Cairo switched to 24.8 fixed point internally, but I don't think anybody 816 // has done the work to fix it 817 } else { 818 // calculate the neccessary width 819 // if clipping region exceeds lochstreifen width.... make it shorter, else let it. 820 double width = ( (l->clip->x + l->clip->width) > (LOCHSTREIFEN_LENGTH - LOCHSTREIFEN_TEAR_OFF_LENGTH) ) 821 ? ( LOCHSTREIFEN_LENGTH - LOCHSTREIFEN_TEAR_OFF_LENGTH - l->clip->x ) 822 : l->clip->width; 823 // don't have the clipping region paint in the tear off 824 // right, so crop it at the left. 825 if(l->clip->x < LOCHSTREIFEN_TEAR_OFF_LENGTH) 826 width -= LOCHSTREIFEN_TEAR_OFF_LENGTH; 827 cairo_rectangle(cr, 828 (l->clip->x >= LOCHSTREIFEN_TEAR_OFF_LENGTH) ? 829 l->clip->x : LOCHSTREIFEN_TEAR_OFF_LENGTH, 830 0, 831 width, 832 LOCHSTREIFEN_WIDTH); 833 } 834 cairo_fill(cr); 835 581 836 582 837 // tear-off at the end (0.5 of paper tape width) … … 587 842 cairo_line_to(cr, length-LOCHSTREIFEN_TEAR_OFF_LENGTH * 0.2, 0); 588 843 cairo_close_path(cr); 589 590 // paper tape background finished.591 844 cairo_fill(cr); 592 } 845 846 } // paper tape background finished. 593 847 594 848 // paint feed holes in the tear-off at the beginning … … 606 860 607 861 if(l->clip != NULL) { 608 // calculate clipping in dimension X (rows, bytes) 609 // calculation of first row to begin with. 610 row = floor ( 611 (l->clip->x - LOCHSTREIFEN_TEAR_OFF_LENGTH - LOCHSTREIFEN_ROW_DISTANCE / 2) 612 / LOCHSTREIFEN_ROW_DISTANCE 613 ); 614 615 // calculation of last row to end with. 616 row_max = floor( 617 (length - (l->clip->x + l->clip->width) - LOCHSTREIFEN_TEAR_OFF_LENGTH - LOCHSTREIFEN_ROW_DISTANCE/2) 618 / LOCHSTREIFEN_ROW_DISTANCE 619 ); 620 621 // calculate clipping in dimension Y (tracks, bits) 862 /* calculate clipping in dimension X (rows, bytes). 863 * Clipping in this dimension is very important, especially at very long 864 * papertapes. Application software (like GtkPaperTape) usually zooms the 865 * papertape, so it won't fit completely on the screen. So skipping bytes 866 * which are not displayed is very performant. 867 */ 868 if(l->clip->x < LOCHSTREIFEN_TEAR_OFF_LENGTH) { 869 // begin before tear off 870 row = 0; 871 row_max = floor( 872 ( l->clip->width - (l->clip->x - LOCHSTREIFEN_TEAR_OFF_LENGTH) ) 873 / LOCHSTREIFEN_ROW_DISTANCE 874 ); 875 } else { 876 // after tear off 877 row = floor ( 878 (l->clip->x - LOCHSTREIFEN_TEAR_OFF_LENGTH) / LOCHSTREIFEN_ROW_DISTANCE 879 ); 880 881 // end with just one more row as neccessary 882 row_max = row + 1 + ceil( 883 ( l->clip->width ) / LOCHSTREIFEN_ROW_DISTANCE 884 ); 885 } 886 887 // don't go over the data range 888 if(row_max > l->data_length) 889 row_max = l->data_length; 890 // dont' have row_max smaller than row 891 //if(row_max < row) 892 // row_max = row; 893 894 /* calculate clipping in dimension Y (tracks, bits) 895 * Y clipping is not as important, because there are only 9 circles 896 * to paint. The feed hole (which is painted just in the loop for the 897 * 3. track hole is not counted, therefore the calculations become somewhat 898 * inneccessary complex, compared to the painting overhead for the complete 899 * 8 tracks instead of e.g. only 6 tracks. Apart from that, application software 900 * usually doesn't clip the papertape this way, because users usually want to 901 * see a complete byte and not only a half byte. 902 */ 622 903 // calculation of first track to begin with. 623 track_min = floor( l->clip->y / LOCHSTREIFEN_TRACK_DISTANCE ); 904 /* 905 track_min = l->clip->y == 0 ? 0 : floor( l->clip->y / LOCHSTREIFEN_TRACK_DISTANCE ); 906 624 907 625 908 // calculation of last track to end with. 626 track_max = 8 - floor( 627 (LOCHSTREIFEN_WIDTH - (l->clip->y + l->clip->height)) 628 / LOCHSTREIFEN_TRACK_DISTANCE 629 ); 909 if(l->clip->y + l->clip->height > LOCHSTREIFEN_WIDTH) 910 track_max = 8; // clipping region is *much* bigger than the papertape width 911 else { 912 // just paint one more than neccessary 913 track_max = 1 + 8 - floor( 914 (LOCHSTREIFEN_WIDTH - (l->clip->y + l->clip->height)) 915 / LOCHSTREIFEN_TRACK_DISTANCE 916 ); 917 // dont't go over the track range 918 if(track_max > 8) 919 track_max = 8; 920 }*/ 921 track_min = 0; 922 track_max = 8; 630 923 } else { 631 924 // no clipping. Paint *everything*. … … 637 930 } 638 931 932 if(l->clip != NULL) { 933 double x,y,width,height; 934 x=l->clip->x; y=l->clip->y; width=l->clip->width; height=l->clip->height; 935 cairo_user_to_device(cr, &x, &y); 936 cairo_user_to_device_distance(cr, &width, &height); 937 printf("draw: %i|%i %ix%i ", (int)x, (int)y, (int)width, (int)height); 938 } else printf("draw: "); 939 printf("row %i->%i track %i->%i\n", row, row_max, track_min, track_max); 940 639 941 // loop all the rows (bytes) 640 942 // x start: tear off + one half row offset + offset rows * length of row 641 for(x=LOCHSTREIFEN_TEAR_OFF_LENGTH + LOCHSTREIFEN_TRACK_DISTANCE/2 + row*LOCHSTREIFEN_TRACK_DISTANCE; 642 row < row_max; row++, x += LOCHSTREIFEN_TRACK_DISTANCE) { 643 943 for(x=LOCHSTREIFEN_TEAR_OFF_LENGTH + LOCHSTREIFEN_ROW_DISTANCE/2 + row*LOCHSTREIFEN_ROW_DISTANCE; 944 row < row_max; row++, x += LOCHSTREIFEN_ROW_DISTANCE) { 945 946 // call row callback 947 if(l->row_callback != NULL) { 948 (*l->row_callback) (&row, cr, l->row_callback_user_data); 949 // at least now that's all the magic ;) 950 } 951 644 952 // highlight region? 645 if(l->highlight_region_color != NULL && 953 if(l->highlight_region_color != NULL && l->highlight_region_start != LOCHSTREIFEN_NO_ROW && 646 954 (row >= l->highlight_region_start || row < l->highlight_region_end) ) { 647 955 cairo_set_source(cr, l->highlight_region_color); … … 650 958 // Rechteck? Wuerde zu den Löchern passen. 651 959 // http://www.cairographics.org/cookbook/roundedrectangles/ 652 cairo_rectangle(cr, x - LOCHSTREIFEN_ TRACK_DISTANCE / 2, 0,960 cairo_rectangle(cr, x - LOCHSTREIFEN_ROW_DISTANCE / 2, 0, 653 961 LOCHSTREIFEN_TRACK_DISTANCE * (l->highlight_region_end - l->highlight_region_start), 654 962 LOCHSTREIFEN_WIDTH); … … 658 966 // highlight (only) this row? 659 967 if(l->highlight_row_color != NULL && row == l->highlight_row_number) { 968 // if check again LOCHSTREIFEN_NO_ROW not neccessary because row iterator never 969 // gets LOCHSTREIFEN_NO_ROW. 660 970 cairo_set_source(cr, l->highlight_row_color); 661 971 // genauso abgerundetes Rechteck wie bei der region 662 972 // überlegen. 663 cairo_rectangle(cr, x - LOCHSTREIFEN_ TRACK_DISTANCE/2, 0,973 cairo_rectangle(cr, x - LOCHSTREIFEN_ROW_DISTANCE/2, 0, 664 974 LOCHSTREIFEN_TRACK_DISTANCE, LOCHSTREIFEN_WIDTH); 665 975 cairo_fill(cr); … … 699 1009 if(l->highlight_bit_row == row && l->highlight_bit_track == track 700 1010 && l->highlight_bit_color != NULL) { 1011 // if check against l->highlight_bit_row == LOCHSTREIFEN_NO_ROW 1012 // not neccessary because row never gets LOCHSTREIFEN_NO_ROW. 1013 701 1014 // eigentlich wollen wir hier eine Umrahmung zeichnen, 702 1015 // damit der Zustand (0/1) nicht unsichtbar wird. Jetzt … … 705 1018 cairo_set_source(cr, l->highlight_bit_color); 706 1019 cairo_arc(cr, x, y, LOCHSTREIFEN_RADIUS_CODE_HOLE, 0., 2*M_PI); 1020 cairo_set_line_width(cr, 0.01); 707 1021 cairo_stroke(cr); // mal testen :-) 708 1022 } -
visualisator/lochstreifen.h
r18 r19 12 12 typedef struct lochstreifen LOCHSTREIFEN; 13 13 14 /** 15 * Identifing a track. 16 * This enum is used in various functions. 17 * Principally it's only sensefule for the 18 * LOCHSTREIFEN_NO_TRACK value. 19 **/ 20 typedef enum lochstreifen_track { 21 LOCHSTREIFEN_TRACK_0 = 0, 22 LOCHSTREIFEN_TRACK_1 = 1, 23 LOCHSTREIFEN_TRACK_2 = 2, 24 LOCHSTREIFEN_TRACK_FEED = -13, 25 LOCHSTREIFEN_TRACK_3 = 3, 26 LOCHSTREIFEN_TRACK_4 = 4, 27 LOCHSTREIFEN_TRACK_5 = 5, 28 LOCHSTREIFEN_TRACK_6 = 6, 29 LOCHSTREIFEN_TRACK_7 = 7, 30 LOCHSTREIFEN_NO_TRACK = -42 31 } track_t; 32 33 /** 34 * This typedef just says: This int represents a row in a LOCHSTREIFEN 35 * It's range should be >= 0 and <= the data_len member of the 36 * LOCHSTREIFEN structure. 37 * The MAX_INT value is therefore also the value of bytes which can be 38 * drawn: 4 GB. That's pretty much, because it all must be held in RAM ;-) 39 **/ 40 typedef int row_t; 41 42 /** 43 * The adequate to the lochstreifen_track enum value LOCHSTREIFEN_NO_TRACK. 44 * If a row_t == LOCHSTREIFEN_NO_ROW, it indicates that this 45 * is not a row at all. Of course you could also simply use check if 46 * row_t is < 0, but this is more meaningful. 47 **/ 48 #define LOCHSTREIFEN_NO_ROW -1 49 50 /** 51 * To be used as a return value, in comparision with 52 * LOCHSTREIFEN_NO_ROW and LOCHSTREIFEN_NO_TRACK: It indicates that 53 * everything successed. 54 **/ 55 #define LOCHSTREIFEN_SUCCESS (-42*42) 56 57 /** 58 * This is the LOCHSTREIFEN structure. It will always be referenced as a 59 * pointer, created by lochstreifen_new(). This function will also 60 * initialize the LOCHSTREIFEN structure. 61 * It's commonly referenced as "*l" or "l->", using "l" as abbrevation 62 * for LOCHSTREIFEN. 63 **/ 14 64 struct lochstreifen { 15 65 /* DATA (not supposed to be set directly) */ … … 27 77 28 78 /// Highlighting a (row/byte) region 29 int highlight_region_start; ///< counting from 0, already in selection30 int highlight_region_end; ///< counting from 0, no more in selection79 row_t highlight_region_start; ///< counting from 0, already in selection 80 row_t highlight_region_end; ///< counting from 0, no more in selection 31 81 cairo_pattern_t *highlight_region_color; ///< == NULL => no selection painted 32 82 33 83 /// Highlight one special row 34 int highlight_row_number; ///< counting from 084 row_t highlight_row_number; ///< counting from 0 35 85 cairo_pattern_t *highlight_row_color; 36 86 37 87 /// Highlight one special bit (not complete track) 38 int highlight_bit_row; ///< counting from 039 int highlight_bit_track; ///< counting from 088 row_t highlight_bit_row; 89 track_t highlight_bit_track; 40 90 cairo_pattern_t *highlight_bit_color; 41 91 … … 44 94 45 95 /// Matrix to apply for every paint process 46 cairo_matrix_t *matrix; 96 /// Call lochstreifen_check_matrix() after you have touched it. 97 cairo_matrix_t matrix; 98 99 /// Callback functions: 100 void (*row_callback) (const row_t* current_row, cairo_t* context, void* user_data); 101 void* row_callback_user_data; 102 //void (*bit_callback) 103 // etc. 47 104 48 105 /*<private>*/ … … 51 108 /// Make debug output if debug != 0. 52 109 byte_t debug; 110 111 /// Inverse CTM. Don't touch it, use 112 /// lochstreifen_check_matrix() instead to calculate it automatically 113 cairo_matrix_t matrix_inverse; 53 114 }; 54 115 … … 61 122 #define LOCHSTREIFEN_DEFAULT_HIGHLIGHT_REGION_COLOR cairo_pattern_create_rgb(0.95, 1, 0) 62 123 #define LOCHSTREIFEN_DEFAULT_HIGHLIGHT_ROW_COLOR cairo_pattern_create_rgb(1, 0, 0) 63 #define LOCHSTREIFEN_DEFAULT_HIGHLIGHT_BIT_COLOR cairo_pattern_create_rgb(0.4, 0.55, 0.7) 124 #define LOCHSTREIFEN_DEFAULT_HIGHLIGHT_BIT_COLOR cairo_pattern_create_rgb(1,1,1) 125 #define LOCHSTREIFEN_DEFAULT_CTM { 1, 0, 0, 1, 0, 0 } 64 126 65 127 /// dimensions of the paper tape after ECMA-10 standard … … 90 152 LOCHSTREIFEN_ROW_DISTANCE * (l->data_length + 1) ) 91 153 92 enum lochstreifen_direction {154 typedef enum lochstreifen_direction { 93 155 // special values for compatibility to old implementation 94 156 LOCHSTREIFEN_MOVEMENT_TO_LEFT = 0, … … 99 161 LOCHSTREIFEN_ROTATION_CLOCKWISE = 4, 100 162 LOCHSTREIFEN_ROTATION_ANTICLOCKWISE = 5 101 }; 163 } lochstreifen_direction_t; 164 165 166 102 167 103 168 104 169 // functions 105 170 LOCHSTREIFEN *lochstreifen_new(); 171 LOCHSTREIFEN* lochstreifen_copy(const LOCHSTREIFEN* t); 172 void lochstreifen_free(LOCHSTREIFEN* l); 106 173 void lochstreifen_print_debug(LOCHSTREIFEN* l); 107 174 void lochstreifen_set_data(LOCHSTREIFEN *l, int data_length, byte_t *data); … … 119 186 void lochstreifen_set_clip(LOCHSTREIFEN *l, double x, double y, double width, double height); 120 187 void lochstreifen_remove_clip(LOCHSTREIFEN *l); 188 void lochstreifen_check_matrix(LOCHSTREIFEN* l); 121 189 void lochstreifen_set_scaling_by_length(LOCHSTREIFEN *l, int length); 122 190 void lochstreifen_set_scaling_by_width(LOCHSTREIFEN *l, int width); … … 125 193 int lochstreifen_get_target_width(LOCHSTREIFEN *l); 126 194 int lochstreifen_get_target_height(LOCHSTREIFEN *l); 127 int lochstreifen_get_target_row_from_point(LOCHSTREIFEN* l, double x, double y); 195 void lochstreifen_get_target_bit_from_point(LOCHSTREIFEN* l, row_t* row, track_t* track, double x, double y); 196 row_t lochstreifen_get_target_row_from_point(LOCHSTREIFEN* l, double x, double y); 197 track_t lochstreifen_get_target_track_from_point(LOCHSTREIFEN* l, double x, double y); 198 int lochstreifen_get_target_rect_from_row(LOCHSTREIFEN* l, row_t row, cairo_rectangle_t* rect); 199 int lochstreifen_get_target_rect_from_bit(LOCHSTREIFEN* l, row_t row, track_t track, cairo_rectangle_t* rect); 128 200 void lochstreifen_set_rotation(LOCHSTREIFEN *l, enum lochstreifen_direction direction); 129 201 void lochstreifen_draw(LOCHSTREIFEN *l, cairo_t *cr);
Note: See TracChangeset
for help on using the changeset viewer.