/* -*- 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 .
*/
// calculate rendering text glow radius from biggest Char size for the full text in shape double nRadius = 0.0;
sal_uInt32 nFontSize = 0; if (const SvxFontHeightItem* pItem = rSet.GetItemIfSet(EE_CHAR_FONTHEIGHT))
nFontSize = pItem->GetHeight();
if (pOutliner)
{ const EditTextObject& aEdit = pOutliner->GetTextObject(); for (sal_Int32 i = 0; i < aEdit.GetParagraphCount(); i++)
{
std::vector<EECharAttrib> aAttribs;
aEdit.GetCharAttribs(i, aAttribs); for (constauto& attrib : aAttribs)
{ if (const SvxFontHeightItem* pFontHeight = dynamic_cast<const SvxFontHeightItem*>(attrib.pAttr))
{ if (nFontSize < pFontHeight->GetHeight())
nFontSize = pFontHeight->GetHeight();
}
}
}
}
if (nFontSize)
{ // Rendering_glow_size = Original_glow_size / (154.39 * FontSize ^ -0,575) // This is an approximate calculation similar to MSO text glow size which is // depending on font size
nRadius = nTextRadius / (154.39 * pow(nFontSize, -0.575));
nTextRadius = std::round(nRadius);
}
sal_Int32 getSoftEdgeRadius(const SfxItemSet& rSet)
{ return rSet.Get(SDRATTR_SOFTEDGE_RADIUS).GetValue();
}
} // end of anonymous namespace
} // end of namespace drawinglayer
if(nTransparence == nFillTransparence)
{ // shadow does not really have an own transparence, but the application // sets the shadow transparence equal to the object transparence for // convenience. This is not useful for primitive creation, so take // this as no shadow transparence
nTransparence = 0;
}
}
if(bSlideBackgroundFill)
{ // we have SlideBackgroundFill mode, create a // SdrFillAttribute accordingly return attribute::SdrFillAttribute(true);
}
}
if(drawing::FillStyle_NONE != eStyle)
{ if(100 != nTransparence)
{ // need to check XFillFloatTransparence, object fill may still be completely transparent const XFillFloatTransparenceItem* pGradientItem;
switch(eStyle)
{ default:
{ // nothing to do, color is defined break;
} case drawing::FillStyle_GRADIENT :
{
basegfx::BGradient aBGradient(rSet.Get(XATTR_FILLGRADIENT).GetGradientValue());
basegfx::BColorStops aColorStops(aBGradient.GetColorStops());
if (aBGradient.GetStartIntens() != 100 || aBGradient.GetEndIntens() != 100)
{ // Need to do the (old, crazy) blend against black for a // used intensity, but now for all ColorStops relative to their // offsets, where 0 means black and 100 means original color
aColorStops.blendToIntensity(
aBGradient.GetStartIntens() * 0.01,
aBGradient.GetEndIntens() * 0.01,
basegfx::BColor()); // COL_BLACK
}
break;
} case drawing::FillStyle_HATCH :
{ const XHatch& rHatch(rSet.Get(XATTR_FILLHATCH).GetHatchValue()); const Color aColorB(rHatch.GetColor());
aHatch = attribute::FillHatchAttribute(
XHatchStyleToHatchStyle(rHatch.GetHatchStyle()), static_cast<double>(rHatch.GetDistance()),
toRadians(rHatch.GetAngle()),
aColorB.getBColor(),
3, // same default as VCL, a minimum of three discrete units (pixels) offset
rSet.Get(XATTR_FILLBACKGROUND).GetValue());
if(bInEditMode)
{ // if yes, try to get OutlinerParaObject from active TextEdit
std::optional<OutlinerParaObject> aTextEditOutlinerParaObject(rTextObj.CreateEditOutlinerParaObject());
if (aTextEditOutlinerParaObject)
{ // if we got one, prefer text from active TextEdit
aOutlinerParaObject = std::move(aTextEditOutlinerParaObject);
}
}
if((pGradientItem = rSet.GetItemIfSet(XATTR_FILLFLOATTRANSPARENCE))
&& pGradientItem->IsEnabled())
{ // test if float transparency is completely transparent const basegfx::BGradient& rGradient(pGradientItem->GetGradientValue());
basegfx::BColor aSingleColor; constbool bSingleColor(rGradient.GetColorStops().isSingleColor(aSingleColor)); constbool bCompletelyTransparent(bSingleColor && basegfx::fTools::equal(aSingleColor.luminance(), 1.0)); constbool bNotTransparent(bSingleColor && basegfx::fTools::equalZero(aSingleColor.luminance()));
// create nothing when completely transparent: This case is already checked for the // normal fill attributes, XFILL_NONE will be used. // create nothing when not transparent: use normal fill, no need t create a FillGradientAttribute. // Both cases are optimizations, always creating FillGradientAttribute will work, too if (!bNotTransparent && !bCompletelyTransparent)
{
basegfx::BColorStops aColorStops(rGradient.GetColorStops());
if (rGradient.GetStartIntens() != 100 || rGradient.GetEndIntens() != 100)
{ // tdf#155913 Start/EndIntens is not used for transparency gradient, // so might even get asserted (?) // this may also be set for transparence, so need to take care of it
aColorStops.blendToIntensity(
rGradient.GetStartIntens() * 0.01,
rGradient.GetEndIntens() * 0.01,
basegfx::BColor()); // COL_BLACK
}
// tdf#155913 GradientStepCount is not used for transparency gradient return attribute::FillGradientAttribute(
rGradient.GetGradientStyle(), static_cast<double>(rGradient.GetBorder()) * 0.01, static_cast<double>(rGradient.GetXOffset()) * 0.01, static_cast<double>(rGradient.GetYOffset()) * 0.01,
toRadians(rGradient.GetAngle()),
aColorStops);
}
}
if(GraphicType::Bitmap != aGraphic.GetType() && GraphicType::GdiMetafile != aGraphic.GetType())
{ // no content if not bitmap or metafile
OSL_ENSURE(false, "No fill graphic in SfxItemSet (!)"); return attribute::SdrFillGraphicAttribute();
}
Size aPrefSize(aGraphic.GetPrefSize());
if(!aPrefSize.Width() || !aPrefSize.Height())
{ // if there is no logical size, create a size from pixel size and set MapMode accordingly if(GraphicType::Bitmap == aGraphic.GetType())
{
aGraphic.SetPrefSize(aGraphic.GetBitmapEx().GetSizePixel());
aGraphic.SetPrefMapMode(MapMode(MapUnit::MapPixel));
aPrefSize = aGraphic.GetPrefSize();
}
}
if(!aPrefSize.Width() || !aPrefSize.Height())
{ // no content if no size
OSL_ENSURE(false, "Graphic has no size in SfxItemSet (!)"); return attribute::SdrFillGraphicAttribute();
}
// convert size and MapMode to destination logical size and MapMode const MapUnit aDestinationMapUnit(rSet.GetPool()->GetMetric(0));
basegfx::B2DVector aGraphicLogicSize(aGraphic.GetPrefSize().Width(), aGraphic.GetPrefSize().Height());
if (aGraphic.GetPrefMapMode().GetMapUnit() != aDestinationMapUnit)
{ // #i100360# for MapUnit::MapPixel, LogicToLogic will not work properly, // so fallback to Application::GetDefaultDevice()
Size aNewSize(0, 0);
// #i124002# do not set new size using SetPrefSize at the graphic, this will lead to problems. // Instead, adapt the GraphicLogicSize which will be used for further decompositions
aGraphicLogicSize = basegfx::B2DVector(aNewSize.Width(), aNewSize.Height());
}
// look for text first if(pText)
{
aText = createNewSdrTextAttribute(rSet, *pText);
// when object has text and text is fontwork and hide contour is set for fontwork, force // line and fill style to empty if(!aText.isDefault()
&& !aText.getSdrFormTextAttribute().isDefault()
&& aText.isHideContour())
{
bFontworkHideContour = true;
}
}
// try line style if(!bFontworkHideContour)
{
aLine = createNewSdrLineAttribute(rSet);
// look for text first if(pText)
{
aText = createNewSdrTextAttribute(rSet, *pText);
// when object has text and text is fontwork and hide contour is set for fontwork, force // line and fill style to empty if(!aText.getSdrFormTextAttribute().isDefault() && aText.isHideContour())
{
bFontworkHideContour = true;
}
}
if(!bFontworkHideContour)
{ // try line style
aLine = createNewSdrLineAttribute(rSet);
// bHasContent is used from OLE and graphic objects. Normally a possible shadow // depends on line, fill or text to be set, but for these objects it is possible // to have none of these, but still content which needs to have a shadow (if set), // so shadow needs to be tried if(bHasContent || !aLine.isDefault() || !aFill.isDefault() || !aText.isDefault())
{ // try shadow const attribute::SdrShadowAttribute aShadow = !bSuppressShadow ?
createNewSdrShadowAttribute(rSet) : attribute::SdrShadowAttribute();
// get ambient color const Color aAmbientValue(rSet.Get(SDRATTR_3DSCENE_AMBIENTCOLOR).GetValue()); const basegfx::BColor aAmbientLight(aAmbientValue.getBColor());
// look for text first if(pText)
{
aText = createNewSdrTextAttribute(rSet, *pText, pLeft, pUpper, pRight, pLower);
// when object has text and text is fontwork and hide contour is set for fontwork, force // fill style to empty if(!aText.getSdrFormTextAttribute().isDefault() && aText.isHideContour())
{
bFontworkHideContour = true;
}
}
if(!bFontworkHideContour)
{ // try fill style
aFill = createNewSdrFillAttribute(rSet);
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.