1 /*
2    Source File : PDFDocEncoding.cpp
3 
4 
5    Copyright 2011 Gal Kahana PDFWriter
6 
7    Licensed under the Apache License, Version 2.0 (the "License");
8    you may not use this file except in compliance with the License.
9    You may obtain a copy of the License at
10 
11        http://www.apache.org/licenses/LICENSE-2.0
12 
13    Unless required by applicable law or agreed to in writing, software
14    distributed under the License is distributed on an "AS IS" BASIS,
15    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16    See the License for the specific language governing permissions and
17    limitations under the License.
18 
19 
20 */
21 #include "PDFDocEncoding.h"
22 #include "BetweenIncluding.h"
23 
24 static const char* scGlyphNames[256] =
25 {
26 		".notdef", ".notdef", ".notdef", ".notdef",".notdef", ".notdef", ".notdef", ".notdef",
27 		".notdef", ".notdef", ".notdef", ".notdef",".notdef", ".notdef", ".notdef", ".notdef",
28 		".notdef", ".notdef", ".notdef", ".notdef",".notdef", ".notdef", ".notdef", ".notdef",
29 		"breve", "caron", "circumflex", "dotaccent","hungarumlaut", "ogonek", "ring", ".notdef",
30 		"space", "exclam", "quotedbl", "numbersign","dollar", "percent", "ampersand", "quotesingle",
31 		"parenleft", "parenright", "asterisk", "plus","comma", "hyphen", "period", "slash",
32 		"zero", "one", "two", "three","four", "five", "six", "seven",
33 		"eight", "nine", "colon", "semicolon","less", "equal", "greater", "question",
34 		"at", "A", "B", "C","D", "E", "F", "G",
35 		"H", "I", "J", "K","L", "M", "N", "O",
36 		"P", "Q", "R", "S","T", "U", "V", "W",
37 		"X", "Y", "Z", "bracketleft","backslash", "bracketright", "asciicircum", "underscore",
38 		"grave", "a", "b", "c","d", "e", "f", "g",
39 		"h", "i", "j", "k","l", "m", "n", "o",
40 		"p", "q", "r", "s","t", "u", "v", "w",
41 		"x", "y", "z", "braceleft","bar", "braceright", "asciitilde", ".notdef",
42 		"bullet", "dagger", "daggerdbl", "ellipsis","emdash", "endash", "florin", "fraction",
43 		"guilsinglleft", "guilsinglright", "minus", "perthousand","quotedblbase", "quotedblleft", "quotedblright", "quoteleft",
44 		"quoteright", "quotesinglbase", "trademark", "fi","fl", "Lslash", "OE", "Scaron",
45 		"Ydieresis", "Zcaron", "dotlessi", "lslash","oe", "scaron", "zcaron", ".notdef",
46 		"Euro", "exclamdown", "cent", "sterling","currency", "yen", "brokenbar", "section",
47 		"dieresis", "copyright", "ordfeminine", "guillemotleft","logicalnot", ".notdef", "registered", "macron",
48 		"degree", "plusminus", "twosuperior", "threesuperior","acute", "mu", "paragraph", "periodcentered",
49 		"cedilla", "onesuperior", "ordmasculine", "guillemotright","onequarter", "onehalf", "threequarters", "questiondown",
50 		"Agrave", "Aacute", "Acircumflex", "Atilde","Adieresis", "Aring", "AE", "Ccedilla",
51 		"Egrave", "Eacute", "Ecircumflex", "Edieresis","Igrave", "Iacute", "Icircumflex", "Idieresis",
52 		"Eth", "Ntilde", "Ograve", "Oacute","Ocircumflex", "Otilde", "Odieresis", "multiply",
53 		"Oslash", "Ugrave", "Uacute", "Ucircumflex","Udieresis", "Yacute", "Thorn", "germandbls",
54 		"agrave", "aacute", "acircumflex", "atilde","adieresis", "aring", "ae", "ccedilla",
55 		"egrave", "eacute", "ecircumflex", "edieresis","igrave", "iacute", "icircumflex", "idieresis",
56 		"eth", "ntilde", "ograve", "oacute","ocircumflex", "otilde", "odieresis", "divide",
57 		"oslash", "ugrave", "uacute", "ucircumflex","udieresis", "yacute", "thorn", "ydieresis"
58 };
59 
60 
PDFDocEncoding(void)61 PDFDocEncoding::PDFDocEncoding(void)
62 {
63 }
64 
~PDFDocEncoding(void)65 PDFDocEncoding::~PDFDocEncoding(void)
66 {
67 }
68 
Encode(unsigned long inUnicodeCharacter)69 BoolAndByte PDFDocEncoding::Encode(unsigned long inUnicodeCharacter)
70 {
71 	BoolAndByte result(true,0);
72 
73 	if(	betweenIncluding<unsigned long>(inUnicodeCharacter,0x00,0x17) ||
74 		betweenIncluding<unsigned long>(inUnicodeCharacter,0x20,0x7E) ||
75 		betweenIncluding<unsigned long>(inUnicodeCharacter,0xA1,0xFF))
76 	{
77 		result.second = (char)inUnicodeCharacter;
78 	}
79 	else
80 	{
81 		switch(inUnicodeCharacter)
82 		{
83 			case 0x02D8:
84 				result.second = 0x18;
85 				break;
86 			case 0x02C7:
87 				result.second = 0x19;
88 				break;
89 			case 0x02C6:
90 				result.second = 0x1a;
91 				break;
92 			case 0x02D9:
93 				result.second = 0x1b;
94 				break;
95 			case 0x02DD:
96 				result.second = 0x1c;
97 				break;
98 			case 0x02DB:
99 				result.second = 0x1d;
100 				break;
101 			case 0x02DA:
102 				result.second = 0x1e;
103 				break;
104 			case 0x02DC:
105 				result.second = 0x1f;
106 				break;
107 			case 0x2022:
108 				result.second = 0x80;
109 				break;
110 			case 0x2020:
111 				result.second = 0x81;
112 				break;
113 			case 0x2021:
114 				result.second = 0x82;
115 				break;
116 			case 0x2026:
117 				result.second = 0x83;
118 				break;
119 			case 0x2014:
120 				result.second = 0x84;
121 				break;
122 			case 0x2013:
123 				result.second = 0x85;
124 				break;
125 			case 0x192:
126 				result.second = 0x86;
127 				break;
128 			case 0x2044:
129 				result.second = 0x87;
130 				break;
131 			case 0x2039:
132 				result.second = 0x88;
133 				break;
134 			case 0x203A:
135 				result.second = 0x89;
136 				break;
137 			case 0x2212:
138 				result.second = 0x8a;
139 				break;
140 			case 0x2030:
141 				result.second = 0x8b;
142 				break;
143 			case 0x201E:
144 				result.second = 0x8c;
145 				break;
146 			case 0x201C:
147 				result.second = 0x8d;
148 				break;
149 			case 0x201D:
150 				result.second = 0x8e;
151 				break;
152 			case 0x2018:
153 				result.second = 0x8f;
154 				break;
155 			case 0x2019:
156 				result.second = 0x90;
157 				break;
158 			case 0x201A:
159 				result.second = 0x91;
160 				break;
161 			case 0x2122:
162 				result.second = 0x92;
163 				break;
164 			case 0xFB01:
165 				result.second = 0x93;
166 				break;
167 			case 0xFB02:
168 				result.second = 0x94;
169 				break;
170 			case 0x141:
171 				result.second = 0x95;
172 				break;
173 			case 0x152:
174 				result.second = 0x96;
175 				break;
176 			case 0x160:
177 				result.second = 0x97;
178 				break;
179 			case 0x178:
180 				result.second = 0x98;
181 				break;
182 			case 0x17D:
183 				result.second = 0x99;
184 				break;
185 			case 0x131:
186 				result.second = 0x9a;
187 				break;
188 			case 0x142:
189 				result.second = 0x9b;
190 				break;
191 			case 0x153:
192 				result.second = 0x9c;
193 				break;
194 			case 0x161:
195 				result.second = 0x9d;
196 				break;
197 			case 0x17E:
198 				result.second = 0x9e;
199 				break;
200 			case 0x20AC:
201 				result.second = 0xa0;
202 				break;
203 			default:
204 				result.first = false;
205 		}
206 	}
207 	return result;
208 }
209 
GetEncodedGlyphName(IOBasicTypes::Byte inEncodedCharacter)210 const char* PDFDocEncoding::GetEncodedGlyphName(IOBasicTypes::Byte inEncodedCharacter)
211 {
212 	return scGlyphNames[inEncodedCharacter];
213 }
214 
Decode(IOBasicTypes::Byte inEncodedCharacter)215 unsigned long PDFDocEncoding::Decode(IOBasicTypes::Byte inEncodedCharacter)
216 {
217 	unsigned long result;
218 
219 	if(	betweenIncluding<IOBasicTypes::Byte>(inEncodedCharacter,0x00,0x17) ||
220 		betweenIncluding<IOBasicTypes::Byte>(inEncodedCharacter,0x20,0x7E) ||
221 		betweenIncluding<IOBasicTypes::Byte>(inEncodedCharacter,0xA1,0xFF))
222 	{
223 		result = (unsigned long)inEncodedCharacter;
224 	}
225 	else
226 	{
227 		switch(inEncodedCharacter)
228 		{
229 			case 0x18:
230 				result = 0x02D8;
231 				break;
232 			case 0x19:
233 				result = 0x02C7;
234 				break;
235 			case 0x1a:
236 				result = 0x02C6;
237 				break;
238 			case 0x1b:
239 				result = 0x02D9;
240 				break;
241 			case 0x1c:
242 				result = 0x02DD;
243 				break;
244 			case 0x1d:
245 				result = 0x02DB;
246 				break;
247 			case 0x1e:
248 				result = 0x02DA;
249 				break;
250 			case 0x1f:
251 				result = 0x02DC;
252 				break;
253 			case 0x80:
254 				result = 0x2022;
255 				break;
256 			case 0x81:
257 				result = 0x2020;
258 				break;
259 			case 0x82:
260 				result = 0x2021;
261 				break;
262 			case 0x83:
263 				result = 0x2026;
264 				break;
265 			case 0x84:
266 				result = 0x2014;
267 				break;
268 			case 0x85:
269 				result = 0x2013;
270 				break;
271 			case 0x86:
272 				result = 0x192;
273 				break;
274 			case 0x87:
275 				result = 0x2044;
276 				break;
277 			case 0x88:
278 				result = 0x2039;
279 				break;
280 			case 0x89:
281 				result = 0x203A;
282 				break;
283 			case 0x8a:
284 				result = 0x2212;
285 				break;
286 			case 0x8b:
287 				result = 0x2030;
288 				break;
289 			case 0x8c:
290 				result = 0x201E;
291 				break;
292 			case 0x8d:
293 				result = 0x201C;
294 				break;
295 			case 0x8e:
296 				result = 0x201D;
297 				break;
298 			case 0x8f:
299 				result = 0x2018;
300 				break;
301 			case 0x90:
302 				result = 0x2019;
303 				break;
304 			case 0x91:
305 				result = 0x201A;
306 				break;
307 			case 0x92:
308 				result = 0x2122;
309 				break;
310 			case 0x93:
311 				result = 0xFB01;
312 				break;
313 			case 0x94:
314 				result = 0xFB02;
315 				break;
316 			case 0x95:
317 				result = 0x141;
318 				break;
319 			case 0x96:
320 				result = 0x152;
321 				break;
322 			case 0x97:
323 				result = 0x160;
324 				break;
325 			case 0x98:
326 				result = 0x178;
327 				break;
328 			case 0x99:
329 				result = 0x17D;
330 				break;
331 			case 0x9a:
332 				result = 0x131;
333 				break;
334 			case 0x9b:
335 				result = 0x142;
336 				break;
337 			case 0x9c:
338 				result = 0x153;
339 				break;
340 			case 0x9d:
341 				result = 0x161;
342 				break;
343 			case 0x9e:
344 				result = 0x17E;
345 				break;
346 			case 0xa0:
347 				result = 0x20AC;
348 				break;
349 			default:
350 				result = 0;
351 		}
352 	}
353 	return result;
354 }
355