+void gr_stylespec_unset(GrStyleSpec *spec, GrAttr a)
+{
+ static const uint sz=sizeof(GrAttrScore);
+ GrAttrScore *idsn;
+ int idx_ge;
+
+ if(a==GRATTR_NONE)
+ return;
+
+ if(!gr_stylespec_find_(spec, a, &idx_ge))
+ return;
+
+ stringstore_free(spec->attrs[idx_ge].attr);
+
+ memmove(spec->attrs+idx_ge, spec->attrs+idx_ge+1,
+ (spec->n-idx_ge-1)*sz);
+
+ spec->n--;
+
+ idsn=(GrAttrScore*)realloc(spec->attrs, (spec->n)*sz);
+
+ if(idsn!=NULL || spec->n==0)
+ spec->attrs=idsn;
+}
+
+
+static bool gr_stylespec_do_init_from(GrStyleSpec *dst, const GrStyleSpec *src)
+{
+ uint i;
+
+ if(src->n==0)
+ return TRUE;
+
+ dst->attrs=ALLOC_N(GrAttrScore, src->n);
+
+ if(dst->attrs==NULL)
+ return FALSE;
+
+ for(i=0; i<src->n; i++){
+ dst->attrs[i]=src->attrs[i];
+ stringstore_ref(dst->attrs[i].attr);
+ }
+
+ dst->n=src->n;
+
+ return TRUE;
+}
+
+
+bool gr_stylespec_append(GrStyleSpec *dst, const GrStyleSpec *src)
+{
+ uint i;
+ bool ok=TRUE;
+
+ if(dst->attrs==NULL){
+ ok=gr_stylespec_do_init_from(dst, src);
+ }else{
+ for(i=0; i<src->n; i++){
+ if(!gr_stylespec_add(dst, src->attrs[i].attr, src->attrs[i].score))
+ ok=FALSE;
+ }
+ }
+
+ return ok;
+}
+
+
+bool gr_stylespec_equals(const GrStyleSpec *s1, const GrStyleSpec *s2)
+{
+ uint i;
+
+ if(s1->n!=s2->n)
+ return FALSE;
+
+ for(i=0; i<s1->n; i++){
+ if(s1->attrs[i].attr!=s2->attrs[i].attr)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+