⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xo-misc.c

📁 高手写的手写代码!欢迎大家下载,共同交流,如果有问题,请联系我!谢谢!
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef HAVE_CONFIG_H#  include <config.h>#endif#include <math.h>#include <string.h>#include <gtk/gtk.h>#include <libgnomecanvas/libgnomecanvas.h>#include <gdk/gdkkeysyms.h>#include "xournal.h"#include "xo-interface.h"#include "xo-support.h"#include "xo-callbacks.h"#include "xo-misc.h"#include "xo-file.h"#include "xo-paint.h"// some global constantsguint predef_colors_rgba[COLOR_MAX] =  { 0x000000ff, 0x3333ccff, 0xff0000ff, 0x008000ff,    0x808080ff, 0x00c0ffff, 0x00ff00ff, 0xff00ffff,    0xff8000ff, 0xffff00ff, 0xffffffff };guint predef_bgcolors_rgba[COLOR_MAX] = // meaningless ones set to white  { 0xffffffff, 0xa0e8ffff, 0xffc0d4ff, 0x80ffc0ff,    0xffffffff, 0xa0e8ffff, 0x80ffc0ff, 0xffc0d4ff,    0xffc080ff, 0xffff80ff, 0xffffffff };double predef_thickness[NUM_STROKE_TOOLS][THICKNESS_MAX] =  { { 0.42, 0.85, 1.41,  2.26, 5.67 }, // pen thicknesses = 0.15, 0.3, 0.5, 0.8, 2 mm    { 2.83, 2.83, 8.50, 19.84, 19.84 }, // eraser thicknesses = 1, 3, 7 mm    { 2.83, 2.83, 8.50, 19.84, 19.84 }, // highlighter thicknesses = 1, 3, 7 mm  };// some manipulation functionsstruct Page *new_page(struct Page *template){  struct Page *pg = (struct Page *) g_memdup(template, sizeof(struct Page));  struct Layer *l = g_new(struct Layer, 1);    l->items = NULL;  l->nitems = 0;  pg->layers = g_list_append(NULL, l);  pg->nlayers = 1;  pg->bg = (struct Background *)g_memdup(template->bg, sizeof(struct Background));  pg->bg->canvas_item = NULL;  if (pg->bg->type == BG_PIXMAP || pg->bg->type == BG_PDF) {    gdk_pixbuf_ref(pg->bg->pixbuf);    refstring_ref(pg->bg->filename);  }  pg->group = (GnomeCanvasGroup *) gnome_canvas_item_new(      gnome_canvas_root(canvas), gnome_canvas_clipgroup_get_type(), NULL);  make_page_clipbox(pg);  update_canvas_bg(pg);  l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(      pg->group, gnome_canvas_group_get_type(), NULL);    return pg;}/* Create a page from a background.    Note: bg should be an UNREFERENCED background.   If needed, first duplicate it and increase the refcount of the pixbuf.*/struct Page *new_page_with_bg(struct Background *bg, double width, double height){  struct Page *pg = g_new(struct Page, 1);  struct Layer *l = g_new(struct Layer, 1);    l->items = NULL;  l->nitems = 0;  pg->layers = g_list_append(NULL, l);  pg->nlayers = 1;  pg->bg = bg;  pg->bg->canvas_item = NULL;  pg->height = height;  pg->width = width;  pg->group = (GnomeCanvasGroup *) gnome_canvas_item_new(      gnome_canvas_root(canvas), gnome_canvas_clipgroup_get_type(), NULL);  make_page_clipbox(pg);  update_canvas_bg(pg);  l->group = (GnomeCanvasGroup *) gnome_canvas_item_new(      pg->group, gnome_canvas_group_get_type(), NULL);    return pg;}void realloc_cur_path(int n){  if (n <= ui.cur_path_storage_alloc) return;  ui.cur_path_storage_alloc = n+10;  ui.cur_path.coords = g_realloc(ui.cur_path.coords, 2*(n+10)*sizeof(double));}// undo utility functionsvoid prepare_new_undo(void){  struct UndoItem *u;  // add a new UndoItem on the stack    u = (struct UndoItem *)g_malloc(sizeof(struct UndoItem));  u->next = undo;  u->multiop = 0;  undo = u;  ui.saved = FALSE;  clear_redo_stack();}void clear_redo_stack(void){  struct UndoItem *u;    GList *list, *repl;  struct UndoErasureData *erasure;  struct Item *it;  /* Warning: the redo items might reference items from past redo entries,     which have been destroyed before them. Be careful! As a rule, it's     safe to destroy data which has been created at the current history step,     it's unsafe to refer to any data from previous history steps */    while (redo!=NULL) {    if (redo->type == ITEM_STROKE) {      gnome_canvas_points_free(redo->item->path);      g_free(redo->item);      /* the strokes are unmapped, so there are no associated canvas items */    }    else if (redo->type == ITEM_TEXT) {      g_free(redo->item->text);      g_free(redo->item->font_name);      g_free(redo->item);    }    else if (redo->type == ITEM_ERASURE) {      for (list = redo->erasurelist; list!=NULL; list=list->next) {        erasure = (struct UndoErasureData *)list->data;        for (repl = erasure->replacement_items; repl!=NULL; repl=repl->next) {          it = (struct Item *)repl->data;          gnome_canvas_points_free(it->path);          g_free(it);        }        g_list_free(erasure->replacement_items);        g_free(erasure);      }      g_list_free(redo->erasurelist);    }    else if (redo->type == ITEM_NEW_BG_ONE || redo->type == ITEM_NEW_BG_RESIZE          || redo->type == ITEM_NEW_DEFAULT_BG) {      if (redo->bg->type == BG_PIXMAP || redo->bg->type == BG_PDF) {        if (redo->bg->pixbuf!=NULL) gdk_pixbuf_unref(redo->bg->pixbuf);        refstring_unref(redo->bg->filename);      }      g_free(redo->bg);    }    else if (redo->type == ITEM_NEW_PAGE) {      redo->page->group = NULL;      delete_page(redo->page);    }    else if (redo->type == ITEM_MOVESEL || redo->type == ITEM_REPAINTSEL) {      g_list_free(redo->itemlist); g_list_free(redo->auxlist);    }    else if (redo->type == ITEM_PASTE) {      for (list = redo->itemlist; list!=NULL; list=list->next) {        it = (struct Item *)list->data;        if (it->type == ITEM_STROKE) gnome_canvas_points_free(it->path);        g_free(it);      }      g_list_free(redo->itemlist);    }    else if (redo->type == ITEM_NEW_LAYER) {      g_free(redo->layer);    }    else if (redo->type == ITEM_TEXT_EDIT || redo->type == ITEM_TEXT_ATTRIB) {      g_free(redo->str);      if (redo->type == ITEM_TEXT_ATTRIB) g_free(redo->brush);    }    u = redo;    redo = redo->next;    g_free(u);  }  update_undo_redo_enabled();}void clear_undo_stack(void){  struct UndoItem *u;  GList *list;  struct UndoErasureData *erasure;    while (undo!=NULL) {    // for strokes, items are already in the journal, so we don't free them    // for erasures, we need to free the dead items    if (undo->type == ITEM_ERASURE) {      for (list = undo->erasurelist; list!=NULL; list=list->next) {        erasure = (struct UndoErasureData *)list->data;        if (erasure->item->type == ITEM_STROKE)          gnome_canvas_points_free(erasure->item->path);        if (erasure->item->type == ITEM_TEXT)          { g_free(erasure->item->text); g_free(erasure->item->font_name); }        g_free(erasure->item);        g_list_free(erasure->replacement_items);        g_free(erasure);      }      g_list_free(undo->erasurelist);    }    else if (undo->type == ITEM_NEW_BG_ONE || undo->type == ITEM_NEW_BG_RESIZE          || undo->type == ITEM_NEW_DEFAULT_BG) {      if (undo->bg->type == BG_PIXMAP || undo->bg->type == BG_PDF) {        if (undo->bg->pixbuf!=NULL) gdk_pixbuf_unref(undo->bg->pixbuf);        refstring_unref(undo->bg->filename);      }      g_free(undo->bg);    }    else if (undo->type == ITEM_MOVESEL || undo->type == ITEM_REPAINTSEL) {      g_list_free(undo->itemlist); g_list_free(undo->auxlist);    }    else if (undo->type == ITEM_PASTE) {      g_list_free(undo->itemlist);    }    else if (undo->type == ITEM_DELETE_LAYER) {      undo->layer->group = NULL;      delete_layer(undo->layer);    }    else if (undo->type == ITEM_DELETE_PAGE) {      undo->page->group = NULL;      delete_page(undo->page);    }    else if (undo->type == ITEM_TEXT_EDIT || undo->type == ITEM_TEXT_ATTRIB) {      g_free(undo->str);      if (undo->type == ITEM_TEXT_ATTRIB) g_free(undo->brush);    }    u = undo;    undo = undo->next;    g_free(u);  }  update_undo_redo_enabled();}// free data structures void delete_journal(struct Journal *j){  while (j->pages!=NULL) {    delete_page((struct Page *)j->pages->data);    j->pages = g_list_delete_link(j->pages, j->pages);  }}void delete_page(struct Page *pg){  struct Layer *l;    while (pg->layers!=NULL) {    l = (struct Layer *)pg->layers->data;    l->group = NULL;    delete_layer(l);    pg->layers = g_list_delete_link(pg->layers, pg->layers);  }  if (pg->group!=NULL) gtk_object_destroy(GTK_OBJECT(pg->group));              // this also destroys the background's canvas items  if (pg->bg->type == BG_PIXMAP || pg->bg->type == BG_PDF) {    if (pg->bg->pixbuf != NULL) gdk_pixbuf_unref(pg->bg->pixbuf);    if (pg->bg->filename != NULL) refstring_unref(pg->bg->filename);  }  g_free(pg->bg);  g_free(pg);}void delete_layer(struct Layer *l){  struct Item *item;    while (l->items!=NULL) {    item = (struct Item *)l->items->data;    if (item->type == ITEM_STROKE && item->path != NULL)       gnome_canvas_points_free(item->path);    if (item->type == ITEM_TEXT) {      g_free(item->font_name); g_free(item->text);    }    // don't need to delete the canvas_item, as it's part of the group destroyed below    g_free(item);    l->items = g_list_delete_link(l->items, l->items);  }  if (l->group!= NULL) gtk_object_destroy(GTK_OBJECT(l->group));  g_free(l);}// referenced stringsstruct Refstring *new_refstring(const char *s){  struct Refstring *rs = g_new(struct Refstring, 1);  rs->nref = 1;  if (s!=NULL) rs->s = g_strdup(s);  else rs->s = NULL;  rs->aux = NULL;  return rs;}struct Refstring *refstring_ref(struct Refstring *rs){  rs->nref++;  return rs;}void refstring_unref(struct Refstring *rs){  rs->nref--;  if (rs->nref == 0) {    if (rs->s!=NULL) g_free(rs->s);    if (rs->aux!=NULL) g_free(rs->aux);    g_free(rs);  }}// some helper functionsvoid get_pointer_coords(GdkEvent *event, gdouble *ret){  double x, y;  gdk_event_get_coords(event, &x, &y);  gnome_canvas_window_to_world(canvas, x, y, ret, ret+1);  ret[0] -= ui.cur_page->hoffset;  ret[1] -= ui.cur_page->voffset;}void fix_xinput_coords(GdkEvent *event){#ifdef ENABLE_XINPUT_BUGFIX  double *axes, *px, *py, axis_width;  GdkDevice *device;  int wx, wy, sx, sy;  if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) {    axes = event->button.axes;    px = &(event->button.x);    py = &(event->button.y);    device = event->button.device;  }  else if (event->type == GDK_MOTION_NOTIFY) {    axes = event->motion.axes;    px = &(event->motion.x);    py = &(event->motion.y);    device = event->motion.device;  }  else return; // nothing we know how to do    gdk_window_get_origin(event->any.window, &wx, &wy);  // somehow, behavior changed starting with GTK+ 2.11.0  if (!gtk_check_version(2, 11, 0)) sx = sy = 0;  else gnome_canvas_get_scroll_offsets(canvas, &sx, &sy);    axis_width = device->axes[0].max - device->axes[0].min;  if (axis_width>EPSILON)    *px = (axes[0]/axis_width)*ui.screen_width + sx - wx;  axis_width = device->axes[1].max - device->axes[1].min;  if (axis_width>EPSILON)    *py = (axes[1]/axis_width)*ui.screen_height + sy - wy;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -