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

📄 xo-print.c

📁 高手写的手写代码!欢迎大家下载,共同交流,如果有问题,请联系我!谢谢!
💻 C
📖 第 1 页 / 共 4 页
字号:
  font->glyphmap[0] = 0;  // fill in info from the FT_Face  font->is_truetype = FT_IS_SFNT(face);  font->nglyphs = face->num_glyphs;  font->ft2ps = 1000.0 / face->units_per_EM;  font->ascender = (int)(font->ft2ps*face->ascender);  font->descender = (int)(font->ft2ps*face->descender);  if (face->bbox.xMin < -100000 || face->bbox.xMin > 100000) font->xmin = 0;  else font->xmin = (int)(font->ft2ps*face->bbox.xMin);  if (face->bbox.xMax < -100000 || face->bbox.xMax > 100000) font->xmax = 0;  else font->xmax = (int)(font->ft2ps*face->bbox.xMax);  if (face->bbox.yMin < -100000 || face->bbox.yMin > 100000) font->ymin = 0;  else font->ymin = (int)(font->ft2ps*face->bbox.yMin);  if (face->bbox.yMax < -100000 || face->bbox.yMax > 100000) font->ymax = 0;  else font->ymax = (int)(font->ft2ps*face->bbox.yMax);  if (font->is_truetype) font->flags = 4; // symbolic  else {    font->flags = 4; // symbolic    if (FT_IS_FIXED_WIDTH(face)) font->flags |= 1;    if (face->style_flags & FT_STYLE_FLAG_ITALIC) font->flags |= 64;  }  s = FT_Get_Postscript_Name(face);  if (s==NULL) s = "Noname";  if (glyph_page) font->fontname = g_strdup_printf("%s_%03d", s, glyph_page);  else font->fontname = g_strdup(s);  return font;}#define pfb_get_length(x) (((x)[3]<<24) + ((x)[2]<<16) + ((x)[1]<<8) + (x)[0])#define T1_SEGMENT_1_END "currentfile eexec"#define T1_SEGMENT_3_END "cleartomark"void embed_pdffont(GString *pdfbuf, struct XrefTable *xref, struct PdfFont *font){  // this code inspired by libgnomeprint  gboolean fallback, is_binary;  guchar encoding[256];  gushort glyphs[256];  int i, j, num, len, len1, len2;  TrueTypeFont *ttfnt;  char *tmpfile, *seg1, *seg2;  unsigned char *fontdata, *p;  char prefix[8];  int nobj_fontprog, nobj_descr, lastchar;    fallback = FALSE;  // embed the font file: TrueType case  if (font->is_truetype) {    glyphs[0] = encoding[0] = 0;    num = 1;    for (i=1; i<=255; i++)       if (font->glyphmap[i]>=0) {        font->glyphmap[i] = num;        glyphs[num] = 255*font->glyph_page+i-1;        encoding[num] = i;        num++;      }    font->num_glyphs_used = num-1;    if (OpenTTFont(font->filename, 0, &ttfnt) == SF_OK) {      tmpfile = mktemp(g_strdup(TMPDIR_TEMPLATE));      CreateTTFromTTGlyphs(ttfnt, tmpfile, glyphs, encoding, num,                            0, NULL, TTCF_AutoName | TTCF_IncludeOS2);      CloseTTFont(ttfnt);      if (g_file_get_contents(tmpfile, (char **)&fontdata, &len, NULL) && len>=8) {        make_xref(xref, xref->last+1, pdfbuf->len);        nobj_fontprog = xref->last;        g_string_append_printf(pdfbuf,           "%d 0 obj\n<< /Length %d /Length1 %d >> stream\n",          nobj_fontprog, len, len);        g_string_append_len(pdfbuf, fontdata, len);        g_string_append(pdfbuf, "endstream\nendobj\n");        g_free(fontdata);      }       else fallback = TRUE;      unlink(tmpfile);      g_free(tmpfile);    }    else fallback = TRUE;    } else {  // embed the font file: Type1 case    if (g_file_get_contents(font->filename, (char **)&fontdata, &len, NULL) && len>=8) {      if (fontdata[0]==0x80 && fontdata[1]==0x01) {        is_binary = TRUE;        len1 = pfb_get_length(fontdata+2);        if (fontdata[len1+6]!=0x80 || fontdata[len1+7]!=0x02) fallback = TRUE;        else {          len2 = pfb_get_length(fontdata+len1+8);          if (fontdata[len1+len2+12]!=0x80 || fontdata[len1+len2+13]!=0x01)            fallback = TRUE;        }      }      else if (!strncmp(fontdata, "%!PS", 4)) {        is_binary = FALSE;        p = strstr(fontdata, T1_SEGMENT_1_END) + strlen(T1_SEGMENT_1_END);        if (p==NULL) fallback = TRUE;        else {          if (*p=='\n' || *p=='\r') p++;          if (*p=='\n' || *p=='\r') p++;          len1 = p-fontdata;          p = g_strrstr_len(fontdata, len, T1_SEGMENT_3_END);          if (p==NULL) fallback = TRUE;          else {            // rewind 512 zeros            i = 512; p--;            while (i>0 && p!=fontdata && (*p=='0' || *p=='\r' || *p=='\n')) {              if (*p=='0') i--;              p--;            }            while (p!=fontdata && (*p=='\r' || *p=='\n')) p--;            p++;            if (i>0) fallback = TRUE;            else len2 = p-fontdata-len1;          }        }      }      else fallback = TRUE;      if (!fallback) {        if (is_binary) {          seg1 = fontdata+6;          seg2 = fontdata + len1 + 12;        } else {          seg1 = fontdata;          seg2 = g_malloc(len2/2);          j=0;          p = fontdata+len1;          while (p+1 < fontdata+len1+len2) {            if (*p==' '||*p=='\t'||*p=='\n'||*p=='\r') { p++; continue; }            if (p[0]>'9') { p[0]|=0x20; p[0]-=39; }            if (p[1]>'9') { p[1]|=0x20; p[1]-=39; }            seg2[j++] = ((p[0]-'0')<<4) + (p[1]-'0');            p+=2;          }          len2 = j;        }        make_xref(xref, xref->last+1, pdfbuf->len);        nobj_fontprog = xref->last;        g_string_append_printf(pdfbuf,           "%d 0 obj\n<< /Length %d /Length1 %d /Length2 %d /Length3 0 >> stream\n",          nobj_fontprog, len1+len2, len1, len2);        g_string_append_len(pdfbuf, seg1, len1);        g_string_append_len(pdfbuf, seg2, len2);        g_string_append(pdfbuf, "endstream\nendobj\n");        if (!is_binary) g_free(seg2);      }      g_free(fontdata);    }    else fallback = TRUE;  }    // next, the font descriptor  if (!fallback) {    make_xref(xref, xref->last+1, pdfbuf->len);    nobj_descr = xref->last;    g_string_append_printf(pdfbuf,      "%d 0 obj\n<< /Type /FontDescriptor /FontName /%s /Flags %d "      "/FontBBox [%d %d %d %d] /ItalicAngle 0 /Ascent %d "      "/Descent %d /CapHeight %d /StemV 100 /%s %d 0 R >> endobj\n",      nobj_descr, font->fontname, font->flags,       font->xmin, font->ymin, font->xmax, font->ymax,       font->ascender, -font->descender, font->ascender,       font->is_truetype ? "FontFile2":"FontFile",      nobj_fontprog);  }    // finally, the font itself  /* Note: in Type1 case, font->glyphmap maps charcodes to glyph no's     in TrueType case, encoding lists the used charcodes by index,                       glyphs   list the used glyph no's by index                       font->glyphmap maps charcodes to indices        */  xref->data[font->n_obj] = pdfbuf->len;  if (font->is_truetype) lastchar = encoding[font->num_glyphs_used];  else lastchar = font->num_glyphs_used;  if (fallback) {    font->is_truetype = FALSE;    g_free(font->fontname);    font->fontname = g_strdup("Helvetica");  }  prefix[0]=0;  if (font->is_truetype) {    num = font->glyph_page;    for (i=0; i<6; i++) { prefix[i] = 'A'+(num%26); num/=26; }    prefix[6]='+'; prefix[7]=0;  }  g_string_append_printf(pdfbuf,    "%d 0 obj\n<< /Type /Font /Subtype /%s /BaseFont /%s%s /Name /F%d ",    font->n_obj, font->is_truetype?"TrueType":"Type1",    prefix, font->fontname, font->n_obj);  if (!fallback) {    g_string_append_printf(pdfbuf,      "/FontDescriptor %d 0 R /FirstChar 0 /LastChar %d /Widths [",      nobj_descr, lastchar);    for (i=0; i<=lastchar; i++)      g_string_append_printf(pdfbuf, "%d ", font->advance[i]);    g_string_append(pdfbuf, "] ");  }  if (!font->is_truetype) { /* encoding */    g_string_append(pdfbuf, "/Encoding << /Type /Encoding "      "/BaseEncoding /MacRomanEncoding /Differences [1 ");    for (i=1; i<=lastchar; i++) {      g_string_append_printf(pdfbuf, "/%s ", font->glyphpsnames[i]);      g_free(font->glyphpsnames[i]);    }    g_string_append(pdfbuf, "] >> ");  }  g_string_append(pdfbuf, ">> endobj\n");}// draw a page's graphicsvoid pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter,                   struct XrefTable *xref, GList **pdffonts){  GList *layerlist, *itemlist, *tmplist;  struct Layer *l;  struct Item *item;  guint old_rgba, old_text_rgba;  double old_thickness;  double *pt;  int i, j;  PangoFontDescription *font_desc;  PangoContext *context;  PangoLayout *layout;  PangoLayoutIter *iter;  PangoRectangle logical_rect;  PangoLayoutRun *run;  PangoFcFont *fcfont;  FcPattern *pattern;  int baseline, advance;  int glyph_no, glyph_page, current_page;  unsigned char *filename;  char tmpstr[200];  int font_id;  FT_Face ftface;  struct PdfFont *cur_font;  gboolean in_string;    old_rgba = old_text_rgba = 0x12345678;    // not any values we use, so we'll reset them  old_thickness = 0.0;  for (tmplist = *pdffonts; tmplist!=NULL; tmplist = tmplist->next) {    cur_font = (struct PdfFont *)tmplist->data;    cur_font->used_in_this_page = FALSE;  }  for (layerlist = pg->layers; layerlist!=NULL; layerlist = layerlist->next) {    l = (struct Layer *)layerlist->data;    for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next) {      item = (struct Item *)itemlist->data;      if (item->type == ITEM_STROKE) {        if ((item->brush.color_rgba & ~0xff) != old_rgba)          g_string_append_printf(str, "%.2f %.2f %.2f RG ",            RGBA_RGB(item->brush.color_rgba));        if (item->brush.thickness != old_thickness)          g_string_append_printf(str, "%.2f w ", item->brush.thickness);        if ((item->brush.color_rgba & 0xf0) != 0xf0) { // transparent          g_string_append(str, "q /XoHi gs ");          *use_hiliter = TRUE;        }        old_rgba = item->brush.color_rgba & ~0xff;        old_thickness = item->brush.thickness;        pt = item->path->coords;        g_string_append_printf(str, "%.2f %.2f m ", pt[0], pt[1]);        for (i=1, pt+=2; i<item->path->num_points; i++, pt+=2)          g_string_append_printf(str, "%.2f %.2f l ", pt[0], pt[1]);        g_string_append_printf(str,"S\n");        if ((item->brush.color_rgba & 0xf0) != 0xf0) // undo transparent          g_string_append(str, "Q ");      }      else if (item->type == ITEM_TEXT) {        if ((item->brush.color_rgba & ~0xff) != old_text_rgba)          g_string_append_printf(str, "%.2f %.2f %.2f rg ",            RGBA_RGB(item->brush.color_rgba));        old_text_rgba = item->brush.color_rgba & ~0xff;        context = gnome_print_pango_create_context(gnome_print_pango_get_default_font_map());        layout = pango_layout_new(context);        g_object_unref(context);        font_desc = pango_font_description_from_string(item->font_name);        pango_font_description_set_absolute_size(font_desc,          item->font_size*PANGO_SCALE);        pango_layout_set_font_description(layout, font_desc);        pango_font_description_free(font_desc);        pango_layout_set_text(layout, item->text, -1);        // this code inspired by the code in libgnomeprint        iter = pango_layout_get_iter(layout);        do {          run = pango_layout_iter_get_run(iter);          if (run==NULL) continue;          pango_layout_iter_get_run_extents (iter, NULL, &logical_rect);          baseline = pango_layout_iter_get_baseline (iter);          if (!PANGO_IS_FC_FONT(run->item->analysis.font)) continue;          fcfont = PANGO_FC_FONT(run->item->analysis.font);          pattern = fcfont->font_pattern;          if (FcPatternGetString(pattern, FC_FILE, 0, &filename) != FcResultMatch ||              FcPatternGetInteger(pattern, FC_INDEX, 0, &font_id) != FcResultMatch)                continue;          ftface = pango_fc_font_lock_face(fcfont);          current_page = -1;          cur_font = NULL;          g_string_append_printf(str, "BT %.2f 0 0 %.2f %.2f %.2f Tm ",            item->font_size, -item->font_size,            item->bbox.left + (gdouble) logical_rect.x/PANGO_SCALE,            item->bbox.top + (gdouble) baseline/PANGO_SCALE);          in_string = FALSE;          for (i=0; i<run->glyphs->num_glyphs; i++) {            glyph_no = run->glyphs->glyphs[i].glyph;            if (FT_IS_SFNT(ftface)) glyph_page = glyph_no/255;            else glyph_page = 0;            if (glyph_page != current_page) {              cur_font = new_pdffont(xref, pdffonts, filename, font_id,                 ftface, glyph_page);              if (in_string) g_string_append(str, ") Tj ");              in_string = FALSE;              g_string_append_printf(str, "/F%d 1 Tf ", cur_font->n_obj);            }            current_page = glyph_page;            FT_Load_Glyph(ftface, glyph_no, FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);            advance = (int)(ftface->glyph->metrics.horiAdvance * cur_font->ft2ps + 0.5);            if (!in_string) g_string_append_c(str, '(');            in_string = TRUE;            if (cur_font->is_truetype) {              if (glyph_no) glyph_no = (glyph_no%255)+1;              cur_font->glyphmap[glyph_no] = glyph_no;            }            else {              for (j=1; j<=cur_font->num_glyphs_used; j++)                if (cur_font->glyphmap[j] == glyph_no) break;              if (j==256) j=0; // font is full, what do we do?              if (j>cur_font->num_glyphs_used) {                cur_font->glyphmap[j] = glyph_no;                 cur_font->num_glyphs_used++;                if (FT_Get_Glyph_Name(ftface, glyph_no, tmpstr, 200) == FT_Err_Ok)                  cur_font->glyphpsnames[j] = g_strdup(tmpstr);                else cur_font->glyphpsnames[j] = g_strdup(".notdef");              }              glyph_no = j;            }            cur_font->advance[glyph_no] = advance;            if (glyph_no=='\\' || glyph_no == '(' || glyph_no == ')' || glyph_no == 10 || glyph_no == 13)               g_string_append_c(str, '\\');            if (glyph_no==10) g_string_append_c(str,'n');            else if (glyph_no==13) g_string_append_c(str,'r');            else g_string_append_c(str, glyph_no);          }          if (in_string) g_string_append(str, ") Tj ");          g_string_append(str, "ET ");          pango_fc_font_unlock_face(fcfont);        } while (pango_layout_iter_next_run(iter));        pango_layout_iter_free(iter);        g_object_unref(layout);      }    }  }}// main printing function/* we use the following object numbers, starting with n_obj_catalog:    0 the document catalog    1 the page tree    2 the GS for the hiliters    3 ... the page objects*/gboolean print_to_pdf(char *filename){  FILE *f;  GString *pdfbuf, *pgstrm, *zpgstrm, *tmpstr;  int n_obj_catalog, n_obj_pages_offs, n_page, n_obj_bgpix, n_obj_prefix;  int i, startxref;  struct XrefTable xref;  GList *pglist;  struct Page *pg;  char *buf;  unsigned int len;  gboolean annot, uses_pdf;  gboolean use_hiliter;  struct PdfInfo pdfinfo;  struct PdfObj *obj;  GList *pdffonts, *list;  struct PdfFont *font;  char *tmpbuf;    f = fopen(filename, "w");  if (f == NULL) return FALSE;  setlocale(LC_NUMERIC, "C");  annot = FALSE;  xref.data = NULL;  uses_pdf = FALSE;  pdffonts = NULL;  for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {    pg = (struct Page *)pglist->data;    if (pg->bg->type == BG_PDF) uses_pdf = TRUE;  }    if (uses_pdf && bgpdf.status != STATUS_NOT_INIT &&       g_file_get_contents(bgpdf.tmpfile_copy, &buf, &len, NULL) &&      !strncmp(buf, "%PDF-1.", 7)) {    // parse the existing PDF file

⌨️ 快捷键说明

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