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

📄 xo-file.c

📁 高手写的手写代码!欢迎大家下载,共同交流,如果有问题,请联系我!谢谢!
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef HAVE_CONFIG_H#  include <config.h>#endif#include <signal.h>#include <memory.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <gtk/gtk.h>#include <libgnomecanvas/libgnomecanvas.h>#include <zlib.h>#include <math.h>#include <gdk/gdkx.h>#include <X11/Xlib.h>#include <locale.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"const char *tool_names[NUM_TOOLS] = {"pen", "eraser", "highlighter", "text", "", "selectrect", "vertspace", "hand"};const char *color_names[COLOR_MAX] = {"black", "blue", "red", "green",   "gray", "lightblue", "lightgreen", "magenta", "orange", "yellow", "white"};const char *bgtype_names[3] = {"solid", "pixmap", "pdf"};const char *bgcolor_names[COLOR_MAX] = {"", "blue", "pink", "green",   "", "", "", "", "orange", "yellow", "white"};const char *bgstyle_names[4] = {"plain", "lined", "ruled", "graph"};const char *file_domain_names[3] = {"absolute", "attach", "clone"};const char *unit_names[4] = {"cm", "in", "px", "pt"};int PDFTOPPM_PRINTING_DPI, GS_BITMAP_DPI;// creates a new empty journalvoid new_journal(void){  journal.npages = 1;  journal.pages = g_list_append(NULL, new_page(&ui.default_page));  journal.last_attach_no = 0;  ui.pageno = 0;  ui.layerno = 0;  ui.cur_page = (struct Page *) journal.pages->data;  ui.cur_layer = (struct Layer *) ui.cur_page->layers->data;  ui.saved = TRUE;  ui.filename = NULL;  update_file_name(NULL);}// check attachment namesvoid chk_attach_names(void){  GList *list;  struct Background *bg;    for (list = journal.pages; list!=NULL; list = list->next) {    bg = ((struct Page *)list->data)->bg;    if (bg->type == BG_SOLID || bg->file_domain != DOMAIN_ATTACH ||        bg->filename->s != NULL) continue;    bg->filename->s = g_strdup_printf("bg_%d.png", ++journal.last_attach_no);  }}// saves the journal to a file: returns true on success, false on errorgboolean save_journal(const char *filename){  gzFile f;  struct Page *pg, *tmppg;  struct Layer *layer;  struct Item *item;  int i, is_clone;  char *tmpfn, *tmpstr;  gchar *pdfbuf;  gsize pdflen;  gboolean success;  FILE *tmpf;  GList *pagelist, *layerlist, *itemlist, *list;  GtkWidget *dialog;    f = gzopen(filename, "w");  if (f==NULL) return FALSE;  chk_attach_names();  setlocale(LC_NUMERIC, "C");    gzprintf(f, "<?xml version=\"1.0\" standalone=\"no\"?>\n"     "<xournal version=\"" VERSION "\">\n"     "<title>Xournal document - see http://math.mit.edu/~auroux/software/xournal/</title>\n");  for (pagelist = journal.pages; pagelist!=NULL; pagelist = pagelist->next) {    pg = (struct Page *)pagelist->data;    gzprintf(f, "<page width=\"%.2f\" height=\"%.2f\">\n", pg->width, pg->height);    gzprintf(f, "<background type=\"%s\" ", bgtype_names[pg->bg->type]);     if (pg->bg->type == BG_SOLID) {      gzputs(f, "color=\"");      if (pg->bg->color_no >= 0) gzputs(f, bgcolor_names[pg->bg->color_no]);      else gzprintf(f, "#%08x", pg->bg->color_rgba);      gzprintf(f, "\" style=\"%s\" ", bgstyle_names[pg->bg->ruling]);    }    else if (pg->bg->type == BG_PIXMAP) {      is_clone = -1;      for (list = journal.pages, i = 0; list!=pagelist; list = list->next, i++) {        tmppg = (struct Page *)list->data;        if (tmppg->bg->type == BG_PIXMAP &&             tmppg->bg->pixbuf == pg->bg->pixbuf &&            tmppg->bg->filename == pg->bg->filename)          { is_clone = i; break; }      }      if (is_clone >= 0)        gzprintf(f, "domain=\"clone\" filename=\"%d\" ", is_clone);      else {        if (pg->bg->file_domain == DOMAIN_ATTACH) {          tmpfn = g_strdup_printf("%s.%s", filename, pg->bg->filename->s);          if (!gdk_pixbuf_save(pg->bg->pixbuf, tmpfn, "png", NULL, NULL)) {            dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,              GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,               "Could not write background '%s'. Continuing anyway.", tmpfn);            gtk_dialog_run(GTK_DIALOG(dialog));            gtk_widget_destroy(dialog);          }          g_free(tmpfn);        }        gzprintf(f, "domain=\"%s\" filename=\"%s\" ",           file_domain_names[pg->bg->file_domain], pg->bg->filename->s);      }    }    else if (pg->bg->type == BG_PDF) {      is_clone = 0;      for (list = journal.pages; list!=pagelist; list = list->next) {        tmppg = (struct Page *)list->data;        if (tmppg->bg->type == BG_PDF) { is_clone = 1; break; }      }      if (!is_clone) {        if (pg->bg->file_domain == DOMAIN_ATTACH) {          tmpfn = g_strdup_printf("%s.%s", filename, pg->bg->filename->s);          success = FALSE;          if (bgpdf.status != STATUS_NOT_INIT &&              g_file_get_contents(bgpdf.tmpfile_copy, &pdfbuf, &pdflen, NULL))          {            tmpf = fopen(tmpfn, "w");            if (tmpf != NULL && fwrite(pdfbuf, 1, pdflen, tmpf) == pdflen)              success = TRUE;            g_free(pdfbuf);            fclose(tmpf);          }          if (!success) {            dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,              GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,               "Could not write background '%s'. Continuing anyway.", tmpfn);            gtk_dialog_run(GTK_DIALOG(dialog));            gtk_widget_destroy(dialog);          }          g_free(tmpfn);        }        gzprintf(f, "domain=\"%s\" filename=\"%s\" ",           file_domain_names[pg->bg->file_domain], pg->bg->filename->s);      }      gzprintf(f, "pageno=\"%d\" ", pg->bg->file_page_seq);    }    gzprintf(f, "/>\n");    for (layerlist = pg->layers; layerlist!=NULL; layerlist = layerlist->next) {      layer = (struct Layer *)layerlist->data;      gzprintf(f, "<layer>\n");      for (itemlist = layer->items; itemlist!=NULL; itemlist = itemlist->next) {        item = (struct Item *)itemlist->data;        if (item->type == ITEM_STROKE) {          gzprintf(f, "<stroke tool=\"%s\" color=\"",                           tool_names[item->brush.tool_type]);          if (item->brush.color_no >= 0)            gzputs(f, color_names[item->brush.color_no]);          else            gzprintf(f, "#%08x", item->brush.color_rgba);          gzprintf(f, "\" width=\"%.2f\">\n", item->brush.thickness);          for (i=0;i<2*item->path->num_points;i++)            gzprintf(f, "%.2f ", item->path->coords[i]);          gzprintf(f, "\n</stroke>\n");        }        if (item->type == ITEM_TEXT) {          gzprintf(f, "<text font=\"%s\" size=\"%.2f\" x=\"%.2f\" y=\"%.2f\" color=\"",            item->font_name, item->font_size, item->bbox.left, item->bbox.top);          if (item->brush.color_no >= 0)            gzputs(f, color_names[item->brush.color_no]);          else            gzprintf(f, "#%08x", item->brush.color_rgba);          tmpstr = g_markup_escape_text(item->text, -1);          gzprintf(f, "\">%s</text>\n", tmpstr);          g_free(tmpstr);                  }      }      gzprintf(f, "</layer>\n");    }    gzprintf(f, "</page>\n");  }  gzprintf(f, "</xournal>\n");  gzclose(f);  setlocale(LC_NUMERIC, "");  return TRUE;}// closes a journal: returns true on success, false on abortgboolean close_journal(void){  if (!ok_to_close()) return FALSE;    // free everything...  reset_selection();  clear_redo_stack();  clear_undo_stack();  shutdown_bgpdf();  delete_journal(&journal);    return TRUE;  /* note: various members of ui and journal are now in invalid states,     use new_journal() to reinitialize them */}// sanitize a string containing floats, in case it may have , instead of .void cleanup_numeric(char *s){  while (*s!=0) { if (*s==',') *s='.'; s++; }}// the XML parser functions for open_journal()struct Journal tmpJournal;struct Page *tmpPage;struct Layer *tmpLayer;struct Item *tmpItem;char *tmpFilename;struct Background *tmpBg_pdf;GError *xoj_invalid(void){  return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Invalid file contents");}void xoj_parser_start_element(GMarkupParseContext *context,   const gchar *element_name, const gchar **attribute_names,    const gchar **attribute_values, gpointer user_data, GError **error){  int has_attr, i;  char *ptr;  struct Background *tmpbg;  char *tmpbg_filename;  GtkWidget *dialog;    if (!strcmp(element_name, "title") || !strcmp(element_name, "xournal")) {    if (tmpPage != NULL) {      *error = xoj_invalid();      return;    }    // nothing special to do  }  else if (!strcmp(element_name, "page")) { // start of a page    if (tmpPage != NULL) {      *error = xoj_invalid();      return;    }    tmpPage = (struct Page *)g_malloc(sizeof(struct Page));    tmpPage->layers = NULL;    tmpPage->nlayers = 0;    tmpPage->group = NULL;    tmpPage->bg = g_new(struct Background, 1);    tmpPage->bg->type = -1;    tmpPage->bg->canvas_item = NULL;    tmpPage->bg->pixbuf = NULL;    tmpPage->bg->filename = NULL;    tmpJournal.pages = g_list_append(tmpJournal.pages, tmpPage);    tmpJournal.npages++;    // scan for height and width attributes    has_attr = 0;    while (*attribute_names!=NULL) {      if (!strcmp(*attribute_names, "width")) {        if (has_attr & 1) *error = xoj_invalid();        cleanup_numeric((gchar *)*attribute_values);        tmpPage->width = g_ascii_strtod(*attribute_values, &ptr);        if (ptr == *attribute_values) *error = xoj_invalid();        has_attr |= 1;      }      else if (!strcmp(*attribute_names, "height")) {        if (has_attr & 2) *error = xoj_invalid();        cleanup_numeric((gchar *)*attribute_values);        tmpPage->height = g_ascii_strtod(*attribute_values, &ptr);        if (ptr == *attribute_values) *error = xoj_invalid();        has_attr |= 2;      }      else *error = xoj_invalid();      attribute_names++;      attribute_values++;    }    if (has_attr!=3) *error = xoj_invalid();  }  else if (!strcmp(element_name, "background")) {    if (tmpPage == NULL || tmpLayer !=NULL || tmpPage->bg->type >= 0) {      *error = xoj_invalid();      return;    }    has_attr = 0;    while (*attribute_names!=NULL) {      if (!strcmp(*attribute_names, "type")) {        if (has_attr) *error = xoj_invalid();        for (i=0; i<3; i++)          if (!strcmp(*attribute_values, bgtype_names[i]))            tmpPage->bg->type = i;        if (tmpPage->bg->type < 0) *error = xoj_invalid();        has_attr |= 1;        if (tmpPage->bg->type == BG_PDF) {          if (tmpBg_pdf == NULL) tmpBg_pdf = tmpPage->bg;          else {            has_attr |= 24;            tmpPage->bg->filename = refstring_ref(tmpBg_pdf->filename);            tmpPage->bg->file_domain = tmpBg_pdf->file_domain;          }        }      }      else if (!strcmp(*attribute_names, "color")) {        if (tmpPage->bg->type != BG_SOLID) *error = xoj_invalid();        if (has_attr & 2) *error = xoj_invalid();        tmpPage->bg->color_no = COLOR_OTHER;        for (i=0; i<COLOR_MAX; i++)          if (!strcmp(*attribute_values, bgcolor_names[i])) {            tmpPage->bg->color_no = i;            tmpPage->bg->color_rgba = predef_bgcolors_rgba[i];          }        // there's also the case of hex (#rrggbbaa) colors        if (tmpPage->bg->color_no == COLOR_OTHER && **attribute_values == '#') {          tmpPage->bg->color_rgba = strtol(*attribute_values + 1, &ptr, 16);          if (*ptr!=0) *error = xoj_invalid();        }        has_attr |= 2;      }      else if (!strcmp(*attribute_names, "style")) {        if (tmpPage->bg->type != BG_SOLID) *error = xoj_invalid();        if (has_attr & 4) *error = xoj_invalid();        tmpPage->bg->ruling = -1;        for (i=0; i<4; i++)          if (!strcmp(*attribute_values, bgstyle_names[i]))            tmpPage->bg->ruling = i;        if (tmpPage->bg->ruling < 0) *error = xoj_invalid();        has_attr |= 4;      }      else if (!strcmp(*attribute_names, "domain")) {        if (tmpPage->bg->type <= BG_SOLID || (has_attr & 8))          { *error = xoj_invalid(); return; }        tmpPage->bg->file_domain = -1;        for (i=0; i<3; i++)          if (!strcmp(*attribute_values, file_domain_names[i]))            tmpPage->bg->file_domain = i;        if (tmpPage->bg->file_domain < 0)          { *error = xoj_invalid(); return; }        has_attr |= 8;      }      else if (!strcmp(*attribute_names, "filename")) {        if (tmpPage->bg->type <= BG_SOLID || (has_attr != 9))           { *error = xoj_invalid(); return; }        if (tmpPage->bg->file_domain == DOMAIN_CLONE) {          // filename is a page number          i = strtol(*attribute_values, &ptr, 10);          if (ptr == *attribute_values || i < 0 || i > tmpJournal.npages-2)

⌨️ 快捷键说明

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