LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/text - EnhancedPDFExportHelper.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 17 914 1.9 %
Date: 2013-07-09 Functions: 5 24 20.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/embed/XEmbeddedObject.hpp>
      21             : #include <com/sun/star/i18n/ScriptType.hpp>
      22             : #include <EnhancedPDFExportHelper.hxx>
      23             : #include <hintids.hxx>
      24             : 
      25             : #include <vcl/outdev.hxx>
      26             : #include <tools/multisel.hxx>
      27             : #include <editeng/adjustitem.hxx>
      28             : #include <editeng/lrspitem.hxx>
      29             : #include <editeng/langitem.hxx>
      30             : #include <editeng/scripttypeitem.hxx>
      31             : #include <tools/urlobj.hxx>
      32             : #include <svl/zforlist.hxx>
      33             : #include <swatrset.hxx>
      34             : #include <frmatr.hxx>
      35             : #include <paratr.hxx>
      36             : #include <ndtxt.hxx>
      37             : #include <ndole.hxx>
      38             : #include <section.hxx>
      39             : #include <tox.hxx>
      40             : #include <fmtfld.hxx>
      41             : #include <txtinet.hxx>
      42             : #include <fmtinfmt.hxx>
      43             : #include <fchrfmt.hxx>
      44             : #include <charfmt.hxx>
      45             : #include <fmtanchr.hxx>
      46             : #include <fmturl.hxx>
      47             : #include <editsh.hxx>
      48             : #include <viscrs.hxx>
      49             : #include <txtfld.hxx>
      50             : #include <reffld.hxx>
      51             : #include <doc.hxx>
      52             : #include <docary.hxx>
      53             : #include <crsskip.hxx>
      54             : #include <mdiexp.hxx>
      55             : #include <docufld.hxx>
      56             : #include <ftnidx.hxx>
      57             : #include <txtftn.hxx>
      58             : #include <fmtftn.hxx>
      59             : #include <rootfrm.hxx>
      60             : #include <pagefrm.hxx>
      61             : #include <txtfrm.hxx>
      62             : #include <tabfrm.hxx>
      63             : #include <rowfrm.hxx>
      64             : #include <cellfrm.hxx>
      65             : #include <sectfrm.hxx>
      66             : #include <flyfrm.hxx>
      67             : #include <notxtfrm.hxx>
      68             : #include <porfld.hxx>
      69             : #include <SwStyleNameMapper.hxx>
      70             : #include <itrpaint.hxx>
      71             : #include "i18nlangtag/languagetag.hxx"
      72             : #include <IMark.hxx>
      73             : #include <SwNodeNum.hxx>
      74             : #include <switerator.hxx>
      75             : #include <stack>
      76             : 
      77             : #include <tools/globname.hxx>
      78             : 
      79             : using namespace ::com::sun::star;
      80             : 
      81             : //
      82             : // Some static data structures
      83             : //
      84          33 : TableColumnsMap SwEnhancedPDFExportHelper::aTableColumnsMap;
      85          33 : LinkIdMap SwEnhancedPDFExportHelper::aLinkIdMap;
      86          33 : NumListIdMap SwEnhancedPDFExportHelper::aNumListIdMap;
      87          33 : NumListBodyIdMap SwEnhancedPDFExportHelper::aNumListBodyIdMap;
      88          33 : FrmTagIdMap SwEnhancedPDFExportHelper::aFrmTagIdMap;
      89             : 
      90             : LanguageType SwEnhancedPDFExportHelper::eLanguageDefault = 0;
      91             : 
      92             : #if OSL_DEBUG_LEVEL > 1
      93             : 
      94             : static std::vector< sal_uInt16 > aStructStack;
      95             : 
      96             : void lcl_DBGCheckStack()
      97             : {
      98             :     /* NonStructElement = 0     Document = 1        Part = 2
      99             :      * Article = 3              Section = 4         Division = 5
     100             :      * BlockQuote = 6           Caption = 7         TOC = 8
     101             :      * TOCI = 9                 Index = 10          Paragraph = 11
     102             :      * Heading = 12             H1-6 = 13 - 18      List = 19
     103             :      * ListItem = 20            LILabel = 21        LIBody = 22
     104             :      * Table = 23               TableRow = 24       TableHeader = 25
     105             :      * TableData = 26           Span = 27           Quote = 28
     106             :      * Note = 29                Reference = 30      BibEntry = 31
     107             :      * Code = 32                Link = 33           Figure = 34
     108             :      * Formula = 35             Form = 36           Continued frame = 99
     109             :      */
     110             : 
     111             :     sal_uInt16 nElement;
     112             :     std::vector< sal_uInt16 >::iterator aIter;
     113             :     for ( aIter = aStructStack.begin(); aIter != aStructStack.end(); ++aIter )
     114             :     {
     115             :         nElement = *aIter;
     116             :     }
     117             :     (void)nElement;
     118             : }
     119             : 
     120             : #endif
     121             : 
     122             : namespace
     123             : {
     124             : // ODF Style Names:
     125             : const char aTableHeadingName[]  = "Table Heading";
     126             : const char aQuotations[]        = "Quotations";
     127             : const char aCaption[]           = "Caption";
     128             : const char aHeading[]           = "Heading";
     129             : const char aQuotation[]         = "Quotation";
     130             : const char aSourceText[]        = "Source Text";
     131             : 
     132             : // PDF Tag Names:
     133             : const char aDocumentString[] = "Document";
     134             : const char aDivString[] = "Div";
     135             : const char aSectString[] = "Sect";
     136             : const char aHString[] = "H";
     137             : const char aH1String[] = "H1";
     138             : const char aH2String[] = "H2";
     139             : const char aH3String[] = "H3";
     140             : const char aH4String[] = "H4";
     141             : const char aH5String[] = "H5";
     142             : const char aH6String[] = "H6";
     143             : const char aListString[] = "L";
     144             : const char aListItemString[] = "LI";
     145             : const char aListBodyString[] = "LBody";
     146             : const char aBlockQuoteString[] = "BlockQuote";
     147             : const char aCaptionString[] = "Caption";
     148             : const char aIndexString[] = "Index";
     149             : const char aTOCString[] = "TOC";
     150             : const char aTOCIString[] = "TOCI";
     151             : const char aTableString[] = "Table";
     152             : const char aTRString[] = "TR";
     153             : const char aTDString[] = "TD";
     154             : const char aTHString[] = "TH";
     155             : const char aBibEntryString[] = "BibEntry";
     156             : const char aQuoteString[] = "Quote";
     157             : const char aSpanString[] = "Span";
     158             : const char aCodeString[] = "Code";
     159             : const char aFigureString[] = "Figure";
     160             : const char aFormulaString[] = "Formula";
     161             : const char aLinkString[] = "Link";
     162             : const char aNoteString[] = "Note";
     163             : 
     164             : // returns true if first paragraph in cell frame has 'table heading' style
     165           0 : bool lcl_IsHeadlineCell( const SwCellFrm& rCellFrm )
     166             : {
     167           0 :     bool bRet = false;
     168             : 
     169           0 :     const SwCntntFrm *pCnt = rCellFrm.ContainsCntnt();
     170           0 :     if ( pCnt && pCnt->IsTxtFrm() )
     171             :     {
     172           0 :         const SwTxtNode* pTxtNode = static_cast<const SwTxtFrm*>(pCnt)->GetTxtNode();
     173           0 :         const SwFmt* pTxtFmt = pTxtNode->GetFmtColl();
     174             : 
     175           0 :         String sStyleName;
     176           0 :         SwStyleNameMapper::FillProgName( pTxtFmt->GetName(), sStyleName, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, true );
     177           0 :         bRet = sStyleName.EqualsAscii(aTableHeadingName);
     178             :     }
     179             : 
     180           0 :     return bRet;
     181             : }
     182             : 
     183             : // List all frames for which the NonStructElement tag is set:
     184           0 : bool lcl_IsInNonStructEnv( const SwFrm& rFrm )
     185             : {
     186           0 :     bool bRet = false;
     187             : 
     188           0 :     if ( 0 != rFrm.FindFooterOrHeader() &&
     189           0 :            !rFrm.IsHeaderFrm() && !rFrm.IsFooterFrm() )
     190             :     {
     191           0 :         bRet = true;
     192             :     }
     193           0 :     else if ( rFrm.IsInTab() && !rFrm.IsTabFrm() )
     194             :     {
     195           0 :         const SwTabFrm* pTabFrm = rFrm.FindTabFrm();
     196           0 :         if ( rFrm.GetUpper() != pTabFrm &&
     197           0 :              pTabFrm->IsFollow() && pTabFrm->IsInHeadline( rFrm ) )
     198           0 :              bRet = true;
     199             :     }
     200             : 
     201           0 :     return bRet;
     202             : }
     203             : 
     204             : // Generate key from frame for reopening tags:
     205           0 : void* lcl_GetKeyFromFrame( const SwFrm& rFrm )
     206             : {
     207           0 :     void* pKey = 0;
     208             : 
     209           0 :     if ( rFrm.IsPageFrm() )
     210           0 :         pKey = (void*)static_cast<const SwPageFrm&>(rFrm).GetFmt()->getIDocumentSettingAccess();
     211           0 :     else if ( rFrm.IsTxtFrm() )
     212           0 :         pKey = (void*)static_cast<const SwTxtFrm&>(rFrm).GetTxtNode();
     213           0 :     else if ( rFrm.IsSctFrm() )
     214           0 :         pKey = (void*)static_cast<const SwSectionFrm&>(rFrm).GetSection();
     215           0 :     else if ( rFrm.IsTabFrm() )
     216           0 :         pKey = (void*)static_cast<const SwTabFrm&>(rFrm).GetTable();
     217           0 :     else if ( rFrm.IsRowFrm() )
     218           0 :         pKey = (void*)static_cast<const SwRowFrm&>(rFrm).GetTabLine();
     219           0 :     else if ( rFrm.IsCellFrm() )
     220             :     {
     221           0 :         const SwTabFrm* pTabFrm = rFrm.FindTabFrm();
     222           0 :         const SwTable* pTable = pTabFrm->GetTable();
     223           0 :         pKey = (void*) & static_cast<const SwCellFrm&>(rFrm).GetTabBox()->FindStartOfRowSpan( *pTable );
     224             :     }
     225             : 
     226           0 :     return pKey;
     227             : }
     228             : 
     229           0 : bool lcl_HasPreviousParaSameNumRule( const SwTxtNode& rNode )
     230             : {
     231           0 :     bool bRet = false;
     232           0 :     SwNodeIndex aIdx( rNode );
     233           0 :     const SwDoc* pDoc = rNode.GetDoc();
     234           0 :     const SwNodes& rNodes = pDoc->GetNodes();
     235           0 :     const SwNode* pNode = &rNode;
     236           0 :     const SwNumRule* pNumRule = rNode.GetNumRule();
     237             : 
     238           0 :     while (! (pNode == rNodes.DocumentSectionStartNode((SwNode*)&rNode) ) )
     239             :     {
     240           0 :         --aIdx;
     241             : 
     242           0 :         if (aIdx.GetNode().IsTxtNode())
     243             :         {
     244           0 :             const SwTxtNode* pPrevTxtNd = aIdx.GetNode().GetTxtNode();
     245           0 :             const SwNumRule * pPrevNumRule = pPrevTxtNd->GetNumRule();
     246             : 
     247             :             // We find the previous text node. Now check, if the previous text node
     248             :             // has the same numrule like rNode:
     249           0 :             if ( (pPrevNumRule == pNumRule) &&
     250           0 :                  (!pPrevTxtNd->IsOutline() == !rNode.IsOutline()))
     251           0 :                 bRet = true;
     252             : 
     253           0 :             break;
     254             :         }
     255             : 
     256           0 :         pNode = &aIdx.GetNode();
     257             :     }
     258           0 :     return bRet;
     259             : }
     260             : 
     261             : } // end namespace
     262             : 
     263             : /*
     264             :  * SwTaggedPDFHelper::SwTaggedPDFHelper()
     265             :  */
     266       91043 : SwTaggedPDFHelper::SwTaggedPDFHelper( const Num_Info* pNumInfo,
     267             :                                       const Frm_Info* pFrmInfo,
     268             :                                       const Por_Info* pPorInfo,
     269             :                                       OutputDevice& rOut )
     270             :   : nEndStructureElement( 0 ),
     271             :     nRestoreCurrentTag( -1 ),
     272             :     mpNumInfo( pNumInfo ),
     273             :     mpFrmInfo( pFrmInfo ),
     274       91043 :     mpPorInfo( pPorInfo )
     275             : {
     276             :     mpPDFExtOutDevData =
     277       91043 :         PTR_CAST( vcl::PDFExtOutDevData, rOut.GetExtOutDevData() );
     278             : 
     279       91043 :     if ( mpPDFExtOutDevData && mpPDFExtOutDevData->GetIsExportTaggedPDF() )
     280             :     {
     281             : #if OSL_DEBUG_LEVEL > 1
     282             :         sal_Int32 nCurrentStruct = mpPDFExtOutDevData->GetCurrentStructureElement();
     283             :         lcl_DBGCheckStack();
     284             : #endif
     285           0 :         if ( mpNumInfo )
     286           0 :             BeginNumberedListStructureElements();
     287           0 :         else if ( mpFrmInfo )
     288           0 :             BeginBlockStructureElements();
     289           0 :         else if ( mpPorInfo )
     290           0 :             BeginInlineStructureElements();
     291             :         else
     292           0 :             BeginTag( vcl::PDFWriter::NonStructElement, OUString() );
     293             : 
     294             : #if OSL_DEBUG_LEVEL > 1
     295             :         nCurrentStruct = mpPDFExtOutDevData->GetCurrentStructureElement();
     296             :         lcl_DBGCheckStack();
     297             :         (void)nCurrentStruct;
     298             : #endif
     299             :     }
     300       91043 : }
     301             : 
     302             : 
     303             : /*
     304             :  * SwTaggedPDFHelper::~SwTaggedPDFHelper()
     305             :  */
     306       91043 : SwTaggedPDFHelper::~SwTaggedPDFHelper()
     307             : {
     308       91043 :     if ( mpPDFExtOutDevData && mpPDFExtOutDevData->GetIsExportTaggedPDF() )
     309             :     {
     310             : #if OSL_DEBUG_LEVEL > 1
     311             :         sal_Int32 nCurrentStruct = mpPDFExtOutDevData->GetCurrentStructureElement();
     312             :         lcl_DBGCheckStack();
     313             : #endif
     314           0 :         EndStructureElements();
     315             : 
     316             : #if OSL_DEBUG_LEVEL > 1
     317             :         nCurrentStruct = mpPDFExtOutDevData->GetCurrentStructureElement();
     318             :         lcl_DBGCheckStack();
     319             :         (void)nCurrentStruct;
     320             : #endif
     321             : 
     322             :     }
     323       91043 : }
     324             : 
     325             : /*
     326             :  * SwTaggedPDFHelper::CheckReopenTag()
     327             :  */
     328           0 : bool SwTaggedPDFHelper::CheckReopenTag()
     329             : {
     330           0 :     bool bRet = false;
     331           0 :     sal_Int32 nReopenTag = -1;
     332           0 :     bool bContinue = false; // in some cases we just have to reopen a tag without early returning
     333             : 
     334           0 :     if ( mpFrmInfo )
     335             :     {
     336           0 :         const SwFrm& rFrm = mpFrmInfo->mrFrm;
     337           0 :         const SwFrm* pKeyFrm = 0;
     338           0 :         void* pKey = 0;
     339             : 
     340             :         // Reopen an existing structure element if
     341             :         // - rFrm is not the first page frame (reopen Document tag)
     342             :         // - rFrm is a follow frame (reopen Master tag)
     343             :         // - rFrm is a fly frame anchored at content (reopen Anchor paragraph tag)
     344             :         // - rFrm is a fly frame anchord at page (reopen Document tag)
     345             :         // - rFrm is a follow flow row (reopen TableRow tag)
     346             :         // - rFrm is a cell frame in a follow flow row (reopen TableData tag)
     347           0 :         if ( ( rFrm.IsPageFrm() && static_cast<const SwPageFrm&>(rFrm).GetPrev() ) ||
     348           0 :              ( rFrm.IsFlowFrm() && SwFlowFrm::CastFlowFrm(&rFrm)->IsFollow() ) ||
     349           0 :              ( rFrm.IsRowFrm() && rFrm.IsInFollowFlowRow() ) ||
     350           0 :              ( rFrm.IsCellFrm() && const_cast<SwFrm&>(rFrm).GetPrevCellLeaf( MAKEPAGE_NONE ) ) )
     351             :         {
     352           0 :             pKeyFrm = &rFrm;
     353             :         }
     354           0 :         else if ( rFrm.IsFlyFrm() )
     355             :         {
     356             :             const SwFmtAnchor& rAnchor =
     357           0 :                 static_cast<const SwFlyFrm*>(&rFrm)->GetFmt()->GetAnchor();
     358           0 :             if ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
     359           0 :                 (FLY_AT_CHAR == rAnchor.GetAnchorId()) ||
     360           0 :                 (FLY_AT_PAGE == rAnchor.GetAnchorId()))
     361             :             {
     362           0 :                 pKeyFrm = static_cast<const SwFlyFrm&>(rFrm).GetAnchorFrm();
     363           0 :                 bContinue = true;
     364             :             }
     365             :         }
     366             : 
     367           0 :         if ( pKeyFrm )
     368             :         {
     369           0 :             pKey = lcl_GetKeyFromFrame( *pKeyFrm );
     370             : 
     371           0 :             if ( pKey )
     372             :             {
     373           0 :                 FrmTagIdMap& rFrmTagIdMap = SwEnhancedPDFExportHelper::GetFrmTagIdMap();
     374           0 :                 const FrmTagIdMap::const_iterator aIter =  rFrmTagIdMap.find( pKey );
     375           0 :                 if ( aIter != rFrmTagIdMap.end() )
     376           0 :                     nReopenTag = (*aIter).second;
     377             :             }
     378             :         }
     379             :     }
     380             : 
     381           0 :     if ( -1 != nReopenTag )
     382             :     {
     383           0 :         nRestoreCurrentTag = mpPDFExtOutDevData->GetCurrentStructureElement();
     384           0 :         const bool bSuccess = mpPDFExtOutDevData->SetCurrentStructureElement( nReopenTag );
     385             :         OSL_ENSURE( bSuccess, "Failed to reopen tag" );
     386             : 
     387             : #if OSL_DEBUG_LEVEL > 1
     388             :         aStructStack.push_back( 99 );
     389             : #endif
     390             : 
     391           0 :         bRet = bSuccess;
     392             :     }
     393             : 
     394           0 :     return bRet && !bContinue;
     395             : }
     396             : 
     397             : 
     398             : /*
     399             :  * SwTaggedPDFHelper::CheckRestoreTag()
     400             :  */
     401           0 : bool SwTaggedPDFHelper::CheckRestoreTag() const
     402             : {
     403           0 :     bool bRet = false;
     404           0 :     if ( nRestoreCurrentTag != -1 )
     405             :     {
     406           0 :         const bool bSuccess = mpPDFExtOutDevData->SetCurrentStructureElement( nRestoreCurrentTag );
     407             :         (void)bSuccess;
     408             :         OSL_ENSURE( bSuccess, "Failed to restore reopened tag" );
     409             : 
     410             : #if OSL_DEBUG_LEVEL > 1
     411             :         aStructStack.pop_back();
     412             : #endif
     413             : 
     414           0 :         bRet = true;
     415             :     }
     416             : 
     417           0 :     return bRet;
     418             : }
     419             : 
     420             : 
     421             : /*
     422             :  * SwTaggedPDFHelper::BeginTag()
     423             :  */
     424           0 : void SwTaggedPDFHelper::BeginTag( vcl::PDFWriter::StructElement eType, const String& rString )
     425             : {
     426             :     // write new tag
     427           0 :     const sal_Int32 nId = mpPDFExtOutDevData->BeginStructureElement( eType, OUString( rString ) );
     428           0 :     ++nEndStructureElement;
     429             : 
     430             : #if OSL_DEBUG_LEVEL > 1
     431             :     aStructStack.push_back( static_cast<sal_uInt16>(eType) );
     432             : #endif
     433             : 
     434             :     // Store the id of the current structure element if
     435             :     // - it is a list structure element
     436             :     // - it is a list body element with children
     437             :     // - rFrm is the first page frame
     438             :     // - rFrm is a master frame
     439             :     // - rFrm has objects anchored to it
     440             :     // - rFrm is a row frame or cell frame in a split table row
     441             : 
     442           0 :     if ( mpNumInfo )
     443             :     {
     444           0 :         const SwTxtFrm& rTxtFrm = static_cast<const SwTxtFrm&>(mpNumInfo->mrFrm);
     445           0 :         const SwTxtNode* pTxtNd = rTxtFrm.GetTxtNode();
     446           0 :         const SwNodeNum* pNodeNum = pTxtNd->GetNum();
     447             : 
     448           0 :         if ( vcl::PDFWriter::List == eType )
     449             :         {
     450           0 :             NumListIdMap& rNumListIdMap = SwEnhancedPDFExportHelper::GetNumListIdMap();
     451           0 :             rNumListIdMap[ pNodeNum ] = nId;
     452             :         }
     453           0 :         else if ( vcl::PDFWriter::LIBody == eType )
     454             :         {
     455           0 :             NumListBodyIdMap& rNumListBodyIdMap = SwEnhancedPDFExportHelper::GetNumListBodyIdMap();
     456           0 :             rNumListBodyIdMap[ pNodeNum ] = nId;
     457             :         }
     458             :     }
     459           0 :     else if ( mpFrmInfo )
     460             :     {
     461           0 :         const SwFrm& rFrm = mpFrmInfo->mrFrm;
     462             : 
     463           0 :         if ( ( rFrm.IsPageFrm() && !static_cast<const SwPageFrm&>(rFrm).GetPrev() ) ||
     464           0 :              ( rFrm.IsFlowFrm() && !SwFlowFrm::CastFlowFrm(&rFrm)->IsFollow() && SwFlowFrm::CastFlowFrm(&rFrm)->HasFollow() ) ||
     465           0 :              ( rFrm.IsTxtFrm() && rFrm.GetDrawObjs() ) ||
     466           0 :              ( rFrm.IsRowFrm() && rFrm.IsInSplitTableRow() ) ||
     467           0 :              ( rFrm.IsCellFrm() && const_cast<SwFrm&>(rFrm).GetNextCellLeaf( MAKEPAGE_NONE ) ) )
     468             :         {
     469           0 :             const void* pKey = lcl_GetKeyFromFrame( rFrm );
     470             : 
     471           0 :             if ( pKey )
     472             :             {
     473           0 :                 FrmTagIdMap& rFrmTagIdMap = SwEnhancedPDFExportHelper::GetFrmTagIdMap();
     474           0 :                 rFrmTagIdMap[ pKey ] = nId;
     475             :             }
     476             :         }
     477             :     }
     478             : 
     479           0 :     SetAttributes( eType );
     480           0 : }
     481             : 
     482             : 
     483             : /*
     484             :  * SwTaggedPDFHelper::EndTag()
     485             :  */
     486           0 : void SwTaggedPDFHelper::EndTag()
     487             : {
     488           0 :     mpPDFExtOutDevData->EndStructureElement();
     489             : 
     490             : #if OSL_DEBUG_LEVEL > 1
     491             :     aStructStack.pop_back();
     492             : #endif
     493           0 : }
     494             : 
     495             : 
     496             : /*
     497             :  * SwTaggedPDFHelper::SetAttributes()
     498             :  *
     499             :  * Sets the attributes according to the structure type.
     500             :  */
     501           0 : void SwTaggedPDFHelper::SetAttributes( vcl::PDFWriter::StructElement eType )
     502             : {
     503             :     vcl::PDFWriter::StructAttributeValue eVal;
     504             :     sal_Int32 nVal;
     505             : 
     506             :     /*
     507             :      * ATTRIBUTES FOR BLSE
     508             :      */
     509           0 :     if ( mpFrmInfo )
     510             :     {
     511           0 :         const SwFrm* pFrm = &mpFrmInfo->mrFrm;
     512           0 :         SWRECTFN( pFrm )
     513             : 
     514           0 :         bool bPlacement = false;
     515           0 :         bool bWritingMode = false;
     516           0 :         bool bSpaceBefore = false;
     517           0 :         bool bSpaceAfter = false;
     518           0 :         bool bStartIndent = false;
     519           0 :         bool bEndIndent = false;
     520           0 :         bool bTextIndent = false;
     521           0 :         bool bTextAlign = false;
     522           0 :         bool bAlternateText = false;
     523           0 :         bool bWidth = false;
     524           0 :         bool bHeight = false;
     525           0 :         bool bBox = false;
     526           0 :         bool bRowSpan = false;
     527             : 
     528             :         //
     529             :         // Check which attributes to set:
     530             :         //
     531           0 :         switch ( eType )
     532             :         {
     533             :             case vcl::PDFWriter::Document :
     534           0 :                 bWritingMode = true;
     535           0 :                 break;
     536             : 
     537             :             case vcl::PDFWriter::Table :
     538             :                 bPlacement =
     539             :                 bWritingMode =
     540             :                 bSpaceBefore =
     541             :                 bSpaceAfter =
     542             :                 bStartIndent =
     543             :                 bEndIndent =
     544             :                 bWidth =
     545             :                 bHeight =
     546           0 :                 bBox = true;
     547           0 :                 break;
     548             : 
     549             :             case vcl::PDFWriter::TableRow :
     550             :                 bPlacement =
     551           0 :                 bWritingMode = true;
     552           0 :                 break;
     553             : 
     554             :             case vcl::PDFWriter::TableHeader :
     555             :             case vcl::PDFWriter::TableData :
     556             :                 bPlacement =
     557             :                 bWritingMode =
     558             :                 bWidth =
     559             :                 bHeight =
     560           0 :                 bRowSpan = true;
     561           0 :                 break;
     562             : 
     563             :             case vcl::PDFWriter::H1 :
     564             :             case vcl::PDFWriter::H2 :
     565             :             case vcl::PDFWriter::H3 :
     566             :             case vcl::PDFWriter::H4 :
     567             :             case vcl::PDFWriter::H5 :
     568             :             case vcl::PDFWriter::H6 :
     569             :             case vcl::PDFWriter::Paragraph :
     570             :             case vcl::PDFWriter::Heading :
     571             :             case vcl::PDFWriter::Caption :
     572             :             case vcl::PDFWriter::BlockQuote :
     573             : 
     574             :                 bPlacement =
     575             :                 bWritingMode =
     576             :                 bSpaceBefore =
     577             :                 bSpaceAfter =
     578             :                 bStartIndent =
     579             :                 bEndIndent =
     580             :                 bTextIndent =
     581           0 :                 bTextAlign = true;
     582           0 :                 break;
     583             : 
     584             :             case vcl::PDFWriter::Formula :
     585             :             case vcl::PDFWriter::Figure :
     586             :                 bPlacement =
     587             :                 bAlternateText =
     588             :                 bWidth =
     589             :                 bHeight =
     590           0 :                 bBox = true;
     591           0 :                 break;
     592             :             default :
     593           0 :                 break;
     594             :         }
     595             : 
     596             :         //
     597             :         // Set the attributes:
     598             :         //
     599           0 :         if ( bPlacement )
     600             :         {
     601           0 :             eVal = vcl::PDFWriter::TableHeader == eType ||
     602             :                    vcl::PDFWriter::TableData   == eType ?
     603             :                    vcl::PDFWriter::Inline :
     604           0 :                    vcl::PDFWriter::Block;
     605             : 
     606           0 :             mpPDFExtOutDevData->SetStructureAttribute( vcl::PDFWriter::Placement, eVal );
     607             :         }
     608             : 
     609           0 :         if ( bWritingMode )
     610             :         {
     611           0 :             eVal =  pFrm->IsVertical() ?
     612             :                     vcl::PDFWriter::TbRl :
     613           0 :                     pFrm->IsRightToLeft() ?
     614             :                     vcl::PDFWriter::RlTb :
     615           0 :                     vcl::PDFWriter::LrTb;
     616             : 
     617           0 :             if ( vcl::PDFWriter::LrTb != eVal )
     618           0 :                 mpPDFExtOutDevData->SetStructureAttribute( vcl::PDFWriter::WritingMode, eVal );
     619             :         }
     620             : 
     621           0 :         if ( bSpaceBefore )
     622             :         {
     623           0 :             nVal = (pFrm->*fnRect->fnGetTopMargin)();
     624           0 :             if ( 0 != nVal )
     625           0 :                 mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::SpaceBefore, nVal );
     626             :         }
     627             : 
     628           0 :         if ( bSpaceAfter )
     629             :         {
     630           0 :             nVal = (pFrm->*fnRect->fnGetBottomMargin)();
     631           0 :             if ( 0 != nVal )
     632           0 :                 mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::SpaceAfter, nVal );
     633             :         }
     634             : 
     635           0 :         if ( bStartIndent )
     636             :         {
     637           0 :             nVal = (pFrm->*fnRect->fnGetLeftMargin)();
     638           0 :             if ( 0 != nVal )
     639           0 :                 mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::StartIndent, nVal );
     640             :         }
     641             : 
     642           0 :         if ( bEndIndent )
     643             :         {
     644           0 :             nVal = (pFrm->*fnRect->fnGetRightMargin)();
     645           0 :             if ( 0 != nVal )
     646           0 :                 mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::EndIndent, nVal );
     647             :         }
     648             : 
     649           0 :         if ( bTextIndent )
     650             :         {
     651             :             OSL_ENSURE( pFrm->IsTxtFrm(), "Frame type <-> tag attribute mismatch" );
     652             :             const SvxLRSpaceItem &rSpace =
     653           0 :                 static_cast<const SwTxtFrm*>(pFrm)->GetTxtNode()->GetSwAttrSet().GetLRSpace();
     654           0 :             nVal =  rSpace.GetTxtFirstLineOfst();
     655           0 :             if ( 0 != nVal )
     656           0 :                 mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::TextIndent, nVal );
     657             :         }
     658             : 
     659           0 :         if ( bTextAlign )
     660             :         {
     661             :             OSL_ENSURE( pFrm->IsTxtFrm(), "Frame type <-> tag attribute mismatch" );
     662           0 :             const SwAttrSet& aSet = static_cast<const SwTxtFrm*>(pFrm)->GetTxtNode()->GetSwAttrSet();
     663           0 :             const SvxAdjust nAdjust = aSet.GetAdjust().GetAdjust();
     664           0 :             if ( SVX_ADJUST_BLOCK == nAdjust || SVX_ADJUST_CENTER == nAdjust ||
     665           0 :                  (  (pFrm->IsRightToLeft() && SVX_ADJUST_LEFT == nAdjust) ||
     666           0 :                    (!pFrm->IsRightToLeft() && SVX_ADJUST_RIGHT == nAdjust) ) )
     667             :             {
     668             :                 eVal = SVX_ADJUST_BLOCK == nAdjust ?
     669             :                        vcl::PDFWriter::Justify :
     670             :                        SVX_ADJUST_CENTER == nAdjust ?
     671             :                        vcl::PDFWriter::Center :
     672           0 :                        vcl::PDFWriter::End;
     673             : 
     674           0 :                 mpPDFExtOutDevData->SetStructureAttribute( vcl::PDFWriter::TextAlign, eVal );
     675             :             }
     676             :         }
     677             : 
     678           0 :         if ( bAlternateText )
     679             :         {
     680             :             OSL_ENSURE( pFrm->IsFlyFrm(), "Frame type <-> tag attribute mismatch" );
     681           0 :             const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pFrm);
     682           0 :             if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
     683             :             {
     684           0 :                 const SwNoTxtFrm* pNoTxtFrm   = static_cast<const SwNoTxtFrm*>(pFly->Lower());
     685           0 :                 const SwNoTxtNode* pNoTxtNode = static_cast<const SwNoTxtNode*>(pNoTxtFrm->GetNode());
     686             : 
     687           0 :                 const String aAlternateTxt( pNoTxtNode->GetTitle() );
     688           0 :                 mpPDFExtOutDevData->SetAlternateText( aAlternateTxt );
     689             :             }
     690             :         }
     691             : 
     692           0 :         if ( bWidth )
     693             :         {
     694           0 :             nVal = (pFrm->Frm().*fnRect->fnGetWidth)();
     695           0 :             mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::Width, nVal );
     696             :         }
     697             : 
     698           0 :         if ( bHeight )
     699             :         {
     700           0 :             nVal = (pFrm->Frm().*fnRect->fnGetHeight)();
     701           0 :             mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::Height, nVal );
     702             :         }
     703             : 
     704           0 :         if ( bBox )
     705             :         {
     706             :             // BBox only for non-split tables:
     707           0 :             if ( vcl::PDFWriter::Table != eType ||
     708           0 :                  ( pFrm->IsTabFrm() &&
     709           0 :                    !static_cast<const SwTabFrm*>(pFrm)->IsFollow() &&
     710           0 :                    !static_cast<const SwTabFrm*>(pFrm)->HasFollow() ) )
     711           0 :                 mpPDFExtOutDevData->SetStructureBoundingBox( pFrm->Frm().SVRect() );
     712             :         }
     713             : 
     714           0 :         if ( bRowSpan )
     715             :         {
     716           0 :             const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(pFrm);
     717           0 :             if ( pThisCell )
     718             :             {
     719           0 :                 nVal =  pThisCell->GetTabBox()->getRowSpan();
     720           0 :                 if ( nVal > 1 )
     721           0 :                     mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::RowSpan, nVal );
     722             : 
     723             :                 // calculate colspan:
     724           0 :                 const SwTabFrm* pTabFrm = pThisCell->FindTabFrm();
     725           0 :                 const SwTable* pTable = pTabFrm->GetTable();
     726             : 
     727           0 :                 SWRECTFNX( pTabFrm )
     728             : 
     729           0 :                 const TableColumnsMapEntry& rCols = SwEnhancedPDFExportHelper::GetTableColumnsMap()[ pTable ];
     730             : 
     731           0 :                 const long nLeft  = (pThisCell->Frm().*fnRectX->fnGetLeft)();
     732           0 :                 const long nRight = (pThisCell->Frm().*fnRectX->fnGetRight)();
     733           0 :                 const TableColumnsMapEntry::const_iterator aLeftIter =  rCols.find( nLeft );
     734           0 :                 const TableColumnsMapEntry::const_iterator aRightIter = rCols.find( nRight );
     735             : 
     736             :                 OSL_ENSURE( aLeftIter != rCols.end() && aRightIter != rCols.end(), "Colspan trouble" );
     737           0 :                 if ( aLeftIter != rCols.end() && aRightIter != rCols.end() )
     738             :                 {
     739           0 :                     nVal = std::distance( aLeftIter, aRightIter );
     740           0 :                     if ( nVal > 1 )
     741           0 :                         mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::ColSpan, nVal );
     742             :                 }
     743             :             }
     744             :         }
     745             :     }
     746             : 
     747             :     /*
     748             :      * ATTRIBUTES FOR ILSE
     749             :      */
     750           0 :     else if ( mpPorInfo )
     751             :     {
     752           0 :         const SwLinePortion* pPor = &mpPorInfo->mrPor;
     753           0 :         const SwTxtPaintInfo& rInf = mpPorInfo->mrTxtPainter.GetInfo();
     754             : 
     755           0 :         bool bActualText = false;
     756           0 :         bool bBaselineShift = false;
     757           0 :         bool bTextDecorationType = false;
     758           0 :         bool bLinkAttribute = false;
     759           0 :         bool bLanguage = false;
     760             : 
     761             :         //
     762             :         // Check which attributes to set:
     763             :         //
     764           0 :         switch ( eType )
     765             :         {
     766             :             case vcl::PDFWriter::Span :
     767             :             case vcl::PDFWriter::Quote :
     768             :             case vcl::PDFWriter::Code :
     769           0 :                 if( POR_HYPHSTR == pPor->GetWhichPor() || POR_SOFTHYPHSTR == pPor->GetWhichPor() )
     770           0 :                     bActualText = true;
     771             :                 else
     772             :                 {
     773             :                     bBaselineShift =
     774             :                     bTextDecorationType =
     775           0 :                     bLanguage = true;
     776             :                 }
     777           0 :                 break;
     778             : 
     779             :             case vcl::PDFWriter::Link :
     780             :                 bTextDecorationType =
     781             :                 bBaselineShift =
     782             :                 bLinkAttribute =
     783           0 :                 bLanguage = true;
     784           0 :                 break;
     785             : 
     786             :             default:
     787           0 :                 break;
     788             :         }
     789             : 
     790           0 :         if ( bActualText )
     791             :         {
     792           0 :             const String aActualTxt( rInf.GetTxt(), rInf.GetIdx(), pPor->GetLen() );
     793           0 :             mpPDFExtOutDevData->SetActualText( aActualTxt );
     794             :         }
     795             : 
     796           0 :         if ( bBaselineShift )
     797             :         {
     798             :             // TODO: Calculate correct values!
     799           0 :             nVal = rInf.GetFont()->GetEscapement();
     800           0 :             if ( nVal > 0 ) nVal = 33;
     801           0 :             else if ( nVal < 0 ) nVal = -33;
     802             : 
     803           0 :             if ( 0 != nVal )
     804             :             {
     805           0 :                 nVal = nVal * pPor->Height() / 100;
     806           0 :                 mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::BaselineShift, nVal );
     807             :             }
     808             :         }
     809             : 
     810           0 :         if ( bTextDecorationType )
     811             :         {
     812           0 :             if ( UNDERLINE_NONE    != rInf.GetFont()->GetUnderline() )
     813           0 :                 mpPDFExtOutDevData->SetStructureAttribute( vcl::PDFWriter::TextDecorationType, vcl::PDFWriter::Underline );
     814           0 :             if ( UNDERLINE_NONE    != rInf.GetFont()->GetOverline() )
     815           0 :                 mpPDFExtOutDevData->SetStructureAttribute( vcl::PDFWriter::TextDecorationType, vcl::PDFWriter::Overline );
     816           0 :             if ( STRIKEOUT_NONE    != rInf.GetFont()->GetStrikeout() )
     817           0 :                 mpPDFExtOutDevData->SetStructureAttribute( vcl::PDFWriter::TextDecorationType, vcl::PDFWriter::LineThrough );
     818           0 :             if ( EMPHASISMARK_NONE != rInf.GetFont()->GetEmphasisMark() )
     819           0 :                 mpPDFExtOutDevData->SetStructureAttribute( vcl::PDFWriter::TextDecorationType, vcl::PDFWriter::Overline );
     820             :         }
     821             : 
     822           0 :         if ( bLanguage )
     823             :         {
     824             : 
     825           0 :             const LanguageType nCurrentLanguage = rInf.GetFont()->GetLanguage();
     826           0 :             const LanguageType nDefaultLang = SwEnhancedPDFExportHelper::GetDefaultLanguage();
     827             : 
     828           0 :             if ( nDefaultLang != nCurrentLanguage )
     829           0 :                 mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::Language, nCurrentLanguage );
     830             :         }
     831             : 
     832           0 :         if ( bLinkAttribute )
     833             :         {
     834           0 :             const LinkIdMap& rLinkIdMap = SwEnhancedPDFExportHelper::GetLinkIdMap();
     835           0 :             SwRect aPorRect;
     836           0 :             rInf.CalcRect( *pPor, &aPorRect );
     837           0 :             const Point aPorCenter = aPorRect.Center();
     838           0 :             LinkIdMap::const_iterator aIter;
     839           0 :             for ( aIter = rLinkIdMap.begin(); aIter != rLinkIdMap.end(); ++aIter )
     840             :             {
     841           0 :                 const SwRect& rLinkRect = (*aIter).first;
     842           0 :                 if ( rLinkRect.IsInside( aPorCenter ) )
     843             :                 {
     844           0 :                     sal_Int32 nLinkId = (*aIter).second;
     845           0 :                     mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::LinkAnnotation, nLinkId );
     846           0 :                     break;
     847             :                 }
     848             :             }
     849             :         }
     850             :     }
     851           0 : }
     852             : 
     853             : /*
     854             :  * SwTaggedPDFHelper::BeginNumberedListStructureElements()
     855             :  */
     856           0 : void SwTaggedPDFHelper::BeginNumberedListStructureElements()
     857             : {
     858             :     OSL_ENSURE( mpNumInfo, "List without mpNumInfo?" );
     859           0 :     if ( !mpNumInfo )
     860           0 :         return;
     861             : 
     862           0 :     const SwFrm& rFrm = mpNumInfo->mrFrm;
     863             :     OSL_ENSURE( rFrm.IsTxtFrm(), "numbered only for text frames" );
     864           0 :     const SwTxtFrm& rTxtFrm = static_cast<const SwTxtFrm&>(rFrm);
     865             : 
     866             :     //
     867             :     // Lowers of NonStructureElements should not be considered:
     868             :     //
     869           0 :     if ( lcl_IsInNonStructEnv( rTxtFrm ) || rTxtFrm.IsFollow() )
     870           0 :         return;
     871             : 
     872           0 :     const SwTxtNode* pTxtNd = rTxtFrm.GetTxtNode();
     873           0 :     const SwNumRule* pNumRule = pTxtNd->GetNumRule();
     874           0 :     const SwNodeNum* pNodeNum = pTxtNd->GetNum();
     875             : 
     876           0 :     const bool bNumbered = !pTxtNd->IsOutline() && pNodeNum && pNodeNum->GetParent() && pNumRule;
     877             : 
     878             :     // Check, if we have to reopen a list or a list body:
     879             :     // First condition:
     880             :     // Paragraph is numbered/bulleted
     881           0 :     if ( !bNumbered )
     882           0 :         return;
     883             : 
     884           0 :     const SwNumberTreeNode* pParent = pNodeNum->GetParent();
     885           0 :     const bool bSameNumbering = lcl_HasPreviousParaSameNumRule(*pTxtNd);
     886             : 
     887             :     // Second condition: current numbering is not 'interrupted'
     888           0 :     if ( bSameNumbering )
     889             :     {
     890           0 :         sal_Int32 nReopenTag = -1;
     891             : 
     892             :         // Two cases:
     893             :         // 1. We have to reopen an existing list body tag:
     894             :         // - If the current node is either the first child of its parent
     895             :         //   and its level > 1 or
     896             :         // - Numbering should restart at the current node and its level > 1
     897             :         // - The current item has no label
     898           0 :         const bool bNewSubListStart = pParent->GetParent() && (pParent->IsFirst( pNodeNum ) || pTxtNd->IsListRestart() );
     899           0 :         const bool bNoLabel = !pTxtNd->IsCountedInList() && !pTxtNd->IsListRestart();
     900           0 :         if ( bNewSubListStart || bNoLabel )
     901             :         {
     902             :             // Fine, we try to reopen the appropriate list body
     903           0 :             NumListBodyIdMap& rNumListBodyIdMap = SwEnhancedPDFExportHelper::GetNumListBodyIdMap();
     904             : 
     905           0 :             if ( bNewSubListStart )
     906             :             {
     907             :                 // The list body tag associated with the parent has to be reopened
     908             :                 // to start a new list inside the list body
     909           0 :                 NumListBodyIdMap::const_iterator aIter;
     910             : 
     911           0 :                 do
     912           0 :                     aIter = rNumListBodyIdMap.find( pParent );
     913           0 :                 while ( aIter == rNumListBodyIdMap.end() && 0 != ( pParent = pParent->GetParent() ) );
     914             : 
     915           0 :                 if ( aIter != rNumListBodyIdMap.end() )
     916           0 :                     nReopenTag = (*aIter).second;
     917             :             }
     918             :             else // if(bNoLabel)
     919             :             {
     920             :                 // The list body tag of a 'counted' predecessor has to be reopened
     921           0 :                 const SwNumberTreeNode* pPrevious = pNodeNum->GetPred(true);
     922           0 :                 while ( pPrevious )
     923             :                 {
     924           0 :                     if ( pPrevious->IsCounted())
     925             :                     {
     926             :                         // get id of list body tag
     927           0 :                         const NumListBodyIdMap::const_iterator aIter =  rNumListBodyIdMap.find( pPrevious );
     928           0 :                         if ( aIter != rNumListBodyIdMap.end() )
     929             :                         {
     930           0 :                             nReopenTag = (*aIter).second;
     931           0 :                             break;
     932             :                         }
     933             :                     }
     934           0 :                     pPrevious = pPrevious->GetPred(true);
     935             :                 }
     936           0 :             }
     937             :         }
     938             :         // 2. We have to reopen an existing list tag:
     939           0 :         else if ( !pParent->IsFirst( pNodeNum ) && !pTxtNd->IsListRestart() )
     940             :         {
     941             :             // any other than the first node in a list level has to reopen the current
     942             :             // list. The current list is associated in a map with the first child of the list:
     943           0 :             NumListIdMap& rNumListIdMap = SwEnhancedPDFExportHelper::GetNumListIdMap();
     944             : 
     945             :             // Search backwards and check if any of the previous nodes has a list associated with it:
     946           0 :             const SwNumberTreeNode* pPrevious = pNodeNum->GetPred(true);
     947           0 :             while ( pPrevious )
     948             :             {
     949             :                 // get id of list tag
     950           0 :                 const NumListIdMap::const_iterator aIter =  rNumListIdMap.find( pPrevious );
     951           0 :                 if ( aIter != rNumListIdMap.end() )
     952             :                 {
     953           0 :                     nReopenTag = (*aIter).second;
     954           0 :                     break;
     955             :                 }
     956             : 
     957           0 :                 pPrevious = pPrevious->GetPred(true);
     958             :             }
     959             :         }
     960             : 
     961           0 :         if ( -1 != nReopenTag )
     962             :         {
     963           0 :             nRestoreCurrentTag = mpPDFExtOutDevData->GetCurrentStructureElement();
     964           0 :             mpPDFExtOutDevData->SetCurrentStructureElement( nReopenTag );
     965             : 
     966             : #if OSL_DEBUG_LEVEL > 1
     967             :             aStructStack.push_back( 99 );
     968             : #endif
     969             :         }
     970             :     }
     971             :     else
     972             :     {
     973             :         // clear list maps in case a list has been interrupted
     974           0 :         NumListIdMap& rNumListIdMap = SwEnhancedPDFExportHelper::GetNumListIdMap();
     975           0 :         rNumListIdMap.clear();
     976           0 :         NumListBodyIdMap& rNumListBodyIdMap = SwEnhancedPDFExportHelper::GetNumListBodyIdMap();
     977           0 :         rNumListBodyIdMap.clear();
     978             :     }
     979             : 
     980             :     // New tags:
     981           0 :     const bool bNewListTag = (pNodeNum->GetParent()->IsFirst( pNodeNum ) || pTxtNd->IsListRestart() || !bSameNumbering);
     982           0 :     const bool bNewItemTag = bNewListTag || pTxtNd->IsCountedInList(); // If the text node is not counted, we do not start a new list item:
     983             : 
     984           0 :     if ( bNewListTag )
     985           0 :         BeginTag( vcl::PDFWriter::List, OUString(aListString) );
     986             : 
     987           0 :     if ( bNewItemTag )
     988             :     {
     989           0 :         BeginTag( vcl::PDFWriter::ListItem, OUString(aListItemString) );
     990           0 :         BeginTag( vcl::PDFWriter::LIBody, OUString(aListBodyString) );
     991             :     }
     992             : }
     993             : 
     994             : /*
     995             :  * SwTaggedPDFHelper::BeginBlockStructureElements()
     996             :  */
     997           0 : void SwTaggedPDFHelper::BeginBlockStructureElements()
     998             : {
     999           0 :     const SwFrm* pFrm = &mpFrmInfo->mrFrm;
    1000             : 
    1001             :     //
    1002             :     // Lowers of NonStructureElements should not be considered:
    1003             :     //
    1004           0 :     if ( lcl_IsInNonStructEnv( *pFrm ) )
    1005           0 :         return;
    1006             : 
    1007             :     // Check if we have to reopen an existing structure element.
    1008             :     // This has to be done e.g., if pFrm is a follow frame.
    1009           0 :     if ( CheckReopenTag() )
    1010           0 :         return;
    1011             : 
    1012           0 :     sal_uInt16 nPDFType = USHRT_MAX;
    1013           0 :     String aPDFType;
    1014             : 
    1015           0 :     switch ( pFrm->GetType() )
    1016             :     {
    1017             :         /*
    1018             :          * GROUPING ELEMENTS
    1019             :          */
    1020             : 
    1021             :         case FRM_PAGE :
    1022             :             //
    1023             :             // Document: Document
    1024             :             //
    1025           0 :             nPDFType = vcl::PDFWriter::Document;
    1026           0 :             aPDFType = OUString(aDocumentString);
    1027           0 :             break;
    1028             : 
    1029             :         case FRM_HEADER :
    1030             :         case FRM_FOOTER :
    1031             :             //
    1032             :             // Header, Footer: NonStructElement
    1033             :             //
    1034           0 :             nPDFType = vcl::PDFWriter::NonStructElement;
    1035           0 :             break;
    1036             : 
    1037             :         case FRM_FTNCONT :
    1038             :             //
    1039             :             // Footnote container: Division
    1040             :             //
    1041           0 :             nPDFType = vcl::PDFWriter::Division;
    1042           0 :             aPDFType = OUString(aDivString);
    1043           0 :             break;
    1044             : 
    1045             :         case FRM_FTN :
    1046             :             //
    1047             :             // Footnote frame: Note
    1048             :             //
    1049             :             // Note: vcl::PDFWriter::Note is actually a ILSE. Nevertheless
    1050             :             // we treat it like a grouping element!
    1051           0 :             nPDFType = vcl::PDFWriter::Note;
    1052           0 :             aPDFType = OUString(aNoteString);
    1053           0 :             break;
    1054             : 
    1055             :         case FRM_SECTION :
    1056             :             //
    1057             :             // Section: TOX, Index, or Sect
    1058             :             //
    1059             :             {
    1060             :                 const SwSection* pSection =
    1061           0 :                         static_cast<const SwSectionFrm*>(pFrm)->GetSection();
    1062           0 :                 if ( TOX_CONTENT_SECTION == pSection->GetType() )
    1063             :                 {
    1064           0 :                     const SwTOXBase* pTOXBase = pSection->GetTOXBase();
    1065           0 :                     if ( pTOXBase )
    1066             :                     {
    1067           0 :                         if ( TOX_INDEX == pTOXBase->GetType() )
    1068             :                         {
    1069           0 :                             nPDFType = vcl::PDFWriter::Index;
    1070           0 :                             aPDFType = OUString(aIndexString);
    1071             :                         }
    1072             :                         else
    1073             :                         {
    1074           0 :                             nPDFType = vcl::PDFWriter::TOC;
    1075           0 :                             aPDFType = OUString(aTOCString);
    1076             :                         }
    1077             :                     }
    1078             :                 }
    1079           0 :                 else if ( CONTENT_SECTION == pSection->GetType() )
    1080             :                 {
    1081           0 :                     nPDFType = vcl::PDFWriter::Section;
    1082           0 :                     aPDFType = OUString(aSectString);
    1083             :                 }
    1084             :             }
    1085           0 :             break;
    1086             : 
    1087             :         /*
    1088             :          * BLOCK-LEVEL STRUCTURE ELEMENTS
    1089             :          */
    1090             : 
    1091             :         case FRM_TXT :
    1092             :             {
    1093             :                 const SwTxtNode* pTxtNd =
    1094           0 :                     static_cast<const SwTxtFrm*>(pFrm)->GetTxtNode();
    1095             : 
    1096           0 :                 const SwFmt* pTxtFmt = pTxtNd->GetFmtColl();
    1097           0 :                 const SwFmt* pParentTxtFmt = pTxtFmt ? pTxtFmt->DerivedFrom() : NULL;
    1098             : 
    1099           0 :                 String sStyleName;
    1100           0 :                 String sParentStyleName;
    1101             : 
    1102           0 :                 if ( pTxtFmt)
    1103           0 :                     SwStyleNameMapper::FillProgName( pTxtFmt->GetName(), sStyleName, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, true );
    1104           0 :                 if ( pParentTxtFmt)
    1105           0 :                     SwStyleNameMapper::FillProgName( pParentTxtFmt->GetName(), sParentStyleName, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, true );
    1106             : 
    1107             :                 // This is the default. If the paragraph could not be mapped to
    1108             :                 // any of the standard pdf tags, we write a user defined tag
    1109             :                 // <stylename> with role = P
    1110           0 :                 nPDFType = static_cast<sal_uInt16>(vcl::PDFWriter::Paragraph);
    1111           0 :                 aPDFType = sStyleName;
    1112             : 
    1113             :                 //
    1114             :                 // Quotations: BlockQuote
    1115             :                 //
    1116           0 :                 if ( sStyleName.EqualsAscii(aQuotations) )
    1117             :                 {
    1118           0 :                     nPDFType = static_cast<sal_uInt16>(vcl::PDFWriter::BlockQuote);
    1119           0 :                     aPDFType = OUString(aBlockQuoteString);
    1120             :                 }
    1121             : 
    1122             :                 //
    1123             :                 // Caption: Caption
    1124             :                 //
    1125           0 :                 else if ( sStyleName.EqualsAscii(aCaption) )
    1126             :                 {
    1127           0 :                     nPDFType = static_cast<sal_uInt16>(vcl::PDFWriter::Caption);
    1128           0 :                     aPDFType = OUString(aCaptionString);
    1129             :                 }
    1130             : 
    1131             :                 //
    1132             :                 // Caption: Caption
    1133             :                 //
    1134           0 :                 else if ( sParentStyleName.EqualsAscii(aCaption) )
    1135             :                 {
    1136           0 :                     nPDFType = static_cast<sal_uInt16>(vcl::PDFWriter::Caption);
    1137           0 :                     aPDFType = sStyleName.Append(OUString(aCaptionString));
    1138             :                 }
    1139             : 
    1140             :                 //
    1141             :                 // Heading: H
    1142             :                 //
    1143           0 :                 else if ( sStyleName.EqualsAscii(aHeading) )
    1144             :                 {
    1145           0 :                     nPDFType = static_cast<sal_uInt16>(vcl::PDFWriter::Heading);
    1146           0 :                     aPDFType = OUString(aHString);
    1147             :                 }
    1148             : 
    1149             :                 //
    1150             :                 // Heading: H1 - H6
    1151             :                 //
    1152           0 :                 if ( pTxtNd->IsOutline() )
    1153             :                 {
    1154             :                     //int nRealLevel = pTxtNd->GetOutlineLevel();   //#outline level,zhaojianwei
    1155           0 :                     int nRealLevel = pTxtNd->GetAttrOutlineLevel()-1;       //<-end,zhaojianwei
    1156           0 :                    nRealLevel = nRealLevel > 5 ? 5 : nRealLevel;
    1157             : 
    1158           0 :                     nPDFType =  static_cast<sal_uInt16>(vcl::PDFWriter::H1 + nRealLevel);
    1159           0 :                     switch(nRealLevel)
    1160             :                     {
    1161             :                         case 0 :
    1162           0 :                             aPDFType = OUString(aH1String);
    1163           0 :                             break;
    1164             :                         case 1 :
    1165           0 :                             aPDFType = OUString(aH2String);
    1166           0 :                             break;
    1167             :                         case 2 :
    1168           0 :                             aPDFType = OUString(aH3String);
    1169           0 :                             break;
    1170             :                         case 3 :
    1171           0 :                             aPDFType = OUString(aH4String);
    1172           0 :                             break;
    1173             :                         case 4 :
    1174           0 :                             aPDFType = OUString(aH5String);
    1175           0 :                             break;
    1176             :                         default:
    1177           0 :                             aPDFType = OUString(aH6String);
    1178           0 :                             break;
    1179             :                     }
    1180             :                 }
    1181             : 
    1182             :                 //
    1183             :                 // Section: TOCI
    1184             :                 //
    1185           0 :                 else if ( pFrm->IsInSct() )
    1186             :                 {
    1187           0 :                     const SwSectionFrm* pSctFrm = pFrm->FindSctFrm();
    1188             :                     const SwSection* pSection =
    1189           0 :                             static_cast<const SwSectionFrm*>(pSctFrm)->GetSection();
    1190             : 
    1191           0 :                     if ( TOX_CONTENT_SECTION == pSection->GetType() )
    1192             :                     {
    1193           0 :                         const SwTOXBase* pTOXBase = pSection->GetTOXBase();
    1194           0 :                         if ( pTOXBase && TOX_INDEX != pTOXBase->GetType() )
    1195             :                         {
    1196             :                             // Special case: Open additional TOCI tag:
    1197           0 :                             BeginTag( vcl::PDFWriter::TOCI, OUString(aTOCIString) );
    1198             :                         }
    1199             :                     }
    1200           0 :                 }
    1201             :             }
    1202           0 :             break;
    1203             : 
    1204             :         case FRM_TAB :
    1205             :             //
    1206             :             // TabFrm: Table
    1207             :             //
    1208           0 :             nPDFType = vcl::PDFWriter::Table;
    1209           0 :             aPDFType = OUString(aTableString);
    1210             : 
    1211             :             {
    1212             :                 // set up table column data:
    1213           0 :                 const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>(pFrm);
    1214           0 :                 const SwTable* pTable = pTabFrm->GetTable();
    1215             : 
    1216           0 :                 TableColumnsMap& rTableColumnsMap = SwEnhancedPDFExportHelper::GetTableColumnsMap();
    1217           0 :                 const TableColumnsMap::const_iterator aIter = rTableColumnsMap.find( pTable );
    1218             : 
    1219           0 :                 if ( aIter == rTableColumnsMap.end() )
    1220             :                 {
    1221           0 :                     SWRECTFN( pTabFrm )
    1222           0 :                     TableColumnsMapEntry& rCols = rTableColumnsMap[ pTable ];
    1223             : 
    1224           0 :                     const SwTabFrm* pMasterFrm = pTabFrm->IsFollow() ? pTabFrm->FindMaster( true ) : pTabFrm;
    1225             : 
    1226           0 :                     while ( pMasterFrm )
    1227             :                     {
    1228           0 :                         const SwRowFrm* pRowFrm = static_cast<const SwRowFrm*>(pMasterFrm->GetLower());
    1229             : 
    1230           0 :                         while ( pRowFrm )
    1231             :                         {
    1232           0 :                             const SwFrm* pCellFrm = pRowFrm->GetLower();
    1233             : 
    1234           0 :                             const long nLeft  = (pCellFrm->Frm().*fnRect->fnGetLeft)();
    1235           0 :                             rCols.insert( nLeft );
    1236             : 
    1237           0 :                             while ( pCellFrm )
    1238             :                             {
    1239           0 :                                 const long nRight = (pCellFrm->Frm().*fnRect->fnGetRight)();
    1240           0 :                                 rCols.insert( nRight );
    1241           0 :                                 pCellFrm = pCellFrm->GetNext();
    1242             :                             }
    1243           0 :                             pRowFrm = static_cast<const SwRowFrm*>(pRowFrm->GetNext());
    1244             :                         }
    1245           0 :                         pMasterFrm = static_cast<const SwTabFrm*>(pMasterFrm->GetFollow());
    1246             :                     }
    1247             :                 }
    1248             :             }
    1249             : 
    1250           0 :             break;
    1251             : 
    1252             :         /*
    1253             :          * TABLE ELEMENTS
    1254             :          */
    1255             : 
    1256             :         case FRM_ROW :
    1257             :             //
    1258             :             // RowFrm: TR
    1259             :             //
    1260           0 :             if ( !static_cast<const SwRowFrm*>(pFrm)->IsRepeatedHeadline() )
    1261             :             {
    1262           0 :                 nPDFType = vcl::PDFWriter::TableRow;
    1263           0 :                 aPDFType = OUString(aTRString);
    1264             :             }
    1265             :             else
    1266             :             {
    1267           0 :                 nPDFType = vcl::PDFWriter::NonStructElement;
    1268             :             }
    1269           0 :             break;
    1270             : 
    1271             :         case FRM_CELL :
    1272             :             //
    1273             :             // CellFrm: TH, TD
    1274             :             //
    1275             :             {
    1276           0 :                 const SwTabFrm* pTable = static_cast<const SwCellFrm*>(pFrm)->FindTabFrm();
    1277           0 :                 if ( pTable->IsInHeadline( *pFrm ) || lcl_IsHeadlineCell( *static_cast<const SwCellFrm*>(pFrm) ) )
    1278             :                 {
    1279           0 :                     nPDFType = vcl::PDFWriter::TableHeader;
    1280           0 :                     aPDFType = OUString(aTHString);
    1281             :                 }
    1282             :                 else
    1283             :                 {
    1284           0 :                     nPDFType = vcl::PDFWriter::TableData;
    1285           0 :                     aPDFType = OUString(aTDString);
    1286             :                 }
    1287             :             }
    1288           0 :             break;
    1289             : 
    1290             :         /*
    1291             :          * ILLUSTRATION
    1292             :          */
    1293             : 
    1294             :         case FRM_FLY :
    1295             :             //
    1296             :             // FlyFrm: Figure, Formula, Control
    1297             :             // fly in content or fly at page
    1298             :             {
    1299           0 :                 bool bFormula = false;
    1300           0 :                 const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pFrm);
    1301           0 :                 if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
    1302             :                 {
    1303           0 :                     const SwNoTxtFrm* pNoTxtFrm = static_cast<const SwNoTxtFrm*>(pFly->Lower());
    1304           0 :                     SwOLENode* pOLENd = const_cast<SwOLENode*>(pNoTxtFrm->GetNode()->GetOLENode());
    1305           0 :                     if ( pOLENd )
    1306             :                     {
    1307           0 :                         SwOLEObj& aOLEObj = pOLENd->GetOLEObj();
    1308           0 :                         uno::Reference< embed::XEmbeddedObject > aRef = aOLEObj.GetOleRef();
    1309           0 :                         if ( aRef.is() )
    1310             :                         {
    1311           0 :                             bFormula = 0 != SotExchange::IsMath( SvGlobalName( aRef->getClassID() ) );
    1312           0 :                         }
    1313             :                     }
    1314           0 :                     if ( bFormula )
    1315             :                     {
    1316           0 :                         nPDFType = vcl::PDFWriter::Formula;
    1317           0 :                         aPDFType = OUString(aFormulaString);
    1318             :                     }
    1319             :                     else
    1320             :                     {
    1321           0 :                         nPDFType = vcl::PDFWriter::Figure;
    1322           0 :                         aPDFType = OUString(aFigureString);
    1323             :                     }
    1324             :                 }
    1325             :                 else
    1326             :                 {
    1327           0 :                     nPDFType = vcl::PDFWriter::Division;
    1328           0 :                     aPDFType = OUString(aDivString);
    1329             :                 }
    1330             :             }
    1331           0 :             break;
    1332             :     }
    1333             : 
    1334           0 :     if ( USHRT_MAX != nPDFType )
    1335             :     {
    1336           0 :         BeginTag( static_cast<vcl::PDFWriter::StructElement>(nPDFType), aPDFType );
    1337           0 :     }
    1338             : }
    1339             : 
    1340             : 
    1341             : /*
    1342             :  * SwTaggedPDFHelper::EndStructureElements()
    1343             :  */
    1344           0 : void SwTaggedPDFHelper::EndStructureElements()
    1345             : {
    1346           0 :     while ( nEndStructureElement > 0 )
    1347             :     {
    1348           0 :         EndTag();
    1349           0 :         --nEndStructureElement;
    1350             :     }
    1351             : 
    1352           0 :     CheckRestoreTag();
    1353           0 : }
    1354             : 
    1355             : 
    1356             : /*
    1357             :  * SwTaggedPDFHelper::BeginInlineStructureElements()
    1358             :  */
    1359           0 : void SwTaggedPDFHelper::BeginInlineStructureElements()
    1360             : {
    1361           0 :     const SwLinePortion* pPor = &mpPorInfo->mrPor;
    1362           0 :     const SwTxtPaintInfo& rInf = mpPorInfo->mrTxtPainter.GetInfo();
    1363           0 :     const SwTxtFrm* pFrm = rInf.GetTxtFrm();
    1364             : 
    1365             :     //
    1366             :     // Lowers of NonStructureElements should not be considered:
    1367             :     //
    1368           0 :     if ( lcl_IsInNonStructEnv( *pFrm ) )
    1369           0 :         return;
    1370             : 
    1371           0 :     sal_uInt16 nPDFType = USHRT_MAX;
    1372           0 :     String aPDFType;
    1373             : 
    1374           0 :     switch ( pPor->GetWhichPor() )
    1375             :     {
    1376             :         // Check for alternative spelling:
    1377             :         case POR_HYPHSTR :
    1378             :         case POR_SOFTHYPHSTR :
    1379           0 :             nPDFType = vcl::PDFWriter::Span;
    1380           0 :             aPDFType = OUString(aSpanString);
    1381           0 :             break;
    1382             : 
    1383             :         case POR_LAY :
    1384             :         case POR_TXT :
    1385             :         case POR_PARA :
    1386             :             {
    1387           0 :                 SwTxtNode* pNd = (SwTxtNode*)pFrm->GetTxtNode();
    1388             :                 SwTxtAttr const*const pInetFmtAttr =
    1389           0 :                     pNd->GetTxtAttrAt(rInf.GetIdx(), RES_TXTATR_INETFMT);
    1390             : 
    1391           0 :                 String sStyleName;
    1392           0 :                 if ( !pInetFmtAttr )
    1393             :                 {
    1394             :                     ::std::vector<SwTxtAttr *> const charAttrs(
    1395           0 :                         pNd->GetTxtAttrsAt(rInf.GetIdx(), RES_TXTATR_CHARFMT));
    1396             :                     // TODO: handle more than 1 char style?
    1397           0 :                     const SwCharFmt* pCharFmt = (charAttrs.size())
    1398           0 :                         ? (*charAttrs.begin())->GetCharFmt().GetCharFmt() : 0;
    1399           0 :                     if ( pCharFmt )
    1400           0 :                         SwStyleNameMapper::FillProgName( pCharFmt->GetName(), sStyleName, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, true );
    1401             :                 }
    1402             : 
    1403             :                 // Check for Link:
    1404           0 :                 if( pInetFmtAttr )
    1405             :                 {
    1406           0 :                     nPDFType = vcl::PDFWriter::Link;
    1407           0 :                     aPDFType = OUString(aLinkString);
    1408             :                 }
    1409             :                 // Check for Quote/Code character style:
    1410           0 :                 else if ( sStyleName.EqualsAscii(aQuotation) )
    1411             :                 {
    1412           0 :                     nPDFType = vcl::PDFWriter::Quote;
    1413           0 :                     aPDFType = OUString(aQuoteString);
    1414             :                 }
    1415           0 :                 else if ( sStyleName.EqualsAscii(aSourceText) )
    1416             :                 {
    1417           0 :                     nPDFType = vcl::PDFWriter::Code;
    1418           0 :                     aPDFType = OUString(aCodeString);
    1419             :                 }
    1420             :                 else
    1421             :                 {
    1422           0 :                     const LanguageType nCurrentLanguage = rInf.GetFont()->GetLanguage();
    1423           0 :                     const sal_uInt16 nFont = rInf.GetFont()->GetActual();
    1424           0 :                     const LanguageType nDefaultLang = SwEnhancedPDFExportHelper::GetDefaultLanguage();
    1425             : 
    1426           0 :                     if ( UNDERLINE_NONE    != rInf.GetFont()->GetUnderline() ||
    1427           0 :                          UNDERLINE_NONE    != rInf.GetFont()->GetOverline()  ||
    1428           0 :                          STRIKEOUT_NONE    != rInf.GetFont()->GetStrikeout() ||
    1429           0 :                          EMPHASISMARK_NONE != rInf.GetFont()->GetEmphasisMark() ||
    1430           0 :                          0                 != rInf.GetFont()->GetEscapement() ||
    1431           0 :                          SW_LATIN          != nFont ||
    1432           0 :                          nCurrentLanguage  != nDefaultLang ||
    1433           0 :                          sStyleName.Len()  > 0 )
    1434             :                     {
    1435           0 :                         nPDFType = vcl::PDFWriter::Span;
    1436           0 :                         if ( sStyleName.Len() > 0 )
    1437           0 :                             aPDFType = sStyleName;
    1438             :                         else
    1439           0 :                             aPDFType = OUString(aSpanString);
    1440             :                     }
    1441           0 :                 }
    1442             :             }
    1443           0 :             break;
    1444             : 
    1445             :         case POR_FTN :
    1446           0 :             nPDFType = vcl::PDFWriter::Link;
    1447           0 :             aPDFType = OUString(aLinkString);
    1448           0 :             break;
    1449             : 
    1450             :         case POR_FLD :
    1451             :             {
    1452             :                 // check field type:
    1453           0 :                 const xub_StrLen nIdx = static_cast<const SwFldPortion*>(pPor)->IsFollow() ?
    1454           0 :                                         rInf.GetIdx() - 1 :
    1455           0 :                                         rInf.GetIdx();
    1456           0 :                 const SwTxtAttr* pHint = mpPorInfo->mrTxtPainter.GetAttr( nIdx );
    1457           0 :                 const SwField* pFld = 0;
    1458           0 :                 if ( pHint && RES_TXTATR_FIELD == pHint->Which() )
    1459             :                 {
    1460           0 :                     pFld = (SwField*)pHint->GetFld().GetFld();
    1461           0 :                     if ( RES_GETREFFLD == pFld->Which() )
    1462             :                     {
    1463           0 :                         nPDFType = vcl::PDFWriter::Link;
    1464           0 :                         aPDFType = OUString(aLinkString);
    1465             :                     }
    1466           0 :                     else if ( RES_AUTHORITY == pFld->Which() )
    1467             :                     {
    1468           0 :                         nPDFType = vcl::PDFWriter::BibEntry;
    1469           0 :                         aPDFType = OUString(aBibEntryString);
    1470             :                     }
    1471             :                 }
    1472             :             }
    1473           0 :             break;
    1474             : 
    1475             :         case POR_TAB :
    1476             :         case POR_TABRIGHT :
    1477             :         case POR_TABCENTER :
    1478             :         case POR_TABDECIMAL :
    1479           0 :             nPDFType = vcl::PDFWriter::NonStructElement;
    1480           0 :             break;
    1481             :     }
    1482             : 
    1483           0 :     if ( USHRT_MAX != nPDFType )
    1484             :     {
    1485           0 :         BeginTag( static_cast<vcl::PDFWriter::StructElement>(nPDFType), aPDFType );
    1486           0 :     }
    1487             : }
    1488             : 
    1489             : /*
    1490             :  * static SwTaggedPDFHelper::IsExportTaggedPDF
    1491             :  */
    1492         183 :  bool SwTaggedPDFHelper::IsExportTaggedPDF( const OutputDevice& rOut )
    1493             :  {
    1494         183 :     vcl::PDFExtOutDevData* pPDFExtOutDevData = PTR_CAST( vcl::PDFExtOutDevData, rOut.GetExtOutDevData() );
    1495         183 :     return pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportTaggedPDF();
    1496             :  }
    1497             : 
    1498             : /*
    1499             :  * SwEnhancedPDFExportHelper::SwEnhancedPDFExportHelper()
    1500             :  */
    1501           0 : SwEnhancedPDFExportHelper::SwEnhancedPDFExportHelper( SwEditShell& rSh,
    1502             :                                                       OutputDevice& rOut,
    1503             :                                                       const OUString& rPageRange,
    1504             :                                                       bool bSkipEmptyPages,
    1505             :                                                       bool bEditEngineOnly )
    1506             :     : mrSh( rSh ),
    1507             :       mrOut( rOut ),
    1508             :       mpRangeEnum( 0 ),
    1509             :       mbSkipEmptyPages( bSkipEmptyPages ),
    1510           0 :       mbEditEngineOnly( bEditEngineOnly )
    1511             : {
    1512           0 :     if ( !rPageRange.isEmpty() )
    1513           0 :         mpRangeEnum = new StringRangeEnumerator( rPageRange, 0, mrSh.GetPageCount()-1 );
    1514             : 
    1515           0 :     if ( mbSkipEmptyPages )
    1516             :     {
    1517           0 :         maPageNumberMap.resize( mrSh.GetPageCount() );
    1518             :         const SwPageFrm* pCurrPage =
    1519           0 :             static_cast<const SwPageFrm*>( mrSh.GetLayout()->Lower() );
    1520           0 :         sal_Int32 nPageNumber = 0;
    1521           0 :         for ( size_t i = 0, n = maPageNumberMap.size(); i < n && pCurrPage; ++i )
    1522             :         {
    1523           0 :             if ( pCurrPage->IsEmptyPage() )
    1524           0 :                 maPageNumberMap[i] = -1;
    1525             :             else
    1526           0 :                 maPageNumberMap[i] = nPageNumber++;
    1527             : 
    1528           0 :             pCurrPage = static_cast<const SwPageFrm*>( pCurrPage->GetNext() );
    1529             :         }
    1530             :     }
    1531             : 
    1532           0 :     aTableColumnsMap.clear();
    1533           0 :     aLinkIdMap.clear();
    1534           0 :     aNumListIdMap.clear();
    1535           0 :     aNumListBodyIdMap.clear();
    1536           0 :     aFrmTagIdMap.clear();
    1537             : 
    1538             : #if OSL_DEBUG_LEVEL > 1
    1539             :     aStructStack.clear();
    1540             : #endif
    1541             : 
    1542           0 :     const sal_uInt8 nScript = (sal_uInt8)GetI18NScriptTypeOfLanguage( (sal_uInt16)GetAppLanguage() );
    1543           0 :     sal_uInt16 nLangRes = RES_CHRATR_LANGUAGE;
    1544             : 
    1545           0 :     if ( i18n::ScriptType::ASIAN == nScript )
    1546           0 :         nLangRes = RES_CHRATR_CJK_LANGUAGE;
    1547           0 :     else if ( i18n::ScriptType::COMPLEX == nScript )
    1548           0 :         nLangRes = RES_CHRATR_CTL_LANGUAGE;
    1549             : 
    1550           0 :     eLanguageDefault = static_cast<const SvxLanguageItem*>(&mrSh.GetDoc()->GetDefault( nLangRes ))->GetLanguage();
    1551             : 
    1552           0 :     EnhancedPDFExport();
    1553           0 : }
    1554             : 
    1555           0 : SwEnhancedPDFExportHelper::~SwEnhancedPDFExportHelper()
    1556             : {
    1557           0 :     delete mpRangeEnum;
    1558           0 : }
    1559             : 
    1560             : /*
    1561             :  * SwEnhancedPDFExportHelper::EnhancedPDFExport()
    1562             :  */
    1563           0 : void SwEnhancedPDFExportHelper::EnhancedPDFExport()
    1564             : {
    1565             :     vcl::PDFExtOutDevData* pPDFExtOutDevData =
    1566           0 :         PTR_CAST( vcl::PDFExtOutDevData, mrOut.GetExtOutDevData() );
    1567             : 
    1568           0 :     if ( !pPDFExtOutDevData )
    1569           0 :         return;
    1570             : 
    1571             :     //
    1572             :     // set the document locale
    1573             :     //
    1574           0 :     com::sun::star::lang::Locale aDocLocale( LanguageTag( SwEnhancedPDFExportHelper::GetDefaultLanguage() ).getLocale() );
    1575           0 :     pPDFExtOutDevData->SetDocumentLocale( aDocLocale );
    1576             : 
    1577             :     //
    1578             :     // Prepare the output device:
    1579             :     //
    1580           0 :     mrOut.Push( PUSH_MAPMODE );
    1581           0 :     MapMode aMapMode( mrOut.GetMapMode() );
    1582           0 :     aMapMode.SetMapUnit( MAP_TWIP );
    1583           0 :     mrOut.SetMapMode( aMapMode );
    1584             : 
    1585             :     //
    1586             :     // Create new cursor and lock the view:
    1587             :     //
    1588           0 :     SwDoc* pDoc = mrSh.GetDoc();
    1589           0 :     mrSh.SwCrsrShell::Push();
    1590           0 :     mrSh.SwCrsrShell::ClearMark();
    1591           0 :     const sal_Bool bOldLockView = mrSh.IsViewLocked();
    1592           0 :     mrSh.LockView( sal_True );
    1593             : 
    1594           0 :     if ( !mbEditEngineOnly )
    1595             :     {
    1596             :         //
    1597             :         // POSTITS
    1598             :         //
    1599           0 :         if ( pPDFExtOutDevData->GetIsExportNotes() )
    1600             :         {
    1601           0 :             SwFieldType* pType = mrSh.GetFldType( RES_POSTITFLD, aEmptyStr );
    1602           0 :             SwIterator<SwFmtFld,SwFieldType> aIter( *pType );
    1603           0 :             for( SwFmtFld* pFirst = aIter.First(); pFirst; )
    1604             :             {
    1605           0 :                 if( pFirst->GetTxtFld() && pFirst->IsFldInDoc() )
    1606             :                 {
    1607           0 :                     const SwTxtNode* pTNd = (SwTxtNode*)pFirst->GetTxtFld()->GetpTxtNode();
    1608             :                     OSL_ENSURE( 0 != pTNd, "Enhanced pdf export - text node is missing" );
    1609             : 
    1610             :                     // 1. Check if the whole paragraph is hidden
    1611             :                     // 2. Move to the field
    1612             :                     // 3. Check for hidden text attribute
    1613           0 :                     if ( !pTNd->IsHidden() &&
    1614           0 :                           mrSh.GotoFld( *pFirst ) &&
    1615           0 :                          !mrSh.SelectHiddenRange() )
    1616             :                     {
    1617             :                         // Link Rectangle
    1618           0 :                         const SwRect& rNoteRect = mrSh.GetCharRect();
    1619             : 
    1620             :                         // Link PageNums
    1621           0 :                         std::vector<sal_Int32> aNotePageNums = CalcOutputPageNums( rNoteRect );
    1622           0 :                         for ( size_t nNumIdx = 0; nNumIdx < aNotePageNums.size(); ++nNumIdx )
    1623             :                         {
    1624             :                             // Link Note
    1625           0 :                             vcl::PDFNote aNote;
    1626             : 
    1627             :                             // Use the NumberFormatter to get the date string:
    1628           0 :                             const SwPostItField* pField = (SwPostItField*)pFirst->GetFld();
    1629           0 :                             SvNumberFormatter* pNumFormatter = pDoc->GetNumberFormatter();
    1630           0 :                             const Date aDateDiff( pField->GetDate() -
    1631           0 :                                                  *pNumFormatter->GetNullDate() );
    1632             :                             const sal_uLong nFormat =
    1633           0 :                                 pNumFormatter->GetStandardFormat( NUMBERFORMAT_DATE, pField->GetLanguage() );
    1634           0 :                             OUString sDate;
    1635             :                             Color* pColor;
    1636           0 :                             pNumFormatter->GetOutputString( aDateDiff.GetDate(), nFormat, sDate, &pColor );
    1637             : 
    1638             :                             // The title should consist of the author and the date:
    1639           0 :                             String sTitle( pField->GetPar1() );
    1640           0 :                             sTitle.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ", " ) );
    1641           0 :                             sTitle += sDate;
    1642           0 :                             aNote.Title = sTitle;
    1643             :                             // Guess what the contents contains...
    1644           0 :                             aNote.Contents = pField->GetTxt();
    1645             : 
    1646             :                             // Link Export
    1647           0 :                             pPDFExtOutDevData->CreateNote( rNoteRect.SVRect(), aNote, aNotePageNums[nNumIdx] );
    1648           0 :                         }
    1649             :                     }
    1650             :                 }
    1651           0 :                 pFirst = aIter.Next();
    1652           0 :                 mrSh.SwCrsrShell::ClearMark();
    1653           0 :             }
    1654             :         }
    1655             : 
    1656             :         //
    1657             :         // HYPERLINKS
    1658             :         //
    1659           0 :         SwGetINetAttrs aArr;
    1660           0 :         const sal_uInt16 nHyperLinkCount = mrSh.GetINetAttrs( aArr );
    1661           0 :         for( sal_uInt16 n = 0; n < nHyperLinkCount; ++n )
    1662             :         {
    1663           0 :             SwGetINetAttr* p = &aArr[ n ];
    1664             :             OSL_ENSURE( 0 != p, "Enhanced pdf export - SwGetINetAttr is missing" );
    1665             : 
    1666           0 :             const SwTxtNode* pTNd = p->rINetAttr.GetpTxtNode();
    1667             :             OSL_ENSURE( 0 != pTNd, "Enhanced pdf export - text node is missing" );
    1668             : 
    1669             :             // 1. Check if the whole paragraph is hidden
    1670             :             // 2. Move to the hyperlink
    1671             :             // 3. Check for hidden text attribute
    1672           0 :             if ( !pTNd->IsHidden() &&
    1673           0 :                   mrSh.GotoINetAttr( p->rINetAttr ) &&
    1674           0 :                  !mrSh.SelectHiddenRange() )
    1675             :             {
    1676             :                 // Select the hyperlink:
    1677           0 :                 mrSh.SwCrsrShell::Right( 1, CRSR_SKIP_CHARS );
    1678           0 :                 if ( mrSh.SwCrsrShell::SelectTxtAttr( RES_TXTATR_INETFMT, sal_True ) )
    1679             :                 {
    1680             :                     // First, we create the destination, because there may be more
    1681             :                     // than one link to this destination:
    1682             :                     String aURL( INetURLObject::decode(
    1683           0 :                         p->rINetAttr.GetINetFmt().GetValue(),
    1684             :                         INET_HEX_ESCAPE,
    1685             :                         INetURLObject::DECODE_UNAMBIGUOUS,
    1686           0 :                         RTL_TEXTENCODING_UTF8 ) );
    1687             : 
    1688             :                     // We have to distinguish between intern and real URLs
    1689           0 :                     const bool bIntern = '#' == aURL.GetChar( 0 );
    1690             : 
    1691             :                     // _GetCrsr() is a SwShellCrsr, which is derived from
    1692             :                     // SwSelPaintRects, therefore the rectangles of the current
    1693             :                     // selection can be easily obtained:
    1694             :                     // Note: We make a copy of the rectangles, because they may
    1695             :                     // be deleted again in JumpToSwMark.
    1696           0 :                     SwRects aTmp;
    1697           0 :                     aTmp.insert( aTmp.begin(), mrSh.SwCrsrShell::_GetCrsr()->begin(), mrSh.SwCrsrShell::_GetCrsr()->end() );
    1698             :                     OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" );
    1699             : 
    1700             :                     // Create the destination for internal links:
    1701           0 :                     sal_Int32 nDestId = -1;
    1702           0 :                     if ( bIntern )
    1703             :                     {
    1704           0 :                         aURL.Erase( 0, 1 );
    1705           0 :                         mrSh.SwCrsrShell::ClearMark();
    1706           0 :                         JumpToSwMark( &mrSh, aURL );
    1707             : 
    1708             :                         // Destination Rectangle
    1709           0 :                         const SwRect& rDestRect = mrSh.GetCharRect();
    1710             : 
    1711             :                         // Destination PageNum
    1712           0 :                         const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
    1713             : 
    1714             :                         // Destination Export
    1715           0 :                         if ( -1 != nDestPageNum )
    1716           0 :                             nDestId = pPDFExtOutDevData->CreateDest( rDestRect.SVRect(), nDestPageNum );
    1717             :                     }
    1718             : 
    1719           0 :                     if ( !bIntern || -1 != nDestId )
    1720             :                     {
    1721             :                         // #i44368# Links in Header/Footer
    1722           0 :                         const SwPosition aPos( *pTNd );
    1723           0 :                         const bool bHeaderFooter = pDoc->IsInHeaderFooter( aPos.nNode );
    1724             : 
    1725             :                         // Create links for all selected rectangles:
    1726           0 :                         const sal_uInt16 nNumOfRects = aTmp.size();
    1727           0 :                         for ( sal_uInt16 i = 0; i < nNumOfRects; ++i )
    1728             :                         {
    1729             :                             // Link Rectangle
    1730           0 :                             const SwRect& rLinkRect( aTmp[ i ] );
    1731             : 
    1732             :                             // Link PageNums
    1733           0 :                             std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( rLinkRect );
    1734             : 
    1735           0 :                             for ( size_t nNumIdx = 0; nNumIdx < aLinkPageNums.size(); ++nNumIdx )
    1736             :                             {
    1737             :                                 // Link Export
    1738             :                                 const sal_Int32 nLinkId =
    1739           0 :                                     pPDFExtOutDevData->CreateLink( rLinkRect.SVRect(), aLinkPageNums[nNumIdx] );
    1740             : 
    1741             :                                 // Store link info for tagged pdf output:
    1742           0 :                                 const IdMapEntry aLinkEntry( rLinkRect, nLinkId );
    1743           0 :                                 aLinkIdMap.push_back( aLinkEntry );
    1744             : 
    1745             :                                 // Connect Link and Destination:
    1746           0 :                                 if ( bIntern )
    1747           0 :                                     pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
    1748             :                                 else
    1749           0 :                                     pPDFExtOutDevData->SetLinkURL( nLinkId, aURL );
    1750             : 
    1751             :                                 // #i44368# Links in Header/Footer
    1752           0 :                                 if ( bHeaderFooter )
    1753           0 :                                     MakeHeaderFooterLinks( *pPDFExtOutDevData, *pTNd, rLinkRect, nDestId, aURL, bIntern );
    1754             :                             }
    1755           0 :                         }
    1756           0 :                     }
    1757             :                 }
    1758             :             }
    1759           0 :             mrSh.SwCrsrShell::ClearMark();
    1760             :         }
    1761             : 
    1762             :         //
    1763             :         // HYPERLINKS (Graphics, Frames, OLEs )
    1764             :         //
    1765           0 :         const SwFrmFmts* pTbl = pDoc->GetSpzFrmFmts();
    1766           0 :         const sal_uInt16 nSpzFrmFmtsCount = pTbl->size();
    1767           0 :         for( sal_uInt16 n = 0; n < nSpzFrmFmtsCount; ++n )
    1768             :         {
    1769           0 :             const SwFrmFmt* pFrmFmt = (*pTbl)[n];
    1770             :             const SfxPoolItem* pItem;
    1771           0 :             if ( RES_DRAWFRMFMT != pFrmFmt->Which() &&
    1772           0 :                  SFX_ITEM_SET == pFrmFmt->GetAttrSet().GetItemState( RES_URL, sal_True, &pItem ) )
    1773             :             {
    1774           0 :                 String aURL( static_cast<const SwFmtURL*>(pItem)->GetURL() );
    1775           0 :                 const bool bIntern = '#' == aURL.GetChar( 0 );
    1776             : 
    1777             :                 // Create the destination for internal links:
    1778           0 :                 sal_Int32 nDestId = -1;
    1779           0 :                 if ( bIntern )
    1780             :                 {
    1781           0 :                     aURL.Erase( 0, 1 );
    1782           0 :                     mrSh.SwCrsrShell::ClearMark();
    1783           0 :                     JumpToSwMark( &mrSh, aURL );
    1784             : 
    1785             :                     // Destination Rectangle
    1786           0 :                     const SwRect& rDestRect = mrSh.GetCharRect();
    1787             : 
    1788             :                     // Destination PageNum
    1789           0 :                     const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
    1790             : 
    1791             :                     // Destination Export
    1792           0 :                     if ( -1 != nDestPageNum )
    1793           0 :                         nDestId = pPDFExtOutDevData->CreateDest( rDestRect.SVRect(), nDestPageNum );
    1794             :                 }
    1795             : 
    1796           0 :                 if ( !bIntern || -1 != nDestId )
    1797             :                 {
    1798           0 :                     Point aNullPt;
    1799           0 :                     const SwRect aLinkRect = pFrmFmt->FindLayoutRect( sal_False, &aNullPt );
    1800             : 
    1801             :                     // Link PageNums
    1802           0 :                     std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( aLinkRect );
    1803             : 
    1804             :                     // Link Export
    1805           0 :                     for ( size_t nNumIdx = 0; nNumIdx < aLinkPageNums.size(); ++nNumIdx )
    1806             :                     {
    1807             :                         const sal_Int32 nLinkId =
    1808           0 :                             pPDFExtOutDevData->CreateLink( aLinkRect.SVRect(), aLinkPageNums[nNumIdx] );
    1809             : 
    1810             :                         // Connect Link and Destination:
    1811           0 :                         if ( bIntern )
    1812           0 :                             pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
    1813             :                         else
    1814           0 :                             pPDFExtOutDevData->SetLinkURL( nLinkId, aURL );
    1815             : 
    1816             :                         // #i44368# Links in Header/Footer
    1817           0 :                         const SwFmtAnchor &rAnch = pFrmFmt->GetAnchor();
    1818           0 :                         if (FLY_AT_PAGE != rAnch.GetAnchorId())
    1819             :                         {
    1820           0 :                             const SwPosition* pPosition = rAnch.GetCntntAnchor();
    1821           0 :                             if ( pPosition && pDoc->IsInHeaderFooter( pPosition->nNode ) )
    1822             :                             {
    1823           0 :                                 const SwTxtNode* pTNd = pPosition->nNode.GetNode().GetTxtNode();
    1824           0 :                                 if ( pTNd )
    1825           0 :                                     MakeHeaderFooterLinks( *pPDFExtOutDevData, *pTNd, aLinkRect, nDestId, aURL, bIntern );
    1826             :                             }
    1827             :                         }
    1828           0 :                     }
    1829           0 :                 }
    1830             :             }
    1831           0 :             mrSh.SwCrsrShell::ClearMark();
    1832             :         }
    1833             : 
    1834             :         //
    1835             :         // REFERENCES
    1836             :         //
    1837           0 :         SwFieldType* pType = mrSh.GetFldType( RES_GETREFFLD, aEmptyStr );
    1838           0 :         SwIterator<SwFmtFld,SwFieldType> aIter( *pType );
    1839           0 :         for( SwFmtFld* pFirst = aIter.First(); pFirst; )
    1840             :         {
    1841           0 :             if( pFirst->GetTxtFld() && pFirst->IsFldInDoc() )
    1842             :             {
    1843           0 :                 const SwTxtNode* pTNd = (SwTxtNode*)pFirst->GetTxtFld()->GetpTxtNode();
    1844             :                OSL_ENSURE( 0 != pTNd, "Enhanced pdf export - text node is missing" );
    1845             : 
    1846             :                 // 1. Check if the whole paragraph is hidden
    1847             :                 // 2. Move to the field
    1848             :                 // 3. Check for hidden text attribute
    1849           0 :                 if ( !pTNd->IsHidden() &&
    1850           0 :                       mrSh.GotoFld( *pFirst ) &&
    1851           0 :                      !mrSh.SelectHiddenRange() )
    1852             :                 {
    1853             :                     // Select the field:
    1854           0 :                     mrSh.SwCrsrShell::SetMark();
    1855           0 :                     mrSh.SwCrsrShell::Right( 1, CRSR_SKIP_CHARS );
    1856             : 
    1857             :                     // Link Rectangles
    1858           0 :                     SwRects aTmp;
    1859           0 :                     aTmp.insert( aTmp.begin(), mrSh.SwCrsrShell::_GetCrsr()->begin(), mrSh.SwCrsrShell::_GetCrsr()->end() );
    1860             :                     OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" );
    1861             : 
    1862           0 :                     mrSh.SwCrsrShell::ClearMark();
    1863             : 
    1864             :                     // Destination Rectangle
    1865             :                     const SwGetRefField* pField =
    1866           0 :                         (SwGetRefField*)pFirst->GetFld();
    1867           0 :                     const String& rRefName = pField->GetSetRefName();
    1868           0 :                     mrSh.GotoRefMark( rRefName, pField->GetSubType(), pField->GetSeqNo() );
    1869           0 :                     const SwRect& rDestRect = mrSh.GetCharRect();
    1870             : 
    1871             :                     // Destination PageNum
    1872           0 :                     const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
    1873             : 
    1874           0 :                     if ( -1 != nDestPageNum )
    1875             :                     {
    1876             :                         // Destination Export
    1877           0 :                         const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest( rDestRect.SVRect(), nDestPageNum );
    1878             : 
    1879             :                         // #i44368# Links in Header/Footer
    1880           0 :                         const SwPosition aPos( *pTNd );
    1881           0 :                         const bool bHeaderFooter = pDoc->IsInHeaderFooter( aPos.nNode );
    1882             : 
    1883             :                         // Create links for all selected rectangles:
    1884           0 :                         const sal_uInt16 nNumOfRects = aTmp.size();
    1885           0 :                         for ( sal_uInt16 i = 0; i < nNumOfRects; ++i )
    1886             :                         {
    1887             :                             // Link rectangle
    1888           0 :                             const SwRect& rLinkRect( aTmp[ i ] );
    1889             : 
    1890             :                             // Link PageNums
    1891           0 :                             std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( rLinkRect );
    1892             : 
    1893           0 :                             for ( size_t nNumIdx = 0; nNumIdx < aLinkPageNums.size(); ++nNumIdx )
    1894             :                             {
    1895             :                                 // Link Export
    1896             :                                 const sal_Int32 nLinkId =
    1897           0 :                                     pPDFExtOutDevData->CreateLink( rLinkRect.SVRect(), aLinkPageNums[nNumIdx] );
    1898             : 
    1899             :                                 // Store link info for tagged pdf output:
    1900           0 :                                 const IdMapEntry aLinkEntry( rLinkRect, nLinkId );
    1901           0 :                                 aLinkIdMap.push_back( aLinkEntry );
    1902             : 
    1903             :                                 // Connect Link and Destination:
    1904           0 :                                 pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
    1905             : 
    1906             :                                 // #i44368# Links in Header/Footer
    1907           0 :                                 if ( bHeaderFooter )
    1908             :                                 {
    1909           0 :                                     const String aDummy;
    1910           0 :                                     MakeHeaderFooterLinks( *pPDFExtOutDevData, *pTNd, rLinkRect, nDestId, aDummy, true );
    1911             :                                 }
    1912             :                             }
    1913           0 :                         }
    1914           0 :                     }
    1915             :                 }
    1916             :             }
    1917           0 :             pFirst = aIter.Next();
    1918           0 :             mrSh.SwCrsrShell::ClearMark();
    1919             :         }
    1920             : 
    1921             :         //
    1922             :         // FOOTNOTES
    1923             :         //
    1924           0 :         const sal_uInt16 nFtnCount = pDoc->GetFtnIdxs().size();
    1925           0 :         for ( sal_uInt16 nIdx = 0; nIdx < nFtnCount; ++nIdx )
    1926             :         {
    1927             :             // Set cursor to text node that contains the footnote:
    1928           0 :             const SwTxtFtn* pTxtFtn = pDoc->GetFtnIdxs()[ nIdx ];
    1929           0 :             SwTxtNode& rTNd = const_cast<SwTxtNode&>(pTxtFtn->GetTxtNode());
    1930             : 
    1931           0 :             mrSh._GetCrsr()->GetPoint()->nNode = rTNd;
    1932           0 :             mrSh._GetCrsr()->GetPoint()->nContent.Assign( &rTNd, *pTxtFtn->GetStart() );
    1933             : 
    1934             :             // 1. Check if the whole paragraph is hidden
    1935             :             // 2. Check for hidden text attribute
    1936           0 :             if ( static_cast<const SwTxtNode&>(rTNd).IsHidden() ||
    1937           0 :                  mrSh.SelectHiddenRange() )
    1938           0 :                 continue;
    1939             : 
    1940           0 :             SwCrsrSaveState aSaveState( *mrSh._GetCrsr() );
    1941             : 
    1942             :             // Select the footnote:
    1943           0 :             mrSh.SwCrsrShell::SetMark();
    1944           0 :             mrSh.SwCrsrShell::Right( 1, CRSR_SKIP_CHARS );
    1945             : 
    1946             :             // Link Rectangle
    1947           0 :             SwRects aTmp;
    1948           0 :             aTmp.insert( aTmp.begin(), mrSh.SwCrsrShell::_GetCrsr()->begin(), mrSh.SwCrsrShell::_GetCrsr()->end() );
    1949             :             OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" );
    1950           0 :             const SwRect aLinkRect( aTmp[ 0 ] );
    1951             : 
    1952           0 :             mrSh._GetCrsr()->RestoreSavePos();
    1953           0 :             mrSh.SwCrsrShell::ClearMark();
    1954             : 
    1955             :             // Goto footnote text:
    1956           0 :             if ( mrSh.GotoFtnTxt() )
    1957             :             {
    1958             :                 // Link PageNums
    1959           0 :                 std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( aLinkRect );
    1960             : 
    1961             :                 // Destination Rectangle
    1962           0 :                 const SwRect& rDestRect = mrSh.GetCharRect();
    1963             : 
    1964             :                 // Destination PageNum
    1965           0 :                 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
    1966             : 
    1967           0 :                 for ( size_t nNumIdx = 0; nNumIdx < aLinkPageNums.size(); ++nNumIdx )
    1968             :                 {
    1969             :                     // Link Export
    1970             :                     const sal_Int32 nLinkId =
    1971           0 :                         pPDFExtOutDevData->CreateLink( aLinkRect.SVRect(), aLinkPageNums[nNumIdx] );
    1972             : 
    1973             :                     // Store link info for tagged pdf output:
    1974           0 :                     const IdMapEntry aLinkEntry( aLinkRect, nLinkId );
    1975           0 :                     aLinkIdMap.push_back( aLinkEntry );
    1976             : 
    1977           0 :                     if ( -1 != nDestPageNum )
    1978             :                     {
    1979             :                         // Destination Export
    1980           0 :                         const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest( rDestRect.SVRect(), nDestPageNum );
    1981             : 
    1982             :                         // Connect Link and Destination:
    1983           0 :                         pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
    1984             :                     }
    1985           0 :                 }
    1986             :             }
    1987           0 :         }
    1988             : 
    1989             :         //
    1990             :         // OUTLINE
    1991             :         //
    1992           0 :         if( pPDFExtOutDevData->GetIsExportBookmarks() )
    1993             :         {
    1994             :             typedef std::pair< sal_Int8, sal_Int32 > StackEntry;
    1995           0 :             std::stack< StackEntry > aOutlineStack;
    1996           0 :             aOutlineStack.push( StackEntry( -1, -1 ) ); // push default value
    1997             : 
    1998             :             const sal_uInt16 nOutlineCount =
    1999           0 :                 static_cast<sal_uInt16>(mrSh.getIDocumentOutlineNodesAccess()->getOutlineNodesCount());
    2000           0 :             for ( sal_uInt16 i = 0; i < nOutlineCount; ++i )
    2001             :             {
    2002             :                 // Check if outline is hidden
    2003           0 :                 const SwTxtNode* pTNd = mrSh.GetNodes().GetOutLineNds()[ i ]->GetTxtNode();
    2004             :                 OSL_ENSURE( 0 != pTNd, "Enhanced pdf export - text node is missing" );
    2005             : 
    2006           0 :                 if ( pTNd->IsHidden() ||
    2007             :                      // #i40292# Skip empty outlines:
    2008           0 :                      pTNd->GetTxt().isEmpty())
    2009           0 :                     continue;
    2010             : 
    2011             :                 // Get parent id from stack:
    2012           0 :                 const sal_Int8 nLevel = (sal_Int8)mrSh.getIDocumentOutlineNodesAccess()->getOutlineLevel( i );
    2013           0 :                 sal_Int8 nLevelOnTopOfStack = aOutlineStack.top().first;
    2014           0 :                 while ( nLevelOnTopOfStack >= nLevel &&
    2015             :                         nLevelOnTopOfStack != -1 )
    2016             :                 {
    2017           0 :                     aOutlineStack.pop();
    2018           0 :                     nLevelOnTopOfStack = aOutlineStack.top().first;
    2019             :                 }
    2020           0 :                 const sal_Int32 nParent = aOutlineStack.top().second;
    2021             : 
    2022             :                 // Destination rectangle
    2023           0 :                 mrSh.GotoOutline(i);
    2024           0 :                 const SwRect& rDestRect = mrSh.GetCharRect();
    2025             : 
    2026             :                 // Destination PageNum
    2027           0 :                 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
    2028             : 
    2029           0 :                 if ( -1 != nDestPageNum )
    2030             :                 {
    2031             :                     // Destination Export
    2032             :                     const sal_Int32 nDestId =
    2033           0 :                         pPDFExtOutDevData->CreateDest( rDestRect.SVRect(), nDestPageNum );
    2034             : 
    2035             :                     // Outline entry text
    2036           0 :                     const String& rEntry = mrSh.getIDocumentOutlineNodesAccess()->getOutlineText( i );
    2037             : 
    2038             :                     // Create a new outline item:
    2039             :                     const sal_Int32 nOutlineId =
    2040           0 :                         pPDFExtOutDevData->CreateOutlineItem( nParent, rEntry, nDestId );
    2041             : 
    2042             :                     // Push current level and nOutlineId on stack:
    2043           0 :                     aOutlineStack.push( StackEntry( nLevel, nOutlineId ) );
    2044             :                 }
    2045           0 :             }
    2046             :         }
    2047             : 
    2048           0 :         if( pPDFExtOutDevData->GetIsExportNamedDestinations() )
    2049             :         {
    2050             :             // #i56629# the iteration to convert the OOo bookmark (#bookmark)
    2051             :             // into PDF named destination, see section 8.2.1 in PDF 1.4 spec
    2052             :             // We need:
    2053             :             // 1. a name for the destination, formed from the standard OOo bookmark name
    2054             :             // 2. the destination, obtained from where the bookmark destination lies
    2055           0 :             IDocumentMarkAccess* const pMarkAccess = mrSh.GetDoc()->getIDocumentMarkAccess();
    2056           0 :             for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getBookmarksBegin();
    2057           0 :                 ppMark != pMarkAccess->getBookmarksEnd();
    2058             :                 ++ppMark)
    2059             :             {
    2060             :                 //get the name
    2061           0 :                 const ::sw::mark::IMark* pBkmk = ppMark->get();
    2062           0 :                 mrSh.SwCrsrShell::ClearMark();
    2063           0 :                 OUString sBkName = pBkmk->GetName();
    2064             : 
    2065             :                 //jump to it
    2066           0 :                 JumpToSwMark( &mrSh, sBkName );
    2067             : 
    2068             :                 // Destination Rectangle
    2069           0 :                 const SwRect& rDestRect = mrSh.GetCharRect();
    2070             : 
    2071             :                 // Destination PageNum
    2072           0 :                 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
    2073             : 
    2074             :                 // Destination Export
    2075           0 :                 if ( -1 != nDestPageNum )
    2076           0 :                     pPDFExtOutDevData->CreateNamedDest( sBkName, rDestRect.SVRect(), nDestPageNum );
    2077           0 :             }
    2078           0 :             mrSh.SwCrsrShell::ClearMark();
    2079             :             //<--- i56629
    2080           0 :         }
    2081             :     }
    2082             :     else
    2083             :     {
    2084             :         //
    2085             :         // LINKS FROM EDITENGINE
    2086             :         //
    2087           0 :         std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFExtOutDevData->GetBookmarks();
    2088           0 :         std::vector< vcl::PDFExtOutDevBookmarkEntry >::const_iterator aIBeg = rBookmarks.begin();
    2089           0 :         const std::vector< vcl::PDFExtOutDevBookmarkEntry >::const_iterator aIEnd = rBookmarks.end();
    2090           0 :         while ( aIBeg != aIEnd )
    2091             :         {
    2092           0 :             String aBookmarkName( aIBeg->aBookmark );
    2093           0 :             const bool bIntern = '#' == aBookmarkName.GetChar( 0 );
    2094           0 :             if ( bIntern )
    2095             :             {
    2096           0 :                 aBookmarkName.Erase( 0, 1 );
    2097           0 :                 JumpToSwMark( &mrSh, aBookmarkName );
    2098             : 
    2099             :                 // Destination Rectangle
    2100           0 :                 const SwRect& rDestRect = mrSh.GetCharRect();
    2101             : 
    2102             :                 // Destination PageNum
    2103           0 :                 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
    2104             : 
    2105           0 :                 if ( -1 != nDestPageNum )
    2106             :                 {
    2107           0 :                     if ( aIBeg->nLinkId != -1 )
    2108             :                     {
    2109             :                         // Destination Export
    2110           0 :                         const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest( rDestRect.SVRect(), nDestPageNum );
    2111             : 
    2112             :                         // Connect Link and Destination:
    2113           0 :                         pPDFExtOutDevData->SetLinkDest( aIBeg->nLinkId, nDestId );
    2114             :                     }
    2115             :                     else
    2116             :                     {
    2117           0 :                         pPDFExtOutDevData->DescribeRegisteredDest( aIBeg->nDestId, rDestRect.SVRect(), nDestPageNum );
    2118             :                     }
    2119             :                 }
    2120             :             }
    2121             :             else
    2122           0 :                 pPDFExtOutDevData->SetLinkURL( aIBeg->nLinkId, aBookmarkName );
    2123             : 
    2124           0 :             ++aIBeg;
    2125           0 :         }
    2126           0 :         rBookmarks.clear();
    2127             :     }
    2128             : 
    2129             :     // Restore view, cursor, and outdev:
    2130           0 :     mrSh.LockView( bOldLockView );
    2131           0 :     mrSh.SwCrsrShell::Pop( sal_False );
    2132           0 :     mrOut.Pop();
    2133             : }
    2134             : 
    2135             : /*
    2136             :  * SwEnhancedPDFExportHelper::CalcOutputPageNum()
    2137             :  *
    2138             :  * Returns the page number in the output pdf on which the given rect is located.
    2139             :  * If this page is duplicated, method will return first occurrence of it.
    2140             :  */
    2141           0 : sal_Int32 SwEnhancedPDFExportHelper::CalcOutputPageNum( const SwRect& rRect ) const
    2142             : {
    2143           0 :     std::vector< sal_Int32 > aPageNums = CalcOutputPageNums( rRect );
    2144           0 :     if ( !aPageNums.empty() )
    2145           0 :         return aPageNums[0];
    2146           0 :     return -1;
    2147             : }
    2148             : 
    2149             : /*
    2150             :  * SwEnhancedPDFExportHelper::CalcOutputPageNums()
    2151             :  *
    2152             :  * Returns a vector of the page numbers in the output pdf on which the given
    2153             :  * rect is located. There can be many such pages since StringRangeEnumerator
    2154             :  * allows duplication of its entries.
    2155             :  */
    2156           0 : std::vector< sal_Int32 > SwEnhancedPDFExportHelper::CalcOutputPageNums(
    2157             :     const SwRect& rRect ) const
    2158             : {
    2159           0 :     std::vector< sal_Int32 > aPageNums;
    2160             : 
    2161             :     // Document page number.
    2162           0 :     sal_Int32 nPageNumOfRect = mrSh.GetPageNumAndSetOffsetForPDF( mrOut, rRect );
    2163           0 :     if ( nPageNumOfRect < 0 )
    2164           0 :         return aPageNums;
    2165             : 
    2166             :     // What will be the page numbers of page nPageNumOfRect in the output pdf?
    2167           0 :     if ( mpRangeEnum )
    2168             :     {
    2169           0 :         if ( mbSkipEmptyPages )
    2170             :             // Map the page number to the range without empty pages.
    2171           0 :             nPageNumOfRect = maPageNumberMap[ nPageNumOfRect ];
    2172             : 
    2173           0 :         if ( mpRangeEnum->hasValue( nPageNumOfRect ) )
    2174             :         {
    2175           0 :             sal_Int32 nOutputPageNum = 0;
    2176           0 :             StringRangeEnumerator::Iterator aIter = mpRangeEnum->begin();
    2177           0 :             StringRangeEnumerator::Iterator aEnd  = mpRangeEnum->end();
    2178           0 :             for ( ; aIter != aEnd; ++aIter )
    2179             :             {
    2180           0 :                 if ( *aIter == nPageNumOfRect )
    2181           0 :                     aPageNums.push_back( nOutputPageNum );
    2182           0 :                 ++nOutputPageNum;
    2183             :             }
    2184             :         }
    2185             :     }
    2186             :     else
    2187             :     {
    2188           0 :         if ( mbSkipEmptyPages )
    2189             :         {
    2190           0 :             sal_Int32 nOutputPageNum = 0;
    2191           0 :             for ( size_t i = 0; i < maPageNumberMap.size(); ++i )
    2192             :             {
    2193           0 :                 if ( maPageNumberMap[i] >= 0 ) // is not empty?
    2194             :                 {
    2195           0 :                     if ( i == static_cast<size_t>( nPageNumOfRect ) )
    2196             :                     {
    2197           0 :                         aPageNums.push_back( nOutputPageNum );
    2198           0 :                         break;
    2199             :                     }
    2200           0 :                     ++nOutputPageNum;
    2201             :                 }
    2202             :             }
    2203             :         }
    2204             :         else
    2205           0 :             aPageNums.push_back( nPageNumOfRect );
    2206             :     }
    2207             : 
    2208           0 :     return aPageNums;
    2209             : }
    2210             : 
    2211           0 : void SwEnhancedPDFExportHelper::MakeHeaderFooterLinks( vcl::PDFExtOutDevData& rPDFExtOutDevData,
    2212             :                                                        const SwTxtNode& rTNd,
    2213             :                                                        const SwRect& rLinkRect,
    2214             :                                                        sal_Int32 nDestId,
    2215             :                                                        const String& rURL,
    2216             :                                                        bool bIntern ) const
    2217             : {
    2218             :     // We assume, that the primary link has just been exported. Therefore
    2219             :     // the offset of the link rectangle calculates as follows:
    2220           0 :     const Point aOffset = rLinkRect.Pos() + mrOut.GetMapMode().GetOrigin();
    2221             : 
    2222           0 :     SwIterator<SwTxtFrm,SwTxtNode> aIter( rTNd );
    2223           0 :     for ( SwTxtFrm* pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
    2224             :         {
    2225             :             // Add offset to current page:
    2226           0 :             const SwPageFrm* pPageFrm = pTmpFrm->FindPageFrm();
    2227           0 :             SwRect aHFLinkRect( rLinkRect );
    2228           0 :             aHFLinkRect.Pos() = pPageFrm->Frm().Pos() + aOffset;
    2229             : 
    2230             :             // #i97135# the gcc_x64 optimizer gets aHFLinkRect != rLinkRect wrong
    2231             :             // fool it by comparing the position only (the width and height are the
    2232             :             // same anyway)
    2233           0 :             if ( aHFLinkRect.Pos() != rLinkRect.Pos() )
    2234             :             {
    2235             :                 // Link PageNums
    2236           0 :                 std::vector<sal_Int32> aHFLinkPageNums = CalcOutputPageNums( aHFLinkRect );
    2237             : 
    2238           0 :                 for ( size_t nNumIdx = 0; nNumIdx < aHFLinkPageNums.size(); ++nNumIdx )
    2239             :                 {
    2240             :                     // Link Export
    2241             :                     const sal_Int32 nHFLinkId =
    2242           0 :                         rPDFExtOutDevData.CreateLink( aHFLinkRect.SVRect(), aHFLinkPageNums[nNumIdx] );
    2243             : 
    2244             :                     // Connect Link and Destination:
    2245           0 :                     if ( bIntern )
    2246           0 :                         rPDFExtOutDevData.SetLinkDest( nHFLinkId, nDestId );
    2247             :                     else
    2248           0 :                         rPDFExtOutDevData.SetLinkURL( nHFLinkId, rURL );
    2249           0 :                 }
    2250             :             }
    2251           0 :         }
    2252          99 : }
    2253             : 
    2254             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10