~ubuntu-branches/debian/squeeze/inkscape/squeeze

« back to all changes in this revision

Viewing changes to src/xml/repr-css.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-09-09 23:29:02 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080909232902-c50iujhk1w79u8e7
Tags: 0.46-2.1
* Non-maintainer upload.
* Add upstream patch fixing a crash in the open dialog
  in the zh_CN.utf8 locale. Closes: #487623.
  Thanks to Luca Bruno for the patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *   bulia byak <buliabyak@users.sf.net>
3
 
*/ 
4
 
 
 
3
*/
 
4
 
5
5
#define SP_REPR_CSS_C
6
6
 
7
 
 
 
7
#include <cstring>
8
8
#include <glibmm/ustring.h>
9
9
 
10
10
#include "xml/repr.h"
11
11
#include "xml/simple-node.h"
 
12
#include "style.h"
 
13
#include "libcroco/cr-sel-eng.h"
12
14
 
13
15
using Inkscape::Util::List;
14
16
using Inkscape::XML::AttributeRecord;
15
17
using Inkscape::XML::SimpleNode;
16
18
using Inkscape::XML::Node;
17
19
using Inkscape::XML::NodeType;
 
20
using Inkscape::XML::Document;
18
21
 
19
22
struct SPCSSAttrImpl : public SimpleNode, public SPCSSAttr {
20
23
public:
23
26
    NodeType type() const { return Inkscape::XML::ELEMENT_NODE; }
24
27
 
25
28
protected:
26
 
    SimpleNode *_duplicate() const { return new SPCSSAttrImpl(*this); }
 
29
    SimpleNode *_duplicate(Document* doc) const { return new SPCSSAttrImpl(*this); }
27
30
};
28
31
 
29
32
static void sp_repr_css_add_components(SPCSSAttr *css, Node *repr, gchar const *attr);
51
54
    return css;
52
55
}
53
56
 
 
57
static void
 
58
sp_repr_css_attr_inherited_recursive(SPCSSAttr *css, Node *repr, gchar const *attr)
 
59
{
 
60
    Node *parent = sp_repr_parent(repr);
 
61
 
 
62
    // read the ancestors from root down, using head recursion, so that children override parents
 
63
    if (parent) {
 
64
        sp_repr_css_attr_inherited_recursive(css, parent, attr);
 
65
    }
 
66
 
 
67
    sp_repr_css_add_components(css, repr, attr);
 
68
}
 
69
 
 
70
 
54
71
SPCSSAttr *sp_repr_css_attr_inherited(Node *repr, gchar const *attr)
55
72
{
56
73
    g_assert(repr != NULL);
58
75
 
59
76
    SPCSSAttr *css = sp_repr_css_attr_new();
60
77
 
61
 
    sp_repr_css_add_components(css, repr, attr);
62
 
    Node *current = sp_repr_parent(repr);
63
 
 
64
 
    while (current) {
65
 
        sp_repr_css_add_components(css, current, attr);
66
 
        current = sp_repr_parent(current);
67
 
    }
 
78
    sp_repr_css_attr_inherited_recursive(css, repr, attr);
68
79
 
69
80
    return css;
70
81
}
144
155
 
145
156
        buffer.append(g_quark_to_string(iter->key));
146
157
        buffer.push_back(':');
147
 
        buffer.append(iter->value);
 
158
        if (!strcmp(g_quark_to_string(iter->key), "font-family")
 
159
                || !strcmp(g_quark_to_string(iter->key), "-inkscape-font-specification")) { 
 
160
            // we only quote font-family/font-specification, as SPStyle does
 
161
            gchar *t = g_strdup (iter->value);
 
162
            g_free (t);
 
163
            gchar *val_quoted = css2_escape_quote (iter->value);
 
164
            if (val_quoted) {
 
165
                buffer.append(val_quoted);
 
166
                g_free (val_quoted);
 
167
            }
 
168
        } else {
 
169
            buffer.append(iter->value); // unquoted
 
170
        }
 
