- Added maximization features, with corresponding plugins. Added painting feature...
[mldemos:mldemos.git] / _3rdParty / dlib / unicode / unicode.cpp
1 // Copyright (C) 2008 Keita Mochizuki, Davis E. King (davis@dlib.net)\r
2 // License: Boost Software License   See LICENSE.txt for the full license.\r
3 #ifndef DLIB_UNICODe_CPp_\r
4 #define DLIB_UNICODe_CPp_\r
5 #include "unicode.h"\r
6 #include <cwchar>\r
7 #include "../string.h"\r
8 #include <vector>\r
9 \r
10 namespace dlib\r
11 {\r
12 \r
13 // ----------------------------------------------------------------------------------------\r
14 \r
15     static const unichar SURROGATE_FIRST_TOP = 0xD800;\r
16     static const unichar SURROGATE_SECOND_TOP = 0xDC00;\r
17     static const unichar SURROGATE_CLEARING_MASK = 0x03FF;\r
18     static const unichar SURROGATE_TOP = SURROGATE_FIRST_TOP;\r
19     static const unichar SURROGATE_END = 0xE000;\r
20     static const unichar SMP_TOP = 0x10000;\r
21     static const int VALID_BITS = 10;\r
22 \r
23 // ----------------------------------------------------------------------------------------\r
24 \r
25     template <typename T> bool is_surrogate(T ch)\r
26     {\r
27         return (zero_extend_cast<unichar>(ch) >= SURROGATE_TOP && \r
28                 zero_extend_cast<unichar>(ch) < SURROGATE_END);\r
29     }\r
30 \r
31 // ----------------------------------------------------------------------------------------\r
32 \r
33     template <typename T> unichar surrogate_pair_to_unichar(T first, T second)\r
34     {\r
35         return ((first & SURROGATE_CLEARING_MASK) << VALID_BITS) | ((second & SURROGATE_CLEARING_MASK) + SMP_TOP);\r
36     }\r
37     //110110 0000000000\r
38     //110111 0000000000\r
39 \r
40 // ----------------------------------------------------------------------------------------\r
41 \r
42     void unichar_to_surrogate_pair(unichar input, unichar &first, unichar &second)\r
43     {\r
44         first = ((input - SMP_TOP) >> VALID_BITS) | SURROGATE_FIRST_TOP;\r
45         second = (input & SURROGATE_CLEARING_MASK) | SURROGATE_SECOND_TOP;\r
46     }\r
47 \r
48 // ----------------------------------------------------------------------------------------\r
49 \r
50     template <int N> void wstr2ustring_t(const wchar_t *src, size_t src_len, ustring &dest);\r
51 \r
52     template <> void wstr2ustring_t<4>(const wchar_t *src, size_t , ustring &dest)\r
53     {\r
54         dest.assign((const unichar *)(src));\r
55     }\r
56 \r
57     template <> void wstr2ustring_t<2>(const wchar_t *src, size_t src_len, ustring &dest)\r
58     {\r
59         size_t wlen = 0;\r
60         for (size_t i = 0; i < src_len; i++)\r
61         {\r
62             is_surrogate(src[i]) ? i++, wlen++ : wlen++;\r
63         }\r
64         dest.resize(wlen);\r
65         for (size_t i = 0, ii = 0; ii < src_len; ++i)\r
66         {\r
67             if (is_surrogate(src[ii]))\r
68             {\r
69                 dest[i] = surrogate_pair_to_unichar(src[ii], src[ii+1]);\r
70                 ii += 2;\r
71             }else\r
72             {\r
73                 dest[i] = zero_extend_cast<unichar>(src[ii]);\r
74                 ii++;\r
75             }\r
76         }\r
77     }\r
78 \r
79 // ----------------------------------------------------------------------------------------\r
80 \r
81     const ustring convert_wstring_to_utf32(const std::wstring &src)\r
82     {\r
83         ustring dest;\r
84         wstr2ustring_t<sizeof(wchar_t)>(src.c_str(), src.size(), dest);\r
85         return dest;\r
86     }\r
87 \r
88 // ----------------------------------------------------------------------------------------\r
89 \r
90     template <int N> struct ustring2wstr\r
91     {\r
92     };\r
93 \r
94     // for the environment of sizeof(wchar_t) == 2 (i.e. Win32)\r
95     template <> struct ustring2wstr<2>\r
96     {\r
97         wchar_t *wstr;\r
98         size_t wlen;\r
99         ustring2wstr(const ustring &src){\r
100             wlen = 0;\r
101             for (size_t i = 0; i < src.length(); ++i)\r
102             {\r
103                 if (src[i] < SMP_TOP) wlen++;\r
104                 else wlen += 2;\r
105             }\r
106             wstr = new wchar_t[wlen+1];\r
107             wstr[wlen] = L'\0';\r
108 \r
109             size_t wi = 0;\r
110             for (size_t i = 0; i < src.length(); ++i)\r
111             {\r
112                 if (src[i] < SMP_TOP)\r
113                 {\r
114                     wstr[wi++] = (wchar_t)src[i];\r
115                 }else\r
116                 {\r
117                     unichar high, low;\r
118                     unichar_to_surrogate_pair(src[i], high, low);\r
119                     wstr[wi++] = (wchar_t)high;\r
120                     wstr[wi++] = (wchar_t)low;\r
121                 }\r
122             }\r
123         }\r
124         ~ustring2wstr()\r
125         {\r
126             delete[] wstr;\r
127         }\r
128     };\r
129 \r
130     // for the environment of sizeof(wchar_t) == 4 (i.e. Unix gcc)\r
131     template <> struct ustring2wstr<4>\r
132     {\r
133         const wchar_t *wstr;\r
134         size_t wlen;\r
135         ustring2wstr(const ustring &src){\r
136             wstr = (const wchar_t *)(src.c_str());\r
137             wlen = src.size();\r
138         }\r
139     };\r
140 \r
141 // ----------------------------------------------------------------------------------------\r
142 \r
143     const std::wstring convert_utf32_to_wstring(const ustring &src)\r
144     {\r
145         ustring2wstr<sizeof(wchar_t)> conv(src);\r
146         std::wstring dest(conv.wstr);\r
147         return dest;\r
148     }\r
149 \r
150 // ----------------------------------------------------------------------------------------\r
151 \r
152     const std::wstring convert_mbstring_to_wstring(const std::string &src)\r
153     {\r
154         std::vector<wchar_t> wstr(src.length()+1);\r
155         std::mbstowcs(&wstr.front(), src.c_str(), src.length()+1);\r
156         return std::wstring(&wstr.front());\r
157     }\r
158 \r
159 // ----------------------------------------------------------------------------------------\r
160 \r
161     const std::string convert_wstring_to_mbstring(const std::wstring &src)\r
162     {\r
163         using namespace std;\r
164         std::string str;\r
165         str.resize((src.length() + 1) * MB_CUR_MAX);\r
166         wcstombs(&str[0], src.c_str(), str.size());\r
167         return std::string(&str[0]);\r
168     }\r
169 \r
170 // ----------------------------------------------------------------------------------------\r
171 \r
172 }\r
173 \r
174 #endif // DLIB_UNICODe_CPp_\r
175 \r