~ubuntu-branches/ubuntu/wily/luatex/wily

« back to all changes in this revision

Viewing changes to source/libs/xpdf/xpdf-3.02/splash/SplashFont.cc

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2010-04-29 00:47:19 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20100429004719-o42etkqe90n97b9e
Tags: 0.60.1-1
* new upstream release, adapt build-script patch
* disable patch: upstream-epstopdf_cc_no_xpdf_patching, included upstream
* disable patch: libpoppler-0.12, not needed anymore

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//========================================================================
 
2
//
 
3
// SplashFont.cc
 
4
//
 
5
//========================================================================
 
6
 
 
7
#include <aconf.h>
 
8
 
 
9
#ifdef USE_GCC_PRAGMAS
 
10
#pragma implementation
 
11
#endif
 
12
 
 
13
#include <string.h>
 
14
#include "gmem.h"
 
15
#include "SplashMath.h"
 
16
#include "SplashGlyphBitmap.h"
 
17
#include "SplashFontFile.h"
 
18
#include "SplashFont.h"
 
19
 
 
20
//------------------------------------------------------------------------
 
21
 
 
22
struct SplashFontCacheTag {
 
23
  int c;
 
24
  short xFrac, yFrac;           // x and y fractions
 
25
  int mru;                      // valid bit (0x80000000) and MRU index
 
26
  int x, y, w, h;               // offset and size of glyph
 
27
};
 
28
 
 
29
//------------------------------------------------------------------------
 
30
// SplashFont
 
31
//------------------------------------------------------------------------
 
32
 
 
33
SplashFont::SplashFont(SplashFontFile *fontFileA, SplashCoord *matA,
 
34
                       SplashCoord *textMatA, GBool aaA) {
 
35
  fontFile = fontFileA;
 
36
  fontFile->incRefCnt();
 
37
  mat[0] = matA[0];
 
38
  mat[1] = matA[1];
 
39
  mat[2] = matA[2];
 
40
  mat[3] = matA[3];
 
41
  textMat[0] = textMatA[0];
 
42
  textMat[1] = textMatA[1];
 
43
  textMat[2] = textMatA[2];
 
44
  textMat[3] = textMatA[3];
 
45
  aa = aaA;
 
46
 
 
47
  cache = NULL;
 
48
  cacheTags = NULL;
 
49
 
 
50
  xMin = yMin = xMax = yMax = 0;
 
51
}
 
52
 
 
53
void SplashFont::initCache() {
 
54
  int i;
 
55
 
 
56
  // this should be (max - min + 1), but we add some padding to
 
57
  // deal with rounding errors
 
58
  glyphW = xMax - xMin + 3;
 
59
  glyphH = yMax - yMin + 3;
 
60
  if (aa) {
 
61
    glyphSize = glyphW * glyphH;
 
62
  } else {
 
63
    glyphSize = ((glyphW + 7) >> 3) * glyphH;
 
64
  }
 
65
 
 
66
  // set up the glyph pixmap cache
 
67
  cacheAssoc = 8;
 
68
  if (glyphSize <= 256) {
 
69
    cacheSets = 8;
 
70
  } else if (glyphSize <= 512) {
 
71
    cacheSets = 4;
 
72
  } else if (glyphSize <= 1024) {
 
73
    cacheSets = 2;
 
74
  } else {
 
75
    cacheSets = 1;
 
76
  }
 
77
  cache = (Guchar *)gmallocn(cacheSets * cacheAssoc, glyphSize);
 
78
  cacheTags = (SplashFontCacheTag *)gmallocn(cacheSets * cacheAssoc,
 
79
                                             sizeof(SplashFontCacheTag));
 
80
  for (i = 0; i < cacheSets * cacheAssoc; ++i) {
 
81
    cacheTags[i].mru = i & (cacheAssoc - 1);
 
82
  }
 
83
}
 
84
 
 
85
SplashFont::~SplashFont() {
 
86
  fontFile->decRefCnt();
 
87
  if (cache) {
 
88
    gfree(cache);
 
89
  }
 
90
  if (cacheTags) {
 
91
    gfree(cacheTags);
 
92
  }
 
93
}
 
