From Inkscape Wiki
Revision as of 23:33, 30 December 2008 by Verbalshadow (Talk | contribs) (add replacement python script)

Jump to: navigation, search

Cheat Sheet For Converting to 2geom

If you are just starting I suggest you pick a header file and convert just one function at a time. That will give you a feel for the process as you get more comfortable do more at one time.

Lets talk about emptiness.

In Inkscape and in 2geom there are two types of emptiness for rectangles.

Rectangles with no coordinates. Rectangles with zero area.

What is the difference?

A Rect that has the coordinates of (1,2) - (2,6) contains points and has a non-zero area. A Rect that has the coordinates of (0,0) - (0,0) contains one point but has zero area. A Rect that has the coordinates of (0,0) - (10,0) contains points but has zero area. A Geom::OptRect that has not been defined with coordinates has neither points or area.

If you need to define a rectangle, but are not sure whether it is always a valid rectangle, please use Geom::OptRect. It means "Optional Rect". A bounding box of a path could be an "invalid" rectangle for example, when the path has no fill or stroke.

optrect.isEmpty() checks if optrect contains a valid rectangle NOT if the rect has zero area. rect.hasZeroArea() does that.

Items That you Can Switch NR:: for Geom::

  • NR::Matrix
  • NR::Rect
  • NR::Dim2
  • NR::L2
  • NR::Y
  • NR::X
  • NR::identity
  • NR::Coord

Things that need small adjustments or complete replacement

Error looks like NR Function or Code 2geom Replacement
NR::scale Geom::Scale (note the capital letter S)
NR::translate Geom::Translate (capital)
nrrect.extent(NR::X) geomrect.dimensions()[Geom::X] OR


height = r->extent(NR::Y); height = r->dimensions()[Geom::Y];
NR::expansion(nrmatrix) geommatrix.descrim()
desktop.cpp:754: error: 'expand' is not a member of 'Geom' NR::Rect const viewbox = NR::expand(canvas->getViewbox(), border);

Geom::Rect viewbox = canvas->getViewbox();


desktop.cpp:162: error: 'class Geom::Matrix' has no member named 'set_identity' Mymatrix = set_identity (Nrmatrix) identity(Nrmatrix) OR


desktop.cpp: In member function 'bool SPDesktop::isWithinViewport(SPItem*) const':

desktop.cpp:532: error: conversion from

'boost::optional<NR::Rect>' to non-scalar type

'boost::optional<Geom::D2<Geom::Interval> >' requested

boost::optional<NR::Rect> Geom::OptRect
desktop.cpp:1004: error: no matching function for call to 'Geom::D2<Geom::Interval>::isEmpty(double)' ./2geom/rect.h:105: note: candidates are: bool Geom::D2<Geom::Interval>::isEmpty() const
if ( !d || d->isEmpty(0.1) ) {
<nowiki> if ( !d
    || d->width() < 0.1
    || d->height() < 0.1)
display/nr-arena-item.cpp:734: error: ‘const class Geom::Matrix’ has no member named ‘test_identity’ NR::matrix.test_identity() local.isIdentity()
selection-chemistry.cpp:1424: error: no match for ‘operator[]’ in ‘center[X]’

center is a boost::optional<Geom::Point>

you're missing the *
Geom::Rotate doesn't seem have a operator/ what is the trick for turning division in to multiplication, again r1/r2 r1 * r2.inverse()
NR::Rect's can be changed to Geom::Rect But it is better not to do this. geomrect = to_2geom(nrrect)
NR::union_bounds() Geom::unify()
sp-item.cpp:814: error: ‘expansionX’ is not a member of ‘Geom’ dy0 *= NR::expansionY(i2d);

dx0 *= NR::expansionX(i2d);

dy0 *= i2d.expansionY();

dx0 *= i2d.expansionX();

sp-item.cpp:1447: error: ‘const class Geom::Matrix’ has no member named ‘is_translation’ !(!transform.is_translation() && SP_OBJECT_STYLE(item) && SP_OBJECT_STYLE(item)->getFilter()) !(!transform.isTranslation() && SP_OBJECT_STYLE(item) && SP_OBJECT_STYLE(item)->getFilter())
text-context.cpp:1610: error: no matching function for call to ‘to_2geom(boost::optional<Geom::D2<Geom::Interval> >)’ boost::optional<Geom::Rect> frame_bbox = to_2geom(sp_item_bbox_desktop(frame)); boost::optional<Geom::Rect> frame_bbox = sp_item_bbox_desktop(frame);

Conversion of rectangles (NR::Rect, NRRect, Geom::Rect, Geom::OptRect)

sorry for the very brief text here. feel free to improve it and add things. ask in the jabber channel if you have difficulties.

Most of the conversions of NR::Rect and NRRect to 2Geom needs careful thought.

2Geom makes a very important distinction between rectangles and optional rectangles. Libnr is most vague about this, so you often have to find out how a certain rectangle is used: whether it always contains valid data, or whether it can contain wrong data. For example, an NRRect that is defined as (a,b)-(a,b) often means it is an "invalid" rectangle, i.e. the data is invalid and the rectangle coordinates should not be trusted. In this case NRRect::upgrade() returns an empty boost::optional<NR::Rect>. So probably, an NRRect should be replaced with Geom::OptRect. A what? OptRect. Optional Rectangle. This means 2geom knows the data in it can not always be trusted. So when one unifies an OptRect with another OptRect, 2geom checks first whether the coordinates in both can be trusted. An Geom::Rect is always considered as a valid rectangle:

    Geom::Rect  rect1;     //  will probably be initialized as (0,0)-(0,0), but don't use this! (deprecated)
    Geom::Rect  rect2(Geom::Point(1,1), Geom::Point(1,1); // creates (1,1)-(1,1) rect :-)
    Geom::OptRect  rect3;   // creates rectangle with no coordinates
    Geom::OptRect  rect4(Geom::Rect((Geom::Point(1,2), Geom::Point(3,4)); // creates optional rectangle with defined coordinates.
    Geom::Rect   rect3b = *rect3;  // this will crash, because rect3 does not contain a rect
    //correct usage is:
    if (rect4) {
       Geom::Rect   rect4b = *rect4;  // rect4b = (1,2)-(3,4)

Note that geomrect.isEmpty() does not exist as this name is ambiguous. geomrect.hasZeroArea() does exist, and geomoptrect.isEmpty() too.

In summary, it is safest to do the following, but please think carefully about your decision

NRRect ==> Geom::OptRect
NR::Rect ==> Geom::OptRect

If you are certain that the NR::Rect always contains valid coordinates, replace it with Geom::Rect.

Simple One for One Multi-Replacement in a Single Pass Python Script