summaryrefslogtreecommitdiffstats
path: root/svgio/source/svgreader/svgstyleattributes.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svgio/source/svgreader/svgstyleattributes.cxx')
-rw-r--r--svgio/source/svgreader/svgstyleattributes.cxx1194
1 files changed, 597 insertions, 597 deletions
diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx
index b0c45fb90372..9b6b81cbcdb2 100644
--- a/svgio/source/svgreader/svgstyleattributes.cxx
+++ b/svgio/source/svgreader/svgstyleattributes.cxx
@@ -262,76 +262,76 @@ namespace svgio
drawinglayer::primitive2d::Primitive2DContainer& rTarget,
drawinglayer::primitive2d::Primitive2DContainer const & rSource) const
{
- if(!rSource.empty())
- {
- // at this point the primitives in rSource are of type TextSimplePortionPrimitive2D
- // or TextDecoratedPortionPrimitive2D and have the Fill Color (pAttributes->getFill())
- // set. When another fill is used and also evtl. stroke is set it gets necessary to
- // dismantle to geometry and add needed primitives
- const basegfx::BColor* pFill = getFill();
- const SvgGradientNode* pFillGradient = getSvgGradientNodeFill();
- const SvgPatternNode* pFillPattern = getSvgPatternNodeFill();
- const basegfx::BColor* pStroke = getStroke();
- const SvgGradientNode* pStrokeGradient = getSvgGradientNodeStroke();
- const SvgPatternNode* pStrokePattern = getSvgPatternNodeStroke();
- basegfx::B2DPolyPolygon aMergedArea;
-
- if(pFillGradient || pFillPattern || pStroke || pStrokeGradient || pStrokePattern)
- {
- // text geometry is needed, create
- // use neutral ViewInformation and create LineGeometryExtractor2D
- const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
- drawinglayer::processor2d::TextAsPolygonExtractor2D aExtractor(aViewInformation2D);
-
- // process
- aExtractor.process(rSource);
-
- // get results
- const drawinglayer::processor2d::TextAsPolygonDataNodeVector& rResult = aExtractor.getTarget();
- const sal_uInt32 nResultCount(rResult.size());
- basegfx::B2DPolyPolygonVector aTextFillVector;
- aTextFillVector.reserve(nResultCount);
-
- for(sal_uInt32 a(0); a < nResultCount; a++)
- {
- const drawinglayer::processor2d::TextAsPolygonDataNode& rCandidate = rResult[a];
+ if(rSource.empty())
+ return;
- if(rCandidate.getIsFilled())
- {
- aTextFillVector.push_back(rCandidate.getB2DPolyPolygon());
- }
- }
+ // at this point the primitives in rSource are of type TextSimplePortionPrimitive2D
+ // or TextDecoratedPortionPrimitive2D and have the Fill Color (pAttributes->getFill())
+ // set. When another fill is used and also evtl. stroke is set it gets necessary to
+ // dismantle to geometry and add needed primitives
+ const basegfx::BColor* pFill = getFill();
+ const SvgGradientNode* pFillGradient = getSvgGradientNodeFill();
+ const SvgPatternNode* pFillPattern = getSvgPatternNodeFill();
+ const basegfx::BColor* pStroke = getStroke();
+ const SvgGradientNode* pStrokeGradient = getSvgGradientNodeStroke();
+ const SvgPatternNode* pStrokePattern = getSvgPatternNodeStroke();
+ basegfx::B2DPolyPolygon aMergedArea;
- if(!aTextFillVector.empty())
- {
- aMergedArea = basegfx::utils::mergeToSinglePolyPolygon(aTextFillVector);
- }
- }
+ if(pFillGradient || pFillPattern || pStroke || pStrokeGradient || pStrokePattern)
+ {
+ // text geometry is needed, create
+ // use neutral ViewInformation and create LineGeometryExtractor2D
+ const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
+ drawinglayer::processor2d::TextAsPolygonExtractor2D aExtractor(aViewInformation2D);
- const bool bStrokeUsed(pStroke || pStrokeGradient || pStrokePattern);
+ // process
+ aExtractor.process(rSource);
- // add fill. Use geometry even for simple color fill when stroke
- // is used, else text rendering and the geometry-based stroke will
- // normally not really match optically due to diverse system text
- // renderers
- if(aMergedArea.count() && (pFillGradient || pFillPattern || bStrokeUsed))
- {
- // create text fill content based on geometry
- add_fill(aMergedArea, rTarget, aMergedArea.getB2DRange());
- }
- else if(pFill)
+ // get results
+ const drawinglayer::processor2d::TextAsPolygonDataNodeVector& rResult = aExtractor.getTarget();
+ const sal_uInt32 nResultCount(rResult.size());
+ basegfx::B2DPolyPolygonVector aTextFillVector;
+ aTextFillVector.reserve(nResultCount);
+
+ for(sal_uInt32 a(0); a < nResultCount; a++)
{
- // add the already prepared primitives for single color fill
- rTarget.append(rSource);
+ const drawinglayer::processor2d::TextAsPolygonDataNode& rCandidate = rResult[a];
+
+ if(rCandidate.getIsFilled())
+ {
+ aTextFillVector.push_back(rCandidate.getB2DPolyPolygon());
+ }
}
- // add stroke
- if(aMergedArea.count() && bStrokeUsed)
+ if(!aTextFillVector.empty())
{
- // create text stroke content
- add_stroke(aMergedArea, rTarget, aMergedArea.getB2DRange());
+ aMergedArea = basegfx::utils::mergeToSinglePolyPolygon(aTextFillVector);
}
}
+
+ const bool bStrokeUsed(pStroke || pStrokeGradient || pStrokePattern);
+
+ // add fill. Use geometry even for simple color fill when stroke
+ // is used, else text rendering and the geometry-based stroke will
+ // normally not really match optically due to diverse system text
+ // renderers
+ if(aMergedArea.count() && (pFillGradient || pFillPattern || bStrokeUsed))
+ {
+ // create text fill content based on geometry
+ add_fill(aMergedArea, rTarget, aMergedArea.getB2DRange());
+ }
+ else if(pFill)
+ {
+ // add the already prepared primitives for single color fill
+ rTarget.append(rSource);
+ }
+
+ // add stroke
+ if(aMergedArea.count() && bStrokeUsed)
+ {
+ // create text stroke content
+ add_stroke(aMergedArea, rTarget, aMergedArea.getB2DRange());
+ }
}
void SvgStyleAttributes::add_fillGradient(
@@ -346,127 +346,127 @@ namespace svgio
// get the color stops
rFillGradient.collectGradientEntries(aSvgGradientEntryVector);
- if(!aSvgGradientEntryVector.empty())
+ if(aSvgGradientEntryVector.empty())
+ return;
+
+ basegfx::B2DHomMatrix aGeoToUnit;
+ basegfx::B2DHomMatrix aGradientTransform;
+
+ if(rFillGradient.getGradientTransform())
{
- basegfx::B2DHomMatrix aGeoToUnit;
- basegfx::B2DHomMatrix aGradientTransform;
+ aGradientTransform = *rFillGradient.getGradientTransform();
+ }
- if(rFillGradient.getGradientTransform())
- {
- aGradientTransform = *rFillGradient.getGradientTransform();
- }
+ if(userSpaceOnUse == rFillGradient.getGradientUnits())
+ {
+ aGeoToUnit.translate(-rGeoRange.getMinX(), -rGeoRange.getMinY());
+ aGeoToUnit.scale(1.0 / rGeoRange.getWidth(), 1.0 / rGeoRange.getHeight());
+ }
+
+ if(SVGTokenLinearGradient == rFillGradient.getType())
+ {
+ basegfx::B2DPoint aStart(0.0, 0.0);
+ basegfx::B2DPoint aEnd(1.0, 0.0);
if(userSpaceOnUse == rFillGradient.getGradientUnits())
{
- aGeoToUnit.translate(-rGeoRange.getMinX(), -rGeoRange.getMinY());
- aGeoToUnit.scale(1.0 / rGeoRange.getWidth(), 1.0 / rGeoRange.getHeight());
+ // all possible units
+ aStart.setX(rFillGradient.getX1().solve(mrOwner, xcoordinate));
+ aStart.setY(rFillGradient.getY1().solve(mrOwner, ycoordinate));
+ aEnd.setX(rFillGradient.getX2().solve(mrOwner, xcoordinate));
+ aEnd.setY(rFillGradient.getY2().solve(mrOwner, ycoordinate));
+ }
+ else
+ {
+ // fractions or percent relative to object bounds
+ const SvgNumber X1(rFillGradient.getX1());
+ const SvgNumber Y1(rFillGradient.getY1());
+ const SvgNumber X2(rFillGradient.getX2());
+ const SvgNumber Y2(rFillGradient.getY2());
+
+ aStart.setX(Unit_percent == X1.getUnit() ? X1.getNumber() * 0.01 : X1.getNumber());
+ aStart.setY(Unit_percent == Y1.getUnit() ? Y1.getNumber() * 0.01 : Y1.getNumber());
+ aEnd.setX(Unit_percent == X2.getUnit() ? X2.getNumber() * 0.01 : X2.getNumber());
+ aEnd.setY(Unit_percent == Y2.getUnit() ? Y2.getNumber() * 0.01 : Y2.getNumber());
}
- if(SVGTokenLinearGradient == rFillGradient.getType())
+ if(!aGeoToUnit.isIdentity())
{
- basegfx::B2DPoint aStart(0.0, 0.0);
- basegfx::B2DPoint aEnd(1.0, 0.0);
+ aStart *= aGeoToUnit;
+ aEnd *= aGeoToUnit;
+ }
- if(userSpaceOnUse == rFillGradient.getGradientUnits())
- {
- // all possible units
- aStart.setX(rFillGradient.getX1().solve(mrOwner, xcoordinate));
- aStart.setY(rFillGradient.getY1().solve(mrOwner, ycoordinate));
- aEnd.setX(rFillGradient.getX2().solve(mrOwner, xcoordinate));
- aEnd.setY(rFillGradient.getY2().solve(mrOwner, ycoordinate));
- }
- else
- {
- // fractions or percent relative to object bounds
- const SvgNumber X1(rFillGradient.getX1());
- const SvgNumber Y1(rFillGradient.getY1());
- const SvgNumber X2(rFillGradient.getX2());
- const SvgNumber Y2(rFillGradient.getY2());
-
- aStart.setX(Unit_percent == X1.getUnit() ? X1.getNumber() * 0.01 : X1.getNumber());
- aStart.setY(Unit_percent == Y1.getUnit() ? Y1.getNumber() * 0.01 : Y1.getNumber());
- aEnd.setX(Unit_percent == X2.getUnit() ? X2.getNumber() * 0.01 : X2.getNumber());
- aEnd.setY(Unit_percent == Y2.getUnit() ? Y2.getNumber() * 0.01 : Y2.getNumber());
- }
+ rTarget.push_back(
+ new drawinglayer::primitive2d::SvgLinearGradientPrimitive2D(
+ aGradientTransform,
+ rPath,
+ aSvgGradientEntryVector,
+ aStart,
+ aEnd,
+ userSpaceOnUse != rFillGradient.getGradientUnits(),
+ rFillGradient.getSpreadMethod()));
+ }
+ else
+ {
+ basegfx::B2DPoint aStart(0.5, 0.5);
+ basegfx::B2DPoint aFocal;
+ double fRadius(0.5);
+ const SvgNumber* pFx = rFillGradient.getFx();
+ const SvgNumber* pFy = rFillGradient.getFy();
+ const bool bFocal(pFx || pFy);
+
+ if(userSpaceOnUse == rFillGradient.getGradientUnits())
+ {
+ // all possible units
+ aStart.setX(rFillGradient.getCx().solve(mrOwner, xcoordinate));
+ aStart.setY(rFillGradient.getCy().solve(mrOwner, ycoordinate));
+ fRadius = rFillGradient.getR().solve(mrOwner);
- if(!aGeoToUnit.isIdentity())
+ if(bFocal)
{
- aStart *= aGeoToUnit;
- aEnd *= aGeoToUnit;
+ aFocal.setX(pFx ? pFx->solve(mrOwner, xcoordinate) : aStart.getX());
+ aFocal.setY(pFy ? pFy->solve(mrOwner, ycoordinate) : aStart.getY());
}
-
- rTarget.push_back(
- new drawinglayer::primitive2d::SvgLinearGradientPrimitive2D(
- aGradientTransform,
- rPath,
- aSvgGradientEntryVector,
- aStart,
- aEnd,
- userSpaceOnUse != rFillGradient.getGradientUnits(),
- rFillGradient.getSpreadMethod()));
}
else
{
- basegfx::B2DPoint aStart(0.5, 0.5);
- basegfx::B2DPoint aFocal;
- double fRadius(0.5);
- const SvgNumber* pFx = rFillGradient.getFx();
- const SvgNumber* pFy = rFillGradient.getFy();
- const bool bFocal(pFx || pFy);
+ // fractions or percent relative to object bounds
+ const SvgNumber Cx(rFillGradient.getCx());
+ const SvgNumber Cy(rFillGradient.getCy());
+ const SvgNumber R(rFillGradient.getR());
- if(userSpaceOnUse == rFillGradient.getGradientUnits())
- {
- // all possible units
- aStart.setX(rFillGradient.getCx().solve(mrOwner, xcoordinate));
- aStart.setY(rFillGradient.getCy().solve(mrOwner, ycoordinate));
- fRadius = rFillGradient.getR().solve(mrOwner);
+ aStart.setX(Unit_percent == Cx.getUnit() ? Cx.getNumber() * 0.01 : Cx.getNumber());
+ aStart.setY(Unit_percent == Cy.getUnit() ? Cy.getNumber() * 0.01 : Cy.getNumber());
+ fRadius = (Unit_percent == R.getUnit()) ? R.getNumber() * 0.01 : R.getNumber();
- if(bFocal)
- {
- aFocal.setX(pFx ? pFx->solve(mrOwner, xcoordinate) : aStart.getX());
- aFocal.setY(pFy ? pFy->solve(mrOwner, ycoordinate) : aStart.getY());
- }
- }
- else
+ if(bFocal)
{
- // fractions or percent relative to object bounds
- const SvgNumber Cx(rFillGradient.getCx());
- const SvgNumber Cy(rFillGradient.getCy());
- const SvgNumber R(rFillGradient.getR());
-
- aStart.setX(Unit_percent == Cx.getUnit() ? Cx.getNumber() * 0.01 : Cx.getNumber());
- aStart.setY(Unit_percent == Cy.getUnit() ? Cy.getNumber() * 0.01 : Cy.getNumber());
- fRadius = (Unit_percent == R.getUnit()) ? R.getNumber() * 0.01 : R.getNumber();
-
- if(bFocal)
- {
- aFocal.setX(pFx ? (Unit_percent == pFx->getUnit() ? pFx->getNumber() * 0.01 : pFx->getNumber()) : aStart.getX());
- aFocal.setY(pFy ? (Unit_percent == pFy->getUnit() ? pFy->getNumber() * 0.01 : pFy->getNumber()) : aStart.getY());
- }
+ aFocal.setX(pFx ? (Unit_percent == pFx->getUnit() ? pFx->getNumber() * 0.01 : pFx->getNumber()) : aStart.getX());
+ aFocal.setY(pFy ? (Unit_percent == pFy->getUnit() ? pFy->getNumber() * 0.01 : pFy->getNumber()) : aStart.getY());
}
+ }
- if(!aGeoToUnit.isIdentity())
- {
- aStart *= aGeoToUnit;
- fRadius = (aGeoToUnit * basegfx::B2DVector(fRadius, 0.0)).getLength();
+ if(!aGeoToUnit.isIdentity())
+ {
+ aStart *= aGeoToUnit;
+ fRadius = (aGeoToUnit * basegfx::B2DVector(fRadius, 0.0)).getLength();
- if(bFocal)
- {
- aFocal *= aGeoToUnit;
- }
+ if(bFocal)
+ {
+ aFocal *= aGeoToUnit;
}
-
- rTarget.push_back(
- new drawinglayer::primitive2d::SvgRadialGradientPrimitive2D(
- aGradientTransform,
- rPath,
- aSvgGradientEntryVector,
- aStart,
- fRadius,
- userSpaceOnUse != rFillGradient.getGradientUnits(),
- rFillGradient.getSpreadMethod(),
- bFocal ? &aFocal : nullptr));
}
+
+ rTarget.push_back(
+ new drawinglayer::primitive2d::SvgRadialGradientPrimitive2D(
+ aGradientTransform,
+ rPath,
+ aSvgGradientEntryVector,
+ aStart,
+ fRadius,
+ userSpaceOnUse != rFillGradient.getGradientUnits(),
+ rFillGradient.getSpreadMethod(),
+ bFocal ? &aFocal : nullptr));
}
}
@@ -513,85 +513,85 @@ namespace svgio
// fill polyPolygon with given pattern
const drawinglayer::primitive2d::Primitive2DContainer& rPrimitives = rFillPattern.getPatternPrimitives();
- if(!rPrimitives.empty())
- {
- double fTargetWidth(rGeoRange.getWidth());
- double fTargetHeight(rGeoRange.getHeight());
-
- if(fTargetWidth > 0.0 && fTargetHeight > 0.0)
- {
- // get relative values from pattern
- double fX(0.0);
- double fY(0.0);
- double fW(0.0);
- double fH(0.0);
+ if(rPrimitives.empty())
+ return;
- rFillPattern.getValuesRelative(fX, fY, fW, fH, rGeoRange, mrOwner);
+ double fTargetWidth(rGeoRange.getWidth());
+ double fTargetHeight(rGeoRange.getHeight());
- if(fW > 0.0 && fH > 0.0)
- {
- // build the reference range relative to the rGeoRange
- const basegfx::B2DRange aReferenceRange(fX, fY, fX + fW, fY + fH);
+ if(!(fTargetWidth > 0.0 && fTargetHeight > 0.0))
+ return;
- // find out how the content is mapped to the reference range
- basegfx::B2DHomMatrix aMapPrimitivesToUnitRange;
- const basegfx::B2DRange* pViewBox = rFillPattern.getViewBox();
+ // get relative values from pattern
+ double fX(0.0);
+ double fY(0.0);
+ double fW(0.0);
+ double fH(0.0);
- if(pViewBox)
- {
- // use viewBox/preserveAspectRatio
- const SvgAspectRatio& rRatio = rFillPattern.getSvgAspectRatio();
- const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
+ rFillPattern.getValuesRelative(fX, fY, fW, fH, rGeoRange, mrOwner);
- if(rRatio.isSet())
- {
- // let mapping be created from SvgAspectRatio
- aMapPrimitivesToUnitRange = rRatio.createMapping(aUnitRange, *pViewBox);
- }
- else
- {
- // choose default mapping
- aMapPrimitivesToUnitRange = SvgAspectRatio::createLinearMapping(aUnitRange, *pViewBox);
- }
- }
- else
- {
- // use patternContentUnits
- const SvgUnits aPatternContentUnits(rFillPattern.getPatternContentUnits() ? *rFillPattern.getPatternContentUnits() : userSpaceOnUse);
+ if(!(fW > 0.0 && fH > 0.0))
+ return;
- if(userSpaceOnUse == aPatternContentUnits)
- {
- // create relative mapping to unit coordinates
- aMapPrimitivesToUnitRange.scale(1.0 / (fW * fTargetWidth), 1.0 / (fH * fTargetHeight));
- }
- else
- {
- aMapPrimitivesToUnitRange.scale(1.0 / fW, 1.0 / fH);
- }
- }
+ // build the reference range relative to the rGeoRange
+ const basegfx::B2DRange aReferenceRange(fX, fY, fX + fW, fY + fH);
- // apply aMapPrimitivesToUnitRange to content when used
- drawinglayer::primitive2d::Primitive2DContainer aPrimitives(rPrimitives);
+ // find out how the content is mapped to the reference range
+ basegfx::B2DHomMatrix aMapPrimitivesToUnitRange;
+ const basegfx::B2DRange* pViewBox = rFillPattern.getViewBox();
- if(!aMapPrimitivesToUnitRange.isIdentity())
- {
- const drawinglayer::primitive2d::Primitive2DReference xRef(
- new drawinglayer::primitive2d::TransformPrimitive2D(
- aMapPrimitivesToUnitRange,
- aPrimitives));
+ if(pViewBox)
+ {
+ // use viewBox/preserveAspectRatio
+ const SvgAspectRatio& rRatio = rFillPattern.getSvgAspectRatio();
+ const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
- aPrimitives = drawinglayer::primitive2d::Primitive2DContainer { xRef };
- }
+ if(rRatio.isSet())
+ {
+ // let mapping be created from SvgAspectRatio
+ aMapPrimitivesToUnitRange = rRatio.createMapping(aUnitRange, *pViewBox);
+ }
+ else
+ {
+ // choose default mapping
+ aMapPrimitivesToUnitRange = SvgAspectRatio::createLinearMapping(aUnitRange, *pViewBox);
+ }
+ }
+ else
+ {
+ // use patternContentUnits
+ const SvgUnits aPatternContentUnits(rFillPattern.getPatternContentUnits() ? *rFillPattern.getPatternContentUnits() : userSpaceOnUse);
- // embed in PatternFillPrimitive2D
- rTarget.push_back(
- new drawinglayer::primitive2d::PatternFillPrimitive2D(
- rPath,
- aPrimitives,
- aReferenceRange));
- }
+ if(userSpaceOnUse == aPatternContentUnits)
+ {
+ // create relative mapping to unit coordinates
+ aMapPrimitivesToUnitRange.scale(1.0 / (fW * fTargetWidth), 1.0 / (fH * fTargetHeight));
}
+ else
+ {
+ aMapPrimitivesToUnitRange.scale(1.0 / fW, 1.0 / fH);
+ }
+ }
+
+ // apply aMapPrimitivesToUnitRange to content when used
+ drawinglayer::primitive2d::Primitive2DContainer aPrimitives(rPrimitives);
+
+ if(!aMapPrimitivesToUnitRange.isIdentity())
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aMapPrimitivesToUnitRange,
+ aPrimitives));
+
+ aPrimitives = drawinglayer::primitive2d::Primitive2DContainer { xRef };
}
+
+ // embed in PatternFillPrimitive2D
+ rTarget.push_back(
+ new drawinglayer::primitive2d::PatternFillPrimitive2D(
+ rPath,
+ aPrimitives,
+ aReferenceRange));
}
void SvgStyleAttributes::add_fill(
@@ -603,50 +603,50 @@ namespace svgio
const SvgGradientNode* pFillGradient = getSvgGradientNodeFill();
const SvgPatternNode* pFillPattern = getSvgPatternNodeFill();
- if(pFill || pFillGradient || pFillPattern)
- {
- const double fFillOpacity(getFillOpacity().solve(mrOwner));
+ if(!(pFill || pFillGradient || pFillPattern))
+ return;
- if(basegfx::fTools::more(fFillOpacity, 0.0))
- {
- drawinglayer::primitive2d::Primitive2DContainer aNewFill;
+ const double fFillOpacity(getFillOpacity().solve(mrOwner));
- if(pFillGradient)
- {
- // create fill content with SVG gradient primitive
- add_fillGradient(rPath, aNewFill, *pFillGradient, rGeoRange);
- }
- else if(pFillPattern)
- {
- // create fill content with SVG pattern primitive
- add_fillPatternTransform(rPath, aNewFill, *pFillPattern, rGeoRange);
- }
- else // if(pFill)
- {
- // create fill content
- aNewFill.resize(1);
- aNewFill[0] = new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
- rPath,
- *pFill);
- }
+ if(!basegfx::fTools::more(fFillOpacity, 0.0))
+ return;
- if(!aNewFill.empty())
- {
- if(basegfx::fTools::less(fFillOpacity, 1.0))
- {
- // embed in UnifiedTransparencePrimitive2D
- rTarget.push_back(
- new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
- aNewFill,
- 1.0 - fFillOpacity));
- }
- else
- {
- // append
- rTarget.append(aNewFill);
- }
- }
- }
+ drawinglayer::primitive2d::Primitive2DContainer aNewFill;
+
+ if(pFillGradient)
+ {
+ // create fill content with SVG gradient primitive
+ add_fillGradient(rPath, aNewFill, *pFillGradient, rGeoRange);
+ }
+ else if(pFillPattern)
+ {
+ // create fill content with SVG pattern primitive
+ add_fillPatternTransform(rPath, aNewFill, *pFillPattern, rGeoRange);
+ }
+ else // if(pFill)
+ {
+ // create fill content
+ aNewFill.resize(1);
+ aNewFill[0] = new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ rPath,
+ *pFill);
+ }
+
+ if(aNewFill.empty())
+ return;
+
+ if(basegfx::fTools::less(fFillOpacity, 1.0))
+ {
+ // embed in UnifiedTransparencePrimitive2D
+ rTarget.push_back(
+ new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
+ aNewFill,
+ 1.0 - fFillOpacity));
+ }
+ else
+ {
+ // append
+ rTarget.append(aNewFill);
}
}
@@ -659,151 +659,151 @@ namespace svgio
const SvgGradientNode* pStrokeGradient = getSvgGradientNodeStroke();
const SvgPatternNode* pStrokePattern = getSvgPatternNodeStroke();
- if(pStroke || pStrokeGradient || pStrokePattern)
- {
- drawinglayer::primitive2d::Primitive2DContainer aNewStroke;
- const double fStrokeOpacity(getStrokeOpacity().solve(mrOwner));
+ if(!(pStroke || pStrokeGradient || pStrokePattern))
+ return;
- if(basegfx::fTools::more(fStrokeOpacity, 0.0))
- {
- // get stroke width; SVG does not use 0.0 == hairline, so 0.0 is no line at all
- const double fStrokeWidth(getStrokeWidth().isSet() ? getStrokeWidth().solve(mrOwner) : 1.0);
+ drawinglayer::primitive2d::Primitive2DContainer aNewStroke;
+ const double fStrokeOpacity(getStrokeOpacity().solve(mrOwner));
- if(basegfx::fTools::more(fStrokeWidth, 0.0))
- {
- drawinglayer::primitive2d::Primitive2DReference aNewLinePrimitive;
+ if(!basegfx::fTools::more(fStrokeOpacity, 0.0))
+ return;
- // if we have a line with two identical points it is not really a line,
- // but used by SVG sometimes to paint a single dot.In that case, create
- // the geometry for a single dot
- if(1 == rPath.count())
- {
- const basegfx::B2DPolygon& aSingle(rPath.getB2DPolygon(0));
+ // get stroke width; SVG does not use 0.0 == hairline, so 0.0 is no line at all
+ const double fStrokeWidth(getStrokeWidth().isSet() ? getStrokeWidth().solve(mrOwner) : 1.0);
- if(2 == aSingle.count() && aSingle.getB2DPoint(0).equal(aSingle.getB2DPoint(1)))
- {
- aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
- basegfx::B2DPolyPolygon(
- basegfx::utils::createPolygonFromCircle(
- aSingle.getB2DPoint(0),
- fStrokeWidth * (1.44 * 0.5))),
- pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0));
- }
- }
+ if(!basegfx::fTools::more(fStrokeWidth, 0.0))
+ return;
- if(!aNewLinePrimitive.is())
- {
- // get LineJoin, LineCap and stroke array
- const basegfx::B2DLineJoin aB2DLineJoin(StrokeLinejoinToB2DLineJoin(getStrokeLinejoin()));
- const css::drawing::LineCap aLineCap(StrokeLinecapToDrawingLineCap(getStrokeLinecap()));
- ::std::vector< double > aDashArray;
+ drawinglayer::primitive2d::Primitive2DReference aNewLinePrimitive;
- if(!getStrokeDasharray().empty())
- {
- aDashArray = solveSvgNumberVector(getStrokeDasharray(), mrOwner);
- }
+ // if we have a line with two identical points it is not really a line,
+ // but used by SVG sometimes to paint a single dot.In that case, create
+ // the geometry for a single dot
+ if(1 == rPath.count())
+ {
+ const basegfx::B2DPolygon& aSingle(rPath.getB2DPolygon(0));
- // convert svg:stroke-miterlimit to LineAttrute:mfMiterMinimumAngle
- // The default needs to be set explicitly, because svg default <> Draw default
- double fMiterMinimumAngle;
- if (getStrokeMiterLimit().isSet())
- {
- fMiterMinimumAngle = 2.0 * asin(1.0/getStrokeMiterLimit().getNumber());
- }
- else
- {
- fMiterMinimumAngle = 2.0 * asin(0.25); // 1.0/default 4.0
- }
+ if(2 == aSingle.count() && aSingle.getB2DPoint(0).equal(aSingle.getB2DPoint(1)))
+ {
+ aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(
+ basegfx::utils::createPolygonFromCircle(
+ aSingle.getB2DPoint(0),
+ fStrokeWidth * (1.44 * 0.5))),
+ pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0));
+ }
+ }
- // todo: Handle getStrokeDashOffset()
+ if(!aNewLinePrimitive.is())
+ {
+ // get LineJoin, LineCap and stroke array
+ const basegfx::B2DLineJoin aB2DLineJoin(StrokeLinejoinToB2DLineJoin(getStrokeLinejoin()));
+ const css::drawing::LineCap aLineCap(StrokeLinecapToDrawingLineCap(getStrokeLinecap()));
+ ::std::vector< double > aDashArray;
- // prepare line attribute
- const drawinglayer::attribute::LineAttribute aLineAttribute(
- pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0),
- fStrokeWidth,
- aB2DLineJoin,
- aLineCap,
- fMiterMinimumAngle);
+ if(!getStrokeDasharray().empty())
+ {
+ aDashArray = solveSvgNumberVector(getStrokeDasharray(), mrOwner);
+ }
- if(aDashArray.empty())
- {
- aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
- rPath,
- aLineAttribute);
- }
- else
- {
- const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(aDashArray);
+ // convert svg:stroke-miterlimit to LineAttrute:mfMiterMinimumAngle
+ // The default needs to be set explicitly, because svg default <> Draw default
+ double fMiterMinimumAngle;
+ if (getStrokeMiterLimit().isSet())
+ {
+ fMiterMinimumAngle = 2.0 * asin(1.0/getStrokeMiterLimit().getNumber());
+ }
+ else
+ {
+ fMiterMinimumAngle = 2.0 * asin(0.25); // 1.0/default 4.0
+ }
- aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
- rPath,
- aLineAttribute,
- aStrokeAttribute);
- }
- }
+ // todo: Handle getStrokeDashOffset()
- if(pStrokeGradient || pStrokePattern)
- {
- // put primitive into Primitive2DReference and Primitive2DSequence
- const drawinglayer::primitive2d::Primitive2DContainer aSeq { aNewLinePrimitive };
+ // prepare line attribute
+ const drawinglayer::attribute::LineAttribute aLineAttribute(
+ pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0),
+ fStrokeWidth,
+ aB2DLineJoin,
+ aLineCap,
+ fMiterMinimumAngle);
+
+ if(aDashArray.empty())
+ {
+ aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
+ rPath,
+ aLineAttribute);
+ }
+ else
+ {
+ const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(aDashArray);
- // use neutral ViewInformation and create LineGeometryExtractor2D
- const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
- drawinglayer::processor2d::LineGeometryExtractor2D aExtractor(aViewInformation2D);
+ aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
+ rPath,
+ aLineAttribute,
+ aStrokeAttribute);
+ }
+ }
- // process
- aExtractor.process(aSeq);
+ if(pStrokeGradient || pStrokePattern)
+ {
+ // put primitive into Primitive2DReference and Primitive2DSequence
+ const drawinglayer::primitive2d::Primitive2DContainer aSeq { aNewLinePrimitive };
- // check for fill rsults
- const basegfx::B2DPolyPolygonVector& rLineFillVector(aExtractor.getExtractedLineFills());
+ // use neutral ViewInformation and create LineGeometryExtractor2D
+ const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
+ drawinglayer::processor2d::LineGeometryExtractor2D aExtractor(aViewInformation2D);
- if(!rLineFillVector.empty())
- {
- const basegfx::B2DPolyPolygon aMergedArea(
- basegfx::utils::mergeToSinglePolyPolygon(
- rLineFillVector));
+ // process
+ aExtractor.process(aSeq);
- if(aMergedArea.count())
- {
- if(pStrokeGradient)
- {
- // create fill content with SVG gradient primitive. Use original GeoRange,
- // e.g. from circle without LineWidth
- add_fillGradient(aMergedArea, aNewStroke, *pStrokeGradient, rGeoRange);
- }
- else // if(pStrokePattern)
- {
- // create fill content with SVG pattern primitive. Use GeoRange
- // from the expanded data, e.g. circle with extended geo by half linewidth
- add_fillPatternTransform(aMergedArea, aNewStroke, *pStrokePattern, aMergedArea.getB2DRange());
- }
- }
- }
- }
- else // if(pStroke)
+ // check for fill rsults
+ const basegfx::B2DPolyPolygonVector& rLineFillVector(aExtractor.getExtractedLineFills());
+
+ if(!rLineFillVector.empty())
+ {
+ const basegfx::B2DPolyPolygon aMergedArea(
+ basegfx::utils::mergeToSinglePolyPolygon(
+ rLineFillVector));
+
+ if(aMergedArea.count())
+ {
+ if(pStrokeGradient)
{
- aNewStroke.push_back(aNewLinePrimitive);
+ // create fill content with SVG gradient primitive. Use original GeoRange,
+ // e.g. from circle without LineWidth
+ add_fillGradient(aMergedArea, aNewStroke, *pStrokeGradient, rGeoRange);
}
-
- if(!aNewStroke.empty())
+ else // if(pStrokePattern)
{
- if(basegfx::fTools::less(fStrokeOpacity, 1.0))
- {
- // embed in UnifiedTransparencePrimitive2D
- rTarget.push_back(
- new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
- aNewStroke,
- 1.0 - fStrokeOpacity));
- }
- else
- {
- // append
- rTarget.append(aNewStroke);
- }
+ // create fill content with SVG pattern primitive. Use GeoRange
+ // from the expanded data, e.g. circle with extended geo by half linewidth
+ add_fillPatternTransform(aMergedArea, aNewStroke, *pStrokePattern, aMergedArea.getB2DRange());
}
}
}
}
+ else // if(pStroke)
+ {
+ aNewStroke.push_back(aNewLinePrimitive);
+ }
+
+ if(aNewStroke.empty())
+ return;
+
+ if(basegfx::fTools::less(fStrokeOpacity, 1.0))
+ {
+ // embed in UnifiedTransparencePrimitive2D
+ rTarget.push_back(
+ new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
+ aNewStroke,
+ 1.0 - fStrokeOpacity));
+ }
+ else
+ {
+ // append
+ rTarget.append(aNewStroke);
+ }
}
bool SvgStyleAttributes::prepare_singleMarker(
@@ -906,174 +906,174 @@ namespace svgio
const SvgMarkerNode* pMid = accessMarkerMidXLink();
const SvgMarkerNode* pEnd = accessMarkerEndXLink();
- if(pStart || pMid || pEnd)
+ if(!(pStart || pMid || pEnd))
+ return;
+
+ const sal_uInt32 nSubPathCount(rPath.count());
+
+ if(!nSubPathCount)
+ return;
+
+ // remember prepared marker; pStart, pMid and pEnd may all be equal when
+ // only 'marker' was used instead of 'marker-start', 'marker-mid' or 'marker-end',
+ // see 'case SVGTokenMarker' in this file; thus in this case only one common
+ // marker in primitive form will be prepared
+ const SvgMarkerNode* pPrepared = nullptr;
+
+ // values for the prepared marker, results of prepare_singleMarker
+ drawinglayer::primitive2d::Primitive2DContainer aPreparedMarkerPrimitives;
+ basegfx::B2DHomMatrix aPreparedMarkerTransform;
+ basegfx::B2DRange aPreparedMarkerClipRange;
+
+ for (sal_uInt32 a(0); a < nSubPathCount; a++)
{
- const sal_uInt32 nSubPathCount(rPath.count());
+ // iterate over sub-paths
+ const basegfx::B2DPolygon& aSubPolygonPath(rPath.getB2DPolygon(a));
+ const sal_uInt32 nSubPolygonPointCount(aSubPolygonPath.count());
+ const bool bSubPolygonPathIsClosed(aSubPolygonPath.isClosed());
- if(nSubPathCount)
+ if(nSubPolygonPointCount)
{
- // remember prepared marker; pStart, pMid and pEnd may all be equal when
- // only 'marker' was used instead of 'marker-start', 'marker-mid' or 'marker-end',
- // see 'case SVGTokenMarker' in this file; thus in this case only one common
- // marker in primitive form will be prepared
- const SvgMarkerNode* pPrepared = nullptr;
+ // for each sub-path, create one marker per point (when closed, two markers
+ // need to pe created for the 1st point)
+ const sal_uInt32 nTargetMarkerCount(bSubPolygonPathIsClosed ? nSubPolygonPointCount + 1 : nSubPolygonPointCount);
- // values for the prepared marker, results of prepare_singleMarker
- drawinglayer::primitive2d::Primitive2DContainer aPreparedMarkerPrimitives;
- basegfx::B2DHomMatrix aPreparedMarkerTransform;
- basegfx::B2DRange aPreparedMarkerClipRange;
-
- for (sal_uInt32 a(0); a < nSubPathCount; a++)
+ for (sal_uInt32 b(0); b < nTargetMarkerCount; b++)
{
- // iterate over sub-paths
- const basegfx::B2DPolygon& aSubPolygonPath(rPath.getB2DPolygon(a));
- const sal_uInt32 nSubPolygonPointCount(aSubPolygonPath.count());
- const bool bSubPolygonPathIsClosed(aSubPolygonPath.isClosed());
+ const bool bIsFirstMarker(!a && !b);
+ const bool bIsLastMarker(nSubPathCount - 1 == a && nTargetMarkerCount - 1 == b);
+ const SvgMarkerNode* pNeeded = nullptr;
+
+ if(bIsFirstMarker)
+ {
+ // 1st point in 1st sub-polygon, use pStart
+ pNeeded = pStart;
+ }
+ else if(bIsLastMarker)
+ {
+ // last point in last sub-polygon, use pEnd
+ pNeeded = pEnd;
+ }
+ else
+ {
+ // anything in-between, use pMid
+ pNeeded = pMid;
+ }
- if(nSubPolygonPointCount)
+ if(pHelpPointIndices && !pHelpPointIndices->empty())
{
- // for each sub-path, create one marker per point (when closed, two markers
- // need to pe created for the 1st point)
- const sal_uInt32 nTargetMarkerCount(bSubPolygonPathIsClosed ? nSubPolygonPointCount + 1 : nSubPolygonPointCount);
+ const basegfx::utils::PointIndexSet::const_iterator aFound(
+ pHelpPointIndices->find(basegfx::utils::PointIndex(a, b)));
- for (sal_uInt32 b(0); b < nTargetMarkerCount; b++)
+ if(aFound != pHelpPointIndices->end())
{
- const bool bIsFirstMarker(!a && !b);
- const bool bIsLastMarker(nSubPathCount - 1 == a && nTargetMarkerCount - 1 == b);
- const SvgMarkerNode* pNeeded = nullptr;
+ // this point is a pure helper point; do not create a marker for it
+ continue;
+ }
+ }
- if(bIsFirstMarker)
- {
- // 1st point in 1st sub-polygon, use pStart
- pNeeded = pStart;
- }
- else if(bIsLastMarker)
- {
- // last point in last sub-polygon, use pEnd
- pNeeded = pEnd;
- }
- else
- {
- // anything in-between, use pMid
- pNeeded = pMid;
- }
+ if(!pNeeded)
+ {
+ // no marker needs to be created for this point
+ continue;
+ }
- if(pHelpPointIndices && !pHelpPointIndices->empty())
- {
- const basegfx::utils::PointIndexSet::const_iterator aFound(
- pHelpPointIndices->find(basegfx::utils::PointIndex(a, b)));
-
- if(aFound != pHelpPointIndices->end())
- {
- // this point is a pure helper point; do not create a marker for it
- continue;
- }
- }
+ if(pPrepared != pNeeded)
+ {
+ // if needed marker is not yet prepared, do it now
+ if(prepare_singleMarker(aPreparedMarkerPrimitives, aPreparedMarkerTransform, aPreparedMarkerClipRange, *pNeeded))
+ {
+ pPrepared = pNeeded;
+ }
+ else
+ {
+ // error: could not prepare given marker
+ OSL_ENSURE(false, "OOps, could not prepare given marker as primitives (!)");
+ pPrepared = nullptr;
+ continue;
+ }
+ }
- if(!pNeeded)
- {
- // no marker needs to be created for this point
- continue;
- }
+ // prepare complete transform
+ basegfx::B2DHomMatrix aCombinedTransform(aPreparedMarkerTransform);
+
+ // get rotation
+ if(pPrepared->getOrientAuto())
+ {
+ const sal_uInt32 nPointIndex(b % nSubPolygonPointCount);
+
+ // get entering and leaving tangents; this will search backward/forward
+ // in the polygon to find tangents unequal to zero, skipping empty edges
+ // see basegfx descriptions)
+ // Hint: Mozilla, Inkscape and others use only leaving tangent for start marker
+ // and entering tangent for end marker. To achieve this (if wanted) it is possible
+ // to make the fetch of aEntering/aLeaving dependent on bIsFirstMarker/bIsLastMarker.
+ // This is not done here, see comment 14 in task #1232379#
+ // or http://www.w3.org/TR/SVG/painting.html#OrientAttribute
+ basegfx::B2DVector aEntering(
+ basegfx::utils::getTangentEnteringPoint(
+ aSubPolygonPath,
+ nPointIndex));
+ basegfx::B2DVector aLeaving(
+ basegfx::utils::getTangentLeavingPoint(
+ aSubPolygonPath,
+ nPointIndex));
+ const bool bEntering(!aEntering.equalZero());
+ const bool bLeaving(!aLeaving.equalZero());
+
+ if(bEntering || bLeaving)
+ {
+ basegfx::B2DVector aSum(0.0, 0.0);
- if(pPrepared != pNeeded)
+ if(bEntering)
{
- // if needed marker is not yet prepared, do it now
- if(prepare_singleMarker(aPreparedMarkerPrimitives, aPreparedMarkerTransform, aPreparedMarkerClipRange, *pNeeded))
- {
- pPrepared = pNeeded;
- }
- else
- {
- // error: could not prepare given marker
- OSL_ENSURE(false, "OOps, could not prepare given marker as primitives (!)");
- pPrepared = nullptr;
- continue;
- }
+ aSum += aEntering.normalize();
}
- // prepare complete transform
- basegfx::B2DHomMatrix aCombinedTransform(aPreparedMarkerTransform);
-
- // get rotation
- if(pPrepared->getOrientAuto())
+ if(bLeaving)
{
- const sal_uInt32 nPointIndex(b % nSubPolygonPointCount);
-
- // get entering and leaving tangents; this will search backward/forward
- // in the polygon to find tangents unequal to zero, skipping empty edges
- // see basegfx descriptions)
- // Hint: Mozilla, Inkscape and others use only leaving tangent for start marker
- // and entering tangent for end marker. To achieve this (if wanted) it is possible
- // to make the fetch of aEntering/aLeaving dependent on bIsFirstMarker/bIsLastMarker.
- // This is not done here, see comment 14 in task #1232379#
- // or http://www.w3.org/TR/SVG/painting.html#OrientAttribute
- basegfx::B2DVector aEntering(
- basegfx::utils::getTangentEnteringPoint(
- aSubPolygonPath,
- nPointIndex));
- basegfx::B2DVector aLeaving(
- basegfx::utils::getTangentLeavingPoint(
- aSubPolygonPath,
- nPointIndex));
- const bool bEntering(!aEntering.equalZero());
- const bool bLeaving(!aLeaving.equalZero());
-
- if(bEntering || bLeaving)
- {
- basegfx::B2DVector aSum(0.0, 0.0);
-
- if(bEntering)
- {
- aSum += aEntering.normalize();
- }
-
- if(bLeaving)
- {
- aSum += aLeaving.normalize();
- }
-
- if(!aSum.equalZero())
- {
- const double fAngle(atan2(aSum.getY(), aSum.getX()));
-
- // apply rotation
- aCombinedTransform.rotate(fAngle);
- }
- }
+ aSum += aLeaving.normalize();
}
- else
+
+ if(!aSum.equalZero())
{
+ const double fAngle(atan2(aSum.getY(), aSum.getX()));
+
// apply rotation
- aCombinedTransform.rotate(pPrepared->getAngle());
+ aCombinedTransform.rotate(fAngle);
}
+ }
+ }
+ else
+ {
+ // apply rotation
+ aCombinedTransform.rotate(pPrepared->getAngle());
+ }
- // get and apply target position
- const basegfx::B2DPoint aPoint(aSubPolygonPath.getB2DPoint(b % nSubPolygonPointCount));
-
- aCombinedTransform.translate(aPoint.getX(), aPoint.getY());
+ // get and apply target position
+ const basegfx::B2DPoint aPoint(aSubPolygonPath.getB2DPoint(b % nSubPolygonPointCount));
- // prepare marker
- drawinglayer::primitive2d::Primitive2DReference xMarker(
- new drawinglayer::primitive2d::TransformPrimitive2D(
- aCombinedTransform,
- aPreparedMarkerPrimitives));
+ aCombinedTransform.translate(aPoint.getX(), aPoint.getY());
- if(!aPreparedMarkerClipRange.isEmpty())
- {
- // marker needs to be clipped, it's bigger as the mapping
- basegfx::B2DPolyPolygon aClipPolygon(basegfx::utils::createPolygonFromRect(aPreparedMarkerClipRange));
+ // prepare marker
+ drawinglayer::primitive2d::Primitive2DReference xMarker(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aCombinedTransform,
+ aPreparedMarkerPrimitives));
- aClipPolygon.transform(aCombinedTransform);
- xMarker = new drawinglayer::primitive2d::MaskPrimitive2D(
- aClipPolygon,
- drawinglayer::primitive2d::Primitive2DContainer { xMarker });
- }
+ if(!aPreparedMarkerClipRange.isEmpty())
+ {
+ // marker needs to be clipped, it's bigger as the mapping
+ basegfx::B2DPolyPolygon aClipPolygon(basegfx::utils::createPolygonFromRect(aPreparedMarkerClipRange));
- // add marker
- rTarget.push_back(xMarker);
- }
+ aClipPolygon.transform(aCombinedTransform);
+ xMarker = new drawinglayer::primitive2d::MaskPrimitive2D(
+ aClipPolygon,
+ drawinglayer::primitive2d::Primitive2DContainer { xMarker });
}
+
+ // add marker
+ rTarget.push_back(xMarker);
}
}
}
@@ -1153,98 +1153,98 @@ namespace svgio
const drawinglayer::primitive2d::Primitive2DContainer& rSource,
const basegfx::B2DHomMatrix* pTransform) const
{
- if(!rSource.empty())
+ if(rSource.empty())
+ return;
+
+ const double fOpacity(getOpacity().solve(mrOwner));
+
+ if(basegfx::fTools::equalZero(fOpacity))
{
- const double fOpacity(getOpacity().solve(mrOwner));
+ return;
+ }
- if(basegfx::fTools::equalZero(fOpacity))
- {
- return;
- }
+ drawinglayer::primitive2d::Primitive2DContainer aSource(rSource);
- drawinglayer::primitive2d::Primitive2DContainer aSource(rSource);
+ if(basegfx::fTools::less(fOpacity, 1.0))
+ {
+ // embed in UnifiedTransparencePrimitive2D
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
+ aSource,
+ 1.0 - fOpacity));
- if(basegfx::fTools::less(fOpacity, 1.0))
- {
- // embed in UnifiedTransparencePrimitive2D
- const drawinglayer::primitive2d::Primitive2DReference xRef(
- new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
- aSource,
- 1.0 - fOpacity));
+ aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
+ }
- aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
- }
+ if(pTransform)
+ {
+ // create embedding group element with transformation. This applies the given
+ // transformation to the graphical content, but *not* to mask and/or clip (as needed)
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ *pTransform,
+ aSource));
- if(pTransform)
- {
- // create embedding group element with transformation. This applies the given
- // transformation to the graphical content, but *not* to mask and/or clip (as needed)
- const drawinglayer::primitive2d::Primitive2DReference xRef(
- new drawinglayer::primitive2d::TransformPrimitive2D(
- *pTransform,
- aSource));
+ aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
+ }
- aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
- }
+ const SvgClipPathNode* pClip = accessClipPathXLink();
+ while(pClip)
+ {
+ // #i124852# transform may be needed when userSpaceOnUse
+ pClip->apply(aSource, pTransform);
+ pClip = pClip->getSvgStyleAttributes()->accessClipPathXLink();
+ }
- const SvgClipPathNode* pClip = accessClipPathXLink();
- while(pClip)
+ if(!aSource.empty()) // test again, applied clipPath may have lead to empty geometry
+ {
+ const SvgMaskNode* pMask = accessMaskXLink();
+ if(pMask)
{
// #i124852# transform may be needed when userSpaceOnUse
- pClip->apply(aSource, pTransform);
- pClip = pClip->getSvgStyleAttributes()->accessClipPathXLink();
+ pMask->apply(aSource, pTransform);
}
+ }
- if(!aSource.empty()) // test again, applied clipPath may have lead to empty geometry
- {
- const SvgMaskNode* pMask = accessMaskXLink();
- if(pMask)
- {
- // #i124852# transform may be needed when userSpaceOnUse
- pMask->apply(aSource, pTransform);
- }
- }
+ // This is part of the SVG import of self-written SVGs from
+ // Draw/Impress containing multiple Slides/Pages. To be able
+ // to later 'break' these to multiple Pages if wanted, embed
+ // each Page-Content in a identifiable Primitive Grouping
+ // Object.
+ // This is the case when the current Node is a GroupNode, has
+ // class="Page" set, has a parent that also is a GroupNode
+ // at which class="Slide" is set.
+ // Multiple Slides/Pages are possible for Draw and Impress.
+ if(SVGTokenG == mrOwner.getType() && mrOwner.getClass())
+ {
+ const OUString aOwnerClass(*mrOwner.getClass());
- // This is part of the SVG import of self-written SVGs from
- // Draw/Impress containing multiple Slides/Pages. To be able
- // to later 'break' these to multiple Pages if wanted, embed
- // each Page-Content in a identifiable Primitive Grouping
- // Object.
- // This is the case when the current Node is a GroupNode, has
- // class="Page" set, has a parent that also is a GroupNode
- // at which class="Slide" is set.
- // Multiple Slides/Pages are possible for Draw and Impress.
- if(SVGTokenG == mrOwner.getType() && mrOwner.getClass())
+ if("Page" == aOwnerClass)
{
- const OUString aOwnerClass(*mrOwner.getClass());
+ const SvgNode* pParent(mrOwner.getParent());
- if("Page" == aOwnerClass)
+ if(nullptr != pParent && SVGTokenG == pParent->getType() && pParent->getClass())
{
- const SvgNode* pParent(mrOwner.getParent());
+ const OUString aParentClass(*pParent->getClass());
- if(nullptr != pParent && SVGTokenG == pParent->getType() && pParent->getClass())
+ if("Slide" == aParentClass)
{
- const OUString aParentClass(*pParent->getClass());
-
- if("Slide" == aParentClass)
- {
- // embed to grouping primitive to identify the
- // Slide/Page information
- const drawinglayer::primitive2d::Primitive2DReference xRef(
- new drawinglayer::primitive2d::PageHierarchyPrimitive2D(
- aSource));
+ // embed to grouping primitive to identify the
+ // Slide/Page information
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::PageHierarchyPrimitive2D(
+ aSource));
- aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
- }
+ aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
}
}
}
+ }
- if(!aSource.empty()) // test again, applied mask may have lead to empty geometry
- {
- // append to current target
- rTarget.append(aSource);
- }
+ if(!aSource.empty()) // test again, applied mask may have lead to empty geometry
+ {
+ // append to current target
+ rTarget.append(aSource);
}
}