171
 
148
172
        if (rest(iter)) {
149
173
            buffer.push_back(';');
150
174
        }
173
197
    for ( List<AttributeRecord const> iter = css->attributeList() ;
174
198
          iter ; ++iter )
175
199
    {
176
 
        g_print(g_quark_to_string(iter->key));
177
 
        g_print(":\t");
178
 
        g_print(iter->value);
179
 
        g_print("\n");
 
200
        gchar const * key = g_quark_to_string(iter->key);
 
201
        gchar const * val = iter->value;
 
202
        g_print("%s:\t%s\n",key,val);
180
203
    }
181
204
}
182
205
 
189
212
    dst->mergeFrom(src, "");
190
213
}
191
214
 
 
215
 
 
216
static void
 
217
sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *const decl)
 
218
{
 
219
    guchar *const str_value_unsigned = cr_term_to_string(decl->value);
 
220
    gchar *const str_value = reinterpret_cast<gchar *>(str_value_unsigned);
 
221
    gchar *value_unquoted = attribute_unquote (str_value); // libcroco returns strings quoted in ""
 
222
    sp_repr_set_attr((Node *) css, decl->property->stryng->str, value_unquoted);
 
223
    g_free(value_unquoted);
 
224
    g_free(str_value);
 
225
}
 
226
 
 
227
/**
 
228
 * \pre decl_list != NULL
 
229
 */
 
230
static void
 
231
sp_repr_css_merge_from_decl_list(SPCSSAttr *css, CRDeclaration const *const decl_list)
 
232
{
 
233
    // read the decls from start to end, using tail recursion, so that latter declarations override
 
234
    // (Ref: http://www.w3.org/TR/REC-CSS2/cascade.html#cascading-order point 4.)
 
235
    // because sp_repr_css_merge_from_decl sets properties unconditionally
 
236
    sp_repr_css_merge_from_decl(css, decl_list);
 
237
    if (decl_list->next) {
 
238
        sp_repr_css_merge_from_decl_list(css, decl_list->next);
 
239
    }
 
240
}
 
241
 
192
242
void
193
 
sp_repr_css_attr_add_from_string(SPCSSAttr *css, gchar const *data)
 
243
sp_repr_css_attr_add_from_string(SPCSSAttr *css, gchar const *p)
194
244
{
195
 
    if (data != NULL) {
196
 
        char *new_str = g_strdup(data);
197
 
        char **token = g_strsplit(new_str, ";", 0);
198
 
        for (char **ctoken = token; *ctoken != NULL; ctoken++) {
199
 
            char *current = g_strstrip(*ctoken);
200
 
            char *key = current;
201
 
            char *val;
202
 
            for (val = key; *val != '\0'; val++)
203
 
                if (*val == ':') break;
204
 
            if (*val == '\0') break;
205
 
            *val++ = '\0';
206
 
            key = g_strstrip(key);
207
 
            val = g_strstrip(val);
208
 
            if (*val == '\0') break;
209
 
 
210
 
            /* fixme: CSS specifies that later declarations override earlier ones with the same
211
 
               key.  (Ref: http://www.w3.org/TR/REC-CSS2/cascade.html#cascading-order point 4.)
212
 
               Either add a precondition that there are no key duplicates in the string, or get rid
213
 
               of the below condition (documenting the change that data[] will override existing
214
 
               values in *css), or process the list in reverse order. */
215
 
            if (!css->attribute(key))
216
 
                sp_repr_set_attr((Node *) css, key, val);
 
245
    if (p != NULL) {
 
246
        CRDeclaration *const decl_list
 
247
            = cr_declaration_parse_list_from_buf(reinterpret_cast<guchar const *>(p), CR_UTF_8);
 
248
        if (decl_list) {
 
249
            sp_repr_css_merge_from_decl_list(css, decl_list);
 
250
            cr_declaration_destroy(decl_list);
217
251
        }
218
 
        g_strfreev(token);
219
 
        g_free(new_str);
220
252
    }
221
253
}
222
254