From 963d87c95becc6ec4f174719cbb31aec3a5e989a Mon Sep 17 00:00:00 2001 From: JucaBlues Date: Mon, 16 Jun 2008 01:24:19 +0000 Subject: [PATCH] UnicodeRange class implementation. This class represents a range of unicode codepoints as used in the u1 and u2 attributes of glyph kerning nodes. --- src/Makefile_insert | 1 + src/display/nr-svgfonts.cpp | 4 +- src/sp-glyph-kerning.cpp | 4 +- src/sp-glyph-kerning.h | 5 +- src/unicoderange.cpp | 96 +++++++++++++++++++++++++++++++++++++ src/unicoderange.h | 19 ++++++++ 6 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 src/unicoderange.cpp create mode 100644 src/unicoderange.h diff --git a/src/Makefile_insert b/src/Makefile_insert index f49498092..786322574 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -290,6 +290,7 @@ libinkpre_a_SOURCES = \ text-tag-attributes.h \ tools-switch.cpp tools-switch.h\ tweak-context.h tweak-context.cpp \ + unicoderange.cpp unicoderange.h \ uri-references.cpp uri-references.h \ vanishing-point.cpp vanishing-point.h \ verbs.cpp verbs.h \ diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp index 143b02188..e9d251820 100644 --- a/src/display/nr-svgfonts.cpp +++ b/src/display/nr-svgfonts.cpp @@ -166,11 +166,11 @@ SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, for(SPObject* node = this->font->children;previous_unicode && node;node=node->next){ //apply glyph kerning if appropriate if (SP_IS_HKERN(node) && is_horizontal_text){ - if ( (((SPHkern*)node)->u1[0] == previous_unicode[0]) && (((SPHkern*)node)->u2[0] == this->glyphs[i]->unicode[0]))//TODO: strings + if ( (((SPHkern*)node)->u1->contains(previous_unicode[0])) && (((SPHkern*)node)->u2->contains(this->glyphs[i]->unicode[0]) ))//TODO: verify what happens when using unicode strings. x -= (((SPHkern*)node)->k / this->font->horiz_adv_x); } if (SP_IS_VKERN(node) && !is_horizontal_text){ - if ( (((SPVkern*)node)->u1[0] == previous_unicode[0]) && (((SPVkern*)node)->u2[0] == this->glyphs[i]->unicode[0]))//TODO: strings + if ( (((SPVkern*)node)->u1->contains(previous_unicode[0])) && (((SPVkern*)node)->u2->contains(this->glyphs[i]->unicode[0]) ))//TODO: idem y -= (((SPVkern*)node)->k / this->font->vert_adv_y); } } diff --git a/src/sp-glyph-kerning.cpp b/src/sp-glyph-kerning.cpp index 173747af3..1c439be19 100644 --- a/src/sp-glyph-kerning.cpp +++ b/src/sp-glyph-kerning.cpp @@ -132,13 +132,13 @@ static void sp_glyph_kerning_set(SPObject *object, unsigned int key, const gchar switch (key) { case SP_ATTR_U1: if (glyphkern->u1) g_free(glyphkern->u1); - glyphkern->u1 = g_strdup(value);//todo: + glyphkern->u1 = new UnicodeRange(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); g_warning("<%s>: SP_ATTR_U1: %s", tag, value); break; case SP_ATTR_U2: if (glyphkern->u2) g_free(glyphkern->u2); - glyphkern->u2 = g_strdup(value);//todo: + glyphkern->u2 = new UnicodeRange(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); g_warning("<%s>: SP_ATTR_U2: %s", tag, value); break; diff --git a/src/sp-glyph-kerning.h b/src/sp-glyph-kerning.h index 806ec0986..9e8395d3b 100644 --- a/src/sp-glyph-kerning.h +++ b/src/sp-glyph-kerning.h @@ -15,6 +15,7 @@ */ #include "sp-object.h" +#include "unicoderange.h" #define SP_TYPE_HKERN (sp_glyph_kerning_h_get_type ()) #define SP_HKERN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_HKERN, SPHkern)) @@ -29,9 +30,9 @@ #define SP_IS_VKERN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_VKERN)) struct SPGlyphKerning : public SPObject { - char* u1; + UnicodeRange* u1; char* g1; - char* u2; + UnicodeRange* u2; char* g2; double k; }; diff --git a/src/unicoderange.cpp b/src/unicoderange.cpp new file mode 100644 index 000000000..c40891009 --- /dev/null +++ b/src/unicoderange.cpp @@ -0,0 +1,96 @@ +#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] > '9') res += mul * (s[i]-'A'+10); + else res += mul * (s[i]-'0'); + i--; + mul*=16; + } + return res; +} + +UnicodeRange::UnicodeRange(const gchar* value){ + gchar* val = (gchar*) value; + while(val[0] != '\0'){ + if (val[0]=='U' && val[1]=='+'){ + val += add_range(val); + } else { +// g_warning("adding unichar. unichar=%c", g_utf8_get_char(&val[0])); + 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; + //U+ + val+=2; + int i=0, count=2; + 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; + } +// g_warning("adding range. from %s to %s", r.start, r.end); + this->range.push_back(r); + return count+1; +} + +bool UnicodeRange::contains(gchar unicode){ + for(unsigned int i=0;iunichars.size();i++){ + if ((gunichar) unicode == this->unichars[i]) return true; + } + + unsigned int unival; + unival = g_utf8_get_char (&unicode); + g_warning("unival=%d", unival); + 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; + } +// g_warning("uni=%s", uni); + + bool found; + for(unsigned int i=0;irange.size();i++){ + Urange r = this->range[i]; + if (r.end){ +// g_warning("hex2int: start=%d", hex2int(r.start)); +// g_warning("hex2int: end=%d", hex2int(r.end)); + if (unival >= hex2int(r.start) && unival <= hex2int(r.end)) return true; + } else { + found = true; + for (int pos=0;pos<8;pos++){ + if (uni[pos]!='?' && uni[pos]!=r.start[pos]) found = false; + } + if (found) return true; + } + } + return false; +} diff --git a/src/unicoderange.h b/src/unicoderange.h new file mode 100644 index 000000000..656f53c50 --- /dev/null +++ b/src/unicoderange.h @@ -0,0 +1,19 @@ +#include +#include + +struct Urange{ + gchar* start; + gchar* end; +}; + +class UnicodeRange{ +public: +UnicodeRange(const gchar* val); +int add_range(gchar* val); +bool contains(gchar unicode); + +private: +std::vector range; +std::vector unichars; +}; + -- 2.30.2