sdext/source/pdfimport/inc/genericelements.hxx | 7 +++++++ sdext/source/pdfimport/tree/drawtreevisiting.cxx | 14 +++++++------- sdext/source/pdfimport/tree/genericelements.cxx | 14 +++++++------- sdext/source/pdfimport/tree/pdfiprocessor.cxx | 6 +++--- sdext/source/pdfimport/tree/writertreevisiting.cxx | 12 ++++++------ 5 files changed, 30 insertions(+), 23 deletions(-)
New commits: commit 3fe18ba1b0be041f66124324e96d9cb6d56ff5ce Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Wed Jun 29 20:49:53 2022 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Fri Jul 1 08:16:49 2022 +0200 tdf#137544 reduce cost of dynamic_cast casting to TextElement is very hot here Change-Id: I3195da6f09edb270eebdc6f38a1bbb2405b74de6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136659 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sdext/source/pdfimport/inc/genericelements.hxx b/sdext/source/pdfimport/inc/genericelements.hxx index 63325213f59a..1fec2e6f4042 100644 --- a/sdext/source/pdfimport/inc/genericelements.hxx +++ b/sdext/source/pdfimport/inc/genericelements.hxx @@ -92,6 +92,10 @@ namespace pdfi /// Union element geometry with given element void updateGeometryWith( const Element* pMergeFrom ); + /// To avoid some dynamic_cast cost + virtual const TextElement* dynCastAsTextElement() const { return nullptr; } + virtual TextElement* dynCastAsTextElement() { return nullptr; } + #if OSL_DEBUG_LEVEL > 0 // xxx refact TODO: move code to visitor virtual void emitStructure( int nLevel ); @@ -175,6 +179,9 @@ namespace pdfi public: virtual void visitedBy( ElementTreeVisitor&, const std::list< std::unique_ptr<Element> >::const_iterator& ) override; + virtual const TextElement* dynCastAsTextElement() const override { return this; } + virtual TextElement* dynCastAsTextElement() override { return this; } + OUStringBuffer Text; sal_Int32 FontId; }; diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.cxx b/sdext/source/pdfimport/tree/drawtreevisiting.cxx index ffc27c65f56c..dfdec02539db 100644 --- a/sdext/source/pdfimport/tree/drawtreevisiting.cxx +++ b/sdext/source/pdfimport/tree/drawtreevisiting.cxx @@ -492,7 +492,7 @@ void DrawXmlOptimizer::visit( PageElement& elem, const std::list< std::unique_pt nCurLineElements = 0; for( const auto& rxChild : pCurPara->Children ) { - TextElement* pTestText = dynamic_cast<TextElement*>(rxChild.get()); + TextElement* pTestText = rxChild->dynCastAsTextElement(); if( pTestText ) { fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pTestText->h)/double(nCurLineElements+1); @@ -526,12 +526,12 @@ void DrawXmlOptimizer::visit( PageElement& elem, const std::list< std::unique_pt // or perhaps the draw element begins a new paragraph else if( next_page_element != elem.Children.end() ) { - TextElement* pText = dynamic_cast<TextElement*>(next_page_element->get()); + TextElement* pText = (*next_page_element)->dynCastAsTextElement(); if( ! pText ) { ParagraphElement* pPara = dynamic_cast<ParagraphElement*>(next_page_element->get()); if( pPara && ! pPara->Children.empty() ) - pText = dynamic_cast<TextElement*>(pPara->Children.front().get()); + pText = pPara->Children.front()->dynCastAsTextElement(); } if( pText && // check there is a text pDraw->h < pText->h*1.5 && // and it is approx the same height @@ -560,9 +560,9 @@ void DrawXmlOptimizer::visit( PageElement& elem, const std::list< std::unique_pt } } - TextElement* pText = dynamic_cast<TextElement*>(page_element->get()); + TextElement* pText = (*page_element)->dynCastAsTextElement(); if( ! pText && pLink && ! pLink->Children.empty() ) - pText = dynamic_cast<TextElement*>(pLink->Children.front().get()); + pText = pLink->Children.front()->dynCastAsTextElement(); if( pText ) { Element* pGeo = pLink ? static_cast<Element*>(pLink) : @@ -671,11 +671,11 @@ void DrawXmlOptimizer::optimizeTextElements(Element& rParent) while( next != rParent.Children.end() ) { bool bConcat = false; - TextElement* pCur = dynamic_cast<TextElement*>(it->get()); + TextElement* pCur = (*it)->dynCastAsTextElement(); if( pCur ) { - TextElement* pNext = dynamic_cast<TextElement*>(next->get()); + TextElement* pNext = (*next)->dynCastAsTextElement(); bool isComplex = false; OUString str(pCur->Text.toString()); for(int i=0; i< str.getLength(); i++) diff --git a/sdext/source/pdfimport/tree/genericelements.cxx b/sdext/source/pdfimport/tree/genericelements.cxx index 2eb789616b30..7f751e18ba5c 100644 --- a/sdext/source/pdfimport/tree/genericelements.cxx +++ b/sdext/source/pdfimport/tree/genericelements.cxx @@ -192,7 +192,7 @@ bool ParagraphElement::isSingleLined( PDFIProcessor const & rProc ) const if( dynamic_cast< ParagraphElement* >(rxChild.get()) != nullptr ) return false; - pText = dynamic_cast< TextElement* >(rxChild.get()); + pText = rxChild->dynCastAsTextElement(); if( pText ) { const FontAttributes& rFont = rProc.getFont( pText->FontId ); @@ -226,7 +226,7 @@ double ParagraphElement::getLineHeight( PDFIProcessor& rProc ) const if( lh > line_h ) line_h = lh; } - else if( (pText = dynamic_cast< TextElement* >( rxChild.get() )) != nullptr ) + else if( (pText = rxChild->dynCastAsTextElement()) != nullptr ) { const FontAttributes& rFont = rProc.getFont( pText->FontId ); double lh = pText->h; @@ -243,9 +243,9 @@ TextElement* ParagraphElement::getFirstTextChild() const { TextElement* pText = nullptr; auto it = std::find_if(Children.begin(), Children.end(), - [](const std::unique_ptr<Element>& rxElem) { return dynamic_cast<TextElement*>(rxElem.get()) != nullptr; }); + [](const std::unique_ptr<Element>& rxElem) { return rxElem->dynCastAsTextElement() != nullptr; }); if (it != Children.end()) - pText = dynamic_cast<TextElement*>(it->get()); + pText = (*it)->dynCastAsTextElement(); return pText; } @@ -270,7 +270,7 @@ bool PageElement::resolveHyperlink( const std::list<std::unique_ptr<Element>>::i if( (*it)->x >= pLink->x && (*it)->x + (*it)->w <= pLink->x + pLink->w && (*it)->y >= pLink->y && (*it)->y + (*it)->h <= pLink->y + pLink->h ) { - TextElement* pText = dynamic_cast<TextElement*>(it->get()); + TextElement* pText = (*it)->dynCastAsTextElement(); if( pText ) { if( pLink->Children.empty() ) @@ -336,7 +336,7 @@ void PageElement::resolveUnderlines( PDFIProcessor const & rProc ) textAndHypers.reserve(Children.size()); for (auto const & p : Children) { - if (dynamic_cast< TextElement* >(p.get()) || dynamic_cast<HyperlinkElement*>(p.get())) + if (p->dynCastAsTextElement() || dynamic_cast<HyperlinkElement*>(p.get())) textAndHypers.push_back(p.get()); } @@ -388,7 +388,7 @@ void PageElement::resolveUnderlines( PDFIProcessor const & rProc ) if( pEle->x + pEle->w*0.1 >= l_x && pEle->x + pEle->w*0.9 <= r_x ) { - TextElement* pText = dynamic_cast< TextElement* >(pEle); + TextElement* pText = pEle->dynCastAsTextElement(); if( pText ) { const GraphicsContext& rTextGC = rProc.getGraphicsContext( pText->GCId ); diff --git a/sdext/source/pdfimport/tree/pdfiprocessor.cxx b/sdext/source/pdfimport/tree/pdfiprocessor.cxx index ff105426ad51..40ee39705c25 100644 --- a/sdext/source/pdfimport/tree/pdfiprocessor.cxx +++ b/sdext/source/pdfimport/tree/pdfiprocessor.cxx @@ -317,7 +317,7 @@ void PDFIProcessor::drawGlyphs( const OUString& rGlyphs, void PDFIProcessor::endText() { - TextElement* pText = dynamic_cast<TextElement*>(m_pCurElement); + TextElement* pText = m_pCurElement->dynCastAsTextElement(); if( pText ) m_pCurElement = pText->Parent; } @@ -637,9 +637,9 @@ static bool lr_tb_sort( std::unique_ptr<Element> const & pLeft, std::unique_ptr< // of the same order as font height whereas the real paint area // of text is usually smaller double fudge_factor_left = 0.0, fudge_factor_right = 0.0; - if( dynamic_cast< TextElement* >(pLeft.get()) ) + if( pLeft->dynCastAsTextElement() ) fudge_factor_left = 0.1; - if (dynamic_cast< TextElement* >(pRight.get())) + if( pRight->dynCastAsTextElement() ) fudge_factor_right = 0.1; // Allow negative height diff --git a/sdext/source/pdfimport/tree/writertreevisiting.cxx b/sdext/source/pdfimport/tree/writertreevisiting.cxx index a3d66f33636a..3e21932eb6c9 100644 --- a/sdext/source/pdfimport/tree/writertreevisiting.cxx +++ b/sdext/source/pdfimport/tree/writertreevisiting.cxx @@ -518,7 +518,7 @@ void WriterXmlOptimizer::visit( PageElement& elem, const std::list< std::unique_ nCurLineElements = 0; for( const auto& rxChild : pCurPara->Children ) { - TextElement* pTestText = dynamic_cast<TextElement*>(rxChild.get()); + TextElement* pTestText = rxChild->dynCastAsTextElement(); if( pTestText ) { fCurLineHeight = (fCurLineHeight*double(nCurLineElements) + pTestText->h)/double(nCurLineElements+1); @@ -552,12 +552,12 @@ void WriterXmlOptimizer::visit( PageElement& elem, const std::list< std::unique_ // or perhaps the draw element begins a new paragraph else if( next_page_element != elem.Children.end() ) { - TextElement* pText = dynamic_cast<TextElement*>(next_page_element->get()); + TextElement* pText = (*next_page_element)->dynCastAsTextElement(); if( ! pText ) { ParagraphElement* pPara = dynamic_cast<ParagraphElement*>(next_page_element->get()); if( pPara && ! pPara->Children.empty() ) - pText = dynamic_cast<TextElement*>(pPara->Children.front().get()); + pText = pPara->Children.front()->dynCastAsTextElement(); } if( pText && // check there is a text pDraw->h < pText->h*1.5 && // and it is approx the same height @@ -586,9 +586,9 @@ void WriterXmlOptimizer::visit( PageElement& elem, const std::list< std::unique_ } } - TextElement* pText = dynamic_cast<TextElement*>(page_element->get()); + TextElement* pText = (*page_element)->dynCastAsTextElement(); if( ! pText && pLink && ! pLink->Children.empty() ) - pText = dynamic_cast<TextElement*>(pLink->Children.front().get()); + pText = pLink->Children.front()->dynCastAsTextElement(); if( pText ) { Element* pGeo = pLink ? static_cast<Element*>(pLink) : @@ -745,7 +745,7 @@ void WriterXmlOptimizer::optimizeTextElements(Element& rParent) while( next != rParent.Children.end() ) { bool bConcat = false; - TextElement* pCur = dynamic_cast<TextElement*>(it->get()); + TextElement* pCur = (*it)->dynCastAsTextElement(); if( pCur ) { TextElement* pNext = dynamic_cast<TextElement*>(next->get());