// 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 #include 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(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; iunichars.size(); i++){ // g_warning("uni: %d %x", i, unichars[i]); result += this->unichars[i]; if (i!=this->unichars.size()-1) result += ","; } for(i=0; irange.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) ' '; }