summaryrefslogtreecommitdiffstats
path: root/src/unicoderange.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/unicoderange.cpp136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/unicoderange.cpp b/src/unicoderange.cpp
new file mode 100644
index 0000000..237fac7
--- /dev/null
+++ b/src/unicoderange.cpp
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/** @file
+ * TODO: insert short description here
+ *//*
+ * Authors: see git history
+ *
+ * Copyright (C) 2018 Authors
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+#include "unicoderange.h"
+
+#include <cstdlib>
+#include <cstring>
+
+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 = g_utf8_next_char(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=nullptr;
+ }
+ this->range.push_back(r);
+ return count+1;
+}
+
+bool UnicodeRange::contains(gchar unicode){
+ for(unsigned int unichar : this->unichars){
+ if (static_cast<gunichar>(unicode) == unichar){
+ return true;
+ }
+ }
+
+ unsigned int unival;
+ unival = g_utf8_get_char (&unicode);
+ char uni[9] = "00000000";
+ uni[8]= '\0';
+ for (unsigned int i=7; unival>0; i--){
+ unsigned char val = unival & 0xf;
+ unival = unival >> 4;
+ if (val < 10) uni[i] = '0' + val;
+ else uni[i] = 'A'+ val - 10;
+ }
+
+ bool found;
+ for(auto r : this->range){
+ 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++){
+// g_warning("uni: %d %x", i, unichars[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.empty())
+ return unichars[0];
+ if (!range.empty())
+ return hex2int(range[0].start);
+ return (gunichar) ' ';
+}
+