#include #include #include #include #include #include "aalib.h" #include "aaint.h" #include "aamktabl.h" #include "config.h" #define TABLESIZE 65536 #define pow2(i) ((i)*(i)) /*#define pow2(i) (abs(i)) */ #define add(i) if(next[(i)]==(i)&&last!=(i)) {if(last!=-1) next[last]=(i),last=(i); else last=first=(i);} #define dist(i1,i2,i3,i4,i5,y1,y2,y3,y4,y5) (2*(pow2((int)(i1)-(int)(y1))+pow2((int)(i2)-(int)(y2))+(pow2((int)(i3)-(int)(y3))+pow2((int)(i4)-(int)(y4))))+1*pow2((int)(i5)-(int)(y5))) #define dist1(i1,i2,i3,i4,i5,y1,y2,y3,y4,y5) ((pow2((int)(i1)-(int)(y1))+pow2((int)(i2)-(int)(y2))+(pow2((int)(i3)-(int)(y3))+pow2((int)(i4)-(int)(y4))))+2*pow2((int)(i5)-(int)(y5))) #define pos(i1,i2,i3,i4) (((int)(i1)<<12)+((int)(i2)<<8)+((int)(i3)<<4)+(int)(i4)) #define postoparams(pos,i1,i2,i3,i4) \ ((i1)=(pos)>>12),((i2)=((pos)>>8)&15),((i3)=((pos)>>4)&15),((i4)=((pos))&15) int priority[]={4,5,3,2,1}; unsigned short *aa_mktable(aa_context *c) { int i; int i1, i2, i3, i4; int sum, pos; struct aa_font *currfont = c->params.font; int supported = c->params.supported; unsigned short *next; int first = -1; int last = -1; unsigned short *table; unsigned short *filltable; static struct parameters *parameters; debugStr("In mktable 0") next = (unsigned short *) malloc(sizeof(*next) * TABLESIZE); parameters = (struct parameters *) calloc(1, sizeof(struct parameters) * (NCHARS + 1)); table = (unsigned short *) calloc(1, TABLESIZE * sizeof(*table)); filltable = (unsigned short *) calloc(1, 256 * sizeof(*filltable)); if(!next || !parameters || !table || !filltable) { printf("Could not allocate enough memory! %x %x %x %x\n", next,parameters,table,filltable); exit(1); } first = -1; last = -1; for (i = 0; i < TABLESIZE; i++) next[i] = i, table[i] = 0; aa_calcparams(currfont, parameters, supported,c->params.dimmul, c->params.boldmul); for (i = 0; i < NCHARS; i++) { if (ALOWED(i, supported)) { int p1, p2, p3, p4; i1 = parameters[i].p[0]; i2 = parameters[i].p[1]; i3 = parameters[i].p[2]; i4 = parameters[i].p[3]; p1 = i1 >> 4; p2 = i2 >> 4; p3 = i3 >> 4; p4 = i4 >> 4; sum = parameters[i].p[4]; pos = pos(p1, p2, p3, p4); if (table[pos]) { int sum; p1 = (p1 << 4) + p1; p2 = (p2 << 4) + p2; p3 = (p3 << 4) + p3; p4 = (p4 << 4) + p4; sum = p1 + p2 + p3 + p4; if ((p1=dist(parameters[i].p[0], parameters[i].p[1], parameters[i].p[2], parameters[i].p[3], parameters[i].p[4], p1, p2, p3, p4, sum)) >= (p1=dist(parameters[table[pos]].p[0], parameters[table[pos]].p[1], parameters[table[pos]].p[2], parameters[table[pos]].p[3], parameters[table[pos]].p[4], p1, p2, p3, p4, sum))&&(p1!=p2||priority[i/256]<=priority[table[pos]/256])) goto skip; } table[pos] = i; add(pos); skip:; } } debugStr("In mktable 2") for (pos = 0; pos < 256; pos++) { int mindist = INT_MAX, d1; for (i = 0; i < NCHARS; i++) { if (ALOWED(i, supported)) { if ((d1 = dist1(parameters[i].p[0], parameters[i].p[1], parameters[i].p[2], parameters[i].p[3], parameters[i].p[4], pos, pos, pos, pos, pos*4)) <= mindist&&(d1!=mindist||priority[i/256]>priority[filltable[pos]/256])) filltable[pos] = i, mindist = d1; } } } debugStr("In mktable 3") do { int blocked; if (last != -1) next[last] = last; else break; blocked = last; i = first; if (i == -1) break; first = last = -1; do { int m1, m2, m3, m4, ii, dm; unsigned short c = table[i]; postoparams(i, m1, m2, m3, m4); for (dm = 0; dm < 4; dm++) for (ii = -1; ii <= 1; ii += 2) { int dist, dist1, index; unsigned short ch; i1 = m1; i2 = m2; i3 = m3; i4 = m4; switch (dm) { case 0: i1 += ii; if (i1 < 0 || i1 >= 16) continue; break; case 1: i2 += ii; if (i2 < 0 || i2 >= 16) continue; break; case 2: i3 += ii; if (i3 < 0 || i3 >= 16) continue; break; case 3: i4 += ii; if (i4 < 0 || i4 >= 16) continue; break; } index = pos(i1, i2, i3, i4); ch = table[index]; if (ch == c || index == blocked) continue; if (ch) { int ii1 = (i1 << 4) + i1; int ii2 = (i2 << 4) + i2; int ii3 = (i3 << 4) + i3; int ii4 = (i4 << 4) + i4; int iisum = ii1 + ii2 + ii3 + ii4; dist = dist( ii1, ii2, ii3, ii4, iisum, parameters[c].p[0], parameters[c].p[1], parameters[c].p[2], parameters[c].p[3], parameters[c].p[4]); dist1 = dist( ii1, ii2, ii3, ii4, iisum, parameters[ch].p[0], parameters[ch].p[1], parameters[ch].p[2], parameters[ch].p[3], parameters[ch].p[4]); } if (!ch || dist < dist1) { table[index] = c; add(index); } } i1 = i; i = next[i]; next[i1] = i1; } while (i != i1); } while (last != -1); c->table = table; c->filltable = filltable; c->parameters = parameters; free(next); debugStr("In mktable 4 (last)") return table; }