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

« back to all changes in this revision

Viewing changes to src/sp-flowtext.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:
5
5
# include "config.h"
6
6
#endif
7
7
#include <glibmm/i18n.h>
 
8
#include <cstring>
 
9
#include <string>
8
10
 
9
11
#include "attributes.h"
10
12
#include "xml/repr.h"
25
27
#include "sp-use.h"
26
28
#include "sp-rect.h"
27
29
#include "text-tag-attributes.h"
 
30
#include "text-chemistry.h"
28
31
 
29
32
 
30
33
#include "livarot/Shape.h"
172
175
 
173
176
    group->rebuildLayout();
174
177
 
175
 
    // pass the bbox of the flowtext object as paintbox (used for paintserver fills)
176
178
    NRRect paintbox;
177
179
    sp_item_invoke_bbox(group, &paintbox, NR::identity(), TRUE);
178
180
    for (SPItemView *v = group->display; v != NULL; v = v->next) {
179
181
        group->_clearFlow(NR_ARENA_GROUP(v->arenaitem));
 
182
        nr_arena_group_set_style(NR_ARENA_GROUP(v->arenaitem), SP_OBJECT_STYLE(object));
 
183
        // pass the bbox of the flowtext object as paintbox (used for paintserver fills)
180
184
        group->layout.show(NR_ARENA_GROUP(v->arenaitem), &paintbox);
181
185
    }
182
186
}
190
194
    if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
191
195
    flags &= SP_OBJECT_MODIFIED_CASCADE;
192
196
 
 
197
    // FIXME: the below stanza is copied over from sp_text_modified, consider factoring it out
 
198
    if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG )) {
 
199
        SPFlowtext *text = SP_FLOWTEXT(object);
 
200
        NRRect paintbox;
 
201
        sp_item_invoke_bbox(text, &paintbox, NR::identity(), TRUE);
 
202
        for (SPItemView* v = text->display; v != NULL; v = v->next) {
 
203
            text->_clearFlow(NR_ARENA_GROUP(v->arenaitem));
 
204
            nr_arena_group_set_style(NR_ARENA_GROUP(v->arenaitem), SP_OBJECT_STYLE(object));
 
205
            text->layout.show(NR_ARENA_GROUP(v->arenaitem), &paintbox);
 
206
        }
 
207
    }
 
208
 
