/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
void SvgDocHdl::startDocument( )
{
OSL_ENSURE(!mpTarget, "Already a target at document start (!)");
OSL_ENSURE(maCssContents.empty(), "SvgDocHdl startDocument with active css style stack entry (!)");
}
void SvgDocHdl::endDocument( )
{
OSL_ENSURE(!mpTarget, "Still a target at document end (!)");
OSL_ENSURE(maCssContents.empty(), "SvgDocHdl endDocument with active css style stack entry (!)");
}
switch (aSVGToken)
{ /// structural elements case SVGToken::Symbol:
{ /// new basic node for Symbol. Content gets scanned, but /// will not be decomposed (see SvgNode::decomposeSvgNode and bReferenced)
mpTarget = new SvgSymbolNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Switch:
{ /// new node for Switch
mpTarget = new SvgSwitchNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Defs: case SVGToken::G:
{ /// new node for Defs/G
mpTarget = new SvgGNode(aSVGToken, maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Svg:
{ /// new node for Svg
mpTarget = new SvgSvgNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Use:
{ /// new node for Use
mpTarget = new SvgUseNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::A:
{ /// new node for A
mpTarget = new SvgANode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
}
/// shape elements case SVGToken::Circle:
{ /// new node for Circle
mpTarget = new SvgCircleNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Ellipse:
{ /// new node for Ellipse
mpTarget = new SvgEllipseNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Line:
{ /// new node for Line
mpTarget = new SvgLineNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Path:
{ /// new node for Path
mpTarget = new SvgPathNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Polygon:
{ /// new node for Polygon
mpTarget = new SvgPolyNode(aSVGToken, maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Polyline:
{ /// new node for Polyline
mpTarget = new SvgPolyNode(aSVGToken, maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Rect:
{ /// new node for Rect
mpTarget = new SvgRectNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Image:
{ /// new node for Image
mpTarget = new SvgImageNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
}
/// title and description case SVGToken::Title: case SVGToken::Desc:
{ /// new node for Title and/or Desc
mpTarget = new SvgTitleDescNode(aSVGToken, maDocument, mpTarget); break;
}
/// gradients case SVGToken::LinearGradient: case SVGToken::RadialGradient:
{
mpTarget = new SvgGradientNode(aSVGToken, maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
}
/// gradient stops case SVGToken::Stop:
{
mpTarget = new SvgGradientStopNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
}
/// text case SVGToken::Text:
{
mpTarget = new SvgTextNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Tspan:
{
mpTarget = new SvgTspanNode(aSVGToken, maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Tref:
{
mpTarget = new SvgTrefNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::TextPath:
{
mpTarget = new SvgTextPathNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
}
/// styles (as stylesheets) case SVGToken::Style:
{
SvgStyleNode* pNew = new SvgStyleNode(maDocument, mpTarget);
mpTarget = pNew;
// #i125326# there are attributes, read them. This will set isTextCss to false if // type attribute is different to "text/css"
mpTarget->parseAttributes(xAttribs);
if(pNew->isTextCss())
{ // if it is a Css style, allow reading text between the start and end tag (see // SvgDocHdl::characters for details)
maCssContents.emplace_back();
} break;
}
/// structural elements clip-path and mask. Content gets scanned, but /// will not be decomposed (see SvgNode::decomposeSvgNode and bReferenced) case SVGToken::ClipPathNode:
{ /// new node for ClipPath
mpTarget = new SvgClipPathNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Mask:
{ /// new node for Mask
mpTarget = new SvgMaskNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::FeBlend:
{ /// new node for feBlend
mpTarget = new SvgFeBlendNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::FeColorMatrix:
{ /// new node for feColorMatrix
mpTarget = new SvgFeColorMatrixNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::FeComposite:
{ /// new node for feComposite
mpTarget = new SvgFeCompositeNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::FeDropShadow:
{ /// new node for feDropShadow
mpTarget = new SvgFeDropShadowNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::FeFlood:
{ /// new node for feFlood
mpTarget = new SvgFeFloodNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::FeImage:
{ /// new node for feImage
mpTarget = new SvgFeImageNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::FeGaussianBlur:
{ /// new node for feGaussianBlur
mpTarget = new SvgFeGaussianBlurNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::FeMerge:
{ /// new node for feMerge
mpTarget = new SvgFeMergeNode(aSVGToken, maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::FeMergeNode:
{ /// new node for feMergeNode
mpTarget = new SvgFeMergeNodeNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::FeOffset:
{ /// new node for feOffset
mpTarget = new SvgFeOffsetNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
} case SVGToken::Filter:
{ /// new node for Filter
mpTarget = new SvgFilterNode(aSVGToken, maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
}
/// structural element marker case SVGToken::Marker:
{ /// new node for marker
mpTarget = new SvgMarkerNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
}
/// structural element pattern case SVGToken::Pattern:
{ /// new node for pattern
mpTarget = new SvgPatternNode(maDocument, mpTarget);
mpTarget->parseAttributes(xAttribs); break;
}
if(pCssStyle && pCssStyle->isTextCss())
{ // css style parsing if(!maCssContents.empty())
{ // need to interpret css styles and remember them as StyleSheets // #125325# Caution! the Css content may contain block comments // (see http://www.w3.org/wiki/CSS_basics#CSS_comments). These need // to be removed first const OUString aCommentFreeSource(removeBlockComments(*(maCssContents.end() - 1)));
maCssContents.pop_back();
} else
{
OSL_ENSURE(false, "Closing CssStyle, but no collector string on stack (!)");
}
}
if(pTextNode)
{ // cleanup read strings // First pass: handle whitespace. This works in a way that handling a following // node may append a space to a previous node; so correct line width calculation // may only happen after this pass finishes
walkRecursive(pTextNode, static_cast<SvgTspanNode*>(pTextNode), nullptr, whiteSpaceHandling); // Second pass: calculate line widths
walkRecursive(pTextNode, static_cast<SvgTspanNode*>(pTextNode), nullptr, calcTextLineWidths);
}
}
// concatenate to current character span
rSvgCharacterNode.concatenate(aChars); break;
}
}
// add character span as simplified tspan (no arguments) // as direct child of SvgTextNode/SvgTspanNode/SvgTextPathNode new SvgCharacterNode(maDocument, mpTarget, aChars); break;
} case SVGToken::Style:
{
SvgStyleNode& rSvgStyleNode = static_cast< SvgStyleNode& >(*mpTarget);
if(!aTrimmedChars.isEmpty())
{
std::vector< OUString >::iterator aString(maCssContents.end() - 1);
(*aString) += aTrimmedChars;
}
} else
{
OSL_ENSURE(false, "Closing CssStyle, but no collector string on stack (!)");
}
} break;
} case SVGToken::Title: case SVGToken::Desc:
{
SvgTitleDescNode& rSvgTitleDescNode = static_cast< SvgTitleDescNode& >(*mpTarget);
// add text directly to SvgTitleDescNode
rSvgTitleDescNode.concatenate(aChars); break;
} default:
{ // characters not used by a known node break;
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.