1 /*
2 * << H a r u --free pdf library >> -- PdfCMap.cc
3 *
4 * Copyright (c) 1999-2003 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
5 *
6 * Permission to use, copy, modify, distribute and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appear in all copies and
9 * that both that copyright notice and this permission notice appear
10 * in supporting documentation.
11 * It is provided "as is" without express or implied warranty.
12 *
13 */
14
15 #include "libharu.h"
16
17 static const unsigned char UNICODE_HEADER[PDF_UNICODE_HEADER_LEN] = {
18 0xFE, 0xFF
19 };
20
21 /*------ PdfCMap -------------------------------------------------------------*/
22
PdfCMap()23 PdfCMap::PdfCMap()
24 : PdfAutoPtrObject()
25 {
26 PDF_DEBUG_PRINT(("++ [%x] PdfCMap new[].\n", (int)this));
27 fRegistry = NULL;
28 fOrdering = NULL;
29 fSupplement = 0;
30
31 for (int i = 0; i <= 255; i++) {
32 for (int j = 0; j <= 255; j++) {
33 /* undefined charactors are replaced to square */
34 fUnicodeArray[i][j] = 0x25A1;
35 fCMapArray[i][j] = 0x0000;
36 }
37 }
38 }
39
~PdfCMap()40 PdfCMap::~PdfCMap()
41 {
42 PDF_DEBUG_PRINT(("++ [%x] fRegistry delete.\n", (int)fRegistry));
43 delete fRegistry;
44
45 PDF_DEBUG_PRINT(("++ [%x] fOrdering delete.\n", (int)fOrdering));
46 delete fOrdering;
47
48 PDF_DEBUG_PRINT(("++ [%x] PdfCMap delete[].\n", (int)this));
49 }
50
51 unsigned int
GetUnicode(unsigned int code)52 PdfCMap::GetUnicode(unsigned int code)
53 {
54 unsigned char l = code;
55 unsigned char h = code >> 8;
56
57 return fUnicodeArray[l][h];
58 }
59
60 pdf_cid
GetCID(unsigned int code)61 PdfCMap::GetCID(unsigned int code)
62 {
63 unsigned char l = code;
64 unsigned char h = code >> 8;
65
66 return fCMapArray[l][h];
67 }
68
69 void
AddCMap(const pdf_cid_range * range)70 PdfCMap::AddCMap(const pdf_cid_range* range)
71 {
72 const pdf_cid_range* prange = range;
73
74 /* Copy specified pdf_cid_range array to fRangeArray. */
75 while (prange->from != 0xffff && prange->to != 0xffff) {
76 unsigned short code = prange->from;
77 unsigned short cid = prange->cid;
78
79 while (code <= prange->to) {
80 unsigned char l = code;
81 unsigned char h = code >> 8;
82
83 fCMapArray[l][h] = cid;
84 code++;
85 cid++;
86 }
87 prange++;
88 }
89 }
90
91 void
SetCIDSystemInfo(const char * registry,const char * ordering,unsigned int supplement)92 PdfCMap::SetCIDSystemInfo(const char* registry,
93 const char* ordering, unsigned int supplement)
94 {
95 if (fRegistry != NULL) {
96 PDF_DEBUG_PRINT(("++ [%x] fRegistry delete.\n", (int)fRegistry));
97 delete fRegistry;
98 fRegistry = NULL;
99 }
100 if (fOrdering != NULL) {
101 PDF_DEBUG_PRINT(("++ [%x] fOrdering delete.\n", (int)fOrdering));
102 delete fOrdering;
103 fOrdering = NULL;
104 }
105 fSupplement = 0;
106
107 if (registry != NULL) {
108 fRegistry = new char[strlen(registry + 1)];
109 PDF_DEBUG_PRINT(("++ [%x] fRegistry new.\n", (int)fRegistry));
110 strcpy(fRegistry, registry);
111 }
112 if (ordering != NULL) {
113 fOrdering = new char[strlen(ordering + 1)];
114 PDF_DEBUG_PRINT(("++ [%x] fOrdering new.\n", (int)fOrdering));
115 strcpy(fOrdering, ordering);
116 }
117 fSupplement = supplement;
118 }
119
120 void
AddCIDSystemInfo(PdfCIDFont * font)121 PdfCMap::AddCIDSystemInfo(PdfCIDFont* font)
122 {
123 if (fRegistry == NULL || fOrdering == NULL) {
124 PDF_DEBUG_PRINT(("WARNING PdfCMap::AddCIDSystemInfo "
125 "CIDSystemInfo is not prepared.\n"));
126 return;
127 }
128
129 PdfDictionary* dict = new PdfDictionary(font->GetXref());
130 font->AddElement("CIDSystemInfo", dict);
131 dict->AddElement("Registry", new PdfText(fRegistry));
132 dict->AddElement("Ordering", new PdfText(fOrdering));
133 dict->AddElement("Supplement", new PdfNumber(fSupplement));
134 }
135
136 void
SetUnicodeArray(const pdf_mb_unicode_map1 * array1,const pdf_mb_unicode_map2 * array2)137 PdfCMap::SetUnicodeArray(const pdf_mb_unicode_map1* array1,
138 const pdf_mb_unicode_map2* array2)
139 {
140 if (array1 != NULL)
141 while (array1->unicode != 0xffff) {
142 unsigned char l = array1->mbchar;
143 unsigned char h = array1->mbchar >> 8;
144 fUnicodeArray[l][h] = array1->unicode;
145 array1++;
146 }
147
148 if (array2 != NULL)
149 while (array2->unicode != 0xffff) {
150 unsigned short mbchar = array2->from;
151 unsigned short unicode = array2->unicode;
152 while (mbchar <= array2->to) {
153 unsigned char l = mbchar;
154 unsigned char h = mbchar >> 8;
155 fUnicodeArray[l][h] = unicode;
156 mbchar++;
157 unicode++;
158 }
159 array2++;
160 }
161 }
162
163 int
ToUnicode(const char * src,unsigned char * dst,int * len)164 PdfCMap::ToUnicode(const char* src, unsigned char* dst, int* len)
165 {
166 int srclen = strlen(src);
167 int dstlen;
168 int j = 0;
169
170 if (dst != NULL && len != NULL)
171 dstlen = *len - 1;
172 else
173 dstlen = -1;
174
175 pdf_byte_type* btype = new pdf_byte_type[srclen];
176 try {
177 ParseText(src, btype);
178
179 if (dstlen > PDF_UNICODE_HEADER_LEN) {
180 memcpy(dst, UNICODE_HEADER, PDF_UNICODE_HEADER_LEN);
181 j = PDF_UNICODE_HEADER_LEN;
182 } else
183 return -1;
184
185 const unsigned char* usrc = (const unsigned char*)src;
186 for (int i = 0; i < srclen; i++) {
187 unsigned int unicode;
188 unsigned char tmp[2];
189
190 if (btype[i] != PDF_BYTE_TYPE_TRIAL) {
191 if (btype[i] == PDF_BYTE_TYPE_SINGLE)
192 unicode = GetUnicode(usrc[i]);
193 else {
194 unsigned int code = (unsigned int)usrc[i] * 256 + usrc[i+1];
195 unicode = GetUnicode(code);
196 }
197 tmp[0] = unicode >> 8;
198 tmp[1] = unicode;
199
200 if (j < dstlen) {
201 memcpy(dst + j, tmp, 2);
202 j += 2;
203 }
204 }
205 }
206 } catch (...) {
207 delete btype;
208 throw;
209 }
210 delete btype;
211 *len = j;
212 return j;
213 }
214
215 /*----------------------------------------------------------------------------*/
216
217