29#include <osl/diagnose.h>
30#include <rtl/math.hxx>
31#include <com/sun/star/i18n/BreakIterator.hpp>
32#include <com/sun/star/i18n/CharacterClassification.hpp>
33#include <com/sun/star/i18n/ScriptType.hpp>
34#include <com/sun/star/i18n/DirectionProperty.hpp>
63 mxCharClass = CharacterClassification::create(xContext);
73 const char* pType =
dynamic_cast<DrawElement*
>(elem.
Children.front().get()) ?
"draw:a" :
"text:a";
76 aProps[
"xlink:type" ] =
"simple";
77 aProps[
"xlink:href" ] = elem.
URI;
78 aProps[
"office:target-frame-name" ] =
"_blank";
79 aProps[
"xlink:show" ] =
"new";
82 auto this_it = elem.
Children.begin();
83 while( this_it != elem.
Children.end() && this_it->get() != &elem )
85 (*this_it)->visitedBy( *
this, this_it );
93 if( elem.
Text.isEmpty() )
96 OUString strSpace(
u' ');
97 OUString strNbSpace(
u'\x00A0');
98 OUString tabSpace(
u'\x0009');
102 aProps[ OUString(
"text:style-name" ) ] =
106 OUString str(elem.
Text.toString());
113 for(
int i=1;
i< elem.
Text.getLength();
i++)
115 css::i18n::DirectionProperty
nType =
static_cast<css::i18n::DirectionProperty
>(xCC->getCharacterDirection( str,
i ));
116 if (
nType == css::i18n::DirectionProperty_RIGHT_TO_LEFT ||
117 nType == css::i18n::DirectionProperty_RIGHT_TO_LEFT_ARABIC ||
118 nType == css::i18n::DirectionProperty_RIGHT_TO_LEFT_EMBEDDING ||
119 nType == css::i18n::DirectionProperty_RIGHT_TO_LEFT_OVERRIDE
130 str = ::comphelper::string::reverseCodePoints(str);
136 for(
int i=0;
i< elem.
Text.getLength();
i++)
138 OUString strToken= str.copy(
i,1) ;
139 if( strSpace == strToken || strNbSpace == strToken )
141 aProps[
"text:c" ] =
"1";
147 if( tabSpace == strToken )
159 auto this_it = elem.
Children.begin();
160 while( this_it != elem.
Children.end() && this_it->get() != &elem )
162 (*this_it)->visitedBy( *
this, this_it );
176 const char* pTagType =
"text:p";
181 auto this_it = elem.
Children.begin();
182 while( this_it != elem.
Children.end() && this_it->get() != &elem )
184 (*this_it)->visitedBy( *
this, this_it );
197 static constexpr OUStringLiteral sDrawZIndex =
u"draw:z-index";
198 static constexpr OUStringLiteral sDrawStyleName =
u"draw:style-name";
199 static constexpr OUStringLiteral sDrawTextStyleName =
u"draw:text-style-name";
200 static constexpr OUStringLiteral sSvgX =
u"svg:x";
201 static constexpr OUStringLiteral sSvgY =
u"svg:y";
202 static constexpr OUStringLiteral sSvgWidth =
u"svg:width";
203 static constexpr OUStringLiteral sSvgHeight =
u"svg:height";
204 static constexpr OUStringLiteral sDrawTransform =
u"draw:transform";
206 rProps[ sDrawZIndex ] = OUString::number( rElem.
ZOrder );
238 rProps[ sDrawTransform ] =
239 OUString::Concat(
"matrix(")
240 + OUString::number(mat.
get(0, 0))
242 + OUString::number(mat.
get(1, 0))
244 + OUString::number(mat.
get(0, 1))
246 + OUString::number(mat.
get(1, 1))
248 + OUString::number(mat.
get(0, 2))
250 + OUString::number(mat.
get(1, 2))
268 auto this_it = elem.
Children.begin();
269 while( this_it != elem.
Children.end() && this_it->get() != &elem )
271 (*this_it)->visitedBy( *
this, this_it );
294 for ( sal_uInt32 j = 0; j< b2dPolygon.
count(); j++ )
335 aProps[
"svg:viewBox" ] =
366 auto this_it = elem.
Children.begin();
367 while( this_it != elem.
Children.end() && this_it->get() != &elem )
369 (*this_it)->visitedBy( *
this, this_it );
382 auto this_it = elem.
Children.begin();
383 while( this_it != elem.
Children.end() && this_it->get() != &elem )
385 (*this_it)->visitedBy( *
this, this_it );
423 auto next_it = elemIt;
488 std::list< std::unique_ptr<Element> >::iterator page_element, next_page_element;
489 next_page_element = elem.
Children.begin();
490 double fCurLineHeight = 0.0;
491 int nCurLineElements = 0;
492 double line_left = elem.
w, line_right = 0.0;
493 double column_width = elem.
w*0.75;
495 while( next_page_element != elem.
Children.end() )
497 page_element = next_page_element++;
501 pCurPara = pPagePara;
503 fCurLineHeight = 0.0;
504 nCurLineElements = 0;
505 for(
const auto& rxChild : pCurPara->
Children )
510 fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pTestText->
h)/
double(nCurLineElements+1);
519 if( ! pDraw &&
pLink && !
pLink->Children.empty() )
525 bool bInsertToParagraph =
false;
527 if( pCurPara && pDraw->
y < pCurPara->
y + pCurPara->
h )
529 if( pDraw->
h < fCurLineHeight * 1.5 )
531 bInsertToParagraph =
true;
532 fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pDraw->
h)/
double(nCurLineElements+1);
539 else if( next_page_element != elem.
Children.end() )
545 if( pPara && ! pPara->
Children.empty() )
546 pText = pPara->
Children.front()->dynCastAsTextElement();
549 pDraw->
h < pText->
h*1.5 &&
551 ( ( pDraw->
y >= pText->
y && pDraw->
y <= pText->
y+pText->
h ) ||
552 ( pDraw->
y+pDraw->
h >= pText->
y && pDraw->
y+pDraw->
h <= pText->
y+pText->
h )
556 bInsertToParagraph =
true;
557 fCurLineHeight = pDraw->
h;
558 nCurLineElements = 1;
559 line_left = pDraw->
x;
560 line_right = pDraw->
x + pDraw->
w;
568 if( ! bInsertToParagraph )
576 if( ! pText &&
pLink && !
pLink->Children.empty() )
577 pText =
pLink->Children.front()->dynCastAsTextElement();
585 if( nCurLineElements > 0 )
589 if( pGeo->
y > pCurPara->
y + pCurPara->
h + fCurLineHeight*0.5 )
591 else if( pGeo->
y > (pCurPara->
y+pCurPara->
h - fCurLineHeight*0.05) )
595 if( (line_right - line_left) < pCurPara->
w*0.75 )
598 else if( (line_right - line_left) < column_width*0.75 )
610 fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pGeo->
h)/
double(nCurLineElements+1);
612 if( pGeo->
x < line_left )
614 if( pGeo->
x+pGeo->
w > line_right )
615 line_right = pGeo->
x+pGeo->
w;
619 fCurLineHeight = pGeo->
h;
620 nCurLineElements = 1;
622 line_right = pGeo->
x + pGeo->
w;
634 page_element = elem.
Children.insert( page_element, std::unique_ptr<Element>(pCurPara) );
638 next_page_element = page_element;
639 ++ next_page_element;
641 Element* pCurEle = page_element->get();
643 OSL_ENSURE( !pText || pCurEle == pText || pCurEle ==
pLink,
"paragraph child list in disorder" );
654 for (sal_Int32
i = 0;
i != pTextElem->
Text.getLength(); ++
i) {
655 if (pTextElem->
Text[
i] !=
' ') {
666 OSL_FAIL(
"empty paragraph optimized" );
671 auto next = rParent.
Children.begin();
674 while( next != rParent.
Children.end() )
676 bool bConcat =
false;
683 bool bPara = strspn(
"ParagraphElement",
typeid(rParent).
name());
704 if (pPara && pPara->
bRtl)
709 bool bNeedReverse=
false;
710 str = pNext->
Text.toString();
711 for (sal_Int32
i=0;
i < str.getLength();
i++)
716 pCur->
Text.append(OUStringChar(str[
i]));
720 tempStr = ::comphelper::string::reverseCodePoints(tempStr);
721 pCur->
Text.append(tempStr);
724 bNeedReverse =
false;
728 tempStr += OUStringChar(str[
i]);
735 tempStr = ::comphelper::string::reverseCodePoints(tempStr);
736 pCur->
Text.append(tempStr);
740 pCur->
Text.append(tempStr);
783 aProps[
"style:family" ] =
"graphic";
784 aProps[
"style:parent-style-name" ] =
"standard";
794 aGCProps[
"draw:stroke" ] =
"solid";
802 aGCProps[
"draw:stroke" ] =
"dash";
803 aGCProps[
"draw:stroke-dash" ] =
817 aGCProps[
"draw:stroke" ] =
"none";
823 aGCProps[
"draw:fill" ] =
"solid";
830 aGCProps[
"draw:fill" ] =
"none";
835 aStyle.
SubStyles.push_back( &aSubStyle );
847 props[
"fo:font-size"] = aFSize;
848 props[
"style:font-size-asian"] = aFSize;
849 props[
"style:font-size-complex"] = aFSize;
856 aProps[
"style:family" ] =
"text";
863 aFontProps[
"fo:font-family" ] = rFont.
familyName;
864 aFontProps[
"style:font-family-asian" ] = rFont.
familyName;
865 aFontProps[
"style:font-family-complex" ] = rFont.
familyName;
868 aFontProps[
"fo:font-weight" ] = rFont.
fontWeight;
869 aFontProps[
"style:font-weight-asian" ] = rFont.
fontWeight;
870 aFontProps[
"style:font-weight-complex" ] = rFont.
fontWeight;
875 aFontProps[
"fo:font-style" ] =
"italic";
876 aFontProps[
"style:font-style-asian" ] =
"italic";
877 aFontProps[
"style:font-style-complex" ] =
"italic";
883 aFontProps[
"style:text-underline-style" ] =
"solid";
884 aFontProps[
"style:text-underline-width" ] =
"auto";
885 aFontProps[
"style:text-underline-color" ] =
"font-color";
890 aFontProps[
"style:text-outline" ] =
"true";
900 double fRotate, fShearX;
903 double textScale = 100 * aScale.
getX() / aScale.
getY();
904 if (((textScale >= 1) && (textScale <= 99)) ||
905 ((textScale >= 101) && (textScale <= 999)))
912 aStyle.
SubStyles.push_back( &aSubStyle );
920 aProps[
"style:family" ] =
"paragraph";
926 aParProps[
"fo:text-align"] =
"start";
928 aParProps[
"style:writing-mode"] =
"rl-tb";
930 aParProps[
"style:writing-mode"] =
"lr-tb";
934 aStyle.
SubStyles.push_back( &aSubStyle );
944 props1[
"style:family" ] =
"graphic";
945 props1[
"style:parent-style-name" ] =
"standard";
951 aGCProps[
"draw:stroke" ] =
"none";
952 aGCProps[
"draw:fill" ] =
"none";
953 aGCProps[
"draw:auto-grow-height" ] =
"true";
954 aGCProps[
"draw:auto-grow-width" ] =
"true";
955 aGCProps[
"draw:textarea-horizontal-align" ] =
"left";
956 aGCProps[
"draw:textarea-vertical-align" ] =
"top";
957 aGCProps[
"fo:min-height"] =
"0cm";
958 aGCProps[
"fo:min-width"] =
"0cm";
959 aGCProps[
"fo:padding-top" ] =
"0cm";
960 aGCProps[
"fo:padding-left" ] =
"0cm";
961 aGCProps[
"fo:padding-right" ] =
"0cm";
962 aGCProps[
"fo:padding-bottom" ] =
"0cm";
973 props2[
"style:family"] =
"paragraph";
1005 for(
const auto& rxChild : elem.
Children )
1024 left_margin = rtl_math_round( left_margin, 0, rtl_math_RoundingMode_Floor );
1025 top_margin = rtl_math_round( top_margin, 0, rtl_math_RoundingMode_Floor );
1027 right_margin = rtl_math_round( right_margin, right_margin >= 10 ? -1 : 0, rtl_math_RoundingMode_Floor );
1028 bottom_margin = rtl_math_round( bottom_margin, bottom_margin >= 10 ? -1 : 0, rtl_math_RoundingMode_Floor );
1032 if( left_margin > page_width/2.0 - 10 )
1034 if( right_margin > page_width/2.0 - 10 )
1036 if( top_margin > page_height/2.0 - 10 )
1038 if( bottom_margin > page_height/2.0 - 10 )
1042 if( left_margin < 0 )
1044 if( right_margin < 0 )
1046 if( top_margin < 0 )
1048 if( bottom_margin < 0 )
1052 if( right_margin > left_margin*1.5 )
1053 right_margin = left_margin;
1063 aPageLayoutProps[
"fo:margin-top" ] =
unitMMString( top_margin );
1064 aPageLayoutProps[
"fo:margin-bottom" ] =
unitMMString( bottom_margin );
1065 aPageLayoutProps[
"fo:margin-left" ] =
unitMMString( left_margin );
1066 aPageLayoutProps[
"fo:margin-right" ] =
unitMMString( right_margin );
1067 aPageLayoutProps[
"fo:page-width" ] =
unitMMString( page_width );
1068 aPageLayoutProps[
"fo:page-height" ] =
unitMMString( page_height );
1069 aPageLayoutProps[
"style:print-orientation" ]= elem.
w < elem.
h ? std::u16string_view(
u"portrait") : std::u16string_view(
u"landscape");
1070 aPageLayoutProps[
"style:writing-mode" ]=
"lr-tb";
1079 aPageProps[
"style:page-layout-name" ] = aMasterPageLayoutName;
bool decompose(B2DTuple &rScale, B2DTuple &rTranslate, double &rRotate, double &rShearX) const
void translate(double fX, double fY)
double get(sal_uInt16 nRow, sal_uInt16 nColumn) const
void scale(double fX, double fY)
B2DPolygon const & getB2DPolygon(sal_uInt32 nIndex) const
void setB2DPolygon(sal_uInt32 nIndex, const B2DPolygon &rPolygon)
bool isPrevControlPointUsed(sal_uInt32 nIndex) const
void setB2DPoint(sal_uInt32 nIndex, const basegfx::B2DPoint &rValue)
bool isNextControlPointUsed(sal_uInt32 nIndex) const
void setPrevControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint &rValue)
basegfx::B2DPoint const & getB2DPoint(sal_uInt32 nIndex) const
void setNextControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint &rValue)
basegfx::B2DPoint getPrevControlPoint(sal_uInt32 nIndex) const
basegfx::B2DPoint getNextControlPoint(sal_uInt32 nIndex) const
css::uno::Reference< css::i18n::XCharacterClassification > mxCharClass
virtual void visit(HyperlinkElement &, const std::list< std::unique_ptr< Element > >::const_iterator &) override
const bool m_bWriteDrawDocument
writes Impress doc when false
const css::uno::Reference< css::i18n::XCharacterClassification > & GetCharacterClassification()
EmitContext & m_rEmitContext
static void fillFrameProps(DrawElement &rElem, PropertyMap &rProps, const EmitContext &rEmitContext, bool bWasTransformed)
StyleContainer & m_rStyleContainer
PDFIProcessor & m_rProcessor
virtual void visit(HyperlinkElement &, const std::list< std::unique_ptr< Element > >::const_iterator &) override
void optimizeTextElements(Element &rParent)
const css::uno::Reference< css::i18n::XBreakIterator > & GetBreakIterator()
virtual void visit(HyperlinkElement &, const std::list< std::unique_ptr< Element > >::const_iterator &) override
PDFIProcessor & m_rProcessor
css::uno::Reference< css::i18n::XBreakIterator > mxBreakIter
static ParagraphElement * createParagraphElement(Element *pParent)
void writeBase64EncodedStream(ImageId nImageId, EmitContext &rContext)
css::uno::Reference< css::uno::XComponentContext > m_xContext
const GraphicsContext & getGraphicsContext(sal_Int32 nGCId) const
const FontAttributes & getFont(sal_Int32 nFontId) const
const css::uno::Reference< css::task::XStatusIndicator > & getStatusIndicator() const
static void sortElements(Element *pElement)
static OUString SubstituteBidiMirrored(const OUString &rString)
sal_Int32 getGCId(const GraphicsContext &rGC)
OUString getStyleName(sal_Int32 nStyle) const
sal_Int32 impl_getStyleId(const Style &rStyle, bool bSubStyle)
sal_Int32 getStandardStyleId(std::string_view rFamily)
sal_Int32 getStyleId(const Style &rStyle)
virtual void write(const OUString &rString)=0
Write PCTEXT as-is to output.
virtual void endTag(const char *pTag)=0
Close previously opened tag.
virtual void beginTag(const char *pTag, const PropertyMap &rProperties)=0
Open up a tag with the given properties.
#define SAL_INFO(area, stream)
OUString exportToSvgD(const B2DPolyPolygon &rPolyPoly, bool bUseRelativeCoordinates, bool bDetectQuadraticBeziers, bool bHandleRelativeNextPointCompatible, bool bOOXMLMotionPath=false)
OUString convertPixelToUnitString(double fPix)
OUString getColorString(const css::rendering::ARGBColor &)
Convert color to "#FEFEFE" color notation.
double convmm2Px(double fMM)
static bool isSpaces(TextElement *pTextElem)
double convPx2mm(double fPix)
OUString getPercentString(double value)
double GetAverageTransformationScale(const basegfx::B2DHomMatrix &matrix)
OUString unitMMString(double fMM)
std::unordered_map< OUString, OUString > PropertyMap
double convPx2mmPrec2(double fPix)
round to 2 decimal places
static void SetFontsizeProperties(PropertyMap &props, double fontSize)
bool isComplex(const css::uno::Reference< css::i18n::XBreakIterator > &rBreakIterator, TextElement *const pTextElem)
void FillDashStyleProps(PropertyMap &props, const std::vector< double > &dashArray, double scale)
#define PDFI_OUTDEV_RESOLUTION
static void setParent(std::list< std::unique_ptr< Element > >::iterator const &el, Element *pNewParent)
el must be a valid dereferenceable iterator of el->Parent->Children pNewParent must not be NULL
std::list< std::unique_ptr< Element > > Children
void applyToChildren(ElementTreeVisitor &)
Apply visitor to all children.
void updateGeometryWith(const Element *pMergeFrom)
Union element geometry with given element.
css::uno::Reference< css::uno::XComponentContext > m_xContext
PDFIProcessor & rProcessor
css::uno::Reference< css::task::XStatusIndicator > xStatusIndicator
css::rendering::ARGBColor FillColor
css::rendering::ARGBColor LineColor
basegfx::B2DHomMatrix Transformation
OUString GetLineCapString() const
OUString GetLineJoinString() const
std::vector< double > DashArray
basegfx::B2DPolyPolygon Clip
void resolveFontStyles(PDFIProcessor const &rProc)
basegfx::B2DPolyPolygon PolyPoly
std::vector< Style * > SubStyles
virtual const TextElement * dynCastAsTextElement() const override
To avoid some dynamic_cast cost.