Code

Fixed signed/unsigned problem with precision calc. Fixes bug #399604.
[inkscape.git] / src / unicoderange.cpp
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;
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) ' ';