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

📄 xo-print.c

📁 高手写的手写代码!欢迎大家下载,共同交流,如果有问题,请联系我!谢谢!
💻 C
📖 第 1 页 / 共 4 页
字号:
    obj = get_pdfobj(pdfbuf, xref, get_dict_entry(pgtree, "/Resources"));    if (obj!=NULL) {      free_pdfobj(pages->resources);      pages->resources = obj;    }    obj = get_pdfobj(pdfbuf, xref, get_dict_entry(pgtree, "/MediaBox"));    if (obj!=NULL) {      free_pdfobj(pages->mediabox);      pages->mediabox = obj;    }    obj = get_pdfobj(pdfbuf, xref, get_dict_entry(pgtree, "/Rotate"));    if (obj!=NULL && obj->type == PDFTYPE_INT)      pages->rotate = obj->intval;    free_pdfobj(obj);    return 1;  }  else if (!strcmp(obj->str, "/Pages")) {    free_pdfobj(obj);    obj = get_pdfobj(pdfbuf, xref, get_dict_entry(pgtree, "/Count"));    if (obj!=NULL && obj->type == PDFTYPE_INT &&         obj->intval>0 && obj->intval<=nmax) count = obj->intval;    else count = 0;    free_pdfobj(obj);    obj = get_pdfobj(pdfbuf, xref, get_dict_entry(pgtree, "/Resources"));    if (obj!=NULL)      for (i=0; i<count; i++) {        free_pdfobj(pages[i].resources);        pages[i].resources = dup_pdfobj(obj);      }    free_pdfobj(obj);    obj = get_pdfobj(pdfbuf, xref, get_dict_entry(pgtree, "/MediaBox"));    if (obj!=NULL)      for (i=0; i<count; i++) {        free_pdfobj(pages[i].mediabox);        pages[i].mediabox = dup_pdfobj(obj);      }    free_pdfobj(obj);    obj = get_pdfobj(pdfbuf, xref, get_dict_entry(pgtree, "/Rotate"));    if (obj!=NULL && obj->type == PDFTYPE_INT)      for (i=0; i<count; i++)        pages[i].rotate = obj->intval;    free_pdfobj(obj);    obj = get_pdfobj(pdfbuf, xref, get_dict_entry(pgtree, "/Kids"));    if (obj!=NULL && obj->type == PDFTYPE_ARRAY) {      for (i=0; i<obj->num; i++) {        kid = get_pdfobj(pdfbuf, xref, obj->elts[i]);        if (kid!=NULL) {          j = pdf_getpageinfo(pdfbuf, xref, kid, nmax, pages);          nmax -= j;          pages += j;          free_pdfobj(kid);        }      }    }    free_pdfobj(obj);    return count;  }  return 0;}// parse a PDF file in memorygboolean pdf_parse_info(GString *pdfbuf, struct PdfInfo *pdfinfo, struct XrefTable *xref){  char *p;  int i, offs;  struct PdfObj *obj, *pages;  xref->n_alloc = xref->last = 0;  xref->data = NULL;  p = pdfbuf->str + pdfbuf->len-1;    while (*p!='s' && p!=pdfbuf->str) p--;  if (strncmp(p, "startxref", 9)) return FALSE; // fail  p+=9;  while (ispdfspace(*p) && p!=pdfbuf->str+pdfbuf->len) p++;  offs = strtol(p, NULL, 10);  if (offs <= 0 || offs > pdfbuf->len) return FALSE; // fail  pdfinfo->startxref = offs;    pdfinfo->trailerdict = parse_xref_table(pdfbuf, xref, offs);  if (pdfinfo->trailerdict == NULL) return FALSE; // fail    obj = get_pdfobj(pdfbuf, xref,     get_dict_entry(pdfinfo->trailerdict, "/Root"));  if (obj == NULL)    { free_pdfobj(pdfinfo->trailerdict); return FALSE; }  pages = get_pdfobj(pdfbuf, xref, get_dict_entry(obj, "/Pages"));  free_pdfobj(obj);  if (pages == NULL)    { free_pdfobj(pdfinfo->trailerdict); return FALSE; }  obj = get_pdfobj(pdfbuf, xref, get_dict_entry(pages, "/Count"));  if (obj == NULL || obj->type != PDFTYPE_INT || obj->intval<=0)     { free_pdfobj(pdfinfo->trailerdict); free_pdfobj(pages);       free_pdfobj(obj); return FALSE; }  pdfinfo->npages = obj->intval;  free_pdfobj(obj);    pdfinfo->pages = g_malloc0(pdfinfo->npages*sizeof(struct PdfPageDesc));  pdf_getpageinfo(pdfbuf, xref, pages, pdfinfo->npages, pdfinfo->pages);  free_pdfobj(pages);    return TRUE;}// add an entry to the xref tablevoid make_xref(struct XrefTable *xref, int nobj, int offset){  if (xref->n_alloc <= nobj) {    xref->n_alloc = nobj + 10;    xref->data = g_realloc(xref->data, xref->n_alloc*sizeof(int));  }  if (xref->last < nobj) xref->last = nobj;  xref->data[nobj] = offset;}// a wrapper for deflateGString *do_deflate(char *in, int len){  GString *out;  z_stream zs;    zs.zalloc = Z_NULL;  zs.zfree = Z_NULL;  deflateInit(&zs, Z_DEFAULT_COMPRESSION);  zs.next_in = (Bytef *)in;  zs.avail_in = len;  zs.avail_out = deflateBound(&zs, len);  out = g_string_sized_new(zs.avail_out);  zs.next_out = (Bytef *)out->str;  deflate(&zs, Z_FINISH);  out->len = zs.total_out;  deflateEnd(&zs);  return out;}// prefix to scale the original pageGString *make_pdfprefix(struct PdfPageDesc *pgdesc, double width, double height){  GString *str;  double v[4], t, xscl, yscl;  int i;  // push 3 times in case code to be annotated has unbalanced q/Q (B of A., ...)  str = g_string_new("q q q ");   if (pgdesc->rotate == 90) {    g_string_append_printf(str, "0 -1 1 0 0 %.2f cm ", height);    t = height; height = width; width = t;  }  if (pgdesc->rotate == 270) {    g_string_append_printf(str, "0 1 -1 0 %.2f 0 cm ", width);    t = height; height = width; width = t;  }  if (pgdesc->rotate == 180) {    g_string_append_printf(str, "-1 0 0 -1 %.2f %.2f cm ", width, height);  }  if (pgdesc->mediabox==NULL || pgdesc->mediabox->type != PDFTYPE_ARRAY ||      pgdesc->mediabox->num != 4) return str;  for (i=0; i<4; i++) {    if (pgdesc->mediabox->elts[i]->type == PDFTYPE_INT)      v[i] = pgdesc->mediabox->elts[i]->intval;    else if (pgdesc->mediabox->elts[i]->type == PDFTYPE_REAL)      v[i] = pgdesc->mediabox->elts[i]->realval;    else return str;  }  if (v[0]>v[2]) { t = v[0]; v[0] = v[2]; v[2] = t; }  if (v[1]>v[3]) { t = v[1]; v[1] = v[3]; v[3] = t; }  if (v[2]-v[0] < 1. || v[3]-v[1] < 1.) return str;  xscl = width/(v[2]-v[0]);  yscl = height/(v[3]-v[1]);  g_string_append_printf(str, "%.4f 0 0 %.4f %.2f %.2f cm ",    xscl, yscl, -v[0]*xscl, -v[1]*yscl);  return str;}// add an entry to a subentry of a directorystruct PdfObj *mk_pdfname(char *name){  struct PdfObj *obj;    obj = g_malloc(sizeof(struct PdfObj));  obj->type = PDFTYPE_NAME;  obj->str = g_strdup(name);  return obj;}struct PdfObj *mk_pdfref(int num){  struct PdfObj *obj;    obj = g_malloc(sizeof(struct PdfObj));  obj->type = PDFTYPE_REF;  obj->intval = num;  obj->num = 0;  return obj;}gboolean iseq_obj(struct PdfObj *a, struct PdfObj *b){  if (a==NULL || b==NULL) return (a==b);  if (a->type!=b->type) return FALSE;  if (a->type == PDFTYPE_CST || a->type == PDFTYPE_INT)    return (a->intval == b->intval);  if (a->type == PDFTYPE_REAL)    return (a->realval == b->realval);  if (a->type == PDFTYPE_NAME)    return !strcmp(a->str, b->str);  if (a->type == PDFTYPE_REF)    return (a->intval == b->intval && a->num == b->num);  return FALSE;}void add_dict_subentry(GString *pdfbuf, struct XrefTable *xref,   struct PdfObj *obj, char *section, int type, char *name, struct PdfObj *entry){  struct PdfObj *sec;  int i, subpos;    subpos = -1;  for (i=0; i<obj->num; i++)     if (!strcmp(obj->names[i], section)) subpos = i;  if (subpos == -1) {    subpos = obj->num;    obj->num++;    obj->elts = g_realloc(obj->elts, obj->num*sizeof(struct PdfObj*));    obj->names = g_realloc(obj->names, obj->num*sizeof(char *));    obj->names[subpos] = g_strdup(section);    obj->elts[subpos] = NULL;  }  if (obj->elts[subpos]!=NULL && obj->elts[subpos]->type==PDFTYPE_REF) {    sec = get_pdfobj(pdfbuf, xref, obj->elts[subpos]);    free_pdfobj(obj->elts[subpos]);    obj->elts[subpos] = sec;  }  if (obj->elts[subpos]!=NULL && obj->elts[subpos]->type!=type)    { free_pdfobj(obj->elts[subpos]); obj->elts[subpos] = NULL; }  if (obj->elts[subpos] == NULL) {    obj->elts[subpos] = sec = g_malloc(sizeof(struct PdfObj));    sec->type = type;    sec->num = 0;    sec->elts = NULL;    sec->names = NULL;  }  sec = obj->elts[subpos];  subpos = -1;  if (type==PDFTYPE_DICT) {    for (i=0; i<sec->num; i++)       if (!strcmp(sec->names[i], name)) subpos = i;    if (subpos == -1) {      subpos = sec->num;      sec->num++;      sec->elts = g_realloc(sec->elts, sec->num*sizeof(struct PdfObj*));      sec->names = g_realloc(sec->names, sec->num*sizeof(char *));      sec->names[subpos] = g_strdup(name);      sec->elts[subpos] = NULL;    }    free_pdfobj(sec->elts[subpos]);    sec->elts[subpos] = entry;  }   if (type==PDFTYPE_ARRAY) {    for (i=0; i<sec->num; i++)      if (iseq_obj(sec->elts[i], entry)) subpos = i;    if (subpos == -1) {      subpos = sec->num;      sec->num++;      sec->elts = g_realloc(sec->elts, sec->num*sizeof(struct PdfObj*));      sec->elts[subpos] = entry;    }    else free_pdfobj(entry);  }}// draw a page's backgroundvoid pdf_draw_solid_background(struct Page *pg, GString *str){  double x, y;  g_string_append_printf(str,     "%.2f %.2f %.2f rg 0 0 %.2f %.2f re f ",    RGBA_RGB(pg->bg->color_rgba), pg->width, pg->height);  if (!ui.print_ruling) return;  if (pg->bg->ruling == RULING_NONE) return;  g_string_append_printf(str,    "%.2f %.2f %.2f RG %.2f w ",    RGBA_RGB(RULING_COLOR), RULING_THICKNESS);  if (pg->bg->ruling == RULING_GRAPH) {    for (x=RULING_GRAPHSPACING; x<pg->width-1; x+=RULING_GRAPHSPACING)      g_string_append_printf(str, "%.2f 0 m %.2f %.2f l S ",        x, x, pg->height);    for (y=RULING_GRAPHSPACING; y<pg->height-1; y+=RULING_GRAPHSPACING)      g_string_append_printf(str, "0 %.2f m %.2f %.2f l S ",        y, pg->width, y);    return;  }  for (y=RULING_TOPMARGIN; y<pg->height-1; y+=RULING_SPACING)    g_string_append_printf(str, "0 %.2f m %.2f %.2f l S ",      y, pg->width, y);  if (pg->bg->ruling == RULING_LINED)    g_string_append_printf(str,       "%.2f %.2f %.2f RG %.2f 0 m %.2f %.2f l S ",      RGBA_RGB(RULING_MARGIN_COLOR),       RULING_LEFTMARGIN, RULING_LEFTMARGIN, pg->height);}int pdf_draw_bitmap_background(struct Page *pg, GString *str,                                 struct XrefTable *xref, GString *pdfbuf){  BgPdfPage *pgpdf;  GdkPixbuf *pix;  GString *zpix;  char *buf, *p1, *p2;  int height, width, stride, x, y, chan;    if (pg->bg->type == BG_PDF) {    pgpdf = (struct BgPdfPage *)g_list_nth_data(bgpdf.pages, pg->bg->file_page_seq-1);    if (pgpdf == NULL) return -1;    if (pgpdf->dpi != PDFTOPPM_PRINTING_DPI) {      add_bgpdf_request(pg->bg->file_page_seq, 0, TRUE);      while (pgpdf->dpi != PDFTOPPM_PRINTING_DPI && bgpdf.status == STATUS_RUNNING)        gtk_main_iteration();    }    pix = pgpdf->pixbuf;  }  else pix = pg->bg->pixbuf;    if (gdk_pixbuf_get_bits_per_sample(pix) != 8) return -1;  if (gdk_pixbuf_get_colorspace(pix) != GDK_COLORSPACE_RGB) return -1;    width = gdk_pixbuf_get_width(pix);  height = gdk_pixbuf_get_height(pix);  stride = gdk_pixbuf_get_rowstride(pix);  chan = gdk_pixbuf_get_n_channels(pix);  if (chan!=3 && chan!=4) return -1;  g_string_append_printf(str, "q %.2f 0 0 %.2f 0 %.2f cm /ImBg Do Q ",    pg->width, -pg->height, pg->height);    p2 = buf = (char *)g_malloc(3*width*height);  for (y=0; y<height; y++) {    p1 = (char *)gdk_pixbuf_get_pixels(pix)+stride*y;    for (x=0; x<width; x++) {      *(p2++)=*(p1++); *(p2++)=*(p1++); *(p2++)=*(p1++);      if (chan==4) p1++;    }  }  zpix = do_deflate(buf, 3*width*height);  g_free(buf);  make_xref(xref, xref->last+1, pdfbuf->len);  g_string_append_printf(pdfbuf,     "%d 0 obj\n<< /Length %d /Filter /FlateDecode /Type /Xobject "    "/Subtype /Image /Width %d /Height %d /ColorSpace /DeviceRGB "    "/BitsPerComponent 8 >> stream\n",    xref->last, zpix->len, width, height);  g_string_append_len(pdfbuf, zpix->str, zpix->len);  g_string_free(zpix, TRUE);  g_string_append(pdfbuf, "endstream\nendobj\n");   return xref->last;}// manipulate Pdf fontsstruct PdfFont *new_pdffont(struct XrefTable *xref, GList **fonts,   unsigned char *filename, int font_id, FT_Face face, int glyph_page){  GList *list;  struct PdfFont *font;  int i;  const char *s;    for (list = *fonts; list!=NULL; list = list->next) {    font = (struct PdfFont *)list->data;    if (!strcmp(font->filename, filename) && font->font_id == font_id         && font->glyph_page == glyph_page)          { font->used_in_this_page = TRUE; return font; }  }  font = g_malloc(sizeof(struct PdfFont));  *fonts = g_list_append(*fonts, font);  font->n_obj = xref->last+1;  make_xref(xref, xref->last+1, 0); // will give it a value later  font->filename = g_strdup(filename);  font->font_id = font_id;  font->glyph_page = glyph_page;  font->used_in_this_page = TRUE;  font->num_glyphs_used = 0;  for (i=0; i<256; i++) {    font->glyphmap[i] = -1;    font->advance[i] = 0;    font->glyphpsnames[i] = NULL;  }

⌨️ 快捷键说明

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