1
//========================================================================
5
//========================================================================
7
//========================================================================
9
// Modified under the Poppler project - http://poppler.freedesktop.org
11
// All changes made under the Poppler project to this file are licensed
12
// under GPL version 2 or later
14
// Copyright (C) 2007-2008, 2010 Albert Astals Cid <aacid@kde.org>
16
// To see a description of the changes please see the Changelog file that
17
// came with your tarball or type make ChangeLog if you are building from git
19
//========================================================================
23
#ifdef USE_GCC_PRAGMAS
24
#pragma implementation
29
#include "SplashMath.h"
30
#include "SplashGlyphBitmap.h"
31
#include "SplashFontFile.h"
32
#include "SplashFont.h"
34
//------------------------------------------------------------------------
36
struct SplashFontCacheTag {
38
short xFrac, yFrac; // x and y fractions
39
int mru; // valid bit (0x80000000) and MRU index
40
int x, y, w, h; // offset and size of glyph
43
//------------------------------------------------------------------------
45
//------------------------------------------------------------------------
47
SplashFont::SplashFont(SplashFontFile *fontFileA, SplashCoord *matA,
48
SplashCoord *textMatA, GBool aaA) {
50
fontFile->incRefCnt();
55
textMat[0] = textMatA[0];
56
textMat[1] = textMatA[1];
57
textMat[2] = textMatA[2];
58
textMat[3] = textMatA[3];
64
xMin = yMin = xMax = yMax = 0;
67
void SplashFont::initCache() {
70
// this should be (max - min + 1), but we add some padding to
71
// deal with rounding errors
72
glyphW = xMax - xMin + 3;
73
glyphH = yMax - yMin + 3;
75
glyphSize = glyphW * glyphH;
77
glyphSize = ((glyphW + 7) >> 3) * glyphH;
80
// set up the glyph pixmap cache
82
if (glyphSize <= 64) {
84
} else if (glyphSize <= 128) {
86
} else if (glyphSize <= 256) {
88
} else if (glyphSize <= 512) {
90
} else if (glyphSize <= 1024) {
95
cache = (Guchar *)gmallocn_checkoverflow(cacheSets* cacheAssoc, glyphSize);
97
cacheTags = (SplashFontCacheTag *)gmallocn(cacheSets * cacheAssoc,
98
sizeof(SplashFontCacheTag));
99
for (i = 0; i < cacheSets * cacheAssoc; ++i) {
100
cacheTags[i].mru = i & (cacheAssoc - 1);
107
SplashFont::~SplashFont() {
108
fontFile->decRefCnt();
117
GBool SplashFont::getGlyph(int c, int xFrac, int yFrac,
118
SplashGlyphBitmap *bitmap, int x0, int y0, SplashClip *clip, SplashClipResult *clipRes) {
119
SplashGlyphBitmap bitmap2;
124
// no fractional coordinates for large glyphs or non-anti-aliased
126
if (!aa || glyphH > 50) {
131
i = (c & (cacheSets - 1)) * cacheAssoc;
132
for (j = 0; j < cacheAssoc; ++j) {
133
if ((cacheTags[i+j].mru & 0x80000000) &&
134
cacheTags[i+j].c == c &&
135
(int)cacheTags[i+j].xFrac == xFrac &&
136
(int)cacheTags[i+j].yFrac == yFrac) {
137
bitmap->x = cacheTags[i+j].x;
138
bitmap->y = cacheTags[i+j].y;
139
bitmap->w = cacheTags[i+j].w;
140
bitmap->h = cacheTags[i+j].h;
141
for (k = 0; k < cacheAssoc; ++k) {
143
(cacheTags[i+k].mru & 0x7fffffff) <
144
(cacheTags[i+j].mru & 0x7fffffff)) {
145
++cacheTags[i+k].mru;
148
cacheTags[i+j].mru = 0x80000000;
150
bitmap->data = cache + (i+j) * glyphSize;
151
bitmap->freeData = gFalse;
153
*clipRes = clip->testRect(x0 - bitmap->x,
155
x0 - bitmap->x + bitmap->w - 1,
156
y0 - bitmap->y + bitmap->h - 1);
162
// generate the glyph bitmap
163
if (!makeGlyph(c, xFrac, yFrac, &bitmap2, x0, y0, clip, clipRes)) {
167
if (*clipRes == splashClipAllOutside)
169
bitmap->freeData = gFalse;
170
if (bitmap2.freeData) gfree(bitmap2.data);
174
// if the glyph doesn't fit in the bounding box, return a temporary
176
if (bitmap2.w > glyphW || bitmap2.h > glyphH) {
181
// insert glyph pixmap in cache
183
size = bitmap2.w * bitmap2.h;
185
size = ((bitmap2.w + 7) >> 3) * bitmap2.h;
187
p = NULL; // make gcc happy
190
// we had problems on the malloc of the cache, so ignore it
195
for (j = 0; j < cacheAssoc; ++j) {
196
if ((cacheTags[i+j].mru & 0x7fffffff) == cacheAssoc - 1) {
197
cacheTags[i+j].mru = 0x80000000;
198
cacheTags[i+j].c = c;
199
cacheTags[i+j].xFrac = (short)xFrac;
200
cacheTags[i+j].yFrac = (short)yFrac;
201
cacheTags[i+j].x = bitmap2.x;
202
cacheTags[i+j].y = bitmap2.y;
203
cacheTags[i+j].w = bitmap2.w;
204
cacheTags[i+j].h = bitmap2.h;
205
p = cache + (i+j) * glyphSize;
206
memcpy(p, bitmap2.data, size);
208
++cacheTags[i+j].mru;
213
bitmap->freeData = gFalse;
214
if (bitmap2.freeData) {