30 #include <osl/diagnose.h>
31 #include <rtl/math.hxx>
32 #include <com/sun/star/i18n/BreakIterator.hpp>
33 #include <com/sun/star/i18n/CharacterClassification.hpp>
34 #include <com/sun/star/i18n/ScriptType.hpp>
35 #include <com/sun/star/i18n/DirectionProperty.hpp>
38 #include <string_view>
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 for(
int i=0;
i< elem.
Text.getLength();
i++)
132 OUString strToken= str.copy(
i,1) ;
133 if( strSpace == strToken || strNbSpace == strToken )
135 aProps[
"text:c" ] =
"1";
141 if( tabSpace == strToken )
153 auto this_it = elem.
Children.begin();
154 while( this_it != elem.
Children.end() && this_it->get() != &elem )
156 (*this_it)->visitedBy( *
this, this_it );
170 const char* pTagType =
"text:p";
175 auto this_it = elem.
Children.begin();
176 while( this_it != elem.
Children.end() && this_it->get() != &elem )
178 (*this_it)->visitedBy( *
this, this_it );
191 rProps[
"draw:z-index" ] = OUString::number( rElem.
ZOrder );
209 OUStringBuffer
aBuf(256);
223 mat.
scale(scale, scale);
225 aBuf.append(
"matrix(");
226 aBuf.append(mat.
get(0, 0));
228 aBuf.append(mat.
get(1, 0));
230 aBuf.append(mat.
get(0, 1));
232 aBuf.append(mat.
get(1, 1));
234 aBuf.append(mat.
get(0, 2));
236 aBuf.append(mat.
get(1, 2));
239 rProps[
"draw:transform"] = aBuf.makeStringAndClear();
255 auto this_it = elem.
Children.begin();
256 while( this_it != elem.
Children.end() && this_it->get() != &elem )
258 (*this_it)->visitedBy( *
this, this_it );
281 for ( sal_uInt32 j = 0; j< b2dPolygon.
count(); j++ )
322 OUStringBuffer
aBuf( 64 );
323 aBuf.append(
"0 0 " );
327 aProps[
"svg:viewBox" ] = aBuf.makeStringAndClear();
354 auto this_it = elem.
Children.begin();
355 while( this_it != elem.
Children.end() && this_it->get() != &elem )
357 (*this_it)->visitedBy( *
this, this_it );
370 auto this_it = elem.
Children.begin();
371 while( this_it != elem.
Children.end() && this_it->get() != &elem )
373 (*this_it)->visitedBy( *
this, this_it );
411 auto next_it = elemIt;
476 std::list< std::unique_ptr<Element> >::iterator page_element, next_page_element;
477 next_page_element = elem.
Children.begin();
478 double fCurLineHeight = 0.0;
479 int nCurLineElements = 0;
480 double line_left = elem.
w, line_right = 0.0;
481 double column_width = elem.
w*0.75;
483 while( next_page_element != elem.
Children.end() )
485 page_element = next_page_element++;
489 pCurPara = pPagePara;
491 fCurLineHeight = 0.0;
492 nCurLineElements = 0;
493 for(
const auto& rxChild : pCurPara->
Children )
498 fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pTestText->
h)/
double(nCurLineElements+1);
507 if( ! pDraw && pLink && ! pLink->
Children.empty() )
508 pDraw = dynamic_cast<DrawElement*>(pLink->
Children.front().get() );
513 bool bInsertToParagraph =
false;
515 if( pCurPara && pDraw->
y < pCurPara->
y + pCurPara->
h )
517 if( pDraw->
h < fCurLineHeight * 1.5 )
519 bInsertToParagraph =
true;
520 fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pDraw->
h)/
double(nCurLineElements+1);
527 else if( next_page_element != elem.
Children.end() )
533 if( pPara && ! pPara->
Children.empty() )
534 pText = dynamic_cast<TextElement*>(pPara->
Children.front().get());
537 pDraw->
h < pText->
h*1.5 &&
539 ( ( pDraw->
y >= pText->
y && pDraw->
y <= pText->
y+pText->
h ) ||
540 ( pDraw->
y+pDraw->
h >= pText->
y && pDraw->
y+pDraw->
h <= pText->
y+pText->
h )
544 bInsertToParagraph =
true;
545 fCurLineHeight = pDraw->
h;
546 nCurLineElements = 1;
547 line_left = pDraw->
x;
548 line_right = pDraw->
x + pDraw->
w;
556 if( ! bInsertToParagraph )
564 if( ! pText && pLink && ! pLink->
Children.empty() )
565 pText = dynamic_cast<TextElement*>(pLink->
Children.front().get());
569 static_cast<Element*>(pText);
573 if( nCurLineElements > 0 )
577 if( pGeo->
y > pCurPara->
y + pCurPara->
h + fCurLineHeight*0.5 )
579 else if( pGeo->
y > (pCurPara->
y+pCurPara->
h - fCurLineHeight*0.05) )
583 if( (line_right - line_left) < pCurPara->
w*0.75 )
586 else if( (line_right - line_left) < column_width*0.75 )
598 fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pGeo->
h)/
double(nCurLineElements+1);
600 if( pGeo->
x < line_left )
602 if( pGeo->
x+pGeo->
w > line_right )
603 line_right = pGeo->
x+pGeo->
w;
607 fCurLineHeight = pGeo->
h;
608 nCurLineElements = 1;
610 line_right = pGeo->
x + pGeo->
w;
622 page_element = elem.
Children.insert( page_element, std::unique_ptr<Element>(pCurPara) );
626 next_page_element = page_element;
627 ++ next_page_element;
629 Element* pCurEle = page_element->get();
631 OSL_ENSURE( !pText || pCurEle == pText || pCurEle == pLink,
"paragraph child list in disorder" );
642 for (sal_Int32
i = 0;
i != pTextElem->
Text.getLength(); ++
i) {
643 if (pTextElem->
Text[
i] !=
' ') {
663 OSL_FAIL(
"empty paragraph optimized" );
668 auto next = rParent.
Children.begin();
671 while( next != rParent.
Children.end() )
673 bool bConcat =
false;
679 bool isComplex =
false;
680 OUString str(pCur->
Text.toString());
681 for(
int i=0;
i< str.getLength();
i++)
684 if (nType == css::i18n::ScriptType::COMPLEX)
687 bool bPara = strspn(
"ParagraphElement",
typeid(rParent).
name());
689 if (bPara && pPara && isComplex)
712 str = pCur->
Text.toString();
713 for(
int i=0;
i< str.getLength();
i++)
716 if (nType == css::i18n::ScriptType::COMPLEX)
719 if (bPara && pPara && isComplex)
731 else if( dynamic_cast<HyperlinkElement*>(it->get()) )
753 aProps[
"style:family" ] =
"graphic";
754 aProps[
"style:parent-style-name" ] =
"standard";
764 aGCProps[
"draw:stroke" ] =
"solid";
772 aGCProps[
"draw:stroke" ] =
"dash";
773 aGCProps[
"draw:stroke-dash" ] =
787 aGCProps[
"draw:stroke" ] =
"none";
793 aGCProps[
"draw:fill" ] =
"solid";
800 aGCProps[
"draw:fill" ] =
"none";
805 aStyle.
SubStyles.push_back( &aSubStyle );
817 props[
"fo:font-size"] = aFSize;
818 props[
"style:font-size-asian"] = aFSize;
819 props[
"style:font-size-complex"] = aFSize;
826 aProps[
"style:family" ] =
"text";
831 aFontProps[
"fo:font-family" ] = rFont.
familyName;
832 aFontProps[
"style:font-family-complex" ] = rFont.
familyName;
837 aFontProps[
"fo:font-weight" ] =
"bold";
838 aFontProps[
"fo:font-weight-asian" ] =
"bold";
839 aFontProps[
"style:font-weight-complex" ] =
"bold";
844 aFontProps[
"fo:font-style" ] =
"italic";
845 aFontProps[
"fo:font-style-asian" ] =
"italic";
846 aFontProps[
"style:font-style-complex" ] =
"italic";
851 aFontProps[
"style:text-underline-style" ] =
"solid";
852 aFontProps[
"style:text-underline-width" ] =
"auto";
853 aFontProps[
"style:text-underline-color" ] =
"font-color";
858 aFontProps[
"style:text-outline" ] =
"true";
869 double fRotate, fShearX;
872 double textScale = 100 * aScale.
getX() / aScale.
getY();
873 if (((textScale >= 1) && (textScale <= 99)) ||
874 ((textScale >= 101) && (textScale <= 999)))
881 aStyle.
SubStyles.push_back( &aSubStyle );
889 aProps[
"style:family" ] =
"paragraph";
895 aParProps[
"fo:text-align"] =
"start";
897 aParProps[
"style:writing-mode"] =
"rl-tb";
899 aParProps[
"style:writing-mode"] =
"lr-tb";
903 aStyle.
SubStyles.push_back( &aSubStyle );
913 props1[
"style:family" ] =
"graphic";
914 props1[
"style:parent-style-name" ] =
"standard";
920 aGCProps[
"draw:stroke" ] =
"none";
921 aGCProps[
"draw:fill" ] =
"none";
922 aGCProps[
"draw:auto-grow-height" ] =
"true";
923 aGCProps[
"draw:auto-grow-width" ] =
"true";
924 aGCProps[
"draw:textarea-horizontal-align" ] =
"left";
925 aGCProps[
"draw:textarea-vertical-align" ] =
"top";
926 aGCProps[
"fo:min-height"] =
"0cm";
927 aGCProps[
"fo:min-width"] =
"0cm";
928 aGCProps[
"fo:padding-top" ] =
"0cm";
929 aGCProps[
"fo:padding-left" ] =
"0cm";
930 aGCProps[
"fo:padding-right" ] =
"0cm";
931 aGCProps[
"fo:padding-bottom" ] =
"0cm";
942 props2[
"style:family"] =
"paragraph";
974 for(
const auto& rxChild : elem.
Children )
993 left_margin = rtl_math_round( left_margin, 0, rtl_math_RoundingMode_Floor );
994 top_margin = rtl_math_round( top_margin, 0, rtl_math_RoundingMode_Floor );
996 right_margin = rtl_math_round( right_margin, right_margin >= 10 ? -1 : 0, rtl_math_RoundingMode_Floor );
997 bottom_margin = rtl_math_round( bottom_margin, bottom_margin >= 10 ? -1 : 0, rtl_math_RoundingMode_Floor );
1001 if( left_margin > page_width/2.0 - 10 )
1003 if( right_margin > page_width/2.0 - 10 )
1005 if( top_margin > page_height/2.0 - 10 )
1007 if( bottom_margin > page_height/2.0 - 10 )
1011 if( left_margin < 0 )
1013 if( right_margin < 0 )
1015 if( top_margin < 0 )
1017 if( bottom_margin < 0 )
1021 if( right_margin > left_margin*1.5 )
1022 right_margin = left_margin;
1032 aPageLayoutProps[
"fo:margin-top" ] =
unitMMString( top_margin );
1033 aPageLayoutProps[
"fo:margin-bottom" ] =
unitMMString( bottom_margin );
1034 aPageLayoutProps[
"fo:margin-left" ] =
unitMMString( left_margin );
1035 aPageLayoutProps[
"fo:margin-right" ] =
unitMMString( right_margin );
1036 aPageLayoutProps[
"fo:page-width" ] =
unitMMString( page_width );
1037 aPageLayoutProps[
"fo:page-height" ] =
unitMMString( page_height );
1038 aPageLayoutProps[
"style:print-orientation" ]= elem.
w < elem.
h ? std::u16string_view(
u"portrait") : std::u16string_view(
u"landscape");
1039 aPageLayoutProps[
"style:writing-mode" ]=
"lr-tb";
1048 aPageProps[
"style:page-layout-name" ] = aMasterPageLayoutName;
css::rendering::ARGBColor LineColor
std::unordered_map< OUString, OUString > PropertyMap
css::uno::Reference< css::uno::XComponentContext > m_xContext
PDFIProcessor & m_rProcessor
EmitContext & m_rEmitContext
basegfx::B2DPolyPolygon PolyPoly
basegfx::B2DPoint getNextControlPoint(sal_uInt32 nIndex) const
OUString unitMMString(double fMM)
static OUString mirrorString(const OUString &i_rInString)
OUString getPercentString(double value)
#define PDFI_OUTDEV_RESOLUTION
double convmm2Px(double fMM)
static void fillFrameProps(DrawElement &rElem, PropertyMap &rProps, const EmitContext &rEmitContext, bool bWasTransformed)
std::vector< Style * > SubStyles
void applyToChildren(ElementTreeVisitor &)
Apply visitor to all children.
static ParagraphElement * createParagraphElement(Element *pParent)
virtual void beginTag(const char *pTag, const PropertyMap &rProperties)=0
Open up a tag with the given properties.
OUString convertPixelToUnitString(double fPix)
void setB2DPolygon(sal_uInt32 nIndex, const B2DPolygon &rPolygon)
sal_Int32 impl_getStyleId(const Style &rStyle, bool bSubStyle)
const FontAttributes & getFont(sal_Int32 nFontId) const
PDFIProcessor & m_rProcessor
StyleContainer & m_rStyleContainer
virtual void visit(HyperlinkElement &, const std::list< std::unique_ptr< Element > >::const_iterator &) override
double get(sal_uInt16 nRow, sal_uInt16 nColumn) const
static bool notTransformed(const GraphicsContext &GC)
B2DPolygon const & getB2DPolygon(sal_uInt32 nIndex) const
basegfx::B2DPolyPolygon Clip
static bool isSpaces(TextElement *pTextElem)
PDFIProcessor & rProcessor
bool isPrevControlPointUsed(sal_uInt32 nIndex) const
void setB2DPoint(sal_uInt32 nIndex, const basegfx::B2DPoint &rValue)
css::rendering::ARGBColor FillColor
const GraphicsContext & getGraphicsContext(sal_Int32 nGCId) const
double convPx2mm(double fPix)
std::vector< double > DashArray
const css::uno::Reference< css::i18n::XBreakIterator > & GetBreakIterator()
sal_Int32 getGCId(const GraphicsContext &rGC)
css::uno::Reference< css::i18n::XCharacterClassification > mxCharClass
virtual void visit(HyperlinkElement &, const std::list< std::unique_ptr< Element > >::const_iterator &) override
css::uno::Reference< css::task::XStatusIndicator > xStatusIndicator
std::list< std::unique_ptr< Element > > Children
OUString GetLineJoinString() const
bool decompose(B2DTuple &rScale, B2DTuple &rTranslate, double &rRotate, double &rShearX) const
double GetAverageTransformationScale(const basegfx::B2DHomMatrix &matrix)
basegfx::B2DHomMatrix Transformation
void resolveFontStyles(PDFIProcessor const &rProc)
OUString getStyleName(sal_Int32 nStyle) const
OUString getColorString(const css::rendering::ARGBColor &)
Convert color to "#FEFEFE" color notation.
basegfx::B2DPoint getPrevControlPoint(sal_uInt32 nIndex) const
void scale(double fX, double fY)
void setNextControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint &rValue)
void FillDashStyleProps(PropertyMap &props, const std::vector< double > &dashArray, double scale)
const css::uno::Reference< css::i18n::XCharacterClassification > & GetCharacterClassification()
sal_Int32 getStandardStyleId(std::string_view rFamily)
exports com.sun.star. style
css::uno::Reference< css::i18n::XBreakIterator > mxBreakIter
const css::uno::Reference< css::task::XStatusIndicator > & getStatusIndicator() const
bool isNextControlPointUsed(sal_uInt32 nIndex) const
void updateGeometryWith(const Element *pMergeFrom)
Union element geometry with given element.
double convPx2mmPrec2(double fPix)
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 ...
sal_Int32 getStyleId(const Style &rStyle)
static void sortElements(Element *pElement)
void translate(double fX, double fY)
css::uno::Reference< css::uno::XComponentContext > m_xContext
void optimizeTextElements(Element &rParent)
OUString exportToSvgD(const B2DPolyPolygon &rPolyPoly, bool bUseRelativeCoordinates, bool bDetectQuadraticBeziers, bool bHandleRelativeNextPointCompatible, bool bOOXMLMotionPath=false)
static void SetFontsizeProperties(PropertyMap &props, double fontSize)
virtual void visit(HyperlinkElement &, const std::list< std::unique_ptr< Element > >::const_iterator &) override
void writeBase64EncodedStream(ImageId nImageId, EmitContext &rContext)
OUString GetLineCapString() const
virtual void write(const OUString &rString)=0
Write PCTEXT as-is to output.
const bool m_bWriteDrawDocument
writes Impress doc when false
void setPrevControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint &rValue)
virtual void endTag(const char *pTag)=0
Close previously opened tag.
basegfx::B2DPoint const & getB2DPoint(sal_uInt32 nIndex) const