Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include "fitz.h"
  2. #include "mupdf.h"
  3.  
  4. static fz_error
  5. pdf_run_glyph_func(void *xref, fz_obj *rdb, fz_buffer *contents, fz_device *dev, fz_matrix ctm)
  6. {
  7.         return pdf_run_glyph(xref, rdb, contents, dev, ctm);
  8. }
  9.  
  10. fz_error
  11. pdf_load_type3_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict)
  12. {
  13.         fz_error error;
  14.         char buf[256];
  15.         char *estrings[256];
  16.         pdf_font_desc *fontdesc;
  17.         fz_obj *encoding;
  18.         fz_obj *widths;
  19.         fz_obj *charprocs;
  20.         fz_obj *obj;
  21.         int first, last;
  22.         int i, k, n;
  23.         fz_rect bbox;
  24.         fz_matrix matrix;
  25.  
  26.         obj = fz_dict_gets(dict, "Name");
  27.         if (fz_is_name(obj))
  28.                 fz_strlcpy(buf, fz_to_name(obj), sizeof buf);
  29.         else
  30.                 sprintf(buf, "Unnamed-T3");
  31.  
  32.         fontdesc = pdf_new_font_desc();
  33.  
  34.         obj = fz_dict_gets(dict, "FontMatrix");
  35.         matrix = pdf_to_matrix(obj);
  36.  
  37.         obj = fz_dict_gets(dict, "FontBBox");
  38.         bbox = pdf_to_rect(obj);
  39.  
  40.         fontdesc->font = fz_new_type3_font(buf, matrix);
  41.  
  42.         fz_set_font_bbox(fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
  43.  
  44.         /* Encoding */
  45.  
  46.         for (i = 0; i < 256; i++)
  47.                 estrings[i] = NULL;
  48.  
  49.         encoding = fz_dict_gets(dict, "Encoding");
  50.         if (!encoding)
  51.         {
  52.                 error = fz_throw("syntaxerror: Type3 font missing Encoding");
  53.                 goto cleanup;
  54.         }
  55.  
  56.         if (fz_is_name(encoding))
  57.                 pdf_load_encoding(estrings, fz_to_name(encoding));
  58.  
  59.         if (fz_is_dict(encoding))
  60.         {
  61.                 fz_obj *base, *diff, *item;
  62.  
  63.                 base = fz_dict_gets(encoding, "BaseEncoding");
  64.                 if (fz_is_name(base))
  65.                         pdf_load_encoding(estrings, fz_to_name(base));
  66.  
  67.                 diff = fz_dict_gets(encoding, "Differences");
  68.                 if (fz_is_array(diff))
  69.                 {
  70.                         n = fz_array_len(diff);
  71.                         k = 0;
  72.                         for (i = 0; i < n; i++)
  73.                         {
  74.                                 item = fz_array_get(diff, i);
  75.                                 if (fz_is_int(item))
  76.                                         k = fz_to_int(item);
  77.                                 if (fz_is_name(item))
  78.                                         estrings[k++] = fz_to_name(item);
  79.                                 if (k < 0) k = 0;
  80.                                 if (k > 255) k = 255;
  81.                         }
  82.                 }
  83.         }
  84.  
  85.         fontdesc->encoding = pdf_new_identity_cmap(0, 1);
  86.  
  87.         error = pdf_load_to_unicode(fontdesc, xref, estrings, NULL, fz_dict_gets(dict, "ToUnicode"));
  88.         if (error)
  89.                 goto cleanup;
  90.  
  91.         /* Widths */
  92.  
  93.         pdf_set_default_hmtx(fontdesc, 0);
  94.  
  95.         first = fz_to_int(fz_dict_gets(dict, "FirstChar"));
  96.         last = fz_to_int(fz_dict_gets(dict, "LastChar"));
  97.  
  98.         widths = fz_dict_gets(dict, "Widths");
  99.         if (!widths)
  100.         {
  101.                 error = fz_throw("syntaxerror: Type3 font missing Widths");
  102.                 goto cleanup;
  103.         }
  104.  
  105.         for (i = first; i <= last; i++)
  106.         {
  107.                 float w = fz_to_real(fz_array_get(widths, i - first));
  108.                 w = fontdesc->font->t3matrix.a * w * 1000;
  109.                 fontdesc->font->t3widths[i] = w * 0.001f;
  110.                 pdf_add_hmtx(fontdesc, i, i, w);
  111.         }
  112.  
  113.         pdf_end_hmtx(fontdesc);
  114.  
  115.         /* Resources -- inherit page resources if the font doesn't have its own */
  116.  
  117.         fontdesc->font->t3resources = fz_dict_gets(dict, "Resources");
  118.         if (!fontdesc->font->t3resources)
  119.                 fontdesc->font->t3resources = rdb;
  120.         if (fontdesc->font->t3resources)
  121.                 fz_keep_obj(fontdesc->font->t3resources);
  122.         if (!fontdesc->font->t3resources)
  123.                 fz_warn("no resource dictionary for type 3 font!");
  124.  
  125.         fontdesc->font->t3xref = xref;
  126.         fontdesc->font->t3run = pdf_run_glyph_func;
  127.  
  128.         /* CharProcs */
  129.  
  130.         charprocs = fz_dict_gets(dict, "CharProcs");
  131.         if (!charprocs)
  132.         {
  133.                 error = fz_throw("syntaxerror: Type3 font missing CharProcs");
  134.                 goto cleanup;
  135.         }
  136.  
  137.         for (i = 0; i < 256; i++)
  138.         {
  139.                 if (estrings[i])
  140.                 {
  141.                         obj = fz_dict_gets(charprocs, estrings[i]);
  142.                         if (pdf_is_stream(xref, fz_to_num(obj), fz_to_gen(obj)))
  143.                         {
  144.                                 error = pdf_load_stream(&fontdesc->font->t3procs[i], xref, fz_to_num(obj), fz_to_gen(obj));
  145.                                 if (error)
  146.                                         goto cleanup;
  147.                         }
  148.                 }
  149.         }
  150.  
  151.         *fontdescp = fontdesc;
  152.         return fz_okay;
  153.  
  154. cleanup:
  155.         fz_drop_font(fontdesc->font);
  156.         fz_free(fontdesc);
  157.         return fz_rethrow(error, "cannot load type3 font (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
  158. }
  159.