1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 /**
21  * Rule :
22  * Hangule johap code => unicode
23  * Hanja johap code => ks code => unicode
24  * Special johap code => ks code => unicode
25  */
26 #include "precompile.h"
27 #include <sal/types.h>
28 #include <sal/macros.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
33 #include "hcode.h"
34 #include "ksc5601.h"
35 
36 #define PI 3.14159265358979323846
37 
38 static hchar jaso2ks(hchar hh);
39 
40 // ccvHH2ASC    code convert HWP20 to ASC(KSSM)
41 
42 #define HCA_KSS         0x3400
43 #define HCA_TG          0x37C0
44 #define noneks          0xA1A1
45 
46 #define UNI_HANGUL_FIRST        0xac00
47 
48 #define NUM_JOONGSEONG          21
49 #define NUM_JONGSEONG           28
50 
51 /**
52  * kssm code table matching with ks index
53  */
54 static const hchar ksTbl[2350] =
55 {
56     0x8861, 0x8862, 0x8865, 0x8868, 0x8869, 0x886A, 0x886B, 0x8871,
57     0x8873, 0x8874, 0x8875, 0x8876, 0x8877, 0x8878, 0x8879, 0x887B,
58     0x887C, 0x887D, 0x8881, 0x8882, 0x8885, 0x8889, 0x8891, 0x8893,
59     0x8895, 0x8896, 0x8897, 0x88A1, 0x88A2, 0x88A5, 0x88A9, 0x88B5,
60     0x88B7, 0x88C1, 0x88C5, 0x88C9, 0x88E1, 0x88E2, 0x88E5, 0x88E8,
61     0x88E9, 0x88EB, 0x88F1, 0x88F3, 0x88F5, 0x88F6, 0x88F7, 0x88F8,
62     0x88FB, 0x88FC, 0x88FD, 0x8941, 0x8945, 0x8949, 0x8951, 0x8953,
63     0x8955, 0x8956, 0x8957, 0x8961, 0x8962, 0x8963, 0x8965, 0x8968,
64     0x8969, 0x8971, 0x8973, 0x8975, 0x8976, 0x8977, 0x897B, 0x8981,
65     0x8985, 0x8989, 0x8993, 0x8995, 0x89A1, 0x89A2, 0x89A5, 0x89A8,
66     0x89A9, 0x89AB, 0x89AD, 0x89B0, 0x89B1, 0x89B3, 0x89B5, 0x89B7,
67     0x89B8, 0x89C1, 0x89C2, 0x89C5, 0x89C9, 0x89CB, 0x89D1, 0x89D3,
68     0x89D5, 0x89D7, 0x89E1, 0x89E5, 0x89E9, 0x89F3, 0x89F6, 0x89F7,
69     0x8A41, 0x8A42, 0x8A45, 0x8A49, 0x8A51, 0x8A53, 0x8A55, 0x8A57,
70     0x8A61, 0x8A65, 0x8A69, 0x8A73, 0x8A75, 0x8A81, 0x8A82, 0x8A85,
71     0x8A88, 0x8A89, 0x8A8A, 0x8A8B, 0x8A90, 0x8A91, 0x8A93, 0x8A95,
72     0x8A97, 0x8A98, 0x8AA1, 0x8AA2, 0x8AA5, 0x8AA9, 0x8AB6, 0x8AB7,
73     0x8AC1, 0x8AD5, 0x8AE1, 0x8AE2, 0x8AE5, 0x8AE9, 0x8AF1, 0x8AF3,
74     0x8AF5, 0x8B41, 0x8B45, 0x8B49, 0x8B61, 0x8B62, 0x8B65, 0x8B68,
75     0x8B69, 0x8B6A, 0x8B71, 0x8B73, 0x8B75, 0x8B77, 0x8B81, 0x8BA1,
76     0x8BA2, 0x8BA5, 0x8BA8, 0x8BA9, 0x8BAB, 0x8BB1, 0x8BB3, 0x8BB5,
77     0x8BB7, 0x8BB8, 0x8BBC, 0x8C61, 0x8C62, 0x8C63, 0x8C65, 0x8C69,
78     0x8C6B, 0x8C71, 0x8C73, 0x8C75, 0x8C76, 0x8C77, 0x8C7B, 0x8C81,
79     0x8C82, 0x8C85, 0x8C89, 0x8C91, 0x8C93, 0x8C95, 0x8C96, 0x8C97,
80     0x8CA1, 0x8CA2, 0x8CA9, 0x8CE1, 0x8CE2, 0x8CE3, 0x8CE5, 0x8CE9,
81     0x8CF1, 0x8CF3, 0x8CF5, 0x8CF6, 0x8CF7, 0x8D41, 0x8D42, 0x8D45,
82     0x8D51, 0x8D55, 0x8D57, 0x8D61, 0x8D65, 0x8D69, 0x8D75, 0x8D76,
83     0x8D7B, 0x8D81, 0x8DA1, 0x8DA2, 0x8DA5, 0x8DA7, 0x8DA9, 0x8DB1,
84     0x8DB3, 0x8DB5, 0x8DB7, 0x8DB8, 0x8DB9, 0x8DC1, 0x8DC2, 0x8DC9,
85     0x8DD6, 0x8DD7, 0x8DE1, 0x8DE2, 0x8DF7, 0x8E41, 0x8E45, 0x8E49,
86     0x8E51, 0x8E53, 0x8E57, 0x8E61, 0x8E81, 0x8E82, 0x8E85, 0x8E89,
87     0x8E90, 0x8E91, 0x8E93, 0x8E95, 0x8E97, 0x8E98, 0x8EA1, 0x8EA9,
88     0x8EB6, 0x8EB7, 0x8EC1, 0x8EC2, 0x8EC5, 0x8EC9, 0x8ED1, 0x8ED3,
89     0x8ED6, 0x8EE1, 0x8EE5, 0x8EE9, 0x8EF1, 0x8EF3, 0x8F41, 0x8F61,
90     0x8F62, 0x8F65, 0x8F67, 0x8F69, 0x8F6B, 0x8F70, 0x8F71, 0x8F73,
91     0x8F75, 0x8F77, 0x8F7B, 0x8FA1, 0x8FA2, 0x8FA5, 0x8FA9, 0x8FB1,
92     0x8FB3, 0x8FB5, 0x8FB7, 0x9061, 0x9062, 0x9063, 0x9065, 0x9068,
93     0x9069, 0x906A, 0x906B, 0x9071, 0x9073, 0x9075, 0x9076, 0x9077,
94     0x9078, 0x9079, 0x907B, 0x907D, 0x9081, 0x9082, 0x9085, 0x9089,
95     0x9091, 0x9093, 0x9095, 0x9096, 0x9097, 0x90A1, 0x90A2, 0x90A5,
96     0x90A9, 0x90B1, 0x90B7, 0x90E1, 0x90E2, 0x90E4, 0x90E5, 0x90E9,
97     0x90EB, 0x90EC, 0x90F1, 0x90F3, 0x90F5, 0x90F6, 0x90F7, 0x90FD,
98     0x9141, 0x9142, 0x9145, 0x9149, 0x9151, 0x9153, 0x9155, 0x9156,
99     0x9157, 0x9161, 0x9162, 0x9165, 0x9169, 0x9171, 0x9173, 0x9176,
100     0x9177, 0x917A, 0x9181, 0x9185, 0x91A1, 0x91A2, 0x91A5, 0x91A9,
101     0x91AB, 0x91B1, 0x91B3, 0x91B5, 0x91B7, 0x91BC, 0x91BD, 0x91C1,
102     0x91C5, 0x91C9, 0x91D6, 0x9241, 0x9245, 0x9249, 0x9251, 0x9253,
103     0x9255, 0x9261, 0x9262, 0x9265, 0x9269, 0x9273, 0x9275, 0x9277,
104     0x9281, 0x9282, 0x9285, 0x9288, 0x9289, 0x9291, 0x9293, 0x9295,
105     0x9297, 0x92A1, 0x92B6, 0x92C1, 0x92E1, 0x92E5, 0x92E9, 0x92F1,
106     0x92F3, 0x9341, 0x9342, 0x9349, 0x9351, 0x9353, 0x9357, 0x9361,
107     0x9362, 0x9365, 0x9369, 0x936A, 0x936B, 0x9371, 0x9373, 0x9375,
108     0x9377, 0x9378, 0x937C, 0x9381, 0x9385, 0x9389, 0x93A1, 0x93A2,
109     0x93A5, 0x93A9, 0x93AF, 0x93B1, 0x93B3, 0x93B5, 0x93B7, 0x93BC,
110     0x9461, 0x9462, 0x9463, 0x9465, 0x9468, 0x9469, 0x946A, 0x946B,
111     0x946C, 0x9470, 0x9471, 0x9473, 0x9475, 0x9476, 0x9477, 0x9478,
112     0x9479, 0x947D, 0x9481, 0x9482, 0x9485, 0x9489, 0x9491, 0x9493,
113     0x9495, 0x9496, 0x9497, 0x94A1, 0x94E1, 0x94E2, 0x94E3, 0x94E5,
114     0x94E8, 0x94E9, 0x94EB, 0x94EC, 0x94F1, 0x94F3, 0x94F5, 0x94F7,
115     0x94F9, 0x94FC, 0x9541, 0x9542, 0x9545, 0x9549, 0x9551, 0x9553,
116     0x9555, 0x9556, 0x9557, 0x9561, 0x9565, 0x9569, 0x9576, 0x9577,
117     0x9581, 0x9585, 0x95A1, 0x95A2, 0x95A5, 0x95A8, 0x95A9, 0x95AB,
118     0x95AD, 0x95B1, 0x95B3, 0x95B5, 0x95B7, 0x95B9, 0x95BB, 0x95C1,
119     0x95C5, 0x95C9, 0x95E1, 0x95F6, 0x9641, 0x9645, 0x9649, 0x9651,
120     0x9653, 0x9655, 0x9661, 0x9681, 0x9682, 0x9685, 0x9689, 0x9691,
121     0x9693, 0x9695, 0x9697, 0x96A1, 0x96B6, 0x96C1, 0x96D7, 0x96E1,
122     0x96E5, 0x96E9, 0x96F3, 0x96F5, 0x96F7, 0x9741, 0x9745, 0x9749,
123     0x9751, 0x9757, 0x9761, 0x9762, 0x9765, 0x9768, 0x9769, 0x976B,
124     0x9771, 0x9773, 0x9775, 0x9777, 0x9781, 0x97A1, 0x97A2, 0x97A5,
125     0x97A8, 0x97A9, 0x97B1, 0x97B3, 0x97B5, 0x97B6, 0x97B7, 0x97B8,
126     0x9861, 0x9862, 0x9865, 0x9869, 0x9871, 0x9873, 0x9875, 0x9876,
127     0x9877, 0x987D, 0x9881, 0x9882, 0x9885, 0x9889, 0x9891, 0x9893,
128     0x9895, 0x9896, 0x9897, 0x98E1, 0x98E2, 0x98E5, 0x98E9, 0x98EB,
129     0x98EC, 0x98F1, 0x98F3, 0x98F5, 0x98F6, 0x98F7, 0x98FD, 0x9941,
130     0x9942, 0x9945, 0x9949, 0x9951, 0x9953, 0x9955, 0x9956, 0x9957,
131     0x9961, 0x9976, 0x99A1, 0x99A2, 0x99A5, 0x99A9, 0x99B7, 0x99C1,
132     0x99C9, 0x99E1, 0x9A41, 0x9A45, 0x9A81, 0x9A82, 0x9A85, 0x9A89,
133     0x9A90, 0x9A91, 0x9A97, 0x9AC1, 0x9AE1, 0x9AE5, 0x9AE9, 0x9AF1,
134     0x9AF3, 0x9AF7, 0x9B61, 0x9B62, 0x9B65, 0x9B68, 0x9B69, 0x9B71,
135     0x9B73, 0x9B75, 0x9B81, 0x9B85, 0x9B89, 0x9B91, 0x9B93, 0x9BA1,
136     0x9BA5, 0x9BA9, 0x9BB1, 0x9BB3, 0x9BB5, 0x9BB7, 0x9C61, 0x9C62,
137     0x9C65, 0x9C69, 0x9C71, 0x9C73, 0x9C75, 0x9C76, 0x9C77, 0x9C78,
138     0x9C7C, 0x9C7D, 0x9C81, 0x9C82, 0x9C85, 0x9C89, 0x9C91, 0x9C93,
139     0x9C95, 0x9C96, 0x9C97, 0x9CA1, 0x9CA2, 0x9CA5, 0x9CB5, 0x9CB7,
140     0x9CE1, 0x9CE2, 0x9CE5, 0x9CE9, 0x9CF1, 0x9CF3, 0x9CF5, 0x9CF6,
141     0x9CF7, 0x9CFD, 0x9D41, 0x9D42, 0x9D45, 0x9D49, 0x9D51, 0x9D53,
142     0x9D55, 0x9D57, 0x9D61, 0x9D62, 0x9D65, 0x9D69, 0x9D71, 0x9D73,
143     0x9D75, 0x9D76, 0x9D77, 0x9D81, 0x9D85, 0x9D93, 0x9D95, 0x9DA1,
144     0x9DA2, 0x9DA5, 0x9DA9, 0x9DB1, 0x9DB3, 0x9DB5, 0x9DB7, 0x9DC1,
145     0x9DC5, 0x9DD7, 0x9DF6, 0x9E41, 0x9E45, 0x9E49, 0x9E51, 0x9E53,
146     0x9E55, 0x9E57, 0x9E61, 0x9E65, 0x9E69, 0x9E73, 0x9E75, 0x9E77,
147     0x9E81, 0x9E82, 0x9E85, 0x9E89, 0x9E91, 0x9E93, 0x9E95, 0x9E97,
148     0x9EA1, 0x9EB6, 0x9EC1, 0x9EE1, 0x9EE2, 0x9EE5, 0x9EE9, 0x9EF1,
149     0x9EF5, 0x9EF7, 0x9F41, 0x9F42, 0x9F45, 0x9F49, 0x9F51, 0x9F53,
150     0x9F55, 0x9F57, 0x9F61, 0x9F62, 0x9F65, 0x9F69, 0x9F71, 0x9F73,
151     0x9F75, 0x9F77, 0x9F78, 0x9F7B, 0x9F7C, 0x9FA1, 0x9FA2, 0x9FA5,
152     0x9FA9, 0x9FB1, 0x9FB3, 0x9FB5, 0x9FB7, 0xA061, 0xA062, 0xA065,
153     0xA067, 0xA068, 0xA069, 0xA06A, 0xA06B, 0xA071, 0xA073, 0xA075,
154     0xA077, 0xA078, 0xA07B, 0xA07D, 0xA081, 0xA082, 0xA085, 0xA089,
155     0xA091, 0xA093, 0xA095, 0xA096, 0xA097, 0xA098, 0xA0A1, 0xA0A2,
156     0xA0A9, 0xA0B7, 0xA0E1, 0xA0E2, 0xA0E5, 0xA0E9, 0xA0EB, 0xA0F1,
157     0xA0F3, 0xA0F5, 0xA0F7, 0xA0F8, 0xA0FD, 0xA141, 0xA142, 0xA145,
158     0xA149, 0xA151, 0xA153, 0xA155, 0xA156, 0xA157, 0xA161, 0xA162,
159     0xA165, 0xA169, 0xA175, 0xA176, 0xA177, 0xA179, 0xA181, 0xA1A1,
160     0xA1A2, 0xA1A4, 0xA1A5, 0xA1A9, 0xA1AB, 0xA1B1, 0xA1B3, 0xA1B5,
161     0xA1B7, 0xA1C1, 0xA1C5, 0xA1D6, 0xA1D7, 0xA241, 0xA245, 0xA249,
162     0xA253, 0xA255, 0xA257, 0xA261, 0xA265, 0xA269, 0xA273, 0xA275,
163     0xA281, 0xA282, 0xA283, 0xA285, 0xA288, 0xA289, 0xA28A, 0xA28B,
164     0xA291, 0xA293, 0xA295, 0xA297, 0xA29B, 0xA29D, 0xA2A1, 0xA2A5,
165     0xA2A9, 0xA2B3, 0xA2B5, 0xA2C1, 0xA2E1, 0xA2E5, 0xA2E9, 0xA341,
166     0xA345, 0xA349, 0xA351, 0xA355, 0xA361, 0xA365, 0xA369, 0xA371,
167     0xA375, 0xA3A1, 0xA3A2, 0xA3A5, 0xA3A8, 0xA3A9, 0xA3AB, 0xA3B1,
168     0xA3B3, 0xA3B5, 0xA3B6, 0xA3B7, 0xA3B9, 0xA3BB, 0xA461, 0xA462,
169     0xA463, 0xA464, 0xA465, 0xA468, 0xA469, 0xA46A, 0xA46B, 0xA46C,
170     0xA471, 0xA473, 0xA475, 0xA477, 0xA47B, 0xA481, 0xA482, 0xA485,
171     0xA489, 0xA491, 0xA493, 0xA495, 0xA496, 0xA497, 0xA49B, 0xA4A1,
172     0xA4A2, 0xA4A5, 0xA4B3, 0xA4E1, 0xA4E2, 0xA4E5, 0xA4E8, 0xA4E9,
173     0xA4EB, 0xA4F1, 0xA4F3, 0xA4F5, 0xA4F7, 0xA4F8, 0xA541, 0xA542,
174     0xA545, 0xA548, 0xA549, 0xA551, 0xA553, 0xA555, 0xA556, 0xA557,
175     0xA561, 0xA562, 0xA565, 0xA569, 0xA573, 0xA575, 0xA576, 0xA577,
176     0xA57B, 0xA581, 0xA585, 0xA5A1, 0xA5A2, 0xA5A3, 0xA5A5, 0xA5A9,
177     0xA5B1, 0xA5B3, 0xA5B5, 0xA5B7, 0xA5C1, 0xA5C5, 0xA5D6, 0xA5E1,
178     0xA5F6, 0xA641, 0xA642, 0xA645, 0xA649, 0xA651, 0xA653, 0xA661,
179     0xA665, 0xA681, 0xA682, 0xA685, 0xA688, 0xA689, 0xA68A, 0xA68B,
180     0xA691, 0xA693, 0xA695, 0xA697, 0xA69B, 0xA69C, 0xA6A1, 0xA6A9,
181     0xA6B6, 0xA6C1, 0xA6E1, 0xA6E2, 0xA6E5, 0xA6E9, 0xA6F7, 0xA741,
182     0xA745, 0xA749, 0xA751, 0xA755, 0xA757, 0xA761, 0xA762, 0xA765,
183     0xA769, 0xA771, 0xA773, 0xA775, 0xA7A1, 0xA7A2, 0xA7A5, 0xA7A9,
184     0xA7AB, 0xA7B1, 0xA7B3, 0xA7B5, 0xA7B7, 0xA7B8, 0xA7B9, 0xA861,
185     0xA862, 0xA865, 0xA869, 0xA86B, 0xA871, 0xA873, 0xA875, 0xA876,
186     0xA877, 0xA87D, 0xA881, 0xA882, 0xA885, 0xA889, 0xA891, 0xA893,
187     0xA895, 0xA896, 0xA897, 0xA8A1, 0xA8A2, 0xA8B1, 0xA8E1, 0xA8E2,
188     0xA8E5, 0xA8E8, 0xA8E9, 0xA8F1, 0xA8F5, 0xA8F6, 0xA8F7, 0xA941,
189     0xA957, 0xA961, 0xA962, 0xA971, 0xA973, 0xA975, 0xA976, 0xA977,
190     0xA9A1, 0xA9A2, 0xA9A5, 0xA9A9, 0xA9B1, 0xA9B3, 0xA9B7, 0xAA41,
191     0xAA61, 0xAA77, 0xAA81, 0xAA82, 0xAA85, 0xAA89, 0xAA91, 0xAA95,
192     0xAA97, 0xAB41, 0xAB57, 0xAB61, 0xAB65, 0xAB69, 0xAB71, 0xAB73,
193     0xABA1, 0xABA2, 0xABA5, 0xABA9, 0xABB1, 0xABB3, 0xABB5, 0xABB7,
194     0xAC61, 0xAC62, 0xAC64, 0xAC65, 0xAC68, 0xAC69, 0xAC6A, 0xAC6B,
195     0xAC71, 0xAC73, 0xAC75, 0xAC76, 0xAC77, 0xAC7B, 0xAC81, 0xAC82,
196     0xAC85, 0xAC89, 0xAC91, 0xAC93, 0xAC95, 0xAC96, 0xAC97, 0xACA1,
197     0xACA2, 0xACA5, 0xACA9, 0xACB1, 0xACB3, 0xACB5, 0xACB7, 0xACC1,
198     0xACC5, 0xACC9, 0xACD1, 0xACD7, 0xACE1, 0xACE2, 0xACE3, 0xACE4,
199     0xACE5, 0xACE8, 0xACE9, 0xACEB, 0xACEC, 0xACF1, 0xACF3, 0xACF5,
200     0xACF6, 0xACF7, 0xACFC, 0xAD41, 0xAD42, 0xAD45, 0xAD49, 0xAD51,
201     0xAD53, 0xAD55, 0xAD56, 0xAD57, 0xAD61, 0xAD62, 0xAD65, 0xAD69,
202     0xAD71, 0xAD73, 0xAD75, 0xAD76, 0xAD77, 0xAD81, 0xAD85, 0xAD89,
203     0xAD97, 0xADA1, 0xADA2, 0xADA3, 0xADA5, 0xADA9, 0xADAB, 0xADB1,
204     0xADB3, 0xADB5, 0xADB7, 0xADBB, 0xADC1, 0xADC2, 0xADC5, 0xADC9,
205     0xADD7, 0xADE1, 0xADE5, 0xADE9, 0xADF1, 0xADF5, 0xADF6, 0xAE41,
206     0xAE45, 0xAE49, 0xAE51, 0xAE53, 0xAE55, 0xAE61, 0xAE62, 0xAE65,
207     0xAE69, 0xAE71, 0xAE73, 0xAE75, 0xAE77, 0xAE81, 0xAE82, 0xAE85,
208     0xAE88, 0xAE89, 0xAE91, 0xAE93, 0xAE95, 0xAE97, 0xAE99, 0xAE9B,
209     0xAE9C, 0xAEA1, 0xAEB6, 0xAEC1, 0xAEC2, 0xAEC5, 0xAEC9, 0xAED1,
210     0xAED7, 0xAEE1, 0xAEE2, 0xAEE5, 0xAEE9, 0xAEF1, 0xAEF3, 0xAEF5,
211     0xAEF7, 0xAF41, 0xAF42, 0xAF49, 0xAF51, 0xAF55, 0xAF57, 0xAF61,
212     0xAF62, 0xAF65, 0xAF69, 0xAF6A, 0xAF71, 0xAF73, 0xAF75, 0xAF77,
213     0xAFA1, 0xAFA2, 0xAFA5, 0xAFA8, 0xAFA9, 0xAFB0, 0xAFB1, 0xAFB3,
214     0xAFB5, 0xAFB7, 0xAFBC, 0xB061, 0xB062, 0xB064, 0xB065, 0xB069,
215     0xB071, 0xB073, 0xB076, 0xB077, 0xB07D, 0xB081, 0xB082, 0xB085,
216     0xB089, 0xB091, 0xB093, 0xB096, 0xB097, 0xB0B7, 0xB0E1, 0xB0E2,
217     0xB0E5, 0xB0E9, 0xB0EB, 0xB0F1, 0xB0F3, 0xB0F6, 0xB0F7, 0xB141,
218     0xB145, 0xB149, 0xB185, 0xB1A1, 0xB1A2, 0xB1A5, 0xB1A8, 0xB1A9,
219     0xB1AB, 0xB1B1, 0xB1B3, 0xB1B7, 0xB1C1, 0xB1C2, 0xB1C5, 0xB1D6,
220     0xB1E1, 0xB1F6, 0xB241, 0xB245, 0xB249, 0xB251, 0xB253, 0xB261,
221     0xB281, 0xB282, 0xB285, 0xB289, 0xB291, 0xB293, 0xB297, 0xB2A1,
222     0xB2B6, 0xB2C1, 0xB2E1, 0xB2E5, 0xB357, 0xB361, 0xB362, 0xB365,
223     0xB369, 0xB36B, 0xB370, 0xB371, 0xB373, 0xB381, 0xB385, 0xB389,
224     0xB391, 0xB3A1, 0xB3A2, 0xB3A5, 0xB3A9, 0xB3B1, 0xB3B3, 0xB3B5,
225     0xB3B7, 0xB461, 0xB462, 0xB465, 0xB466, 0xB467, 0xB469, 0xB46A,
226     0xB46B, 0xB470, 0xB471, 0xB473, 0xB475, 0xB476, 0xB477, 0xB47B,
227     0xB47C, 0xB481, 0xB482, 0xB485, 0xB489, 0xB491, 0xB493, 0xB495,
228     0xB496, 0xB497, 0xB4A1, 0xB4A2, 0xB4A5, 0xB4A9, 0xB4AC, 0xB4B1,
229     0xB4B3, 0xB4B5, 0xB4B7, 0xB4BB, 0xB4BD, 0xB4C1, 0xB4C5, 0xB4C9,
230     0xB4D3, 0xB4E1, 0xB4E2, 0xB4E5, 0xB4E6, 0xB4E8, 0xB4E9, 0xB4EA,
231     0xB4EB, 0xB4F1, 0xB4F3, 0xB4F4, 0xB4F5, 0xB4F6, 0xB4F7, 0xB4F8,
232     0xB4FA, 0xB4FC, 0xB541, 0xB542, 0xB545, 0xB549, 0xB551, 0xB553,
233     0xB555, 0xB557, 0xB561, 0xB562, 0xB563, 0xB565, 0xB569, 0xB56B,
234     0xB56C, 0xB571, 0xB573, 0xB574, 0xB575, 0xB576, 0xB577, 0xB57B,
235     0xB57C, 0xB57D, 0xB581, 0xB585, 0xB589, 0xB591, 0xB593, 0xB595,
236     0xB596, 0xB5A1, 0xB5A2, 0xB5A5, 0xB5A9, 0xB5AA, 0xB5AB, 0xB5AD,
237     0xB5B0, 0xB5B1, 0xB5B3, 0xB5B5, 0xB5B7, 0xB5B9, 0xB5C1, 0xB5C2,
238     0xB5C5, 0xB5C9, 0xB5D1, 0xB5D3, 0xB5D5, 0xB5D6, 0xB5D7, 0xB5E1,
239     0xB5E2, 0xB5E5, 0xB5F1, 0xB5F5, 0xB5F7, 0xB641, 0xB642, 0xB645,
240     0xB649, 0xB651, 0xB653, 0xB655, 0xB657, 0xB661, 0xB662, 0xB665,
241     0xB669, 0xB671, 0xB673, 0xB675, 0xB677, 0xB681, 0xB682, 0xB685,
242     0xB689, 0xB68A, 0xB68B, 0xB691, 0xB693, 0xB695, 0xB697, 0xB6A1,
243     0xB6A2, 0xB6A5, 0xB6A9, 0xB6B1, 0xB6B3, 0xB6B6, 0xB6B7, 0xB6C1,
244     0xB6C2, 0xB6C5, 0xB6C9, 0xB6D1, 0xB6D3, 0xB6D7, 0xB6E1, 0xB6E2,
245     0xB6E5, 0xB6E9, 0xB6F1, 0xB6F3, 0xB6F5, 0xB6F7, 0xB741, 0xB742,
246     0xB745, 0xB749, 0xB751, 0xB753, 0xB755, 0xB757, 0xB759, 0xB761,
247     0xB762, 0xB765, 0xB769, 0xB76F, 0xB771, 0xB773, 0xB775, 0xB777,
248     0xB778, 0xB779, 0xB77A, 0xB77B, 0xB77C, 0xB77D, 0xB781, 0xB785,
249     0xB789, 0xB791, 0xB795, 0xB7A1, 0xB7A2, 0xB7A5, 0xB7A9, 0xB7AA,
250     0xB7AB, 0xB7B0, 0xB7B1, 0xB7B3, 0xB7B5, 0xB7B6, 0xB7B7, 0xB7B8,
251     0xB7BC, 0xB861, 0xB862, 0xB865, 0xB867, 0xB868, 0xB869, 0xB86B,
252     0xB871, 0xB873, 0xB875, 0xB876, 0xB877, 0xB878, 0xB881, 0xB882,
253     0xB885, 0xB889, 0xB891, 0xB893, 0xB895, 0xB896, 0xB897, 0xB8A1,
254     0xB8A2, 0xB8A5, 0xB8A7, 0xB8A9, 0xB8B1, 0xB8B7, 0xB8C1, 0xB8C5,
255     0xB8C9, 0xB8E1, 0xB8E2, 0xB8E5, 0xB8E9, 0xB8EB, 0xB8F1, 0xB8F3,
256     0xB8F5, 0xB8F7, 0xB8F8, 0xB941, 0xB942, 0xB945, 0xB949, 0xB951,
257     0xB953, 0xB955, 0xB957, 0xB961, 0xB965, 0xB969, 0xB971, 0xB973,
258     0xB976, 0xB977, 0xB981, 0xB9A1, 0xB9A2, 0xB9A5, 0xB9A9, 0xB9AB,
259     0xB9B1, 0xB9B3, 0xB9B5, 0xB9B7, 0xB9B8, 0xB9B9, 0xB9BD, 0xB9C1,
260     0xB9C2, 0xB9C9, 0xB9D3, 0xB9D5, 0xB9D7, 0xB9E1, 0xB9F6, 0xB9F7,
261     0xBA41, 0xBA45, 0xBA49, 0xBA51, 0xBA53, 0xBA55, 0xBA57, 0xBA61,
262     0xBA62, 0xBA65, 0xBA77, 0xBA81, 0xBA82, 0xBA85, 0xBA89, 0xBA8A,
263     0xBA8B, 0xBA91, 0xBA93, 0xBA95, 0xBA97, 0xBAA1, 0xBAB6, 0xBAC1,
264     0xBAE1, 0xBAE2, 0xBAE5, 0xBAE9, 0xBAF1, 0xBAF3, 0xBAF5, 0xBB41,
265     0xBB45, 0xBB49, 0xBB51, 0xBB61, 0xBB62, 0xBB65, 0xBB69, 0xBB71,
266     0xBB73, 0xBB75, 0xBB77, 0xBBA1, 0xBBA2, 0xBBA5, 0xBBA8, 0xBBA9,
267     0xBBAB, 0xBBB1, 0xBBB3, 0xBBB5, 0xBBB7, 0xBBB8, 0xBBBB, 0xBBBC,
268     0xBC61, 0xBC62, 0xBC65, 0xBC67, 0xBC69, 0xBC6C, 0xBC71, 0xBC73,
269     0xBC75, 0xBC76, 0xBC77, 0xBC81, 0xBC82, 0xBC85, 0xBC89, 0xBC91,
270     0xBC93, 0xBC95, 0xBC96, 0xBC97, 0xBCA1, 0xBCA5, 0xBCB7, 0xBCE1,
271     0xBCE2, 0xBCE5, 0xBCE9, 0xBCF1, 0xBCF3, 0xBCF5, 0xBCF6, 0xBCF7,
272     0xBD41, 0xBD57, 0xBD61, 0xBD76, 0xBDA1, 0xBDA2, 0xBDA5, 0xBDA9,
273     0xBDB1, 0xBDB3, 0xBDB5, 0xBDB7, 0xBDB9, 0xBDC1, 0xBDC2, 0xBDC9,
274     0xBDD6, 0xBDE1, 0xBDF6, 0xBE41, 0xBE45, 0xBE49, 0xBE51, 0xBE53,
275     0xBE77, 0xBE81, 0xBE82, 0xBE85, 0xBE89, 0xBE91, 0xBE93, 0xBE97,
276     0xBEA1, 0xBEB6, 0xBEB7, 0xBEE1, 0xBF41, 0xBF61, 0xBF71, 0xBF75,
277     0xBF77, 0xBFA1, 0xBFA2, 0xBFA5, 0xBFA9, 0xBFB1, 0xBFB3, 0xBFB7,
278     0xBFB8, 0xBFBD, 0xC061, 0xC062, 0xC065, 0xC067, 0xC069, 0xC071,
279     0xC073, 0xC075, 0xC076, 0xC077, 0xC078, 0xC081, 0xC082, 0xC085,
280     0xC089, 0xC091, 0xC093, 0xC095, 0xC096, 0xC097, 0xC0A1, 0xC0A5,
281     0xC0A7, 0xC0A9, 0xC0B1, 0xC0B7, 0xC0E1, 0xC0E2, 0xC0E5, 0xC0E9,
282     0xC0F1, 0xC0F3, 0xC0F5, 0xC0F6, 0xC0F7, 0xC141, 0xC142, 0xC145,
283     0xC149, 0xC151, 0xC153, 0xC155, 0xC157, 0xC161, 0xC165, 0xC176,
284     0xC181, 0xC185, 0xC197, 0xC1A1, 0xC1A2, 0xC1A5, 0xC1A9, 0xC1B1,
285     0xC1B3, 0xC1B5, 0xC1B7, 0xC1C1, 0xC1C5, 0xC1C9, 0xC1D7, 0xC241,
286     0xC245, 0xC249, 0xC251, 0xC253, 0xC255, 0xC257, 0xC261, 0xC271,
287     0xC281, 0xC282, 0xC285, 0xC289, 0xC291, 0xC293, 0xC295, 0xC297,
288     0xC2A1, 0xC2B6, 0xC2C1, 0xC2C5, 0xC2E1, 0xC2E5, 0xC2E9, 0xC2F1,
289     0xC2F3, 0xC2F5, 0xC2F7, 0xC341, 0xC345, 0xC349, 0xC351, 0xC357,
290     0xC361, 0xC362, 0xC365, 0xC369, 0xC371, 0xC373, 0xC375, 0xC377,
291     0xC3A1, 0xC3A2, 0xC3A5, 0xC3A8, 0xC3A9, 0xC3AA, 0xC3B1, 0xC3B3,
292     0xC3B5, 0xC3B7, 0xC461, 0xC462, 0xC465, 0xC469, 0xC471, 0xC473,
293     0xC475, 0xC477, 0xC481, 0xC482, 0xC485, 0xC489, 0xC491, 0xC493,
294     0xC495, 0xC496, 0xC497, 0xC4A1, 0xC4A2, 0xC4B7, 0xC4E1, 0xC4E2,
295     0xC4E5, 0xC4E8, 0xC4E9, 0xC4F1, 0xC4F3, 0xC4F5, 0xC4F6, 0xC4F7,
296     0xC541, 0xC542, 0xC545, 0xC549, 0xC551, 0xC553, 0xC555, 0xC557,
297     0xC561, 0xC565, 0xC569, 0xC571, 0xC573, 0xC575, 0xC576, 0xC577,
298     0xC581, 0xC5A1, 0xC5A2, 0xC5A5, 0xC5A9, 0xC5B1, 0xC5B3, 0xC5B5,
299     0xC5B7, 0xC5C1, 0xC5C2, 0xC5C5, 0xC5C9, 0xC5D1, 0xC5D7, 0xC5E1,
300     0xC5F7, 0xC641, 0xC649, 0xC661, 0xC681, 0xC682, 0xC685, 0xC689,
301     0xC691, 0xC693, 0xC695, 0xC697, 0xC6A1, 0xC6A5, 0xC6A9, 0xC6B7,
302     0xC6C1, 0xC6D7, 0xC6E1, 0xC6E2, 0xC6E5, 0xC6E9, 0xC6F1, 0xC6F3,
303     0xC6F5, 0xC6F7, 0xC741, 0xC745, 0xC749, 0xC751, 0xC761, 0xC762,
304     0xC765, 0xC769, 0xC771, 0xC773, 0xC777, 0xC7A1, 0xC7A2, 0xC7A5,
305     0xC7A9, 0xC7B1, 0xC7B3, 0xC7B5, 0xC7B7, 0xC861, 0xC862, 0xC865,
306     0xC869, 0xC86A, 0xC871, 0xC873, 0xC875, 0xC876, 0xC877, 0xC881,
307     0xC882, 0xC885, 0xC889, 0xC891, 0xC893, 0xC895, 0xC896, 0xC897,
308     0xC8A1, 0xC8B7, 0xC8E1, 0xC8E2, 0xC8E5, 0xC8E9, 0xC8EB, 0xC8F1,
309     0xC8F3, 0xC8F5, 0xC8F6, 0xC8F7, 0xC941, 0xC942, 0xC945, 0xC949,
310     0xC951, 0xC953, 0xC955, 0xC957, 0xC961, 0xC965, 0xC976, 0xC981,
311     0xC985, 0xC9A1, 0xC9A2, 0xC9A5, 0xC9A9, 0xC9B1, 0xC9B3, 0xC9B5,
312     0xC9B7, 0xC9BC, 0xC9C1, 0xC9C5, 0xC9E1, 0xCA41, 0xCA45, 0xCA55,
313     0xCA57, 0xCA61, 0xCA81, 0xCA82, 0xCA85, 0xCA89, 0xCA91, 0xCA93,
314     0xCA95, 0xCA97, 0xCAA1, 0xCAB6, 0xCAC1, 0xCAE1, 0xCAE2, 0xCAE5,
315     0xCAE9, 0xCAF1, 0xCAF3, 0xCAF7, 0xCB41, 0xCB45, 0xCB49, 0xCB51,
316     0xCB57, 0xCB61, 0xCB62, 0xCB65, 0xCB68, 0xCB69, 0xCB6B, 0xCB71,
317     0xCB73, 0xCB75, 0xCB81, 0xCB85, 0xCB89, 0xCB91, 0xCB93, 0xCBA1,
318     0xCBA2, 0xCBA5, 0xCBA9, 0xCBB1, 0xCBB3, 0xCBB5, 0xCBB7, 0xCC61,
319     0xCC62, 0xCC63, 0xCC65, 0xCC69, 0xCC6B, 0xCC71, 0xCC73, 0xCC75,
320     0xCC76, 0xCC77, 0xCC7B, 0xCC81, 0xCC82, 0xCC85, 0xCC89, 0xCC91,
321     0xCC93, 0xCC95, 0xCC96, 0xCC97, 0xCCA1, 0xCCA2, 0xCCE1, 0xCCE2,
322     0xCCE5, 0xCCE9, 0xCCF1, 0xCCF3, 0xCCF5, 0xCCF6, 0xCCF7, 0xCD41,
323     0xCD42, 0xCD45, 0xCD49, 0xCD51, 0xCD53, 0xCD55, 0xCD57, 0xCD61,
324     0xCD65, 0xCD69, 0xCD71, 0xCD73, 0xCD76, 0xCD77, 0xCD81, 0xCD89,
325     0xCD93, 0xCD95, 0xCDA1, 0xCDA2, 0xCDA5, 0xCDA9, 0xCDB1, 0xCDB3,
326     0xCDB5, 0xCDB7, 0xCDC1, 0xCDD7, 0xCE41, 0xCE45, 0xCE61, 0xCE65,
327     0xCE69, 0xCE73, 0xCE75, 0xCE81, 0xCE82, 0xCE85, 0xCE88, 0xCE89,
328     0xCE8B, 0xCE91, 0xCE93, 0xCE95, 0xCE97, 0xCEA1, 0xCEB7, 0xCEE1,
329     0xCEE5, 0xCEE9, 0xCEF1, 0xCEF5, 0xCF41, 0xCF45, 0xCF49, 0xCF51,
330     0xCF55, 0xCF57, 0xCF61, 0xCF65, 0xCF69, 0xCF71, 0xCF73, 0xCF75,
331     0xCFA1, 0xCFA2, 0xCFA5, 0xCFA9, 0xCFB1, 0xCFB3, 0xCFB5, 0xCFB7,
332     0xD061, 0xD062, 0xD065, 0xD069, 0xD06E, 0xD071, 0xD073, 0xD075,
333     0xD077, 0xD081, 0xD082, 0xD085, 0xD089, 0xD091, 0xD093, 0xD095,
334     0xD096, 0xD097, 0xD0A1, 0xD0B7, 0xD0E1, 0xD0E2, 0xD0E5, 0xD0E9,
335     0xD0EB, 0xD0F1, 0xD0F3, 0xD0F5, 0xD0F7, 0xD141, 0xD142, 0xD145,
336     0xD149, 0xD151, 0xD153, 0xD155, 0xD157, 0xD161, 0xD162, 0xD165,
337     0xD169, 0xD171, 0xD173, 0xD175, 0xD176, 0xD177, 0xD181, 0xD185,
338     0xD189, 0xD193, 0xD1A1, 0xD1A2, 0xD1A5, 0xD1A9, 0xD1AE, 0xD1B1,
339     0xD1B3, 0xD1B5, 0xD1B7, 0xD1BB, 0xD1C1, 0xD1C2, 0xD1C5, 0xD1C9,
340     0xD1D5, 0xD1D7, 0xD1E1, 0xD1E2, 0xD1E5, 0xD1F5, 0xD1F7, 0xD241,
341     0xD242, 0xD245, 0xD249, 0xD253, 0xD255, 0xD257, 0xD261, 0xD265,
342     0xD269, 0xD273, 0xD275, 0xD281, 0xD282, 0xD285, 0xD289, 0xD28E,
343     0xD291, 0xD295, 0xD297, 0xD2A1, 0xD2A5, 0xD2A9, 0xD2B1, 0xD2B7,
344     0xD2C1, 0xD2C2, 0xD2C5, 0xD2C9, 0xD2D7, 0xD2E1, 0xD2E2, 0xD2E5,
345     0xD2E9, 0xD2F1, 0xD2F3, 0xD2F5, 0xD2F7, 0xD341, 0xD342, 0xD345,
346     0xD349, 0xD351, 0xD355, 0xD357, 0xD361, 0xD362, 0xD365, 0xD367,
347     0xD368, 0xD369, 0xD36A, 0xD371, 0xD373, 0xD375, 0xD377, 0xD37B,
348     0xD381, 0xD385, 0xD389, 0xD391, 0xD393, 0xD397, 0xD3A1, 0xD3A2,
349     0xD3A5, 0xD3A9, 0xD3B1, 0xD3B3, 0xD3B5, 0xD3B7
350 };
351 
352 /**
353  * ks symbols
354  */
355 static const unsigned tblhhtg_ks[] =
356 {
357     0xC7D1, 0xB1DB, 0xB0FA, 0xC4C4, 0xC7BB, 0xC5CD, noneks, noneks,
358     0xA2B1, 0xA3DF, 0xA2D5, 0xA6B1, 0xA1B8, 0xA1B9, 0xA3DF, 0xA1DA,
359     0xA2C6, 0xA2CC, 0xA2CB, noneks, noneks, 0xA6BE, 0xA6B9, 0xA6C1,
360     0xA6C2, 0xA6B4, 0xA6AD, 0xA6AF, 0xA6B0, 0xA6C3, 0xA6C4, noneks,
361     0xA6AE, 0xA6B0, 0xA2D7, 0xA1E1, 0xA1D6, noneks, 0xA6BC, 0xA6B7,
362     0xA6B1, 0xA6AE, 0xA6B5, 0xA6B3, 0xA6B2, 0xA6AC, 0xA6B6, 0xA6BA,
363     0xA6BF, 0xA6B8, 0xA6BD, 0xA6C5, 0xA6C6, 0xA6C8, 0xA6C7, 0xA6C0,
364     0xA6BB, noneks, noneks, noneks, 0xA1E1, 0xA1E1, 0xA1E1, 0xA1E1
365 };
366 
367 /**
368  * kssm symbols
369  */
370 static const unsigned hhtg_tg[] =
371 {
372     0xD065, 0x8B69, 0x89C1, 0xC4F1, 0xCF41, 0xC8E1, 0xD3C5, 0xD931,
373     0xD931, 0xD481, 0xD482, 0xD488, 0xD48A, 0xD48F, 0xD493, 0xD494,
374     0xD4B0, 0xD4B1, 0xD4B2, 0xD931, 0xD931, 0xD4B5, 0xD4B6, 0xD4B7,
375     0xD4B8, 0xD4B9, 0xD4BA, 0xD4BB, 0xD4BC, 0xD4BD, 0xD4BE, 0xD496,
376     0xD497, 0xD49C, 0xD4A9, 0xD4AF, 0xD4F4, 0xD4F5, 0xD4C6, 0xD4C7,
377     0xD4C8, 0xD4C9, 0xD4CA, 0xD4CB, 0xD4CC, 0xD4CD, 0xD4CE, 0xD4CF,
378     0xD4D0, 0xD4D1, 0xD4D2, 0xD4D3, 0xD4D4, 0xD4D5, 0xD4D6, 0xD4D7,
379     0xD4D8, 0xD4F7, 0xD4FA, 0xD4FE, 0xD4DC, 0xD4DD, 0xD4DE, 0xD4DF
380 };
381 
382 #define LINEBASE    0x3013
383 
384 // ?
LineCharDir(hchar ch)385 static char LineCharDir(hchar ch)
386 {
387     static const char index2dir[] = { 10, 11, 9, 14, 15, 13, 6, 7, 5, 3, 12 };
388 
389     return (LINEBASE <= ch && ch < LINEBASE + 11 * 7) ?
390         index2dir[(ch - LINEBASE) % 11] : 0;
391 }
392 
393 
394 /**
395  * Convert hwp's special character to ks
396  */
s_hh2ks(hchar hh)397 static hchar s_hh2ks(hchar hh)
398 {
399     hchar i, idx = hh >> 8;
400 
401     if (hh == 0x81 || hh == 0x82)
402         return '\"';
403     else if (hh == 0x83 || hh == 0x84)
404         return '\'';
405     if (idx == 0x1F)
406     {
407         idx = 170;
408         i = hh & 0xff;
409         if (i >= 0x60)
410         {
411             idx++;
412             i -= 0x60;
413         }
414         return (idx << 8) | (i + 160);
415     }
416     if (((hh & 0xff) >= 0xC0) || (hh == 0x1F00))
417         return 0;
418     if (idx < 0x34 || idx >= 0x38)
419         return 0x2020;
420     if (hh >= HCA_TG)
421     {
422         return sal::static_int_cast<hchar>(tblhhtg_ks[hh - HCA_TG]);
423     }
424     hh -= HCA_KSS;
425     idx = hh / 0x60 + 161;
426     i = hh % 0x60 + 160;
427     if (idx == 170)
428         idx += 2;
429     return (idx << 8) | i;
430 }
431 
432 
433 /**
434  * Convert hwp's special character to kssm
435  */
s_hh2kssm(hchar hh)436 static hchar s_hh2kssm(hchar hh)
437 {
438     hchar i, idx = hh >> 8;
439 
440     if ((idx < 0x34 || idx >= 0x38) && idx != 0x1F)
441         return 0;
442     if (hh >= HCA_TG)
443         return sal::static_int_cast<hchar>(hhtg_tg[hh - HCA_TG]);
444     if (idx == 0x1F)
445         hh = hh - 0x1F00 + 0x360;
446     else
447     {
448         hh -= HCA_KSS;
449         if (hh >= 0x360)
450             hh += 0xC0;
451     }
452     idx = hh / 0xC0 + 217;
453     i = hh % 0xC0;
454     if (i >= 95)
455         i -= 2;
456     i += 48;
457     if (i >= 127)
458         i += 18;
459     return (idx << 8) | i;
460 }
461 
462 
lineCharConv(hchar ch)463 static hchar lineCharConv(hchar ch)
464 {
465     int flag;
466 
467     switch (ch)
468     {
469         case 0x3060 + '\'' - 31:
470         case 0x3060 + '\"' - 31:
471             ch--;
472             [[fallthrough]];
473         case 0x3060 + '\'' - 32:
474         case 0x3060 + '\"' - 32:
475         case 0x3060 + '{' - 32:
476         case 0x3060 + '[' - 32:
477         case 0x3060 + ']' - 32:
478         case 0x3060 + '}' - 32:
479             return ch - (0x3060 - 32);
480     }
481     flag = LineCharDir(ch);
482     switch (flag)
483     {
484         case 3:
485             return '-';
486         case 12:
487             return '|';
488         default:
489             return '+';
490     }
491 }
492 
493 
KsSearch(hchar c)494 static int KsSearch(hchar c)
495 {
496     int lo, hi, mid;
497 
498     lo = mid = 0;
499     hi = 2350 - 1;
500 
501     while (lo <= hi)
502     {
503         mid = (lo + hi) >> 1;
504         hchar c2 = ksTbl[mid];
505         if (c == c2)
506             break;
507         if (c < c2)
508             hi = mid - 1;
509         else
510             lo = mid + 1;
511     }
512     return mid;
513 }
514 
515 
cdkssm2ks_han(hchar kssm)516 static hchar cdkssm2ks_han(hchar kssm)
517 {
518     unsigned int index;
519     unsigned char lo, hi;
520 
521 /* "One" */
522     if (kssm == 0xd3c5)
523         return 0xc7d1;
524 
525     index = KsSearch(kssm);
526     if (kssm != ksTbl[index])
527         return jaso2ks(kssm);
528     hi = sal::static_int_cast<char>(index / (0xFE - 0xA1 + 1) + 0xB0);
529     lo = sal::static_int_cast<unsigned char>(index % (0xFE - 0xA1 + 1) + 0xA1);
530     return lo | (hi << 8);
531 }
532 
533 
534 #define IsHangul(c) ((c) & 0x8000)
535 #define IsHanja(c)  (((c) & 0x4000)==0x4000)
536 
537 static const hchar jaso_hh_code[] =
538 {
539     34881, 35905, 33860, 36929, 33862, 33863, 37953, 38977, 40001, 33866,
540     33867,
541     33868, 33869, 33870, 33871, 33872, 41025, 42049, 43073, 33876, 44097,
542     45121,
543     46145, 47169, 48193, 49217, 50241, 51265, 52289, 53313, 33889, 33921,
544     33953,
545     33985, 34017, 34113, 34145, 34177, 34209, 34241, 34273, 34369, 34401,
546     34433,
547     34465, 34497, 34529, 34625, 34657, 34689, 34721
548 };
549 
550 /* os: unused
551 static int is_jaso(hchar hh)
552 {
553     unsigned int i;
554 
555     for (i = 0; i < SAL_N_ELEMENTS(jaso_hh_code); i++)
556         if (hh == jaso_hh_code[i])
557             return 1;
558     return 0;
559 }*/
560 
561 
jaso2ks(hchar hh)562 static hchar jaso2ks(hchar hh)
563 {
564     for (size_t i = 0; i < SAL_N_ELEMENTS(jaso_hh_code); i++)
565         if (hh == jaso_hh_code[i])
566     {
567         return sal::static_int_cast<hchar>(0xa4a1 + i);
568     }
569     return 0;
570 }
571 
572 
573 //1 00011 00 001 00011
574 static const hchar choseong_to_unicode[] =
575 {
576     0x111e,  0,  0x1100, 0x1101, 0x1102, 0x1103, 0x1104, 0x1105,
577     0x1106, 0x1107, 0x1108, 0x1109, 0x110a, 0x110b, 0x110c, 0x110d,
578     0x110e, 0x110f, 0x1110, 0x1111, 0x1112, 0x1120, 0x1121, 0x1127,
579     0x112b, 0x112d, 0x112f, 0x1132, 0x1136, 0x1140, 0x114c, 0x1158
580 };
581 /* There are some other codes where the medial sound is 0 or 1. It needs to extract the rules in those area */
582 static const hchar joongseong_to_unicode[] =
583 {
584     0,      0,  0, 0x1161, 0x1162, 0x1163, 0x1164, 0x1165,
585     0,      0, 0x1166, 0x1167, 0x1168, 0x1169, 0x116a, 0x116b,
586     0,  0x1188, 0x116c, 0x116d, 0x116e, 0x116f, 0x1170, 0x1171,
587     0x1191, 0x1194, 0x1172, 0x1173, 0x1174, 0x1175, 0x119e, 0x11a1
588 };
589 
590 static const hchar jongseong_to_unicode[] =
591 {
592     0x11d9, 0  , 0x11a8, 0x11a9, 0x11aa, 0x11ab, 0x11ac, 0x11ad,
593     0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5,
594     0x11b6, 0x11b7, 0x11e6, 0x11b8, 0x11b9, 0x11ba, 0x11bb, 0x11bc,
595     0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x11eb, 0x11f0
596 };
597 
598 /* The medial sound is 0 or 1
599  * first 32 are consonants and vowels and the other 32 is combinations of alphabets
600  * (0x8000 ~ 0xa413) are the first 32. the other 32 start from 0x8400
601  * consonants and vowels area is made as a general table and the rest are made of a structure mapping table
602  *
603  * 844, except for the remaining 1152-308 is a combination of consonants and vowels. */
604 static const hchar jamo_to_unicode[] =
605 {
606     0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138,
607     0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140,
608     0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148,
609     0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x3172, 0x3173,
610 
611     0x3176, 0x317a, 0x317c, 0x317d, 0x317e, 0x3185, 0x3178, 0x317f,
612      0x3181, 0x316d, 0x11c3, 0x11c4, 0x1113, 0x1114, 0x1115, 0x1116,
613     0x11c7, 0x11c8, 0x11c9, 0x11ca, 0x11cb, 0x11cc, 0x11cd, 0x11ce,
614     0x11cf, 0x11d0, 0x11d1, 0x11d2, 0x11d3, 0x11d4, 0x11d5, 0x11d6,
615 
616     0x11d7, 0x11d8, 0x111b, 0x11da, 0x11db, 0x11dc, 0x11dd, 0x11de,
617     0x11df, 0x11e0, 0x11e1, 0x11e2, 0x111f, 0x11e3, 0x1122, 0x1123,
618     0x1124, 0x1125, 0x1126, 0x1128, 0x1129, 0x112a, 0x11e5, 0x112c,
619     0x112e, 0x1130, 0x1131, 0x1133, 0x1134, 0x1135, 0x1137, 0x1138,
620 
621     0x1139, 0x113a, 0x113b, 0x113c, 0x113d, 0x113e, 0x113f, 0x1141,
622     0x11ed, 0x1142, 0x1143, 0x1144, 0x1145, 0x1146, 0x1147, 0x1148,
623     0x1149, 0x11ef, 0x114a, 0x114b, 0x11f1, 0x11f2, 0x114d, 0x114e,
624     0x114f, 0x1150, 0x1151, 0x1152, 0x1153, 0x1154, 0x1155, 0x1156,
625 
626     0x1157, 0x11f5, 0x11f6, 0x11f7, 0x11f8, 0x11f9, 0x1176, 0x1177,
627     0x1178, 0x1179, 0x117a, 0x117b, 0x117c, 0x117d, 0x117e, 0x117f,
628     0x1180, 0x1181, 0x1182, 0x1183, 0x1184, 0x1185, 0x1186, 0x1187,
629     0x1189, 0x118a, 0x118b, 0x118c, 0x118d, 0x118e, 0x118f, 0x1190,
630 
631     0x1192, 0x1193, 0x1195, 0x1196, 0x1197, 0x1198, 0x1199, 0x119a,
632     0x119b, 0x119c, 0x119d, 0x119f, 0x11a0, 0x11a2, 0x11a8, 0x11a9,
633     0x11aa, 0x11ab, 0x11ac, 0x11ad, 0x11ae, 0x1104, 0x11af, 0x11b0,
634     0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8,
635 
636     0x1108, 0x11b9, 0x11ba, 0x11bb, 0x11bc, 0x11bd, 0x3149, 0x11be,
637     0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x111e, 0x1120, 0x1127, 0x11e7,
638     0x11e8, 0x11ea, 0x1136, 0x1158, 0x11e6, 0x11eb, 0x11f0, 0x11d9,
639     0x11c3, 0x11c4, 0x11c5, 0x1114, 0x11c6, 0x1116, 0x11c7, 0x11c8,
640 
641     0x11c9, 0x11ca, 0x11cb, 0x3169, 0x11cd, 0x11ce, 0x11cf, 0x1119,
642     0x11d1, 0x11d2, 0x11d3, 0x11d4, 0x11d5, 0x11d6, 0x11d7, 0x11d8,
643     0x111b, 0x11da, 0x11db, 0x11dc, 0x11dd, 0x11de, 0x11df, 0x11e0,
644     0x11e1, 0x11e2, 0x111f, 0x11e3, 0x1122, 0x1123, 0x1124, 0x1125,
645 
646     0x1126, 0x1128, 0x1129, 0x11e4, 0x11e5, 0x112c, 0x112e, 0x1130,
647     0x1131, 0x1133, 0x1134, 0x1135, 0x1137, 0x1138, 0x1139, 0x113a,
648     0x113b, 0x113c, 0x113d, 0x113e, 0x113f, 0x11ec, 0x11ed, 0x1142,
649     0x1143, 0x1144, 0x1145, 0x1146, 0x1147, 0x1148, 0x1149, 0x11ef,
650 
651     0x114a, 0x114b, 0x11f1, 0x11f2, 0x114d, 0x114e, 0x114f, 0x1150,
652     0x1151, 0x1152, 0x1153, 0x1154, 0x1155, 0x1156, 0x1157, 0x11f5,
653     0x11f6, 0x11f7, 0x11f8, 0x11f9
654 };
655 
656 struct JamoComp{
657     int size;
658     hchar v1;
659     hchar v2;
660     hchar v3;
661 };
662 /* 704 + 12 = 706 */
663 static const JamoComp jamocomp1_to_unicode[] =
664 {
665     {3, 0x1100, 0x1161, 0x11e7}, {3, 0x1100, 0x1161, 0x3167},
666     {3, 0x1100, 0x1161, 0x11dd}, {3, 0x1100, 0x1161, 0x11e2},
667     {3, 0x1100, 0x1161, 0x11e5}, {3, 0x1100, 0x1161, 0x11f1},
668     {3, 0x1100, 0x1163, 0x11e2}, {3, 0x1100, 0x1163, 0x11f9},
669     {3, 0x1100, 0x1165, 0x11e7}, {3, 0x1100, 0x1165, 0x11c7},
670     {3, 0x1100, 0x1165, 0x11dd}, {3, 0x1100, 0x1165, 0x11e2},
671 
672     {3, 0x1100, 0x1165, 0x11e3}, {3, 0x1100, 0x1167, 0x11e7},
673     {3, 0x1100, 0x1167, 0x11f1}, {3, 0x1100, 0x1167, 0x11f9},
674     {3, 0x1100, 0x1169, 0x11d6}, {3, 0x1100, 0x1169, 0x11dd},
675     {3, 0x1100, 0x1169, 0x11e2}, {3, 0x1100, 0x1169, 0x11f1},
676     {3, 0x1100, 0x1169, 0x11f7}, {3, 0x1100, 0x1169, 0x11f8},
677     {3, 0x1100, 0x116a, 0x11f9}, {3, 0x1100, 0x116d, 0x11e2},
678     {3, 0x1100, 0x116e, 0x11c7}, {3, 0x1100, 0x116e, 0x11cd},
679     {3, 0x1100, 0x116e, 0x11da}, {3, 0x1100, 0x116e, 0x11dd},
680 
681     {3, 0x1100, 0x116e, 0x11e2}, {3, 0x1100, 0x116e, 0x11f6},
682     {3, 0x1100, 0x116e, 0x11f9}, {3, 0x1100, 0x116f, 0x11c7},
683     {3, 0x1100, 0x116f, 0x11f9}, {3, 0x1100, 0x1172, 0x11e2},
684     {3, 0x1100, 0x1172, 0x11f9}, {3, 0x1100, 0x1173, 0x11c7},
685     {3, 0x1100, 0x1173, 0x11dd}, {3, 0x1100, 0x1173, 0x11df},
686     {3, 0x1100, 0x1173, 0x11e2}, {3, 0x1100, 0x1173, 0x11f9},
687     {3, 0x1100, 0x1174, 0x11f9}, {3, 0x1100, 0x1175, 0x11e7},
688     {3, 0x1100, 0x1175, 0x11cd}, {3, 0x1100, 0x1175, 0x11e2},
689 
690     {3, 0x1100, 0x1175, 0x11f9}, {3, 0x1100, 0x1191, 0x11f9},
691     {3, 0x1100, 0x119e, 0x11e7}, {3, 0x1100, 0x119e, 0x11d3},
692     {3, 0x1100, 0x119e, 0x11d5}, {3, 0x1100, 0x119e, 0x11e3},
693     {3, 0x1100, 0x11a1, 0x11f1}, {2, 0x1100, 0x1176, 0x0000},
694     {2, 0x1100, 0x1178, 0x0000}, {2, 0x1100, 0x117c, 0x0000},
695     {3, 0x1100, 0x117c, 0x11ab}, {3, 0x1100, 0x117c, 0x11af},
696     {3, 0x1100, 0x117c, 0x11b7}, {2, 0x1100, 0x1189, 0x0000},
697     {3, 0x1100, 0x1189, 0x11ab}, {3, 0x1100, 0x1189, 0x11bc},
698 
699     {2, 0x1100, 0x118b, 0x0000}, {3, 0x1100, 0x118b, 0x11ab},
700     {2, 0x1100, 0x118c, 0x0000}, {2, 0x1100, 0x118d, 0x0000},
701     {2, 0x1100, 0x1192, 0x0000}, {3, 0x1100, 0x1192, 0x11bc},
702     {2, 0x1100, 0x1195, 0x0000}, {2, 0x1100, 0x1196, 0x0000},
703     {2, 0x1100, 0x1198, 0x0000}, {2, 0x1100, 0x119b, 0x0000},
704     {2, 0x1100, 0x119c, 0x0000}, {2, 0x1100, 0x119d, 0x0000},
705     {2, 0x1100, 0x119f, 0x0000}, {3, 0x1100, 0x119f, 0x11bc},
706     {3, 0x1101, 0x1163, 0x11e2}, {3, 0x1101, 0x1165, 0x11ec},
707 
708     {3, 0x1101, 0x1165, 0x11ed}, {3, 0x1101, 0x116e, 0x11e2},
709     {3, 0x1101, 0x1172, 0x11e2}, {3, 0x1101, 0x1175, 0x11e2},
710     {3, 0x1101, 0x1175, 0x11f9}, {3, 0x1101, 0x1191, 0x11bc},
711     {2, 0x1101, 0x1176, 0x0000}, {2, 0x1101, 0x117b, 0x0000},
712     {2, 0x1101, 0x1189, 0x0000}, {2, 0x1101, 0x118c, 0x0000},
713     {2, 0x1101, 0x1198, 0x0000}, {3, 0x1102, 0x1161, 0x11e7},
714     {3, 0x1102, 0x1161, 0x11c4}, {3, 0x1102, 0x1161, 0x11da},
715     {3, 0x1102, 0x1161, 0x11dd}, {3, 0x1102, 0x1161, 0x11e2},
716 
717     {3, 0x1102, 0x1161, 0x11f9}, {3, 0x1102, 0x1165, 0x11db},
718     {3, 0x1102, 0x1165, 0x11dd}, {3, 0x1102, 0x1165, 0x11e3},
719     {3, 0x1102, 0x1167, 0x11c5}, {3, 0x1102, 0x1167, 0x11c7},
720     {3, 0x1102, 0x1167, 0x11f9}, {3, 0x1102, 0x1169, 0x11e2},
721     {3, 0x1102, 0x1169, 0x11e4}, {3, 0x1102, 0x1169, 0x11f3},
722     {3, 0x1102, 0x116e, 0x11c6}, {3, 0x1102, 0x116e, 0x11c7},
723     {3, 0x1102, 0x116e, 0x11c8}, {3, 0x1102, 0x116e, 0x11dd},
724     {3, 0x1102, 0x116e, 0x11e2}, {3, 0x1102, 0x116e, 0x11f5},
725 
726     {3, 0x1102, 0x1172, 0x11e2}, {3, 0x1102, 0x1173, 0x11c3},
727     {3, 0x1102, 0x1175, 0x11c3}, {3, 0x1102, 0x1175, 0x11dd},
728     {3, 0x1102, 0x1175, 0x11e2}, {3, 0x1102, 0x119e, 0x11d7},
729     {2, 0x1102, 0x1176, 0x0000}, {2, 0x1102, 0x117c, 0x0000},
730     {3, 0x1102, 0x117c, 0x11a8}, {2, 0x1102, 0x118c, 0x0000},
731     {2, 0x1102, 0x1196, 0x0000}, {2, 0x1102, 0x1197, 0x0000},
732     {2, 0x1102, 0x1198, 0x0000}, {2, 0x1102, 0x119b, 0x0000},
733     {3, 0x1103, 0x1161, 0x11e7}, {3, 0x1103, 0x1161, 0x11c7},
734 
735     {3, 0x1103, 0x1161, 0x1119}, {3, 0x1103, 0x1161, 0x11db},
736     {3, 0x1103, 0x1161, 0x11dd}, {3, 0x1103, 0x1161, 0x11e2},
737     {3, 0x1103, 0x1161, 0x11f1}, {3, 0x1103, 0x1161, 0x11f9},
738     {3, 0x1103, 0x1163, 0x11e2}, {3, 0x1103, 0x1163, 0x11f1},
739     {3, 0x1103, 0x1165, 0x11dd}, {3, 0x1103, 0x1167, 0x11f9},
740     {3, 0x1103, 0x1169, 0x11e7}, {3, 0x1103, 0x1169, 0x11d6},
741     {3, 0x1103, 0x1169, 0x11e2}, {3, 0x1103, 0x1169, 0x11f1},
742     {3, 0x1103, 0x116d, 0x11e2}, {3, 0x1103, 0x116e, 0x11ce},
743 
744     {3, 0x1103, 0x116e, 0x1119}, {3, 0x1103, 0x116e, 0x11da},
745     {3, 0x1103, 0x116e, 0x11e2}, {3, 0x1103, 0x1172, 0x11e2},
746     {3, 0x1103, 0x1173, 0x11cd}, {3, 0x1103, 0x1173, 0x11ce},
747     {3, 0x1103, 0x1173, 0x11e2}, {3, 0x1103, 0x1173, 0x11e3},
748     {3, 0x1103, 0x1173, 0x11f1}, {3, 0x1103, 0x1174, 0x11f9},
749     {3, 0x1103, 0x1175, 0x11f9}, {3, 0x1103, 0x119e, 0x11e7},
750     {3, 0x1103, 0x119e, 0x11e8}, {3, 0x1103, 0x119e, 0x11ea},
751     {3, 0x1103, 0x119e, 0x11c3}, {3, 0x1103, 0x119e, 0x11cc},
752 
753     {3, 0x1103, 0x119e, 0x11e3}, {3, 0x1103, 0x119e, 0x11e9},
754     {2, 0x1103, 0x1176, 0x0000}, {2, 0x1103, 0x1178, 0x0000},
755     {2, 0x1103, 0x117c, 0x0000}, {3, 0x1103, 0x117c, 0x11b7},
756     {2, 0x1103, 0x1189, 0x0000}, {3, 0x1103, 0x1189, 0x11ab},
757     {2, 0x1103, 0x118c, 0x0000}, {2, 0x1103, 0x1195, 0x0000},
758     {2, 0x1103, 0x1196, 0x0000}, {2, 0x1103, 0x1198, 0x0000},
759     {2, 0x1103, 0x1199, 0x0000}, {3, 0x1103, 0x1199, 0x11ab},
760     {3, 0x1103, 0x1199, 0x11bc}, {3, 0x1104, 0x1161, 0x11d8},
761 
762     {3, 0x1104, 0x1161, 0x11e2}, {3, 0x1104, 0x1161, 0x11f9},
763     {3, 0x1104, 0x1163, 0x11e2}, {3, 0x1104, 0x1169, 0x11e2},
764     {3, 0x1104, 0x1169, 0x11f9}, {3, 0x1104, 0x116d, 0x11e2},
765     {3, 0x1104, 0x116e, 0x11e2}, {3, 0x1104, 0x116e, 0x11f9},
766     {3, 0x1104, 0x1172, 0x11e2}, {3, 0x1104, 0x1173, 0x11e2},
767     {3, 0x1104, 0x1175, 0x11f9}, {2, 0x1104, 0x117b, 0x0000},
768     {2, 0x1104, 0x118c, 0x0000}, {2, 0x1104, 0x1198, 0x0000},
769     {3, 0x1105, 0x1161, 0x11e7}, {3, 0x1105, 0x1161, 0x11dd},
770 
771     {3, 0x1105, 0x1161, 0x11e2}, {3, 0x1105, 0x1161, 0x11f5},
772     {3, 0x1105, 0x1161, 0x11f9}, {3, 0x1105, 0x1163, 0x11e2},
773     {3, 0x1105, 0x1167, 0x11c7}, {3, 0x1105, 0x1167, 0x11e2},
774     {3, 0x1105, 0x1167, 0x11f9}, {3, 0x1105, 0x1169, 0x11dd},
775     {3, 0x1105, 0x1169, 0x11e2}, {3, 0x1105, 0x1169, 0x11f1},
776     {3, 0x1105, 0x116d, 0x11dd}, {3, 0x1105, 0x116d, 0x11e2},
777     {3, 0x1105, 0x116e, 0x11dd}, {3, 0x1105, 0x116e, 0x11e2},
778     {3, 0x1105, 0x1172, 0x11e2}, {3, 0x1105, 0x1173, 0x11dd},
779 
780     {3, 0x1105, 0x1173, 0x11e2}, {3, 0x1105, 0x1175, 0x11dd},
781     {3, 0x1105, 0x1175, 0x11e2}, {3, 0x1105, 0x1175, 0x11f9},
782     {3, 0x1105, 0x119e, 0x11d7}, {3, 0x1105, 0x119e, 0x11dc},
783     {3, 0x1105, 0x119e, 0x11dd}, {2, 0x1105, 0x1176, 0x0000},
784 
785 /* From here, numbers are not changed. So must change 3 to 2 manually. */
786     {2, 0x1105, 0x1178, 0x0000}, {2, 0x1105, 0x117a, 0x0000},
787     {2, 0x1105, 0x117b, 0x0000}, {2, 0x1105, 0x1186, 0x0000},
788     {2, 0x1105, 0x1187, 0x0000}, {2, 0x1105, 0x118c, 0x0000},
789     {2, 0x1105, 0x1195, 0x0000}, {2, 0x1105, 0x1196, 0x0000},
790 
791     {2, 0x1105, 0x1198, 0x0000}, {2, 0x1105, 0x1199, 0x0000},
792     {3, 0x1105, 0x1199, 0x11bc}, {2, 0x1105, 0x119b, 0x0000},
793     {2, 0x111a, 0x1163, 0x0000}, {3, 0x111a, 0x1163, 0x11bc},
794     {3, 0x1106, 0x1161, 0x11e8}, {3, 0x1106, 0x1161, 0x11c7},
795     {3, 0x1106, 0x1161, 0x11cd}, {3, 0x1106, 0x1161, 0x1119},
796     {3, 0x1106, 0x1161, 0x11d8}, {3, 0x1106, 0x1161, 0x11e2},
797     {3, 0x1106, 0x1163, 0x11e2}, {3, 0x1106, 0x1165, 0x11c6},
798     {3, 0x1106, 0x1165, 0x11f9}, {3, 0x1106, 0x1169, 0x11c6},
799 
800     {3, 0x1106, 0x1169, 0x11dd}, {3, 0x1106, 0x1169, 0x11e2},
801     {3, 0x1106, 0x116d, 0x11e2}, {3, 0x1106, 0x116e, 0x11e7},
802     {3, 0x1106, 0x116e, 0x11c7}, {3, 0x1106, 0x116e, 0x11e2},
803     {3, 0x1106, 0x116e, 0x11ec}, {3, 0x1106, 0x116e, 0x11ed},
804     {3, 0x1106, 0x116e, 0x11f9}, {3, 0x1106, 0x116f, 0x11f9},
805     {3, 0x1106, 0x1173, 0x11e7}, {3, 0x1106, 0x1174, 0x11f9},
806     {3, 0x1106, 0x1175, 0x11e7}, {3, 0x1106, 0x1175, 0x11f6},
807     {3, 0x1106, 0x1175, 0x11f9}, {3, 0x1106, 0x119e, 0x11c3},
808 
809     {2, 0x1106, 0x1176, 0x0000}, {2, 0x1106, 0x1178, 0x0000},
810     {2, 0x1106, 0x117c, 0x0000}, {3, 0x1106, 0x117c, 0x11af},
811     {2, 0x1106, 0x1182, 0x0000}, {2, 0x1106, 0x1183, 0x0000},
812     {2, 0x1106, 0x118c, 0x0000}, {2, 0x1106, 0x1196, 0x0000},
813     {3, 0x1106, 0x1196, 0x11b7}, {2, 0x1106, 0x1198, 0x0000},
814     {2, 0x1106, 0x119f, 0x0000}, {3, 0x1106, 0x119f, 0x11ab},
815     {3, 0x1106, 0x119f, 0x11bc}, {3, 0x1107, 0x1161, 0x11e7},
816     {3, 0x1107, 0x1161, 0x11c9}, {3, 0x1107, 0x1161, 0x11dd},
817 
818     {3, 0x1107, 0x1161, 0x11e2}, {3, 0x1107, 0x1161, 0x11e3},
819     {3, 0x1107, 0x1161, 0x11f1}, {3, 0x1107, 0x1161, 0x11f6},
820     {3, 0x1107, 0x1161, 0x11f9}, {3, 0x1107, 0x1165, 0x11c7},
821     {3, 0x1107, 0x1167, 0x11f1}, {3, 0x1107, 0x1169, 0x11e7},
822     {3, 0x1107, 0x1169, 0x11dd}, {3, 0x1107, 0x1169, 0x11e2},
823     {3, 0x1107, 0x116d, 0x11e2}, {3, 0x1107, 0x116e, 0x11e7},
824     {3, 0x1107, 0x116e, 0x11c7}, {3, 0x1107, 0x116e, 0x1119},
825     {3, 0x1107, 0x116e, 0x11d1}, {3, 0x1107, 0x116e, 0x11d2},
826 
827     {3, 0x1107, 0x116e, 0x11e2}, {3, 0x1107, 0x116e, 0x11ef},
828     {3, 0x1107, 0x116e, 0x11f9}, {3, 0x1107, 0x116f, 0x11f9},
829     {3, 0x1107, 0x1173, 0x11e7}, {3, 0x1107, 0x1173, 0x11c3},
830     {3, 0x1107, 0x1175, 0x11e7}, {3, 0x1107, 0x1175, 0x11e2},
831     {3, 0x1107, 0x1175, 0x11f1}, {3, 0x1107, 0x1175, 0x11f9},
832     {3, 0x1107, 0x119e, 0x11c3}, {3, 0x1107, 0x119e, 0x11d5},
833     {3, 0x1107, 0x119e, 0x11e3}, {3, 0x1107, 0x11a1, 0x11f1},
834     {2, 0x1107, 0x1176, 0x0000}, {2, 0x1107, 0x1177, 0x0000},
835 
836     {2, 0x1107, 0x1178, 0x0000}, {2, 0x1107, 0x117c, 0x0000},
837     {3, 0x1107, 0x117c, 0x11a8}, {3, 0x1107, 0x117c, 0x11af},
838     {3, 0x1107, 0x117c, 0x11b7}, {3, 0x1107, 0x117c, 0x11bc},
839     {2, 0x1107, 0x1182, 0x0000}, {2, 0x1107, 0x118c, 0x0000},
840     {2, 0x1107, 0x1196, 0x0000}, {2, 0x1107, 0x1198, 0x0000},
841     {2, 0x1107, 0x119a, 0x0000}, {2, 0x1107, 0x119f, 0x0000},
842     {3, 0x1107, 0x119f, 0x11ab}, {3, 0x1107, 0x119f, 0x11bc},
843     {3, 0x1108, 0x1161, 0x11e2}, {3, 0x1108, 0x1167, 0x11f9},
844 
845     {3, 0x1108, 0x1169, 0x11e2}, {3, 0x1108, 0x116e, 0x11e2},
846     {3, 0x1108, 0x1174, 0x11f9}, {3, 0x1108, 0x1175, 0x11f9},
847     {3, 0x1121, 0x116a, 0x11f9}, {3, 0x1121, 0x119e, 0x114d},
848     {2, 0x1121, 0x118c, 0x0000}, {2, 0x1121, 0x1198, 0x0000},
849     {3, 0x1109, 0x1161, 0x11ca}, {3, 0x1109, 0x1161, 0x11dd},
850     {3, 0x1109, 0x1161, 0x11e2}, {3, 0x1109, 0x1161, 0x11f1},
851     {3, 0x1109, 0x1161, 0x11f9}, {3, 0x1109, 0x1163, 0x11e2},
852     {3, 0x1109, 0x1163, 0x11f1}, {3, 0x1109, 0x1165, 0x11e7},
853 
854     {3, 0x1109, 0x1165, 0x11c3}, {3, 0x1109, 0x1165, 0x11ec},
855     {3, 0x1109, 0x1165, 0x11ed}, {3, 0x1109, 0x1167, 0x11e7},
856     {3, 0x1109, 0x1167, 0x11d5}, {3, 0x1109, 0x1167, 0x11dd},
857     {3, 0x1109, 0x1167, 0x11e3}, {3, 0x1109, 0x1167, 0x11f1},
858     {3, 0x1109, 0x1167, 0x11f9}, {3, 0x1109, 0x1169, 0x11c7},
859     {3, 0x1109, 0x1169, 0x11e2}, {3, 0x1109, 0x116a, 0x11f9},
860     {3, 0x1109, 0x116b, 0x11f9}, {3, 0x1109, 0x116d, 0x11e2},
861     {3, 0x1109, 0x116d, 0x11f1}, {3, 0x1109, 0x116e, 0x11e7},
862 
863     {3, 0x1109, 0x116e, 0x11e2}, {3, 0x1109, 0x116e, 0x11f9},
864     {3, 0x1109, 0x1172, 0x11e2}, {3, 0x1109, 0x1173, 0x11e2},
865     {3, 0x1109, 0x1173, 0x11e3}, {3, 0x1109, 0x1173, 0x11f1},
866     {3, 0x1109, 0x1174, 0x11f9}, {3, 0x1109, 0x1175, 0x11c7},
867     {3, 0x1109, 0x1175, 0x11ce}, {3, 0x1109, 0x1175, 0x11da},
868     {3, 0x1109, 0x1175, 0x11e2}, {3, 0x1109, 0x1175, 0x11f9},
869     {3, 0x1109, 0x1191, 0x11f9}, {3, 0x1109, 0x119e, 0x11ca},
870     {3, 0x1109, 0x119e, 0x11d6}, {3, 0x1109, 0x119e, 0x11f1},
871 
872     {3, 0x1109, 0x119e, 0x11e3}, {3, 0x1109, 0x11a1, 0x11dd},
873     {3, 0x1109, 0x11a1, 0x11f1}, {2, 0x1109, 0x1176, 0x0000},
874     {2, 0x1109, 0x1177, 0x0000}, {2, 0x1109, 0x1178, 0x0000},
875     {2, 0x1109, 0x117c, 0x0000}, {3, 0x1109, 0x117c, 0x11a8},
876     {3, 0x1109, 0x117c, 0x11af}, {3, 0x1109, 0x117c, 0x11b7},
877     {3, 0x1109, 0x117c, 0x11bc}, {2, 0x1109, 0x117e, 0x0000},
878     {2, 0x1109, 0x1189, 0x0000}, {3, 0x1109, 0x1189, 0x11ab},
879     {2, 0x1109, 0x118c, 0x0000}, {2, 0x1109, 0x1190, 0x0000},
880 
881     {2, 0x1109, 0x1192, 0x0000}, {3, 0x1109, 0x1192, 0x11bc}
882 };
883 
884 //#define IS_OLD_HAN(x) (((x) >= 0x8020 && (x) <= 0x83ff ) || ( (x) >= 0x8420 && (x) <= 0x843f )) // beside these, there are very much characters in the hangul.
hcharconv(hchar ch,hchar * dest,int codeType)885 int hcharconv(hchar ch, hchar *dest, int codeType)
886 {
887     unsigned char lo;
888      //printf("hcharconv[%04x]\n",ch);
889     if (ch < 128){
890         dest[0] = ch;
891         return 1;
892     }
893     if (IsHangul(ch))
894     {
895         hchar ch2 = ch;
896         if (codeType == KS)
897             ch = cdkssm2ks_han(ch);
898         else if( codeType == UNICODE ){
899                 if( ch2 == 0xd3c5 ){
900                     dest[0] = 0xd55c;
901                     return 1 ;
902                 }
903                 int res = kssm_hangul_to_ucs2(ch, dest);
904                //printf("hcharconv Hangul[%04x]\n",dest[0]);
905                 return res;
906         }
907         dest[0] = ch;
908         return 1;
909     }
910       /* Chinese characters have a value of 4888 kinds from 0x4000. */
911     else if (IsHanja(ch))
912     {
913         unsigned int index;
914         unsigned char hi;
915         /*Out of 4888 kinds are Chinese characters which are defined by Hangul Word Processor. For this
916           there is no mapping table to convert to Unicode or completion code(KSC5601-87, EUC-KR)
917          */
918         if ((index = ch - 0x4000) >= 4888)
919         {
920             if( codeType == UNICODE )
921                 dest[0]= 0x25A1;
922             else
923                 dest[0]= 0xA1E0;
924             return 1;
925         }
926         if (codeType == KS)
927         {
928             /* Chinese code is divided into the upper cord and lower cord. Lower code has the value from 0xA1 up to 0xFE.
929                In other words, the number of lower code is the number of (0xFE - 0xA1) +1
930              */
931             hi = sal::static_int_cast<unsigned char>(index / (0xFE - 0xA1 + 1) + 0xCA);
932             lo = sal::static_int_cast<unsigned char>(index % (0xFE - 0xA1 + 1) + 0xA1);
933             ch = (hi << 8) | lo;
934         }
935         else if(codeType == UNICODE){
936                 hi = sal::static_int_cast<unsigned char>(index / (0xFE - 0xA1 + 1) + 0xCA);
937                 lo = sal::static_int_cast<unsigned char>(index % (0xFE - 0xA1 + 1) + 0xA1);
938                 ch = (hi << 8) | lo;
939                 ch = ksc5601_han_to_ucs2(ch);
940         }
941         else
942         {
943             hi = sal::static_int_cast<unsigned char>(index / (0x100 - 0x31 - 0x11 - 2) + 0xE0);
944             lo = sal::static_int_cast<unsigned char>(index % (0x100 - 0x31 - 0x11 - 2) + 0x31);
945             if (lo >= 0x7F)
946                 lo += 0x12;
947             ch = (hi << 8) | lo;
948         }
949           //printf("hcharconv Hanja[%04x]\n",ch);
950         dest[0] = ch;
951         return 1;
952     }
953     if (LineCharDir(ch))
954     {
955         dest[0] = lineCharConv(ch);
956         return 1;
957     }
958     else if (0x2f00 <= ch && ch <= 0x2f6f && (ch & 0x0f) < 9)
959     {
960 // bullet
961         lo = sal::static_int_cast<unsigned char>(ch & 0x0f);
962 
963         if( codeType != KSSM )
964         {
965             if (ch < 0x2f10) ch = 0xa1e0;
966             else if (ch < 0x2f20) ch = 0xa1db;
967             else if (ch < 0x2f30) ch = 0xa1de;
968             else if (ch < 0x2f40) ch = 0xa1e2;
969             else if (ch < 0x2f50) ch = 0xa1e4;
970             else if (ch < 0x2f60) ch = 0xa2b7;
971             else ch = 0xa2b9;
972 
973             ch = (lo < 6) ? ch : ch + 1;
974             if( codeType == UNICODE)
975                      ch = ksc5601_sym_to_ucs2(ch);
976         }
977         else
978         {
979             if (ch < 0x2f10) ch = 0xd970;
980             else if (ch < 0x2f20) ch = 0xd96b;
981             else if (ch < 0x2f30) ch = 0xd96e;
982             else if (ch < 0x2f40) ch = 0xd972;
983             else if (ch < 0x2f50) ch = 0xd974;
984             else if (ch < 0x2f60) ch = 0xd9b7;
985             else ch = 0xd9b9;
986             ch = (lo < 6) ? ch : ch + 1;
987         }
988           //printf("hcharconv Bullet[%04x]\n",ch);
989         dest[0] = ch;
990         return 1 ;
991     }
992 /*
993  * Special characters code
994  * In Hangul Word Processor, special characters begins from 0x3400. Combinations are from 0xA1A0
995  */
996     else
997     {
998         if( codeType != KSSM )
999         {
1000                //printf("code[0x%04x]\n",ch);
1001             hchar ch2 = ch;
1002             ch = s_hh2ks(ch);
1003                 //printf("code ks[0x%04x]\n",ch);
1004             if( codeType == UNICODE ){
1005                      if (ch < 128){
1006                         dest[0] = ch;
1007                         return 1;
1008                      }
1009                      /* Hangul and Computer: 0x37c0 ~ 0x37c5 */
1010                      if( ch2 >= 0x37c0 && ch2 <= 0x37c5 ){
1011                          if( ch2 == 0x37c0 ) dest[0] = 0xd55c;
1012                          else if( ch2 == 0x37c1 ) dest[0] = 0xae00;
1013                          else if( ch2 == 0x37c2 ) dest[0] = 0xacfc;
1014                          else if( ch2 == 0x37c3 ) dest[0] = 0xcef4;
1015                          else if( ch2 == 0x37c4 ) dest[0] = 0xd4e8;
1016                          else if( ch2 == 0x37c5 ) dest[0] = 0xd130;
1017                          return 1;
1018                      }
1019                      if( ch == 0x2020 ){
1020                           switch( ch2 ){
1021                                 case 0x309b :
1022                                      ch = 0xff62;
1023                                      break;
1024                                 case 0x309d :
1025                                      ch = 0xff63;
1026                                      break;
1027                                 default:
1028                                      ch = 0x25a1;
1029                                      break;
1030                           }
1031                      }
1032                      else{
1033                           ch = ksc5601_sym_to_ucs2(ch);
1034                      }
1035                      //printf("code ucs2[0x%04x]\n",ch);
1036             }
1037         }
1038         else{
1039             ch = s_hh2kssm(ch);
1040           }
1041 
1042         if (ch == 0){ // not '?', but square mark
1043                 if( codeType == UNICODE )
1044                      dest[0] =  0x25A1;
1045                 else
1046                      dest[0] =  0xA1E0;
1047                 return 1;
1048           }
1049           //printf("hcharconv Special[%04x]\n",ch);
1050         dest[0] = ch;
1051         return 1;
1052     }
1053 }
1054 
1055 /* If it's Korean(Hangul). */
kssm_hangul_to_ucs2(hchar ch,hchar * dest)1056 int kssm_hangul_to_ucs2(hchar ch, hchar *dest)
1057 {
1058     hchar choseong, joongseong, jongseong;
1059 
1060     choseong = ((ch >> 10) & 0x1f);
1061     joongseong = ((ch >> 5) & 0x1f);
1062     jongseong = (ch & 0x1f) ;
1063 
1064      //printf("kssm_hangul_to_ucs2 : [%d,%d,%d]\n", choseong,joongseong,jongseong);
1065 
1066     if( joongseong < 2 ){ /* Not combined area, medial sound = 0,1 */
1067          if( joongseong == 0 && ch < 0xa414 ){ /* consonants and vowels includes old characters */
1068              int index = choseong * 32 + jongseong;
1069              dest[0] = jamo_to_unicode[index];
1070              return 1;
1071          }
1072          else{ /* combination of consonants and vowels includes old characters: an unfinished table */
1073              unsigned int index = choseong * 32 + jongseong - 308;
1074              if( index < SAL_N_ELEMENTS(jamocomp1_to_unicode) ){
1075                  dest[0] = jamocomp1_to_unicode[index].v1;
1076                  dest[1] = jamocomp1_to_unicode[index].v2;
1077                  dest[2] = jamocomp1_to_unicode[index].v3;
1078                  return jamocomp1_to_unicode[index].size;
1079              }
1080              dest[0] = 0x25a1; // empty square.
1081              return 1;
1082          }
1083      }
1084      else if ( choseong == 1 && jongseong == 1 ){ /* Vowel */
1085          dest[0] = joongseong_to_unicode[joongseong];
1086          return 1;
1087      }
1088      else if ( joongseong == 2 && jongseong == 1 ){  /* Consonant */
1089         dest[0] = choseong_to_unicode[choseong];
1090         return 1;
1091     }
1092      else if( choseong > 20 || choseong == 0 ||
1093              joongseong == 17 || joongseong == 24 ||
1094              joongseong == 25 || joongseong > 29 ||
1095              jongseong == 0 || jongseong == 18 ||
1096              jongseong > 29 ||
1097              choseong == 1 || joongseong == 2  /* Incomplete Hangul */
1098              ) { /* Gore */
1099          int count = 0;
1100          if( choseong != 1 ){
1101              dest[count] = choseong_to_unicode[choseong];
1102              count++;
1103          }
1104          if( joongseong > 2 ){
1105              dest[count] = joongseong_to_unicode[joongseong];
1106              count++;
1107          }
1108          if( jongseong != 1 ){
1109              dest[count] = jongseong_to_unicode[jongseong];
1110              count++;
1111          }
1112          return count;
1113     }
1114 
1115     choseong -= 2;
1116     if( joongseong < 0x8 )
1117          joongseong -= 3;
1118     else if( joongseong < 0x10 )
1119          joongseong -= 5;
1120     else if( joongseong < 0x18 )
1121          joongseong -= 7;
1122     else
1123          joongseong -= 9;
1124 
1125     choseong *= (NUM_JOONGSEONG * NUM_JONGSEONG);
1126     joongseong *= NUM_JONGSEONG;
1127     jongseong -= jongseong > 0x12 ?  2 : 1;
1128 
1129     dest[0] = UNI_HANGUL_FIRST + choseong + joongseong + jongseong;
1130     return 1;
1131 }
1132 
ksc5601_sym_to_ucs2(hchar input)1133 hchar ksc5601_sym_to_ucs2 (hchar input)
1134 {
1135     unsigned char ch = sal::static_int_cast<unsigned char>(input >> 8);
1136     unsigned char ch2 = sal::static_int_cast<unsigned char>(input & 0xff);
1137     int idx = (ch - 0xA1) * 94 + (ch2 - 0xA1);
1138     if (idx >= 0 && idx < static_cast<int>(SAL_N_ELEMENTS(ksc5601_2uni_page21))) {
1139         hchar value = ksc5601_2uni_page21[idx];
1140         return value ? value :  0x25a1;
1141     }
1142     return 0x25a1;
1143 }
1144 
ksc5601_han_to_ucs2(hchar input)1145 hchar ksc5601_han_to_ucs2 (hchar input)
1146 {
1147     unsigned char ch = sal::static_int_cast<unsigned char>(input >> 8);
1148     unsigned char ch2 = sal::static_int_cast<unsigned char>(input & 0xff);
1149     int idx = (ch - 0xA1) * 94 + (ch2 - 0xA1);
1150     if (idx >= 3854 && idx < static_cast<int>(3854 + SAL_N_ELEMENTS(ksc5601_2uni_page21))) {
1151         // Hanja : row 42 - row 93 : 3854 = 94 * (42-1)
1152         hchar value = ksc5601_2uni_page21[idx - 3854];
1153         return value ? value : '?';
1154     }
1155     return '?';
1156 }
1157 
hstr2ucsstr(hchar const * hstr)1158 hchar_string hstr2ucsstr(hchar const* hstr)
1159 {
1160     hchar_string ret;
1161     hchar dest[3];
1162     for( ; *hstr ; ){
1163         int const res = hcharconv(*hstr++, dest, UNICODE);
1164         for (int j = 0 ; j < res ; j++) {
1165             ret.push_back(dest[j]);
1166         }
1167     }
1168     return ret;
1169 }
1170 
1171 /**
1172  * Convert 'Hangul and Computer' strings to the completion code(KSC5601-87)
1173  */
hstr2ksstr(hchar const * hstr)1174 ::std::string hstr2ksstr(hchar const* hstr)
1175 {
1176     ::std::string ret;
1177     int j;
1178     hchar dest[3];
1179     for( ; *hstr ; )
1180     {
1181         int res = hcharconv(*hstr++, dest, KS);
1182         for( j = 0 ; j < res ; j++ ){
1183               int c = dest[j];
1184               if( c < 32 )
1185                   c = ' ';
1186               if( c < 256 )
1187               {
1188                   ret.push_back(sal::static_int_cast<char>(c));
1189               }
1190               else
1191               {
1192                   ret.push_back(sal::static_int_cast<char>((c >> 8 ) & 0xff));
1193                   ret.push_back(sal::static_int_cast<char>(c & 0xff));
1194               }
1195         }
1196     }
1197     return ret;
1198 }
1199 
1200 
1201 /*
1202  * Convert strings of kchar type, which can contain Korean, English and others
1203  * to strings of hchar type of Hangul Word Processor
1204  */
kstr2hstr(uchar const * src)1205 hchar_string kstr2hstr(uchar const* src)
1206 {
1207     hchar_string ret;
1208     if (!src)
1209         return ret;
1210     for (unsigned int i = 0; src[i] != '\0' ; i++)
1211     {
1212         if ( src[i] < 127 )
1213         {
1214             ret.push_back(src[i]);
1215         }
1216         else
1217         {
1218             ret.push_back(src[i] << 8 | src[i+1]);
1219             i++;
1220         }
1221     }
1222     return ret;
1223 }
1224 
1225 
1226 /**
1227  * Transfer integer to string following format
1228  */
Int2Str(int value,const char * format,char * buf)1229 char* Int2Str(int value, const char *format, char *buf)
1230 {
1231     sprintf(buf,format,value);
1232     return buf;
1233 }
1234 
1235 
1236 /* Convert a combination of a color index value and a shade value to the color value of LibreOffice */
hcolor2str(uchar color,uchar shade,char * buf,bool bIsChar)1237 char *hcolor2str(uchar color, uchar shade, char *buf, bool bIsChar)
1238 {
1239     unsigned short red,green,blue;
1240 
1241     switch( static_cast<int>(color) )
1242     {
1243         case 0 :                                  // black
1244             red =  0xff * (100 - shade ) /100;
1245             green =  0xff * (100 - shade ) /100;
1246             blue =  0xff * (100 - shade ) /100;
1247             break;
1248         case 1:                                   // blue
1249             red =  0xff * (100 - shade ) /100;
1250             green =  0xff * (100 - shade ) /100;
1251             blue = 0xff;
1252             break;
1253         case 2:                                   // green
1254             red =  0xff * (100 - shade ) /100;
1255                 if( bIsChar )
1256                      green = 0x80;
1257                 else
1258                      green = 0xff;
1259             blue =  0xff * (100 - shade ) /100;
1260             break;
1261         case 3:                                   // cyan
1262             red =  0xff * (100 - shade ) /100;
1263             green = 0xff;
1264             blue = 0xff;
1265             break;
1266         case 4:                                   // red
1267             red = 0xff;
1268             green =  0xff * (100 - shade ) /100;
1269             blue =  0xff * (100 - shade ) /100;
1270             break;
1271         case 5:                                   // magenta
1272             red = 0xff;
1273             green =  0xff * (100 - shade ) /100;
1274             blue = 0xff;
1275             break;
1276         case 6:                                   //yellow
1277             red = 0xff;
1278             green = 0xff;
1279             blue =  0xff * (100 - shade ) /100;
1280             break;
1281         case 7:                                   //white
1282         default:
1283             red = 0xff;
1284             green = 0xff;
1285             blue = 0xff;
1286             break;
1287     }
1288 
1289     sprintf(buf,"#%02x%02x%02x", red, green, blue);
1290     return buf;
1291 }
1292 
1293 
urltounix(const char * src)1294 ::std::string urltounix(const char *src)
1295 {
1296     ::std::string ret;
1297     std::size_t i = 0;
1298     if( src[0] == 'C' && src[1] == ':' && src[2] == '\\' ) // Home Dir
1299     {
1300         ret.append("file://");
1301         const char *pHome = getenv("HOME");
1302         if (pHome)
1303         {
1304             ret.append(pHome);
1305             ret.push_back('/');
1306         }
1307         i = 3; // skip first 3
1308     }
1309     else if( src[0] == 'D' && src[1] == ':' && src[2] == '\\' ) // Root Dir
1310     {
1311         ret.append("file:///");
1312         i = 3; // skip first 3
1313     }
1314     else if( !strncmp(src,"http",4)  ) // Start from "http"
1315     {
1316         // nothing special here, just copy
1317     }
1318     else
1319     {
1320         unsigned int srclen = strlen(src);
1321         if (3 < srclen)
1322         {
1323             char const*const ext = src + (srclen-3);
1324 #ifdef _WIN32
1325             if (_strnicmp(ext,"HWP",3) && _strnicmp(ext,"HWT",3))
1326 #else
1327             if (strcasecmp(ext,"HWP") && strcasecmp(ext,"HWT"))
1328 #endif
1329             {
1330                 ret.append("http://");
1331             }
1332         }
1333     }
1334     for (; i < strlen(src); i++)
1335     {
1336         if (src[i] == '\\') {
1337             ret.push_back('/');
1338         } else {
1339             ret.push_back(src[i]);
1340         }
1341     }
1342     return ret;
1343 }
1344 
1345 #ifdef _WIN32
urltowin(const char * src)1346 ::std::string urltowin(const char *src)
1347 {
1348     std::string ret;
1349     if( !_strnicmp(src, "http", 4))
1350      {
1351         // nothing special here, just copy
1352     }
1353      else
1354     {
1355         unsigned int srclen = strlen(src);
1356         if (3 < srclen)
1357         {
1358             char const*const ext = src + (srclen-3);
1359             if (_strnicmp(ext,"HWP",3) && _strnicmp(ext,"HWT",3))
1360             {
1361                 ret.append("http://");
1362             }
1363             else
1364             {
1365                 ret.append(src); // no backslash conversion
1366                 return ret;
1367             }
1368         }
1369     }
1370     for (size_t i = 0; i < strlen(src); i++)
1371     {
1372         if (src[i] == '\\') {
1373             ret.push_back('/');
1374         } else {
1375             ret.push_back(src[i]);
1376         }
1377     }
1378     return ret;
1379 }
1380 #endif
1381 
base64_encode_string(const uchar * buf,unsigned int len)1382 char* base64_encode_string( const uchar *buf, unsigned int len )
1383 {
1384     char basis_64[] =
1385         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1386     char * out;
1387     int inPos  = 0;
1388     int outPos = 0;
1389     int c1, c2;
1390     unsigned int i;
1391 
1392     out=static_cast<char *>(malloc( (len*4/3)+8 ));
1393 
1394 /* Get three characters at a time and encode them. */
1395     for (i=0; i < len/3; ++i)
1396     {
1397         c1 = buf[inPos++] & 0xFF;
1398         c2 = buf[inPos++] & 0xFF;
1399         int c3 = buf[inPos++] & 0xFF;
1400         out[outPos++] = basis_64[(c1 & 0xFC) >> 2];
1401         out[outPos++] = basis_64[((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4)];
1402         out[outPos++] = basis_64[((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)];
1403         out[outPos++] = basis_64[c3 & 0x3F];
1404     }
1405 
1406 /* Encode the remaining one or two characters. */
1407 
1408     switch (len % 3)
1409     {
1410         case 0:
1411             break;
1412         case 1:
1413             c1 = buf[inPos] & 0xFF;
1414             out[outPos++] = basis_64[(c1 & 0xFC) >> 2];
1415             out[outPos++] = basis_64[((c1 & 0x03) << 4)];
1416             out[outPos++] = '=';
1417             out[outPos++] = '=';
1418             break;
1419         case 2:
1420             c1 = buf[inPos++] & 0xFF;
1421             c2 = buf[inPos] & 0xFF;
1422             out[outPos++] = basis_64[(c1 & 0xFC) >> 2];
1423             out[outPos++] = basis_64[((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4)];
1424             out[outPos++] = basis_64[((c2 & 0x0F) << 2)];
1425             out[outPos++] = '=';
1426             break;
1427     }
1428     out[outPos] = 0;
1429     return out;
1430 }
1431 
calcAngle(int x1,int y1,int x2,int y2)1432 double calcAngle(int x1, int y1, int x2, int y2)
1433 {
1434      y1 = -y1;
1435      y2 = -y2;
1436      if( x2 == x1 ){
1437           if( y2 >= y1 )
1438                 return 0.;
1439           else
1440                 return 270.;
1441      }
1442      double angle;
1443      angle = (180 / PI) * atan( ( y2 - y1 ) * 1.0 / ( x2 - x1 ));
1444      if( y2 >= y1 ){ /* 1, 2 quadrant */
1445           if( angle < 0. )
1446                 angle += 180.;
1447      }
1448      else{ /* 3, 4 quadrants */
1449           if( angle > 0 )
1450                 angle += 180.;
1451           else
1452                 angle += 360.;
1453      }
1454      return angle;
1455 }
1456 
1457 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1458