193
209
    for (SPObject *o = sp_object_first_child(SP_OBJECT(ft)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) {
194
210
        if (SP_IS_FLOWREGION(o)) {
195
211
            region = o;
278
294
sp_flowtext_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
279
295
{
280
296
    if ( flags & SP_OBJECT_WRITE_BUILD ) {
281
 
        if ( repr == NULL ) repr = sp_repr_new("svg:flowRoot");
 
297
        Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(object));
 
298
        if ( repr == NULL ) repr = xml_doc->createElement("svg:flowRoot");
282
299
        GSList *l = NULL;
283
300
        for (SPObject *child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) {
284
301
            Inkscape::XML::Node *c_repr = NULL;
314
331
 
315
332
    // Add stroke width
316
333
    SPStyle* style=SP_OBJECT_STYLE (item);
317
 
    if (style->stroke.type != SP_PAINT_TYPE_NONE) {
 
334
    if ( !style->stroke.isNone() ) {
318
335
        double const scale = expansion(transform);
319
336
        if ( fabs(style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord
320
337
            double const width = MAX(0.125, style->stroke_width.computed * scale);
336
353
    NRRect pbox;
337
354
    sp_item_invoke_bbox(item, &pbox, NR::identity(), TRUE);
338
355
    NRRect bbox;
339
 
    sp_item_bbox_desktop(item, &bbox);
 
356
    NR::Maybe<NR::Rect> bbox_maybe = sp_item_bbox_desktop(item);
 
357
    if (!bbox_maybe) {
 
358
        return;
 
359
    }
 
360
    bbox = NRRect(*bbox_maybe);
 
361
 
340
362
    NRRect dbox;
341
363
    dbox.x0 = 0.0;
342
364
    dbox.y0 = 0.0;
365
387
    NRArenaGroup *flowed = NRArenaGroup::create(arena);
366
388
    nr_arena_group_set_transparent(flowed, FALSE);
367
389
 
 
390
    nr_arena_group_set_style(flowed, group->style);
 
391
 
368
392
    // pass the bbox of the flowtext object as paintbox (used for paintserver fills)
369
393
    NRRect paintbox;
370
394
    sp_item_invoke_bbox(item, &paintbox, NR::identity(), TRUE);
499
523
    }
500
524
}
501
525
 
502
 
void SPFlowtext::convert_to_text()
 
526
Inkscape::XML::Node *
 
527
SPFlowtext::getAsText()
503
528
{
504
 
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
505
 
    Inkscape::Selection *selection = sp_desktop_selection(desktop);
506
 
    SPItem *item = selection->singleItem();
507
 
    if (!SP_IS_FLOWTEXT(item)) return;
508
 
 
509
 
    SPFlowtext *group = SP_FLOWTEXT(item);
510
 
 
511
 
    if (!group->layout.outputExists()) return;
512
 
 
513
 
    Inkscape::XML::Node *repr = sp_repr_new("svg:text");
 
529
    if (!this->layout.outputExists()) return NULL;
 
530
 
 
531
    SPItem *item = SP_ITEM(this);
 
532
 
 
533
    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(this));
 
534
    Inkscape::XML::Node *repr = xml_doc->createElement("svg:text");
514
535
    repr->setAttribute("xml:space", "preserve");
515
 
    repr->setAttribute("style", SP_OBJECT_REPR(group)->attribute("style"));
516
 
    NR::Point anchor_point = group->layout.characterAnchorPoint(group->layout.begin());
 
536
    repr->setAttribute("style", SP_OBJECT_REPR(this)->attribute("style"));
 
537
    NR::Point anchor_point = this->layout.characterAnchorPoint(this->layout.begin());
517
538
    sp_repr_set_svg_double(repr, "x", anchor_point[NR::X]);
518
539
    sp_repr_set_svg_double(repr, "y", anchor_point[NR::Y]);
519
540
 
520
 
    for (Inkscape::Text::Layout::iterator it = group->layout.begin() ; it != group->layout.end() ; ) {
521
 
 
522
 
            Inkscape::XML::Node *line_tspan = sp_repr_new("svg:tspan");
 
541
    for (Inkscape::Text::Layout::iterator it = this->layout.begin() ; it != this->layout.end() ; ) {
 
542
        Inkscape::XML::Node *line_tspan = xml_doc->createElement("svg:tspan");
523
543
        line_tspan->setAttribute("sodipodi:role", "line");
524
544
 
525
545
        Inkscape::Text::Layout::iterator it_line_end = it;
526
546
        it_line_end.nextStartOfLine();
 
547
 
527
548
        while (it != it_line_end) {
528
549
 
529
 
                Inkscape::XML::Node *span_tspan = sp_repr_new("svg:tspan");
530
 
            NR::Point anchor_point = group->layout.characterAnchorPoint(it);
 
550
            Inkscape::XML::Node *span_tspan = xml_doc->createElement("svg:tspan");
 
551
            NR::Point anchor_point = this->layout.characterAnchorPoint(it);
531
552
            // use kerning to simulate justification and whatnot
532
553
            Inkscape::Text::Layout::iterator it_span_end = it;
533
554
            it_span_end.nextStartOfSpan();
534
555
            Inkscape::Text::Layout::OptionalTextTagAttrs attrs;
535
 
            group->layout.simulateLayoutUsingKerning(it, it_span_end, &attrs);
 
556
            this->layout.simulateLayoutUsingKerning(it, it_span_end, &attrs);
536
557
            // set x,y attributes only when we need to
537
558
            bool set_x = false;
538
559
            bool set_y = false;
561
582
            SPObject *source_obj = 0;
562
583
            void *rawptr = 0;
563
584
            Glib::ustring::iterator span_text_start_iter;
564
 
            group->layout.getSourceOfCharacter(it, &rawptr, &span_text_start_iter);
 
585
            this->layout.getSourceOfCharacter(it, &rawptr, &span_text_start_iter);
565
586
            source_obj = SP_OBJECT (rawptr);
566
 
            gchar *style_text = sp_style_write_difference((SP_IS_STRING(source_obj) ? source_obj->parent : source_obj)->style, group->style);
 
587
            gchar *style_text = sp_style_write_difference((SP_IS_STRING(source_obj) ? source_obj->parent : source_obj)->style, this->style);
567
588
            if (style_text && *style_text) {
568
589
                span_tspan->setAttribute("style", style_text);
569
590
                g_free(style_text);
574
595
                SPObject *span_end_obj = 0;
575
596
                void *rawptr = 0;
576
597
                Glib::ustring::iterator span_text_end_iter;
577
 
                group->layout.getSourceOfCharacter(it_span_end, &rawptr, &span_text_end_iter);
 
598
                this->layout.getSourceOfCharacter(it_span_end, &rawptr, &span_text_end_iter);
578
599
                span_end_obj = SP_OBJECT(rawptr);
579
600
                if (span_end_obj != source_obj) {
580
 
                    if (it_span_end == group->layout.end()) {
 
601
                    if (it_span_end == this->layout.end()) {
581
602
                        span_text_end_iter = span_text_start_iter;
582
 
                        for (int i = group->layout.iteratorToCharIndex(it_span_end) - group->layout.iteratorToCharIndex(it) ; i ; --i)
 
603
                        for (int i = this->layout.iteratorToCharIndex(it_span_end) - this->layout.iteratorToCharIndex(it) ; i ; --i)
583
604
                            ++span_text_end_iter;
584
605
                    } else
585
606
                        span_text_end_iter = string->end();    // spans will never straddle a source boundary
589
610
                    Glib::ustring new_string;
590
611
                    while (span_text_start_iter != span_text_end_iter)
591
612
                        new_string += *span_text_start_iter++;    // grr. no substr() with iterators
592
 
                    Inkscape::XML::Node *new_text = sp_repr_new_text(new_string.c_str());
 
613
                    Inkscape::XML::Node *new_text = xml_doc->createTextNode(new_string.c_str());
593
614
                    span_tspan->appendChild(new_text);
594
615
                    Inkscape::GC::release(new_text);
595
616
                }
597
618
            it = it_span_end;
598
619
 
599
620
            line_tspan->appendChild(span_tspan);
600
 
                Inkscape::GC::release(span_tspan);
 
621
            Inkscape::GC::release(span_tspan);
601
622
        }
602
623
        repr->appendChild(line_tspan);
603
 
            Inkscape::GC::release(line_tspan);
 
624
        Inkscape::GC::release(line_tspan);
604
625
    }
605
626
 
606
 
    Inkscape::XML::Node *parent = SP_OBJECT_REPR(item)->parent();
607
 
    parent->appendChild(repr);
608
 
    SPItem *new_item = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr);
609
 
    sp_item_write_transform(new_item, repr, item->transform);
610
 
    SP_OBJECT(new_item)->updateRepr();
611
 
 
612
 
    Inkscape::GC::release(repr);
613
 
    selection->set(new_item);
614
 
    item->deleteObject();
615
 
 
616
 
    sp_document_done(sp_desktop_document(desktop));
 
627
    return repr;
617
628
}
618
629
 
619
630
SPItem *SPFlowtext::get_frame(SPItem *after)
666
677
{
667
678
    SPDocument *doc = sp_desktop_document (desktop);
668
679
 
669
 
    Inkscape::XML::Node *root_repr = sp_repr_new("svg:flowRoot");
 
680
    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
 
681
    Inkscape::XML::Node *root_repr = xml_doc->createElement("svg:flowRoot");
670
682
    root_repr->setAttribute("xml:space", "preserve"); // we preserve spaces in the text objects we create
671
683
    SPItem *ft_item = SP_ITEM(desktop->currentLayer()->appendChildRepr(root_repr));
672
684
    SPObject *root_object = doc->getObjectByRepr(root_repr);
673
685
    g_assert(SP_IS_FLOWTEXT(root_object));
674
686
 
675
 
    Inkscape::XML::Node *region_repr = sp_repr_new("svg:flowRegion");
 
687
    Inkscape::XML::Node *region_repr = xml_doc->createElement("svg:flowRegion");
676
688
    root_repr->appendChild(region_repr);
677
689
    SPObject *region_object = doc->getObjectByRepr(region_repr);
678
690
    g_assert(SP_IS_FLOWREGION(region_object));
679
691
 
680
 
    Inkscape::XML::Node *rect_repr = sp_repr_new("svg:rect"); // FIXME: use path!!! after rects are converted to use path
 
692
    Inkscape::XML::Node *rect_repr = xml_doc->createElement("svg:rect"); // FIXME: use path!!! after rects are converted to use path
681
693
    region_repr->appendChild(rect_repr);
682
694
 
683
695
    SPObject *rect = doc->getObjectByRepr(rect_repr);
696
708
    sp_rect_position_set(SP_RECT(rect), x0, y0, w, h);
697
709
    SP_OBJECT(rect)->updateRepr();
698
710
 
699
 
    Inkscape::XML::Node *para_repr = sp_repr_new("svg:flowPara");
 
711
    Inkscape::XML::Node *para_repr = xml_doc->createElement("svg:flowPara");
700
712
    root_repr->appendChild(para_repr);
701
713
    SPObject *para_object = doc->getObjectByRepr(para_repr);
702
714
    g_assert(SP_IS_FLOWPARA(para_object));
703
715
 
704
 
    Inkscape::XML::Node *text = sp_repr_new_text("");
 
716
    Inkscape::XML::Node *text = xml_doc->createTextNode("");
705
717
    para_repr->appendChild(text);
706
718
 
707
719
    Inkscape::GC::release(root_repr);