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