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

📄 xo-print.c

📁 高手写的手写代码!欢迎大家下载,共同交流,如果有问题,请联系我!谢谢!
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifdef HAVE_CONFIG_H#  include <config.h>#endif#define PANGO_ENABLE_BACKEND /* to access PangoFcFont.font_pattern */#include <gtk/gtk.h>#include <libgnomecanvas/libgnomecanvas.h>#include <libgnomeprint/gnome-print-job.h>#include <libgnomeprint/gnome-print-pango.h>#include <zlib.h>#include <string.h>#include <locale.h>#include <pango/pango.h>#include <pango/pangofc-font.h>#include <fontconfig/fontconfig.h>#include <ft2build.h>#include FT_FREETYPE_H#include "sft.h" /* Sun Font Tools, embedded in libgnomeprint */#include "xournal.h"#include "xo-misc.h"#include "xo-paint.h"#include "xo-print.h"#include "xo-file.h"#define RGBA_RED(rgba) (((rgba>>24)&0xff)/255.0)#define RGBA_GREEN(rgba) (((rgba>>16)&0xff)/255.0)#define RGBA_BLUE(rgba) (((rgba>>8)&0xff)/255.0)#define RGBA_ALPHA(rgba) (((rgba>>0)&0xff)/255.0)#define RGBA_RGB(rgba) RGBA_RED(rgba), RGBA_GREEN(rgba), RGBA_BLUE(rgba)/*********** Printing to PDF ************/gboolean ispdfspace(char c){  return (c==0 || c==9 || c==10 || c==12 || c==13 || c==' ');}gboolean ispdfdelim(char c){  return (c=='(' || c==')' || c=='<' || c=='>' || c=='[' || c==']' ||          c=='{' || c=='}' || c=='/' || c=='%');}void skipspace(char **p, char *eof){  while (ispdfspace(**p) || **p=='%') {    if (**p=='%') while (*p!=eof && **p!=10 && **p!=13) (*p)++;    if (*p==eof) return;    (*p)++;  }}void free_pdfobj(struct PdfObj *obj){  int i;    if (obj==NULL) return;  if ((obj->type == PDFTYPE_STRING || obj->type == PDFTYPE_NAME ||      obj->type == PDFTYPE_STREAM) && obj->str!=NULL)    g_free(obj->str);  if ((obj->type == PDFTYPE_ARRAY || obj->type == PDFTYPE_DICT ||      obj->type == PDFTYPE_STREAM) && obj->num>0) {    for (i=0; i<obj->num; i++)      free_pdfobj(obj->elts[i]);    g_free(obj->elts);  }  if ((obj->type == PDFTYPE_DICT || obj->type == PDFTYPE_STREAM) && obj->num>0) {    for (i=0; i<obj->num; i++)      g_free(obj->names[i]);    g_free(obj->names);  }  g_free(obj);}struct PdfObj *dup_pdfobj(struct PdfObj *obj){  struct PdfObj *dup;  int i;    if (obj==NULL) return NULL;  dup = g_memdup(obj, sizeof(struct PdfObj));  if ((obj->type == PDFTYPE_STRING || obj->type == PDFTYPE_NAME ||      obj->type == PDFTYPE_STREAM) && obj->str!=NULL) {    if (obj->type == PDFTYPE_NAME) obj->len = strlen(obj->str);    dup->str = g_memdup(obj->str, obj->len+1);  }  if ((obj->type == PDFTYPE_ARRAY || obj->type == PDFTYPE_DICT ||      obj->type == PDFTYPE_STREAM) && obj->num>0) {    dup->elts = g_malloc(obj->num*sizeof(struct PdfObj *));    for (i=0; i<obj->num; i++)      dup->elts[i] = dup_pdfobj(obj->elts[i]);  }  if ((obj->type == PDFTYPE_DICT || obj->type == PDFTYPE_STREAM) && obj->num>0) {    dup->names = g_malloc(obj->num*sizeof(char *));    for (i=0; i<obj->num; i++)      dup->names[i] = g_strdup(obj->names[i]);  }  return dup;}void show_pdfobj(struct PdfObj *obj, GString *str){  int i;  if (obj==NULL) return;  switch(obj->type) {    case PDFTYPE_CST:      if (obj->intval==1) g_string_append(str, "true");      if (obj->intval==0) g_string_append(str, "false");      if (obj->intval==-1) g_string_append(str, "null");      break;    case PDFTYPE_INT:      g_string_append_printf(str, "%d", obj->intval);      break;    case PDFTYPE_REAL:      g_string_append_printf(str, "%f", obj->realval);      break;    case PDFTYPE_STRING:      g_string_append_len(str, obj->str, obj->len);      break;    case PDFTYPE_NAME:      g_string_append(str, obj->str);      break;    case PDFTYPE_ARRAY:      g_string_append_c(str, '[');      for (i=0;i<obj->num;i++) {        if (i) g_string_append_c(str, ' ');        show_pdfobj(obj->elts[i], str);      }      g_string_append_c(str, ']');      break;    case PDFTYPE_DICT:      g_string_append(str, "<<");      for (i=0;i<obj->num;i++) {        g_string_append_printf(str, " %s ", obj->names[i]);         show_pdfobj(obj->elts[i], str);      }      g_string_append(str, " >>");      break;    case PDFTYPE_REF:      g_string_append_printf(str, "%d %d R", obj->intval, obj->num);      break;  }}void DEBUG_PRINTOBJ(struct PdfObj *obj){  GString *s = g_string_new("");  show_pdfobj(obj, s);  puts(s->str);  g_string_free(s, TRUE);}// parse a PDF object; returns NULL if fails// THIS PARSER DOES NOT RECOGNIZE STREAMS YETstruct PdfObj *parse_pdf_object(char **ptr, char *eof){  struct PdfObj *obj, *elt;  char *p, *q, *r, *eltname;  int stack;  obj = g_malloc(sizeof(struct PdfObj));  p = *ptr;  skipspace(&p, eof);  if (p==eof) { g_free(obj); return NULL; }    // maybe a constant  if (!strncmp(p, "true", 4)) {    obj->type = PDFTYPE_CST;    obj->intval = 1;    *ptr = p+4;    return obj;  }  if (!strncmp(p, "false", 5)) {    obj->type = PDFTYPE_CST;    obj->intval = 0;    *ptr = p+5;    return obj;  }  if (!strncmp(p, "null", 4)) {    obj->type = PDFTYPE_CST;    obj->intval = -1;    *ptr = p+4;    return obj;  }  // or a number ?  obj->intval = strtol(p, &q, 10);  *ptr = q;  if (q!=p) {    if (*q == '.') {      obj->type = PDFTYPE_REAL;      obj->realval = g_ascii_strtod(p, ptr);      return obj;    }    if (ispdfspace(*q)) {      // check for indirect reference      skipspace(&q, eof);      obj->num = strtol(q, &r, 10);      if (r!=q) {        skipspace(&r, eof);        if (*r=='R') {          *ptr = r+1;          obj->type = PDFTYPE_REF;          return obj;        }      }    }    obj->type = PDFTYPE_INT;    return obj;  }  // a string ?  if (*p=='(') {    q=p+1; stack=1;    while (stack>0 && q!=eof) {      if (*q=='(') stack++;      if (*q==')') stack--;      if (*q=='\\') q++;      if (q!=eof) q++;    }    if (q==eof) { g_free(obj); return NULL; }    obj->type = PDFTYPE_STRING;    obj->len = q-p;    obj->str = g_malloc(obj->len+1);    obj->str[obj->len] = 0;    g_memmove(obj->str, p, obj->len);    *ptr = q;    return obj;  }    if (*p=='<' && p[1]!='<') {    q=p+1;    while (*q!='>' && q!=eof) q++;    if (q==eof) { g_free(obj); return NULL; }    q++;    obj->type = PDFTYPE_STRING;    obj->len = q-p;    obj->str = g_malloc(obj->len+1);    obj->str[obj->len] = 0;    g_memmove(obj->str, p, obj->len);    *ptr = q;    return obj;  }    // a name ?  if (*p=='/') {    q=p+1;    while (!ispdfspace(*q) && !ispdfdelim(*q)) q++;    obj->type = PDFTYPE_NAME;    obj->str = g_strndup(p, q-p);    *ptr = q;    return obj;  }  // an array ?  if (*p=='[') {    obj->type = PDFTYPE_ARRAY;    obj->num = 0;    obj->elts = NULL;    q=p+1; skipspace(&q, eof);    while (*q!=']') {      elt = parse_pdf_object(&q, eof);      if (elt==NULL) { free_pdfobj(obj); return NULL; }      obj->num++;      obj->elts = g_realloc(obj->elts, obj->num*sizeof(struct PdfObj *));      obj->elts[obj->num-1] = elt;      skipspace(&q, eof);    }    *ptr = q+1;    return obj;  }  // a dictionary ?  if (*p=='<' && p[1]=='<') {    obj->type = PDFTYPE_DICT;    obj->num = 0;    obj->elts = NULL;    obj->names = NULL;    q=p+2; skipspace(&q, eof);    while (*q!='>' || q[1]!='>') {      if (*q!='/') { free_pdfobj(obj); return NULL; }      r=q+1;      while (!ispdfspace(*r) && !ispdfdelim(*r)) r++;      eltname = g_strndup(q, r-q);      q=r; skipspace(&q, eof);      elt = parse_pdf_object(&q, eof);      if (elt==NULL) { g_free(eltname); free_pdfobj(obj); return NULL; }      obj->num++;      obj->elts = g_realloc(obj->elts, obj->num*sizeof(struct PdfObj *));      obj->names = g_realloc(obj->names, obj->num*sizeof(char *));      obj->elts[obj->num-1] = elt;      obj->names[obj->num-1] = eltname;      skipspace(&q, eof);    }    *ptr = q+2;    return obj;  }  // DOES NOT RECOGNIZE STREAMS YET (handle as subcase of dictionary)    g_free(obj);  return NULL;}struct PdfObj *get_dict_entry(struct PdfObj *dict, char *name){  int i;    if (dict==NULL) return NULL;  if (dict->type != PDFTYPE_DICT) return NULL;  for (i=0; i<dict->num; i++)     if (!strcmp(dict->names[i], name)) return dict->elts[i];  return NULL;}struct PdfObj *get_pdfobj(GString *pdfbuf, struct XrefTable *xref, struct PdfObj *obj){  char *p, *eof;  int offs, n;  if (obj==NULL) return NULL;  if (obj->type!=PDFTYPE_REF) return dup_pdfobj(obj);  if (obj->intval>xref->last) return NULL;  offs = xref->data[obj->intval];  if (offs<=0 || offs >= pdfbuf->len) return NULL;  p = pdfbuf->str + offs;  eof = pdfbuf->str + pdfbuf->len;  n = strtol(p, &p, 10);  if (n!=obj->intval) return NULL;  skipspace(&p, eof);  n = strtol(p, &p, 10);  skipspace(&p, eof);  if (strncmp(p, "obj", 3)) return NULL;  p+=3;  return parse_pdf_object(&p, eof);}// read the xref table of a PDF file in memory, and return the trailerdictstruct PdfObj *parse_xref_table(GString *pdfbuf, struct XrefTable *xref, int offs){  char *p, *q, *eof;  struct PdfObj *trailerdict, *obj;  int start, len, i;    if (strncmp(pdfbuf->str+offs, "xref", 4)) return NULL;  p = strstr(pdfbuf->str+offs, "trailer");  eof = pdfbuf->str + pdfbuf->len;  if (p==NULL) return NULL;  p+=8;  trailerdict = parse_pdf_object(&p, eof);  obj = get_dict_entry(trailerdict, "/Size");  if (obj!=NULL && obj->type == PDFTYPE_INT && obj->intval-1>xref->last)    make_xref(xref, obj->intval-1, 0);  obj = get_dict_entry(trailerdict, "/Prev");  if (obj!=NULL && obj->type == PDFTYPE_INT && obj->intval>0 && obj->intval!=offs) {    // recurse into older xref table    obj = parse_xref_table(pdfbuf, xref, obj->intval);    free_pdfobj(obj);  }  p = pdfbuf->str+offs+4;  skipspace(&p, eof);  if (*p<'0' || *p>'9') { free_pdfobj(trailerdict); return NULL; }  while (*p>='0' && *p<='9') {    start = strtol(p, &p, 10);    skipspace(&p, eof);    len = strtol(p, &p, 10);    skipspace(&p, eof);    if (len <= 0 || 20*len > eof-p) break;    if (start+len-1 > xref->last) make_xref(xref, start+len-1, 0);    for (i=start; i<start+len; i++) {      xref->data[i] = strtol(p, NULL, 10);      p+=20;    }    skipspace(&p, eof);  }  if (*p!='t') { free_pdfobj(trailerdict); return NULL; }  return trailerdict;}// parse the page treeint pdf_getpageinfo(GString *pdfbuf, struct XrefTable *xref,                 struct PdfObj *pgtree, int nmax, struct PdfPageDesc *pages){  struct PdfObj *obj, *kid;  int i, count, j;    obj = get_pdfobj(pdfbuf, xref, get_dict_entry(pgtree, "/Type"));  if (obj == NULL || obj->type != PDFTYPE_NAME)    return 0;  if (!strcmp(obj->str, "/Page")) {    free_pdfobj(obj);    pages->contents = dup_pdfobj(get_dict_entry(pgtree, "/Contents"));

⌨️ 快捷键说明

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