X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fsp-pattern.cpp;h=fbba4cc48caaa56c21939104603deaffebd44288;hb=8680124aec2da49c3e34695c68840387511f78bf;hp=3958da66a9579e7e09d9999cd67ee390f8d19cb4;hpb=ab17729e09d54ccfcb65645e6dae62a343e9c6b7;p=inkscape.git diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 3958da66a..fbba4cc48 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -1,11 +1,11 @@ -#define __SP_PATTERN_C__ - /* * SVG implementation * * Author: * Lauris Kaplinski * bulia byak + * Jon A. Cruz + * Abhishek Sharma * * Copyright (C) 2002 Lauris Kaplinski * @@ -156,18 +156,18 @@ sp_pattern_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *r if (((SPObjectClass *) pattern_parent_class)->build) (* ((SPObjectClass *) pattern_parent_class)->build) (object, document, repr); - sp_object_read_attr (object, "patternUnits"); - sp_object_read_attr (object, "patternContentUnits"); - sp_object_read_attr (object, "patternTransform"); - sp_object_read_attr (object, "x"); - sp_object_read_attr (object, "y"); - sp_object_read_attr (object, "width"); - sp_object_read_attr (object, "height"); - sp_object_read_attr (object, "viewBox"); - sp_object_read_attr (object, "xlink:href"); + object->readAttr( "patternUnits" ); + object->readAttr( "patternContentUnits" ); + object->readAttr( "patternTransform" ); + object->readAttr( "x" ); + object->readAttr( "y" ); + object->readAttr( "width" ); + object->readAttr( "height" ); + object->readAttr( "viewBox" ); + object->readAttr( "xlink:href" ); /* Register ourselves */ - document->add_resource ("pattern", object); + document->addResource("pattern", object); } static void @@ -179,7 +179,7 @@ sp_pattern_release (SPObject *object) if (SP_OBJECT_DOCUMENT (object)) { /* Unregister ourselves */ - SP_OBJECT_DOCUMENT (object)->remove_resource ("pattern", SP_OBJECT (object)); + SP_OBJECT_DOCUMENT (object)->removeResource("pattern", SP_OBJECT (object)); } if (pat->ref) { @@ -347,21 +347,20 @@ sp_pattern_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape:: /* fixme: We need ::order_changed handler too (Lauris) */ -GSList * -pattern_getchildren (SPPattern *pat) +GSList *pattern_getchildren(SPPattern *pat) { - GSList *l = NULL; - - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (SP_OBJECT(pat_i)->first_child()) { // find the first one with children - for (SPObject *child = SP_OBJECT (pat)->first_child() ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { - l = g_slist_prepend (l, child); - } - break; // do not go further up the chain if children are found - } + GSList *l = NULL; + + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->firstChild()) { // find the first one with children + for (SPObject *child = pat->firstChild() ; child ; child = child->getNext() ) { + l = g_slist_prepend (l, child); + } + break; // do not go further up the chain if children are found } + } - return l; + return l; } static void @@ -435,17 +434,45 @@ pattern_ref_modified (SPObject */*ref*/, guint /*flags*/, SPPattern *pattern) /* Conditional to avoid causing infinite loop if there's a cycle in the href chain. */ } + +/** +Count how many times pat is used by the styles of o and its descendants +*/ guint -pattern_users (SPPattern *pattern) +count_pattern_hrefs(SPObject *o, SPPattern *pat) { - return SP_OBJECT (pattern)->hrefcount; + if (!o) + return 1; + + guint i = 0; + + SPStyle *style = SP_OBJECT_STYLE(o); + if (style + && style->fill.isPaintserver() + && SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style)) + && SP_PATTERN(SP_STYLE_FILL_SERVER(style)) == pat) + { + i ++; + } + if (style + && style->stroke.isPaintserver() + && SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style)) + && SP_PATTERN(SP_STYLE_STROKE_SERVER(style)) == pat) + { + i ++; + } + + for ( SPObject *child = o->firstChild(); child != NULL; child = child->next ) { + i += count_pattern_hrefs(child, pat); + } + + return i; } -SPPattern * -pattern_chain (SPPattern *pattern) +SPPattern *pattern_chain(SPPattern *pattern) { SPDocument *document = SP_OBJECT_DOCUMENT (pattern); - Inkscape::XML::Document *xml_doc = sp_document_repr_doc(document); + Inkscape::XML::Document *xml_doc = document->getReprDoc(); Inkscape::XML::Node *defsrepr = SP_OBJECT_REPR (SP_DOCUMENT_DEFS (document)); Inkscape::XML::Node *repr = xml_doc->createElement("svg:pattern"); @@ -465,7 +492,7 @@ pattern_chain (SPPattern *pattern) SPPattern * sp_pattern_clone_if_necessary (SPItem *item, SPPattern *pattern, const gchar *property) { - if (pattern_users(pattern) > 1) { + if (!pattern->href || pattern->hrefcount > count_pattern_hrefs(item, pattern)) { pattern = pattern_chain (pattern); gchar *href = g_strconcat ("url(#", SP_OBJECT_REPR (pattern)->attribute("id"), ")", NULL); @@ -496,10 +523,9 @@ sp_pattern_transform_multiply (SPPattern *pattern, Geom::Matrix postmul, bool se g_free(c); } -const gchar * -pattern_tile (GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Matrix transform, Geom::Matrix move) +const gchar *pattern_tile(GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Matrix transform, Geom::Matrix move) { - Inkscape::XML::Document *xml_doc = sp_document_repr_doc(document); + Inkscape::XML::Document *xml_doc = document->getReprDoc(); Inkscape::XML::Node *defsrepr = SP_OBJECT_REPR (SP_DOCUMENT_DEFS (document)); Inkscape::XML::Node *repr = xml_doc->createElement("svg:pattern"); @@ -531,15 +557,14 @@ pattern_tile (GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Matr return pat_id; } -SPPattern * -pattern_getroot (SPPattern *pat) +SPPattern *pattern_getroot(SPPattern *pat) { - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (SP_OBJECT (pat_i)->first_child()) { // find the first one with children - return pat_i; - } - } - return pat; // document is broken, we can't get to root; but at least we can return pat which is supposedly a valid pattern + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if ( pat_i->firstChild() ) { // find the first one with children + return pat_i; + } + } + return pat; // document is broken, we can't get to root; but at least we can return pat which is supposedly a valid pattern } @@ -621,12 +646,13 @@ NRRect *pattern_viewBox (SPPattern *pat) bool pattern_hasItemChildren (SPPattern *pat) { - for (SPObject *child = SP_OBJECT (pat)->first_child() ; child != NULL; child = SP_OBJECT_NEXT(child) ) { - if (SP_IS_ITEM (child)) { - return true; - } - } - return false; + bool hasChildren = false; + for (SPObject *child = pat->firstChild() ; child && !hasChildren ; child = child->getNext() ) { + if (SP_IS_ITEM(child)) { + hasChildren = true; + } + } + return hasChildren; } @@ -733,24 +759,23 @@ sp_pattern_painter_new (SPPaintServer *ps, Geom::Matrix const &full_transform, G pp->root = NRArenaGroup::create(pp->arena); /* Show items */ - pp->_release_connections = new std::map; - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i && SP_IS_OBJECT (pat_i) && pattern_hasItemChildren(pat_i)) { // find the first one with item children - for (SPObject *child = SP_OBJECT (pat_i)->first_child() ; child != NULL; child = SP_OBJECT_NEXT(child) ) { - if (SP_IS_ITEM (child)) { - // for each item in pattern, - NRArenaItem *cai; - // show it on our arena, - cai = SP_ITEM (child)->invoke_show (pp->arena, pp->dkey, SP_ITEM_REFERENCE_FLAGS); - // add to the group, - nr_arena_item_append_child (pp->root, cai); - // and connect to the release signal in case the item gets deleted - pp->_release_connections->insert(std::make_pair(child, child->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_pattern_painter_release), pp)))); - } - } - break; // do not go further up the chain if children are found - } - } + pp->_release_connections = new std::map; + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i && SP_IS_OBJECT (pat_i) && pattern_hasItemChildren(pat_i)) { // find the first one with item children + for (SPObject *child = pat_i->firstChild() ; child; child = child->getNext() ) { + if (SP_IS_ITEM (child)) { + // for each item in pattern, + // show it on our arena, + NRArenaItem *cai = SP_ITEM(child)->invoke_show(pp->arena, pp->dkey, SP_ITEM_REFERENCE_FLAGS); + // add to the group, + nr_arena_item_append_child (pp->root, cai); + // and connect to the release signal in case the item gets deleted + pp->_release_connections->insert(std::make_pair(child, child->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_pattern_painter_release), pp)))); + } + } + break; // do not go further up the chain if children are found + } + } { NRRect one_tile,tr_tile; @@ -1016,3 +1041,15 @@ sp_pat_fill (SPPainter *painter, NRPixBlock *pb) } } } + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :