27#include <com/sun/star/rendering/XGraphicDevice.hpp>
28#include <com/sun/star/rendering/TexturingMode.hpp>
29#include <com/sun/star/uno/Sequence.hxx>
30#include <com/sun/star/rendering/PanoseProportion.hpp>
31#include <com/sun/star/rendering/XCanvasFont.hpp>
32#include <com/sun/star/rendering/XCanvas.hpp>
33#include <com/sun/star/rendering/PathCapType.hpp>
34#include <com/sun/star/rendering/PathJoinType.hpp>
49#include <rtl/ustrbuf.hxx>
83 template <
class MetaActionType >
void setStateColor(
MetaActionType* pAct,
85 uno::Sequence< double >& rColorSequence,
88 rIsColorSet = pAct->IsSetting();
92 ::Color aColor( pAct->GetColor() );
102 rCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() );
105 void setupStrokeAttributes( rendering::StrokeAttributes& o_rStrokeAttributes,
106 const ::cppcanvas::internal::ActionFactoryParameters& rParms,
109 const ::basegfx::B2DSize aWidth( rLineInfo.
GetWidth(), 0 );
110 o_rStrokeAttributes.StrokeWidth =
111 (rParms.mrStates.getState().mapModeTransform * aWidth).
getLength();
114 o_rStrokeAttributes.MiterLimit = 15.0;
115 o_rStrokeAttributes.StartCapType = rendering::PathCapType::BUTT;
116 o_rStrokeAttributes.EndCapType = rendering::PathCapType::BUTT;
121 o_rStrokeAttributes.JoinType = rendering::PathJoinType::NONE;
124 o_rStrokeAttributes.JoinType = rendering::PathJoinType::BEVEL;
127 o_rStrokeAttributes.JoinType = rendering::PathJoinType::MITER;
130 o_rStrokeAttributes.JoinType = rendering::PathJoinType::ROUND;
138 o_rStrokeAttributes.StartCapType = rendering::PathCapType::BUTT;
139 o_rStrokeAttributes.EndCapType = rendering::PathCapType::BUTT;
142 case css::drawing::LineCap_ROUND:
144 o_rStrokeAttributes.StartCapType = rendering::PathCapType::ROUND;
145 o_rStrokeAttributes.EndCapType = rendering::PathCapType::ROUND;
148 case css::drawing::LineCap_SQUARE:
150 o_rStrokeAttributes.StartCapType = rendering::PathCapType::SQUARE;
151 o_rStrokeAttributes.EndCapType = rendering::PathCapType::SQUARE;
156 if( LineStyle::Dash != rLineInfo.
GetStyle() )
159 const ::cppcanvas::internal::OutDevState& rState( rParms.mrStates.getState() );
166 const double nDistance( (rState.mapModeTransform * aDistance).getLength() );
168 const ::basegfx::B2DSize aDashLen( rLineInfo.
GetDashLen(), 0 );
169 const double nDashLen( (rState.mapModeTransform * aDashLen).getLength() );
171 const ::basegfx::B2DSize aDotLen( rLineInfo.
GetDotLen(), 0 );
172 const double nDotLen( (rState.mapModeTransform * aDotLen).getLength() );
174 const sal_Int32 nNumArryEntries( 2*rLineInfo.
GetDashCount() +
177 o_rStrokeAttributes.DashArray.realloc( nNumArryEntries );
178 double* pDashArray = o_rStrokeAttributes.DashArray.getArray();
185 sal_Int32 nCurrEntry=0;
189 pDashArray[nCurrEntry++] = nDashLen;
190 pDashArray[nCurrEntry++] = nDistance;
194 pDashArray[nCurrEntry++] = nDotLen;
195 pDashArray[nCurrEntry++] = nDistance;
204 const ::Color& rMaskColor )
206 const ::Color aWhite( COL_WHITE );
215 aSolid.Erase( rMaskColor );
220 OUString convertToLocalizedNumerals(std::u16string_view rStr,
223 OUStringBuffer
aBuf(rStr);
224 for (sal_Int32 i = 0;
i <
aBuf.getLength(); ++
i)
227 if (nChar >=
'0' && nChar <=
'9')
230 return aBuf.makeStringAndClear();
320 aCalculatedNewState.
clip = rNewState.
clip;
393 std::shared_ptr<Action> pPolyAction(
395 rPolyPoly, rParms.
mrCanvas, rState ) );
417 const char* pCommentString,
418 sal_Int32& io_rCurrActionIndex )
421 "ImplRenderer::skipContent(): NULL string given" );
424 while( (pCurrAct=rMtf.
NextAction()) !=
nullptr )
427 ++io_rCurrActionIndex;
429 if( pCurrAct->
GetType() == MetaActionType::COMMENT &&
442 const char* pCommentString,
446 "ImplRenderer::isActionContained(): NULL string given" );
455 while( (pCurrAct=rMtf.
NextAction()) !=
nullptr )
463 if( pCurrAct->
GetType() == MetaActionType::COMMENT &&
490 const ::Gradient& rGradient,
492 bool bIsPolygonRectangle,
493 bool bSubsettableActions )
503 const sal_uInt16 nSteps( rGradient.GetSteps() );
512 uno::Reference< lang::XMultiServiceFactory>
xFactory(
513 rParms.
mrCanvas->getUNOCanvas()->getDevice()->getParametricPolyPolygonFactory() );
517 rendering::Texture aTexture;
519 aTexture.RepeatModeX = rendering::TexturingMode::CLAMP;
520 aTexture.RepeatModeY = rendering::TexturingMode::CLAMP;
521 aTexture.Alpha = 1.0;
528 const sal_uInt16 nStartIntensity( rGradient.GetStartIntensity() );
529 ::Color aVCLStartColor( rGradient.GetStartColor() );
534 const sal_uInt16 nEndIntensity( rGradient.GetEndIntensity() );
535 ::Color aVCLEndColor( rGradient.GetEndColor() );
540 uno::Reference<rendering::XColorSpace> xColorSpace(
541 rParms.
mrCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace());
542 const uno::Sequence< double > aStartColor(
545 const uno::Sequence< double > aEndColor(
549 uno::Sequence< uno::Sequence < double > > aColors;
550 uno::Sequence< double > aStops;
552 if( rGradient.GetStyle() == css::awt::GradientStyle_AXIAL )
554 aStops = { 0.0, 0.5, 1.0 };
555 aColors = { aEndColor, aStartColor, aEndColor };
559 aStops = { 0.0, 1.0 };
560 aColors = { aStartColor, aEndColor };
563 const ::basegfx::B2DRectangle aBounds(
564 ::basegfx::utils::getRange(aDevicePoly) );
565 const ::basegfx::B2DVector aOffset(
566 rGradient.GetOfsX() / 100.0,
567 rGradient.GetOfsY() / 100.0);
568 double fRotation =
toRadians( rGradient.GetAngle() );
569 const double fBorder( rGradient.GetBorder() / 100.0 );
574 basegfx::ODFGradientInfo aGradInfo;
575 OUString aGradientService;
576 switch( rGradient.GetStyle() )
578 case css::awt::GradientStyle_LINEAR:
586 aGradInfo.setTextureTransform(aGradInfo.getTextureTransform() * aRot90);
587 aGradientService =
"LinearGradient";
590 case css::awt::GradientStyle_AXIAL:
604 const double fAxialBorder (1-2*(1-fBorder));
612 aGradInfo.setTextureTransform(aGradInfo.getTextureTransform() * aRot90);
619 aGradInfo.setTextureTransform(aGradInfo.getTextureTransform() * aShift);
620 aGradientService =
"LinearGradient";
624 case css::awt::GradientStyle_RADIAL:
630 aGradientService =
"EllipticalGradient";
633 case css::awt::GradientStyle_ELLIPTICAL:
640 aGradientService =
"EllipticalGradient";
643 case css::awt::GradientStyle_SQUARE:
650 aGradientService =
"RectangularGradient";
653 case css::awt::GradientStyle_RECT:
660 aGradientService =
"RectangularGradient";
665 "ImplRenderer::createGradientAction(): Unexpected gradient type" );
669 ::basegfx::unotools::affineMatrixFromHomMatrix( aTexture.AffineTransform,
670 aGradInfo.getTextureTransform() );
676 {
"AspectRatio",
uno::Any(aGradInfo.getAspectRatio())},
678 aTexture.Gradient.set(
679 xFactory->createInstanceWithArguments(aGradientService,
682 if( aTexture.Gradient.is() )
684 std::shared_ptr<Action> pPolyAction(
711 if( !bIsPolygonRectangle )
735 rendering::FontRequest aFontRequest;
740 aFontRequest.FontDescription.FamilyName = rFont.
GetFamilyName();
742 aFontRequest.FontDescription.StyleName = rFont.
GetStyleName();
744 aFontRequest.FontDescription.IsSymbolFont = (rFont.
GetCharSet() == RTL_TEXTENCODING_SYMBOL) ? util::TriState_YES : util::TriState_NO;
745 aFontRequest.FontDescription.IsVertical = rFont.
IsVertical() ? util::TriState_YES : util::TriState_NO;
748 aFontRequest.FontDescription.FontDescription.Weight =
751 ::canvas::tools::numeric_cast<sal_Int8>( ::basegfx::fround( rFont.
GetWeight() ) );
752 aFontRequest.FontDescription.FontDescription.Letterform =
756 aFontRequest.FontDescription.FontDescription.Proportion =
758 ? rendering::PanoseProportion::MONO_SPACED
759 : rendering::PanoseProportion::ANYTHING;
770 const double nAngle(
toRadians(nFontAngle) );
771 o_rFontRotation = -nAngle;
775 o_rFontRotation = 0.0;
778 geometry::Matrix2D aFontMatrix;
779 ::canvas::tools::setIdentityMatrix2D( aFontMatrix );
789 if (rFontSizeLog.
Height() == 0)
792 rFontSizeLog =
::Size(0, 16);
798 const sal_Int32 nFontWidthLog = rFontSizeLog.
Width();
799 if( nFontWidthLog != 0 )
804 if( nNormalWidth != nFontWidthLog )
806 aFontMatrix.m00 =
static_cast<double>(nFontWidthLog) / nNormalWidth;
813 if( !::basegfx::fTools::equal(
823 if( fabs(nScaleX) < fabs(nScaleY) )
824 aFontMatrix.m00 *= nScaleX / nScaleY;
826 aFontMatrix.m11 *= nScaleY / nScaleX;
834 return rParms.
mrCanvas->getUNOCanvas()->createFont(aFontRequest,
839 return rParms.
mrCanvas->getUNOCanvas()->createFont( aFontRequest,
840 uno::Sequence< beans::PropertyValue >(),
846 const OUString& rString,
852 bool bSubsettableActions )
855 "ImplRenderer::createTextWithEffectsAction(): Invalid text index" );
871 uno::Reference<rendering::XColorSpace> xColorSpace(
872 rParms.
mrCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() );
879 if( nShadowOffset < 1 )
882 aShadowOffset.
setWidth( nShadowOffset );
883 aShadowOffset.
setHeight( nShadowOffset );
899 nReliefOffset += nReliefOffset/2;
900 if( nReliefOffset < 1 )
904 nReliefOffset = -nReliefOffset;
906 aReliefOffset.
setWidth( nReliefOffset );
907 aReliefOffset.
setHeight( nReliefOffset );
923 aTextColor, xColorSpace );
935 std::shared_ptr<Action> pTextAction(
952 bSubsettableActions ) );
954 std::shared_ptr<Action> pStrikeoutTextAction;
965 pChars[3]=pChars[2]=pChars[1]=pChars[0];
968 OUString(pChars, std::size(pChars))) + 2) / 4;
970 if( nStrikeoutWidth <= 0 )
976 nMaxWidth += nWidth + 1;
979 OUStringBuffer aStrikeoutText;
980 while( (nFullStrikeoutWidth+=nStrikeoutWidth ) < nMaxWidth+1 )
981 aStrikeoutText.append(pChars[0]);
983 sal_Int32 nLen = aStrikeoutText.getLength();
987 ::tools::Long nInterval = ( nWidth - nStrikeoutWidth * nLen ) / nLen;
988 nStrikeoutWidth += nInterval;
991 for (
int i = 0;
i<nLen;
i++)
993 aStrikeoutCharWidths.
push_back(nStrikeoutWidth);
996 for (
int i = 1;
i< nLen;
i++ )
998 aStrikeoutCharWidths.
adjust(
i, aStrikeoutCharWidths[
i - 1]);
1001 pStrikeoutTextAction =
1009 aStrikeoutText.makeStringAndClear(),
1012 aStrikeoutCharWidths,
1018 bSubsettableActions ) ;
1029 if ( pStrikeoutTextAction )
1032 pStrikeoutTextAction,
1046 const bool bEmptyClipPoly( rState.
clip.
count() == 0 );
1049 "ImplRenderer::updateClipping(): Clip rect and polygon are both set!" );
1052 (bEmptyClipRect && bEmptyClipPoly) )
1054 rState.
clip = rClipPoly;
1058 if( !bEmptyClipRect )
1072 ::basegfx::utils::createPolygonFromRect(
1078 rClipPoly, rState.
clip,
true,
false);
1099 rState.
xClipPoly = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
1100 rParms.
mrCanvas->getUNOCanvas()->getDevice(),
1102 ::basegfx::utils::createPolygonFromRect(
1108 rState.
xClipPoly = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
1109 rParms.
mrCanvas->getUNOCanvas()->getDevice(),
1121 const bool bEmptyClipPoly( rState.
clip.
count() == 0 );
1124 "ImplRenderer::updateClipping(): Clip rect and polygon are both set!" );
1127 (bEmptyClipRect && bEmptyClipPoly) )
1132 else if( bEmptyClipPoly )
1149 ::basegfx::utils::createPolygonFromRect(
1156 aClipPoly, rState.
clip,
true,
false);
1173 rState.
xClipPoly = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
1174 rParms.
mrCanvas->getUNOCanvas()->getDevice(),
1176 ::basegfx::utils::createPolygonFromRect(
1182 rState.
xClipPoly = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
1183 rParms.
mrCanvas->getUNOCanvas()->getDevice(),
1190 bool bSubsettableActions )
1233 SAL_INFO(
"cppcanvas.emf",
"MTF\trecord type: 0x" <<
static_cast<sal_uInt16
>(pCurrAct->
GetType()) <<
" (" <<
static_cast<sal_uInt16
>(pCurrAct->
GetType()) <<
")");
1244 case MetaActionType::PUSH:
1251 case MetaActionType::POP:
1255 case MetaActionType::TEXTLANGUAGE:
1256 case MetaActionType::REFPOINT:
1260 case MetaActionType::MAPMODE:
1269 case MetaActionType::CLIPREGION:
1282 SAL_INFO(
"cppcanvas.emf",
"ImplRenderer::createActions(): non-polygonal clip "
1283 "region encountered, falling back to bounding box!" );
1315 case MetaActionType::ISECTRECTCLIPREGION:
1332 case MetaActionType::ISECTREGIONCLIPREGION:
1338 SAL_INFO(
"cppcanvas.emf",
"ImplRenderer::createActions(): non-polygonal clip "
1339 "region encountered, falling back to bounding box!" );
1368 case MetaActionType::MOVECLIPREGION:
1372 case MetaActionType::LINECOLOR:
1389 case MetaActionType::FILLCOLOR:
1406 case MetaActionType::TEXTCOLOR:
1422 rCanvas->getUNOCanvas()->getDevice()->getDeviceColorSpace() );
1427 case MetaActionType::TEXTFILLCOLOR:
1444 case MetaActionType::TEXTLINECOLOR:
1461 case MetaActionType::OVERLINECOLOR:
1477 case MetaActionType::TEXTALIGN:
1486 case MetaActionType::FONT:
1509 case MetaActionType::RASTEROP:
1513 case MetaActionType::LAYOUTMODE:
1521 rState.
textDirection = rendering::TextDirection::WEAK_LEFT_TO_RIGHT;
1523 rState.
textDirection = rendering::TextDirection::STRONG_LEFT_TO_RIGHT;
1525 rState.
textDirection = rendering::TextDirection::WEAK_RIGHT_TO_LEFT;
1527 rState.
textDirection = rendering::TextDirection::STRONG_RIGHT_TO_LEFT;
1545 case MetaActionType::GRADIENT:
1552 bSubsettableActions );
1556 case MetaActionType::HATCH:
1565 bSubsettableActions );
1569 case MetaActionType::EPS:
1601 static_cast<double>(rSize.Height()) / aMtfSizePix.
Height() );
1605 bSubsettableActions );
1615 case MetaActionType::COMMENT:
1620 if (pAct->
GetComment().equalsIgnoreAsciiCase(
"XGRAD_SEQ_BEGIN"))
1623 bool bDone(
false );
1632 case MetaActionType::GRADIENTEX:
1637 case MetaActionType::COMMENT:
1648 bSubsettableActions );
1660 else if( pAct->
GetComment() ==
"XPATHFILL_SEQ_BEGIN" )
1680 "XPATHFILL_SEQ_END",
1681 MetaActionType::FLOATTRANSPARENT ) )
1683 rendering::Texture aTexture;
1700 aMatrix.
set(0,0, aTransform.
matrix[ 0 ] );
1701 aMatrix.
set(0,1, aTransform.
matrix[ 1 ] );
1702 aMatrix.
set(0,2, aTransform.
matrix[ 2 ] );
1703 aMatrix.
set(1,0, aTransform.
matrix[ 3 ] );
1704 aMatrix.
set(1,1, aTransform.
matrix[ 4 ] );
1705 aMatrix.
set(1,2, aTransform.
matrix[ 5 ] );
1708 aScale.
scale( aBmpSize.Width(),
1709 aBmpSize.Height() );
1716 aMatrix = aMatrix * aScale;
1726 ::basegfx::unotools::affineMatrixFromHomMatrix(
1727 aTexture.AffineTransform,
1734 aTexture.RepeatModeX = rendering::TexturingMode::REPEAT;
1735 aTexture.RepeatModeY = rendering::TexturingMode::REPEAT;
1739 aTexture.RepeatModeX = rendering::TexturingMode::NONE;
1740 aTexture.RepeatModeY = rendering::TexturingMode::NONE;
1748 std::shared_ptr<Action> pPolyAction(
1759 io_rCurrActionIndex );
1761 io_rCurrActionIndex += pPolyAction->getActionCount()-1;
1766 "XPATHFILL_SEQ_END",
1767 io_rCurrActionIndex );
1772 else if( pAct->
GetComment() ==
"EMF_PLUS" ) {
1773 SAL_WARN (
"cppcanvas.emf",
"EMF+ code was refactored and removed");
1774 }
else if( pAct->
GetComment() ==
"EMF_PLUS_HEADER_INFO" ) {
1775 SAL_INFO (
"cppcanvas.emf",
"EMF+ passed to canvas mtf renderer - header info, size: " << pAct->
GetDataSize ());
1797 case MetaActionType::POINT:
1802 std::shared_ptr<Action> pPointAction(
1813 io_rCurrActionIndex );
1815 io_rCurrActionIndex += pPointAction->getActionCount()-1;
1821 case MetaActionType::PIXEL:
1826 std::shared_ptr<Action> pPointAction(
1838 io_rCurrActionIndex );
1840 io_rCurrActionIndex += pPointAction->getActionCount()-1;
1846 case MetaActionType::LINE:
1855 const ::basegfx::B2DPoint aStartPoint(
1857 const ::basegfx::B2DPoint aEndPoint(
1860 std::shared_ptr<Action> pLineAction;
1876 io_rCurrActionIndex );
1878 io_rCurrActionIndex += pLineAction->getActionCount()-1;
1881 else if( LineStyle::NONE != rLineInfo.
GetStyle() )
1884 rendering::StrokeAttributes aStrokeAttributes;
1886 setupStrokeAttributes( aStrokeAttributes,
1895 aPoly.
append( aStartPoint );
1896 aPoly.
append( aEndPoint );
1900 rCanvas, rState, aStrokeAttributes );
1906 io_rCurrActionIndex );
1908 io_rCurrActionIndex += pLineAction->getActionCount()-1;
1917 case MetaActionType::RECT:
1919 const ::tools::Rectangle& rRect(
1922 if( rRect.IsEmpty() )
1926 const ::basegfx::B2DPoint aTopLeftPixel(
1928 const ::basegfx::B2DPoint aBottomRightPixel(
1937 aBottomRightPixel )),
1942 case MetaActionType::ROUNDRECT:
1944 const ::tools::Rectangle& rRect(
1947 if( rRect.IsEmpty() )
1951 ::basegfx::utils::createPolygonFromRect(
1965 case MetaActionType::ELLIPSE:
1967 const ::tools::Rectangle& rRect(
1970 if( rRect.IsEmpty() )
1973 const ::basegfx::B2DRange aRange(
1979 ::basegfx::utils::createPolygonFromEllipse(
1981 aRange.getWidth() / 2,
1982 aRange.getHeight() / 2 ));
1990 case MetaActionType::ARC:
1993 const ::tools::Polygon aToolsPoly(
static_cast<MetaArcAction*
>(pCurrAct)->GetRect(),
1995 static_cast<MetaArcAction*
>(pCurrAct)->GetEndPoint(), PolyStyle::Arc );
2004 case MetaActionType::PIE:
2007 const ::tools::Polygon aToolsPoly(
static_cast<MetaPieAction*
>(pCurrAct)->GetRect(),
2009 static_cast<MetaPieAction*
>(pCurrAct)->GetEndPoint(), PolyStyle::Pie );
2018 case MetaActionType::CHORD:
2021 const ::tools::Polygon aToolsPoly(
static_cast<MetaChordAction*
>(pCurrAct)->GetRect(),
2023 static_cast<MetaChordAction*
>(pCurrAct)->GetEndPoint(), PolyStyle::Chord );
2032 case MetaActionType::POLYLINE:
2044 std::shared_ptr<Action> pLineAction;
2059 io_rCurrActionIndex );
2061 io_rCurrActionIndex += pLineAction->getActionCount()-1;
2064 else if( LineStyle::NONE != rLineInfo.
GetStyle() )
2067 rendering::StrokeAttributes aStrokeAttributes;
2069 setupStrokeAttributes( aStrokeAttributes,
2078 aStrokeAttributes ) ;
2084 io_rCurrActionIndex );
2086 io_rCurrActionIndex += pLineAction->getActionCount()-1;
2095 case MetaActionType::POLYGON:
2104 case MetaActionType::POLYPOLYGON:
2113 case MetaActionType::BMP:
2117 std::shared_ptr<Action> pBmpAction(
2129 io_rCurrActionIndex );
2131 io_rCurrActionIndex += pBmpAction->getActionCount()-1;
2136 case MetaActionType::BMPSCALE:
2140 std::shared_ptr<Action> pBmpAction(
2152 io_rCurrActionIndex );
2154 io_rCurrActionIndex += pBmpAction->getActionCount()-1;
2159 case MetaActionType::BMPSCALEPART:
2166 const ::tools::Rectangle aCropRect( pAct->
GetSrcPoint(),
2168 aBmp.
Crop( aCropRect );
2170 std::shared_ptr<Action> pBmpAction(
2184 io_rCurrActionIndex );
2186 io_rCurrActionIndex += pBmpAction->getActionCount()-1;
2191 case MetaActionType::BMPEX:
2195 std::shared_ptr<Action> pBmpAction(
2207 io_rCurrActionIndex );
2209 io_rCurrActionIndex += pBmpAction->getActionCount()-1;
2214 case MetaActionType::BMPEXSCALE:
2218 std::shared_ptr<Action> pBmpAction(
2232 io_rCurrActionIndex );
2234 io_rCurrActionIndex += pBmpAction->getActionCount()-1;
2239 case MetaActionType::BMPEXSCALEPART:
2246 const ::tools::Rectangle aCropRect( pAct->
GetSrcPoint(),
2248 aBmp.
Crop( aCropRect );
2250 std::shared_ptr<Action> pBmpAction(
2264 io_rCurrActionIndex );
2266 io_rCurrActionIndex += pBmpAction->getActionCount()-1;
2271 case MetaActionType::MASK:
2281 std::shared_ptr<Action> pBmpAction(
2293 io_rCurrActionIndex );
2295 io_rCurrActionIndex += pBmpAction->getActionCount()-1;
2300 case MetaActionType::MASKSCALE:
2310 std::shared_ptr<Action> pBmpAction(
2324 io_rCurrActionIndex );
2326 io_rCurrActionIndex += pBmpAction->getActionCount()-1;
2331 case MetaActionType::MASKSCALEPART:
2343 const ::tools::Rectangle aCropRect( pAct->
GetSrcPoint(),
2345 aBmp.
Crop( aCropRect );
2347 std::shared_ptr<Action> pBmpAction(
2361 io_rCurrActionIndex );
2363 io_rCurrActionIndex += pBmpAction->getActionCount()-1;
2368 case MetaActionType::GRADIENTEX:
2373 case MetaActionType::WALLPAPER:
2377 case MetaActionType::Transparent:
2387 std::shared_ptr<Action> pPolyAction(
2398 io_rCurrActionIndex );
2400 io_rCurrActionIndex += pPolyAction->getActionCount()-1;
2406 case MetaActionType::FLOATTRANSPARENT:
2410 std::unique_ptr< GDIMetaFile > pMtf(
2414 std::optional< Gradient > pGradient( pAct->
GetGradient() );
2418 std::shared_ptr<Action> pFloatTransAction(
2421 std::move(pGradient),
2429 if( pFloatTransAction )
2433 io_rCurrActionIndex );
2435 io_rCurrActionIndex += pFloatTransAction->getActionCount()-1;
2440 case MetaActionType::TEXT:
2443 OUString sText = pAct->
GetText();
2458 bSubsettableActions );
2462 case MetaActionType::TEXTARRAY:
2465 OUString sText = pAct->
GetText();
2480 bSubsettableActions );
2484 case MetaActionType::TEXTLINE:
2495 std::shared_ptr<Action> pPolyAction(
2512 io_rCurrActionIndex );
2514 io_rCurrActionIndex += pPolyAction->getActionCount()-1;
2519 case MetaActionType::TEXTRECT:
2535 bSubsettableActions );
2542 case MetaActionType::STRETCHTEXT:
2545 OUString sText = pAct->
GetText();
2566 const sal_Int32 nWidthDifference( pAct->
GetWidth() - aDXArray[ nLen-1 ] );
2569 for (sal_Int32
i = 1;
i <= nLen; ++
i)
2577 aDXArray.
adjust(
i - 1,
i * nWidthDifference / nLen);
2588 bSubsettableActions );
2593 SAL_WARN(
"cppcanvas.emf",
"Unknown meta action type encountered" );
2602 ++io_rCurrActionIndex;
2609 class ActionRenderer
2623 void operator()( const ::cppcanvas::internal::ImplRenderer::MtfAction& rAction )
2630 void operator()( const ::cppcanvas::internal::ImplRenderer::MtfAction& rAction,
2631 const Action::Subset& rSubset )
2657 void operator()( const ::cppcanvas::internal::ImplRenderer::MtfAction& rAction )
2662 void operator()( const ::cppcanvas::internal::ImplRenderer::MtfAction& rAction,
2663 const Action::Subset& rSubset )
2669 const ::basegfx::B2DRange& getBounds()
const
2681 struct UpperBoundActionIndexComparator
2683 bool operator()( const ::cppcanvas::internal::ImplRenderer::MtfAction& rLHS,
2684 const ::cppcanvas::internal::ImplRenderer::MtfAction& rRHS )
2686 const sal_Int32 nLHSCount( rLHS.mpAction ?
2687 rLHS.mpAction->getActionCount() : 0 );
2688 const sal_Int32 nRHSCount( rRHS.mpAction ?
2689 rRHS.mpAction->getActionCount() : 0 );
2694 return rLHS.mnOrigIndex + nLHSCount < rRHS.mnOrigIndex + nRHSCount;
2707 template<
typename Functor >
bool
2708 forSubsetRange( Functor& rFunctor,
2709 ImplRenderer::ActionVector::const_iterator aRangeBegin,
2710 const ImplRenderer::ActionVector::const_iterator& aRangeEnd,
2711 sal_Int32 nStartIndex,
2712 sal_Int32 nEndIndex,
2713 const ImplRenderer::ActionVector::const_iterator& rEnd )
2715 if( aRangeBegin == aRangeEnd )
2718 Action::Subset aSubset;
2719 aSubset.mnSubsetBegin = std::max( sal_Int32( 0 ),
2720 nStartIndex - aRangeBegin->mnOrigIndex );
2721 aSubset.mnSubsetEnd = std::min( aRangeBegin->mpAction->getActionCount(),
2722 nEndIndex - aRangeBegin->mnOrigIndex );
2725 "ImplRenderer::forSubsetRange(): Invalid indices" );
2727 rFunctor( *aRangeBegin, aSubset );
2735 Action::Subset aSubset;
2736 aSubset.mnSubsetBegin = std::max( sal_Int32( 0 ),
2737 nStartIndex - aRangeBegin->mnOrigIndex );
2738 aSubset.mnSubsetEnd = aRangeBegin->mpAction->getActionCount();
2741 "ImplRenderer::forSubsetRange(): Invalid indices" );
2743 rFunctor( *aRangeBegin, aSubset );
2749 while( aRangeBegin != aRangeEnd )
2750 rFunctor( *aRangeBegin++ );
2752 if( aRangeEnd == rEnd ||
2753 aRangeEnd->mnOrigIndex > nEndIndex )
2763 return rFunctor.result();
2766 aSubset.mnSubsetBegin = 0;
2767 aSubset.mnSubsetEnd = nEndIndex - aRangeEnd->mnOrigIndex;
2770 "ImplRenderer::forSubsetRange(): Invalid indices" );
2772 rFunctor( *aRangeEnd, aSubset );
2775 return rFunctor.result();
2780 sal_Int32& io_rEndIndex,
2781 ActionVector::const_iterator& o_rRangeBegin,
2782 ActionVector::const_iterator& o_rRangeEnd )
const
2785 "ImplRenderer::getSubsetIndices(): invalid action range" );
2788 "ImplRenderer::getSubsetIndices(): no actions to render" );
2790 const sal_Int32 nMinActionIndex(
maActions.front().mnOrigIndex );
2791 const sal_Int32 nMaxActionIndex(
maActions.back().mnOrigIndex +
2792 maActions.back().mpAction->getActionCount() );
2796 io_rStartIndex = std::max( nMinActionIndex,
2798 io_rEndIndex = std::min( nMaxActionIndex,
2801 if( io_rStartIndex == io_rEndIndex ||
2802 io_rStartIndex > io_rEndIndex )
2811 const ActionVector::const_iterator aBegin(
maActions.begin() );
2812 const ActionVector::const_iterator aEnd(
maActions.end() );
2817 o_rRangeBegin = std::lower_bound( aBegin, aEnd,
2818 MtfAction( std::shared_ptr<Action>(), io_rStartIndex ),
2819 UpperBoundActionIndexComparator() );
2820 o_rRangeEnd = std::lower_bound( aBegin, aEnd,
2821 MtfAction( std::shared_ptr<Action>(), io_rEndIndex ),
2822 UpperBoundActionIndexComparator() );
2843 SAL_INFO(
"cppcanvas.emf",
"::cppcanvas::internal::ImplRenderer::ImplRenderer(mtf)" );
2845 OSL_ENSURE( rCanvas && rCanvas->getUNOCanvas().is(),
2846 "ImplRenderer::ImplRenderer(): Invalid canvas" );
2847 OSL_ENSURE( rCanvas->getUNOCanvas()->getDevice().is(),
2848 "ImplRenderer::ImplRenderer(): Invalid graphic device" );
2853 !rCanvas->getUNOCanvas().is() ||
2854 !rCanvas->getUNOCanvas()->getDevice().is() )
2863 aVDev->EnableOutput(
false );
2871 const Size aMtfSizePixPre( aVDev->LogicToPixel( aMtfSize,
2880 sal_Int32 nCurrActions(0);
2894 1.0 / aMtfSizePix.
Height() );
2963 sal_Int32 nEndIndex )
const
2965 SAL_INFO(
"cppcanvas.emf",
"::cppcanvas::internal::ImplRenderer::drawSubset()" );
2967 ActionVector::const_iterator aRangeBegin;
2968 ActionVector::const_iterator aRangeEnd;
2973 aRangeBegin, aRangeEnd ) )
2988 ::canvas::tools::getRenderStateTransform( aMatrix,
2991 ActionRenderer aRenderer( aMatrix );
2993 return forSubsetRange( aRenderer,
3000 catch( uno::Exception& )
3009 sal_Int32 nEndIndex )
const
3011 SAL_INFO(
"cppcanvas.emf",
"::cppcanvas::internal::ImplRenderer::getSubsetArea()" );
3013 ActionVector::const_iterator aRangeBegin;
3014 ActionVector::const_iterator aRangeEnd;
3017 aRangeBegin, aRangeEnd ) )
3018 return ::basegfx::B2DRange();
3032 ::canvas::tools::getRenderStateTransform( aMatrix,
3035 AreaQuery aQuery( aMatrix );
3036 forSubsetRange( aQuery,
3043 return aQuery.getBounds();
3048 SAL_INFO(
"cppcanvas.emf",
"::cppcanvas::internal::ImplRenderer::draw()" );
3051 ::canvas::tools::getRenderStateTransform( aMatrix,
3056 return std::for_each(
maActions.begin(),
maActions.end(), ActionRenderer( aMatrix ) ).result();
3058 catch( uno::Exception& )
PropertiesInfo aProperties
bool Crop(const tools::Rectangle &rRectPixel)
const Size & GetSizePixel() const
bool Crop(const tools::Rectangle &rRectPixel)
Bitmap CreateMask(const Color &rTransColor) const
Size GetSizePixel() const
sal_uInt8 GetLuminance() const
sal_uInt8 GetBlue() const
void SetGreen(sal_uInt8 nGreen)
void SetRed(sal_uInt8 nRed)
sal_uInt8 GetAlpha() const
sal_uInt8 GetGreen() const
void SetAlpha(sal_uInt8 nAlpha)
void SetBlue(sal_uInt8 nBlue)
void AddGradientActions(tools::Rectangle const &rRect, GDIMetaFile &rMetaFile)
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
void adjust(size_t nIndex, sal_Int32 nDiff)
void push_back(sal_Int32 nUnit)
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
LineStyle GetStyle() const
basegfx::B2DLineJoin GetLineJoin() const
double GetDistance() const
sal_uInt16 GetDashCount() const
double GetDashLen() const
css::drawing::LineCap GetLineCap() const
sal_uInt16 GetDotCount() const
sal_uInt32 GetWidth() const
sal_Int32 GetIndex() const
const OUString & GetText() const
const Point & GetPoint() const
const Point & GetPoint() const
const OUString & GetText() const
sal_Int32 GetIndex() const
sal_Int32 GetIndex() const
const KernArray & GetDXArray() const
const OUString & GetText() const
const Point & GetPoint() const
const std::vector< sal_Bool > & GetKashidaArray() const
const Point & GetStartPoint() const
tools::Long GetWidth() const
DrawTextFlags GetStyle() const
const tools::Rectangle & GetRect() const
const OUString & GetText() const
basegfx::B2DHomMatrix GetViewTransformation() const
const vcl::Font & GetFont() const
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
void AddHatchActions(const tools::PolyPolygon &rPolyPoly, const Hatch &rHatch, GDIMetaFile &rMtf)
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
void AddTextRectActions(const tools::Rectangle &rRect, const OUString &rOrigStr, DrawTextFlags nStyle, GDIMetaFile &rMtf)
tools::Long GetTextArray(const OUString &rStr, KernArray *pDXAry, sal_Int32 nIndex=0, sal_Int32 nLen=-1, bool bCaret=false, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
FontMetric GetFontMetric() const
const MapMode & GetMapMode() const
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
LanguageType GetDigitLanguage() const
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
SvStream & ReadInt32(sal_Int32 &rInt32)
void getTransform(Transform &) const
void getGraphic(Graphic &) const
double getTransparency() const
FillType getFillType() const
void getPath(tools::PolyPolygon &) const
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
void rotate(double fRadiant)
void translate(double fX, double fY)
double get(sal_uInt16 nRow, sal_uInt16 nColumn) const
void scale(double fX, double fY)
void transform(const basegfx::B2DHomMatrix &rMatrix)
void transform(const basegfx::B2DHomMatrix &rMatrix)
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
void expand(const Tuple2D< TYPE > &rTuple)
const css::rendering::RenderState & getRenderState() const
virtual bool drawSubset(sal_Int32 nStartIndex, sal_Int32 nEndIndex) const override
Render subset of metafile to given canvas.
static void skipContent(GDIMetaFile &rMtf, const char *pCommentString, sal_Int32 &io_rCurrActionIndex)
virtual bool draw() const override
Render to parent canvas.
bool getSubsetIndices(sal_Int32 &io_rStartIndex, sal_Int32 &io_rEndIndex, ActionVector::const_iterator &o_rRangeBegin, ActionVector::const_iterator &o_rRangeEnd) const
ImplRenderer(const CanvasSharedPtr &rCanvas, const GDIMetaFile &rMtf, const Parameters &rParms)
void createGradientAction(const ::tools::PolyPolygon &rPoly, const ::Gradient &rGradient, const ActionFactoryParameters &rParms, bool bIsPolygonRectangle, bool bSubsettableActions)
void createTextAction(const ::Point &rStartPoint, const OUString &rString, int nIndex, int nLength, KernArraySpan pCharWidths, o3tl::span< const sal_Bool > pKashidaArray, const ActionFactoryParameters &rParms, bool bSubsettable)
bool createFillAndStroke(const ::basegfx::B2DPolyPolygon &rPolyPoly, const ActionFactoryParameters &rParms)
static css::uno::Reference< css::rendering::XCanvasFont > createFont(double &o_rFontRotation, const vcl::Font &rFont, const ActionFactoryParameters &rParms)
static bool isActionContained(GDIMetaFile &rMtf, const char *pCommentString, MetaActionType nType)
static void updateClipping(const ::basegfx::B2DPolyPolygon &rClipPoly, const ActionFactoryParameters &rParms, bool bIntersect)
virtual ~ImplRenderer() override
virtual ::basegfx::B2DRange getSubsetArea(sal_Int32 nStartIndex, sal_Int32 nEndIndex) const override
Query bounding box of metafile subset.
void createActions(GDIMetaFile &rMtf, const ActionFactoryParameters &rParms, bool bSubsettableActions)
void pushState(vcl::PushFlags nFlags)
std::vector< OutDevState > m_aStates
tools::Long GetFontHeight() const
void SetAverageFontWidth(tools::Long nWidth)
const OUString & GetStyleName() const
FontStrikeout GetStrikeout() const
FontLineStyle GetOverline() const
FontRelief GetRelief() const
FontEmphasisMark GetEmphasisMark() const
const OUString & GetFamilyName() const
const Size & GetFontSize() const
LanguageType GetLanguage() const
FontLineStyle GetUnderline() const
rtl_TextEncoding GetCharSet() const
bool IsWordLineMode() const
Degree10 GetOrientation() const
tools::Long GetAverageFontWidth() const
basegfx::B2DPolyPolygon GetAsB2DPolyPolygon() const
bool HasPolyPolygonOrB2DPolyPolygon() const
tools::Rectangle GetBoundRect() const
constexpr ::Color COL_WHITE(0xFF, 0xFF, 0xFF)
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
constexpr ::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
#define DBG_TESTSOLARMUTEX()
#define ENSURE_OR_RETURN_FALSE(c, m)
#define ENSURE_OR_THROW(c, m)
#define DBG_UNHANDLED_EXCEPTION(...)
Reference< XSingleServiceFactory > xFactory
::basegfx::B2DRange maBounds
::basegfx::B2DHomMatrix maTransformation
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
std::unique_ptr< sal_Int32[]> pData
ODFGradientInfo createRadialODFGradientInfo(const B2DRange &rTargetArea, const B2DVector &rOffset, sal_uInt32 nRequestedSteps, double fBorder)
double getLength(const B2DPolygon &rCandidate)
ODFGradientInfo createAxialODFGradientInfo(const B2DRange &rTargetArea, sal_uInt32 nRequestedSteps, double fBorder, double fAngle)
B2DPolyPolygon clipPolyPolygonOnPolyPolygon(const B2DPolyPolygon &rCandidate, const B2DPolyPolygon &rClip, bool bInside, bool bStroke, size_t *pPointLimit)
ODFGradientInfo createLinearODFGradientInfo(const B2DRange &rTargetArea, sal_uInt32 nRequestedSteps, double fBorder, double fAngle)
ODFGradientInfo createSquareODFGradientInfo(const B2DRange &rTargetArea, const B2DVector &rOffset, sal_uInt32 nRequestedSteps, double fBorder, double fAngle)
ODFGradientInfo createEllipticalODFGradientInfo(const B2DRange &rTargetArea, const B2DVector &rOffset, sal_uInt32 nRequestedSteps, double fBorder, double fAngle)
ODFGradientInfo createRectangularODFGradientInfo(const B2DRange &rTargetArea, const B2DVector &rOffset, sal_uInt32 nRequestedSteps, double fBorder, double fAngle)
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
std::shared_ptr< Action > createBitmapAction(const ::BitmapEx &, const ::basegfx::B2DPoint &rDstPoint, const CanvasSharedPtr &, const OutDevState &)
Unscaled bitmap action, only references destination point.
std::shared_ptr< Action > createLineAction(const ::basegfx::B2DPoint &, const ::basegfx::B2DPoint &, const CanvasSharedPtr &, const OutDevState &)
Plain hair line from point 1 to point 2.
std::shared_ptr< Action > createPointAction(const ::basegfx::B2DPoint &, const CanvasSharedPtr &, const OutDevState &)
Point in current color.
std::shared_ptr< Action > createLinePolyPolyAction(const ::basegfx::B2DPolyPolygon &, const CanvasSharedPtr &, const OutDevState &)
Create line polygon (always stroked, not filled)
std::shared_ptr< Action > createPolyPolyAction(const ::basegfx::B2DPolyPolygon &, const CanvasSharedPtr &, const OutDevState &)
Create polygon, fill/stroke according to state.
std::shared_ptr< Action > createTextAction(const ::Point &rStartPoint, const ::Size &rReliefOffset, const ::Color &rReliefColor, const ::Size &rShadowOffset, const ::Color &rShadowColor, const ::Color &rTextFillColor, const OUString &rText, sal_Int32 nStartPos, sal_Int32 nLen, KernArraySpan pDXArray, o3tl::span< const sal_Bool > pKashidaArray, VirtualDevice &rVDev, const CanvasSharedPtr &rCanvas, const OutDevState &rState, const Renderer::Parameters &rParms, bool bSubsettable)
Create text action, optionally shadow/relief effect.
std::shared_ptr< Action > createTransparencyGroupAction(std::unique_ptr< GDIMetaFile > &&rGroupMtf, std::optional< Gradient > &&rAlphaGradient, const ::basegfx::B2DPoint &rDstPoint, const ::basegfx::B2DVector &rDstSize, const CanvasSharedPtr &rCanvas, const OutDevState &rState)
Create new transparency group action.
std::shared_ptr< Canvas > CanvasSharedPtr
vcl::Font GetFont(vcl::Font const &rFont, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
Parameters for the Renderer.
::std::optional< IntSRGBA > maFillColor
Optionally forces the fill color attribute for all actions.
::std::optional< IntSRGBA > maTextColor
Optionally forces the text color attribute for all actions.
::std::optional< IntSRGBA > maLineColor
Optionally forces the line color attribute for all actions.
::std::optional< OUString > maFontName
Optionally forces the given fontname for all text actions.
::std::optional< sal_Int8 > maFontWeight
Optionally forces the given font weight for all text actions.
::std::optional< bool > maFontUnderline
Optionally forces underlining for all text actions.
::std::optional< sal_Int8 > maFontLetterForm
Optionally forces the given font letter form (italics etc.) for all text actions.
Common parameters when creating actions.
const Renderer::Parameters & mrParms
const CanvasSharedPtr & mrCanvas
VectorOfOutDevStates & mrStates
sal_Int32 & mrCurrActionIndex
FontEmphasisMark textEmphasisMark
::basegfx::B2DHomMatrix transform
FontRelief textReliefStyle
css::uno::Sequence< double > lineColor
bool isTextWordUnderlineSet
::basegfx::B2DHomMatrix mapModeTransform
TextAlign textReferencePoint
css::uno::Reference< css::rendering::XCanvasFont > xFont
Current font.
css::uno::Sequence< double > textLineColor
bool isTextOutlineModeSet
css::uno::Sequence< double > fillColor
bool isTextOverlineColorSet
bool isTextEffectShadowSet
css::uno::Sequence< double > textFillColor
sal_Int8 textUnderlineStyle
css::uno::Sequence< double > textOverlineColor
::tools::Rectangle clipRect
sal_Int8 textStrikeoutStyle
sal_Int8 textOverlineStyle
::basegfx::B2DPolyPolygon clip
css::uno::Reference< css::rendering::XPolyPolygon2D > xClipPoly
css::uno::Sequence< double > textColor
VCL_DLLPUBLIC sal_UCS4 GetLocalizedChar(sal_UCS4, LanguageType)
o3tl::enumarray< SvxBoxItemLine, sal_uInt16 > aDistance