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.  
  3. #define MAX_FONT_SIZE 1000
  4. #define MAX_GLYPH_SIZE 256
  5. #define MAX_CACHE_SIZE (1024*1024)
  6.  
  7. typedef struct fz_glyph_key_s fz_glyph_key;
  8.  
  9. struct fz_glyph_cache_s
  10. {
  11.         fz_hash_table *hash;
  12.         int total;
  13. };
  14.  
  15. struct fz_glyph_key_s
  16. {
  17.         fz_font *font;
  18.         int a, b;
  19.         int c, d;
  20.         unsigned short gid;
  21.         unsigned char e, f;
  22. };
  23.  
  24. fz_glyph_cache *
  25. fz_new_glyph_cache(void)
  26. {
  27.         fz_glyph_cache *cache;
  28.  
  29.         cache = fz_malloc(sizeof(fz_glyph_cache));
  30.         cache->hash = fz_new_hash_table(509, sizeof(fz_glyph_key));
  31.         cache->total = 0;
  32.  
  33.         return cache;
  34. }
  35.  
  36. static void
  37. fz_evict_glyph_cache(fz_glyph_cache *cache)
  38. {
  39.         fz_glyph_key *key;
  40.         fz_pixmap *pixmap;
  41.         int i;
  42.  
  43.         for (i = 0; i < fz_hash_len(cache->hash); i++)
  44.         {
  45.                 key = fz_hash_get_key(cache->hash, i);
  46.                 if (key->font)
  47.                         fz_drop_font(key->font);
  48.                 pixmap = fz_hash_get_val(cache->hash, i);
  49.                 if (pixmap)
  50.                         fz_drop_pixmap(pixmap);
  51.         }
  52.  
  53.         cache->total = 0;
  54.  
  55.         fz_empty_hash(cache->hash);
  56. }
  57.  
  58. void
  59. fz_free_glyph_cache(fz_glyph_cache *cache)
  60. {
  61.         fz_evict_glyph_cache(cache);
  62.         fz_free_hash(cache->hash);
  63.         fz_free(cache);
  64. }
  65.  
  66. fz_pixmap *
  67. fz_render_stroked_glyph(fz_glyph_cache *cache, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *stroke)
  68. {
  69.         if (font->ft_face)
  70.                 return fz_render_ft_stroked_glyph(font, gid, trm, ctm, stroke);
  71.         return fz_render_glyph(cache, font, gid, trm, NULL);
  72. }
  73.  
  74. fz_pixmap *
  75. fz_render_glyph(fz_glyph_cache *cache, fz_font *font, int gid, fz_matrix ctm, fz_colorspace *model)
  76. {
  77.         fz_glyph_key key;
  78.         fz_pixmap *val;
  79.         float size = fz_matrix_expansion(ctm);
  80.  
  81.         if (size > MAX_FONT_SIZE)
  82.         {
  83.                 /* TODO: this case should be handled by rendering glyph as a path fill */
  84.                 fz_warn("font size too large (%g), not rendering glyph", size);
  85.                 return NULL;
  86.         }
  87.  
  88.         memset(&key, 0, sizeof key);
  89.         key.font = font;
  90.         key.gid = gid;
  91.         key.a = ctm.a * 65536;
  92.         key.b = ctm.b * 65536;
  93.         key.c = ctm.c * 65536;
  94.         key.d = ctm.d * 65536;
  95.         key.e = (ctm.e - floorf(ctm.e)) * 256;
  96.         key.f = (ctm.f - floorf(ctm.f)) * 256;
  97.  
  98.         val = fz_hash_find(cache->hash, &key);
  99.         if (val)
  100.                 return fz_keep_pixmap(val);
  101.  
  102.         ctm.e = floorf(ctm.e) + key.e / 256.0f;
  103.         ctm.f = floorf(ctm.f) + key.f / 256.0f;
  104.  
  105.         if (font->ft_face)
  106.         {
  107.                 val = fz_render_ft_glyph(font, gid, ctm);
  108.         }
  109.         else if (font->t3procs)
  110.         {
  111.                 val = fz_render_t3_glyph(font, gid, ctm, model);
  112.         }
  113.         else
  114.         {
  115.                 fz_warn("assert: uninitialized font structure");
  116.                 return NULL;
  117.         }
  118.  
  119.         if (val)
  120.         {
  121.                 if (val->w < MAX_GLYPH_SIZE && val->h < MAX_GLYPH_SIZE)
  122.                 {
  123.                         if (cache->total + val->w * val->h > MAX_CACHE_SIZE)
  124.                                 fz_evict_glyph_cache(cache);
  125.                         fz_keep_font(key.font);
  126.                         fz_hash_insert(cache->hash, &key, val);
  127.                         cache->total += val->w * val->h;
  128.                         return fz_keep_pixmap(val);
  129.                 }
  130.                 return val;
  131.         }
  132.  
  133.         return NULL;
  134. }
  135.