1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#include "unicoderange.h"
#include <stdlib.h>
#include <string.h>
static unsigned int hex2int(char* s){
int res=0;
int i=0, mul=1;
while(s[i+1]!='\0') i++;
while(i>=0){
if (s[i] >= 'A' && s[i] <= 'F') res += mul * (s[i]-'A'+10);
if (s[i] >= 'a' && s[i] <= 'f') res += mul * (s[i]-'a'+10);
if (s[i] >= '0' && s[i] <= '9') res += mul * (s[i]-'0');
i--;
mul*=16;
}
return res;
}
UnicodeRange::UnicodeRange(const gchar* value){
if (!value) return;
gchar* val = (gchar*) value;
while(val[0] != '\0'){
if (val[0]=='U' && val[1]=='+'){
val += add_range(val+2);
} else {
this->unichars.push_back(g_utf8_get_char(&val[0]));
val++;
}
//skip spaces or commas
while(val[0]==' ' || val[0]==',') val++;
}
}
int
UnicodeRange::add_range(gchar* val){
Urange r;
int i=0, count=0;
while(val[i]!='\0' && val[i]!='-' && val[i]!=' ' && val[i]!=',') i++;
r.start = (gchar*) malloc((i+1)*sizeof(gchar*));
strncpy(r.start, val, i);
r.start[i] = '\0';
val+=i;
count+=i;
i=0;
if (val[0]=='-'){
val++;
while(val[i]!='\0' && val[i]!='-' && val[i]!=' ' && val[i]!=',') i++;
r.end = (gchar*) malloc((i+1)*sizeof(gchar*));
strncpy(r.end, val, i);
r.end[i] = '\0';
val+=i;
count+=i;
} else {
r.end=NULL;
}
this->range.push_back(r);
return count+1;
}
bool UnicodeRange::contains(gchar unicode){
for(unsigned int i=0;i<this->unichars.size();i++){
if ((gunichar) unicode == this->unichars[i]) return true;
}
unsigned int unival;
unival = g_utf8_get_char (&unicode);
char uni[9] = "00000000";
uni[8]= '\0';
unsigned char val;
for (unsigned int i=7; unival>0; i--){
val = unival & 0xf;
unival = unival >> 4;
if (val < 10) uni[i] = '0' + val;
else uni[i] = 'A'+ val - 10;
}
bool found;
for(unsigned int i=0;i<this->range.size();i++){
Urange r = this->range[i];
if (r.end){
if (unival >= hex2int(r.start) && unival <= hex2int(r.end)) return true;
} else {
found = true;
int p=0;
while (r.start[p]!='\0') p++;
p--;
for (int pos=8;p>=0;pos--,p--){
if (uni[pos]!='?' && uni[pos]!=r.start[p]) found = false;
}
if (found) return true;
}
}
return false;
}
Glib::ustring UnicodeRange::attribute_string(){
Glib::ustring result;
unsigned int i;
for(i=0; i<this->unichars.size(); i++){
result += this->unichars[i];
if (i!=this->unichars.size()-1) result += ",";
}
for(i=0; i<this->range.size(); i++){
result += "U+" + Glib::ustring(this->range[i].start);
if (this->range[i].end) result += "-" + Glib::ustring(this->range[i].end);
if (i!=this->range.size()-1) result += ", ";
}
return result;
}
gunichar UnicodeRange::sample_glyph(){
//This could be better
if (unichars.size())
return unichars[0];
if (range.size())
return hex2int(range[0].start);
return (gunichar) ' ';
}
|