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());

Reply via email to