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