Author: alg
Date: Tue Aug 13 17:03:33 2013
New Revision: 1513592
URL: http://svn.apache.org/r1513592
Log:
i122600 Added patch from Regina that fixes a bunch of tasks (list see in task
itself) and a reression/crash
Patch by: regina
Review by: ALG
Modified:
openoffice/branches/AOO401/main/svgio/inc/svgio/svgreader/svgsvgnode.hxx
openoffice/branches/AOO401/main/svgio/inc/svgio/svgreader/svgtools.hxx
openoffice/branches/AOO401/main/svgio/source/svgreader/svgcirclenode.cxx
openoffice/branches/AOO401/main/svgio/source/svgreader/svgsvgnode.cxx
openoffice/branches/AOO401/main/svgio/source/svgreader/svgtools.cxx
Modified:
openoffice/branches/AOO401/main/svgio/inc/svgio/svgreader/svgsvgnode.hxx
URL:
http://svn.apache.org/viewvc/openoffice/branches/AOO401/main/svgio/inc/svgio/svgreader/svgsvgnode.hxx?rev=1513592&r1=1513591&r2=1513592&view=diff
==============================================================================
--- openoffice/branches/AOO401/main/svgio/inc/svgio/svgreader/svgsvgnode.hxx
(original)
+++ openoffice/branches/AOO401/main/svgio/inc/svgio/svgreader/svgsvgnode.hxx
Tue Aug 13 17:03:33 2013
@@ -56,7 +56,15 @@ namespace svgio
virtual void parseAttribute(const rtl::OUString& rTokenName,
SVGToken aSVGToken, const rtl::OUString& aContent);
virtual void
decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool
bReferenced) const;
- /// InfoProvider support for % values
+ /// Seeks width and height of viewport, which is current before
the new viewport is set.
+ // needed for percentage unit in x, y, width or height
+ virtual void seekReferenceWidth(double& fWidth, bool& bHasFound)
const;
+ virtual void seekReferenceHeight(double& fHeight, bool& bHasFound)
const;
+
+ /// InfoProvider support for % values in childs
+ // The returned 'CurrentViewPort' is the viewport as it is set by
this svg element
+ // and as it is needed to resolve relative values in childs
+ // The method does not check for invalid width and height
virtual const basegfx::B2DRange* getCurrentViewPort() const;
/// viewBox content
Modified: openoffice/branches/AOO401/main/svgio/inc/svgio/svgreader/svgtools.hxx
URL:
http://svn.apache.org/viewvc/openoffice/branches/AOO401/main/svgio/inc/svgio/svgreader/svgtools.hxx?rev=1513592&r1=1513591&r2=1513592&view=diff
==============================================================================
--- openoffice/branches/AOO401/main/svgio/inc/svgio/svgreader/svgtools.hxx
(original)
+++ openoffice/branches/AOO401/main/svgio/inc/svgio/svgreader/svgtools.hxx Tue
Aug 13 17:03:33 2013
@@ -40,6 +40,9 @@ namespace svgio
void myAssert(const rtl::OUString& rMessage);
#endif
+// recommended value for this devise dependend unit, see CSS2 section 4.3.2
Lenghts
+#define F_SVG_PIXEL_PER_INCH 90.0
+
// common non-token strings
struct commonStrings
{
@@ -126,7 +129,12 @@ namespace svgio
bool isPositive() const;
+ // Only usable in cases, when the unit is not Unit_percent,
otherwise use method solve
+ double solveNonPercentage(const InfoProvider& rInfoProvider) const;
+
double solve(const InfoProvider& rInfoProvider, NumberType
aNumberType = length) const;
+
+
};
typedef ::std::vector< SvgNumber > SvgNumberVector;
Modified:
openoffice/branches/AOO401/main/svgio/source/svgreader/svgcirclenode.cxx
URL:
http://svn.apache.org/viewvc/openoffice/branches/AOO401/main/svgio/source/svgreader/svgcirclenode.cxx?rev=1513592&r1=1513591&r2=1513592&view=diff
==============================================================================
--- openoffice/branches/AOO401/main/svgio/source/svgreader/svgcirclenode.cxx
(original)
+++ openoffice/branches/AOO401/main/svgio/source/svgreader/svgcirclenode.cxx
Tue Aug 13 17:03:33 2013
@@ -128,7 +128,7 @@ namespace svgio
if(pStyle && getR().isSet())
{
- const double fR(getR().solve(*this, xcoordinate));
+ const double fR(getR().solve(*this, length));
if(fR > 0.0)
{
Modified: openoffice/branches/AOO401/main/svgio/source/svgreader/svgsvgnode.cxx
URL:
http://svn.apache.org/viewvc/openoffice/branches/AOO401/main/svgio/source/svgreader/svgsvgnode.cxx?rev=1513592&r1=1513591&r2=1513592&view=diff
==============================================================================
--- openoffice/branches/AOO401/main/svgio/source/svgreader/svgsvgnode.cxx
(original)
+++ openoffice/branches/AOO401/main/svgio/source/svgreader/svgsvgnode.cxx Tue
Aug 13 17:03:33 2013
@@ -162,6 +162,91 @@ namespace svgio
}
}
+ void SvgSvgNode::seekReferenceWidth(double& fWidth, bool& bHasFound)
const
+ {
+ if (!getParent() || bHasFound)
+ {
+ return;
+ }
+ const SvgSvgNode* pParentSvgSvgNode = 0;
+ // enclosing svg might have relative width, need to cumulate them
till they are
+ // resolved somewhere up in the node tree
+ double fPercentage(1.0);
+ for(const SvgNode* pParent = getParent(); pParent && !bHasFound;
pParent = pParent->getParent())
+ {
+ // dynamic_cast results Null-pointer for not SvgSvgNode and so
skips them in if condition
+ pParentSvgSvgNode = dynamic_cast< const SvgSvgNode* >(pParent);
+ if (pParentSvgSvgNode)
+ {
+ if (pParentSvgSvgNode->getViewBox())
+ {
+ // viewbox values are already in 'user unit'.
+ fWidth = pParentSvgSvgNode->getViewBox()->getWidth() *
fPercentage;
+ bHasFound = true;
+ }
+ else
+ {
+ // take absolute value or cummulate percentage
+ if (pParentSvgSvgNode->getWidth().isSet())
+ {
+ if (Unit_percent ==
pParentSvgSvgNode->getWidth().getUnit())
+ {
+ fPercentage *=
pParentSvgSvgNode->getWidth().getNumber() * 0.01;
+ }
+ else
+ {
+ fWidth =
pParentSvgSvgNode->getWidth().solveNonPercentage(*pParentSvgSvgNode) *
fPercentage;
+ bHasFound = true;
+ }
+ } // not set => width=100% => factor 1, no need for
else
+ }
+ }
+ }
+ }
+
+ void SvgSvgNode::seekReferenceHeight(double& fHeight, bool& bHasFound)
const
+ {
+ if (!getParent() || bHasFound)
+ {
+ return;
+ }
+ const SvgSvgNode* pParentSvgSvgNode = 0;
+ // enclosing svg might have relative width and height, need to
cumulate them till they are
+ // resolved somewhere up in the node tree
+ double fPercentage(1.0);
+ for(const SvgNode* pParent = getParent(); pParent && !bHasFound;
pParent = pParent->getParent())
+ {
+ // dynamic_cast results Null-pointer for not SvgSvgNode and so
skips them in if condition
+ pParentSvgSvgNode = dynamic_cast< const SvgSvgNode* >(pParent);
+ if (pParentSvgSvgNode)
+ {
+ if (pParentSvgSvgNode->getViewBox())
+ {
+ // viewbox values are already in 'user unit'.
+ fHeight = pParentSvgSvgNode->getViewBox()->getHeight()
* fPercentage;
+ bHasFound = true;
+ }
+ else
+ {
+ // take absolute value or cummulate percentage
+ if (pParentSvgSvgNode->getHeight().isSet())
+ {
+ if (Unit_percent ==
pParentSvgSvgNode->getHeight().getUnit())
+ {
+ fPercentage *=
pParentSvgSvgNode->getHeight().getNumber() * 0.01;
+ }
+ else
+ {
+ fHeight =
pParentSvgSvgNode->getHeight().solveNonPercentage(*pParentSvgSvgNode) *
fPercentage;
+ bHasFound = true;
+ }
+ } // not set => height=100% => factor 1, no need for
else
+ }
+ }
+ }
+ }
+
+// ToDo: Consider attribute overflow in method decomposeSvgNode
void
SvgSvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence&
rTarget, bool bReferenced) const
{
drawinglayer::primitive2d::Primitive2DSequence aSequence;
@@ -173,13 +258,7 @@ namespace svgio
{
if(getParent())
{
- const bool bWidthIsRelative(!getWidth().isSet() ||
Unit_percent == getWidth().getUnit());
- const bool bHeightIsRelative(!getWidth().isSet() ||
Unit_percent == getWidth().getUnit());
- const SvgSvgNode* pParentSvgSvgNode = 0;
- double fW(0.0);
- double fH(0.0);
-
- // #122594# if width/height is not given, it's 100% (see
5.1.2 The svg element in SVG1.1 spec).
+ // #122594# if width/height is not given, it's 100% (see
5.1.2 The 'svg' element in SVG1.1 spec).
// If it is relative, the question is to what. The
previous implementatin assumed relative to the
// local ViewBox which is implied by (4.2 Basic data
types):
//
@@ -190,56 +269,92 @@ namespace svgio
// units in general), and (b) when a percentage length
value represents a percentage of the
// bounding box width or height on a given object (refer
to the section that describes object
// bounding box units)."
- //
- // This is not closer specified for the SVG element itself
as non-outmost element, but comparisons
- // with common browsers shows that it's mostly interpreted
relative to the viewBox of the parent.
- // Adding code to search the parent SVG element and
calculating width/height relative to it's
- // viewBox width/height (and no longer to the local
viewBox).
- if(bWidthIsRelative || bHeightIsRelative)
+
+ // Comparisons with commom browsers show, that it's mostly
interpreted relative to the viewport
+ // of the parent, and so does the new implementation.
+
+ // Extract known viewport data
+ // bXXXIsAbsolute tracks whether relative values could be
resolved to absolute values
+
+ // If width or height is not provided, the default 100% is
used, see SVG 1.1 section 5.1.2
+ // value 0.0 here is only to initialize variable
+ bool bWidthIsAbsolute(getWidth().isSet() && Unit_percent
!= getWidth().getUnit());
+ double fW( bWidthIsAbsolute ?
getWidth().solveNonPercentage(*this) : 0.0);
+
+ bool bHeightIsAbsolute(getHeight().isSet() && Unit_percent
!= getHeight().getUnit());
+ double fH( bHeightIsAbsolute ?
getHeight().solveNonPercentage(*this) : 0.0);
+
+ // If x or y not provided, then default 0.0 is used, see
SVG 1.1 Section 5.1.2
+ bool bXIsAbsolute((getX().isSet() && Unit_percent !=
getX().getUnit()) || !getX().isSet());
+ double fX( bXIsAbsolute && getX().isSet() ?
getX().solveNonPercentage(*this) : 0.0);
+
+ bool bYIsAbsolute((getY().isSet() && Unit_percent !=
getY().getUnit()) || !getY().isSet());
+ double fY( bYIsAbsolute && getY().isSet() ?
getY().solveNonPercentage(*this) : 0.0);
+
+ if ( !bXIsAbsolute || !bWidthIsAbsolute)
{
- for(const SvgNode* pParent = getParent(); pParent &&
!pParentSvgSvgNode; pParent = pParent->getParent())
+ // get width of enclosing svg and resolve percentage
in x and width;
+ double fWReference(0.0);
+ bool bHasFoundWidth(false);
+ seekReferenceWidth(fWReference, bHasFoundWidth);
+ if (!bHasFoundWidth)
{
- pParentSvgSvgNode = dynamic_cast< const
SvgSvgNode* >(pParent);
+ // Even outermost svg has not all information to
resolve relative values,
+ // I use content itself as fallback to set missing
values for viewport
+ // Any better idea for such ill structures svg
documents?
+ const basegfx::B2DRange aChildRange(
+
drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
+ aSequence,
+
drawinglayer::geometry::ViewInformation2D()));
+ fWReference = aChildRange.getWidth();
}
- }
-
- if(bWidthIsRelative)
- {
- fW = getWidth().isSet() ? getWidth().getNumber() *
0.01 : 1.0;
-
- if(pParentSvgSvgNode)
+ // referenced values are already in 'user unit'
+ if (!bXIsAbsolute)
{
- fW *= pParentSvgSvgNode->getViewBox()->getWidth();
+ fX = getX().getNumber() * 0.01 * fWReference;
+ }
+ if (!bWidthIsAbsolute)
+ {
+ fW = (getWidth().isSet() ? getWidth().getNumber()
*0.01 : 1.0) * fWReference;
}
- }
- else
- {
- fW = getWidth().solve(*this, xcoordinate);
}
- if(bHeightIsRelative)
+ if ( !bYIsAbsolute || !bHeightIsAbsolute)
{
- fH = getHeight().isSet() ? getHeight().getNumber() *
0.01 : 1.0;
+ // get height of enclosing svg and resolve percentage
in y and height
+ double fHReference(0.0);
+ bool bHasFoundHeight(false);
+ seekReferenceHeight(fHReference, bHasFoundHeight);
+ if (!bHasFoundHeight)
+ {
+ // Even outermost svg has not all information to
resolve relative values,
+ // I use content itself as fallback to set missing
values for viewport
+ // Any better idea for such ill structures svg
documents?
+ const basegfx::B2DRange aChildRange(
+
drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
+ aSequence,
+
drawinglayer::geometry::ViewInformation2D()));
+ fHReference = aChildRange.getHeight();
+ }
- if(pParentSvgSvgNode)
+ // referenced values are already in 'user unit'
+ if (!bYIsAbsolute)
{
- fH *= pParentSvgSvgNode->getViewBox()->getHeight();
+ fY = getY().getNumber() * 0.01 * fHReference;
+ }
+ if (!bHeightIsAbsolute)
+ {
+ fH = (getHeight().isSet() ?
getHeight().getNumber() *0.01 : 1.0) * fHReference;
}
- }
- else
- {
- fH = getHeight().solve(*this, ycoordinate);
}
if(getViewBox())
{
- // Svg defines that with no width or no height the
viewBox content is empty,
- // so both need to exist
-
if(!basegfx::fTools::equalZero(getViewBox()->getWidth()) &&
!basegfx::fTools::equalZero(getViewBox()->getHeight()))
- {
- // create target range homing x,y, width and
height as given
- const double fX(getX().isSet() ?
getX().solve(*this, xcoordinate) : 0.0);
- const double fY(getY().isSet() ?
getY().solve(*this, ycoordinate) : 0.0);
+ // SVG 1.1 defines in section 7.7 that a negative
value for width or height
+ // in viewBox is an error and that 0.0 disables
rendering
+ if(basegfx::fTools::more(getViewBox()->getWidth(),0.0)
&& basegfx::fTools::more(getViewBox()->getHeight(),0.0))
+ {
+ // create target range homing x,y, width and
height as calculated above
const basegfx::B2DRange aTarget(fX, fY, fX + fW,
fY + fH);
if(aTarget.equal(*getViewBox()))
@@ -250,63 +365,44 @@ namespace svgio
else
{
// create mapping
- const SvgAspectRatio& rRatio =
getSvgAspectRatio();
+ // #i122610 SVG 1.1 defines in section 5.1.2
that if the attribute perserveAspectRatio is not specified,
+ // then the effect is as if a value of
'xMidYMid meet' were specified.
+ SvgAspectRatio
aRatioDefault(Align_xMidYMid,false,true);
+ const SvgAspectRatio& rRatio =
getSvgAspectRatio().isSet()? getSvgAspectRatio() : aRatioDefault;
+
+ // let mapping be created from SvgAspectRatio
+ const basegfx::B2DHomMatrix
aEmbeddingTransform(
+ rRatio.createMapping(aTarget,
*getViewBox()));
- if(rRatio.isSet())
- {
- // let mapping be created from
SvgAspectRatio
- const basegfx::B2DHomMatrix
aEmbeddingTransform(
- rRatio.createMapping(aTarget,
*getViewBox()));
-
- // prepare embedding in transformation
- const
drawinglayer::primitive2d::Primitive2DReference xRef(
- new
drawinglayer::primitive2d::TransformPrimitive2D(
- aEmbeddingTransform,
- aSequence));
-
- if(rRatio.isMeetOrSlice())
- {
- // embed in transformation
-
drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget,
xRef);
- }
- else
- {
- // need to embed in MaskPrimitive2D,
too
- const
drawinglayer::primitive2d::Primitive2DReference xMask(
- new
drawinglayer::primitive2d::MaskPrimitive2D(
-
basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aTarget)),
-
drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1)));
+ // prepare embedding in transformation
+ const
drawinglayer::primitive2d::Primitive2DReference xRef(
+ new
drawinglayer::primitive2d::TransformPrimitive2D(
+ aEmbeddingTransform,
+ aSequence));
-
drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget,
xMask);
- }
+ if(rRatio.isMeetOrSlice())
+ {
+ // embed in transformation
+
drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget,
xRef);
}
else
{
- // choose default mapping
- const basegfx::B2DHomMatrix
aEmbeddingTransform(
- rRatio.createLinearMapping(
- aTarget, *getViewBox()));
-
- // embed in transformation
- const
drawinglayer::primitive2d::Primitive2DReference xTransform(
- new
drawinglayer::primitive2d::TransformPrimitive2D(
- aEmbeddingTransform,
- aSequence));
+ // need to embed in MaskPrimitive2D, too
+ const
drawinglayer::primitive2d::Primitive2DReference xMask(
+ new
drawinglayer::primitive2d::MaskPrimitive2D(
+
basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aTarget)),
+
drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1)));
-
drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget,
xTransform);
+
drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget,
xMask);
}
}
}
}
- else
+ else // no viewBox attribute
{
// Svg defines that a negative value is an error and
that 0.0 disables rendering
if(basegfx::fTools::more(fW, 0.0) &&
basegfx::fTools::more(fH, 0.0))
{
- // check if we have a x,y position
- const double fX(getX().isSet() ?
getX().solve(*this, xcoordinate) : 0.0);
- const double fY(getY().isSet() ?
getY().solve(*this, ycoordinate) : 0.0);
-
if(!basegfx::fTools::equalZero(fX) ||
!basegfx::fTools::equalZero(fY))
{
// embed in transform
@@ -331,40 +427,64 @@ namespace svgio
}
}
}
- else
+ else // Outermost SVG element
{
- // Outermost SVG element; create target range homing width
and height as given.
- // SVG defines that x,y has no meanig for the outermost
SVG element. Use a fallback
- // width and height of din A 4 (21 x 29,7 cm)
- double fW(getWidth().isSet() ? getWidth().solve(*this,
xcoordinate) : (210.0 * 3.543307));
- double fH(getHeight().isSet() ? getHeight().solve(*this,
ycoordinate) : (297.0 * 3.543307));
+ double fW = 0.0; // effective value depends on viewBox
+ double fH = 0.0;
// Svg defines that a negative value is an error and that
0.0 disables rendering
- if(basegfx::fTools::more(fW, 0.0) &&
basegfx::fTools::more(fH, 0.0))
+ // isPositive() not usable because it allows 0.0 in
contrast to mathematical definition of 'positive'
+ const bool bWidthInvalid(getWidth().isSet() &&
basegfx::fTools::lessOrEqual(getWidth().getNumber(), 0.0));
+ const bool bHeightInvalid(getHeight().isSet() &&
basegfx::fTools::lessOrEqual(getHeight().getNumber(), 0.0));
+ if(!bWidthInvalid && !bHeightInvalid)
{
- const basegfx::B2DRange aSvgCanvasRange(0.0, 0.0, fW,
fH);
-
+ basegfx::B2DRange aSvgCanvasRange; // effective value
depends on viewBox
if(getViewBox())
{
-
if(!basegfx::fTools::equalZero(getViewBox()->getWidth()) &&
!basegfx::fTools::equalZero(getViewBox()->getHeight()))
+ // SVG 1.1 defines in section 7.7 that a negative
value for width or height
+ // in viewBox is an error and that 0.0 disables
rendering
+ const double fViewBoxWidth =
getViewBox()->getWidth();
+ const double fViewBoxHeight =
getViewBox()->getHeight();
+ if(basegfx::fTools::more(fViewBoxWidth,0.0) &&
basegfx::fTools::more(fViewBoxHeight,0.0))
{
- // create mapping
- const SvgAspectRatio& rRatio =
getSvgAspectRatio();
- basegfx::B2DHomMatrix aViewBoxMapping;
-
- if(rRatio.isSet())
+ // The intrinsic aspect ratio of the svg
element is given by absolute values of both width and height
+ // or if one or both of them is relative by
the width and height of the viewBox
+ // see SVG 1.1 section 7.12
+ const bool bWidthIsAbsolute(getWidth().isSet()
&& Unit_percent != getWidth().getUnit());
+ const bool
bHeightIsAbsolute(getHeight().isSet() && Unit_percent != getHeight().getUnit());
+ if(bWidthIsAbsolute && bHeightIsAbsolute)
{
- // let mapping be created from
SvgAspectRatio
- aViewBoxMapping =
rRatio.createMapping(aSvgCanvasRange, *getViewBox());
-
- // no need to check ratio here for slice,
the outermost Svg will
- // be clipped anyways (see below)
+ fW =getWidth().solveNonPercentage(*this);
+ fH =getHeight().solveNonPercentage(*this);
+ }
+ else if (bWidthIsAbsolute)
+ {
+ fW = getWidth().solveNonPercentage(*this);
+ fH = fW * fViewBoxWidth / fViewBoxHeight ;
+ }
+ else if (bHeightIsAbsolute)
+ {
+ fH = getHeight().solveNonPercentage(*this);
+ fW = fH * fViewBoxWidth / fViewBoxHeight ;
}
else
{
- // choose default mapping
- aViewBoxMapping =
rRatio.createLinearMapping(aSvgCanvasRange, *getViewBox());
+ fW = fViewBoxWidth;
+ fH = fViewBoxHeight;
}
+ // SVG 1.1 defines in section 5.1.2 that x,y
has no meanig for the outermost SVG element.
+ aSvgCanvasRange = basegfx::B2DRange(0.0, 0.0,
fW, fH);
+
+ // create mapping
+ // SVG 1.1 defines in section 5.1.2 that if
the attribute perserveAspectRatio is not specified,
+ // then the effect is as if a value of
'xMidYMid meet' were specified.
+ SvgAspectRatio
aRatioDefault(Align_xMidYMid,false,true);
+ const SvgAspectRatio& rRatio =
getSvgAspectRatio().isSet()? getSvgAspectRatio() : aRatioDefault;
+
+ basegfx::B2DHomMatrix aViewBoxMapping;
+ aViewBoxMapping =
rRatio.createMapping(aSvgCanvasRange, *getViewBox());
+ // no need to check ratio here for slice, the
outermost Svg will
+ // be clipped anyways (see below)
// scale content to viewBox definitions
const
drawinglayer::primitive2d::Primitive2DReference xTransform(
@@ -375,6 +495,32 @@ namespace svgio
aSequence =
drawinglayer::primitive2d::Primitive2DSequence(&xTransform, 1);
}
}
+ else // no viewbox
+ {
+ // There exists no parent to resolve relative width
or height.
+ // Use child size as fallback.
+ const bool bWidthIsAbsolute(getWidth().isSet() &&
Unit_percent != getWidth().getUnit());
+ const bool bHeightIsAbsolute(getHeight().isSet()
&& Unit_percent != getHeight().getUnit());
+ if (bWidthIsAbsolute && bHeightIsAbsolute)
+ {
+ fW =getWidth().solveNonPercentage(*this);
+ fH =getHeight().solveNonPercentage(*this);
+
+ }
+ else
+ {
+ const basegfx::B2DRange aChildRange(
+
drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
+ aSequence,
+
drawinglayer::geometry::ViewInformation2D()));
+ const double
fChildWidth(aChildRange.getWidth());
+ const double
fChildHeight(aChildRange.getHeight());
+ fW = bWidthIsAbsolute ?
getWidth().solveNonPercentage(*this) : fChildWidth;
+ fH = bHeightIsAbsolute ?
getHeight().solveNonPercentage(*this) : fChildHeight;
+ }
+ // SVG 1.1 defines in section 5.1.2 that x,y has
no meanig for the outermost SVG element.
+ aSvgCanvasRange = basegfx::B2DRange(0.0, 0.0, fW,
fH);
+ }
// to be completely correct in Svg sense it is
necessary to clip
// the whole content to the given canvas. I choose
here to do this
@@ -436,9 +582,9 @@ namespace svgio
if(aSequence.hasElements())
{
// embed in transform primitive to scale to
1/100th mm
- // where 1 mm == 3.543307 px to get from Svg
coordinates to
- // drawinglayer ones
- const double fScaleTo100thmm(100.0 / 3.543307);
+ // where 1 inch == 25.4 mm to get from Svg
coordinates (px) to
+ // drawinglayer coordinates
+ const double fScaleTo100thmm(25.4 * 100.0 /
F_SVG_PIXEL_PER_INCH);
const basegfx::B2DHomMatrix aTransform(
basegfx::tools::createScaleB2DHomMatrix(
fScaleTo100thmm,
@@ -465,9 +611,100 @@ namespace svgio
{
return getViewBox();
}
- else
+ else // viewport should be given by x, y, width, and height
{
- return SvgNode::getCurrentViewPort();
+ // Extract known viewport data
+ // bXXXIsAbsolute tracks whether relative values could be
resolved to absolute values
+ if (getParent())
+ {
+ // If width or height is not provided, the default 100% is
used, see SVG 1.1 section 5.1.2
+ // value 0.0 here is only to initialize variable
+ bool bWidthIsAbsolute(getWidth().isSet() && Unit_percent
!= getWidth().getUnit());
+ double fW( bWidthIsAbsolute ?
getWidth().solveNonPercentage(*this) : 0.0);
+ bool bHeightIsAbsolute(getHeight().isSet() && Unit_percent
!= getHeight().getUnit());
+ double fH( bHeightIsAbsolute ?
getHeight().solveNonPercentage(*this) : 0.0);
+
+ // If x or y not provided, then default 0.0 is used, see
SVG 1.1 Section 5.1.2
+ bool bXIsAbsolute((getX().isSet() && Unit_percent !=
getX().getUnit()) || !getX().isSet());
+ double fX( bXIsAbsolute && getX().isSet() ?
getX().solveNonPercentage(*this) : 0.0);
+
+ bool bYIsAbsolute((getY().isSet() && Unit_percent !=
getY().getUnit()) || !getY().isSet());
+ double fY( bYIsAbsolute && getY().isSet() ?
getY().solveNonPercentage(*this) : 0.0);
+
+ if (bXIsAbsolute && bYIsAbsolute && bWidthIsAbsolute &&
bHeightIsAbsolute)
+ {
+ return &basegfx::B2DRange(fX, fY, fX+fW, fY+fH);
+ }
+ else // try to resolve relative values
+ {
+ if (!bXIsAbsolute || !bWidthIsAbsolute)
+ {
+ // get width of enclosing svg and resolve
percentage in x and width
+ double fWReference(0.0);
+ bool bHasFoundWidth(false);
+ seekReferenceWidth(fWReference, bHasFoundWidth);
+ // referenced values are already in 'user unit'
+ if (!bXIsAbsolute && bHasFoundWidth)
+ {
+ fX = getX().getNumber() * 0.01 * fWReference;
+ bXIsAbsolute = true;
+ }
+ if (!bWidthIsAbsolute && bHasFoundWidth)
+ {
+ fW = (getWidth().isSet() ?
getWidth().getNumber() *0.01 : 1.0) * fWReference;
+ bWidthIsAbsolute = true;
+ }
+ }
+ if (!bYIsAbsolute || !bHeightIsAbsolute)
+ {
+ // get height of enclosing svg and resolve
percentage in y and height
+ double fHReference(0.0);
+ bool bHasFoundHeight(false);
+ seekReferenceHeight(fHReference, bHasFoundHeight);
+ // referenced values are already in 'user unit'
+ if (!bYIsAbsolute && bHasFoundHeight)
+ {
+ fY = getY().getNumber() * 0.01 * fHReference;
+ bYIsAbsolute = true;
+ }
+ if (!bHeightIsAbsolute && bHasFoundHeight)
+ {
+ fH = (getHeight().isSet() ?
getHeight().getNumber() *0.01 : 1.0) * fHReference;
+ bHeightIsAbsolute = true;
+ }
+ }
+
+ if (bXIsAbsolute && bYIsAbsolute && bWidthIsAbsolute
&& bHeightIsAbsolute)
+ {
+ return &basegfx::B2DRange(fX, fY, fX+fW, fY+fH);
+ }
+ else // relative values could not be resolved, there
exists no fallback
+ {
+ return SvgNode::getCurrentViewPort();
+ }
+ }
+ }
+ else //outermost svg
+ {
+ // If width or height is not provided, the default would
be 100%, see SVG 1.1 section 5.1.2
+ // But here it cannot be resolved and no fallback exists.
+ // SVG 1.1 defines in section 5.1.2 that x,y has no meanig
for the outermost SVG element.
+ bool bWidthIsAbsolute(getWidth().isSet() && Unit_percent
!= getWidth().getUnit());
+ double fW( bWidthIsAbsolute ?
getWidth().solveNonPercentage(*this) : 0.0);
+ bool bHeightIsAbsolute(getHeight().isSet() && Unit_percent
!= getHeight().getUnit());
+ double fH( bHeightIsAbsolute ?
getHeight().solveNonPercentage(*this) : 0.0);
+ if (bWidthIsAbsolute && bHeightIsAbsolute)
+ {
+ return &basegfx::B2DRange(0.0, 0.0, fW, fH);
+ }
+ else // no fallback exists
+ {
+ return SvgNode::getCurrentViewPort();
+ }
+ }
+// ToDo: Is it possible to decompose and use the bounding box of the childs,
if even the
+// outermost svg has no information to resolve percentage? Is it worth,
how expensive is it?
+
}
}
Modified: openoffice/branches/AOO401/main/svgio/source/svgreader/svgtools.cxx
URL:
http://svn.apache.org/viewvc/openoffice/branches/AOO401/main/svgio/source/svgreader/svgtools.cxx?rev=1513592&r1=1513591&r2=1513592&view=diff
==============================================================================
--- openoffice/branches/AOO401/main/svgio/source/svgreader/svgtools.cxx
(original)
+++ openoffice/branches/AOO401/main/svgio/source/svgreader/svgtools.cxx Tue Aug
13 17:03:33 2013
@@ -156,7 +156,7 @@ namespace svgio
return aRetval;
}
- double SvgNumber::solve(const InfoProvider& rInfoProvider, NumberType
aNumberType) const
+ double SvgNumber::solveNonPercentage(const InfoProvider&
rInfoProvider) const
{
if(isSet())
{
@@ -184,20 +184,56 @@ namespace svgio
case Unit_in:
{
double fRetval(mfNumber);
-
+
switch(meUnit)
{
- case Unit_pt: fRetval *= 1.25; break;
- case Unit_pc: fRetval *= 15.0; break;
- case Unit_cm: fRetval *= 35.43307; break;
- case Unit_mm: fRetval *= 3.543307; break;
- case Unit_in: fRetval *= 90.0; break;
+ case Unit_pt: fRetval *= F_SVG_PIXEL_PER_INCH /
72.0; break;
+ case Unit_pc: fRetval *= F_SVG_PIXEL_PER_INCH /
6.0; break;
+ case Unit_cm: fRetval *= F_SVG_PIXEL_PER_INCH /
2.54; break;
+ case Unit_mm: fRetval *= 0.1 *
F_SVG_PIXEL_PER_INCH / 2.54; break;
+ case Unit_in: fRetval *= F_SVG_PIXEL_PER_INCH;
break;
default: break;
}
-
+
return fRetval;
break;
}
+ default:
+ {
+ OSL_ENSURE(false, "Do not use with percentage! ");
+ return 0.0;
+ break;
+ }
+ }
+ }
+
+ /// not set
+ OSL_ENSURE(false, "SvgNumber not set (!)");
+ return 0.0;
+ }
+
+ double SvgNumber::solve(const InfoProvider& rInfoProvider, NumberType
aNumberType) const
+ {
+ if(isSet())
+ {
+ switch(meUnit)
+ {
+ case Unit_px:
+ {
+ return mfNumber;
+ break;
+ }
+ case Unit_pt:
+ case Unit_pc:
+ case Unit_cm:
+ case Unit_mm:
+ case Unit_in:
+ case Unit_em:
+ case Unit_ex:
+ {
+ return solveNonPercentage( rInfoProvider);
+ break;
+ }
case Unit_percent:
{
double fRetval(mfNumber * 0.01);
@@ -205,12 +241,15 @@ namespace svgio
if(!pViewPort)
{
+#ifdef DBG_UTIL
+ myAssert(rtl::OUString::createFromAscii("Design
error, this case should have been handled in the caller"));
+#endif
// no viewPort, assume a normal page size (A4)
static basegfx::B2DRange aDinA4Range(
0.0,
0.0,
- 210.0 * 3.543307,
- 297.0 * 3.543307);
+ 210.0 * F_SVG_PIXEL_PER_INCH / 2.54,
+ 297.0 * F_SVG_PIXEL_PER_INCH / 2.54);
pViewPort = &aDinA4Range;
}
@@ -924,11 +963,11 @@ namespace svgio
if(readNumberAndUnit(rCandidate, nPos, aHeight,
nLen))
{
- return basegfx::B2DRange(
- aMinX.solve(rInfoProvider, xcoordinate),
- aMinY.solve(rInfoProvider, ycoordinate),
- aWidth.solve(rInfoProvider, xcoordinate),
- aHeight.solve(rInfoProvider, ycoordinate));
+ double fX(aMinX.solve(rInfoProvider,
xcoordinate));
+ double fY(aMinY.solve(rInfoProvider,
ycoordinate));
+ double
fW(aWidth.solve(rInfoProvider,xcoordinate));
+ double
fH(aHeight.solve(rInfoProvider,ycoordinate));
+ return basegfx::B2DRange(fX,fY,fX+fW,fY+fH);
}
}
}