1
/*--------------------------------------------------------------------------
3
----- Author: Rainer Menzner (Rainer.Menzner@web.de)
4
Subsampling based on code by Raph Levien (raph@acm.org)
6
----- Description: This file is part of the t1-library. It contains
7
functions for antialiased setting of characters
8
and strings of characters.
9
----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2007.
10
As of version 0.5, t1lib is distributed under the
11
GNU General Public Library Lincense. The
12
conditions can be found in the files LICENSE and
13
LGPL, which should reside in the toplevel
14
directory of the distribution. Please note that
15
there are parts of t1lib that are subject to
17
The parseAFM-package is copyrighted by Adobe Systems
19
The type1 rasterizer is copyrighted by IBM and the
21
----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-)
22
----- Credits: I want to thank IBM and the X11-consortium for making
23
their rasterizer freely available.
24
Also thanks to Piet Tutelaers for his ps2pk, from
25
which I took the rasterizer sources in a format
27
Thanks to all people who make free software living!
28
--------------------------------------------------------------------------*/
34
#include <sys/types.h>
39
# include <sys/types.h>
40
# include <sys/stat.h>
48
#include "../type1/ffilest.h"
49
#include "../type1/types.h"
51
#include "../type1/objects.h"
52
#include "../type1/spaces.h"
53
#include "../type1/util.h"
54
#include "../type1/fontfcn.h"
55
#include "../type1/paths.h"
56
#include "../type1/regions.h"
66
#include "t1outline.h"
74
#define T1_AA_TYPE16 short
77
#define T1_AA_TYPE32 int
81
/* In the following arrays take the gray values. Entry 0 is associated
82
with the white (background) value and the max entry is the
83
black (foreground) value. */
84
static unsigned T1_AA_TYPE32 gv[5]={0,0,0,0,0};
85
static unsigned T1_AA_TYPE32 gv_h[17]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
86
static unsigned T1_AA_TYPE32 gv_n[2]={0,0};
88
static int T1aa_level=T1_AA_LOW; /* The default value */
89
static T1_AA_TYPE32 T1aa_lut[625];
90
static int T1aa_count[256];
91
static T1_AA_TYPE32 T1aa_h_lut[289];
92
static int T1aa_h_count[256];
93
static T1_AA_TYPE32 T1aa_n_lut[64];
95
/* This global is for querying the current bg from other parts
97
unsigned T1_AA_TYPE32 T1aa_bg=0;
99
/* The limit values for smart antialiasing */
100
float T1aa_smartlimit1=T1_AA_SMARTLIMIT1;
101
float T1aa_smartlimit2=T1_AA_SMARTLIMIT2;
102
int T1aa_SmartOn=0; /* We do not enable smart AA by default */
104
/* T1_AAInit: This function must be called whenever the T1aa_gray_val
105
or T1aa_bpp variables change, or the level changes. */
106
static int T1_AAInit ( int level )
110
int movelow=0, movehigh=0, indlow=0, indhigh=0;
112
/* Note: movelow, movehigh, indlow and indhigh take care for proper
113
byte swapping in dependence of endianess for level=4 */
114
if (level==T1_AA_NONE){
116
if (pFontBase->endian){
125
else if (T1aa_bpp==16){
126
if (pFontBase->endian){
137
if (level==T1_AA_HIGH){
140
if (pFontBase->endian){
153
else if (T1aa_bpp==16){
154
if (pFontBase->endian){
167
else if (T1aa_bpp==32){
171
for (i = 0; i < 256; i++) {
173
if (i & 0x80) T1aa_h_count[i] += indhigh;
174
if (i & 0x40) T1aa_h_count[i] += indhigh;
175
if (i & 0x20) T1aa_h_count[i] += indhigh;
176
if (i & 0x10) T1aa_h_count[i] += indhigh;
177
if (i & 0x08) T1aa_h_count[i] += indlow;
178
if (i & 0x04) T1aa_h_count[i] += indlow;
179
if (i & 0x02) T1aa_h_count[i] += indlow;
180
if (i & 0x01) T1aa_h_count[i] += indlow;
184
if (level == 2 && T1aa_bpp == 8) {
185
for (i0 = 0; i0 < 5; i0++)
186
for (i1 = 0; i1 < 5; i1++)
187
for (i2 = 0; i2 < 5; i2++)
188
for (i3 = 0; i3 < 5; i3++) {
189
((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4] = gv[i3];
190
((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4 + 1] = gv[i2];
191
((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4 + 2] = gv[i1];
192
((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4 + 3] = gv[i0];
194
for (i = 0; i < 256; i++) {
196
if (i & 0x80) T1aa_count[i] += 125;
197
if (i & 0x40) T1aa_count[i] += 125;
198
if (i & 0x20) T1aa_count[i] += 25;
199
if (i & 0x10) T1aa_count[i] += 25;
200
if (i & 0x08) T1aa_count[i] += 5;
201
if (i & 0x04) T1aa_count[i] += 5;
202
if (i & 0x02) T1aa_count[i] += 1;
203
if (i & 0x01) T1aa_count[i] += 1;
206
} else if (level == 2 && T1aa_bpp == 16) {
207
for (i0 = 0; i0 < 5; i0++)
208
for (i1 = 0; i1 < 5; i1++) {
209
((T1_AA_TYPE16 *)T1aa_lut)[(i0 * 5 + i1) * 2] = gv[i1];
210
((T1_AA_TYPE16 *)T1aa_lut)[(i0 * 5 + i1) * 2 + 1] = gv[i0];
212
for (i = 0; i < 256; i++) {
214
if (i & 0x80) T1aa_count[i] += 160;
215
if (i & 0x40) T1aa_count[i] += 160;
216
if (i & 0x20) T1aa_count[i] += 32;
217
if (i & 0x10) T1aa_count[i] += 32;
218
if (i & 0x08) T1aa_count[i] += 5;
219
if (i & 0x04) T1aa_count[i] += 5;
220
if (i & 0x02) T1aa_count[i] += 1;
221
if (i & 0x01) T1aa_count[i] += 1;
224
} else if (level == 2 && T1aa_bpp == 32) {
225
for (i0 = 0; i0 < 5; i0++)
226
((T1_AA_TYPE32 *)T1aa_lut)[i0] = gv[i0];
227
for (i = 0; i < 256; i++) {
229
if (i & 0x80) T1aa_count[i] += 512;
230
if (i & 0x40) T1aa_count[i] += 512;
231
if (i & 0x20) T1aa_count[i] += 64;
232
if (i & 0x10) T1aa_count[i] += 64;
233
if (i & 0x08) T1aa_count[i] += 8;
234
if (i & 0x04) T1aa_count[i] += 8;
235
if (i & 0x02) T1aa_count[i] += 1;
236
if (i & 0x01) T1aa_count[i] += 1;
240
else if (level == 4 && T1aa_bpp == 8) {
241
for (i0 = 0; i0 < 17; i0++){ /* i0 indexes higher nibble */
242
for (i1 = 0; i1 < 17; i1++){ /* i1 indixes lower nibble */
243
((char *)T1aa_h_lut)[(i0 * 17 + i1) * 4 + movelow] = gv_h[i1];
244
((char *)T1aa_h_lut)[(i0 * 17 + i1) * 4 + movehigh] = gv_h[i0];
249
else if (level == 4 && T1aa_bpp == 16) {
250
for (i0 = 0; i0 < 17; i0++){ /* i0 indexes higher nibble */
251
for (i1 = 0; i1 < 17; i1++){ /* i1 indixes lower nibble */
252
((T1_AA_TYPE16 *)T1aa_h_lut)[(i0 * 17 + i1) * 2 + movelow] = gv_h[i1];
253
((T1_AA_TYPE16 *)T1aa_h_lut)[(i0 * 17 + i1) * 2 + movehigh] = gv_h[i0];
258
else if (level == 4 && T1aa_bpp == 32) {
259
for (i0 = 0; i0 < 17; i0++){ /* i0 indexes higher nibble */
260
for (i1 = 0; i1 < 17; i1++){ /* i1 indixes lower nibble */
261
((T1_AA_TYPE32 *)T1aa_h_lut)[(i0 * 17 + i1)] = gv_h[i1];
266
else if (level == 1 && T1aa_bpp == 8) {
267
for (i0=0; i0<16; i0++) {
268
((char *)T1aa_n_lut)[i0*4+movelow]=gv_n[i0 & 0x01];
269
((char *)T1aa_n_lut)[i0*4+movelow+1]=gv_n[(i0>>1) & 0x01];
270
((char *)T1aa_n_lut)[i0*4+movelow+2]=gv_n[(i0>>2) & 0x01];
271
((char *)T1aa_n_lut)[i0*4+movelow+3]=gv_n[(i0>>3) & 0x01];
275
else if (level == 1 && T1aa_bpp == 16) {
276
for (i0=0; i0<4; i0++) {
277
((T1_AA_TYPE16 *)T1aa_n_lut)[i0*2]=gv_n[i0 & 0x01];
278
((T1_AA_TYPE16 *)T1aa_n_lut)[i0*2+1]=gv_n[(i0>>1) & 0x01];
282
else if (level == 1 && T1aa_bpp == 32) {
283
for ( i0=0; i0<2; i0++) {
284
((T1_AA_TYPE32 *)T1aa_n_lut)[i0]=gv_n[i0];
289
/* unsupported combination of level and bpp -> we set T1_errno and
290
put an entry into the logfile! */
291
T1_errno=T1ERR_INVALID_PARAMETER;
292
sprintf( err_warn_msg_buf,
293
"Unsupported AA specification: level=%d, bpp=%d",
295
T1_PrintLog( "T1_AAInit()", err_warn_msg_buf, T1LOG_WARNING);
301
/* T1_AADoLine: Create a single scanline of antialiased output. The
302
(x, y) arguments refer to the number of pixels in the input image
303
to convert down. The width argument is the number of bytes
304
separating scanlines in the input. The quantity hcorr describes the
305
number of subpixels. It is the shift of the oversampled bitmap to
307
static void T1_AADoLine ( int level, int x, int y, int width,
308
char *c_in_ptr, char *target_ptr, int hcorr )
315
unsigned char bcarry1=0, bcarry2=0, bcarry3=0, bcarry4=0;
317
static char *align_buf = NULL;
318
static int align_buf_size = 0;
319
unsigned char *in_ptr;
326
/* We convert the input pointer to unsigned since we use it as index! */
327
in_ptr=(unsigned char*)c_in_ptr;
330
if ((long)target_ptr & 3){
331
/* calculate new_size (size in bytes of output buffer */
332
if (level == T1_AA_LOW){
333
new_size=((x + hcorr + 1) >> 1) * (T1aa_bpp >> 3);
335
else{ /* T1_AA_HIGH */
336
new_size = ((x + hcorr + 3) >> 2) * (T1aa_bpp >> 3);
338
if (new_size > align_buf_size)
342
/* Note: we allocate 12 more than necessary to have tolerance
343
at the end of line */
344
align_buf = (char *)malloc(new_size+12);
345
align_buf_size = new_size;
353
/* size: The number of valid byte in the input string, i.e., the number of bytes
354
partially filled with pixels before shifting with hcorr.
355
mod: Is 1 if after shifting with hcorr the last byte in the input line has an
359
if (level == T1_AA_LOW) {
361
mod=(x+hcorr)>(size*8) ? 1 : 0;
365
for (i = 0; i < size; i++) {
366
((T1_AA_TYPE32 *)optr)[i] =
367
T1aa_lut[(T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
368
T1aa_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)])];
369
bcarry1=in_ptr[i]>>(8-hcorr);
370
bcarry2=in_ptr[i+width]>>(8-hcorr);
373
bcarry1=in_ptr[0]<<hcorr;
374
bcarry2=in_ptr[width]<<hcorr;
378
for (i = 0; i < size; i++) {
379
((T1_AA_TYPE32 *)optr)[i] =
380
T1aa_lut[(T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)])];
381
bcarry1=in_ptr[i]>>(8-hcorr);
384
bcarry1=in_ptr[0]<<hcorr;
389
((T1_AA_TYPE32 *)optr)[i]=T1aa_lut[(T1aa_count[bcarry1] +
390
T1aa_count[bcarry2])];
392
((T1_AA_TYPE32 *)optr)[i]=T1aa_lut[(T1aa_count[bcarry1])];
395
else if (T1aa_bpp == 16) {
397
for (i = 0; i < size; i++) {
398
count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)]
399
+ T1aa_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)];
400
((T1_AA_TYPE32 *)optr)[i * 2] = T1aa_lut[count & 31];
401
((T1_AA_TYPE32 *)optr)[i * 2 + 1] = T1aa_lut[count >> 5];
402
bcarry1=in_ptr[i]>>(8-hcorr);
403
bcarry2=in_ptr[i+width]>>(8-hcorr);
406
bcarry1=in_ptr[0]<<hcorr;
407
bcarry2=in_ptr[width]<<hcorr;
411
for (i = 0; i < size; i++) {
412
count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)];
413
((T1_AA_TYPE32 *)optr)[i * 2] = T1aa_lut[count & 31];
414
((T1_AA_TYPE32 *)optr)[i * 2 + 1] = T1aa_lut[count >> 5];
415
bcarry1=in_ptr[i]>>(8-hcorr);
418
bcarry1=in_ptr[0]<<hcorr;
423
count = T1aa_count[bcarry1] +
426
count = T1aa_count[bcarry1];
427
((T1_AA_TYPE32 *)optr)[i * 2] = T1aa_lut[count & 31];
428
((T1_AA_TYPE32 *)optr)[i * 2 + 1] = T1aa_lut[count >> 5];
431
else if (T1aa_bpp == 32) {
433
for (i = 0; i < size; i++) {
434
count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
435
T1aa_count[(unsigned char)((in_ptr[i+width]<<hcorr)|bcarry2)];
436
((T1_AA_TYPE32 *)optr)[i * 4] = T1aa_lut[count & 7];
437
((T1_AA_TYPE32 *)optr)[i * 4 + 1] = T1aa_lut[(count >> 3) & 7];
438
((T1_AA_TYPE32 *)optr)[i * 4 + 2] = T1aa_lut[(count >> 6) & 7];
439
((T1_AA_TYPE32 *)optr)[i * 4 + 3] = T1aa_lut[(count >> 9) & 7];
440
bcarry1=in_ptr[i]>>(8-hcorr);
441
bcarry2=in_ptr[i+width]>>(8-hcorr);
444
bcarry1=in_ptr[0]<<hcorr;
445
bcarry2=in_ptr[width]<<hcorr;
449
for (i = 0; i < size; i++) {
450
count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)];
451
((T1_AA_TYPE32 *)optr)[i * 4] = T1aa_lut[count & 7];
452
((T1_AA_TYPE32 *)optr)[i * 4 + 1] = T1aa_lut[(count >> 3) & 7];
453
((T1_AA_TYPE32 *)optr)[i * 4 + 2] = T1aa_lut[(count >> 6) & 7];
454
((T1_AA_TYPE32 *)optr)[i * 4 + 3] = T1aa_lut[(count >> 9) & 7];
455
bcarry1=in_ptr[i]>>(8-hcorr);
458
bcarry1=in_ptr[0]<<hcorr;
463
count = T1aa_count[bcarry1] +
467
count = T1aa_count[bcarry1];
469
((T1_AA_TYPE32 *)optr)[i * 4] = T1aa_lut[count & 7];
470
((T1_AA_TYPE32 *)optr)[i * 4 + 1] = T1aa_lut[(count >> 3) & 7];
471
((T1_AA_TYPE32 *)optr)[i * 4 + 2] = T1aa_lut[(count >> 6) & 7];
472
((T1_AA_TYPE32 *)optr)[i * 4 + 3] = T1aa_lut[(count >> 9) & 7];
476
else if (level==T1_AA_HIGH){
478
mod=(x+hcorr)>(size*8) ? 1 : 0;
482
for (i = 0; i < size; i++) {
483
((T1_AA_TYPE16 *)optr)[i] =
484
T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
485
T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] +
486
T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)] +
487
T1aa_h_count[(unsigned char)((in_ptr[i + 3*width]<<hcorr)|bcarry4)])];
488
bcarry1=in_ptr[i]>>(8-hcorr);
489
bcarry2=in_ptr[i+width]>>(8-hcorr);
490
bcarry3=in_ptr[i+2*width]>>(8-hcorr);
491
bcarry4=in_ptr[i+3*width]>>(8-hcorr);
495
for (i = 0; i < size; i++) {
496
((T1_AA_TYPE16 *)optr)[i] =
497
T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
498
T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] +
499
T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)])];
500
bcarry1=in_ptr[i]>>(8-hcorr);
501
bcarry2=in_ptr[i+width]>>(8-hcorr);
502
bcarry3=in_ptr[i+2*width]>>(8-hcorr);
506
for (i = 0; i < size; i++) {
507
((T1_AA_TYPE16 *)optr)[i] =
508
T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
509
T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)])];
510
bcarry1=in_ptr[i]>>(8-hcorr);
511
bcarry2=in_ptr[i+width]>>(8-hcorr);
515
for (i = 0; i < size; i++) {
516
((T1_AA_TYPE16 *)optr)[i] =
517
T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)])];
518
bcarry1=in_ptr[i]>>(8-hcorr);
523
((T1_AA_TYPE16 *)optr)[i] =
524
T1aa_h_lut[(T1aa_h_count[bcarry1] +
525
T1aa_h_count[bcarry2] +
526
T1aa_h_count[bcarry3] +
527
T1aa_h_count[bcarry4])];
529
((T1_AA_TYPE16 *)optr)[i] =
530
T1aa_h_lut[(T1aa_h_count[bcarry1] +
531
T1aa_h_count[bcarry2] +
532
T1aa_h_count[bcarry3])];
534
((T1_AA_TYPE16 *)optr)[i] =
535
T1aa_h_lut[(T1aa_h_count[bcarry1] +
536
T1aa_h_count[bcarry2])];
538
((T1_AA_TYPE16 *)optr)[i] =
539
T1aa_h_lut[(T1aa_h_count[bcarry1])];
541
} else if (T1aa_bpp == 16) {
543
for (i = 0; i < size; i++) {
544
((T1_AA_TYPE32 *)optr)[i] =
545
T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
546
T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] +
547
T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)] +
548
T1aa_h_count[(unsigned char)((in_ptr[i + 3*width]<<hcorr)|bcarry4)])];
549
bcarry1=in_ptr[i]>>(8-hcorr);
550
bcarry2=in_ptr[i+width]>>(8-hcorr);
551
bcarry3=in_ptr[i+2*width]>>(8-hcorr);
552
bcarry4=in_ptr[i+3*width]>>(8-hcorr);
555
bcarry1=in_ptr[0]<<hcorr;
556
bcarry2=in_ptr[width]<<hcorr;
557
bcarry3=in_ptr[2*width]<<hcorr;
558
bcarry4=in_ptr[3*width]<<hcorr;
562
for (i = 0; i < size; i++) {
563
((T1_AA_TYPE32 *)optr)[i] =
564
T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
565
T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] +
566
T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)])];
567
bcarry1=in_ptr[i]>>(8-hcorr);
568
bcarry2=in_ptr[i+2*width]>>(8-hcorr);
569
bcarry3=in_ptr[i+3*width]>>(8-hcorr);
572
bcarry1=in_ptr[0]<<hcorr;
573
bcarry2=in_ptr[width]<<hcorr;
574
bcarry3=in_ptr[2*width]<<hcorr;
578
for (i = 0; i < size; i++) {
579
((T1_AA_TYPE32 *)optr)[i] =
580
T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
581
T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)])];
582
bcarry1=in_ptr[i]>>(8-hcorr);
583
bcarry2=in_ptr[i+width]>>(8-hcorr);
586
bcarry1=in_ptr[0]<<hcorr;
587
bcarry2=in_ptr[width]<<hcorr;
591
for (i = 0; i < size; i++) {
592
((T1_AA_TYPE32 *)optr)[i] =
593
T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)])];
594
bcarry1=in_ptr[i]>>(8-hcorr);
597
bcarry1=in_ptr[0]<<hcorr;
602
((T1_AA_TYPE32 *)optr)[i] =
603
T1aa_h_lut[(T1aa_h_count[bcarry1] +
604
T1aa_h_count[bcarry2] +
605
T1aa_h_count[bcarry3] +
606
T1aa_h_count[bcarry4])];
608
((T1_AA_TYPE32 *)optr)[i] =
609
T1aa_h_lut[(T1aa_h_count[bcarry1] +
610
T1aa_h_count[bcarry2] +
611
T1aa_h_count[bcarry3])];
613
((T1_AA_TYPE32 *)optr)[i] =
614
T1aa_h_lut[(T1aa_h_count[bcarry1] +
615
T1aa_h_count[bcarry2])];
617
((T1_AA_TYPE32 *)optr)[i] =
618
T1aa_h_lut[(T1aa_h_count[bcarry1])];
621
else if (T1aa_bpp == 32) {
623
for (i = 0; i < size; i++) {
624
count=T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
625
T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] +
626
T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)] +
627
T1aa_h_count[(unsigned char)((in_ptr[i + 3*width]<<hcorr)|bcarry4)];
628
((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17];
629
((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17];
630
bcarry1=in_ptr[i]>>(8-hcorr);
631
bcarry2=in_ptr[i+width]>>(8-hcorr);
632
bcarry3=in_ptr[i+2*width]>>(8-hcorr);
633
bcarry4=in_ptr[i+3*width]>>(8-hcorr);
636
bcarry1=in_ptr[0]<<hcorr;
637
bcarry2=in_ptr[width]<<hcorr;
638
bcarry3=in_ptr[2*width]<<hcorr;
639
bcarry4=in_ptr[3*width]<<hcorr;
643
for (i = 0; i < size; i++) {
644
count=T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
645
T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] +
646
T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)];
647
((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17];
648
((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17];
649
bcarry1=in_ptr[i]>>(8-hcorr);
650
bcarry2=in_ptr[i+width]>>(8-hcorr);
651
bcarry3=in_ptr[i+2*width]>>(8-hcorr);
654
bcarry1=in_ptr[0]<<hcorr;
655
bcarry2=in_ptr[width]<<hcorr;
656
bcarry3=in_ptr[2*width]<<hcorr;
660
for (i = 0; i < size; i++) {
661
count=T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] +
662
T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)];
663
((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17];
664
((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17];
665
bcarry1=in_ptr[i]>>(8-hcorr);
666
bcarry2=in_ptr[i+width]>>(8-hcorr);
669
bcarry1=in_ptr[0]<<hcorr;
670
bcarry2=in_ptr[width]<<hcorr;
674
for (i = 0; i < size; i++) {
675
count=T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)];
676
((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17];
677
((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17];
678
bcarry1=in_ptr[i]>>(8-hcorr);
681
bcarry1=in_ptr[0]<<hcorr;
686
count=T1aa_h_count[bcarry1] +
687
T1aa_h_count[bcarry2] +
688
T1aa_h_count[bcarry3] +
689
T1aa_h_count[bcarry4];
692
count=T1aa_h_count[bcarry1] +
693
T1aa_h_count[bcarry2] +
694
T1aa_h_count[bcarry3];
696
count=T1aa_h_count[bcarry1] +
697
T1aa_h_count[bcarry2];
699
count=T1aa_h_count[bcarry1];
700
((T1_AA_TYPE32 *)optr)[2*i] = T1aa_h_lut[count % 17];
701
((T1_AA_TYPE32 *)optr)[2*i+1] = T1aa_h_lut[count / 17];
706
/* Copy to target if necessary */
707
if ((long)target_ptr & 3){
708
memcpy (target_ptr, align_buf, new_size);
715
/* T1_DoLine(): Generate a scanline of bytes from a scanline of bits */
716
static void T1_DoLine ( long wd, long paddedW, char *ptr, register char *target_ptr )
719
register unsigned char *in_ptr;
720
T1_AA_TYPE16 *starget_ptr;
721
T1_AA_TYPE32 *ltarget_ptr;
723
in_ptr=(unsigned char *)ptr;
726
for ( j=0; j<wd; j++ ){
727
*target_ptr++=T1aa_n_lut[((in_ptr[j/8])>>j%8)&0x0F];
730
else if (T1aa_bpp==16) {
731
starget_ptr=(T1_AA_TYPE16 *)target_ptr;
732
for ( j=0; j<wd; j++){
733
*starget_ptr++=T1aa_n_lut[((in_ptr[j/8])>>j%8)&0x03];
736
else if (T1aa_bpp==32) {
737
ltarget_ptr=(T1_AA_TYPE32 *)target_ptr;
738
for ( j=0; j<wd; j++)
739
*ltarget_ptr++=T1aa_n_lut[((in_ptr[j/8])>>j%8)&0x01];
746
/* T1_AASetChar(...): Generate the anti-aliased bitmap for a character */
747
GLYPH *T1_AASetChar( int FontID, char charcode, float size,
748
T1_TMATRIX *transform)
751
GLYPH *glyph; /* pointer to bitmap glyph */
752
static GLYPH aaglyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */
753
long asc, dsc, ht, wd;
755
long n_horz, n_horz_pad, n_vert, n_asc, n_dsc;
761
long lsb, aalsb, aahstart;
765
FONTSIZEDEPS *font_ptr=NULL;
766
unsigned char ucharcode;
769
/* Reset character glyph, if necessary */
770
if (aaglyph.bits!=NULL){
774
aaglyph.metrics.leftSideBearing=0;
775
aaglyph.metrics.rightSideBearing=0;
776
aaglyph.metrics.advanceX=0;
777
aaglyph.metrics.advanceY=0;
778
aaglyph.metrics.ascent=0;
779
aaglyph.metrics.descent=0;
780
aaglyph.pFontCacheInfo=NULL;
781
aaglyph.bpp=T1aa_bpp;
786
/* Check for smart antialiasing */
787
savelevel=T1aa_level;
789
if (size>=T1aa_smartlimit2) {
790
T1aa_level=T1_AA_NONE;
792
else if (size>=T1aa_smartlimit1) {
793
T1aa_level=T1_AA_LOW;
796
T1aa_level=T1_AA_HIGH;
801
/* The following code is only exectued if caching of antialiased
802
chracters is enabled. */
803
/* Check if char is in cache */
804
if ((pFontBase->t1lib_flags & T1_AA_CACHING)) {
805
if (transform==NULL){
806
/* if size/aa is not existent we create it */
807
if ((font_ptr=T1int_QueryFontSize( FontID, size, T1aa_level))==NULL){
808
/* We create the required size struct and leave the rest
810
font_ptr=T1int_CreateNewFontSize( FontID, size, T1aa_level);
812
T1_errno=T1ERR_ALLOC_MEM;
813
T1aa_level=savelevel;
817
else {/* size is already existent in cache */
818
if (font_ptr->pFontCache[ucharcode].bits != NULL){
819
/* Character is already in Chache -> create a copy of cache
820
and return a pointer to the result: */
821
memcpy( &aaglyph, &(font_ptr->pFontCache[ucharcode]), sizeof(GLYPH));
822
memsize = (aaglyph.metrics.ascent-aaglyph.metrics.descent) *
823
PAD((aaglyph.metrics.rightSideBearing-aaglyph.metrics.leftSideBearing) *
824
T1aa_bpp,pFontBase->bitmap_pad)/8;
825
aaglyph.bits = (char *)malloc(memsize*sizeof( char));
826
if (aaglyph.bits == NULL){
827
T1_errno=T1ERR_ALLOC_MEM;
828
T1aa_level=savelevel;
831
memcpy( aaglyph.bits, font_ptr->pFontCache[ucharcode].bits, memsize);
835
} /* (transform==NULL) */
836
} /* T1_AA_CACHING */
839
/* First, call routine to rasterize character, all error checking is
840
done in this function: */
841
if ((glyph=T1_SetChar( FontID, charcode, T1aa_level*size, transform))==NULL){
843
T1aa_level=savelevel;
844
return(NULL); /* An error occured */
847
/* In case there are no black pixels, we simply set the dimensions and
849
if ( glyph->bits == NULL) {
851
aaglyph.metrics.leftSideBearing=0;
852
aaglyph.metrics.rightSideBearing=0;
853
aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
854
aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
855
aaglyph.metrics.ascent=0;
856
aaglyph.metrics.descent=0;
857
aaglyph.pFontCacheInfo=NULL;
858
/* restore level and return */
859
T1aa_level=savelevel;
863
/* Get dimensions of bitmap: */
864
asc=glyph->metrics.ascent;
865
dsc=glyph->metrics.descent;
866
lsb=glyph->metrics.leftSideBearing;
868
wd=glyph->metrics.rightSideBearing-lsb;
872
if (T1aa_level==T1_AA_NONE){
873
/* we only convert bitmap to bytemap */
875
aaglyph.bpp=T1aa_bpp;
876
/* Compute scanline length and such */
877
n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3;
878
/* Allocate memory for glyph */
879
memsize = n_horz_pad*ht*8;
880
/* aaglyph.bits = (char *)malloc(memsize*sizeof( char)); */
881
aaglyph.bits = (char *)malloc(memsize*sizeof( char));
882
if (aaglyph.bits == NULL) {
883
T1_errno=T1ERR_ALLOC_MEM;
885
T1aa_level=savelevel;
888
paddedW=PAD(wd,pFontBase->bitmap_pad)>>3;
890
target_ptr=aaglyph.bits;
891
for (i = 0; i < ht; i++) {
892
T1_DoLine ( wd, paddedW, ptr, target_ptr );
894
target_ptr += n_horz_pad;
897
T1aa_level=savelevel;
902
/* Set some looping parameters for subsampling */
904
aalsb=lsb/T1aa_level-1;
905
aahstart=T1aa_level+(lsb%T1aa_level);
908
aalsb=lsb/T1aa_level;
909
aahstart=lsb%T1aa_level;
912
/* The horizontal number of steps: */
913
n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level;
914
/* And the padded value */
915
n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3;
917
/* vertical number of steps: */
918
if (asc % T1aa_level){ /* not aligned */
920
n_asc=asc/T1aa_level+1;
921
v_start=asc % T1aa_level;
924
n_asc=asc/T1aa_level;
925
v_start=T1aa_level + (asc % T1aa_level);
929
n_asc=asc/T1aa_level;
932
if (dsc % T1aa_level){ /* not aligned */
934
n_dsc=dsc/T1aa_level-1;
935
v_end=-(dsc % T1aa_level);
938
n_dsc=dsc/T1aa_level;
939
v_end=T1aa_level - (dsc % T1aa_level);
943
n_dsc=dsc/T1aa_level;
946
/* the total number of lines: */
949
/* Allocate memory for glyph */
950
memsize = n_horz_pad*n_vert;
952
/* Note: we allocate 12 bytes more than necessary */
953
aaglyph.bits = (char *)malloc(memsize*sizeof( char) +12);
954
if (aaglyph.bits == NULL) {
955
T1_errno=T1ERR_ALLOC_MEM;
957
T1aa_level=savelevel;
962
paddedW=PAD(wd,pFontBase->bitmap_pad)/8;
964
target_ptr=aaglyph.bits;
966
/* We must check for n_vert==1 because then both v_start and v_end could / will
967
affect the same AA scan line. Because I'm forgetful, a reminder:
969
v_end | 000000000000000000000
970
| 111111111111111111111 ^
971
Y 111111111111111111111 |
972
000000000000000000000 | v_start
974
In order to count the v_end from bottom to top, we express it as (T1aa_level-v_end).
975
The number of rows to take into account is then v_start-(T1aa_level-v_end).
978
v_start=v_start - (T1aa_level - v_end);
982
for (i = 0; i < n_vert; i++) {
985
else if (i==n_vert-1)
989
T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart );
991
target_ptr += n_horz_pad;
994
/* .. and set them in aaglyph */
995
aaglyph.metrics.leftSideBearing=aalsb;
996
aaglyph.metrics.rightSideBearing=aalsb + n_horz;
997
aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
998
aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
999
aaglyph.metrics.ascent=n_asc;
1000
aaglyph.metrics.descent=n_dsc;
1001
aaglyph.pFontCacheInfo=NULL;
1004
if ((pFontBase->t1lib_flags & T1_AA_CACHING) && (transform==NULL)) {
1005
/* Put char into cache area */
1006
memcpy( &(font_ptr->pFontCache[ucharcode]), &aaglyph, sizeof(GLYPH));
1007
font_ptr->pFontCache[ucharcode].bits = (char *)malloc(memsize*sizeof( char));
1008
if (font_ptr->pFontCache[ucharcode].bits == NULL){
1009
T1_errno=T1ERR_ALLOC_MEM;
1010
T1aa_level=savelevel;
1013
memcpy( font_ptr->pFontCache[ucharcode].bits, aaglyph.bits, memsize);
1017
T1aa_level=savelevel;
1024
/* T1_AASetString(...): Generate the antialiased bitmap for a
1025
string of characters */
1026
GLYPH *T1_AASetString( int FontID, char *string, int len,
1027
long spaceoff, int modflag, float size,
1028
T1_TMATRIX *transform)
1030
GLYPH *glyph; /* pointer to bitmap glyph */
1031
static GLYPH aastring_glyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */
1032
long asc, dsc, ht, wd;
1034
long n_horz, n_horz_pad, n_vert, n_asc, n_dsc;
1035
long v_start, v_end;
1040
long lsb, aalsb, aahstart;
1046
/* Reset character glyph, if necessary */
1047
if (aastring_glyph.bits!=NULL){
1048
free(aastring_glyph.bits);
1049
aastring_glyph.bits=NULL;
1051
aastring_glyph.metrics.leftSideBearing=0;
1052
aastring_glyph.metrics.rightSideBearing=0;
1053
aastring_glyph.metrics.advanceX=0;
1054
aastring_glyph.metrics.advanceY=0;
1055
aastring_glyph.metrics.ascent=0;
1056
aastring_glyph.metrics.descent=0;
1057
aastring_glyph.pFontCacheInfo=NULL;
1058
aastring_glyph.bpp=T1aa_bpp;
1061
/* Check for smart antialiasing */
1062
savelevel=T1aa_level;
1064
if (size>=T1aa_smartlimit2) {
1065
T1aa_level=T1_AA_NONE;
1067
else if (size>=T1aa_smartlimit1) {
1068
T1aa_level=T1_AA_LOW;
1071
T1aa_level=T1_AA_HIGH;
1075
/* First, call routine to rasterize character, all error checking is
1076
done in this function: */
1077
if ((glyph=T1_SetString( FontID, string, len, spaceoff,
1078
modflag, T1aa_level*size, transform))==NULL){
1080
T1aa_level=savelevel;
1081
return(NULL); /* An error occured */
1084
/* In case there are no black pixels, we simply set the dimensions and
1086
if ( glyph->bits == NULL) {
1087
aastring_glyph.bits=NULL;
1088
aastring_glyph.metrics.leftSideBearing=0;
1089
aastring_glyph.metrics.rightSideBearing=0;
1090
aastring_glyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
1091
aastring_glyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
1092
aastring_glyph.metrics.ascent=0;
1093
aastring_glyph.metrics.descent=0;
1094
aastring_glyph.pFontCacheInfo=NULL;
1095
/* restore level and return */
1096
T1aa_level=savelevel;
1097
return(&aastring_glyph);
1101
/* Get dimensions of bitmap: */
1102
asc=glyph->metrics.ascent;
1103
dsc=glyph->metrics.descent;
1104
lsb=glyph->metrics.leftSideBearing;
1106
wd=glyph->metrics.rightSideBearing-lsb;
1108
if (T1aa_level==T1_AA_NONE){
1109
/* we only convert bitmap to bytemap */
1110
aastring_glyph=*glyph;
1111
aastring_glyph.bpp=T1aa_bpp;
1112
/* Compute scanline length and such */
1113
n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3;
1114
/* Allocate memory for glyph */
1115
memsize = n_horz_pad*ht*8;
1116
aastring_glyph.bits = (char *)malloc(memsize*sizeof( char));
1117
if (aastring_glyph.bits == NULL) {
1118
T1_errno=T1ERR_ALLOC_MEM;
1120
T1aa_level=savelevel;
1123
paddedW=PAD(wd,pFontBase->bitmap_pad)>>3;
1125
target_ptr=aastring_glyph.bits;
1126
for (i = 0; i < ht; i++) {
1127
T1_DoLine ( wd, paddedW, ptr, target_ptr );
1129
target_ptr += n_horz_pad;
1132
T1aa_level=savelevel;
1133
return(&aastring_glyph);
1137
/* Set some looping parameters for subsampling */
1139
aalsb=lsb/T1aa_level-1;
1140
aahstart=T1aa_level+(lsb%T1aa_level);
1143
aalsb=lsb/T1aa_level;
1144
aahstart=lsb%T1aa_level;
1147
/* The horizontal number of steps: */
1148
n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level;
1149
/* And the padded value */
1150
n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3;
1152
/* vertical number of steps: */
1153
if (asc % T1aa_level){ /* not aligned */
1155
n_asc=asc/T1aa_level+1;
1156
v_start=asc % T1aa_level;
1159
n_asc=asc/T1aa_level;
1160
v_start=T1aa_level + (asc % T1aa_level);
1164
n_asc=asc/T1aa_level;
1167
if (dsc % T1aa_level){ /* not aligned */
1169
n_dsc=dsc/T1aa_level-1;
1170
v_end=-(dsc % T1aa_level);
1173
n_dsc=dsc/T1aa_level;
1174
v_end=T1aa_level - (dsc % T1aa_level);
1178
n_dsc=dsc/T1aa_level;
1181
/* the total number of lines: */
1184
/* Allocate memory for glyph */
1185
memsize = n_horz_pad*n_vert;
1187
/* Note: we allocate 12 bytes more than necessary */
1188
aastring_glyph.bits = (char *)malloc(memsize*sizeof( char) +12);
1189
if (aastring_glyph.bits == NULL) {
1190
T1_errno=T1ERR_ALLOC_MEM;
1194
paddedW=PAD(wd,pFontBase->bitmap_pad)/8;
1196
target_ptr=aastring_glyph.bits;
1198
/* We must check for n_vert==1 because then both v_start and v_end could / will
1199
affect the same AA scan line.
1202
v_start=v_start - (T1aa_level - v_end);
1206
for (i = 0; i < n_vert; i++) {
1209
else if (i==n_vert-1)
1213
T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart );
1215
target_ptr += n_horz_pad;
1218
/* .. and set them in aastring_glyph */
1219
aastring_glyph.metrics.leftSideBearing=aalsb;
1220
aastring_glyph.metrics.rightSideBearing=aalsb + n_horz;
1221
aastring_glyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
1222
aastring_glyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
1223
aastring_glyph.metrics.ascent=n_asc;
1224
aastring_glyph.metrics.descent=n_dsc;
1225
aastring_glyph.pFontCacheInfo=NULL;
1228
T1aa_level=savelevel;
1230
return(&aastring_glyph);
1235
/* T1_AASetRect(): Raster a rectangle, whose size is given in charspace units.
1236
The resulting glyph does not cause any escapement. */
1237
GLYPH* T1_AASetRect( int FontID, float size,
1238
float width, float height, T1_TMATRIX *transform)
1240
GLYPH *glyph; /* pointer to bitmap glyph */
1241
static GLYPH aaglyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */
1242
long asc, dsc, ht, wd;
1244
long n_horz, n_horz_pad, n_vert, n_asc, n_dsc;
1245
long v_start, v_end;
1250
long lsb, aalsb, aahstart;
1256
/* Reset character glyph, if necessary */
1257
if (aaglyph.bits!=NULL){
1261
aaglyph.metrics.leftSideBearing=0;
1262
aaglyph.metrics.rightSideBearing=0;
1263
aaglyph.metrics.advanceX=0;
1264
aaglyph.metrics.advanceY=0;
1265
aaglyph.metrics.ascent=0;
1266
aaglyph.metrics.descent=0;
1267
aaglyph.pFontCacheInfo=NULL;
1268
aaglyph.bpp=T1aa_bpp;
1271
/* Check for smart antialiasing */
1272
savelevel=T1aa_level;
1274
if (size>=T1aa_smartlimit2) {
1275
T1aa_level=T1_AA_NONE;
1277
else if (size>=T1aa_smartlimit1) {
1278
T1aa_level=T1_AA_LOW;
1281
T1aa_level=T1_AA_HIGH;
1286
/* First, call routine to rasterize character, all error checking is
1287
done in this function: */
1288
if ((glyph=T1_SetRect( FontID, T1aa_level*size, width, height, transform))==NULL){
1290
T1aa_level=savelevel;
1291
return(NULL); /* An error occured */
1294
/* In case there are no black pixels, we simply set the dimensions and
1296
if ( glyph->bits == NULL) {
1298
aaglyph.metrics.leftSideBearing=0;
1299
aaglyph.metrics.rightSideBearing=0;
1300
aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
1301
aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
1302
aaglyph.metrics.ascent=0;
1303
aaglyph.metrics.descent=0;
1304
aaglyph.pFontCacheInfo=NULL;
1305
/* restore level and return */
1306
T1aa_level=savelevel;
1310
/* Get dimensions of bitmap: */
1311
asc=glyph->metrics.ascent;
1312
dsc=glyph->metrics.descent;
1313
lsb=glyph->metrics.leftSideBearing;
1315
wd=glyph->metrics.rightSideBearing-lsb;
1317
if (T1aa_level==T1_AA_NONE){
1318
/* we only convert bitmap to bytemap */
1320
aaglyph.bpp=T1aa_bpp;
1321
/* Compute scanline length and such */
1322
n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3;
1323
/* Allocate memory for glyph */
1324
memsize = n_horz_pad*ht*8;
1325
/* aaglyph.bits = (char *)malloc(memsize*sizeof( char)); */
1326
aaglyph.bits = (char *)malloc(memsize*sizeof( char));
1327
if (aaglyph.bits == NULL) {
1328
T1_errno=T1ERR_ALLOC_MEM;
1330
T1aa_level=savelevel;
1333
paddedW=PAD(wd,pFontBase->bitmap_pad)>>3;
1335
target_ptr=aaglyph.bits;
1336
for (i = 0; i < ht; i++) {
1337
T1_DoLine ( wd, paddedW, ptr, target_ptr );
1339
target_ptr += n_horz_pad;
1342
T1aa_level=savelevel;
1347
/* Set some looping parameters for subsampling */
1349
aalsb=lsb/T1aa_level-1;
1350
aahstart=T1aa_level+(lsb%T1aa_level);
1353
aalsb=lsb/T1aa_level;
1354
aahstart=lsb%T1aa_level;
1357
/* The horizontal number of steps: */
1358
n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level;
1359
/* And the padded value */
1360
n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3;
1362
/* vertical number of steps: */
1363
if (asc % T1aa_level){ /* not aligned */
1365
n_asc=asc/T1aa_level+1;
1366
v_start=asc % T1aa_level;
1369
n_asc=asc/T1aa_level;
1370
v_start=T1aa_level + (asc % T1aa_level);
1374
n_asc=asc/T1aa_level;
1377
if (dsc % T1aa_level){ /* not aligned */
1379
n_dsc=dsc/T1aa_level-1;
1380
v_end=-(dsc % T1aa_level);
1383
n_dsc=dsc/T1aa_level;
1384
v_end=T1aa_level - (dsc % T1aa_level);
1388
n_dsc=dsc/T1aa_level;
1391
/* the total number of lines: */
1394
/* Allocate memory for glyph */
1395
memsize = n_horz_pad*n_vert;
1397
/* Note: we allocate 12 bytes more than necessary */
1398
aaglyph.bits = (char *)malloc(memsize*sizeof( char) +12);
1399
if (aaglyph.bits == NULL) {
1400
T1_errno=T1ERR_ALLOC_MEM;
1402
T1aa_level=savelevel;
1407
paddedW=PAD(wd,pFontBase->bitmap_pad)/8;
1409
target_ptr=aaglyph.bits;
1411
/* We must check for n_vert==1 because then both v_start and v_end could / will
1412
affect the same AA scan line.
1415
v_start=v_start - (T1aa_level - v_end);
1419
for (i = 0; i < n_vert; i++) {
1422
else if (i==n_vert-1)
1426
T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart );
1428
target_ptr += n_horz_pad;
1431
/* .. and set them in aaglyph */
1432
aaglyph.metrics.leftSideBearing=aalsb;
1433
aaglyph.metrics.rightSideBearing=aalsb + n_horz;
1434
aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
1435
aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
1436
aaglyph.metrics.ascent=n_asc;
1437
aaglyph.metrics.descent=n_dsc;
1438
aaglyph.pFontCacheInfo=NULL;
1441
T1aa_level=savelevel;
1449
/* T1_AASetGrayValues(): Sets the byte values that are put into the
1450
pixel position for the respective entries:
1451
Returns 0 if successfull.
1453
int T1_AASetGrayValues(unsigned long white,
1454
unsigned long gray75,
1455
unsigned long gray50,
1456
unsigned long gray25,
1457
unsigned long black)
1460
if (T1_CheckForInit()){
1461
T1_errno=T1ERR_OP_NOT_PERMITTED;
1465
gv[4]=(unsigned T1_AA_TYPE32)black; /* black value */
1466
gv[3]=(unsigned T1_AA_TYPE32)gray25; /* gray 25% value */
1467
gv[2]=(unsigned T1_AA_TYPE32)gray50; /* gray 50% value */
1468
gv[1]=(unsigned T1_AA_TYPE32)gray75; /* gray 75% value */
1469
gv[0]=(unsigned T1_AA_TYPE32)white; /* white value */
1473
if ((T1_AAInit( T1_AA_LOW)))
1481
/* T1_AAHSetGrayValues(): Sets the byte values that are put into the
1482
pixel position for the respective entries (for 17 gray levels):
1483
Returns 0 if successfull.
1485
int T1_AAHSetGrayValues( unsigned long *grayvals)
1489
if (T1_CheckForInit()){
1490
T1_errno=T1ERR_OP_NOT_PERMITTED;
1494
/* 0==white(background) ... 16==black(foreground) */
1495
for (i=0; i<17; i++){
1496
gv_h[i]=(unsigned T1_AA_TYPE32)grayvals[i];
1500
T1aa_bg=grayvals[0];
1502
if ((T1_AAInit( T1_AA_HIGH)))
1510
/* T1_AANSetGrayValues(): Sets the byte values that are put into the
1511
pixel position for the respective entries (for 2 gray levels):
1512
Returns 0 if successfull. This is for the case the non-antialiased
1513
"bytemaps" should be generated.
1515
int T1_AANSetGrayValues( unsigned long bg, unsigned long fg)
1518
if (T1_CheckForInit()){
1519
T1_errno=T1ERR_OP_NOT_PERMITTED;
1528
if ((T1_AAInit( T1_AA_NONE)))
1536
/* Get the current setting of graylevels for 2x antialiasing. The 5
1537
values are stored at address pgrayvals in order from background to
1539
int T1_AAGetGrayValues( long *pgrayvals)
1543
if (T1_CheckForInit()) {
1544
T1_errno=T1ERR_OP_NOT_PERMITTED;
1548
if (pgrayvals==NULL) {
1549
T1_errno=T1ERR_INVALID_PARAMETER;
1553
for ( i=0; i<5; i++) { /* bg (i=0) to fg (i=4) */
1562
/* Get the current setting of graylevels for 4x antialiasing. The 17
1563
values are stored at address pgrayvals in order from background to
1565
int T1_AAHGetGrayValues( long *pgrayvals)
1569
if (T1_CheckForInit()) {
1570
T1_errno=T1ERR_OP_NOT_PERMITTED;
1574
if (pgrayvals==NULL) {
1575
T1_errno=T1ERR_INVALID_PARAMETER;
1579
for ( i=0; i<17; i++) { /* bg (i=0) to fg (i=16) */
1580
pgrayvals[i]=gv_h[i];
1587
/* Get the current setting of graylevels for no antialiasing. The 2
1588
values are stored at address pgrayvals in order from background to
1590
int T1_AANGetGrayValues( long *pgrayvals)
1593
if (T1_CheckForInit()) {
1594
T1_errno=T1ERR_OP_NOT_PERMITTED;
1598
if (pgrayvals==NULL) {
1599
T1_errno=T1ERR_INVALID_PARAMETER;
1602
pgrayvals[0]=gv_n[0]; /* background */
1603
pgrayvals[1]=gv_n[1]; /* foreground */
1608
/* T1_AASetBitsPerPixel(): Sets the depths of the antialiased glyph
1609
pixel. Returns 0 if bpp is valid and -1 otherwise. If 24 is
1610
specified, meaning to be the depth rather than the bpp-value,
1611
automatically 32 bpp is chosen. */
1612
int T1_AASetBitsPerPixel( int bpp)
1615
if (T1_CheckForInit()){
1616
T1_errno=T1ERR_OP_NOT_PERMITTED;
1621
/* T1aa_level = 0; */
1631
if ((bpp==32)|(bpp==24)){
1636
T1_errno=T1ERR_INVALID_PARAMETER;
1641
/* T1_AAGetBitsPerPixel(): Return the number of bits per pixel set in
1644
int T1_AAGetBitsPerPixel( void)
1651
/* Set the Subsampling level for subsequent operations: */
1652
int T1_AASetLevel( int level)
1655
if (T1_CheckForInit()){
1656
T1_errno=T1ERR_OP_NOT_PERMITTED;
1660
if (level==T1_AA_LOW){
1661
T1aa_level=T1_AA_LOW;
1664
else if (level==T1_AA_HIGH){
1665
T1aa_level=T1_AA_HIGH;
1668
else if (level==T1_AA_NONE){
1669
T1aa_level=T1_AA_NONE;
1673
T1_errno=T1ERR_INVALID_PARAMETER;
1679
/* Get the current subsampling level */
1680
int T1_AAGetLevel( void)
1682
return( T1aa_level);
1686
/* T1_AAFillOutline(): Create a filled glyph from an outline description */
1687
GLYPH *T1_AAFillOutline( T1_OUTLINE *path, int modflag)
1690
GLYPH *glyph; /* pointer to bitmap glyph */
1691
static GLYPH aaglyph={NULL,{0,0,0,0,0,0},NULL,DEFAULTBPP};/* The anti-aliased glyph */
1692
long asc, dsc, ht, wd;
1694
long n_horz, n_horz_pad, n_vert, n_asc, n_dsc;
1695
long v_start, v_end;
1700
long lsb, aalsb, aahstart;
1705
/* Reset character glyph, if necessary */
1706
if (aaglyph.bits!=NULL){
1710
aaglyph.metrics.leftSideBearing=0;
1711
aaglyph.metrics.rightSideBearing=0;
1712
aaglyph.metrics.advanceX=0;
1713
aaglyph.metrics.advanceY=0;
1714
aaglyph.metrics.ascent=0;
1715
aaglyph.metrics.descent=0;
1716
aaglyph.pFontCacheInfo=NULL;
1717
aaglyph.bpp=T1aa_bpp;
1720
/* First, scale outline appropriately: */
1721
path=T1_ScaleOutline( path, T1aa_level);
1723
/* Second, call routine to fill outline, all error checking is
1724
done in this function: */
1725
if ((glyph=T1_FillOutline( path, modflag))==NULL)
1726
return(NULL); /* An error occured */
1728
/* In case there are no black pixels, we simply set the dimensions and
1730
if ( glyph->bits == NULL) {
1732
aaglyph.metrics.leftSideBearing=0;
1733
aaglyph.metrics.rightSideBearing=0;
1734
aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
1735
aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
1736
aaglyph.metrics.ascent=0;
1737
aaglyph.metrics.descent=0;
1738
aaglyph.pFontCacheInfo=NULL;
1742
/* Get dimensions of bitmap: */
1743
asc=glyph->metrics.ascent;
1744
dsc=glyph->metrics.descent;
1745
lsb=glyph->metrics.leftSideBearing;
1747
wd=glyph->metrics.rightSideBearing-lsb;
1750
if (T1aa_level==T1_AA_NONE){
1751
/* we only convert bitmap to bytemap */
1753
aaglyph.bpp=T1aa_bpp;
1754
/* Compute scanline length and such */
1755
n_horz_pad=PAD( wd*T1aa_bpp, pFontBase->bitmap_pad )>>3;
1756
/* Allocate memory for glyph, we alloc 12 bytes more to simplify
1758
memsize = n_horz_pad*ht*8;
1759
aaglyph.bits = (char *)malloc(memsize*sizeof( char) +12);
1760
if (aaglyph.bits == NULL) {
1761
T1_errno=T1ERR_ALLOC_MEM;
1764
paddedW=PAD(wd,pFontBase->bitmap_pad)>>3;
1766
target_ptr=aaglyph.bits;
1767
for (i = 0; i < ht; i++) {
1768
T1_DoLine ( wd, paddedW, ptr, target_ptr );
1770
target_ptr += n_horz_pad;
1776
/* Set some looping parameters for subsampling */
1778
aalsb=lsb/T1aa_level-1;
1779
aahstart=T1aa_level+(lsb%T1aa_level);
1782
aalsb=lsb/T1aa_level;
1783
aahstart=lsb%T1aa_level;
1786
/* The horizontal number of steps: */
1787
n_horz=(wd+aahstart+T1aa_level-1)/T1aa_level;
1788
/* And the padded value */
1789
n_horz_pad=PAD( n_horz*T1aa_bpp, pFontBase->bitmap_pad )>>3;
1791
/* vertical number of steps: */
1792
if (asc % T1aa_level){ /* not aligned */
1794
n_asc=asc/T1aa_level+1;
1795
v_start=asc % T1aa_level;
1798
n_asc=asc/T1aa_level;
1799
v_start=T1aa_level + (asc % T1aa_level);
1803
n_asc=asc/T1aa_level;
1806
if (dsc % T1aa_level){ /* not aligned */
1808
n_dsc=dsc/T1aa_level-1;
1809
v_end=-(dsc % T1aa_level);
1812
n_dsc=dsc/T1aa_level;
1813
v_end=T1aa_level - (dsc % T1aa_level);
1817
n_dsc=dsc/T1aa_level;
1820
/* the total number of lines: */
1823
/* Allocate memory for glyph */
1824
memsize = n_horz_pad*n_vert;
1826
aaglyph.bits = (char *)malloc(memsize*sizeof( char)+12);
1827
if (aaglyph.bits == NULL) {
1828
T1_errno=T1ERR_ALLOC_MEM;
1832
paddedW=PAD(wd,pFontBase->bitmap_pad)/8;
1834
target_ptr=aaglyph.bits;
1836
/* We must check for n_vert==1 because then both v_start and v_end could / will
1837
affect the same AA scan line.
1840
v_start=v_start - (T1aa_level - v_end);
1844
for (i = 0; i < n_vert; i++) {
1847
else if (i==n_vert-1)
1851
T1_AADoLine ( T1aa_level, wd, y, paddedW, ptr, target_ptr, aahstart );
1853
target_ptr += n_horz_pad;
1856
/* .. and set them in aaglyph */
1857
aaglyph.metrics.leftSideBearing=aalsb;
1858
aaglyph.metrics.rightSideBearing=aalsb + n_horz;
1859
aaglyph.metrics.advanceX=(int) floor(glyph->metrics.advanceX/(float)T1aa_level+0.5);
1860
aaglyph.metrics.advanceY=(int) floor(glyph->metrics.advanceY/(float)T1aa_level+0.5);
1861
aaglyph.metrics.ascent=n_asc;
1862
aaglyph.metrics.descent=n_dsc;
1863
aaglyph.pFontCacheInfo=NULL;
1870
/* T1_AASetSmartLimits(): Set the limit-values for smart
1871
antialiasing. Returns 0 if OK, and -1 else. */
1872
int T1_AASetSmartLimits( float limit1, float limit2)
1875
if (limit1 > 0.0 && limit2 > 0.0 && limit2 >= limit2) {
1876
T1aa_smartlimit1=limit1;
1877
T1aa_smartlimit2=limit2;
1881
T1_errno=T1ERR_INVALID_PARAMETER;
1888
/* T1_AASetSmartMode(): Enable or disable smart anialiasing */
1889
int T1_AASetSmartMode( int smart)
1892
if (smart==T1_YES) {
1895
else if (smart==T1_NO) {
1899
T1_errno=T1ERR_INVALID_PARAMETER;