sp-string.cpp revision 60282e8335d7b6ae7020613bb22c7c69a6909fbb
1516N/A/*
49N/A * SVG <text> and <tspan> implementation
49N/A *
49N/A * Author:
49N/A * Lauris Kaplinski <lauris@kaplinski.com>
49N/A * Jon A. Cruz <jon@joncruz.org>
49N/A * Abhishek Sharma
49N/A *
49N/A * Copyright (C) 1999-2002 Lauris Kaplinski
49N/A * Copyright (C) 2000-2001 Ximian, Inc.
49N/A *
49N/A * Released under GNU GPL, read the file 'COPYING' for more information
49N/A */
49N/A
49N/A/*
49N/A * fixme:
49N/A *
49N/A * These subcomponents should not be items, or alternately
49N/A * we have to invent set of flags to mark, whether standard
49N/A * attributes are applicable to given item (I even like this
49N/A * idea somewhat - Lauris)
49N/A *
2205N/A */
2204N/A
2205N/A
49N/A
49N/A#ifdef HAVE_CONFIG_H
49N/A# include "config.h"
49N/A#endif
49N/A
49N/A
1859N/A#include "sp-string.h"
1859N/A#include "xml/repr.h"
51N/A
289N/A
941N/A/*#####################################################
1859N/A# SPSTRING
1859N/A#####################################################*/
49N/A
49N/Astatic void sp_string_class_init(SPStringClass *classname);
49N/Astatic void sp_string_init(SPString *string);
49N/A
1846N/Astatic void sp_string_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
1846N/Astatic void sp_string_release(SPObject *object);
51N/Astatic void sp_string_read_content(SPObject *object);
72N/Astatic void sp_string_update(SPObject *object, SPCtx *ctx, unsigned flags);
2205N/A
2205N/Astatic SPObjectClass *string_parent_class;
2205N/A
2205N/AGType
51N/Asp_string_get_type()
307N/A{
307N/A static GType type = 0;
307N/A if (!type) {
2205N/A GTypeInfo info = {
2205N/A sizeof(SPStringClass),
2205N/A NULL, /* base_init */
2205N/A NULL, /* base_finalize */
2205N/A (GClassInitFunc) sp_string_class_init,
2205N/A NULL, /* class_finalize */
2205N/A NULL, /* class_data */
2205N/A sizeof(SPString),
2205N/A 16, /* n_preallocs */
2205N/A (GInstanceInitFunc) sp_string_init,
2205N/A NULL, /* value_table */
2205N/A };
2205N/A type = g_type_register_static(SP_TYPE_OBJECT, "SPString", &info, (GTypeFlags)0);
2205N/A }
2205N/A return type;
307N/A}
307N/A
281N/Astatic void
136N/Asp_string_class_init(SPStringClass *classname)
49N/A{
1755N/A SPObjectClass *sp_object_class;
1755N/A
1755N/A sp_object_class = (SPObjectClass *) classname;
1755N/A
1755N/A string_parent_class = (SPObjectClass*)g_type_class_ref(SP_TYPE_OBJECT);
1755N/A
1755N/A sp_object_class->build = sp_string_build;
1755N/A sp_object_class->release = sp_string_release;
1755N/A sp_object_class->read_content = sp_string_read_content;
1859N/A sp_object_class->update = sp_string_update;
1784N/A}
1784N/A
72N/Astatic void
1784N/Asp_string_init(SPString *string)
1784N/A{
1784N/A new (&string->string) Glib::ustring();
1784N/A}
1784N/A
1784N/Astatic void
1784N/Asp_string_build(SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr)
1784N/A{
72N/A sp_string_read_content(object);
1859N/A
1859N/A if (((SPObjectClass *) string_parent_class)->build)
1859N/A ((SPObjectClass *) string_parent_class)->build(object, doc, repr);
1859N/A}
1859N/A
51N/Astatic void
95N/Asp_string_release(SPObject *object)
289N/A{
1507N/A SPString *string = SP_STRING(object);
95N/A
72N/A string->string.~ustring();
72N/A
1859N/A if (((SPObjectClass *) string_parent_class)->release)
1859N/A ((SPObjectClass *) string_parent_class)->release(object);
72N/A}
1859N/A
1859N/Astatic void
1859N/Asp_string_read_content(SPObject *object)
1859N/A{
1859N/A SPString *string = SP_STRING(object);
1859N/A
1859N/A string->string.clear();
1796N/A
1796N/A //XML Tree being used directly here while it shouldn't be.
1796N/A gchar const *xml_string = string->getRepr()->content();
1796N/A // see algorithms described in svg 1.1 section 10.15
1859N/A if (object->xml_space.value == SP_XML_SPACE_PRESERVE) {
1796N/A for ( ; *xml_string ; xml_string = g_utf8_next_char(xml_string) ) {
1796N/A gunichar c = g_utf8_get_char(xml_string);
1859N/A if ((c == 0xa) || (c == 0xd) || (c == '\t')) {
72N/A c = ' ';
95N/A }
1859N/A string->string += c;
1859N/A }
1859N/A }
1859N/A else {
1859N/A bool whitespace = false;
1859N/A for ( ; *xml_string ; xml_string = g_utf8_next_char(xml_string) ) {
1859N/A gunichar c = g_utf8_get_char(xml_string);
1859N/A if ((c == 0xa) || (c == 0xd)) {
1859N/A continue;
1859N/A }
1859N/A if ((c == ' ') || (c == '\t')) {
1859N/A whitespace = true;
1859N/A } else {
1859N/A if (whitespace && (!string->string.empty() || (object->getPrev() != NULL))) {
1859N/A string->string += ' ';
1859N/A }
1859N/A string->string += c;
1859N/A whitespace = false;
1859N/A }
1859N/A }
1859N/A if (whitespace && object->getRepr()->next() != NULL) { // can't use SPObject::getNext() when the SPObject tree is still being built
1859N/A string->string += ' ';
2293N/A }
1859N/A }
1859N/A object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1859N/A}
1859N/A
1859N/Astatic void
1859N/Asp_string_update(SPObject *object, SPCtx *ctx, unsigned flags)
2470N/A{
2470N/A if (((SPObjectClass *) string_parent_class)->update)
2470N/A ((SPObjectClass *) string_parent_class)->update(object, ctx, flags);
2470N/A
2470N/A if (flags & (SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_MODIFIED_FLAG)) {
2470N/A /* Parent style or we ourselves changed, so recalculate */
2470N/A flags &= ~SP_OBJECT_USER_MODIFIED_FLAG_B; // won't be "just a transformation" anymore, we're going to recompute "x" and "y" attributes
2470N/A }
2470N/A}
1859N/A
95N/A
95N/A/*
95N/A Local Variables:
95N/A mode:c++
95N/A c-file-style:"stroustrup"
95N/A c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
95N/A indent-tabs-mode:nil
95N/A fill-column:99
95N/A End:
95N/A*/
95N/A// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
72N/A