/* -*- 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 .
*/
// check for 'class' references (a list of entries is allowed) if(rNode.getClass())
{ const OUString& rClassList = *rNode.getClass(); const sal_Int32 nLen(rClassList.getLength());
if(pParent)
{ // check for combined selectors at parent first so that higher specificity will be in front
fillCssStyleVectorUsingHierarchyAndSelectors(*pParent, aNewConcatenated);
}
}
}
if(pParent)
{ // check for combined selectors at parent first so that higher specificity will be in front
fillCssStyleVectorUsingHierarchyAndSelectors(*pParent, aNewConcatenated);
}
}
// check for class-dependent references to CssStyles if(sType.isEmpty()) return;
if(pParent)
{ // check for combined selectors at parent first so that higher specificity will be in front
fillCssStyleVectorUsingHierarchyAndSelectors(*pParent, sType);
}
}
// #i125293# If we have CssStyles we need to build a linked list of SvgStyleAttributes // which represent this for the current object. There are various methods to // specify CssStyles which need to be taken into account in a given order: // - local CssStyle (independent from global CssStyles at SvgDocument) // - 'id' CssStyle // - 'class' CssStyle(s) // - type-dependent elements (e..g. 'rect' for all rect elements) // - Css selector '*' // - local attributes (rOriginal) // - inherited attributes (up the hierarchy) // The first four will be collected in maCssStyleVector for the current element // (once, this will not change) and be linked in the needed order using the // get/setCssStyle at the SvgStyleAttributes which will be used preferred in // member evaluation over the existing parent hierarchy
// check for local CssStyle with highest priority if(mpLocalCssStyle)
{ // if we have one, use as first entry
maCssStyleVector.push_back(mpLocalCssStyle.get());
}
// tdf#156038 check for child combinator
fillCssStyleVectorUsingParent(*this);
// check the hierarchy for concatenated patterns of Selectors
fillCssStyleVectorUsingHierarchyAndSelectors(*this, std::u16string_view());
// tdf#99115, Add css selector '*' style only if the element is on top of the hierarchy // meaning its parent is <svg> const SvgNode* pParent = this->getParent();
if(pParent && pParent->getType() == SVGToken::Svg)
{ // #i125329# find Css selector '*', add as last element if found const SvgStyleAttributes* pNew = getDocument().findGlobalCssStyleAttributes(u"*"_ustr);
if(pNew)
{ // add CssStyle for selector '*' if found
maCssStyleVector.push_back(pNew);
}
}
const SvgStyleAttributes* SvgNode::checkForCssStyle(const SvgStyleAttributes& rOriginal) const
{ if(!mbCssStyleVectorBuilt)
{ // build needed CssStyleVector for local node const_cast< SvgNode* >(this)->fillCssStyleVector(rOriginal);
}
if(maCssStyleVector.empty())
{ // return given original if no CssStyles found return &rOriginal;
} else
{ // #i125293# rOriginal will be the last element in the linked list; use no CssStyleParent // there (reset it) to ensure that the parent hierarchy will be used when it's base // is referenced. This new chaining inserts the CssStyles before the original style, // this makes the whole process much safer since the original style when used will // be not different to the situation without CssStyles; thus loops which may be caused // by trying to use the parent hierarchy of the owner of the style will be avoided // already in this mechanism. It's still good to keep the supportsParentStyle // from #i125258# in place, though. // This chain building using pointers will be done every time when checkForCssStyle // is used (not the search, only the chaining). This is needed since the CssStyles // themselves will be potentially used multiple times. It is not expensive since it's // only changing some pointers. // The alternative would be to create the style hierarchy for every element (or even // for the element containing the hierarchy) in a vector of pointers and to use that. // Resetting the CssStyleParent on rOriginal is probably not needed // but simply safer to do.
// loop over the existing CssStyles and link them. There is a first one, take // as current
SvgStyleAttributes* pCurrent = const_cast< SvgStyleAttributes* >(maCssStyleVector[0]);
void SvgNode::readLocalCssStyle(std::u16string_view aContent)
{ if(!mpLocalCssStyle)
{ // create LocalCssStyle if needed but not yet added
mpLocalCssStyle.reset(new SvgStyleAttributes(*this));
} else
{ // 2nd fill would be an error
OSL_ENSURE(false, "Svg node has two local CssStyles, this may lead to problems (!)");
}
if(mpLocalCssStyle)
{ // parse and set values to it
mpLocalCssStyle->readCssStyle(aContent);
} else
{
OSL_ENSURE(false, "Could not get/create a local CssStyle for a node (!)");
}
}
void SvgNode::parseAttributes(const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs)
{ // no longer need to pre-sort moving 'style' entries to the back so that // values get overwritten - that was the previous, not complete solution for // handling the priorities between svg and Css properties const sal_uInt32 nAttributes(xAttribs->getLength());
void SvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DContainer& rTarget, bool bReferenced) const
{ if (mbDecomposing) //guard against infinite recurse return;
if(Display::None == getDisplay())
{ return;
}
if(!bReferenced)
{ if(SVGToken::Defs == getType() ||
SVGToken::Symbol == getType() ||
SVGToken::ClipPathNode == getType() ||
SVGToken::Mask == getType() ||
SVGToken::Marker == getType() ||
SVGToken::Pattern == getType())
{ // do not decompose defs or symbol nodes (these hold only style-like // objects which may be used by referencing them) except when doing // so controlled referenced
// also do not decompose ClipPaths and Masks. These should be embedded // in a defs node (which gets not decomposed by itself), but you never // know
// also not directly used are Markers and Patterns, only indirectly used // by reference
// #i121656# also do not decompose nodes which have display="none" set // as property return;
}
}
double SvgNode::getCurrentXHeight() const
{ // https://drafts.csswg.org/css-values-4/#ex // for XHeight, use 0.5em fallback currently // FIXME: use "x-height of the first available font" return getCurrentFontSize() * 0.5;
}
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.