* new function SWFFont::getWidth(char*)
[swftools.git] / pdf2swf / xpdf / FontEncoding.cc
1 //========================================================================
2 //
3 // FontEncoding.cc
4 //
5 // Copyright 1999 Derek B. Noonburg
6 //
7 //========================================================================
8
9 #ifdef __GNUC__
10 #pragma implementation
11 #endif
12
13 #include <stdlib.h>
14 #include <stddef.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include "gmem.h"
18 #include "FontEncoding.h"
19
20 //------------------------------------------------------------------------
21 // FontEncoding
22 //------------------------------------------------------------------------
23
24 inline int FontEncoding::hash(char *name) {
25   Guint h;
26
27   h = (Guint)name[0] & 0xff;
28   if (h && name[1])
29     h = h * 61 + ((Guint)name[1] & 0xff);
30   return (int)(h % (Guint)fontEncHashSize);
31 }
32
33 FontEncoding::FontEncoding() {
34   int i;
35
36   encoding = (char **)gmalloc(256 * sizeof(char *));
37   size = 256;
38   freeEnc = gTrue;
39   for (i = 0; i < 256; ++i)
40     encoding[i] = NULL;
41   for (i = 0; i < fontEncHashSize; ++i)
42     hashTab[i] = -1;
43 }
44
45 FontEncoding::FontEncoding(char **encoding, int size) {
46   int i;
47
48   this->encoding = encoding;
49   this->size = size;
50   freeEnc = gFalse;
51   for (i = 0; i < fontEncHashSize; ++i)
52     hashTab[i] = -1;
53   for (i = 0; i < size; ++i) {
54     if (encoding[i])
55       addChar1(i, encoding[i]);
56   }
57 }
58
59 FontEncoding::FontEncoding(FontEncoding *fontEnc) {
60   int i;
61
62   encoding = (char **)gmalloc(fontEnc->size * sizeof(char *));
63   size = fontEnc->size;
64   freeEnc = gTrue;
65   for (i = 0; i < size; ++i) {
66     encoding[i] =
67       fontEnc->encoding[i] ? copyString(fontEnc->encoding[i]) : (char *)NULL;
68   }
69   memcpy(hashTab, fontEnc->hashTab, fontEncHashSize * sizeof(short));
70 }
71
72 void FontEncoding::addChar(int code, char *name) {
73   int h, i;
74
75   // replace character associated with code
76   if (encoding[code]) {
77     h = hash(encoding[code]);
78     for (i = 0; i < fontEncHashSize; ++i) {
79       if (hashTab[h] == code) {
80         hashTab[h] = -2;
81         break;
82       }
83       if (++h == fontEncHashSize)
84         h = 0;
85     }
86     gfree(encoding[code]);
87   }
88
89   // associate name with code
90   encoding[code] = name;
91
92   // insert name in hash table
93   addChar1(code, name);
94 }
95
96 void FontEncoding::addChar1(int code, char *name) {
97   int h, i, code2;
98
99   // insert name in hash table
100   h = hash(name); 
101   for (i = 0; i < fontEncHashSize; ++i) {
102     code2 = hashTab[h];
103     if (code2 < 0) {
104       hashTab[h] = code;
105       break;
106     } else if (encoding[code2] && !strcmp(encoding[code2], name)) {
107       // keep the highest code for each char -- this is needed because
108       // X won't display chars with codes < 32
109       if (code > code2)
110         hashTab[h] = code;
111       break;
112     }
113     if (++h == fontEncHashSize)
114       h = 0;
115   }
116 }
117
118 FontEncoding::~FontEncoding() {
119   int i;
120
121   if (freeEnc) {
122     for (i = 0; i < size; ++i) {
123       if (encoding[i])
124         gfree(encoding[i]);
125     }
126     gfree(encoding);
127   }
128 }
129
130 int FontEncoding::getCharCode(char *name) {
131   int h, i, code;
132
133   h = hash(name);
134   for (i = 0; i < fontEncHashSize; ++i) {
135     code = hashTab[h];
136     if (code == -1 ||
137         (code >= 0 && encoding[code] && !strcmp(encoding[code], name)))
138       return code;
139     if (++h >= fontEncHashSize)
140       h = 0;
141   }
142   return -1;
143 }