94
 
 
95
GBool SplashFont::getGlyph(int c, int xFrac, int yFrac,
 
96
                           SplashGlyphBitmap *bitmap) {
 
97
  SplashGlyphBitmap bitmap2;
 
98
  int size;
 
99
  Guchar *p;
 
100
  int i, j, k;
 
101
 
 
102
  // no fractional coordinates for large glyphs or non-anti-aliased
 
103
  // glyphs
 
104
  if (!aa || glyphH > 50) {
 
105
    xFrac = yFrac = 0;
 
106
  }
 
107
 
 
108
  // check the cache
 
109
  i = (c & (cacheSets - 1)) * cacheAssoc;
 
110
  for (j = 0; j < cacheAssoc; ++j) {
 
111
    if ((cacheTags[i+j].mru & 0x80000000) &&
 
112
        cacheTags[i+j].c == c &&
 
113
        (int)cacheTags[i+j].xFrac == xFrac &&
 
114
        (int)cacheTags[i+j].yFrac == yFrac) {
 
115
      bitmap->x = cacheTags[i+j].x;
 
116
      bitmap->y = cacheTags[i+j].y;
 
117
      bitmap->w = cacheTags[i+j].w;
 
118
      bitmap->h = cacheTags[i+j].h;
 
119
      for (k = 0; k < cacheAssoc; ++k) {
 
120
        if (k != j &&
 
121
            (cacheTags[i+k].mru & 0x7fffffff) <
 
122
              (cacheTags[i+j].mru & 0x7fffffff)) {
 
123
          ++cacheTags[i+k].mru;
 
124
        }
 
125
      }
 
126
      cacheTags[i+j].mru = 0x80000000;
 
127
      bitmap->aa = aa;
 
128
      bitmap->data = cache + (i+j) * glyphSize;
 
129
      bitmap->freeData = gFalse;
 
130
      return gTrue;
 
131
    }
 
132
  }
 
133
 
 
134
  // generate the glyph bitmap
 
135
  if (!makeGlyph(c, xFrac, yFrac, &bitmap2)) {
 
136
    return gFalse;
 
137
  }
 
138
 
 
139
  // if the glyph doesn't fit in the bounding box, return a temporary
 
140
  // uncached bitmap
 
141
  if (bitmap2.w > glyphW || bitmap2.h > glyphH) {
 
142
    *bitmap = bitmap2;
 
143
    return gTrue;
 
144
  }
 
145
 
 
146
  // insert glyph pixmap in cache
 
147
  if (aa) {
 
148
    size = bitmap2.w * bitmap2.h;
 
149
  } else {
 
150
    size = ((bitmap2.w + 7) >> 3) * bitmap2.h;
 
151
  }
 
152
  p = NULL; // make gcc happy
 
153
  for (j = 0; j < cacheAssoc; ++j) {
 
154
    if ((cacheTags[i+j].mru & 0x7fffffff) == cacheAssoc - 1) {
 
155
      cacheTags[i+j].mru = 0x80000000;
 
156
      cacheTags[i+j].c = c;
 
157
      cacheTags[i+j].xFrac = (short)xFrac;
 
158
      cacheTags[i+j].yFrac = (short)yFrac;
 
159
      cacheTags[i+j].x = bitmap2.x;
 
160
      cacheTags[i+j].y = bitmap2.y;
 
161
      cacheTags[i+j].w = bitmap2.w;
 
162
      cacheTags[i+j].h = bitmap2.h;
 
163
      p = cache + (i+j) * glyphSize;
 
164
      memcpy(p, bitmap2.data, size);
 
165
    } else {
 
166
      ++cacheTags[i+j].mru;
 
167
    }
 
168
  }
 
169
  *bitmap = bitmap2;
 
170
  bitmap->data = p;
 
171
  bitmap->freeData = gFalse;
 
172
  if (bitmap2.freeData) {
 
173
    gfree(bitmap2.data);
 
174
  }
 
175
  return gTrue;
 
176
}