26int T1FontEngine::t1libInitCount = 0;
30T1FontEngine::T1FontEngine(Display *displayA, Visual *visualA,
int depthA,
31 Colormap colormapA, GBool aaA, GBool aaHighA):
32 SFontEngine(displayA, visualA, depthA, colormapA)
34 static unsigned long grayVals[17] = {
35 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
42 if (t1libInitCount == 0) {
44 if (!T1_InitLib(NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE |
49 T1_AASetBitsPerPixel(8);
51 T1_AASetLevel(T1_AA_HIGH);
52 T1_AAHSetGrayValues(grayVals);
54 T1_AASetLevel(T1_AA_LOW);
55 T1_AASetGrayValues(0, 1, 2, 3, 4);
58 T1_AANSetGrayValues(0, 1);
65T1FontEngine::~T1FontEngine() {
67 if (--t1libInitCount == 0) {
74T1FontFile::T1FontFile(T1FontEngine *engineA,
char *fontFileName,
75 char **fontEnc,
double *bboxA) {
84 for (i = 0; i < 4; ++i) {
89 if ((
id = T1_AddFont(fontFileName)) < 0) {
96 for (i = 0; i < 256; ++i) {
98 encStrSize += strlen(fontEnc[i]) + 1;
101 enc = (
char **)gmalloc(257 *
sizeof(
char *));
102 encStr = (
char *)gmalloc(encStrSize *
sizeof(
char));
104 for (i = 0; i < 256; ++i) {
106 strcpy(encPtr, fontEnc[i]);
108 encPtr += strlen(encPtr) + 1;
114 T1_ReencodeFont(
id, enc);
119T1FontFile::~T1FontFile() {
129T1Font::T1Font(T1FontFile *fontFileA,
double *m) {
130 T1FontEngine *engine;
133 double bbx0, bby0, bbx1, bby1;
134 int x, y, xMin, xMax, yMin, yMax;
138 fontFile = fontFileA;
139 engine = fontFile->engine;
141 id = T1_CopyFont(fontFile->id);
144 size = (float)sqrt(m[2]*m[2] + m[3]*m[3]);
148 bbx0 = fontFile->bbox[0];
149 bby0 = fontFile->bbox[1];
150 bbx1 = fontFile->bbox[2];
151 bby1 = fontFile->bbox[3];
154 bbox = T1_GetFontBBox(
id);
155 if (0.001 * bbox.llx < bbx0) {
156 bbx0 = 0.001 * bbox.llx;
158 if (0.001 * bbox.lly < bby0) {
159 bby0 = 0.001 * bbox.lly;
161 if (0.001 * bbox.urx > bbx1) {
162 bbx1 = 0.001 * bbox.urx;
164 if (0.001 * bbox.ury > bby1) {
165 bby1 = 0.001 * bbox.ury;
169 if (bbx0 == 0 && bby0 == 0 && bbx1 == 0 && bby1 == 0) {
173 x = (int)(m[0] * bbx0 + m[2] * bby0);
175 y = (int)(m[1] * bbx0 + m[3] * bby0);
177 x = (int)(m[0] * bbx0 + m[2] * bby1);
180 }
else if (x > xMax) {
183 y = (int)(m[1] * bbx0 + m[3] * bby1);
186 }
else if (y > yMax) {
189 x = (int)(m[0] * bbx1 + m[2] * bby0);
192 }
else if (x > xMax) {
195 y = (int)(m[1] * bbx1 + m[3] * bby0);
198 }
else if (y > yMax) {
201 x = (int)(m[0] * bbx1 + m[2] * bby1);
204 }
else if (x > xMax) {
207 y = (int)(m[1] * bbx1 + m[3] * bby1);
210 }
else if (y > yMax) {
221 yMax = (int)(1.2 * size);
233 if (xMax - xMin > 5000) {
237 if (yMax - yMin > 5000) {
239 yMax = (int)(1.2 * size);
243 glyphW = xMax - xMin + 3;
244 glyphH = yMax - yMin + 3;
246 glyphSize = glyphW * glyphH;
248 glyphSize = ((glyphW + 7) >> 3) * glyphH;
253 if (glyphSize <= 256) {
255 }
else if (glyphSize <= 512) {
257 }
else if (glyphSize <= 1024) {
262 cache = (Guchar *)gmalloc(cacheSets * cacheAssoc * glyphSize);
263 cacheTags = (T1FontCacheTag *)gmalloc(cacheSets * cacheAssoc *
264 sizeof(T1FontCacheTag));
265 for (i = 0; i < cacheSets * cacheAssoc; ++i) {
266 cacheTags[i].mru = i & (cacheAssoc - 1);
270 if (!(image = XCreateImage(engine->display, engine->visual, engine->depth,
271 ZPixmap, 0, NULL, glyphW, glyphH, 8, 0))) {
274 image->data = (
char *)gmalloc(glyphH * image->bytes_per_line);
277 matrix.cxx = m[0] / size;
278 matrix.cxy = m[1] / size;
279 matrix.cyx = m[2] / size;
280 matrix.cyy = m[3] / size;
281 T1_TransformFont(
id, &matrix);
292 XDestroyImage(image);
297GBool T1Font::drawChar(Drawable d,
int w,
int h, GC gc,
298 int x,
int y,
int r,
int g,
int b,
299 CharCode c, Unicode u) {
300 T1FontEngine *engine;
305 int xOffset, yOffset, x0, y0, x1, y1, gw, gh, w0, h0;
310 engine = fontFile->engine;
313 if (!(p = getGlyphPixmap(c, &xOffset, &yOffset, &gw, &gh))) {
350 XGetSubImage(engine->display, d, x0, y0, w0, h0, (1 << engine->depth) - 1,
351 ZPixmap, image, x1, y1);
356 xcolor.pixel = XGetPixel(image, x1 + w0/2, y1 + h0/2);
357 XQueryColor(engine->display, engine->colormap, &xcolor);
361 if (engine->aaHigh) {
363 for (i = 1; i <= 16; ++i) {
364 colors[i] = engine->findColor((i * r + (16 - i) * bgR) / 16,
365 (i * g + (16 - i) * bgG) / 16,
366 (i * b + (16 - i) * bgB) / 16);
370 colors[1] = engine->findColor((r + 3*bgR) / 4,
373 colors[2] = engine->findColor((r + bgR) / 2,
376 colors[3] = engine->findColor((3*r + bgR) / 4,
379 colors[4] = engine->findColor(r, g, b);
383 for (yy = 0; yy < gh; ++yy) {
384 for (xx = 0; xx < gw; ++xx) {
390 XPutPixel(image, xx, yy, colors[pix]);
398 colors[1] = engine->findColor(r, g, b);
401 for (yy = 0; yy < gh; ++yy) {
402 for (xx = 0; xx < gw; xx += 8) {
404 for (xx1 = xx; xx1 < xx + 8 && xx1 < gw; ++xx1) {
406 XPutPixel(image, xx1, yy, colors[1]);
416 XPutImage(engine->display, d, gc, image, x1, y1, x0, y0, w0, h0);
421Guchar *T1Font::getGlyphPixmap(CharCode c,
int *x,
int *y,
int *w,
int *h) {
422 T1FontEngine *engine;
428 engine = fontFile->engine;
431 i = (c & (cacheSets - 1)) * cacheAssoc;
432 for (j = 0; j < cacheAssoc; ++j) {
433 if ((cacheTags[i+j].mru & 0x8000) && cacheTags[i+j].code == c) {
434 *x = cacheTags[i+j].x;
435 *y = cacheTags[i+j].y;
436 *w = cacheTags[i+j].w;
437 *h = cacheTags[i+j].h;
438 for (k = 0; k < cacheAssoc; ++k) {
440 (cacheTags[i+k].mru & 0x7fff) < (cacheTags[i+j].mru & 0x7fff)) {
441 ++cacheTags[i+k].mru;
444 cacheTags[i+j].mru = 0x8000;
445 return cache + (i+j) * glyphSize;
451 glyph = T1_AASetChar(
id, c, size, NULL);
453 glyph = T1_SetChar(
id, c, size, NULL);
458 *x = -glyph->metrics.leftSideBearing;
459 *y = glyph->metrics.ascent;
460 *w = glyph->metrics.rightSideBearing - glyph->metrics.leftSideBearing;
461 *h = glyph->metrics.ascent - glyph->metrics.descent;
462 if (*w > glyphW || *h > glyphH) {
464 fprintf(stderr,
"Weird t1lib glyph size: %d > %d or %d > %d\n",
465 *w, glyphW, *h, glyphH);
472 for (j = 0; j < cacheAssoc; ++j) {
473 if ((cacheTags[i+j].mru & 0x7fff) == cacheAssoc - 1) {
474 cacheTags[i+j].mru = 0x8000;
475 cacheTags[i+j].code = c;
476 cacheTags[i+j].x = *x;
477 cacheTags[i+j].y = *y;
478 cacheTags[i+j].w = *w;
479 cacheTags[i+j].h = *h;
483 gSize = ((*w + 7) >> 3) * *h;
485 ret = cache + (i+j) * glyphSize;
487 memcpy(ret, glyph->bits, gSize);
489 memset(ret, 0, gSize);
492 ++cacheTags[i+j].mru;
498GBool T1Font::getCharPath(CharCode c, Unicode u, GfxState *state) {
501 T1_BEZIERSEGMENT *bez;
504 outline = T1_GetCharOutline(
id, c, size, NULL);
507 for (seg = outline; seg; seg = seg->link) {
509 case T1_PATHTYPE_MOVE:
510 x += seg->dest.x / 65536.0;
511 y += seg->dest.y / 65536.0;
514 case T1_PATHTYPE_LINE:
515 x += seg->dest.x / 65536.0;
516 y += seg->dest.y / 65536.0;
519 case T1_PATHTYPE_BEZIER:
520 bez = (T1_BEZIERSEGMENT *)seg;
521 x1 = x + bez->dest.x / 65536.0;
522 y1 = y + bez->dest.y / 65536.0;
523 state->curveTo(x + bez->B.x / 65536.0, y + bez->B.y / 65536.0,
524 x + bez->C.x / 65536.0, y + bez->C.y / 65536.0,
531 T1_FreeOutline(outline);