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