1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <o3tl/safeint.hxx>
22 #include <svl/itemiter.hxx>
23 #include <svl/grabbagitem.hxx>
24 #include <rtl/tencinfo.h>
25 #include <sal/log.hxx>
27 #include <hintids.hxx>
28 #include <editeng/lspcitem.hxx>
29 #include <editeng/wrlmitem.hxx>
30 #include <editeng/udlnitem.hxx>
31 #include <editeng/kernitem.hxx>
32 #include <editeng/langitem.hxx>
33 #include <editeng/cmapitem.hxx>
34 #include <editeng/shdditem.hxx>
35 #include <editeng/contouritem.hxx>
36 #include <editeng/crossedoutitem.hxx>
37 #include <editeng/postitem.hxx>
38 #include <editeng/wghtitem.hxx>
39 #include <editeng/colritem.hxx>
40 #include <editeng/brushitem.hxx>
41 #include <editeng/spltitem.hxx>
42 #include <editeng/keepitem.hxx>
43 #include <editeng/orphitem.hxx>
44 #include <editeng/widwitem.hxx>
45 #include <editeng/adjustitem.hxx>
46 #include <editeng/escapementitem.hxx>
47 #include <editeng/fhgtitem.hxx>
48 #include <editeng/fontitem.hxx>
49 #include <editeng/shaditem.hxx>
50 #include <editeng/boxitem.hxx>
51 #include <editeng/ulspitem.hxx>
52 #include <editeng/lrspitem.hxx>
53 #include <editeng/tstpitem.hxx>
54 #include <editeng/autokernitem.hxx>
55 #include <editeng/paperinf.hxx>
56 #include <editeng/emphasismarkitem.hxx>
57 #include <editeng/twolinesitem.hxx>
58 #include <editeng/charscaleitem.hxx>
59 #include <editeng/charrotateitem.hxx>
60 #include <editeng/charreliefitem.hxx>
61 #include <editeng/blinkitem.hxx>
62 #include <editeng/hyphenzoneitem.hxx>
63 #include <editeng/paravertalignitem.hxx>
64 #include <editeng/pgrditem.hxx>
65 #include <editeng/frmdiritem.hxx>
66 #include <editeng/charhiddenitem.hxx>
67 #include <i18nlangtag/mslangid.hxx>
68 #include <svx/xfillit0.hxx>
69 #include <svx/xflclit.hxx>
70 #include "sortedarray.hxx"
71 #include "sprmids.hxx"
76 #include <IDocumentSettingAccess.hxx>
77 #include <pagedesc.hxx>
78 #include <fmtanchr.hxx>
79 #include <fmtcntnt.hxx>
80 #include <fchrfmt.hxx>
81 #include <fmthdft.hxx>
82 #include <fmtclds.hxx>
83 #include <fmtftntx.hxx>
85 #include <section.hxx>
86 #include <lineinfo.hxx>
87 #include <fmtline.hxx>
88 #include <txatbase.hxx>
89 #include <fmtflcnt.hxx>
90 #include <tgrditem.hxx>
91 #include <hfspacingitem.hxx>
92 #include <swtable.hxx>
94 #include "writerhelper.hxx"
95 #include "writerwordglue.hxx"
96 #include "ww8scan.hxx"
97 #include "ww8par2.hxx"
98 #include "ww8graf.hxx"
100 #include <fmtwrapinfluenceonobjpos.hxx>
102 using namespace sw::util
;
103 using namespace sw::types
;
104 using namespace ::com::sun::star
;
105 using namespace nsHdFtFlags
;
109 #define MM_250 1417 // WW default for horizontal borders: 2.5 cm
110 #define MM_200 1134 // WW default for lower border: 2.0 cm
113 static sal_uInt8
lcl_ReadBorders(bool bVer67
, WW8_BRCVer9
* brc
, WW8PLCFx_Cp_FKP
* pPap
,
114 const WW8RStyle
* pSty
= nullptr, const WW8PLCFx_SEPX
* pSep
= nullptr);
116 Color
SwWW8ImplReader::GetCol(sal_uInt8 nIco
)
118 static const Color eSwWW8ColA
[] =
120 COL_AUTO
, COL_BLACK
, COL_LIGHTBLUE
, COL_LIGHTCYAN
, COL_LIGHTGREEN
,
121 COL_LIGHTMAGENTA
, COL_LIGHTRED
, COL_YELLOW
, COL_WHITE
, COL_BLUE
,
122 COL_CYAN
, COL_GREEN
, COL_MAGENTA
, COL_RED
, COL_BROWN
, COL_GRAY
,
126 nIco
>= SAL_N_ELEMENTS(eSwWW8ColA
), "sw.ww8",
127 "ico " << sal_uInt32(nIco
) << " >= " << SAL_N_ELEMENTS(eSwWW8ColA
));
128 return nIco
< SAL_N_ELEMENTS(eSwWW8ColA
) ? eSwWW8ColA
[nIco
] : COL_AUTO
;
131 static sal_uInt32
MSRoundTweak(sal_uInt32 x
)
136 // page attribute which are not handled via the attribute management but
137 // using ...->HasSprm
138 // (except OLST which stays a normal attribute)
139 static short ReadSprm( const WW8PLCFx_SEPX
* pSep
, sal_uInt16 nId
, short nDefaultVal
)
141 SprmResult aRes
= pSep
->HasSprm(nId
); // sprm here?
142 const sal_uInt8
* pS
= aRes
.pSprm
;
143 short nVal
= (pS
&& aRes
.nRemainingData
>= 2) ? SVBT16ToInt16(pS
) : nDefaultVal
;
147 static sal_uInt16
ReadUSprm( const WW8PLCFx_SEPX
* pSep
, sal_uInt16 nId
, short nDefaultVal
)
149 SprmResult aRes
= pSep
->HasSprm(nId
); // sprm here?
150 const sal_uInt8
* pS
= aRes
.pSprm
;
151 sal_uInt16 nVal
= (pS
&& aRes
.nRemainingData
>= 2) ? SVBT16ToUInt16(pS
) : nDefaultVal
;
155 static sal_uInt8
ReadBSprm( const WW8PLCFx_SEPX
* pSep
, sal_uInt16 nId
, sal_uInt8 nDefaultVal
)
157 SprmResult aRes
= pSep
->HasSprm(nId
); // sprm here?
158 const sal_uInt8
* pS
= aRes
.pSprm
;
159 sal_uInt8 nVal
= (pS
&& aRes
.nRemainingData
>= 1) ? *pS
: nDefaultVal
;
163 void wwSection::SetDirection()
166 switch (maSep
.wTextFlow
)
169 OSL_ENSURE(false, "Unknown layout type");
172 meDir
=SvxFrameDirection::Horizontal_LR_TB
;
175 meDir
=SvxFrameDirection::Vertical_RL_TB
;
178 //asian letters are not rotated, western are. We can't import
179 //bottom to top going left to right, we can't do this in
180 //pages, (in drawboxes we could partly hack it with a rotated
181 //drawing box, though not frame)
182 meDir
=SvxFrameDirection::Vertical_RL_TB
;
185 //asian letters are not rotated, western are. We can't import
186 meDir
=SvxFrameDirection::Vertical_RL_TB
;
189 //asian letters are rotated, western not. We can't import
190 meDir
=SvxFrameDirection::Horizontal_LR_TB
;
194 sal_uInt8 bRTLPgn
= maSep
.fBiDi
;
195 if ((meDir
== SvxFrameDirection::Horizontal_LR_TB
) && bRTLPgn
)
196 meDir
= SvxFrameDirection::Horizontal_RL_TB
;
199 bool wwSection::IsVertical() const
201 return meDir
== SvxFrameDirection::Vertical_RL_TB
|| meDir
== SvxFrameDirection::Vertical_LR_TB
;
205 This is something of festering mapping, I'm open to better ways of doing it,
206 but primarily the grid in writer is different to that in word. In writer the
207 grid elements are squares with ruby rows inbetween. While in word there is no
208 ruby stuff, and the elements are rectangles. By misusing the ruby row I can
209 handle distortions in one direction, but its all a bit of a mess:
211 void SwWW8ImplReader::SetDocumentGrid(SwFrameFormat
&rFormat
, const wwSection
&rSection
)
216 rFormat
.SetFormatAttr(SvxFrameDirectionItem(rSection
.meDir
, RES_FRAMEDIR
));
218 SwTwips nTextareaHeight
= rFormat
.GetFrameSize().GetHeight();
219 const SvxULSpaceItem
&rUL
= ItemGet
<SvxULSpaceItem
>(rFormat
, RES_UL_SPACE
);
220 nTextareaHeight
-= rUL
.GetUpper();
221 nTextareaHeight
-= rUL
.GetLower();
223 SwTwips nTextareaWidth
= rFormat
.GetFrameSize().GetWidth();
224 const SvxLRSpaceItem
&rLR
= ItemGet
<SvxLRSpaceItem
>(rFormat
, RES_LR_SPACE
);
225 nTextareaWidth
-= rLR
.GetLeft();
226 nTextareaWidth
-= rLR
.GetRight();
228 if (rSection
.IsVertical())
229 std::swap(nTextareaHeight
, nTextareaWidth
);
231 SwTextGridItem aGrid
;
232 aGrid
.SetDisplayGrid(false);
233 aGrid
.SetPrintGrid(false);
234 SwTextGrid eType
=GRID_NONE
;
236 switch (rSection
.maSep
.clm
)
242 OSL_ENSURE(false, "Unknown grid type");
245 eType
= GRID_LINES_CHARS
;
246 aGrid
.SetSnapToChars(true);
249 eType
= GRID_LINES_CHARS
;
250 aGrid
.SetSnapToChars(false);
253 eType
= GRID_LINES_ONLY
;
257 aGrid
.SetGridType(eType
);
259 // seem to not add external leading in word, or the character would run across
260 // two line in some cases.
261 if (eType
!= GRID_NONE
)
262 m_rDoc
.getIDocumentSettingAccess().set(DocumentSettingId::ADD_EXT_LEADING
, false);
264 //force to set document as standard page mode
265 bool bSquaredMode
= false;
266 m_rDoc
.SetDefaultPageMode( bSquaredMode
);
267 aGrid
.SetSquaredMode( bSquaredMode
);
269 //Get the size of word's default styles font
270 sal_uInt32 nCharWidth
=240;
271 for (sal_uInt16 nI
= 0; nI
< m_xStyles
->GetCount(); ++nI
)
273 if (m_vColl
[nI
].m_bValid
&& m_vColl
[nI
].m_pFormat
&&
274 m_vColl
[nI
].IsWW8BuiltInDefaultStyle())
276 nCharWidth
= ItemGet
<SvxFontHeightItem
>(*(m_vColl
[nI
].m_pFormat
),
277 RES_CHRATR_CJK_FONTSIZE
).GetHeight();
283 if (rSection
.maSep
.dxtCharSpace
)
285 sal_uInt32 nCharSpace
= rSection
.maSep
.dxtCharSpace
;
286 //main lives in top 20 bits, and is signed.
287 sal_Int32 nMain
= (nCharSpace
& 0xFFFFF000);
289 nCharWidth
+= nMain
*20;
291 int nFraction
= (nCharSpace
& 0x00000FFF);
292 nFraction
= (nFraction
*20)/0xFFF;
293 nCharWidth
+= nFraction
;
296 aGrid
.SetBaseWidth( writer_cast
<sal_uInt16
>(nCharWidth
));
299 sal_Int32 nLinePitch
= rSection
.maSep
.dyaLinePitch
;
300 if (nLinePitch
>= 1 && nLinePitch
<= 31680)
302 aGrid
.SetLines(writer_cast
<sal_uInt16
>(nTextareaHeight
/nLinePitch
));
303 aGrid
.SetBaseHeight(writer_cast
<sal_uInt16
>(nLinePitch
));
306 aGrid
.SetRubyHeight(0);
308 rFormat
.SetFormatAttr(aGrid
);
311 void SwWW8ImplReader::SetRelativeJustify( bool bRel
)
313 if ( m_pCurrentColl
&& StyleExists(m_nCurrentColl
) ) // importing style
314 m_vColl
[m_nCurrentColl
].m_nRelativeJustify
= bRel
? 1 : 0;
315 else if ( m_xPlcxMan
&& m_xPlcxMan
->GetPap() ) // importing paragraph
316 m_xPlcxMan
->GetPap()->nRelativeJustify
= bRel
? 1 : 0;
319 bool SwWW8ImplReader::IsRelativeJustify()
321 bool bRet
= m_xWwFib
->GetFIBVersion() >= ww::eWW8
;
324 // if relativeJustify is undefined (-1), then check the parent style.
325 if ( m_pCurrentColl
&& StyleExists(m_nCurrentColl
) )
327 sal_Int16 nRelative
= m_vColl
[m_nCurrentColl
].m_nRelativeJustify
;
328 if ( nRelative
< 0 && m_nCurrentColl
)
330 o3tl::sorted_vector
<sal_uInt16
> aVisitedStyles
;
331 bRet
= IsRelativeJustify(m_vColl
[m_nCurrentColl
].m_nBase
, aVisitedStyles
);
334 bRet
= nRelative
> 0;
336 else if ( m_xPlcxMan
&& m_xPlcxMan
->GetPap() )
338 sal_Int16 nRelative
= m_xPlcxMan
->GetPap()->nRelativeJustify
;
341 o3tl::sorted_vector
<sal_uInt16
> aVisitedStyles
;
342 bRet
= IsRelativeJustify(m_nCurrentColl
, aVisitedStyles
);
345 bRet
= nRelative
> 0;
352 bool SwWW8ImplReader::IsRelativeJustify(sal_uInt16 nColl
, o3tl::sorted_vector
<sal_uInt16
>& rVisitedStyles
)
354 assert( m_xWwFib
->GetFIBVersion() >= ww::eWW8
355 && "pointless to search styles if relative justify is impossible");
357 if ( StyleExists(nColl
) )
359 rVisitedStyles
.insert(nColl
);
360 // if relativeJustify is undefined (-1), then check the parent style.
361 sal_Int16 nRelative
= m_vColl
[nColl
].m_nRelativeJustify
;
362 if ( nColl
== 0 || nRelative
>= 0 )
363 bRet
= nRelative
> 0;
364 else if (rVisitedStyles
.find(m_vColl
[nColl
].m_nBase
) == rVisitedStyles
.end()) // detect loop in chain
365 bRet
= IsRelativeJustify(m_vColl
[nColl
].m_nBase
, rVisitedStyles
);
371 void SwWW8ImplReader::Read_ParaBiDi(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
374 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_FRAMEDIR
);
377 SvxFrameDirection eDir
=
378 *pData
? SvxFrameDirection::Horizontal_RL_TB
: SvxFrameDirection::Horizontal_LR_TB
;
380 // In eWW8+, justify can be absolute, or relative to BiDi
381 bool bBiDiSwap
= IsRelativeJustify();
384 // Only change if ParaBiDi doesn't match previous setting.
385 const bool bParentRTL
= IsRightToLeft();
386 bBiDiSwap
= (eDir
== SvxFrameDirection::Horizontal_RL_TB
&& !bParentRTL
)
387 || (eDir
== SvxFrameDirection::Horizontal_LR_TB
&& bParentRTL
);
392 const SvxAdjustItem
* pItem
= static_cast<const SvxAdjustItem
*>(GetFormatAttr(RES_PARATR_ADJUST
));
395 // no previous adjust: set appropriate default
396 if ( eDir
== SvxFrameDirection::Horizontal_LR_TB
)
397 NewAttr( SvxAdjustItem( SvxAdjust::Left
, RES_PARATR_ADJUST
) );
399 NewAttr( SvxAdjustItem( SvxAdjust::Right
, RES_PARATR_ADJUST
) );
403 // previous adjust and bidi has changed: swap Left/Right
404 const SvxAdjust eJustify
= pItem
->GetAdjust();
405 if ( eJustify
== SvxAdjust::Left
)
406 NewAttr( SvxAdjustItem( SvxAdjust::Right
, RES_PARATR_ADJUST
) );
407 else if ( eJustify
== SvxAdjust::Right
)
408 NewAttr( SvxAdjustItem( SvxAdjust::Left
, RES_PARATR_ADJUST
) );
412 NewAttr(SvxFrameDirectionItem(eDir
, RES_FRAMEDIR
));
414 if ( m_pCurrentColl
&& m_xStyles
) // in style definition
415 m_xStyles
->mbBidiChanged
= true;
419 bool wwSectionManager::SetCols(SwFrameFormat
&rFormat
, const wwSection
&rSection
,
420 sal_uInt32 nNetWidth
)
422 //sprmSCcolumns - number of columns - 1
423 const sal_Int16 nCols
= rSection
.NoCols();
425 if (nCols
< 2) //check for no columns or other weird state
428 const sal_uInt16 nNetWriterWidth
= writer_cast
<sal_uInt16
>(nNetWidth
);
429 if (nNetWriterWidth
== 0)
432 SwFormatCol aCol
; // Create SwFormatCol
434 //sprmSDxaColumns - Default distance is 1.25 cm
435 sal_Int32 nColSpace
= rSection
.StandardColSeparation();
437 const SEPr
& rSep
= rSection
.maSep
;
442 aCol
.SetLineAdj(COLADJ_TOP
); // Line
443 aCol
.SetLineHeight(100);
444 aCol
.SetLineColor(COL_BLACK
);
445 aCol
.SetLineWidth(1);
448 aCol
.Init(nCols
, writer_cast
<sal_uInt16
>(nColSpace
), nNetWriterWidth
);
450 // sprmSFEvenlySpaced
451 if (!rSep
.fEvenlySpaced
)
453 aCol
.SetOrtho_(false);
454 const sal_uInt16 maxIdx
= SAL_N_ELEMENTS(rSep
.rgdxaColumnWidthSpacing
);
455 for (sal_uInt16 i
= 0, nIdx
= 1; i
< nCols
&& nIdx
< maxIdx
; i
++, nIdx
+=2 )
457 SwColumn
* pCol
= &aCol
.GetColumns()[i
];
458 const sal_Int32 nLeft
= rSep
.rgdxaColumnWidthSpacing
[nIdx
-1]/2;
459 const sal_Int32 nRight
= rSep
.rgdxaColumnWidthSpacing
[nIdx
+1]/2;
460 const sal_Int32 nWishWidth
= rSep
.rgdxaColumnWidthSpacing
[nIdx
]
462 pCol
->SetWishWidth(writer_cast
<sal_uInt16
>(nWishWidth
));
463 pCol
->SetLeft(writer_cast
<sal_uInt16
>(nLeft
));
464 pCol
->SetRight(writer_cast
<sal_uInt16
>(nRight
));
466 aCol
.SetWishWidth(nNetWriterWidth
);
468 rFormat
.SetFormatAttr(aCol
);
472 void wwSectionManager::SetLeftRight(wwSection
&rSection
)
475 sal_uInt32 nWWLe
= MSRoundTweak(rSection
.maSep
.dxaLeft
);
476 sal_uInt32 nWWRi
= MSRoundTweak(rSection
.maSep
.dxaRight
);
477 sal_uInt32 nWWGu
= rSection
.maSep
.dzaGutter
;
480 fRTLGutter is set if the gutter is on the right, the gutter is otherwise
481 placed on the left unless the global dop options are to put it on top, that
482 case is handled in GetPageULData.
484 if (rSection
.maSep
.fRTLGutter
)
486 else if (!mrReader
.m_xWDop
->iGutterPos
)
490 if ((rSection
.nPgWidth
- nWWLe
- nWWRi
) < MINLAY
)
493 There are some label templates which are "broken", they specify
494 margins which make no sense e.g. Left 16.10cm, Right 16.10cm. So the
495 space left between the margins is less than 0 In word the left margin
496 is honoured and if the right margin would be past the left margin is
497 left at the left margin position.
499 Now this will work fine for importing, layout and exporting, *but* the
500 page layout dialog has a hardcoded minimum page width of 0.5cm so it
501 will report a different value than what is actually being used. i.e.
502 it will add up the values to give a wider page than is actually being
505 nWWRi
= rSection
.nPgWidth
- nWWLe
- MINLAY
;
508 rSection
.nPgLeft
= nWWLe
;
509 rSection
.nPgRight
= nWWRi
;
512 void wwSectionManager::SetPage(SwPageDesc
&rInPageDesc
, SwFrameFormat
&rFormat
,
513 const wwSection
&rSection
, bool bIgnoreCols
)
516 rInPageDesc
.SetLandscape(rSection
.IsLandScape());
519 SwFormatFrameSize
aSz( rFormat
.GetFrameSize() );
520 aSz
.SetWidth(rSection
.GetPageWidth());
521 aSz
.SetHeight(SvxPaperInfo::GetSloppyPaperDimension(rSection
.GetPageHeight()));
522 rFormat
.SetFormatAttr(aSz
);
524 rFormat
.SetFormatAttr(
525 SvxLRSpaceItem(rSection
.GetPageLeft(), rSection
.GetPageRight(), 0, 0, RES_LR_SPACE
));
528 SetCols(rFormat
, rSection
, rSection
.GetTextAreaWidth());
532 // Returns corrected (ODF) margin size
533 tools::Long
SetBorderDistance(bool bFromEdge
, SvxBoxItem
& aBox
, SvxBoxItemLine eLine
, tools::Long nMSMargin
)
535 const editeng::SvxBorderLine
* pLine
= aBox
.GetLine(eLine
);
538 sal_Int32 nNewMargin
= nMSMargin
;
539 sal_Int32 nNewDist
= aBox
.GetDistance(eLine
);
540 sal_Int32 nLineWidth
= pLine
->GetScaledWidth();
542 editeng::BorderDistanceFromWord(bFromEdge
, nNewMargin
, nNewDist
, nLineWidth
);
543 aBox
.SetDistance(nNewDist
, eLine
);
549 void SwWW8ImplReader::SetPageBorder(SwFrameFormat
&rFormat
, const wwSection
&rSection
)
551 if (!IsBorder(rSection
.brc
))
554 SfxItemSet
aSet(rFormat
.GetAttrSet());
555 short aSizeArray
[5]={0};
556 SetFlyBordersShadow(aSet
, rSection
.brc
, &aSizeArray
[0]);
557 SvxLRSpaceItem
aLR(ItemGet
<SvxLRSpaceItem
>(aSet
, RES_LR_SPACE
));
558 SvxULSpaceItem
aUL(ItemGet
<SvxULSpaceItem
>(aSet
, RES_UL_SPACE
));
559 SvxBoxItem
aBox(ItemGet
<SvxBoxItem
>(aSet
, RES_BOX
));
560 bool bFromEdge
= rSection
.maSep
.pgbOffsetFrom
== 1;
562 aLR
.SetLeft(SetBorderDistance(bFromEdge
, aBox
, SvxBoxItemLine::LEFT
, aLR
.GetLeft()));
563 aLR
.SetRight(SetBorderDistance(bFromEdge
, aBox
, SvxBoxItemLine::RIGHT
, aLR
.GetRight()));
564 aUL
.SetUpper(SetBorderDistance(bFromEdge
, aBox
, SvxBoxItemLine::TOP
, aUL
.GetUpper()));
565 aUL
.SetLower(SetBorderDistance(bFromEdge
, aBox
, SvxBoxItemLine::BOTTOM
, aUL
.GetLower()));
570 rFormat
.SetFormatAttr(aSet
);
573 void wwSectionManager::GetPageULData(const wwSection
&rSection
,
574 wwSectionManager::wwULSpaceData
& rData
) const
576 sal_Int32 nWWUp
= rSection
.maSep
.dyaTop
;
577 sal_Int32 nWWLo
= rSection
.maSep
.dyaBottom
;
578 sal_uInt32 nWWHTop
= rSection
.maSep
.dyaHdrTop
;
579 sal_uInt32 nWWFBot
= rSection
.maSep
.dyaHdrBottom
;
582 If there is gutter in 97+ and the dop says put it on top then get the
583 gutter distance and set it to the top margin. When we are "two pages
584 in one" the gutter is put at the top of odd pages, and bottom of
585 even pages, something we cannot do. So we will put it on top of all
586 pages, that way the pages are at least the right size.
588 if (!mrReader
.m_bVer67
&& mrReader
.m_xWDop
->iGutterPos
&&
589 rSection
.maSep
.fRTLGutter
)
591 nWWUp
+= rSection
.maSep
.dzaGutter
;
594 /* Check whether this section has headers / footers */
595 sal_uInt16 nHeaderMask
= WW8_HEADER_EVEN
| WW8_HEADER_ODD
;
596 sal_uInt16 nFooterMask
= WW8_FOOTER_EVEN
| WW8_FOOTER_ODD
;
597 /* Ignore the presence of a first-page header/footer unless it is enabled */
598 if( rSection
.HasTitlePage() )
600 nHeaderMask
|= WW8_HEADER_FIRST
;
601 nFooterMask
|= WW8_FOOTER_FIRST
;
603 rData
.bHasHeader
= (rSection
.maSep
.grpfIhdt
& nHeaderMask
) != 0;
604 rData
.bHasFooter
= (rSection
.maSep
.grpfIhdt
& nFooterMask
) != 0;
606 if( rData
.bHasHeader
)
608 rData
.nSwUp
= nWWHTop
; // Header -> convert
609 // #i19922# - correction:
610 // consider that <nWWUp> can be negative, compare only if it's positive
612 o3tl::make_unsigned(abs(nWWUp
)) >= nWWHTop
)
613 rData
.nSwHLo
= nWWUp
- nWWHTop
;
617 // #i19922# - minimum page header height is now 1mm
618 // use new constant <cMinHdFtHeight>
619 if (rData
.nSwHLo
< sal::static_int_cast
< sal_uInt32
>(cMinHdFtHeight
))
620 rData
.nSwHLo
= sal::static_int_cast
< sal_uInt32
>(cMinHdFtHeight
);
622 else // no header -> just use Up as-is
623 rData
.nSwUp
= std::abs(nWWUp
);
625 if( rData
.bHasFooter
)
627 rData
.nSwLo
= nWWFBot
; // footer -> convert
628 // #i19922# - correction: consider that <nWWLo> can be negative, compare only if it's positive
630 o3tl::make_unsigned(abs(nWWLo
)) >= nWWFBot
)
631 rData
.nSwFUp
= nWWLo
- nWWFBot
;
635 // #i19922# - minimum page header height is now 1mm
636 // use new constant <cMinHdFtHeight>
637 if (rData
.nSwFUp
< sal::static_int_cast
< sal_uInt32
>(cMinHdFtHeight
))
638 rData
.nSwFUp
= sal::static_int_cast
< sal_uInt32
>(cMinHdFtHeight
);
640 else // no footer -> just use Lo as-is
641 rData
.nSwLo
= std::abs(nWWLo
);
644 void wwSectionManager::SetPageULSpaceItems(SwFrameFormat
&rFormat
,
645 wwSectionManager::wwULSpaceData
const & rData
, const wwSection
&rSection
)
647 if (rData
.bHasHeader
) // ... and set Header-Lower
649 // set header height to minimum
650 if (SwFrameFormat
* pHdFormat
= const_cast<SwFrameFormat
*>(rFormat
.GetHeader().GetHeaderFormat()))
652 SvxULSpaceItem
aHdUL(pHdFormat
->GetULSpace());
653 if (!rSection
.IsFixedHeightHeader()) //normal
655 pHdFormat
->SetFormatAttr(SwFormatFrameSize(SwFrameSize::Minimum
, 0, rData
.nSwHLo
));
656 // #i19922# - minimum page header height is now 1mm
657 // use new constant <cMinHdFtHeight>
658 aHdUL
.SetLower( writer_cast
<sal_uInt16
>(rData
.nSwHLo
- cMinHdFtHeight
) );
659 pHdFormat
->SetFormatAttr(SwHeaderAndFooterEatSpacingItem(
660 RES_HEADER_FOOTER_EAT_SPACING
, true));
664 // Hack alert: these calculations are based on
665 // #112727# import negative height headers/footers as floating frames inside fixed height headers/footer
666 // #i48832# - set correct spacing between header and body.
667 const sal_Int32
nHdLowerSpace(std::max
<sal_Int32
>(0, std::abs(rSection
.maSep
.dyaTop
) - rData
.nSwUp
- rData
.nSwHLo
));
668 pHdFormat
->SetFormatAttr(SwFormatFrameSize(SwFrameSize::Fixed
, 0, rData
.nSwHLo
+ nHdLowerSpace
));
669 aHdUL
.SetLower( static_cast< sal_uInt16
>(nHdLowerSpace
) );
670 pHdFormat
->SetFormatAttr(SwHeaderAndFooterEatSpacingItem(
671 RES_HEADER_FOOTER_EAT_SPACING
, false));
673 pHdFormat
->SetFormatAttr(aHdUL
);
677 if (rData
.bHasFooter
) // ... and set footer-upper
679 if (SwFrameFormat
* pFtFormat
= const_cast<SwFrameFormat
*>(rFormat
.GetFooter().GetFooterFormat()))
681 SvxULSpaceItem
aFtUL(pFtFormat
->GetULSpace());
682 if (!rSection
.IsFixedHeightFooter()) //normal
684 pFtFormat
->SetFormatAttr(SwFormatFrameSize(SwFrameSize::Minimum
, 0, rData
.nSwFUp
));
685 // #i19922# - minimum page header height is now 1mm
686 // use new constant <cMinHdFtHeight>
687 aFtUL
.SetUpper( writer_cast
<sal_uInt16
>(rData
.nSwFUp
- cMinHdFtHeight
) );
688 pFtFormat
->SetFormatAttr(SwHeaderAndFooterEatSpacingItem(
689 RES_HEADER_FOOTER_EAT_SPACING
, true));
693 // #i48832# - set correct spacing between footer and body.
694 const sal_Int32
nFtUpperSpace(std::max
<sal_Int32
>(0, std::abs(rSection
.maSep
.dyaBottom
) - rData
.nSwLo
- rData
.nSwFUp
));
695 pFtFormat
->SetFormatAttr(SwFormatFrameSize(SwFrameSize::Fixed
, 0, rData
.nSwFUp
+ nFtUpperSpace
));
696 aFtUL
.SetUpper( static_cast< sal_uInt16
>(nFtUpperSpace
) );
697 pFtFormat
->SetFormatAttr(SwHeaderAndFooterEatSpacingItem(
698 RES_HEADER_FOOTER_EAT_SPACING
, false));
700 pFtFormat
->SetFormatAttr(aFtUL
);
704 SvxULSpaceItem
aUL(writer_cast
<sal_uInt16
>(rData
.nSwUp
),
705 writer_cast
<sal_uInt16
>(rData
.nSwLo
), RES_UL_SPACE
);
706 rFormat
.SetFormatAttr(aUL
);
709 SwSectionFormat
*wwSectionManager::InsertSection(
710 SwPaM
const & rMyPaM
, wwSection
&rSection
)
712 SwSectionData
aSection( SectionType::Content
,
713 mrReader
.m_rDoc
.GetUniqueSectionName() );
715 SfxItemSet
aSet( mrReader
.m_rDoc
.GetAttrPool(), aFrameFormatSetRange
);
717 bool bRTLPgn
= !maSegments
.empty() && maSegments
.back().IsBiDi();
718 aSet
.Put(SvxFrameDirectionItem(
719 bRTLPgn
? SvxFrameDirection::Horizontal_RL_TB
: SvxFrameDirection::Horizontal_LR_TB
, RES_FRAMEDIR
));
721 if (2 == mrReader
.m_xWDop
->fpc
)
722 aSet
.Put( SwFormatFootnoteAtTextEnd(FTNEND_ATTXTEND
));
723 if (0 == mrReader
.m_xWDop
->epc
)
724 aSet
.Put( SwFormatEndAtTextEnd(FTNEND_ATTXTEND
));
726 aSection
.SetProtectFlag(SectionIsProtected(rSection
));
729 mrReader
.m_rDoc
.InsertSwSection( rMyPaM
, aSection
, nullptr, & aSet
);
730 OSL_ENSURE(rSection
.mpSection
, "section not inserted!");
731 if (!rSection
.mpSection
)
734 SwPageDesc
*pPage
= nullptr;
735 auto aIter
= std::find_if(maSegments
.rbegin(), maSegments
.rend(),
736 [](const wwSection
& rSegment
) { return rSegment
.mpPage
!= nullptr; });
737 if (aIter
!= maSegments
.rend())
738 pPage
= aIter
->mpPage
;
740 OSL_ENSURE(pPage
, "no page outside this section!");
743 pPage
= &mrReader
.m_rDoc
.GetPageDesc(0);
745 SwSectionFormat
*pFormat
= rSection
.mpSection
->GetFormat();
746 OSL_ENSURE(pFormat
, "impossible");
750 SwFrameFormat
& rFormat
= pPage
->GetMaster();
751 const SvxLRSpaceItem
& rLR
= rFormat
.GetLRSpace();
752 tools::Long nPageLeft
= rLR
.GetLeft();
753 tools::Long nPageRight
= rLR
.GetRight();
754 tools::Long nSectionLeft
= rSection
.GetPageLeft() - nPageLeft
;
755 tools::Long nSectionRight
= rSection
.GetPageRight() - nPageRight
;
756 if ((nSectionLeft
!= 0) || (nSectionRight
!= 0))
758 SvxLRSpaceItem
aLR(nSectionLeft
, nSectionRight
, 0, 0, RES_LR_SPACE
);
759 pFormat
->SetFormatAttr(aLR
);
762 SetCols(*pFormat
, rSection
, rSection
.GetTextAreaWidth());
766 void SwWW8ImplReader::HandleLineNumbering(const wwSection
&rSection
)
768 // check if Line Numbering must be activated or reset
769 if (!(m_bNewDoc
&& rSection
.maSep
.nLnnMod
))
772 // restart-numbering-mode: 0 per page, 1 per section, 2 never restart
773 bool bRestartLnNumPerSection
= (1 == rSection
.maSep
.lnc
);
777 SwLineNumberInfo
aInfo( m_rDoc
.GetLineNumberInfo() );
779 aInfo
.SetPaintLineNumbers(true);
781 aInfo
.SetRestartEachPage(rSection
.maSep
.lnc
== 0);
783 // A value of 0 (auto) indicates that the application MUST automatically determine positioning.
784 if ( rSection
.maSep
.dxaLnn
)
785 aInfo
.SetPosFromLeft(writer_cast
<sal_uInt16
>(rSection
.maSep
.dxaLnn
));
787 //Paint only for every n line
788 aInfo
.SetCountBy(rSection
.maSep
.nLnnMod
);
790 // to be defaulted features ( HARDCODED in MS Word 6,7,8,9 )
791 aInfo
.SetCountBlankLines(true);
792 aInfo
.SetCountInFlys(false);
793 aInfo
.SetPos( LINENUMBER_POS_LEFT
);
794 SvxNumberType aNumType
; // this sets SVX_NUM_ARABIC per default
795 aInfo
.SetNumType( aNumType
);
797 m_rDoc
.SetLineNumberInfo( aInfo
);
798 m_bNoLnNumYet
= false;
801 if ((0 < rSection
.maSep
.lnnMin
) || bRestartLnNumPerSection
)
803 SwFormatLineNumber aLN
;
804 if (const SwFormatLineNumber
* pLN
805 = static_cast<const SwFormatLineNumber
*>(GetFormatAttr(RES_LINENUMBER
)))
807 aLN
.SetCountLines( pLN
->IsCount() );
809 aLN
.SetStartValue(1 + rSection
.maSep
.lnnMin
);
811 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_LINENUMBER
);
815 wwSection::wwSection(const SwPosition
&rPos
) : maStart(rPos
.nNode
)
818 , meDir(SvxFrameDirection::Horizontal_LR_TB
)
819 , nPgWidth(SvxPaperInfo::GetPaperSize(PAPER_A4
).Width())
822 , mnVerticalAdjustment(drawing::TextVerticalAdjust_TOP
)
824 , mbHasFootnote(false)
828 void wwSectionManager::SetNumberingType(const wwSection
&rNewSection
,
829 SwPageDesc
&rPageDesc
)
831 // save page number format
832 static const SvxNumType aNumTyp
[5] =
834 SVX_NUM_ARABIC
, SVX_NUM_ROMAN_UPPER
, SVX_NUM_ROMAN_LOWER
,
835 SVX_NUM_CHARS_UPPER_LETTER_N
, SVX_NUM_CHARS_LOWER_LETTER_N
839 aType
.SetNumberingType( aNumTyp
[rNewSection
.maSep
.nfcPgn
] );
840 rPageDesc
.SetNumType(aType
);
843 // CreateSep is called for every section change (even at the start of
844 // the document. CreateSep also creates the pagedesc(s) and
845 // fills it/them with attributes and KF texts.
846 // This has become necessary because the translation of the various
847 // page attributes is interconnected too much.
848 void wwSectionManager::CreateSep(const tools::Long nTextPos
)
851 #i1909# section/page breaks should not occur in tables or subpage
852 elements like frames. Word itself ignores them in this case. The bug is
853 more likely that this filter created such documents in the past!
855 if (mrReader
.m_nInTable
|| mrReader
.m_bTxbxFlySection
|| mrReader
.InLocalApo())
858 WW8PLCFx_SEPX
* pSep
= mrReader
.m_xPlcxMan
->GetSepPLCF();
859 OSL_ENSURE(pSep
, "impossible!");
863 if (!maSegments
.empty() && mrReader
.m_pLastAnchorPos
&& *mrReader
.m_pLastAnchorPos
== *mrReader
.m_pPaM
->GetPoint())
866 SwPaM
pam( *mrReader
.m_pLastAnchorPos
);
867 if( pam
.Move(fnMoveBackward
, GoInNode
))
868 if( SwTextNode
* txtNode
= pam
.GetPoint()->nNode
.GetNode().GetTextNode())
869 if( txtNode
->Len() == 0 )
872 mrReader
.AppendTextNode(*mrReader
.m_pPaM
->GetPoint());
875 ww::WordVersion eVer
= mrReader
.GetFib().GetFIBVersion();
877 // M.M. Create a linked section if the WkbPLCF
878 // has an entry for one at this cp
879 WW8PLCFspecial
* pWkb
= mrReader
.m_xPlcxMan
->GetWkbPLCF();
880 if (pWkb
&& pWkb
->SeekPosExact(nTextPos
) &&
881 pWkb
->Where() == nTextPos
)
885 bool bSuccess
= pWkb
->Get(nTest
, pData
);
888 OUString sSectionName
= mrReader
.m_aLinkStringMap
[SVBT16ToUInt16( static_cast<WW8_WKB
*>(pData
)->nLinkId
) ];
889 sSectionName
= mrReader
.ConvertFFileName(sSectionName
);
890 SwSectionData
aSection(SectionType::FileLink
, sSectionName
);
891 aSection
.SetLinkFileName( sSectionName
);
892 aSection
.SetProtectFlag(true);
893 // #i19922# - improvement: return value of method <Insert> not used.
894 mrReader
.m_rDoc
.InsertSwSection(*mrReader
.m_pPaM
, aSection
, nullptr, nullptr, false);
897 wwSection
aLastSection(*mrReader
.m_pPaM
->GetPoint());
898 if (!maSegments
.empty())
899 aLastSection
= maSegments
.back();
902 sal_uInt16 nLIdx
= ( ( static_cast<sal_uInt16
>(mrReader
.m_xWwFib
->m_lid
) & 0xff ) == 0x9 ) ? 1 : 0;
904 //BEGIN read section values
905 wwSection
aNewSection(*mrReader
.m_pPaM
->GetPoint());
907 static const sal_uInt16 aVer2Ids0
[] =
910 /*sprmSFTitlePage*/ 118,
912 /*sprmSCcolumns*/ 119,
913 /*sprmSDxaColumns*/ 120,
914 /*sprmSLBetween*/ 133
917 static const sal_uInt16 aVer67Ids0
[] =
919 NS_sprm::v6::sprmSBkc
,
920 NS_sprm::v6::sprmSFTitlePage
,
921 NS_sprm::v6::sprmSNfcPgn
,
922 NS_sprm::v6::sprmSCcolumns
,
923 NS_sprm::v6::sprmSDxaColumns
,
924 NS_sprm::v6::sprmSLBetween
927 static const sal_uInt16 aVer8Ids0
[] =
930 NS_sprm::SFTitlePage::val
,
931 NS_sprm::SNfcPgn::val
,
932 NS_sprm::SCcolumns::val
,
933 NS_sprm::SDxaColumns::val
,
934 NS_sprm::SLBetween::val
937 const sal_uInt16
* pIds
= eVer
<= ww::eWW2
? aVer2Ids0
: eVer
<= ww::eWW7
? aVer67Ids0
: aVer8Ids0
;
939 SprmResult aRes
= pSep
->HasSprm(pIds
[0]);
940 const sal_uInt8
* pSprmBkc
= aRes
.pSprm
;
941 if (!maSegments
.empty())
943 // Type of break: break codes are:
949 if (pSprmBkc
&& aRes
.nRemainingData
>= 1)
950 aNewSection
.maSep
.bkc
= *pSprmBkc
;
954 aNewSection
.maSep
.fTitlePage
=
955 sal_uInt8(0 != ReadBSprm( pSep
, pIds
[1], 0 ));
958 aNewSection
.maSep
.nfcPgn
= ReadBSprm( pSep
, pIds
[2], 0 );
959 if (aNewSection
.maSep
.nfcPgn
> 4)
960 aNewSection
.maSep
.nfcPgn
= 0;
962 aNewSection
.maSep
.fUnlocked
= eVer
> ww::eWW2
? ReadBSprm(pSep
, (eVer
<= ww::eWW7
? NS_sprm::v6::sprmSFProtected
: NS_sprm::SFProtected::val
), 0 ) : 0;
965 aNewSection
.maSep
.fBiDi
= eVer
>= ww::eWW8
? ReadBSprm(pSep
, NS_sprm::SFBiDi::val
, 0) : 0;
967 // Reading section property sprmSCcolumns - one less than the number of columns in the section.
968 // It must be less than MAX_NO_OF_SEP_COLUMNS according the WW8 specification.
969 aNewSection
.maSep
.ccolM1
= ReadSprm(pSep
, pIds
[3], 0 );
970 if ( aNewSection
.maSep
.ccolM1
>= MAX_NO_OF_SEP_COLUMNS
)
973 aNewSection
.maSep
.ccolM1
= MAX_NO_OF_SEP_COLUMNS
-1;
976 //sprmSDxaColumns - default distance 1.25 cm
977 aNewSection
.maSep
.dxaColumns
= ReadUSprm( pSep
, pIds
[4], 708 );
980 aNewSection
.maSep
.fLBetween
= ReadBSprm(pSep
, pIds
[5], 0 );
982 if (eVer
>= ww::eWW6
)
984 // sprmSFEvenlySpaced
985 aNewSection
.maSep
.fEvenlySpaced
=
986 sal_uInt8(ReadBSprm(pSep
, (eVer
<= ww::eWW7
? NS_sprm::v6::sprmSFEvenlySpaced
: NS_sprm::SFEvenlySpaced::val
), 1) != 0);
988 if (aNewSection
.maSep
.ccolM1
> 0 && !aNewSection
.maSep
.fEvenlySpaced
)
990 int nColumnDataIdx
= 0;
991 aNewSection
.maSep
.rgdxaColumnWidthSpacing
[nColumnDataIdx
] = 0;
993 const sal_uInt16 nColumnWidthSprmId
= ( eVer
<= ww::eWW7
? NS_sprm::v6::sprmSDxaColWidth
: NS_sprm::SDxaColWidth::val
);
994 const sal_uInt16 nColumnSpacingSprmId
= ( eVer
<= ww::eWW7
? NS_sprm::v6::sprmSDxaColSpacing
: NS_sprm::SDxaColSpacing::val
);
995 const sal_uInt8 nColumnCount
= static_cast< sal_uInt8
>(aNewSection
.maSep
.ccolM1
+ 1);
996 for ( sal_uInt8 nColumn
= 0; nColumn
< nColumnCount
; ++nColumn
)
999 SprmResult aSWRes
= pSep
->HasSprm(nColumnWidthSprmId
, nColumn
);
1000 const sal_uInt8
* pSW
= aSWRes
.pSprm
;
1002 OSL_ENSURE( pSW
, "+Sprm 136 (resp. 0xF203) (ColWidth) missing" );
1003 sal_uInt16 nWidth
= (pSW
&& aSWRes
.nRemainingData
>= 3) ? SVBT16ToUInt16(pSW
+ 1) : 1440;
1005 aNewSection
.maSep
.rgdxaColumnWidthSpacing
[++nColumnDataIdx
] = nWidth
;
1007 if ( nColumn
< nColumnCount
- 1 )
1009 //sprmSDxaColSpacing
1010 SprmResult aSDRes
= pSep
->HasSprm(nColumnSpacingSprmId
, nColumn
);
1011 const sal_uInt8
* pSD
= aSDRes
.pSprm
;
1013 OSL_ENSURE( pSD
, "+Sprm 137 (resp. 0xF204) (Colspacing) missing" );
1014 if (pSD
&& aSDRes
.nRemainingData
>= 3)
1016 nWidth
= SVBT16ToUInt16(pSD
+ 1);
1017 aNewSection
.maSep
.rgdxaColumnWidthSpacing
[++nColumnDataIdx
] = nWidth
;
1024 static const sal_uInt16 aVer2Ids1
[] =
1026 /*sprmSBOrientation*/ 137,
1027 /*sprmSXaPage*/ 139,
1028 /*sprmSYaPage*/ 140,
1029 /*sprmSDxaLeft*/ 141,
1030 /*sprmSDxaRight*/ 142,
1031 /*sprmSDzaGutter*/ 145,
1032 /*sprmSFPgnRestart*/ 125,
1033 /*sprmSPgnStart*/ 136,
1034 /*sprmSDmBinFirst*/ 115,
1035 /*sprmSDmBinOther*/ 116
1038 static const sal_uInt16 aVer67Ids1
[] =
1040 NS_sprm::v6::sprmSBOrientation
,
1041 NS_sprm::v6::sprmSXaPage
,
1042 NS_sprm::v6::sprmSYaPage
,
1043 NS_sprm::v6::sprmSDxaLeft
,
1044 NS_sprm::v6::sprmSDxaRight
,
1045 NS_sprm::v6::sprmSDzaGutter
,
1046 NS_sprm::v6::sprmSFPgnRestart
,
1047 NS_sprm::v6::sprmSPgnStart
,
1048 NS_sprm::v6::sprmSDmBinFirst
,
1049 NS_sprm::v6::sprmSDmBinOther
1052 static const sal_uInt16 aVer8Ids1
[] =
1054 NS_sprm::SBOrientation::val
,
1055 NS_sprm::SXaPage::val
,
1056 NS_sprm::SYaPage::val
,
1057 NS_sprm::SDxaLeft::val
,
1058 NS_sprm::SDxaRight::val
,
1059 NS_sprm::SDzaGutter::val
,
1060 NS_sprm::SFPgnRestart::val
,
1061 NS_sprm::SPgnStart97::val
,
1062 NS_sprm::SDmBinFirst::val
,
1063 NS_sprm::SDmBinOther::val
1066 pIds
= eVer
<= ww::eWW2
? aVer2Ids1
: eVer
<= ww::eWW7
? aVer67Ids1
: aVer8Ids1
;
1069 aNewSection
.maSep
.dmOrientPage
= ReadBSprm(pSep
, pIds
[0], 0);
1072 aNewSection
.maSep
.xaPage
= ReadUSprm(pSep
, pIds
[1], lLetterWidth
);
1073 aNewSection
.nPgWidth
= SvxPaperInfo::GetSloppyPaperDimension(aNewSection
.maSep
.xaPage
);
1075 aNewSection
.maSep
.yaPage
= ReadUSprm(pSep
, pIds
[2], lLetterHeight
);
1078 static const sal_uInt16 nLef
[] = { MM_250
, 1800 };
1079 static const sal_uInt16 nRig
[] = { MM_250
, 1800 };
1081 aNewSection
.maSep
.dxaLeft
= ReadUSprm( pSep
, pIds
[3], nLef
[nLIdx
]);
1082 aNewSection
.maSep
.dxaRight
= ReadUSprm( pSep
, pIds
[4], nRig
[nLIdx
]);
1084 // 2pages in 1sheet hackery ?
1085 // #i31806# but only swap if 2page in 1sheet is enabled.
1086 // it's not clear if dmOrientPage is the correct member to
1088 if(mrReader
.m_xWDop
->doptypography
.m_f2on1
&&
1089 aNewSection
.maSep
.dmOrientPage
== 2)
1090 std::swap(aNewSection
.maSep
.dxaLeft
, aNewSection
.maSep
.dxaRight
);
1092 aNewSection
.maSep
.dzaGutter
= ReadUSprm( pSep
, pIds
[5], 0);
1094 aNewSection
.maSep
.fRTLGutter
= static_cast< sal_uInt8
>(eVer
>= ww::eWW8
? ReadUSprm( pSep
, NS_sprm::SFRTLGutter::val
, 0 ) : 0);
1096 // Page Number Restarts - sprmSFPgnRestart
1097 aNewSection
.maSep
.fPgnRestart
= ReadBSprm(pSep
, pIds
[6], 0);
1099 aNewSection
.maSep
.pgnStart
= ReadUSprm( pSep
, pIds
[7], 0 );
1101 // if the document's first page number is unspecified, but it starts with an even page break,
1102 // then set the first page number to two
1103 if ( maSegments
.empty() && !aNewSection
.maSep
.fPgnRestart
&& pSprmBkc
&& *pSprmBkc
== 3 )
1105 aNewSection
.maSep
.pgnStart
= 2;
1106 aNewSection
.maSep
.fPgnRestart
= 1;
1109 if (eVer
>= ww::eWW6
)
1111 aRes
= pSep
->HasSprm(eVer
<= ww::eWW7
? NS_sprm::v6::sprmSiHeadingPgn
: NS_sprm::SiHeadingPgn::val
);
1112 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 1)
1113 aNewSection
.maSep
.iHeadingPgn
= *aRes
.pSprm
;
1115 aRes
= pSep
->HasSprm(eVer
<= ww::eWW7
? NS_sprm::v6::sprmSScnsPgn
: NS_sprm::ScnsPgn::val
);
1116 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 1)
1117 aNewSection
.maSep
.cnsPgn
= *aRes
.pSprm
;
1120 aRes
= pSep
->HasSprm(pIds
[8]);
1121 const sal_uInt8
* pSprmSDmBinFirst
= aRes
.pSprm
;
1122 if (pSprmSDmBinFirst
&& aRes
.nRemainingData
>= 1)
1123 aNewSection
.maSep
.dmBinFirst
= *pSprmSDmBinFirst
;
1125 aRes
= pSep
->HasSprm(pIds
[9]);
1126 const sal_uInt8
* pSprmSDmBinOther
= aRes
.pSprm
;
1127 if (pSprmSDmBinOther
&& aRes
.nRemainingData
>= 1)
1128 aNewSection
.maSep
.dmBinOther
= *pSprmSDmBinOther
;
1130 static const sal_uInt16 nTop
[] = { MM_250
, 1440 };
1131 static const sal_uInt16 nBot
[] = { MM_200
, 1440 };
1133 static const sal_uInt16 aVer2Ids2
[] =
1135 /*sprmSDyaTop*/ 143,
1136 /*sprmSDyaBottom*/ 144,
1137 /*sprmSDyaHdrTop*/ 131,
1138 /*sprmSDyaHdrBottom*/ 132,
1139 /*sprmSNLnnMod*/ 129,
1141 /*sprmSDxaLnn*/ 130,
1145 static const sal_uInt16 aVer67Ids2
[] =
1147 NS_sprm::v6::sprmSDyaTop
,
1148 NS_sprm::v6::sprmSDyaBottom
,
1149 NS_sprm::v6::sprmSDyaHdrTop
,
1150 NS_sprm::v6::sprmSDyaHdrBottom
,
1151 NS_sprm::v6::sprmSNLnnMod
,
1152 NS_sprm::v6::sprmSLnc
,
1153 NS_sprm::v6::sprmSDxaLnn
,
1154 NS_sprm::v6::sprmSLnnMin
1156 static const sal_uInt16 aVer8Ids2
[] =
1158 NS_sprm::SDyaTop::val
,
1159 NS_sprm::SDyaBottom::val
,
1160 NS_sprm::SDyaHdrTop::val
,
1161 NS_sprm::SDyaHdrBottom::val
,
1162 NS_sprm::SNLnnMod::val
,
1164 NS_sprm::SDxaLnn::val
,
1165 NS_sprm::SLnnMin::val
1168 pIds
= eVer
<= ww::eWW2
? aVer2Ids2
: eVer
<= ww::eWW7
? aVer67Ids2
: aVer8Ids2
;
1170 aNewSection
.maSep
.dyaTop
= ReadSprm( pSep
, pIds
[0], nTop
[nLIdx
] );
1171 aNewSection
.maSep
.dyaBottom
= ReadSprm( pSep
, pIds
[1], nBot
[nLIdx
] );
1172 aNewSection
.maSep
.dyaHdrTop
= ReadUSprm( pSep
, pIds
[2], 720 );
1173 aNewSection
.maSep
.dyaHdrBottom
= ReadUSprm( pSep
, pIds
[3], 720 );
1175 if (eVer
>= ww::eWW8
)
1177 aNewSection
.maSep
.wTextFlow
= ReadUSprm(pSep
, NS_sprm::STextFlow::val
, 0);
1178 aNewSection
.maSep
.clm
= ReadUSprm( pSep
, NS_sprm::SClm::val
, 0 );
1179 aNewSection
.maSep
.dyaLinePitch
= ReadUSprm(pSep
, NS_sprm::SDyaLinePitch::val
, 360);
1180 aRes
= pSep
->HasSprm(NS_sprm::SDxtCharSpace::val
);
1181 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 4)
1182 aNewSection
.maSep
.dxtCharSpace
= SVBT32ToUInt32(aRes
.pSprm
);
1185 sal_uInt16 pgbProp
= ReadSprm( pSep
, NS_sprm::SPgbProp::val
, 0 );
1186 aNewSection
.maSep
.pgbApplyTo
= pgbProp
& 0x0007;
1187 aNewSection
.maSep
.pgbPageDepth
= (pgbProp
& 0x0018) >> 3;
1188 aNewSection
.maSep
.pgbOffsetFrom
= (pgbProp
& 0x00E0) >> 5;
1190 aNewSection
.mnBorders
= ::lcl_ReadBorders(false, aNewSection
.brc
, nullptr, nullptr, pSep
);
1193 // check if Line Numbering must be activated or reset
1194 SprmResult aSprmSNLnnMod
= pSep
->HasSprm(pIds
[4]);
1195 if (aSprmSNLnnMod
.pSprm
&& aSprmSNLnnMod
.nRemainingData
>= 1)
1196 aNewSection
.maSep
.nLnnMod
= *aSprmSNLnnMod
.pSprm
;
1198 SprmResult aSprmSLnc
= pSep
->HasSprm(pIds
[5]);
1199 if (aSprmSLnc
.pSprm
&& aSprmSLnc
.nRemainingData
>= 1)
1200 aNewSection
.maSep
.lnc
= *aSprmSLnc
.pSprm
;
1202 SprmResult aSprmSDxaLnn
= pSep
->HasSprm(pIds
[6]);
1203 if (aSprmSDxaLnn
.pSprm
&& aSprmSDxaLnn
.nRemainingData
>= 2)
1204 aNewSection
.maSep
.dxaLnn
= SVBT16ToUInt16(aSprmSDxaLnn
.pSprm
);
1206 SprmResult aSprmSLnnMin
= pSep
->HasSprm(pIds
[7]);
1207 if (aSprmSLnnMin
.pSprm
&& aSprmSLnnMin
.nRemainingData
>= 1)
1208 aNewSection
.maSep
.lnnMin
= *aSprmSLnnMin
.pSprm
;
1210 if (eVer
<= ww::eWW7
)
1211 aNewSection
.maSep
.grpfIhdt
= ReadBSprm(pSep
, eVer
<= ww::eWW2
? 128 : 153, 0);
1212 else if (mrReader
.m_xHdFt
)
1214 aNewSection
.maSep
.grpfIhdt
= WW8_HEADER_ODD
| WW8_FOOTER_ODD
1215 | WW8_HEADER_FIRST
| WW8_FOOTER_FIRST
;
1217 // It is possible for a first page header to be provided
1218 // for this section, but not actually shown in this section. In this
1219 // case (aNewSection.maSep.grpfIhdt & WW8_HEADER_FIRST) will be nonzero
1220 // but aNewSection.HasTitlePage() will be false.
1221 // Likewise for first page footer.
1223 if (mrReader
.m_xWDop
->fFacingPages
)
1224 aNewSection
.maSep
.grpfIhdt
|= WW8_HEADER_EVEN
| WW8_FOOTER_EVEN
;
1226 //See if we have a header or footer for each enabled possibility
1227 //if we do not then we inherit the previous sections header/footer,
1228 for (int nI
= 0, nMask
= 1; nI
< 6; ++nI
, nMask
<<= 1)
1230 if (aNewSection
.maSep
.grpfIhdt
& nMask
)
1232 WW8_CP nStart
, nLen
;
1233 mrReader
.m_xHdFt
->GetTextPosExact( static_cast< short >(nI
+ ( maSegments
.size() + 1) * 6), nStart
, nLen
);
1234 //No header or footer, inherit previous one, or set to zero
1235 //if no previous one
1239 maSegments
.empty() ||
1240 !(maSegments
.back().maSep
.grpfIhdt
& nMask
)
1243 aNewSection
.maSep
.grpfIhdt
&= ~nMask
;
1250 SetLeftRight(aNewSection
);
1251 //END read section values
1253 if (eVer
>= ww::eWW8
)
1254 aNewSection
.SetDirection();
1256 mrReader
.HandleLineNumbering(aNewSection
);
1257 maSegments
.push_back(aNewSection
);
1260 void SwWW8ImplReader::CopyPageDescHdFt(const SwPageDesc
* pOrgPageDesc
,
1261 SwPageDesc
* pNewPageDesc
, sal_uInt8 nCode
)
1263 // copy odd header content section
1264 if( nCode
& WW8_HEADER_ODD
)
1266 m_rDoc
.CopyHeader(pOrgPageDesc
->GetMaster(),
1267 pNewPageDesc
->GetMaster() );
1269 // copy odd footer content section
1270 if( nCode
& WW8_FOOTER_ODD
)
1272 m_rDoc
.CopyFooter(pOrgPageDesc
->GetMaster(),
1273 pNewPageDesc
->GetMaster());
1275 // copy even header content section
1276 if( nCode
& WW8_HEADER_EVEN
)
1278 m_rDoc
.CopyHeader(pOrgPageDesc
->GetLeft(),
1279 pNewPageDesc
->GetLeft());
1281 // copy even footer content section
1282 if( nCode
& WW8_FOOTER_EVEN
)
1284 m_rDoc
.CopyFooter(pOrgPageDesc
->GetLeft(),
1285 pNewPageDesc
->GetLeft());
1287 // copy first page header content section
1288 if( nCode
& WW8_HEADER_FIRST
)
1290 m_rDoc
.CopyHeader(pOrgPageDesc
->GetFirstMaster(),
1291 pNewPageDesc
->GetFirstMaster());
1293 // copy first page footer content section
1294 if( nCode
& WW8_FOOTER_FIRST
)
1296 m_rDoc
.CopyFooter(pOrgPageDesc
->GetFirstMaster(),
1297 pNewPageDesc
->GetFirstMaster());
1301 // helper functions for graphics, Apos and tables
1303 // Read BoRder Control structure
1304 // nBrcVer should be set to the version of the BRC record being read (6, 8 or 9)
1305 // This will be converted to the latest format (9).
1306 static bool SetWW8_BRC(int nBrcVer
, WW8_BRCVer9
& rVar
, const sal_uInt8
* pS
, size_t nLen
)
1311 if (nBrcVer
== 9 && nLen
>= sizeof(WW8_BRCVer9
))
1312 rVar
= *reinterpret_cast<const WW8_BRCVer9
*>(pS
);
1313 else if (nBrcVer
== 8 && nLen
>= sizeof(WW8_BRC
))
1314 rVar
= WW8_BRCVer9(*reinterpret_cast<const WW8_BRC
*>(pS
));
1315 else if (nLen
>= sizeof(WW8_BRCVer6
)) // nBrcVer == 6
1316 rVar
= WW8_BRCVer9(WW8_BRC(*reinterpret_cast<const WW8_BRCVer6
*>(pS
)));
1319 return nullptr != pS
;
1322 static sal_uInt8
lcl_ReadBorders(bool bVer67
, WW8_BRCVer9
* brc
, WW8PLCFx_Cp_FKP
* pPap
,
1323 const WW8RStyle
* pSty
, const WW8PLCFx_SEPX
* pSep
)
1326 //returns a sal_uInt8 filled with a bit for each position that had a sprm
1327 //setting that border
1329 sal_uInt8 nBorder
= 0;
1334 SprmResult a8Sprm
[4];
1335 if (pSep
->Find4Sprms(
1336 NS_sprm::SBrcTop80::val
, NS_sprm::SBrcLeft80::val
,
1337 NS_sprm::SBrcBottom80::val
, NS_sprm::SBrcRight80::val
,
1338 a8Sprm
[0], a8Sprm
[1], a8Sprm
[2], a8Sprm
[3]))
1340 for( int i
= 0; i
< 4; ++i
)
1341 nBorder
|= int(SetWW8_BRC(8, brc
[i
], a8Sprm
[i
].pSprm
, a8Sprm
[i
].nRemainingData
))<<i
;
1344 // Version 9 BRCs if present will override version 8
1345 SprmResult a9Sprm
[4];
1346 if (pSep
->Find4Sprms(
1347 NS_sprm::SBrcTop::val
, NS_sprm::SBrcLeft::val
,
1348 NS_sprm::SBrcBottom::val
, NS_sprm::SBrcRight::val
,
1349 a9Sprm
[0], a9Sprm
[1], a9Sprm
[2], a9Sprm
[3]))
1351 for( int i
= 0; i
< 4; ++i
)
1352 nBorder
|= int(SetWW8_BRC(9, brc
[i
], a9Sprm
[i
].pSprm
, a9Sprm
[i
].nRemainingData
))<<i
;
1359 static const sal_uInt16 aVer67Ids
[5] = {
1360 NS_sprm::v6::sprmPBrcTop
,
1361 NS_sprm::v6::sprmPBrcLeft
,
1362 NS_sprm::v6::sprmPBrcBottom
,
1363 NS_sprm::v6::sprmPBrcRight
,
1364 NS_sprm::v6::sprmPBrcBetween
1367 static const sal_uInt16 aVer8Ids
[5] = {
1368 NS_sprm::PBrcTop80::val
,
1369 NS_sprm::PBrcLeft80::val
,
1370 NS_sprm::PBrcBottom80::val
,
1371 NS_sprm::PBrcRight80::val
,
1372 NS_sprm::PBrcBetween80::val
1375 static const sal_uInt16 aVer9Ids
[5] = {
1376 NS_sprm::PBrcTop::val
,
1377 NS_sprm::PBrcLeft::val
,
1378 NS_sprm::PBrcBottom::val
,
1379 NS_sprm::PBrcRight::val
,
1380 NS_sprm::PBrcBetween::val
1387 for( int i
= 0; i
< 5; ++i
)
1389 SprmResult
aRes(pPap
->HasSprm(aVer67Ids
[i
]));
1390 nBorder
|= int(SetWW8_BRC(6 , brc
[i
], aRes
.pSprm
, aRes
.nRemainingData
))<<i
;
1395 for( int i
= 0; i
< 5; ++i
)
1397 SprmResult
aRes(pPap
->HasSprm(aVer8Ids
[i
]));
1398 nBorder
|= int(SetWW8_BRC(8 , brc
[i
], aRes
.pSprm
, aRes
.nRemainingData
))<<i
;
1400 // Version 9 BRCs if present will override version 8
1401 for( int i
= 0; i
< 5; ++i
)
1403 SprmResult
aRes(pPap
->HasSprm(aVer9Ids
[i
]));
1404 nBorder
|= int(SetWW8_BRC(9 , brc
[i
], aRes
.pSprm
, aRes
.nRemainingData
))<<i
;
1412 for( int i
= 0; i
< 5; ++i
)
1414 SprmResult
aRes(pSty
->HasParaSprm(aVer67Ids
[i
]));
1415 nBorder
|= int(SetWW8_BRC(6 , brc
[i
], aRes
.pSprm
, aRes
.nRemainingData
))<<i
;
1420 for( int i
= 0; i
< 5; ++i
)
1422 SprmResult
aRes(pSty
->HasParaSprm(aVer8Ids
[i
]));
1423 nBorder
|= int(SetWW8_BRC(8 , brc
[i
], aRes
.pSprm
, aRes
.nRemainingData
))<<i
;
1425 // Version 9 BRCs if present will override version 8
1426 for( int i
= 0; i
< 5; ++i
)
1428 SprmResult
aRes(pSty
->HasParaSprm(aVer9Ids
[i
]));
1429 nBorder
|= int(SetWW8_BRC(9 , brc
[i
], aRes
.pSprm
, aRes
.nRemainingData
))<<i
;
1434 OSL_ENSURE( pSty
|| pPap
, "WW8PLCFx_Cp_FKP and WW8RStyle "
1435 "and WW8PLCFx_SEPX is 0" );
1442 static void GetLineIndex(SvxBoxItem
&rBox
, short nLineThickness
, short nSpace
,
1443 sal_uInt32 cv
, short nIdx
, SvxBoxItemLine nOOIndex
, sal_uInt16 nWWIndex
,
1446 // LO cannot handle outset/inset (new in WW9 BRC) so fall back same as WW8
1447 if ( nIdx
== 0x1A || nIdx
== 0x1B )
1449 nIdx
= (nIdx
== 0x1A) ? 0x12 : 0x11;
1453 SvxBorderLineStyle
const eStyle(
1454 ::editeng::ConvertBorderStyleFromWord(nIdx
));
1456 ::editeng::SvxBorderLine aLine
;
1457 aLine
.SetBorderLineStyle( eStyle
);
1458 double const fConverted( (SvxBorderLineStyle::NONE
== eStyle
) ? 0.0 :
1459 ::editeng::ConvertBorderWidthFromWord(eStyle
, nLineThickness
, nIdx
));
1460 aLine
.SetWidth(fConverted
);
1462 //No AUTO for borders as yet, so if AUTO, use BLACK
1463 Color col
= (cv
==0xff000000) ? COL_BLACK
: msfilter::util::BGRToRGB(cv
);
1465 aLine
.SetColor(col
);
1468 pSize
[nWWIndex
] = fConverted
+ nSpace
;
1470 rBox
.SetLine(&aLine
, nOOIndex
);
1471 rBox
.SetDistance(nSpace
, nOOIndex
);
1475 static void Set1Border(SvxBoxItem
&rBox
, const WW8_BRCVer9
& rBor
, SvxBoxItemLine nOOIndex
,
1476 sal_uInt16 nWWIndex
, short *pSize
, const bool bIgnoreSpace
)
1479 short nLineThickness
= rBor
.DetermineBorderProperties(&nSpace
);
1481 GetLineIndex(rBox
, nLineThickness
, bIgnoreSpace
? 0 : nSpace
,
1482 rBor
.cv(), rBor
.brcType(), nOOIndex
, nWWIndex
, pSize
);
1486 static bool lcl_IsBorder(const WW8_BRCVer9
* pbrc
, bool bChkBtwn
= false)
1488 return pbrc
[WW8_TOP
].brcType() || // brcType != 0
1489 pbrc
[WW8_LEFT
].brcType() ||
1490 pbrc
[WW8_BOT
].brcType() ||
1491 pbrc
[WW8_RIGHT
].brcType() ||
1492 (bChkBtwn
&& pbrc
[WW8_BETW
].brcType());
1495 bool SwWW8ImplReader::IsBorder(const WW8_BRCVer9
* pbrc
, bool bChkBtwn
)
1497 return lcl_IsBorder(pbrc
, bChkBtwn
);
1500 bool SwWW8ImplReader::SetBorder(SvxBoxItem
& rBox
, const WW8_BRCVer9
* pbrc
,
1501 short *pSizeArray
, sal_uInt8 nSetBorders
)
1503 bool bChange
= false;
1504 static const std::pair
<sal_uInt16
, SvxBoxItemLine
> aIdArr
[] =
1506 { WW8_TOP
, SvxBoxItemLine::TOP
},
1507 { WW8_LEFT
, SvxBoxItemLine::LEFT
},
1508 { WW8_RIGHT
, SvxBoxItemLine::RIGHT
},
1509 { WW8_BOT
, SvxBoxItemLine::BOTTOM
},
1510 { WW8_BETW
, SvxBoxItemLine::BOTTOM
}
1513 for( int i
= 0; i
< 4; ++i
)
1515 // filter out the invalid borders
1516 const WW8_BRCVer9
& rB
= pbrc
[ aIdArr
[ i
].first
];
1517 if( !rB
.isNil() && rB
.brcType() )
1519 Set1Border(rBox
, rB
, aIdArr
[i
].second
, aIdArr
[i
].first
, pSizeArray
, false);
1522 else if ( nSetBorders
& (1 << aIdArr
[i
].first
) )
1527 If a style has borders set,and the para attributes attempt remove
1528 the borders, then this is perfectly acceptable, so we shouldn't
1529 ignore this blank entry
1531 nSetBorders has a bit set for each location that a sprm set a
1532 border, so with a sprm set, but no border, then disable the
1535 rBox
.SetLine( nullptr, aIdArr
[ i
].second
);
1541 bool SwWW8ImplReader::SetShadow(SvxShadowItem
& rShadow
, const short *pSizeArray
,
1542 const WW8_BRCVer9
& aRightBrc
)
1544 bool bRet
= aRightBrc
.fShadow() && pSizeArray
&& pSizeArray
[WW8_RIGHT
];
1547 rShadow
.SetColor(COL_BLACK
);
1549 short nVal
= aRightBrc
.DetermineBorderProperties();
1553 rShadow
.SetWidth(nVal
);
1554 rShadow
.SetLocation(SvxShadowLocation::BottomRight
);
1560 void SwWW8ImplReader::GetBorderDistance(const WW8_BRCVer9
* pbrc
,
1561 tools::Rectangle
& rInnerDist
)
1563 rInnerDist
= tools::Rectangle( pbrc
[ 1 ].dptSpace() * 20,
1564 pbrc
[ 0 ].dptSpace() * 20,
1565 pbrc
[ 3 ].dptSpace() * 20,
1566 pbrc
[ 2 ].dptSpace() * 20 );
1569 bool SwWW8ImplReader::SetFlyBordersShadow(SfxItemSet
& rFlySet
,
1570 const WW8_BRCVer9
*pbrc
, short *pSizeArray
)
1572 bool bShadowed
= false;
1575 SvxBoxItem
aBox( RES_BOX
);
1576 SetBorder(aBox
, pbrc
, pSizeArray
);
1578 rFlySet
.Put( aBox
);
1581 SvxShadowItem
aShadow( RES_SHADOW
);
1582 if( SetShadow( aShadow
, pSizeArray
, pbrc
[WW8_RIGHT
] ))
1585 rFlySet
.Put( aShadow
);
1593 // for computing the minimal FrameSize
1594 #define MAX_BORDER_SIZE 210 // max. size of border
1595 #define MAX_EMPTY_BORDER 10 // for off-by-one errors, at least 1
1597 static void FlySecur1(short& rSize
, const bool bBorder
)
1599 short nMin
= MINFLY
+
1600 (bBorder
? MAX_BORDER_SIZE
: MAX_EMPTY_BORDER
);
1606 static bool SetValSprm( sal_Int16
* pVar
, WW8PLCFx_Cp_FKP
* pPap
, sal_uInt16 nId
)
1608 SprmResult aS
= pPap
->HasSprm(nId
);
1609 if (aS
.pSprm
&& aS
.nRemainingData
>= 2)
1610 *pVar
= static_cast<sal_Int16
>(SVBT16ToUInt16(aS
.pSprm
));
1611 return aS
.pSprm
!= nullptr;
1614 static bool SetValSprm( sal_Int16
* pVar
, const WW8RStyle
* pStyle
, sal_uInt16 nId
)
1616 SprmResult aS
= pStyle
->HasParaSprm(nId
);
1617 if (aS
.pSprm
&& aS
.nRemainingData
>= 2)
1618 *pVar
= static_cast<sal_Int16
>(SVBT16ToUInt16(aS
.pSprm
));
1619 return aS
.pSprm
!= nullptr;
1623 #i1930 revealed that sprm 0x360D (sprmTPc) as used in tables can affect the frame
1624 around the table. Its full structure is not fully understood as yet.
1626 void WW8FlyPara::ApplyTabPos(const WW8_TablePos
*pTabPos
)
1630 nSp26
= pTabPos
->nSp26
;
1631 nSp27
= pTabPos
->nSp27
;
1632 nSp29
= pTabPos
->nSp29
;
1633 nLeMgn
= pTabPos
->nLeMgn
;
1634 nRiMgn
= pTabPos
->nRiMgn
;
1635 nUpMgn
= pTabPos
->nUpMgn
;
1636 nLoMgn
= pTabPos
->nLoMgn
;
1637 nSp37
= pTabPos
->nSp37
;
1641 WW8FlyPara::WW8FlyPara(bool bIsVer67
, const WW8FlyPara
* pSrc
/* = 0 */)
1644 memcpy( this, pSrc
, sizeof( WW8FlyPara
) ); // Copy-Ctor
1656 nSp37
= 2; // Default: wrapping
1657 bBorderLines
= false;
1664 bool WW8FlyPara::operator==(const WW8FlyPara
& rSrc
) const
1667 Compare the parts that word seems to compare for equivalence.
1668 Interestingly being autoheight or absolute height (the & 0x7fff) doesn't
1673 (nSp26
== rSrc
.nSp26
) &&
1674 (nSp27
== rSrc
.nSp27
) &&
1675 ((nSp45
& 0x7fff) == (rSrc
.nSp45
& 0x7fff)) &&
1676 (nSp28
== rSrc
.nSp28
) &&
1677 (nLeMgn
== rSrc
.nLeMgn
) &&
1678 (nRiMgn
== rSrc
.nRiMgn
) &&
1679 (nUpMgn
== rSrc
.nUpMgn
) &&
1680 (nLoMgn
== rSrc
.nLoMgn
) &&
1681 (nSp29
== rSrc
.nSp29
) &&
1682 (nSp37
== rSrc
.nSp37
)
1686 // Read for normal text
1687 void WW8FlyPara::Read(sal_uInt8 nOrigSp29
, WW8PLCFx_Cp_FKP
* pPap
)
1691 SetValSprm( &nSp26
, pPap
, 26 ); // X-position //sprmPDxaAbs
1692 //set in me or in parent style
1693 mbVertSet
|= SetValSprm( &nSp27
, pPap
, 27 ); // Y-position //sprmPDyaAbs
1694 SetValSprm( &nSp45
, pPap
, 45 ); // height //sprmPWHeightAbs
1695 SetValSprm( &nSp28
, pPap
, 28 ); // width //sprmPDxaWidth
1696 SetValSprm( &nLeMgn
, pPap
, 49 ); // L-border //sprmPDxaFromText
1697 SetValSprm( &nRiMgn
, pPap
, 49 ); // R-border //sprmPDxaFromText
1698 SetValSprm( &nUpMgn
, pPap
, 48 ); // U-border //sprmPDyaFromText
1699 SetValSprm( &nLoMgn
, pPap
, 48 ); // D-border //sprmPDyaFromText
1701 SprmResult aS
= pPap
->HasSprm(NS_sprm::v6::sprmPWr
);
1702 if (aS
.pSprm
&& aS
.nRemainingData
>= 1)
1707 SetValSprm( &nSp26
, pPap
, NS_sprm::PDxaAbs::val
); // X-position
1708 //set in me or in parent style
1709 mbVertSet
|= SetValSprm( &nSp27
, pPap
, NS_sprm::PDyaAbs::val
); // Y-position
1710 SetValSprm( &nSp45
, pPap
, NS_sprm::PWHeightAbs::val
); // height
1711 SetValSprm( &nSp28
, pPap
, NS_sprm::PDxaWidth::val
); // width
1712 SetValSprm( &nLeMgn
, pPap
, NS_sprm::PDxaFromText::val
); // L-border
1713 SetValSprm( &nRiMgn
, pPap
, NS_sprm::PDxaFromText::val
); // R-border
1714 SetValSprm( &nUpMgn
, pPap
, NS_sprm::PDyaFromText::val
); // U-border
1715 SetValSprm( &nLoMgn
, pPap
, NS_sprm::PDyaFromText::val
); // D-border
1717 SprmResult aS
= pPap
->HasSprm(NS_sprm::PWr::val
); // wrapping
1718 if (aS
.pSprm
&& aS
.nRemainingData
>= 1)
1722 if( ::lcl_ReadBorders( bVer67
, brc
, pPap
)) // borders
1723 bBorderLines
= ::lcl_IsBorder( brc
);
1727 Appears that with no dyaAbs set then the actual vert anchoring set is
1728 ignored and we remain relative to text, so if that is the case we are 0
1729 from para anchor, so we update the frame to have explicitly this type of
1733 nSp29
= (nOrigSp29
& 0xCF) | 0x20;
1738 void WW8FlyPara::ReadFull(sal_uInt8 nOrigSp29
, SwWW8ImplReader
* pIo
)
1740 std::shared_ptr
<WW8PLCFMan
> xPlcxMan
= pIo
->m_xPlcxMan
;
1741 WW8PLCFx_Cp_FKP
* pPap
= xPlcxMan
->GetPapPLCF();
1743 Read(nOrigSp29
, pPap
); // read Apo parameter
1745 do{ // block for quick exit
1746 if( nSp45
!= 0 /* || nSp28 != 0 */ )
1747 break; // bGrafApo only automatic for height
1748 if( pIo
->m_xWwFib
->m_fComplex
)
1749 break; // (*pPap)++ does not work for FastSave
1750 // -> for FastSave, no test for graphics APO
1751 SvStream
* pIoStrm
= pIo
->m_pStrm
;
1752 sal_uLong nPos
= pIoStrm
->Tell();
1753 WW8PLCFxSave1 aSave
;
1754 xPlcxMan
->GetPap()->Save( aSave
);
1757 do{ // block for quick exit
1760 if (!checkRead(*pIoStrm
, nText
, 2)) // read text
1763 if( nText
[0] != 0x01 || nText
[1] != 0x0d )// only graphics + CR?
1766 pPap
->advance(); // next line
1770 SprmResult aS
= pPap
->HasSprm( bVer67
? NS_sprm::v6::sprmPPc
: NS_sprm::PPc::val
);
1772 // no -> graphics Apo
1773 if (!aS
.pSprm
|| aS
.nRemainingData
< 1)
1776 break; // end of APO
1779 ww::WordVersion eVer
= pIo
->GetFib().GetFIBVersion();
1780 WW8FlyPara
*pNowStyleApo
=nullptr;
1781 sal_uInt16 nColl
= pPap
->GetIstd();
1782 ww::sti eSti
= eVer
< ww::eWW6
? ww::GetCanonicalStiFromStc( static_cast< sal_uInt8
>(nColl
) ) : static_cast<ww::sti
>(nColl
);
1783 while (eSti
!= ww::stiNil
&& sal::static_int_cast
<size_t>(nColl
) < pIo
->m_vColl
.size() && nullptr == (pNowStyleApo
= pIo
->m_vColl
[nColl
].m_xWWFly
.get()))
1785 nColl
= pIo
->m_vColl
[nColl
].m_nBase
;
1786 eSti
= eVer
< ww::eWW6
? ww::GetCanonicalStiFromStc( static_cast< sal_uInt8
>(nColl
) ) : static_cast<ww::sti
>(nColl
);
1789 WW8FlyPara
aF(bVer67
, pNowStyleApo
);
1790 // new FlaPara for comparison
1791 aF
.Read(*aS
.pSprm
, pPap
); // WWPara for new Para
1792 if( !( aF
== *this ) ) // same APO? (or a new one?)
1793 bGrafApo
= true; // no -> 1-line APO
1796 while( false ); // block for quick exit
1798 xPlcxMan
->GetPap()->Restore( aSave
);
1799 pIoStrm
->Seek( nPos
);
1800 }while( false ); // block for quick exit
1803 // read for Apo definitions in Styledefs
1804 void WW8FlyPara::Read(sal_uInt8 nOrigSp29
, WW8RStyle
const * pStyle
)
1808 SetValSprm( &nSp26
, pStyle
, NS_sprm::v6::sprmPDxaAbs
); // X-position
1809 //set in me or in parent style
1810 mbVertSet
|= SetValSprm(&nSp27
, pStyle
, NS_sprm::v6::sprmPDyaAbs
); // Y-position
1811 SetValSprm( &nSp45
, pStyle
, NS_sprm::v6::sprmPWHeightAbs
); // height
1812 SetValSprm( &nSp28
, pStyle
, NS_sprm::v6::sprmPDxaWidth
); // width
1813 SetValSprm( &nLeMgn
, pStyle
, NS_sprm::v6::sprmPDxaFromText
); // L-border
1814 SetValSprm( &nRiMgn
, pStyle
, NS_sprm::v6::sprmPDxaFromText
); // R-border
1815 SetValSprm( &nUpMgn
, pStyle
, NS_sprm::v6::sprmPDyaFromText
); // U-border
1816 SetValSprm( &nLoMgn
, pStyle
, NS_sprm::v6::sprmPDyaFromText
); // D-border
1818 SprmResult aS
= pStyle
->HasParaSprm( NS_sprm::v6::sprmPWr
); // wrapping
1819 if (aS
.pSprm
&& aS
.nRemainingData
>= 1)
1824 SetValSprm( &nSp26
, pStyle
, NS_sprm::PDxaAbs::val
); // X-position
1825 //set in me or in parent style
1826 mbVertSet
|= SetValSprm(&nSp27
, pStyle
, NS_sprm::PDyaAbs::val
); // Y-position
1827 SetValSprm( &nSp45
, pStyle
, NS_sprm::PWHeightAbs::val
); // height
1828 SetValSprm( &nSp28
, pStyle
, NS_sprm::PDxaWidth::val
); // width
1829 SetValSprm( &nLeMgn
, pStyle
, NS_sprm::PDxaFromText::val
); // L-border
1830 SetValSprm( &nRiMgn
, pStyle
, NS_sprm::PDxaFromText::val
); // R-border
1831 SetValSprm( &nUpMgn
, pStyle
, NS_sprm::PDyaFromText::val
); // U-border
1832 SetValSprm( &nLoMgn
, pStyle
, NS_sprm::PDyaFromText::val
); // D-border
1834 SprmResult aS
= pStyle
->HasParaSprm( NS_sprm::PWr::val
); // wrapping
1835 if (aS
.pSprm
&& aS
.nRemainingData
>= 1)
1839 if (::lcl_ReadBorders(bVer67
, brc
, nullptr, pStyle
)) // border
1840 bBorderLines
= ::lcl_IsBorder(brc
);
1844 Appears that with no dyaAbs set then the actual vert anchoring set is
1845 ignored and we remain relative to text, so if that is the case we are 0
1846 from para anchor, so we update the frame to have explicitly this type of
1850 nSp29
= (nOrigSp29
& 0xCF) | 0x20;
1855 bool WW8FlyPara::IsEmpty() const
1857 WW8FlyPara
aEmpty(bVer67
);
1859 wr of 0 like 2 appears to me to be equivalent for checking here. See
1860 #107103# if wrong, so given that the empty is 2, if we are 0 then set
1861 empty to 0 to make 0 equiv to 2 for empty checking
1863 OSL_ENSURE(aEmpty
.nSp37
== 2, "this is not what we expect for nSp37");
1864 if (this->nSp37
== 0)
1866 return aEmpty
== *this;
1869 // #i18732# - changes made on behalf of CMC
1870 WW8SwFlyPara::WW8SwFlyPara( SwPaM
& rPaM
,
1871 SwWW8ImplReader
& rIo
,
1873 const sal_uInt32 nWWPgTop
,
1874 const sal_uInt32 nPgWidth
,
1875 const sal_Int32 nIniFlyDx
,
1876 const sal_Int32 nIniFlyDy
):
1877 pFlyFormat(nullptr),
1886 nNetWidth(rWW
.nSp28
),
1887 eHeightFix(SwFrameSize::Fixed
),
1888 eHRel(text::RelOrientation::PAGE_FRAME
),
1889 eVRel(text::RelOrientation::FRAME
),
1890 eVAlign(text::VertOrientation::NONE
),
1891 eHAlign(text::HoriOrientation::NONE
),
1892 eSurround(( rWW
.nSp37
> 1 ) ? css::text::WrapTextMode_DYNAMIC
: css::text::WrapTextMode_NONE
),
1893 nXBind(( rWW
.nSp29
& 0xc0 ) >> 6),
1894 nYBind(( rWW
.nSp29
& 0x30 ) >> 4),
1895 nNewNetWidth(MINFLY
),
1900 //#i119466 mapping "Around" wrap setting to "Parallel" for table
1901 const bool bIsTable
= rIo
.m_xPlcxMan
->HasParaSprm(NS_sprm::PFInTable::val
).pSprm
;
1902 if (bIsTable
&& rWW
.nSp37
== 2)
1903 eSurround
= css::text::WrapTextMode_PARALLEL
;
1906 #95905#, #83307# seems to have gone away now, so re-enable parallel
1907 wrapping support for frames in headers/footers. I don't know if we truly
1908 have an explicitly specified behaviour for these circumstances.
1911 if( nHeight
& 0x8000 )
1914 eHeightFix
= SwFrameSize::Minimum
;
1917 if( nHeight
<= MINFLY
)
1918 { // no data, or bad data
1919 eHeightFix
= SwFrameSize::Minimum
;
1923 if( nWidth
<= 10 ) // auto width
1926 nWidth
= nNetWidth
=
1927 msword_cast
<sal_Int16
>(nPgWidth
? nPgWidth
: 2268); // 4 cm
1929 if( nWidth
<= MINFLY
)
1930 nWidth
= nNetWidth
= MINFLY
; // minimum width
1933 See issue #i9178# for the 9 anchoring options, and make sure they stay
1934 working if you modify the anchoring logic here.
1937 // If the Fly is aligned left, right, up, or down,
1938 // the outer text distance will be ignored, because otherwise
1939 // the Fly will end up in the wrong position.
1940 // The only problem is with inside/outside.
1942 //#i53725# - absolute positioned objects have to be
1943 // anchored at-paragraph to assure its correct anchor position.
1944 rIo
.m_pLastAnchorPos
.reset( new SwPosition(*rPaM
.GetPoint()));
1948 case 0: //relative to margin
1949 eVRel
= text::RelOrientation::PAGE_PRINT_AREA
;
1951 case 1: //relative to page
1952 eVRel
= text::RelOrientation::PAGE_FRAME
;
1954 default: //relative to text
1955 // put in initialization part eVRel = text::RelOrientation::FRAME;
1960 switch( rWW
.nSp27
) // particular Y-positions ?
1963 eVAlign
= text::VertOrientation::TOP
;
1968 eVAlign
= text::VertOrientation::CENTER
;
1971 eVAlign
= text::VertOrientation::BOTTOM
;
1976 nYPos
= rWW
.nSp27
+ static_cast<short>(nIniFlyDy
);
1977 break; // corrections from ini file
1980 switch( rWW
.nSp26
) // particular X-positions ?
1983 eHAlign
= text::HoriOrientation::LEFT
;
1987 eHAlign
= text::HoriOrientation::CENTER
;
1990 eHAlign
= text::HoriOrientation::RIGHT
;
1994 eHAlign
= text::HoriOrientation::LEFT
;
1998 eHAlign
= text::HoriOrientation::RIGHT
;
2002 nXPos
= rWW
.nSp26
+ static_cast<short>(nIniFlyDx
);
2003 break; // corrections from ini file
2007 switch (nXBind
) // X - binding -> transform coordinates
2009 case 0: //relative to column
2010 eHRel
= text::RelOrientation::FRAME
;
2012 case 1: //relative to margin
2013 eHRel
= text::RelOrientation::PAGE_PRINT_AREA
;
2015 default: //relative to page
2016 // put in initialization part eHRel= text::RelOrientation::PAGE_FRAME;
2020 // #i36649# - adjustments for certain horizontal alignments
2021 // Note: These special adjustments found by an investigation of documents
2022 // containing frames with different left/right border distances and
2023 // distances to text. The outcome is somehow strange.
2024 // Note: These adjustments causes wrong horizontal positions for frames,
2025 // which are aligned inside|outside to page|margin on even pages,
2026 // the left and right border distances are different.
2027 // no adjustments possible, if frame has automatic width.
2028 // determine left border distance
2029 sal_Int16
nLeBorderMgn( 0 );
2032 WW8_BRCVer9
&rBrc
= rWW
.brc
[WW8_LEFT
];
2033 sal_Int16 nTemp
= rBrc
.DetermineBorderProperties(&nLeBorderMgn
);
2034 nLeBorderMgn
= nLeBorderMgn
+ nTemp
;
2036 // determine right border distance
2037 sal_Int16
nRiBorderMgn( 0 );
2040 WW8_BRCVer9
&rBrc
= rWW
.brc
[WW8_RIGHT
];
2041 sal_Int16 nTemp
= rBrc
.DetermineBorderProperties(&nRiBorderMgn
);
2042 nRiBorderMgn
= nRiBorderMgn
+ nTemp
;
2044 if ( !bAutoWidth
&& eHAlign
== text::HoriOrientation::LEFT
&& eHRel
== text::RelOrientation::PAGE_FRAME
)
2046 // convert 'left to page' to
2047 // 'from left -<width>-<2*left border distance>-<right wrap distance>
2048 // to page text area'
2049 eHAlign
= text::HoriOrientation::NONE
;
2050 eHRel
= text::RelOrientation::PAGE_PRINT_AREA
;
2051 nXPos
= -nWidth
- (2*nLeBorderMgn
) - rWW
.nRiMgn
;
2052 // re-set left wrap distance
2053 nLeMgn
= rWW
.nLeMgn
;
2055 else if ( !bAutoWidth
&& eHAlign
== text::HoriOrientation::RIGHT
&& eHRel
== text::RelOrientation::PAGE_FRAME
)
2057 // convert 'right to page' to
2058 // 'from left <right border distance-left border distance>+<left wrap distance>
2059 // to right page border'
2060 eHAlign
= text::HoriOrientation::NONE
;
2061 eHRel
= text::RelOrientation::PAGE_RIGHT
;
2062 nXPos
= ( nRiBorderMgn
- nLeBorderMgn
) + rWW
.nLeMgn
;
2063 // re-set right wrap distance
2064 nRiMgn
= rWW
.nRiMgn
;
2066 else if ( !bAutoWidth
&& eHAlign
== text::HoriOrientation::LEFT
&& eHRel
== text::RelOrientation::PAGE_PRINT_AREA
)
2068 // convert 'left to margin' to
2069 // 'from left -<left border distance> to page text area'
2070 eHAlign
= text::HoriOrientation::NONE
;
2071 eHRel
= text::RelOrientation::PAGE_PRINT_AREA
;
2072 nXPos
= -nLeBorderMgn
;
2073 // re-set left wrap distance
2074 nLeMgn
= rWW
.nLeMgn
;
2076 else if ( !bAutoWidth
&& eHAlign
== text::HoriOrientation::RIGHT
&& eHRel
== text::RelOrientation::PAGE_PRINT_AREA
)
2078 // convert 'right to margin' to
2079 // 'from left -<width>-<left border distance> to right page border'
2080 eHAlign
= text::HoriOrientation::NONE
;
2081 eHRel
= text::RelOrientation::PAGE_RIGHT
;
2082 nXPos
= -nWidth
- nLeBorderMgn
;
2083 // re-set right wrap distance
2084 nRiMgn
= rWW
.nRiMgn
;
2086 else if (rWW
.bBorderLines
)
2090 Word has a curious bug where the offset stored do not take into
2091 account the internal distance from the corner both
2093 WW8_BRCVer9
&rBrc
= rWW
.brc
[WW8_LEFT
];
2094 sal_Int16 nLeLMgn
= 0;
2095 sal_Int16 nTemp
= rBrc
.DetermineBorderProperties(&nLeLMgn
);
2096 nLeLMgn
= nLeLMgn
+ nTemp
;
2100 if (eHAlign
== text::HoriOrientation::LEFT
)
2101 eHAlign
= text::HoriOrientation::NONE
;
2102 nXPos
= nXPos
- nLeLMgn
;
2106 // adjustments for certain vertical alignments
2107 if ( eVAlign
== text::VertOrientation::NONE
&& eVRel
== text::RelOrientation::PAGE_PRINT_AREA
)
2109 // convert "<X> from top page text area" to
2110 // "<X + page top margin> from page"
2111 eVRel
= text::RelOrientation::PAGE_FRAME
;
2112 nYPos
= static_cast< sal_Int16
>( nYPos
+ nWWPgTop
);
2115 FlySecur1( nWidth
, rWW
.bBorderLines
); // Do the borders match ?
2116 FlySecur1( nHeight
, rWW
.bBorderLines
);
2120 // If a Fly in WW has automatic width, this has to be simulated
2121 // by modifying the Fly width (fixed in SW) afterwards.
2122 // This can increase or decrease the Fly width, because the default value
2123 // is set without knowledge of the contents.
2124 void WW8SwFlyPara::BoxUpWidth( tools::Long nInWidth
)
2126 if( bAutoWidth
&& nInWidth
> nNewNetWidth
)
2127 nNewNetWidth
= nInWidth
;
2130 // The class WW8FlySet is derived from SfxItemSet and does not
2131 // provide more, but is easier to handle for me.
2132 // WW8FlySet-ctor for Apos and graphics Apos
2133 WW8FlySet::WW8FlySet(SwWW8ImplReader
& rReader
, const WW8FlyPara
* pFW
,
2134 const WW8SwFlyPara
* pFS
, bool bGraf
)
2135 : SfxItemSet(rReader
.m_rDoc
.GetAttrPool(),svl::Items
<RES_FRMATR_BEGIN
,RES_FRMATR_END
-1>{})
2137 Reader::ResetFrameFormatAttrs(*this); // remove distance/border
2139 Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_LR_TB
, RES_FRAMEDIR
));
2141 /*Below can all go when we have from left in rtl mode*/
2142 SwTwips nXPos
= pFS
->nXPos
;
2143 sal_Int16 eHRel
= pFS
->eHRel
;
2144 rReader
.MiserableRTLGraphicsHack(nXPos
, pFS
->nWidth
, pFS
->eHAlign
, eHRel
);
2145 /*Above can all go when we have from left in rtl mode*/
2146 Put( SwFormatHoriOrient(nXPos
, pFS
->eHAlign
, pFS
->eHRel
, pFS
->bTogglePos
));
2147 Put( SwFormatVertOrient( pFS
->nYPos
, pFS
->eVAlign
, pFS
->eVRel
) );
2149 if (pFS
->nLeMgn
|| pFS
->nRiMgn
) // set borders
2150 Put(SvxLRSpaceItem(pFS
->nLeMgn
, pFS
->nRiMgn
, 0, 0, RES_LR_SPACE
));
2152 if (pFS
->nUpMgn
|| pFS
->nLoMgn
)
2153 Put(SvxULSpaceItem(pFS
->nUpMgn
, pFS
->nLoMgn
, RES_UL_SPACE
));
2155 //we no longer need to hack around the header/footer problems
2156 SwFormatSurround
aSurround(pFS
->eSurround
);
2157 if ( pFS
->eSurround
== css::text::WrapTextMode_DYNAMIC
)
2158 aSurround
.SetAnchorOnly( true );
2161 short aSizeArray
[5]={0};
2162 SwWW8ImplReader::SetFlyBordersShadow(*this,pFW
->brc
,&aSizeArray
[0]);
2164 // the 5th parameter is always 0, thus we lose nothing due to the cast
2167 // #i35017# - constant name has changed
2168 Put( SwFormatWrapInfluenceOnObjPos(
2169 text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE
) );
2174 Put( SwFormatAnchor(WW8SwFlyPara::eAnchor
) );
2177 //Ordinarily with frames, the border width and spacing is
2178 //placed outside the frame, making it larger. With these
2179 //types of frames, the left right thickness and space makes
2180 //it wider, but the top bottom spacing and border thickness
2182 Put( SwFormatFrameSize( pFS
->eHeightFix
, pFS
->nWidth
+
2183 aSizeArray
[WW8_LEFT
] + aSizeArray
[WW8_RIGHT
],
2187 // WW8FlySet-ctor for character bound graphics
2188 WW8FlySet::WW8FlySet( SwWW8ImplReader
& rReader
, const SwPaM
* pPaM
,
2189 const WW8_PIC
& rPic
, tools::Long nWidth
, tools::Long nHeight
)
2190 : SfxItemSet(rReader
.m_rDoc
.GetAttrPool(),svl::Items
<RES_FRMATR_BEGIN
,RES_FRMATR_END
-1>{})
2192 Init(rReader
, pPaM
);
2194 Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_LR_TB
, RES_FRAMEDIR
));
2196 short aSizeArray
[5]={0};
2198 If we have set borders then in word the graphic is displaced from the left
2199 and top the width of the borders of those sides, and then the shadow
2200 itself is drawn to the bottom and right of the displaced graphic. In word
2201 the total size is that of the graphic plus the borders, plus the total
2202 shadow around all edges, for this translation the top and left shadow
2203 region is translated spacing around the graphic to those sides, and the
2204 bottom and right shadow size is added to the graphic size.
2206 WW8_BRCVer9 brcVer9
[4];
2207 for (int i
= 0; i
< 4; i
++)
2208 brcVer9
[i
] = WW8_BRCVer9(rPic
.rgbrc
[i
]);
2209 if (SwWW8ImplReader::SetFlyBordersShadow( *this, brcVer9
, &aSizeArray
[0]))
2211 Put(SvxLRSpaceItem( aSizeArray
[WW8_LEFT
], 0, 0, 0, RES_LR_SPACE
) );
2212 Put(SvxULSpaceItem( aSizeArray
[WW8_TOP
], 0, RES_UL_SPACE
));
2213 aSizeArray
[WW8_RIGHT
]*=2;
2214 aSizeArray
[WW8_BOT
]*=2;
2217 Put( SwFormatFrameSize( SwFrameSize::Fixed
, nWidth
+aSizeArray
[WW8_LEFT
]+
2218 aSizeArray
[WW8_RIGHT
], nHeight
+aSizeArray
[WW8_TOP
]
2219 + aSizeArray
[WW8_BOT
]) );
2222 void WW8FlySet::Init(const SwWW8ImplReader
& rReader
, const SwPaM
* pPaM
)
2224 Reader::ResetFrameFormatAttrs(*this); // remove distance/borders
2226 Put(SvxLRSpaceItem(RES_LR_SPACE
)); //inline writer ole2 objects start with 0.2cm l/r
2227 SwFormatAnchor
aAnchor(RndStdIds::FLY_AS_CHAR
);
2229 aAnchor
.SetAnchor(pPaM
->GetPoint());
2232 //The horizontal default is on the baseline, the vertical is centered
2233 //around the character center it appears
2234 if (rReader
.m_aSectionManager
.CurrentSectionIsVertical())
2235 Put(SwFormatVertOrient(0, text::VertOrientation::CHAR_CENTER
,text::RelOrientation::CHAR
));
2237 Put(SwFormatVertOrient(0, text::VertOrientation::TOP
, text::RelOrientation::FRAME
));
2240 WW8DupProperties::WW8DupProperties(SwDoc
&rDoc
, SwWW8FltControlStack
*pStack
)
2241 : pCtrlStck(pStack
),
2242 aChrSet(rDoc
.GetAttrPool(), svl::Items
<RES_CHRATR_BEGIN
, RES_CHRATR_END
- 1>{} ),
2243 aParSet(rDoc
.GetAttrPool(), svl::Items
<RES_PARATR_BEGIN
, RES_PARATR_END
- 1>{} )
2245 //Close any open character properties and duplicate them inside the
2247 size_t nCnt
= pCtrlStck
->size();
2248 for (size_t i
=0; i
< nCnt
; ++i
)
2250 const SwFltStackEntry
& rEntry
= (*pCtrlStck
)[ i
];
2253 if (isCHRATR(rEntry
.pAttr
->Which()))
2255 aChrSet
.Put( *rEntry
.pAttr
);
2258 else if (isPARATR(rEntry
.pAttr
->Which()))
2260 aParSet
.Put( *rEntry
.pAttr
);
2266 void WW8DupProperties::Insert(const SwPosition
&rPos
)
2268 for (const SfxItemSet
* pSet
: {&aChrSet
, &aParSet
})
2272 SfxItemIter
aIter( *pSet
);
2273 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
2276 pCtrlStck
->NewAttr(rPos
, *pItem
);
2277 } while ((pItem
= aIter
.NextItem()));
2282 void SwWW8ImplReader::MoveInsideFly(const SwFrameFormat
*pFlyFormat
)
2284 WW8DupProperties
aDup(m_rDoc
, m_xCtrlStck
.get());
2286 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), 0, false);
2288 // set Pam in FlyFrame
2289 const SwFormatContent
& rContent
= pFlyFormat
->GetContent();
2290 OSL_ENSURE( rContent
.GetContentIdx(), "No content prepared." );
2291 m_pPaM
->GetPoint()->nNode
= rContent
.GetContentIdx()->GetIndex() + 1;
2292 m_pPaM
->GetPoint()->nContent
.Assign( m_pPaM
->GetContentNode(), 0 );
2294 aDup
.Insert(*m_pPaM
->GetPoint());
2297 SwTwips
SwWW8ImplReader::MoveOutsideFly(SwFrameFormat
*pFlyFormat
,
2298 const SwPosition
&rPos
, bool bTableJoin
)
2300 SwTwips nRetWidth
= 0;
2303 // Close all attributes, because otherwise attributes can appear
2304 // that extend out of Flys
2305 WW8DupProperties
aDup(m_rDoc
, m_xCtrlStck
.get());
2306 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), 0, false);
2310 If this fly frame consists entirely of one table inside a frame
2311 followed by an empty paragraph then we want to delete the empty
2312 paragraph so as to get the frame to autoshrink to the size of the
2313 table to emulate words behaviour closer.
2317 const SwNodeIndex
* pNodeIndex
= pFlyFormat
->GetContent().
2321 SwNodeIndex
aIdx( *pNodeIndex
, 1 ),
2322 aEnd( *pNodeIndex
->GetNode().EndOfSectionNode() );
2326 if(aIdx
.GetNode().IsTableNode())
2328 SwTableNode
*pTable
= aIdx
.GetNode().GetTableNode();
2329 aIdx
= *aIdx
.GetNode().EndOfSectionNode();
2331 if ( (aIdx
< aEnd
) && aIdx
.GetNode().IsTextNode() )
2333 SwTextNode
*pNd
= aIdx
.GetNode().GetTextNode();
2335 if (aIdx
== aEnd
&& pNd
&& pNd
->GetText().isEmpty())
2337 //An extra pre-created by writer unused paragraph
2339 //delete after import is complete rather than now
2340 //to avoid the complication of managing uncommitted
2341 //ctrlstack properties that refer to it.
2342 m_aExtraneousParas
.insert(pNd
);
2344 SwTable
& rTable
= pTable
->GetTable();
2345 SwFrameFormat
* pTableFormat
= rTable
.GetFrameFormat();
2349 SwFormatFrameSize aSize
= pTableFormat
->GetFrameSize();
2350 aSize
.SetHeightSizeType(SwFrameSize::Minimum
);
2351 aSize
.SetHeight(MINLAY
);
2352 pFlyFormat
->SetFormatAttr(aSize
);
2353 SwFormatHoriOrient aHori
= pTableFormat
->GetHoriOrient();
2354 // passing the table orientation of
2355 // LEFT_AND_WIDTH to the frame seems to
2356 // work better than FULL, especially if the
2357 // table width exceeds the page width, however
2358 // I am not brave enough to set it in all
2360 pTableFormat
->SetFormatAttr( SwFormatHoriOrient(0, ( aHori
.GetHoriOrient() == text::HoriOrientation::LEFT_AND_WIDTH
) ? ::text::HoriOrientation::LEFT_AND_WIDTH
: text::HoriOrientation::FULL
) );
2361 nRetWidth
= aSize
.GetWidth();
2370 *m_pPaM
->GetPoint() = rPos
;
2371 aDup
.Insert(*m_pPaM
->GetPoint());
2375 std::unique_ptr
<WW8FlyPara
> SwWW8ImplReader::ConstructApo(const ApoTestResults
&rApo
,
2376 const WW8_TablePos
*pTabPos
)
2378 OSL_ENSURE(rApo
.HasFrame() || pTabPos
,
2379 "If no frame found, *MUST* be in a table");
2381 std::unique_ptr
<WW8FlyPara
> pRet(new WW8FlyPara(m_bVer67
, rApo
.mpStyleApo
));
2383 // find APO parameter and test for bGrafApo
2384 if (rApo
.HasFrame())
2385 pRet
->ReadFull(rApo
.m_nSprm29
, this);
2387 pRet
->ApplyTabPos(pTabPos
);
2389 if (pRet
->IsEmpty())
2396 bool SwWW8ImplReader::IsDropCap() const
2398 // Find the DCS (Drop Cap Specifier) for the paragraph
2399 // if does not exist or if the first three bits are 0
2400 // then there is no dropcap on the paragraph
2401 WW8PLCFx_Cp_FKP
*pPap
= m_xPlcxMan
? m_xPlcxMan
->GetPapPLCF() : nullptr;
2406 aDCS
= pPap
->HasSprm(NS_sprm::v6::sprmPDcs
);
2408 aDCS
= m_xPlcxMan
->GetPapPLCF()->HasSprm(NS_sprm::PDcs::val
);
2409 if (aDCS
.pSprm
&& aDCS
.nRemainingData
>= 2)
2412 fdct short :3 0007 drop cap type
2415 2 drop cap in margin
2417 short nDCS
= SVBT16ToUInt16(aDCS
.pSprm
);
2425 bool SwWW8ImplReader::StartApo(const ApoTestResults
&rApo
, const WW8_TablePos
*pTabPos
)
2427 m_xWFlyPara
= ConstructApo(rApo
, pTabPos
);
2431 // <WW8SwFlyPara> constructor has changed - new 4th parameter
2432 // containing WW8 page top margin.
2433 m_xSFlyPara
.reset(new WW8SwFlyPara( *m_pPaM
, *this, *m_xWFlyPara
,
2434 m_aSectionManager
.GetWWPageTopMargin(),
2435 m_aSectionManager
.GetTextAreaWidth(),
2436 m_nIniFlyDx
, m_nIniFlyDy
));
2438 // If this paragraph is a Dropcap set the flag and we will deal with it later
2442 m_xCurrentItemSet
.reset(new SfxItemSet(m_rDoc
.GetAttrPool(), svl::Items
<RES_CHRATR_BEGIN
, RES_PARATR_END
- 1>{}));
2446 if (!m_xWFlyPara
->bGrafApo
)
2449 // Within the GrafApo text attributes have to be ignored, because
2450 // they would apply to the following lines. The frame is only inserted
2451 // if it is not merely positioning a single image. If it is an image
2452 // frame, pWFlyPara and pSFlyPara are retained and the resulting
2453 // attributes applied to the image when inserting the image.
2455 WW8FlySet
aFlySet(*this, m_xWFlyPara
.get(), m_xSFlyPara
.get(), false);
2457 if (pTabPos
&& pTabPos
->bNoFly
)
2459 m_xSFlyPara
->pFlyFormat
= nullptr;
2463 m_xSFlyPara
->pFlyFormat
= m_rDoc
.MakeFlySection(WW8SwFlyPara::eAnchor
,
2464 m_pPaM
->GetPoint(), &aFlySet
);
2465 OSL_ENSURE(m_xSFlyPara
->pFlyFormat
->GetAnchor().GetAnchorId() ==
2466 WW8SwFlyPara::eAnchor
, "Not the anchor type requested!");
2469 if (m_xSFlyPara
->pFlyFormat
)
2474 SdrObject
* pOurNewObject
= CreateContactObject(m_xSFlyPara
->pFlyFormat
);
2475 m_xWWZOrder
->InsertTextLayerObject(pOurNewObject
);
2478 if (RndStdIds::FLY_AS_CHAR
!= WW8SwFlyPara::eAnchor
&& m_xSFlyPara
->pFlyFormat
)
2480 m_xAnchorStck
->AddAnchor(*m_pPaM
->GetPoint(), m_xSFlyPara
->pFlyFormat
);
2483 // remember Pos in body text
2484 m_xSFlyPara
->xMainTextPos
.reset(new SwPosition(*m_pPaM
->GetPoint()));
2486 //remove fltanchors, otherwise they will be closed inside the
2487 //frame, which makes no sense, restore them after the frame is
2489 m_xSFlyPara
->xOldAnchorStck
= std::move(m_xAnchorStck
);
2490 m_xAnchorStck
.reset(new SwWW8FltAnchorStack(m_rDoc
, m_nFieldFlags
));
2492 if (m_xSFlyPara
->pFlyFormat
)
2493 MoveInsideFly(m_xSFlyPara
->pFlyFormat
);
2495 // 1) ReadText() is not called recursively because the length of
2496 // the Apo is unknown at that time, and ReadText() needs it.
2497 // 2) the CtrlStck is not re-created.
2498 // the Char attributes continue (trouble with Sw-attributes)
2499 // Para attributes must be reset at the end of every paragraph,
2500 // i.e. at the end of a paragraph there must not be para attributes
2506 void wwSectionManager::JoinNode(const SwPosition
&rPos
, const SwNode
&rNode
)
2508 if ((!maSegments
.empty()) && (maSegments
.back().maStart
== rPos
.nNode
))
2509 maSegments
.back().maStart
.Assign(rNode
);
2512 bool SwWW8ImplReader::JoinNode(SwPaM
&rPam
, bool bStealAttr
)
2515 rPam
.GetPoint()->nContent
= 0; // go to start of paragraph
2517 SwNodeIndex
aPref(rPam
.GetPoint()->nNode
, -1);
2519 if (SwTextNode
* pNode
= aPref
.GetNode().GetTextNode())
2521 m_aSectionManager
.JoinNode(*rPam
.GetPoint(), aPref
.GetNode());
2522 rPam
.GetPoint()->nNode
= aPref
;
2523 rPam
.GetPoint()->nContent
.Assign(pNode
, pNode
->GetText().getLength());
2525 m_xCtrlStck
->StealAttr(rPam
.GetPoint()->nNode
);
2527 if (m_pLastAnchorPos
|| m_pPreviousNode
|| (m_xSFlyPara
&& m_xSFlyPara
->xMainTextPos
))
2529 SwNodeIndex
aToBeJoined(aPref
, 1);
2531 if (m_pLastAnchorPos
)
2533 //If the last anchor pos is here, then clear the anchor pos.
2534 //This "last anchor pos" is only used for fixing up the
2535 //positions of things anchored to page breaks and here
2536 //we are removing the last paragraph of a frame, so there
2537 //cannot be a page break at this point so we can
2538 //safely reset m_pLastAnchorPos to avoid any dangling
2539 //SwIndex's pointing into the deleted paragraph
2540 SwNodeIndex
aLastAnchorPos(m_pLastAnchorPos
->nNode
);
2541 if (aLastAnchorPos
== aToBeJoined
)
2542 m_pLastAnchorPos
.reset();
2545 if (m_pPreviousNode
)
2547 //If the drop character start pos is here, then clear it.
2548 SwNodeIndex
aDropCharPos(*m_pPreviousNode
);
2549 if (aDropCharPos
== aToBeJoined
)
2550 m_pPreviousNode
= nullptr;
2553 if (m_xSFlyPara
&& m_xSFlyPara
->xMainTextPos
)
2555 // If an open apo pos is here, then clear it before
2556 // JoinNext destroys it
2557 SwNodeIndex
aOpenApoPos(m_xSFlyPara
->xMainTextPos
->nNode
);
2558 if (aOpenApoPos
== aToBeJoined
)
2559 m_xSFlyPara
->xMainTextPos
.reset();
2570 //In auto-width word frames negative after-indent values are ignored
2571 void SwWW8ImplReader::StripNegativeAfterIndent(SwFrameFormat
const *pFlyFormat
)
2573 const SwNodeIndex
* pSttNd
= pFlyFormat
->GetContent().GetContentIdx();
2577 SwNodeIndex
aIdx(*pSttNd
, 1);
2578 SwNodeIndex
aEnd(*pSttNd
->GetNode().EndOfSectionNode());
2581 SwTextNode
*pNd
= aIdx
.GetNode().GetTextNode();
2584 const SvxLRSpaceItem
& rLR
= ItemGet
<SvxLRSpaceItem
>(*pNd
, RES_LR_SPACE
);
2585 if (rLR
.GetRight() < 0)
2587 SvxLRSpaceItem
aLR(rLR
);
2596 void SwWW8ImplReader::StopApo()
2598 OSL_ENSURE(m_xWFlyPara
, "no pWFlyPara to close");
2601 if (m_xWFlyPara
->bGrafApo
)
2603 // image frame that has not been inserted: delete empty paragraph + attr
2604 JoinNode(*m_pPaM
, true);
2609 if (!m_xSFlyPara
->xMainTextPos
)
2611 OSL_ENSURE(m_xSFlyPara
->xMainTextPos
, "StopApo: xMainTextPos is nullptr");
2616 What we are doing with this temporary nodeindex is as follows: The
2617 stack of attributes normally only places them into the document when
2618 the current insertion point has passed them by. Otherwise the end
2619 point of the attribute gets pushed along with the insertion point. The
2620 insertion point is moved and the properties committed during
2621 MoveOutsideFly. We also may want to remove the final paragraph in the
2622 frame, but we need to wait until the properties for that frame text
2623 have been committed otherwise they will be lost. So we first get a
2624 handle to the last the filter inserted. After the attributes are
2625 committed, if that paragraph exists we join it with the para after it
2626 that comes with the frame by default so that as normal we don't end up
2627 with one more paragraph than we wanted.
2629 SwNodeIndex
aPref(m_pPaM
->GetPoint()->nNode
, -1);
2632 MoveOutsideFly(m_xSFlyPara
->pFlyFormat
, *m_xSFlyPara
->xMainTextPos
);
2634 m_xSFlyPara
->BoxUpWidth(nNewWidth
);
2636 Color
aBg(0xFE, 0xFF, 0xFF, 0xFF); //Transparent by default
2638 SwTextNode
* pNd
= aPref
.GetNode().GetTextNode();
2639 SwTextNode
* pJoinNext
= nullptr;
2640 if (pNd
&& m_xSFlyPara
->pFlyFormat
)
2644 Take the last paragraph background colour and fill the frame with
2645 it. Otherwise, make it transparent, this appears to be how MSWord
2648 const SfxPoolItem
&rItm
= pNd
->SwContentNode::GetAttr(RES_BACKGROUND
);
2649 const SvxBrushItem
&rBrush
= static_cast<const SvxBrushItem
&>(rItm
);
2650 if (rBrush
.GetColor() != COL_AUTO
)
2651 aBg
= rBrush
.GetColor();
2653 if (m_pLastAnchorPos
)
2655 //If the last anchor pos is here, then clear the anchor pos.
2656 //This "last anchor pos" is only used for fixing up the
2657 //positions of things anchored to page breaks and here
2658 //we are removing the last paragraph of a frame, so there
2659 //cannot be a page break at this point so we can
2660 //safely reset m_pLastAnchorPos to avoid any dangling
2661 //SwIndex's pointing into the deleted paragraph
2662 SwNodeIndex
aLastAnchorPos(m_pLastAnchorPos
->nNode
);
2663 SwNodeIndex
aToBeJoined(aPref
, 1);
2664 if (aLastAnchorPos
== aToBeJoined
)
2665 m_pLastAnchorPos
.reset();
2668 //Get rid of extra empty paragraph
2672 if (m_xSFlyPara
->pFlyFormat
)
2673 m_xSFlyPara
->pFlyFormat
->SetFormatAttr(SvxBrushItem(aBg
, RES_BACKGROUND
));
2675 DeleteAnchorStack();
2677 pJoinNext
->JoinNext();
2679 m_xAnchorStck
= std::move(m_xSFlyPara
->xOldAnchorStck
);
2681 // When inserting a graphic into the fly frame using the auto
2682 // function, the extension of the SW-fly has to be set
2683 // manually as the SW fly has no auto function to adjust the
2685 if (m_xSFlyPara
->nNewNetWidth
> MINFLY
&& m_xSFlyPara
->pFlyFormat
) // BoxUpWidth ?
2687 tools::Long nW
= m_xSFlyPara
->nNewNetWidth
;
2688 nW
+= m_xSFlyPara
->nWidth
- m_xSFlyPara
->nNetWidth
; // border for it
2689 m_xSFlyPara
->pFlyFormat
->SetFormatAttr(
2690 SwFormatFrameSize(m_xSFlyPara
->eHeightFix
, nW
, m_xSFlyPara
->nHeight
));
2693 Word set *no* width meaning it's an automatic width. The
2694 SwFlyPara reader will have already set a fallback width of the
2695 printable regions width, so we should reuse it. Despite the related
2696 problems with layout addressed with a hack in WW8FlyPara's constructor
2697 #i27204# Added AutoWidth setting. Left the old CalculateFlySize in place
2698 so that if the user unselects autowidth, the width doesn't max out
2700 else if (!m_xWFlyPara
->nSp28
&& m_xSFlyPara
->pFlyFormat
)
2702 using namespace sw::util
;
2703 SfxItemSet
aFlySet( m_xSFlyPara
->pFlyFormat
->GetAttrSet() );
2705 SwFormatFrameSize
aSize(ItemGet
<SwFormatFrameSize
>(aFlySet
, RES_FRM_SIZE
));
2707 aFlySet
.ClearItem(RES_FRM_SIZE
);
2709 CalculateFlySize(aFlySet
, m_xSFlyPara
->xMainTextPos
->nNode
,
2710 m_xSFlyPara
->nWidth
);
2712 nNewWidth
= ItemGet
<SwFormatFrameSize
>(aFlySet
, RES_FRM_SIZE
).GetWidth();
2714 aSize
.SetWidth(nNewWidth
);
2715 aSize
.SetWidthSizeType(SwFrameSize::Variable
);
2717 m_xSFlyPara
->pFlyFormat
->SetFormatAttr(aSize
);
2720 m_xSFlyPara
->xMainTextPos
.reset();
2721 // To create the SwFrames when inserting into an existing document, fltshell.cxx
2722 // will call pFlyFrame->MakeFrames() when setting the FltAnchor attribute
2727 if (m_xSFlyPara
&& m_xSFlyPara
->pFlyFormat
)
2728 m_xFormatOfJustInsertedApo
.reset(new FrameDeleteWatch(m_xSFlyPara
->pFlyFormat
));
2730 m_xSFlyPara
.reset();
2731 m_xWFlyPara
.reset();
2734 // TestSameApo() returns if it's the same Apo or a different one
2735 bool SwWW8ImplReader::TestSameApo(const ApoTestResults
&rApo
,
2736 const WW8_TablePos
*pTabPos
)
2740 OSL_ENSURE(m_xWFlyPara
, " Where is my pWFlyPara ? ");
2744 // We need to a full comparison (excepting borders) to identify all
2745 // combinations style/hard correctly. For this reason we create a
2746 // temporary WW8FlyPara (depending on if style or not), apply the
2747 // hard attributes and then compare.
2750 WW8FlyPara
aF(m_bVer67
, rApo
.mpStyleApo
);
2751 // WWPara for current para
2752 if (rApo
.HasFrame())
2753 aF
.Read(rApo
.m_nSprm29
, m_xPlcxMan
->GetPapPLCF());
2754 aF
.ApplyTabPos(pTabPos
);
2756 return aF
== *m_xWFlyPara
;
2759 void SwWW8ImplReader::NewAttr( const SfxPoolItem
& rAttr
,
2760 const bool bFirstLineOfStSet
,
2761 const bool bLeftIndentSet
)
2763 if( m_bNoAttrImport
) // for ignoring styles during doc inserts
2768 OSL_ENSURE(rAttr
.Which() != RES_FLTR_REDLINE
, "redline in style!");
2769 m_pCurrentColl
->SetFormatAttr(rAttr
);
2771 else if (m_xCurrentItemSet
)
2773 m_xCurrentItemSet
->Put(rAttr
);
2775 else if (rAttr
.Which() == RES_FLTR_REDLINE
)
2777 m_xRedlineStack
->open(*m_pPaM
->GetPoint(), rAttr
);
2781 m_xCtrlStck
->NewAttr(*m_pPaM
->GetPoint(), rAttr
);
2783 if ( bFirstLineOfStSet
)
2785 const SwNode
* pNd
= &(m_pPaM
->GetPoint()->nNode
.GetNode());
2786 m_aTextNodesHavingFirstLineOfstSet
.insert( pNd
);
2789 if ( bLeftIndentSet
)
2791 const SwNode
* pNd
= &(m_pPaM
->GetPoint()->nNode
.GetNode());
2792 m_aTextNodesHavingLeftIndentSet
.insert( pNd
);
2796 if (m_pPostProcessAttrsInfo
&& m_pPostProcessAttrsInfo
->mbCopy
)
2797 m_pPostProcessAttrsInfo
->mItemSet
.Put(rAttr
);
2800 // fetches attribute from FormatColl / Stack / Doc
2801 const SfxPoolItem
* SwWW8ImplReader::GetFormatAttr( sal_uInt16 nWhich
)
2803 const SfxPoolItem
* pRet
= nullptr;
2805 pRet
= &(m_pCurrentColl
->GetFormatAttr(nWhich
));
2806 else if (m_xCurrentItemSet
)
2808 pRet
= m_xCurrentItemSet
->GetItem(nWhich
);
2810 pRet
= m_pStandardFormatColl
? &(m_pStandardFormatColl
->GetFormatAttr(nWhich
)) : nullptr;
2812 pRet
= &m_rDoc
.GetAttrPool().GetDefaultItem(nWhich
);
2814 else if (m_xPlcxMan
&& m_xPlcxMan
->GetDoingDrawTextBox())
2816 pRet
= m_xCtrlStck
->GetStackAttr(*m_pPaM
->GetPoint(), nWhich
);
2819 if (m_nCurrentColl
< m_vColl
.size() && m_vColl
[m_nCurrentColl
].m_pFormat
&&
2820 m_vColl
[m_nCurrentColl
].m_bColl
)
2822 pRet
= &(m_vColl
[m_nCurrentColl
].m_pFormat
->GetFormatAttr(nWhich
));
2826 pRet
= m_pStandardFormatColl
? &(m_pStandardFormatColl
->GetFormatAttr(nWhich
)) : nullptr;
2828 pRet
= &m_rDoc
.GetAttrPool().GetDefaultItem(nWhich
);
2831 pRet
= m_xCtrlStck
->GetFormatAttr(*m_pPaM
->GetPoint(), nWhich
);
2835 // The methods get as parameters the token id and the length of the following
2836 // parameters according to the table in WWScan.cxx.
2837 void SwWW8ImplReader::Read_Special(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
2844 m_bSpec
= ( *pData
!= 0 );
2847 // Read_Obj is used for fObj and for fOle2 !
2848 void SwWW8ImplReader::Read_Obj(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
2854 m_bObj
= 0 != *pData
;
2856 if( m_bObj
&& m_nPicLocFc
&& m_bEmbeddObj
)
2858 if (!m_aFieldStack
.empty() && m_aFieldStack
.back().mnFieldId
== 56)
2860 // For LINK fields, store the nObjLocFc value in the field entry
2861 m_aFieldStack
.back().mnObjLocFc
= m_nPicLocFc
;
2865 m_nObjLocFc
= m_nPicLocFc
;
2871 void SwWW8ImplReader::Read_PicLoc(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
2876 m_bSpec
= false; // Is this always correct?
2880 m_nPicLocFc
= SVBT32ToUInt32( pData
);
2883 if( m_bObj
&& m_nPicLocFc
&& m_bEmbeddObj
)
2884 m_nObjLocFc
= m_nPicLocFc
;
2888 void SwWW8ImplReader::Read_POutLvl(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
2892 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_PARATR_OUTLINELEVEL
);
2896 if (m_pCurrentColl
!= nullptr)
2898 SwWW8StyInf
* pSI
= GetStyle(m_nCurrentColl
);
2899 if (pSI
&& pSI
->m_bColl
&& pSI
->m_pFormat
)
2901 pSI
->mnWW8OutlineLevel
=
2902 static_cast< sal_uInt8
>( ( (pData
&& nLen
>= 1) ? *pData
: 0 ) );
2903 auto nLevel
= SwWW8StyInf::WW8OutlineLevelToOutlinelevel(pSI
->mnWW8OutlineLevel
);
2906 SwTextFormatColl
* pTextFormatColl
= static_cast<SwTextFormatColl
*>(pSI
->m_pFormat
);
2907 pTextFormatColl
->DeleteAssignmentToListLevelOfOutlineStyle();
2909 NewAttr(SfxUInt16Item(RES_PARATR_OUTLINELEVEL
, nLevel
));
2912 else if (m_pPaM
!= nullptr)
2914 const sal_uInt8 nOutlineLevel
2915 = SwWW8StyInf::WW8OutlineLevelToOutlinelevel(
2916 static_cast<sal_uInt8
>(((pData
&& nLen
>= 1) ? *pData
: 0)));
2917 NewAttr(SfxUInt16Item(RES_PARATR_OUTLINELEVEL
, nOutlineLevel
));
2921 void SwWW8ImplReader::Read_Symbol(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
2926 if (nLen
< (m_bVer67
? 3 : 4))
2928 //otherwise disable after we print the char
2929 if (m_xPlcxMan
&& m_xPlcxMan
->GetDoingDrawTextBox())
2930 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_FONT
);
2935 // Make new Font-Attribute
2936 // (will be closed in SwWW8ImplReader::ReadChars() )
2938 //Will not be added to the charencoding stack, for styles the real
2939 //font setting will be put in as the styles charset, and for plain
2940 //text encoding for symbols is moot. Drawing boxes will check bSymbol
2941 //themselves so they don't need to add it to the stack either.
2942 if (SetNewFontAttr(SVBT16ToUInt16( pData
), false, RES_CHRATR_FONT
))
2944 SetNewFontAttr(SVBT16ToUInt16( pData
), false, RES_CHRATR_CJK_FONT
);
2945 SetNewFontAttr(SVBT16ToUInt16( pData
), false, RES_CHRATR_CTL_FONT
);
2948 //convert single byte from MS1252 to Unicode
2949 m_cSymbol
= OUString(
2950 reinterpret_cast<const char*>(pData
+2), 1,
2951 RTL_TEXTENCODING_MS_1252
).toChar();
2955 //already is Unicode
2956 m_cSymbol
= SVBT16ToUInt16( pData
+2 );
2963 SwWW8StyInf
*SwWW8ImplReader::GetStyle(sal_uInt16 nColl
) const
2965 return const_cast<SwWW8StyInf
*>(nColl
< m_vColl
.size() ? &m_vColl
[nColl
] : nullptr);
2968 // Read_BoldUsw for italic, bold, small caps, majuscule, struck out,
2969 // contour and shadow
2970 void SwWW8ImplReader::Read_BoldUsw( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
2972 const int nContiguousWestern
= 8;
2973 const int nWestern
= nContiguousWestern
+ 1;
2974 const int nEastern
= 2;
2976 const int nIds
= nWestern
+ nEastern
+ nCTL
;
2977 static const sal_uInt16 nEndIds
[ nIds
] =
2979 RES_CHRATR_WEIGHT
, RES_CHRATR_POSTURE
,
2980 RES_CHRATR_CROSSEDOUT
, RES_CHRATR_CONTOUR
,
2981 RES_CHRATR_SHADOWED
, RES_CHRATR_CASEMAP
,
2982 RES_CHRATR_CASEMAP
, RES_CHRATR_HIDDEN
,
2984 RES_CHRATR_CROSSEDOUT
,
2986 RES_CHRATR_CJK_WEIGHT
, RES_CHRATR_CJK_POSTURE
,
2988 RES_CHRATR_CTL_WEIGHT
, RES_CHRATR_CTL_POSTURE
2991 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
2994 // the attribute number for "double strike-through" breaks rank
2995 if (NS_sprm::CFDStrike::val
== nId
)
2996 nI
= nContiguousWestern
; // The out of sequence western id
2999 // The contiguous western ids
3000 if (eVersion
<= ww::eWW2
)
3001 nI
= static_cast< sal_uInt8
>(nId
- 60);
3002 else if (eVersion
< ww::eWW8
)
3003 nI
= static_cast< sal_uInt8
>(nId
- NS_sprm::v6::sprmCFBold
);
3005 nI
= static_cast< sal_uInt8
>(nId
- NS_sprm::CFBold::val
);
3008 sal_uInt16 nMask
= 1 << nI
;
3014 if (eVersion
<= ww::eWW6
)
3016 // reset the CTL Weight and Posture, because they are the same as their
3017 // western equivalents in ww6
3018 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nEndIds
[ nWestern
+ nEastern
+ nI
] );
3020 // reset the CJK Weight and Posture, because they are the same as their
3021 // western equivalents in word
3022 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nEndIds
[ nWestern
+ nI
] );
3024 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nEndIds
[ nI
] );
3025 m_xCtrlStck
->SetToggleAttr(nI
, false);
3028 // value: 0 = off, 1 = on, 128 = like style, 129 contrary to style
3029 bool bOn
= *pData
& 1;
3030 SwWW8StyInf
* pSI
= GetStyle(m_nCurrentColl
);
3031 if (m_xPlcxMan
&& eVersion
> ww::eWW2
)
3033 SprmResult aCharIstd
=
3034 m_xPlcxMan
->GetChpPLCF()->HasSprm(m_bVer67
? NS_sprm::v6::sprmCIstd
: NS_sprm::CIstd::val
);
3035 if (aCharIstd
.pSprm
&& aCharIstd
.nRemainingData
>= 2)
3036 pSI
= GetStyle(SVBT16ToUInt16(aCharIstd
.pSprm
));
3039 if( m_pCurrentColl
) // StyleDef -> remember flags
3043 // The style based on has Bit 7 set ?
3045 pSI
->m_nBase
< m_vColl
.size() && (*pData
& 0x80) &&
3046 (m_vColl
[pSI
->m_nBase
].m_n81Flags
& nMask
)
3049 bOn
= !bOn
; // invert
3053 pSI
->m_n81Flags
|= nMask
; // set flag
3055 pSI
->m_n81Flags
&= ~nMask
; // delete flag
3061 // in text -> look at flags
3062 if( *pData
& 0x80 ) // bit 7 set?
3064 if (pSI
&& pSI
->m_n81Flags
& nMask
) // and in StyleDef at ?
3065 bOn
= !bOn
; // then invert
3066 // remember on stack that this is a toggle-attribute
3067 m_xCtrlStck
->SetToggleAttr(nI
, true);
3071 SetToggleAttr( nI
, bOn
);
3074 void SwWW8ImplReader::Read_Bidi(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3076 if (nLen
< 1) //Property end
3079 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(),RES_CHRATR_BIDIRTL
);
3081 else //Property start
3084 sal_uInt8 nBidi
= *pData
;
3085 NewAttr( SfxInt16Item( RES_CHRATR_BIDIRTL
, (nBidi
!=0)? 1 : 0 ) );
3090 tdf#91916, #i8726, #i42685# there is an ambiguity
3091 around certain properties as to what they mean,
3092 which appears to be a problem with different versions
3093 of the file format where properties conflict, i.e.
3095 ooo40606-2.doc, magic is a699
3096 : 0x6f 0x4 0x0 0x71 0x4 0x0
3097 ooo40635-1.doc, magic is a699
3098 : 0x6f 0x4 0x0 0x71 0x4 0x0
3099 ooo31093/SIMPCHIN.doc, magic is a699
3100 : 0x6f 0x2 0x0 0x70 0x0 0x0 0x71 0x2 0x0
3101 : 0x6f 0x5 0x0 0x70 0x5 0x0
3102 ooo31093/TRADCHIN.doc, magic is a699
3103 : 0x6f 0x1 0x0 0x70 0x0 0x0 0x71 0x1 0x0
3104 ooo31093/JAPANESE.doc, magic is a697
3105 : 0x6f 0x2 0x0 0x70 0x0 0x0 0x71 0x2 0x0
3106 ooo31093/KOREAN.doc, magic is a698
3107 : 0x6f 0x2 0x0 0x70 0x0 0x0 0x71 0x2 0x0
3108 ooo31093-1.doc, magic is a698
3109 : 0x6f 0x5 0x0 0x70 0x5 0x0
3110 ooo31093-1.doc, magic is a698
3111 : 0x6f 0x5 0x0 0x70 0x5 0x0
3115 ooo27954-1.doc, magic is a5dc
3116 : 0x6f 0x1 0x81 0x71 0x2 0x4 0x0 0x74 0x2 0x20 0x0
3118 ooo33251-1.doc, magic is a5dc
3119 : 0x6f 0x1 0x81 0x71 0x2 0x3 0x0 0x74 0x2 0x1c 0x0
3123 So we have the same sprm values, but different payloads, where
3124 the a5dc versions appear to use a len argument, followed by len
3125 bytes, while the a698<->a699 versions use a 2byte argument
3127 commit c2213db9ed70c1fd546482d22e36e4029c10aa45
3129 INTEGRATION: CWS tl28 (1.169.24); FILE MERGED
3130 2006/10/25 13:40:41 tl 1.169.24.2: RESYNC: (1.169-1.170); FILE MERGED
3131 2006/09/20 11:55:50 hbrinkm 1.169.24.1: #i42685# applied patch
3133 changed 0x6f and 0x70 from Read_BoldBiDiUsw to Read_FontCode for all versions.
3135 In the Word for Window 2 spec we have...
3143 as see in GetWW2SprmDispatcher, different numbers, but the sequence starts with
3144 the same sprmCMajority as appears before 0x6f in word 6/95
3146 I think the easiest explanation is that the CJK Word for Window 95, or whatever
3147 the product was went rogue, and did their own things with at least first three
3148 slots after sprmCMajority to do a different thing. I have no reason to think Tono
3149 was wrong with what they do in the a698<->a699 versions, but with magic
3150 a5dc they probably did mean sprmCFBoldBi, sprmCFItalicBi cause they have that 0x81
3151 pattern which has significance for those types of properties.
3153 void SwWW8ImplReader::Read_AmbiguousSPRM(sal_uInt16 nId
, const sal_uInt8
* pData
,
3156 if (m_xWwFib
->m_wIdent
>= 0xa697 && m_xWwFib
->m_wIdent
<= 0xa699)
3158 Read_FontCode(nId
, pData
, nLen
);
3162 Read_BoldBiDiUsw(nId
, pData
, nLen
);
3166 // Read_BoldUsw for BiDi Italic, Bold
3167 void SwWW8ImplReader::Read_BoldBiDiUsw(sal_uInt16 nId
, const sal_uInt8
* pData
,
3170 static const sal_uInt16 nEndIds
[2] =
3172 RES_CHRATR_CTL_WEIGHT
, RES_CHRATR_CTL_POSTURE
,
3176 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
3177 if (eVersion
<= ww::eWW2
)
3178 nI
= static_cast< sal_uInt8
>(nId
- 80);
3179 else if (eVersion
< ww::eWW8
)
3180 nI
= static_cast< sal_uInt8
>(nId
- 111);
3182 nI
= static_cast< sal_uInt8
>(nId
- NS_sprm::CFBoldBi::val
);
3184 OSL_ENSURE(nI
<= 1, "not happening");
3188 sal_uInt16 nMask
= 1 << nI
;
3192 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(),nEndIds
[nI
]);
3193 m_xCtrlStck
->SetToggleBiDiAttr(nI
, false);
3196 bool bOn
= *pData
& 1;
3197 SwWW8StyInf
* pSI
= GetStyle(m_nCurrentColl
);
3200 SprmResult aCharIstd
=
3201 m_xPlcxMan
->GetChpPLCF()->HasSprm(m_bVer67
? NS_sprm::v6::sprmCIstd
: NS_sprm::CIstd::val
);
3202 if (aCharIstd
.pSprm
&& aCharIstd
.nRemainingData
>= 2)
3203 pSI
= GetStyle(SVBT16ToUInt16(aCharIstd
.pSprm
));
3206 if (m_pCurrentColl
&& eVersion
> ww::eWW2
) // StyleDef -> remember flags
3210 if( pSI
->m_nBase
< m_vColl
.size() // Style Based on
3211 && ( *pData
& 0x80 ) // bit 7 set?
3212 && ( m_vColl
[pSI
->m_nBase
].m_n81BiDiFlags
& nMask
) ) // base mask?
3213 bOn
= !bOn
; // invert
3216 pSI
->m_n81BiDiFlags
|= nMask
; // set flag
3218 pSI
->m_n81BiDiFlags
&= ~nMask
; // delete flag
3224 // in text -> look at flags
3225 if (*pData
& 0x80) // Bit 7 set?
3227 if (pSI
&& pSI
->m_n81BiDiFlags
& nMask
) // and in StyleDef at ?
3228 bOn
= !bOn
; // then invert
3229 // remember on stack that this is a toggle-attribute
3230 m_xCtrlStck
->SetToggleBiDiAttr(nI
, true);
3234 SetToggleBiDiAttr(nI
, bOn
);
3237 void SwWW8ImplReader::SetToggleBiDiAttr(sal_uInt8 nAttrId
, bool bOn
)
3243 SvxWeightItem
aAttr( bOn
? WEIGHT_BOLD
: WEIGHT_NORMAL
, RES_CHRATR_WEIGHT
);
3244 aAttr
.SetWhich( RES_CHRATR_CTL_WEIGHT
);
3250 SvxPostureItem
aAttr( bOn
? ITALIC_NORMAL
: ITALIC_NONE
, RES_CHRATR_POSTURE
);
3251 aAttr
.SetWhich( RES_CHRATR_CTL_POSTURE
);
3256 OSL_ENSURE(false, "Unhandled unknown bidi toggle attribute");
3262 void SwWW8ImplReader::SetToggleAttr(sal_uInt8 nAttrId
, bool bOn
)
3264 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
3270 SvxWeightItem
aAttr( bOn
? WEIGHT_BOLD
: WEIGHT_NORMAL
, RES_CHRATR_WEIGHT
);
3272 aAttr
.SetWhich( RES_CHRATR_CJK_WEIGHT
);
3274 if (eVersion
<= ww::eWW6
)
3276 aAttr
.SetWhich( RES_CHRATR_CTL_WEIGHT
);
3283 SvxPostureItem
aAttr( bOn
? ITALIC_NORMAL
: ITALIC_NONE
, RES_CHRATR_POSTURE
);
3285 aAttr
.SetWhich( RES_CHRATR_CJK_POSTURE
);
3287 if (eVersion
<= ww::eWW6
)
3289 aAttr
.SetWhich( RES_CHRATR_CTL_POSTURE
);
3295 NewAttr(SvxCrossedOutItem(bOn
? STRIKEOUT_SINGLE
: STRIKEOUT_NONE
, RES_CHRATR_CROSSEDOUT
));
3298 NewAttr( SvxContourItem( bOn
, RES_CHRATR_CONTOUR
) );
3301 NewAttr( SvxShadowedItem( bOn
, RES_CHRATR_SHADOWED
) );
3304 NewAttr( SvxCaseMapItem( bOn
? SvxCaseMap::SmallCaps
3305 : SvxCaseMap::NotMapped
, RES_CHRATR_CASEMAP
) );
3308 NewAttr( SvxCaseMapItem( bOn
? SvxCaseMap::Uppercase
3309 : SvxCaseMap::NotMapped
, RES_CHRATR_CASEMAP
) );
3312 NewAttr(SvxCharHiddenItem(bOn
, RES_CHRATR_HIDDEN
));
3315 NewAttr( SvxCrossedOutItem( bOn
? STRIKEOUT_DOUBLE
3316 : STRIKEOUT_NONE
, RES_CHRATR_CROSSEDOUT
) );
3319 OSL_ENSURE(false, "Unhandled unknown toggle attribute");
3324 void SwWW8ImplReader::ChkToggleAttr_( sal_uInt16 nOldStyle81Mask
,
3325 sal_uInt16 nNewStyle81Mask
)
3327 sal_uInt16 i
= 1, nToggleAttrFlags
= m_xCtrlStck
->GetToggleAttrFlags();
3328 for (sal_uInt8 n
= 0; n
< 7; ++n
, i
<<= 1)
3331 (i
& nToggleAttrFlags
) &&
3332 ((i
& nOldStyle81Mask
) != (i
& nNewStyle81Mask
))
3335 SetToggleAttr(n
, (i
& nOldStyle81Mask
));
3340 void SwWW8ImplReader::ChkToggleBiDiAttr_( sal_uInt16 nOldStyle81Mask
,
3341 sal_uInt16 nNewStyle81Mask
)
3343 sal_uInt16 i
= 1, nToggleAttrFlags
= m_xCtrlStck
->GetToggleBiDiAttrFlags();
3344 for (sal_uInt8 n
= 0; n
< 7; ++n
, i
<<= 1)
3347 (i
& nToggleAttrFlags
) &&
3348 ((i
& nOldStyle81Mask
) != (i
& nNewStyle81Mask
))
3351 SetToggleBiDiAttr(n
, (i
& nOldStyle81Mask
));
3356 void SwWW8ImplReader::Read_SubSuper( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3360 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_ESCAPEMENT
);
3369 nEs
= DFLT_ESC_AUTO_SUPER
;
3370 nProp
= DFLT_ESC_PROP
;
3373 nEs
= DFLT_ESC_AUTO_SUB
;
3374 nProp
= DFLT_ESC_PROP
;
3381 NewAttr( SvxEscapementItem( nEs
, nProp
, RES_CHRATR_ESCAPEMENT
) );
3384 SwFrameFormat
*SwWW8ImplReader::ContainsSingleInlineGraphic(const SwPaM
&rRegion
)
3387 For inline graphics and objects word has a hacked in feature to use
3388 subscripting to force the graphic into a centered position on the line, so
3389 we must check when applying sub/super to see if it the subscript range
3390 contains only a single graphic, and if that graphic is anchored as
3391 RndStdIds::FLY_AS_CHAR and then we can change its anchoring to centered in the line.
3393 SwFrameFormat
*pRet
=nullptr;
3394 SwNodeIndex
aBegin(rRegion
.Start()->nNode
);
3395 const sal_Int32
nBegin(rRegion
.Start()->nContent
.GetIndex());
3396 SwNodeIndex
aEnd(rRegion
.End()->nNode
);
3397 const sal_Int32
nEnd(rRegion
.End()->nContent
.GetIndex());
3398 const SwTextNode
* pTNd
;
3399 const SwTextAttr
* pTFlyAttr
;
3401 aBegin
== aEnd
&& nBegin
== nEnd
- 1 &&
3402 nullptr != (pTNd
= aBegin
.GetNode().GetTextNode()) &&
3403 nullptr != (pTFlyAttr
= pTNd
->GetTextAttrForCharAt(nBegin
, RES_TXTATR_FLYCNT
))
3406 const SwFormatFlyCnt
& rFly
= pTFlyAttr
->GetFlyCnt();
3407 SwFrameFormat
*pFlyFormat
= rFly
.GetFrameFormat();
3409 (RndStdIds::FLY_AS_CHAR
== pFlyFormat
->GetAnchor().GetAnchorId()))
3417 bool SwWW8ImplReader::ConvertSubToGraphicPlacement()
3420 For inline graphics and objects word has a hacked in feature to use
3421 subscripting to force the graphic into a centered position on the line, so
3422 we must check when applying sub/super to see if it the subscript range
3423 contains only a single graphic, and if that graphic is anchored as
3424 RndStdIds::FLY_AS_CHAR and then we can change its anchoring to centered in the line.
3426 bool bIsGraphicPlacementHack
= false;
3428 if (m_xCtrlStck
->GetFormatStackAttr(RES_CHRATR_ESCAPEMENT
, &nPos
))
3430 SwPaM
aRegion(*m_pPaM
->GetPoint());
3432 SwFltPosition
aMkPos((*m_xCtrlStck
)[nPos
].m_aMkPos
);
3433 SwFltPosition
aPtPos(*m_pPaM
->GetPoint());
3435 SwFrameFormat
*pFlyFormat
= nullptr;
3436 if (SwFltStackEntry::MakeRegion(m_rDoc
, aRegion
, SwFltStackEntry::RegionMode::NoCheck
, aMkPos
, aPtPos
)
3437 && nullptr != (pFlyFormat
= ContainsSingleInlineGraphic(aRegion
)))
3439 m_xCtrlStck
->DeleteAndDestroy(nPos
);
3440 pFlyFormat
->SetFormatAttr(SwFormatVertOrient(0, text::VertOrientation::CHAR_CENTER
, text::RelOrientation::CHAR
));
3441 bIsGraphicPlacementHack
= true;
3444 return bIsGraphicPlacementHack
;
3447 void SwWW8ImplReader::Read_SubSuperProp( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3449 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
3451 if (nLen
< (eVersion
<= ww::eWW2
? 1 : 2))
3453 if (!ConvertSubToGraphicPlacement())
3454 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_ESCAPEMENT
);
3458 // if the fontsize for these characters is specified, make sure it is updated first
3461 const sal_uInt16 nFontsizeID
= m_bVer67
? NS_sprm::v6::sprmCHps
: NS_sprm::CHps::val
;
3462 const SprmResult aFontsize
= m_xPlcxMan
->GetChpPLCF()->HasSprm( nFontsizeID
, /*bFindFirst=*/false );
3463 if ( aFontsize
.pSprm
&& aFontsize
.nRemainingData
)
3464 Read_FontSize(nFontsizeID
, aFontsize
.pSprm
, aFontsize
.nRemainingData
);
3467 // font position in HalfPoints
3468 short nPos
= eVersion
<= ww::eWW2
? static_cast< sal_Int8
>( *pData
) : SVBT16ToInt16( pData
);
3469 sal_Int32 nPos2
= nPos
* ( 10 * 100 ); // HalfPoints in 100 * tw
3470 const SvxFontHeightItem
* pF
3471 = static_cast<const SvxFontHeightItem
*>(GetFormatAttr(RES_CHRATR_FONTSIZE
));
3472 OSL_ENSURE(pF
, "Expected to have the fontheight available here");
3474 // #i59022: Check ensure nHeight != 0. Div by zero otherwise.
3475 sal_Int32 nHeight
= 240;
3476 if (pF
!= nullptr && pF
->GetHeight() != 0)
3477 nHeight
= pF
->GetHeight();
3478 nPos2
/= nHeight
; // ... now in % (rounded)
3479 if( nPos2
> MAX_ESC_POS
)
3480 nPos2
= MAX_ESC_POS
;
3481 if( nPos2
< -MAX_ESC_POS
)
3482 nPos2
= -MAX_ESC_POS
;
3483 SvxEscapementItem
aEs( static_cast<short>(nPos2
), 100, RES_CHRATR_ESCAPEMENT
);
3487 void SwWW8ImplReader::Read_Underline( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3489 FontLineStyle eUnderline
= LINESTYLE_NONE
;
3490 bool bWordLine
= false;
3493 // Parameter: 0 = none, 1 = single, 2 = by Word,
3494 // 3 = double, 4 = dotted, 5 = hidden
3495 // 6 = thick, 7 = dash, 8 = dot(not used)
3496 // 9 = dotdash 10 = dotdotdash 11 = wave
3499 case 2: bWordLine
= true;
3501 case 1: eUnderline
= LINESTYLE_SINGLE
; break;
3502 case 3: eUnderline
= LINESTYLE_DOUBLE
; break;
3503 case 4: eUnderline
= LINESTYLE_DOTTED
; break;
3504 case 7: eUnderline
= LINESTYLE_DASH
; break;
3505 case 9: eUnderline
= LINESTYLE_DASHDOT
; break;
3506 case 10:eUnderline
= LINESTYLE_DASHDOTDOT
; break;
3507 case 6: eUnderline
= LINESTYLE_BOLD
; break;
3508 case 11:eUnderline
= LINESTYLE_WAVE
; break;
3509 case 20:eUnderline
= LINESTYLE_BOLDDOTTED
; break;
3510 case 23:eUnderline
= LINESTYLE_BOLDDASH
; break;
3511 case 39:eUnderline
= LINESTYLE_LONGDASH
; break;
3512 case 55:eUnderline
= LINESTYLE_BOLDLONGDASH
; break;
3513 case 25:eUnderline
= LINESTYLE_BOLDDASHDOT
; break;
3514 case 26:eUnderline
= LINESTYLE_BOLDDASHDOTDOT
;break;
3515 case 27:eUnderline
= LINESTYLE_BOLDWAVE
; break;
3516 case 43:eUnderline
= LINESTYLE_DOUBLEWAVE
; break;
3520 // if necessary, mix up stack and exit!
3523 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_UNDERLINE
);
3524 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_WORDLINEMODE
);
3528 NewAttr( SvxUnderlineItem( eUnderline
, RES_CHRATR_UNDERLINE
));
3530 NewAttr(SvxWordLineModeItem(true, RES_CHRATR_WORDLINEMODE
));
3535 //The last three vary, measurements, rotation ? ?
3536 NoBracket 78 CA 06 - 02 00 00 02 34 52
3537 () 78 CA 06 - 02 01 00 02 34 52
3538 [] 78 CA 06 - 02 02 00 02 34 52
3539 <> 78 CA 06 - 02 03 00 02 34 52
3540 {} 78 CA 06 - 02 04 00 02 34 52
3542 void SwWW8ImplReader::Read_DoubleLine_Rotate( sal_uInt16
, const sal_uInt8
* pData
,
3545 if (nLen
< 0) // close the tag
3547 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_TWO_LINES
);
3548 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_ROTATE
);
3550 else if( pData
&& 6 == nLen
)
3554 case 2: // double line
3556 sal_Unicode cStt
= 0, cEnd
= 0;
3557 switch( SVBT16ToUInt16( pData
+1 ) )
3559 case 1: cStt
= '('; cEnd
= ')'; break;
3560 case 2: cStt
= '['; cEnd
= ']'; break;
3561 case 3: cStt
= '<'; cEnd
= '>'; break;
3562 case 4: cStt
= '{'; cEnd
= '}'; break;
3564 NewAttr( SvxTwoLinesItem( true, cStt
, cEnd
, RES_CHRATR_TWO_LINES
));
3568 case 1: // rotated characters
3570 bool bFitToLine
= 0 != *(pData
+1);
3571 NewAttr( SvxCharRotateItem( Degree10(900), bFitToLine
, RES_CHRATR_ROTATE
));
3578 void SwWW8ImplReader::Read_TextColor( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3580 //Has newer colour variant, ignore this old variant
3581 if (!m_bVer67
&& m_xPlcxMan
&& m_xPlcxMan
->GetChpPLCF()->HasSprm(NS_sprm::CCv::val
).pSprm
)
3585 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_COLOR
);
3588 sal_uInt8 b
= *pData
; // parameter: 0 = Auto, 1..16 colors
3590 if( b
> 16 ) // unknown -> Black
3593 NewAttr( SvxColorItem(GetCol(b
), RES_CHRATR_COLOR
));
3594 if (m_pCurrentColl
&& m_xStyles
)
3595 m_xStyles
->mbTextColChanged
= true;
3599 void SwWW8ImplReader::Read_TextForeColor(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3602 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_COLOR
);
3605 Color
aColor(msfilter::util::BGRToRGB(SVBT32ToUInt32(pData
)));
3607 // At least when transparency is 0xff and the color is black, Word renders that as black.
3608 if (aColor
.GetTransparency() && aColor
!= COL_AUTO
)
3610 aColor
.SetTransparency(0);
3613 NewAttr(SvxColorItem(aColor
, RES_CHRATR_COLOR
));
3614 if (m_pCurrentColl
&& m_xStyles
)
3615 m_xStyles
->mbTextColChanged
= true;
3619 void SwWW8ImplReader::Read_UnderlineColor(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3623 //because the UnderlineColor is not a standalone attribute in SW, it belongs to the underline attribute.
3624 //And, the .doc file stores attributes separately, this attribute ends here, the "underline"
3625 //attribute also terminates (if the character next owns underline, that will be a new underline attribute).
3626 //so nothing is left to be done here.
3631 if ( m_pCurrentColl
) //importing style
3633 if( SfxItemState::SET
== m_pCurrentColl
->GetItemState( RES_CHRATR_UNDERLINE
, false ) )
3637 const SwAttrSet
& aSet
= m_pCurrentColl
->GetAttrSet();
3638 std::unique_ptr
<SvxUnderlineItem
> pUnderline(aSet
.Get(RES_CHRATR_UNDERLINE
, false).Clone());
3639 pUnderline
->SetColor( msfilter::util::BGRToRGB(SVBT32ToUInt32(pData
)) );
3640 m_pCurrentColl
->SetFormatAttr( *pUnderline
);
3644 else if (m_xCurrentItemSet
)
3646 if ( SfxItemState::SET
== m_xCurrentItemSet
->GetItemState( RES_CHRATR_UNDERLINE
, false ) )
3650 std::unique_ptr
<SvxUnderlineItem
> pUnderline(m_xCurrentItemSet
->Get(RES_CHRATR_UNDERLINE
, false).Clone());
3651 pUnderline
->SetColor( msfilter::util::BGRToRGB(SVBT32ToUInt32(pData
)) );
3652 m_xCurrentItemSet
->Put( std::move(pUnderline
) );
3658 SvxUnderlineItem
* pUnderlineAttr
= const_cast<SvxUnderlineItem
*>(static_cast<const SvxUnderlineItem
*>(m_xCtrlStck
->GetOpenStackAttr( *m_pPaM
->GetPoint(), RES_CHRATR_UNDERLINE
)));
3659 if (pUnderlineAttr
&& nLen
>= 4)
3660 pUnderlineAttr
->SetColor( msfilter::util::BGRToRGB(SVBT32ToUInt32( pData
) ));
3664 bool SwWW8ImplReader::GetFontParams( sal_uInt16 nFCode
, FontFamily
& reFamily
,
3665 OUString
& rName
, FontPitch
& rePitch
, rtl_TextEncoding
& reCharSet
)
3667 // the definitions that are the base for these tables are in windows.h
3668 static const FontPitch ePitchA
[] =
3670 PITCH_DONTKNOW
, PITCH_FIXED
, PITCH_VARIABLE
, PITCH_DONTKNOW
3673 static const FontFamily eFamilyA
[] =
3675 FAMILY_DONTKNOW
, FAMILY_ROMAN
, FAMILY_SWISS
, FAMILY_MODERN
,
3676 FAMILY_SCRIPT
, FAMILY_DECORATIVE
, FAMILY_DONTKNOW
, FAMILY_DONTKNOW
3679 const WW8_FFN
* pF
= m_xFonts
->GetFont( nFCode
); // Info for it
3680 if( !pF
) // font number unknown ?
3681 return false; // then ignore
3683 rName
= pF
->sFontname
;
3686 rePitch
= ePitchA
[pF
->aFFNBase
.prg
];
3689 if( 77 == pF
->aFFNBase
.chs
) // Mac font in Mac Charset or
3690 reCharSet
= m_eTextCharSet
; // translated to ANSI charset
3693 // #i52786#, for word 67 we'll assume that ANSI is basically invalid,
3694 // might be true for (above) mac as well, but would need a mac example
3695 // that exercises this to be sure
3696 if (m_bVer67
&& pF
->aFFNBase
.chs
== 0)
3697 reCharSet
= RTL_TEXTENCODING_DONTKNOW
;
3699 reCharSet
= rtl_getTextEncodingFromWindowsCharset(pF
->aFFNBase
.chs
);
3702 // make sure Font Family Code is set correctly
3703 // at least for the most important fonts
3704 // ( might be set wrong when Doc was not created by
3705 // Winword but by third party program like Applixware... )
3706 if (rName
.startsWithIgnoreAsciiCase("Tms Rmn") ||
3707 rName
.startsWithIgnoreAsciiCase("Timmons") ||
3708 rName
.startsWithIgnoreAsciiCase("CG Times") ||
3709 rName
.startsWithIgnoreAsciiCase("MS Serif") ||
3710 rName
.startsWithIgnoreAsciiCase("Garamond") ||
3711 rName
.startsWithIgnoreAsciiCase("Times Roman") ||
3712 rName
.startsWithIgnoreAsciiCase("Times New Roman"))
3714 reFamily
= FAMILY_ROMAN
;
3716 else if (rName
.startsWithIgnoreAsciiCase("Helv") ||
3717 rName
.startsWithIgnoreAsciiCase("Arial") ||
3718 rName
.startsWithIgnoreAsciiCase("Univers") ||
3719 rName
.startsWithIgnoreAsciiCase("LinePrinter") ||
3720 rName
.startsWithIgnoreAsciiCase("Lucida Sans") ||
3721 rName
.startsWithIgnoreAsciiCase("Small Fonts") ||
3722 rName
.startsWithIgnoreAsciiCase("MS Sans Serif"))
3724 reFamily
= FAMILY_SWISS
;
3728 reFamily
= eFamilyA
[pF
->aFFNBase
.ff
];
3734 bool SwWW8ImplReader::SetNewFontAttr(sal_uInt16 nFCode
, bool bSetEnums
,
3740 rtl_TextEncoding eSrcCharSet
;
3742 if( !GetFontParams( nFCode
, eFamily
, aName
, ePitch
, eSrcCharSet
) )
3744 //If we fail (and are not doing a style) then put something into the
3745 //character encodings stack anyway so that the property end that pops
3746 //off the stack will keep in sync
3747 if (!m_pCurrentColl
&& IsListOrDropcap())
3749 if (nWhich
== RES_CHRATR_CJK_FONT
)
3751 if (!m_aFontSrcCJKCharSets
.empty())
3753 eSrcCharSet
= m_aFontSrcCJKCharSets
.top();
3757 eSrcCharSet
= RTL_TEXTENCODING_DONTKNOW
;
3760 m_aFontSrcCJKCharSets
.push(eSrcCharSet
);
3764 if (!m_aFontSrcCharSets
.empty())
3766 eSrcCharSet
= m_aFontSrcCharSets
.top();
3770 eSrcCharSet
= RTL_TEXTENCODING_DONTKNOW
;
3773 m_aFontSrcCharSets
.push(eSrcCharSet
);
3779 rtl_TextEncoding eDstCharSet
= eSrcCharSet
;
3781 SvxFontItem
aFont( eFamily
, aName
, OUString(), ePitch
, eDstCharSet
, nWhich
);
3785 if( m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size() ) // StyleDef
3790 case RES_CHRATR_FONT
:
3791 m_vColl
[m_nCurrentColl
].m_eLTRFontSrcCharSet
= eSrcCharSet
;
3793 case RES_CHRATR_CTL_FONT
:
3794 m_vColl
[m_nCurrentColl
].m_eRTLFontSrcCharSet
= eSrcCharSet
;
3796 case RES_CHRATR_CJK_FONT
:
3797 m_vColl
[m_nCurrentColl
].m_eCJKFontSrcCharSet
= eSrcCharSet
;
3801 else if (IsListOrDropcap())
3803 //Add character text encoding to stack
3804 if (nWhich
== RES_CHRATR_CJK_FONT
)
3805 m_aFontSrcCJKCharSets
.push(eSrcCharSet
);
3807 m_aFontSrcCharSets
.push(eSrcCharSet
);
3811 NewAttr( aFont
); // ...and insert
3816 void SwWW8ImplReader::ResetCharSetVars()
3818 OSL_ENSURE(!m_aFontSrcCharSets
.empty(),"no charset to remove");
3819 if (!m_aFontSrcCharSets
.empty())
3820 m_aFontSrcCharSets
.pop();
3823 void SwWW8ImplReader::ResetCJKCharSetVars()
3825 OSL_ENSURE(!m_aFontSrcCJKCharSets
.empty(),"no charset to remove");
3826 if (!m_aFontSrcCJKCharSets
.empty())
3827 m_aFontSrcCJKCharSets
.pop();
3830 void SwWW8ImplReader::openFont(sal_uInt16 nFCode
, sal_uInt16 nId
)
3832 if (SetNewFontAttr(nFCode
, true, nId
) && m_pCurrentColl
&& m_xStyles
)
3834 // remember for simulating default font
3835 if (RES_CHRATR_CJK_FONT
== nId
)
3836 m_xStyles
->mbCJKFontChanged
= true;
3837 else if (RES_CHRATR_CTL_FONT
== nId
)
3838 m_xStyles
->mbCTLFontChanged
= true;
3840 m_xStyles
->mbFontChanged
= true;
3844 void SwWW8ImplReader::closeFont(sal_uInt16 nId
)
3846 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nId
);
3847 if (nId
== RES_CHRATR_CJK_FONT
)
3848 ResetCJKCharSetVars();
3854 Turn font on or off:
3856 void SwWW8ImplReader::Read_FontCode( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
3858 //Note: this function needs to be able to run multiple times on the same data.
3859 //It is called by Read_SubSuperProp to ensure that the current fontsize is known.
3861 if (m_bSymbol
) // if bSymbol, the symbol's font
3864 // (see sprmCSymbol) is valid!
3868 case NS_sprm::CRgFtc2::val
: //"Other" font, override with BiDi if it exists
3869 case NS_sprm::CFtcBi::val
: //BiDi Font
3870 nId
= RES_CHRATR_CTL_FONT
;
3872 case NS_sprm::v6::sprmCFtc
: //WW6
3874 case NS_sprm::CRgFtc0::val
:
3875 nId
= RES_CHRATR_FONT
;
3878 case NS_sprm::CRgFtc1::val
:
3879 nId
= RES_CHRATR_CJK_FONT
;
3885 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
3887 if (nLen
< 2) // end of attribute
3889 if (eVersion
<= ww::eWW6
)
3891 closeFont(RES_CHRATR_CTL_FONT
);
3892 closeFont(RES_CHRATR_CJK_FONT
);
3898 sal_uInt16 nFCode
= SVBT16ToUInt16( pData
); // font number
3899 openFont(nFCode
, nId
);
3900 if (eVersion
<= ww::eWW6
)
3902 openFont(nFCode
, RES_CHRATR_CJK_FONT
);
3903 openFont(nFCode
, RES_CHRATR_CTL_FONT
);
3908 void SwWW8ImplReader::Read_FontSize( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
3913 case NS_sprm::v6::sprmCHps
:
3914 case NS_sprm::CHps::val
:
3915 nId
= RES_CHRATR_FONTSIZE
;
3919 case NS_sprm::CHpsBi::val
:
3920 nId
= RES_CHRATR_CTL_FONTSIZE
;
3926 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
3928 if (nLen
< (eVersion
<= ww::eWW2
? 1 : 2)) // end of attribute
3930 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nId
);
3931 if (eVersion
<= ww::eWW6
) // reset additionally the CTL size
3932 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_CTL_FONTSIZE
);
3933 if (RES_CHRATR_FONTSIZE
== nId
) // reset additionally the CJK size
3934 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_CJK_FONTSIZE
);
3938 // Font-Size in half points e.g. 10 = 1440 / ( 72 * 2 )
3939 sal_uLong nFSize
= eVersion
<= ww::eWW2
? *pData
: SVBT16ToUInt16(pData
);
3942 SvxFontHeightItem
aSz( nFSize
, 100, nId
);
3944 if (RES_CHRATR_FONTSIZE
== nId
) // set additionally the CJK size
3946 aSz
.SetWhich( RES_CHRATR_CJK_FONTSIZE
);
3949 if (eVersion
<= ww::eWW6
) // set additionally the CTL size
3951 aSz
.SetWhich( RES_CHRATR_CTL_FONTSIZE
);
3954 if (m_pCurrentColl
&& m_xStyles
) // Style-Def ?
3956 // remember for simulating default font size
3957 if (nId
== RES_CHRATR_CTL_FONTSIZE
)
3958 m_xStyles
->mbFCTLSizeChanged
= true;
3961 m_xStyles
->mbFSizeChanged
= true;
3962 if (eVersion
<= ww::eWW6
)
3963 m_xStyles
->mbFCTLSizeChanged
= true;
3969 void SwWW8ImplReader::Read_CharSet(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3972 { // end of attribute
3973 m_eHardCharSet
= RTL_TEXTENCODING_DONTKNOW
;
3976 sal_uInt8 nfChsDiff
= *pData
;
3978 if (nfChsDiff
&& nLen
>= 2)
3979 m_eHardCharSet
= rtl_getTextEncodingFromWindowsCharset( *(pData
+ 1) );
3981 m_eHardCharSet
= RTL_TEXTENCODING_DONTKNOW
;
3984 void SwWW8ImplReader::Read_Language( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
3988 case NS_sprm::v6::sprmCLid
:
3989 case NS_sprm::CRgLid0_80::val
:
3990 case NS_sprm::CRgLid0::val
:
3991 nId
= RES_CHRATR_LANGUAGE
;
3993 case NS_sprm::CRgLid1_80::val
:
3994 case NS_sprm::CRgLid1::val
:
3995 nId
= RES_CHRATR_CJK_LANGUAGE
;
3999 case NS_sprm::CLidBi::val
:
4000 nId
= RES_CHRATR_CTL_LANGUAGE
;
4006 if (nLen
< 2) // end of attribute
4007 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nId
);
4010 sal_uInt16 nLang
= SVBT16ToUInt16( pData
); // Language-Id
4011 NewAttr(SvxLanguageItem(LanguageType(nLang
), nId
));
4016 Turn on character style:
4018 void SwWW8ImplReader::Read_CColl( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4020 if (nLen
< 2) // end of attribute
4022 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_TXTATR_CHARFMT
);
4026 sal_uInt16 nId
= SVBT16ToUInt16( pData
); // Style-Id (NOT Sprm-Id!)
4028 if( nId
>= m_vColl
.size() || !m_vColl
[nId
].m_pFormat
// invalid Id?
4029 || m_vColl
[nId
].m_bColl
) // or paragraph style?
4030 return; // then ignore
4032 // if current on loading a TOX field, and current trying to apply a hyperlink character style,
4033 // just ignore. For the hyperlinks inside TOX in MS Word is not same with a common hyperlink
4034 // Character styles: without underline and blue font color. And such type style will be applied in others
4036 if (m_bLoadingTOXCache
&& m_vColl
[nId
].GetWWStyleId() == ww::stiHyperlink
)
4041 NewAttr( SwFormatCharFormat( static_cast<SwCharFormat
*>(m_vColl
[nId
].m_pFormat
) ) );
4042 m_nCharFormat
= static_cast<short>(nId
);
4046 Narrower or wider than normal:
4048 void SwWW8ImplReader::Read_Kern( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4050 if (nLen
< 2) // end of attribute
4052 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_KERNING
);
4055 sal_Int16 nKern
= SVBT16ToUInt16( pData
); // Kerning in Twips
4056 NewAttr( SvxKerningItem( nKern
, RES_CHRATR_KERNING
) );
4059 void SwWW8ImplReader::Read_FontKern( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4061 if (nLen
< 2) // end of attribute
4063 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_AUTOKERN
);
4066 sal_Int16 nAutoKern
= SVBT16ToUInt16( pData
); // Kerning in Twips
4067 NewAttr(SvxAutoKernItem(static_cast<bool>(nAutoKern
), RES_CHRATR_AUTOKERN
));
4070 void SwWW8ImplReader::Read_CharShadow( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4072 //Has newer colour variant, ignore this old variant
4073 if (!m_bVer67
&& m_xPlcxMan
&& m_xPlcxMan
->GetChpPLCF()->HasSprm(NS_sprm::CShd::val
).pSprm
)
4078 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_BACKGROUND
);
4083 aSHD
.SetWWValue( *reinterpret_cast<SVBT16
const *>(pData
) );
4084 SwWW8Shade
aSh( m_bVer67
, aSHD
);
4086 NewAttr( SvxBrushItem( aSh
.aColor
, RES_CHRATR_BACKGROUND
));
4088 // Add a marker to the grabbag indicating that character background was imported from MSO shading
4089 SfxGrabBagItem aGrabBag
= *static_cast<const SfxGrabBagItem
*>(GetFormatAttr(RES_CHRATR_GRABBAG
));
4090 std::map
<OUString
, css::uno::Any
>& rMap
= aGrabBag
.GetGrabBag();
4091 rMap
.insert(std::pair
<OUString
, css::uno::Any
>("CharShadingMarker",uno::makeAny(true)));
4096 void SwWW8ImplReader::Read_TextBackColor(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4100 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_BACKGROUND
);
4104 OSL_ENSURE(nLen
== 10, "Len of para back colour not 10!");
4107 Color
aColour(ExtractColour(pData
, m_bVer67
));
4108 NewAttr(SvxBrushItem(aColour
, RES_CHRATR_BACKGROUND
));
4110 // Add a marker to the grabbag indicating that character background was imported from MSO shading
4111 SfxGrabBagItem aGrabBag
= *static_cast<const SfxGrabBagItem
*>(GetFormatAttr(RES_CHRATR_GRABBAG
));
4112 std::map
<OUString
, css::uno::Any
>& rMap
= aGrabBag
.GetGrabBag();
4113 rMap
.insert(std::pair
<OUString
, css::uno::Any
>("CharShadingMarker",uno::makeAny(true)));
4118 void SwWW8ImplReader::Read_CharHighlight(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4122 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_HIGHLIGHT
);
4126 sal_uInt8 b
= *pData
; // Parameter: 0 = Auto, 1..16 colors
4128 if( b
> 16 ) // invalid -> Black
4129 b
= 0; // Auto -> Black
4131 Color
aCol(GetCol(b
));
4132 NewAttr( SvxBrushItem( aCol
, RES_CHRATR_HIGHLIGHT
));
4136 void SwWW8ImplReader::Read_NoLineNumb(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4138 if (nLen
< 0) // end of attribute
4140 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_LINENUMBER
);
4143 SwFormatLineNumber aLN
;
4144 if (const SwFormatLineNumber
* pLN
4145 = static_cast<const SwFormatLineNumber
*>(GetFormatAttr(RES_LINENUMBER
)))
4147 aLN
.SetStartValue( pLN
->GetStartValue() );
4150 aLN
.SetCountLines(pData
&& nLen
>= 1 && (0 == *pData
));
4154 static bool lcl_HasExplicitLeft(const WW8PLCFMan
*pPlcxMan
, bool bVer67
)
4156 WW8PLCFx_Cp_FKP
*pPap
= pPlcxMan
? pPlcxMan
->GetPapPLCF() : nullptr;
4160 return pPap
->HasSprm(NS_sprm::v6::sprmPDxaLeft
).pSprm
;
4162 return (pPap
->HasSprm(NS_sprm::PDxaLeft80::val
).pSprm
|| pPap
->HasSprm(NS_sprm::PDxaLeft::val
).pSprm
);
4168 void SwWW8ImplReader::Read_LR( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4170 if (nLen
< 2) // end of attribute
4172 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_LR_SPACE
);
4176 short nPara
= SVBT16ToUInt16( pData
);
4178 std::shared_ptr
<SvxLRSpaceItem
> aLR(std::make_shared
<SvxLRSpaceItem
>(RES_LR_SPACE
));
4179 const SfxPoolItem
* pLR
= GetFormatAttr(RES_LR_SPACE
);
4181 aLR
.reset(static_cast<SvxLRSpaceItem
*>(pLR
->Clone()));
4183 // Fix the regression issue: #i99822#: Discussion?
4184 // Since the list level formatting doesn't apply into paragraph style
4185 // for list levels of mode LABEL_ALIGNMENT.(see ww8par3.cxx
4186 // W8ImplReader::RegisterNumFormatOnTextNode).
4187 // Need to apply the list format to the paragraph here.
4188 SwTextNode
* pTextNode
= m_pPaM
->GetNode().GetTextNode();
4189 if( pTextNode
&& pTextNode
->AreListLevelIndentsApplicable() )
4191 SwNumRule
* pNumRule
= pTextNode
->GetNumRule();
4194 sal_uInt8 nLvl
= static_cast< sal_uInt8
>(pTextNode
->GetActualListLevel());
4195 const SwNumFormat
* pFormat
= pNumRule
->GetNumFormat( nLvl
);
4196 if ( pFormat
&& pFormat
->GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
)
4198 aLR
->SetTextLeft( pFormat
->GetIndentAt() );
4199 aLR
->SetTextFirstLineOffset( static_cast<short>(pFormat
->GetFirstLineIndent()) );
4200 // make paragraph have hard-set indent attributes
4201 pTextNode
->SetAttr( *aLR
);
4207 The older word sprms mean left/right, while the new ones mean before/after.
4208 Writer now also works with before after, so when we see old left/right and
4209 we're RTL. We swap them
4211 if (IsRightToLeft())
4215 //Left becomes after;
4216 case NS_sprm::v6::sprmPDxaLeft
:
4217 nId
= NS_sprm::v6::sprmPDxaRight
;
4219 case NS_sprm::PDxaLeft80::val
:
4220 nId
= NS_sprm::PDxaRight80::val
;
4222 //Right becomes before;
4223 case NS_sprm::v6::sprmPDxaRight
:
4224 nId
= NS_sprm::v6::sprmPDxaLeft
;
4226 case NS_sprm::PDxaRight80::val
:
4227 nId
= NS_sprm::PDxaLeft80::val
;
4232 bool bFirstLinOfstSet( false ); // #i103711#
4233 bool bLeftIndentSet( false ); // #i105414#
4238 case NS_sprm::v6::sprmPDxaLeft
:
4239 case NS_sprm::PDxaLeft80::val
:
4240 case NS_sprm::PDxaLeft::val
:
4241 aLR
->SetTextLeft( nPara
);
4242 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size())
4244 m_vColl
[m_nCurrentColl
].m_bListRelevantIndentSet
= true;
4246 bLeftIndentSet
= true; // #i105414#
4249 case NS_sprm::v6::sprmPDxaLeft1
:
4250 case NS_sprm::PDxaLeft180::val
:
4251 case NS_sprm::PDxaLeft1::val
:
4253 As part of an attempt to break my spirit ww 8+ formats can contain
4254 ww 7- lists. If they do and the list is part of the style, then
4255 when removing the list from a paragraph of that style there
4256 appears to be a bug where the hanging indent value which the list
4257 set is still factored into the left indent of the paragraph. Its
4258 not listed in the winword dialogs, but it is clearly there. So if
4259 our style has a broken ww 7- list and we know that the list has
4260 been removed then we will factor the original list applied hanging
4261 into our calculation.
4263 if (m_xPlcxMan
&& m_nCurrentColl
< m_vColl
.size() && m_vColl
[m_nCurrentColl
].m_bHasBrokenWW6List
)
4265 SprmResult aIsZeroed
= m_xPlcxMan
->GetPapPLCF()->HasSprm(NS_sprm::PIlfo::val
);
4266 if (aIsZeroed
.pSprm
&& aIsZeroed
.nRemainingData
>= 1 && *aIsZeroed
.pSprm
== 0)
4268 const SvxLRSpaceItem
&rLR
=
4269 ItemGet
<SvxLRSpaceItem
>(*(m_vColl
[m_nCurrentColl
].m_pFormat
),
4271 nPara
= nPara
- rLR
.GetTextFirstLineOffset();
4275 aLR
->SetTextFirstLineOffset(nPara
);
4277 if (!m_pCurrentColl
)
4279 if (const SwTextNode
* pNode
= m_pPaM
->GetNode().GetTextNode())
4281 if ( const SwNumFormat
*pNumFormat
= GetNumFormatFromTextNode(*pNode
) )
4283 if (!lcl_HasExplicitLeft(m_xPlcxMan
.get(), m_bVer67
))
4285 aLR
->SetTextLeft(pNumFormat
->GetIndentAt());
4287 // If have not explicit left, set number format list tab position is doc default tab
4288 const SvxTabStopItem
*pDefaultStopItem
= m_rDoc
.GetAttrPool().GetPoolDefaultItem(RES_PARATR_TABSTOP
);
4289 if ( pDefaultStopItem
&& pDefaultStopItem
->Count() > 0 )
4290 const_cast<SwNumFormat
*>(pNumFormat
)->SetListtabPos( const_cast<SvxTabStop
&>((*pDefaultStopItem
)[0]).GetTabPos() );
4295 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size())
4297 m_vColl
[m_nCurrentColl
].m_bListRelevantIndentSet
= true;
4299 bFirstLinOfstSet
= true; // #i103711#
4302 case NS_sprm::v6::sprmPDxaRight
:
4303 case NS_sprm::PDxaRight80::val
:
4304 case NS_sprm::PDxaRight::val
:
4305 aLR
->SetRight( nPara
);
4311 NewAttr( *aLR
, bFirstLinOfstSet
, bLeftIndentSet
); // #i103711#, #i105414#
4315 void SwWW8ImplReader::Read_LineSpace( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4317 // comment see Read_UL()
4318 if (m_bStyNormal
&& m_bWWBugNormal
)
4321 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
4323 if (nLen
< (eVersion
<= ww::eWW2
? 3 : 4))
4325 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_LINESPACING
);
4326 if( !( m_nIniFlags
& WW8FL_NO_IMPLPASP
) )
4327 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_UL_SPACE
);
4331 short nSpace
= SVBT16ToUInt16( pData
);
4332 short nMulti
= (eVersion
<= ww::eWW2
) ? 1 : SVBT16ToUInt16( pData
+ 2 );
4334 SvxLineSpaceRule eLnSpc
;
4338 eLnSpc
= SvxLineSpaceRule::Fix
;
4341 eLnSpc
= SvxLineSpaceRule::Min
;
4343 // WW has implicit additional paragraph spacing depending on
4344 // the line spacing. It is, for "exactly", 0.8 * line spacing "before"
4345 // and 0.2 * line spacing "after".
4346 // For "at least", it is 1 * line spacing "before" and 0 * line spacing "after".
4347 // For "multiple", it is 0 "before" and min(0cm, FontSize*(nFach-1)) "after".
4349 // SW also has implicit line spacing. It is, for "at least"
4350 // 1 * line spacing "before" and 0 "after".
4351 // For proportional, it is min(0cm, FontSize*(nFach-1)) both "before" and "after".
4353 sal_uInt16 nSpaceTw
= 0;
4355 SvxLineSpacingItem
aLSpc( LINE_SPACE_DEFAULT_HEIGHT
, RES_PARATR_LINESPACING
);
4357 if( 1 == nMulti
) // MultilineSpace ( proportional )
4359 tools::Long n
= nSpace
* 10 / 24; // WW: 240 = 100%, SW: 100 = 100%
4361 // here n is in [0..13653]
4362 aLSpc
.SetPropLineSpace( static_cast<sal_uInt16
>(n
) );
4363 const SvxFontHeightItem
* pH
= static_cast<const SvxFontHeightItem
*>(
4364 GetFormatAttr( RES_CHRATR_FONTSIZE
));
4365 nSpaceTw
= static_cast<sal_uInt16
>( n
* pH
->GetHeight() / 100 );
4367 else // Fixed / Minimum
4369 // for negative space, the distance is "exact", otherwise "at least"
4370 nSpaceTw
= static_cast<sal_uInt16
>(nSpace
);
4371 aLSpc
.SetLineHeight( nSpaceTw
);
4372 aLSpc
.SetLineSpaceRule( eLnSpc
);
4376 m_xSFlyPara
->nLineSpace
= nSpaceTw
; // linespace for graphics APOs
4379 //#i18519# AutoSpace value depends on Dop fDontUseHTMLAutoSpacing setting
4380 sal_uInt16
SwWW8ImplReader::GetParagraphAutoSpace(bool fDontUseHTMLAutoSpacing
)
4382 if (fDontUseHTMLAutoSpacing
)
4383 return 100; //Seems to be always 5points in this case
4385 return 280; //Seems to be always 14points in this case
4388 void SwWW8ImplReader::Read_ParaAutoBefore(sal_uInt16
, const sal_uInt8
*pData
, short nLen
)
4392 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_UL_SPACE
);
4398 SvxULSpaceItem
aUL(*static_cast<const SvxULSpaceItem
*>(GetFormatAttr(RES_UL_SPACE
)));
4399 aUL
.SetUpper(GetParagraphAutoSpace(m_xWDop
->fDontUseHTMLAutoSpacing
));
4401 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size())
4402 m_vColl
[m_nCurrentColl
].m_bParaAutoBefore
= true;
4404 m_bParaAutoBefore
= true;
4408 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size())
4409 m_vColl
[m_nCurrentColl
].m_bParaAutoBefore
= false;
4411 m_bParaAutoBefore
= false;
4415 void SwWW8ImplReader::Read_ParaAutoAfter(sal_uInt16
, const sal_uInt8
*pData
, short nLen
)
4419 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_UL_SPACE
);
4425 SvxULSpaceItem
aUL(*static_cast<const SvxULSpaceItem
*>(GetFormatAttr(RES_UL_SPACE
)));
4426 aUL
.SetLower(GetParagraphAutoSpace(m_xWDop
->fDontUseHTMLAutoSpacing
));
4428 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size())
4429 m_vColl
[m_nCurrentColl
].m_bParaAutoAfter
= true;
4431 m_bParaAutoAfter
= true;
4435 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size())
4436 m_vColl
[m_nCurrentColl
].m_bParaAutoAfter
= false;
4438 m_bParaAutoAfter
= false;
4443 void SwWW8ImplReader::Read_UL( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4445 // A workaround for an error in WW: For nProduct == 0c03d, usually
4446 // DyaAfter 240 (delta y distance after, comment of the translator)
4447 // is incorrectly inserted into style "Normal", even though it isn't there.
4448 // Using the ini flag WW8FL_NO_STY_DYA you can force this behavior for other
4449 // WW versions as well.
4450 // OSL_ENSURE( !bStyNormal || bWWBugNormal, "+This Document may point to a bug
4451 // in the WW version used for creating it. If the Styles <Standard> resp.
4452 // <Normal> differentiate between WW and SW in paragraph or line spacing,
4453 // then please send this Document to SH.");
4454 // bWWBugNormal is not a sufficient criterion for this distance being wrong.
4459 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_UL_SPACE
);
4462 short nPara
= SVBT16ToUInt16( pData
);
4466 SvxULSpaceItem
aUL( *static_cast<const SvxULSpaceItem
*>(GetFormatAttr( RES_UL_SPACE
)));
4471 case NS_sprm::v6::sprmPDyaBefore
:
4472 case NS_sprm::PDyaBefore::val
:
4473 aUL
.SetUpper( nPara
);
4476 case NS_sprm::v6::sprmPDyaAfter
:
4477 case NS_sprm::PDyaAfter::val
:
4478 aUL
.SetLower( nPara
);
4487 void SwWW8ImplReader::Read_ParaContextualSpacing( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4491 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_UL_SPACE
);
4494 SvxULSpaceItem
aUL( *static_cast<const SvxULSpaceItem
*>(GetFormatAttr( RES_UL_SPACE
)));
4495 aUL
.SetContextValue(*pData
!= 0);
4499 void SwWW8ImplReader::Read_IdctHint( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4501 // sprmcidcthint (opcode 0x286f) specifies a script bias for the text in the run.
4502 // for unicode characters that are shared between far east and non-far east scripts,
4503 // this property determines what font and language the character will use.
4504 // when this value is 0, text properties bias towards non-far east properties.
4505 // when this value is 1, text properties bias towards far east properties.
4506 // when this value is 2, text properties bias towards complex properties.
4507 if (nLen
< 1) //Property end
4509 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(),RES_CHRATR_IDCTHINT
);
4511 else //Property start
4513 NewAttr(SfxInt16Item(RES_CHRATR_IDCTHINT
, *pData
));
4517 void SwWW8ImplReader::Read_Justify( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4521 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_ADJUST
);
4525 SvxAdjust
eAdjust(SvxAdjust::Left
);
4526 bool bDistributed
= false;
4533 eAdjust
= SvxAdjust::Center
;
4536 eAdjust
= SvxAdjust::Right
;
4539 eAdjust
= SvxAdjust::Block
;
4542 eAdjust
= SvxAdjust::Block
;
4543 bDistributed
= true;
4546 SvxAdjustItem
aAdjust(eAdjust
, RES_PARATR_ADJUST
);
4548 aAdjust
.SetLastBlock(SvxAdjust::Block
);
4551 SetRelativeJustify( nId
!= NS_sprm::PJc80::val
);
4554 bool SwWW8ImplReader::IsRightToLeft()
4559 aDir
= m_xPlcxMan
->GetPapPLCF()->HasSprm(NS_sprm::PFBiDi::val
);
4560 if (aDir
.pSprm
&& aDir
.nRemainingData
>= 1)
4561 bRTL
= *aDir
.pSprm
!= 0;
4564 const SvxFrameDirectionItem
* pItem
=
4565 static_cast<const SvxFrameDirectionItem
*>(GetFormatAttr(RES_FRAMEDIR
));
4566 if (pItem
&& (pItem
->GetValue() == SvxFrameDirection::Horizontal_RL_TB
))
4572 void SwWW8ImplReader::Read_RTLJustify( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4576 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_ADJUST
);
4580 //If we are in a ltr paragraph this is the same as normal Justify,
4581 //If we are in a rtl paragraph the meaning is reversed.
4582 if (!IsRightToLeft())
4583 Read_Justify(nId
, pData
, nLen
);
4586 SvxAdjust
eAdjust(SvxAdjust::Right
);
4587 bool bDistributed
= false;
4594 eAdjust
= SvxAdjust::Center
;
4597 eAdjust
= SvxAdjust::Left
;
4600 eAdjust
= SvxAdjust::Block
;
4603 eAdjust
= SvxAdjust::Block
;
4604 bDistributed
= true;
4607 SvxAdjustItem
aAdjust(eAdjust
, RES_PARATR_ADJUST
);
4609 aAdjust
.SetLastBlock(SvxAdjust::Block
);
4612 SetRelativeJustify( true );
4616 void SwWW8ImplReader::Read_BoolItem( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4620 case NS_sprm::PFKinsoku::val
:
4621 nId
= RES_PARATR_FORBIDDEN_RULES
;
4623 case NS_sprm::PFOverflowPunct::val
:
4624 nId
= RES_PARATR_HANGINGPUNCTUATION
;
4626 case NS_sprm::PFAutoSpaceDE::val
:
4627 nId
= RES_PARATR_SCRIPTSPACE
;
4630 OSL_ENSURE( false, "wrong Id" );
4635 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nId
);
4638 std::unique_ptr
<SfxBoolItem
> pI(static_cast<SfxBoolItem
*>(GetDfltAttr( nId
)->Clone()));
4639 pI
->SetValue( 0 != *pData
);
4644 void SwWW8ImplReader::Read_Emphasis( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4647 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_EMPHASIS_MARK
);
4651 //Check to see if there is an up and coming cjk language property. If
4652 //there is use it, if there is not fall back to the currently set one.
4653 //Only the cjk language setting seems to matter to word, the western
4657 aLang
= m_xPlcxMan
->GetChpPLCF()->HasSprm(NS_sprm::CRgLid1_80::val
);
4659 if (aLang
.pSprm
&& aLang
.nRemainingData
>= 2)
4660 nLang
= LanguageType(SVBT16ToUInt16(aLang
.pSprm
));
4663 nLang
= static_cast<const SvxLanguageItem
*>(
4664 GetFormatAttr(RES_CHRATR_CJK_LANGUAGE
))->GetLanguage();
4667 FontEmphasisMark nVal
;
4671 nVal
= FontEmphasisMark::NONE
;
4674 if (MsLangId::isKorean(nLang
) || MsLangId::isTraditionalChinese(nLang
))
4675 nVal
= (FontEmphasisMark::Circle
| FontEmphasisMark::PosAbove
);
4676 else if (nLang
== LANGUAGE_JAPANESE
)
4677 nVal
= (FontEmphasisMark::Accent
| FontEmphasisMark::PosAbove
);
4679 nVal
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosBelow
);
4682 nVal
= (FontEmphasisMark::Circle
| FontEmphasisMark::PosAbove
);
4685 nVal
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosBelow
);
4688 if (MsLangId::isSimplifiedChinese(nLang
))
4689 nVal
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosBelow
);
4691 nVal
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosAbove
);
4694 nVal
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosAbove
);
4698 NewAttr( SvxEmphasisMarkItem( nVal
, RES_CHRATR_EMPHASIS_MARK
) );
4702 void SwWW8ImplReader::Read_ScaleWidth( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4705 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_SCALEW
);
4708 sal_uInt16 nVal
= SVBT16ToUInt16( pData
);
4709 //The number must be between 1 and 600
4710 if (nVal
< 1 || nVal
> 600)
4712 NewAttr( SvxCharScaleWidthItem( nVal
, RES_CHRATR_SCALEW
) );
4716 void SwWW8ImplReader::Read_Relief( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4719 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_RELIEF
);
4724 // not so easy because this is also a toggle attribute!
4725 // 2 x emboss on -> no emboss !!!
4726 // the actual value must be searched over the stack / template
4728 const SvxCharReliefItem
* pOld
= static_cast<const SvxCharReliefItem
*>(
4729 GetFormatAttr( RES_CHRATR_RELIEF
));
4730 FontRelief nNewValue
= NS_sprm::CFImprint::val
== nId
? FontRelief::Engraved
4731 : ( NS_sprm::CFEmboss::val
== nId
? FontRelief::Embossed
4732 : FontRelief::NONE
);
4733 if( pOld
->GetValue() == nNewValue
)
4735 if( FontRelief::NONE
!= nNewValue
)
4736 nNewValue
= FontRelief::NONE
;
4738 NewAttr( SvxCharReliefItem( nNewValue
, RES_CHRATR_RELIEF
));
4743 void SwWW8ImplReader::Read_TextAnim(sal_uInt16
/*nId*/, const sal_uInt8
* pData
, short nLen
)
4746 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_CHRATR_BLINK
);
4753 // The 7 animated text effects available in word all get
4754 // mapped to a blinking text effect in LibreOffice
4755 // 0 no animation 1 Las Vegas lights
4756 // 2 background blink 3 sparkle text
4757 // 4 marching ants 5 marching red ants
4759 bBlink
= *pData
> 0 && *pData
< 7;
4761 NewAttr(SvxBlinkItem(bBlink
, RES_CHRATR_BLINK
));
4766 SwWW8Shade::SwWW8Shade(bool bVer67
, const WW8_SHD
& rSHD
)
4768 sal_uInt8 b
= rSHD
.GetFore();
4769 OSL_ENSURE(b
< 17, "ww8: colour out of range");
4773 Color
nFore(SwWW8ImplReader::GetCol(b
));
4776 OSL_ENSURE(b
< 17, "ww8: colour out of range");
4780 Color
nBack(SwWW8ImplReader::GetCol(b
));
4782 b
= rSHD
.GetStyle(bVer67
);
4784 SetShade(nFore
, nBack
, b
);
4787 void SwWW8Shade::SetShade(Color nFore
, Color nBack
, sal_uInt16 nIndex
)
4789 static const sal_uLong eMSGrayScale
[] =
4809 333, // 14 Dark Horizontal
4810 333, // 15 Dark Vertical
4811 333, // 16 Dark Forward Diagonal
4812 333, // 17 Dark Backward Diagonal
4813 333, // 18 Dark Cross
4814 333, // 19 Dark Diagonal Cross
4815 333, // 20 Horizontal
4817 333, // 22 Forward Diagonal
4818 333, // 23 Backward Diagonal
4820 333, // 25 Diagonal Cross
4821 // Undefined values in DOC spec-sheet
4831 // Different shading types
4832 25, // 35 [available in DOC, not available in DOCX]
4833 75, // 36 [available in DOC, not available in DOCX]
4836 175, // 39 [available in DOC, not available in DOCX]
4837 225, // 40 [available in DOC, not available in DOCX]
4838 275, // 41 [available in DOC, not available in DOCX]
4839 325, // 42 [available in DOC, not available in DOCX]
4842 425, // 45 [available in DOC, not available in DOCX]
4844 475, // 47 [available in DOC, not available in DOCX]
4845 525, // 48 [available in DOC, not available in DOCX]
4847 575, // 50 [available in DOC, not available in DOCX]
4850 675, // 53 [available in DOC, not available in DOCX]
4851 725, // 54 [available in DOC, not available in DOCX]
4852 775, // 55 [available in DOC, not available in DOCX]
4853 825, // 56 [available in DOC, not available in DOCX]
4856 925, // 59 [available in DOC, not available in DOCX]
4858 975 // 61 [available in DOC, not available in DOCX]
4861 //NO auto for shading so Foreground: Auto = Black
4862 if (nFore
== COL_AUTO
)
4865 //NO auto for shading so background: Auto = White
4866 Color nUseBack
= nBack
;
4867 if (nUseBack
== COL_AUTO
)
4868 nUseBack
= COL_WHITE
;
4870 if( nIndex
>= SAL_N_ELEMENTS( eMSGrayScale
) )
4873 sal_uLong nWW8BrushStyle
= eMSGrayScale
[nIndex
];
4875 switch (nWW8BrushStyle
)
4877 case 0: // Null-Brush
4882 Color
aForeColor(nFore
);
4883 Color
aBackColor(nUseBack
);
4885 sal_uInt32 nRed
= aForeColor
.GetRed() * nWW8BrushStyle
;
4886 sal_uInt32 nGreen
= aForeColor
.GetGreen() * nWW8BrushStyle
;
4887 sal_uInt32 nBlue
= aForeColor
.GetBlue() * nWW8BrushStyle
;
4888 nRed
+= aBackColor
.GetRed() * (1000 - nWW8BrushStyle
);
4889 nGreen
+= aBackColor
.GetGreen()* (1000 - nWW8BrushStyle
);
4890 nBlue
+= aBackColor
.GetBlue() * (1000 - nWW8BrushStyle
);
4892 aColor
= Color( nRed
/1000, nGreen
/1000, nBlue
/1000 );
4898 void SwWW8ImplReader::Read_Shade( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4900 if (!m_bVer67
&& m_xPlcxMan
&& m_xPlcxMan
->GetPapPLCF()->HasSprm(NS_sprm::PShd::val
).pSprm
)
4906 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), XATTR_FILLSTYLE
);
4907 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), XATTR_FILLCOLOR
);
4912 aSHD
.SetWWValue( *reinterpret_cast<SVBT16
const *>(pData
) );
4913 SwWW8Shade
aSh( m_bVer67
, aSHD
);
4915 NewAttr( XFillStyleItem(drawing::FillStyle_SOLID
) );
4916 NewAttr( XFillColorItem(OUString(), aSh
.aColor
) );
4920 void SwWW8ImplReader::Read_ParaBackColor(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4925 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), XATTR_FILLSTYLE
);
4926 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), XATTR_FILLCOLOR
);
4930 OSL_ENSURE(nLen
== 10, "Len of para back colour not 10!");
4934 const Color aColor
= ExtractColour(pData
, m_bVer67
);
4935 NewAttr( XFillColorItem(OUString(), aColor
) );
4936 if ( aColor
== COL_AUTO
)
4937 NewAttr( XFillStyleItem(drawing::FillStyle_NONE
) );
4939 NewAttr( XFillStyleItem(drawing::FillStyle_SOLID
) );
4943 Color
SwWW8ImplReader::ExtractColour(const sal_uInt8
* &rpData
, bool bVer67
)
4945 OSL_ENSURE(!bVer67
, "Impossible");
4946 Color nFore
= msfilter::util::BGRToRGB(SVBT32ToUInt32(rpData
));
4948 Color nBack
= msfilter::util::BGRToRGB(SVBT32ToUInt32(rpData
));
4950 sal_uInt16 nIndex
= SVBT16ToUInt16(rpData
);
4952 //Being a transparent background colour doesn't actually show the page
4953 //background through, it merely acts like white
4954 if (nBack
== Color(0xFF000000))
4956 OSL_ENSURE(nBack
== COL_AUTO
|| (nBack
.GetTransparency() == 0),
4957 "ww8: don't know what to do with such a transparent bg colour, report");
4958 SwWW8Shade
aShade(nFore
, nBack
, nIndex
);
4959 return aShade
.aColor
;
4962 void SwWW8ImplReader::Read_TextVerticalAdjustment( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4967 drawing::TextVerticalAdjust nVA
= drawing::TextVerticalAdjust_TOP
;
4971 nVA
= drawing::TextVerticalAdjust_CENTER
;
4974 nVA
= drawing::TextVerticalAdjust_BLOCK
;
4977 nVA
= drawing::TextVerticalAdjust_BOTTOM
;
4982 m_aSectionManager
.SetCurrentSectionVerticalAdjustment( nVA
);
4985 void SwWW8ImplReader::Read_Border(sal_uInt16
, const sal_uInt8
*, short nLen
)
4991 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_BOX
);
4992 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_SHADOW
);
4993 m_bHasBorder
= false;
4996 else if( !m_bHasBorder
)
4998 // the borders on all four sides are bundled. That
4999 // simplifies the administration, i.e., the box does not have
5000 // to be put on and removed from CtrlStack 4 times.
5001 m_bHasBorder
= true;
5003 WW8_BRCVer9_5 aBrcs
; // Top, Left, Bottom, Right, Between
5006 if( m_pCurrentColl
)
5007 nBorder
= ::lcl_ReadBorders(m_bVer67
, aBrcs
, nullptr, m_xStyles
.get());
5009 nBorder
= ::lcl_ReadBorders(m_bVer67
, aBrcs
, m_xPlcxMan
? m_xPlcxMan
->GetPapPLCF() : nullptr);
5011 if( nBorder
) // Border
5013 bool bIsB
= IsBorder(aBrcs
, true);
5014 if (!InLocalApo() || !bIsB
|| (m_xWFlyPara
&& !m_xWFlyPara
->bBorderLines
))
5016 // Do not turn *on* borders in APO, since otherwise
5017 // I get the Fly border twice;
5018 // but only when it is set on in the Fly, skip it;
5019 // otherwise there is none at all!
5021 // even if no border is set, the attribute has to be set,
5022 // otherwise it's not possible to turn off the style attribute.
5023 const SvxBoxItem
* pBox
5024 = static_cast<const SvxBoxItem
*>(GetFormatAttr( RES_BOX
));
5025 std::shared_ptr
<SvxBoxItem
> aBox(std::make_shared
<SvxBoxItem
>(RES_BOX
));
5027 aBox
.reset(pBox
->Clone());
5028 short aSizeArray
[5]={0};
5030 SetBorder(*aBox
, aBrcs
, &aSizeArray
[0], nBorder
);
5032 tools::Rectangle aInnerDist
;
5033 GetBorderDistance( aBrcs
, aInnerDist
);
5035 if (nBorder
& (1 << WW8_LEFT
))
5036 aBox
->SetDistance( static_cast<sal_uInt16
>(aInnerDist
.Left()), SvxBoxItemLine::LEFT
);
5038 if (nBorder
& (1 << WW8_TOP
))
5039 aBox
->SetDistance( static_cast<sal_uInt16
>(aInnerDist
.Top()), SvxBoxItemLine::TOP
);
5041 if (nBorder
& (1 << WW8_RIGHT
))
5042 aBox
->SetDistance( static_cast<sal_uInt16
>(aInnerDist
.Right()), SvxBoxItemLine::RIGHT
);
5044 if (nBorder
& (1 << WW8_BOT
))
5045 aBox
->SetDistance( static_cast<sal_uInt16
>(aInnerDist
.Bottom()), SvxBoxItemLine::BOTTOM
);
5049 SvxShadowItem
aS(RES_SHADOW
);
5050 // Word only allows shadows on visible borders
5051 if ( aBox
->CalcLineSpace( SvxBoxItemLine::RIGHT
) )
5052 SetShadow( aS
, &aSizeArray
[0], aBrcs
[WW8_RIGHT
] );
5059 void SwWW8ImplReader::Read_CharBorder(sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
5061 //Ignore this old border type
5062 //if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(NS_sprm::CBrc::val))
5067 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_BOX
);
5068 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_SHADOW
);
5072 const SvxBoxItem
* pBox
5073 = static_cast<const SvxBoxItem
*>(GetFormatAttr( RES_CHRATR_BOX
));
5076 std::unique_ptr
<SvxBoxItem
> aBoxItem(pBox
->Clone());
5078 int nBrcVer
= (nId
== NS_sprm::CBrc::val
) ? 9 : (m_bVer67
? 6 : 8);
5080 SetWW8_BRC(nBrcVer
, aBrc
, pData
, nLen
);
5082 Set1Border(*aBoxItem
, aBrc
, SvxBoxItemLine::TOP
, 0, nullptr, true);
5083 Set1Border(*aBoxItem
, aBrc
, SvxBoxItemLine::BOTTOM
, 0, nullptr, true);
5084 Set1Border(*aBoxItem
, aBrc
, SvxBoxItemLine::LEFT
, 0, nullptr, true);
5085 Set1Border(*aBoxItem
, aBrc
, SvxBoxItemLine::RIGHT
, 0, nullptr, true);
5086 NewAttr( *aBoxItem
);
5088 short aSizeArray
[WW8_RIGHT
+1]={0}; aSizeArray
[WW8_RIGHT
] = 1;
5089 SvxShadowItem
aShadowItem(RES_CHRATR_SHADOW
);
5090 // Word only allows shadows on visible borders
5091 if ( aBoxItem
->CalcLineSpace( SvxBoxItemLine::RIGHT
) )
5092 SetShadow( aShadowItem
, &aSizeArray
[0], aBrc
);
5093 NewAttr( aShadowItem
);
5098 void SwWW8ImplReader::Read_Hyphenation( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5100 // set Hyphenation flag
5102 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_HYPHENZONE
);
5105 SvxHyphenZoneItem
aAttr(
5106 *static_cast<const SvxHyphenZoneItem
*>(GetFormatAttr( RES_PARATR_HYPHENZONE
) ));
5108 aAttr
.SetHyphen( 0 == *pData
); // sic !
5112 aAttr
.GetMinLead() = 2;
5113 aAttr
.GetMinTrail() = 2;
5114 aAttr
.GetMaxHyphens() = 0;
5121 void SwWW8ImplReader::Read_WidowControl( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5125 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_WIDOWS
);
5126 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_ORPHANS
);
5130 sal_uInt8 nL
= ( *pData
& 1 ) ? 2 : 0;
5132 NewAttr( SvxWidowsItem( nL
, RES_PARATR_WIDOWS
) ); // Off -> nLines = 0
5133 NewAttr( SvxOrphansItem( nL
, RES_PARATR_ORPHANS
) );
5135 if( m_pCurrentColl
&& m_xStyles
) // Style-Def ?
5136 m_xStyles
->mbWidowsChanged
= true; // save for simulation
5141 void SwWW8ImplReader::Read_UsePgsuSettings(sal_uInt16
,const sal_uInt8
* pData
,short nLen
)
5144 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_SNAPTOGRID
);
5148 NewAttr( SvxParaGridItem(false, RES_PARATR_SNAPTOGRID
) );
5150 NewAttr( SvxParaGridItem(*pData
, RES_PARATR_SNAPTOGRID
) );
5154 void SwWW8ImplReader::Read_AlignFont( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5157 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_VERTALIGN
);
5160 sal_uInt16 nVal
= SVBT16ToUInt16( pData
);
5161 SvxParaVertAlignItem::Align nAlign
;
5165 nAlign
= SvxParaVertAlignItem::Align::Top
;
5168 nAlign
= SvxParaVertAlignItem::Align::Center
;
5171 nAlign
= SvxParaVertAlignItem::Align::Baseline
;
5174 nAlign
= SvxParaVertAlignItem::Align::Bottom
;
5177 nAlign
= SvxParaVertAlignItem::Align::Automatic
;
5180 nAlign
= SvxParaVertAlignItem::Align::Automatic
;
5181 OSL_ENSURE(false,"Unknown paragraph vertical align");
5184 NewAttr( SvxParaVertAlignItem( nAlign
, RES_PARATR_VERTALIGN
) );
5188 void SwWW8ImplReader::Read_KeepLines( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5191 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_SPLIT
);
5193 NewAttr( SvxFormatSplitItem( ( *pData
& 1 ) == 0, RES_PARATR_SPLIT
) );
5196 void SwWW8ImplReader::Read_KeepParas( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5199 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_KEEP
);
5201 NewAttr( SvxFormatKeepItem( ( *pData
& 1 ) != 0 , RES_KEEP
) );
5204 void SwWW8ImplReader::Read_BreakBefore( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5207 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_BREAK
);
5209 NewAttr( SvxFormatBreakItem(
5210 ( *pData
& 1 ) ? SvxBreak::PageBefore
: SvxBreak::NONE
, RES_BREAK
) );
5213 void SwWW8ImplReader::Read_ApoPPC( sal_uInt16
, const sal_uInt8
* pData
, short )
5215 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size()) // only for Styledef, otherwise solved differently
5217 SwWW8StyInf
& rSI
= m_vColl
[m_nCurrentColl
];
5219 rSI
.m_xWWFly
= std::make_shared
<WW8FlyPara
>(m_bVer67
);
5220 rSI
.m_xWWFly
->Read(*pData
, m_xStyles
.get());
5221 if (rSI
.m_xWWFly
->IsEmpty())
5223 m_vColl
[m_nCurrentColl
].m_xWWFly
.reset();
5228 bool SwWW8ImplReader::ParseTabPos(WW8_TablePos
*pTabPos
, WW8PLCFx_Cp_FKP
* pPap
)
5231 memset(pTabPos
, 0, sizeof(WW8_TablePos
));
5232 // sprmTPc contains a PositionCodeOperand structure that specifies the origin
5233 // that is used to calculate the table position when it is absolutely positioned
5234 SprmResult aRes
= pPap
->HasSprm(NS_sprm::TPc::val
);
5235 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 1)
5237 pTabPos
->nSp29
= *aRes
.pSprm
;
5238 pTabPos
->nSp37
= 2; //Possible fail area, always parallel wrap
5239 aRes
= pPap
->HasSprm(NS_sprm::TDxaAbs::val
);
5240 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 2)
5241 pTabPos
->nSp26
= SVBT16ToUInt16(aRes
.pSprm
);
5242 aRes
= pPap
->HasSprm(NS_sprm::TDyaAbs::val
);
5243 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 2)
5244 pTabPos
->nSp27
= SVBT16ToUInt16(aRes
.pSprm
);
5245 aRes
= pPap
->HasSprm(NS_sprm::TDxaFromText::val
);
5246 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 2)
5247 pTabPos
->nLeMgn
= SVBT16ToUInt16(aRes
.pSprm
);
5248 aRes
= pPap
->HasSprm(NS_sprm::TDxaFromTextRight::val
);
5249 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 2)
5250 pTabPos
->nRiMgn
= SVBT16ToUInt16(aRes
.pSprm
);
5251 aRes
= pPap
->HasSprm(NS_sprm::TDyaFromText::val
);
5252 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 2)
5253 pTabPos
->nUpMgn
= SVBT16ToUInt16(aRes
.pSprm
);
5254 aRes
= pPap
->HasSprm(NS_sprm::TDyaFromTextBottom::val
);
5255 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 2)
5256 pTabPos
->nLoMgn
= SVBT16ToUInt16(aRes
.pSprm
);
5257 pTabPos
->bNoFly
= !FloatingTableConversion(pPap
);
5263 // page attribute won't be used as attribute anymore
5265 tools::Long
SwWW8ImplReader::ImportExtSprm(WW8PLCFManResult
* pRes
)
5267 // array for reading of the extended ( self-defined ) SPRMs
5268 typedef tools::Long (SwWW8ImplReader::*FNReadRecordExt
)(WW8PLCFManResult
*);
5270 static const FNReadRecordExt aWwSprmTab
[] =
5272 /* 0 (256) */ &SwWW8ImplReader::Read_Footnote
, // FootNote
5273 /* 1 (257) */ &SwWW8ImplReader::Read_Footnote
, // EndNote
5274 /* 2 (258) */ &SwWW8ImplReader::Read_Field
, // Field
5275 /* 3 (259) */ &SwWW8ImplReader::Read_Book
, // Bookmark
5276 /* 4 (260) */ &SwWW8ImplReader::Read_And
, // Annotation
5277 /* 5 (261) */ &SwWW8ImplReader::Read_AtnBook
, // Annotationmark
5278 /* 6 (262) */ &SwWW8ImplReader::Read_FactoidBook
// Smart tag bookmark
5281 if( pRes
->nSprmId
< 280 )
5283 sal_uInt8 nIdx
= static_cast< sal_uInt8
>(pRes
->nSprmId
- eFTN
);
5284 if( nIdx
< SAL_N_ELEMENTS(aWwSprmTab
)
5285 && aWwSprmTab
[nIdx
] )
5286 return (this->*aWwSprmTab
[nIdx
])(pRes
);
5294 void SwWW8ImplReader::EndExtSprm(sal_uInt16 nSprmId
)
5296 typedef sal_uInt16 (SwWW8ImplReader::*FNReadRecordExt
)();
5298 static const FNReadRecordExt aWwSprmTab
[] =
5300 /* 0 (256) */ &SwWW8ImplReader::End_Footnote
, // FootNote
5301 /* 1 (257) */ &SwWW8ImplReader::End_Footnote
, // EndNote
5302 /* 2 (258) */ &SwWW8ImplReader::End_Field
, // Field
5303 /* 3 (259) */ nullptr, // Bookmark
5304 /* 4 (260) */ nullptr // Annotation
5307 sal_uInt8 nIdx
= static_cast< sal_uInt8
>(nSprmId
- eFTN
);
5308 if( nIdx
< SAL_N_ELEMENTS(aWwSprmTab
)
5309 && aWwSprmTab
[nIdx
] )
5310 (this->*aWwSprmTab
[nIdx
])();
5313 // arrays for reading the SPRMs
5315 // function for reading of SPRMs. Par1: SprmId
5316 typedef void (SwWW8ImplReader::*FNReadRecord
)( sal_uInt16
, const sal_uInt8
*, short );
5321 FNReadRecord pReadFnc
;
5324 static bool operator<(const SprmReadInfo
&rFirst
, const SprmReadInfo
&rSecond
)
5326 return (rFirst
.nId
< rSecond
.nId
);
5329 typedef ww::SortedArray
<SprmReadInfo
> wwSprmDispatcher
;
5331 static const wwSprmDispatcher
*GetWW2SprmDispatcher()
5333 static SprmReadInfo aSprms
[] =
5335 {0, nullptr}, // "0" default resp. error
5336 // will be skipped! ,
5337 {2, &SwWW8ImplReader::Read_StyleCode
}, //"sprmPIstd", pap.istd
5339 {3, nullptr}, //"sprmPIstdPermute", pap.istd
5341 {4, nullptr}, //"sprmPIncLv1",
5342 //pap.istddifference
5343 {5, &SwWW8ImplReader::Read_Justify
}, //"sprmPJc", pap.jc
5345 {6, nullptr}, //"sprmPFSideBySide",
5347 {7, &SwWW8ImplReader::Read_KeepLines
}, //"sprmPFKeep", pap.fKeep
5348 {8, &SwWW8ImplReader::Read_KeepParas
}, //"sprmPFKeepFollow ",
5350 {9, &SwWW8ImplReader::Read_BreakBefore
}, //"sprmPPageBreakBefore",
5351 //pap.fPageBreakBefore
5352 {10, nullptr}, //"sprmPBrcl", pap.brcl
5353 {11, nullptr}, //"sprmPBrcp ", pap.brcp
5354 {12, &SwWW8ImplReader::Read_ANLevelDesc
}, //"sprmPAnld", pap.anld (ANLD
5356 {13, &SwWW8ImplReader::Read_ANLevelNo
}, //"sprmPNLvlAnm", pap.nLvlAnm
5358 {14, &SwWW8ImplReader::Read_NoLineNumb
}, //"sprmPFNoLineNumb", ap.fNoLnn
5359 {15, &SwWW8ImplReader::Read_Tab
}, //"?sprmPChgTabsPapx",
5361 {16, &SwWW8ImplReader::Read_LR
}, //"sprmPDxaRight", pap.dxaRight
5362 {17, &SwWW8ImplReader::Read_LR
}, //"sprmPDxaLeft", pap.dxaLeft
5363 {18, nullptr}, //"sprmPNest", pap.dxaLeft
5364 {19, &SwWW8ImplReader::Read_LR
}, //"sprmPDxaLeft1", pap.dxaLeft1
5365 {20, &SwWW8ImplReader::Read_LineSpace
}, //"sprmPDyaLine", pap.lspd
5367 {21, &SwWW8ImplReader::Read_UL
}, //"sprmPDyaBefore",
5369 {22, &SwWW8ImplReader::Read_UL
}, //"sprmPDyaAfter", pap.dyaAfter
5370 {23, nullptr}, //"?sprmPChgTabs", pap.itbdMac,
5372 {24, nullptr}, //"sprmPFInTable", pap.fInTable
5373 {25, &SwWW8ImplReader::Read_TabRowEnd
}, //"sprmPTtp", pap.fTtp
5374 {26, nullptr}, //"sprmPDxaAbs", pap.dxaAbs
5375 {27, nullptr}, //"sprmPDyaAbs", pap.dyaAbs
5376 {28, nullptr}, //"sprmPDxaWidth", pap.dxaWidth
5377 {29, &SwWW8ImplReader::Read_ApoPPC
}, //"sprmPPc", pap.pcHorz,
5379 {30, nullptr}, //"sprmPBrcTop10", pap.brcTop
5381 {31, nullptr}, //"sprmPBrcLeft10",
5383 {32, nullptr}, //"sprmPBrcBottom10",
5384 //pap.brcBottom BRC10
5385 {33, nullptr}, //"sprmPBrcRight10",
5386 //pap.brcRight BRC10
5387 {34, nullptr}, //"sprmPBrcBetween10",
5388 //pap.brcBetween BRC10
5389 {35, nullptr}, //"sprmPBrcBar10", pap.brcBar
5391 {36, nullptr}, //"sprmPFromText10",
5392 //pap.dxaFromText dxa
5393 {37, nullptr}, //"sprmPWr", pap.wr wr
5394 {38, &SwWW8ImplReader::Read_Border
}, //"sprmPBrcTop", pap.brcTop BRC
5395 {39, &SwWW8ImplReader::Read_Border
}, //"sprmPBrcLeft",
5397 {40, &SwWW8ImplReader::Read_Border
}, //"sprmPBrcBottom",
5399 {41, &SwWW8ImplReader::Read_Border
}, //"sprmPBrcRight",
5401 {42, &SwWW8ImplReader::Read_Border
}, //"sprmPBrcBetween",
5402 //pap.brcBetween BRC
5403 {43, nullptr}, //"sprmPBrcBar", pap.brcBar
5405 {44, &SwWW8ImplReader::Read_Hyphenation
}, //"sprmPFNoAutoHyph",
5407 {45, nullptr}, //"sprmPWHeightAbs",
5409 {46, nullptr}, //"sprmPDcs", pap.dcs DCS
5410 {47, &SwWW8ImplReader::Read_Shade
}, //"sprmPShd", pap.shd SHD
5411 {48, nullptr}, //"sprmPDyaFromText",
5412 //pap.dyaFromText dya
5413 {49, nullptr}, //"sprmPDxaFromText",
5414 //pap.dxaFromText dxa
5415 {50, nullptr}, //"sprmPFLocked", pap.fLocked
5417 {51, &SwWW8ImplReader::Read_WidowControl
}, //"sprmPFWidowControl",
5418 //pap.fWidowControl 0 or 1 byte
5419 {52, nullptr}, //"?sprmPRuler 52",
5420 {53, nullptr}, //"??53",
5421 {54, nullptr}, //"??54",
5422 {55, nullptr}, //"??55",
5423 {56, nullptr}, //"??56",
5424 {57, nullptr}, //"??57",
5425 {58, nullptr}, //"??58",
5426 {59, nullptr}, //"??59",
5428 {60, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFBold", chp.fBold 0,1,
5430 {61, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFItalic", chp.fItalic
5431 //0,1, 128, or 129 byte
5432 {62, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFStrike", chp.fStrike
5433 //0,1, 128, or 129 byte
5434 {63, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFOutline", chp.fOutline
5435 //0,1, 128, or 129 byte
5436 {64, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFShadow", chp.fShadow
5437 //0,1, 128, or 129 byte
5438 {65, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFSmallCaps",
5439 //chp.fSmallCaps 0,1, 128, or
5441 {66, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFCaps", chp.fCaps 0,1,
5443 {67, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFVanish", chp.fVanish
5444 //0,1, 128, or 129 byte
5445 {68, &SwWW8ImplReader::Read_FontCode
}, //"sprmCFtc", chp.ftc ftc word
5446 {69, &SwWW8ImplReader::Read_Underline
}, // "sprmCKul", chp.kul kul byte
5447 {70, nullptr}, //"sprmCSizePos", chp.hps,
5448 //chp.hpsPos 3 bytes
5449 {71, &SwWW8ImplReader::Read_Kern
}, //"sprmCDxaSpace",
5450 //chp.dxaSpace dxa word
5451 {72, &SwWW8ImplReader::Read_Language
}, //"sprmCLid", chp.lid LID word
5452 {73, &SwWW8ImplReader::Read_TextColor
}, //"sprmCIco", chp.ico ico byte
5453 {74, &SwWW8ImplReader::Read_FontSize
}, //"sprmCHps", chp.hps hps word!
5454 {75, nullptr}, //"sprmCHpsInc", chp.hps byte
5455 {76, &SwWW8ImplReader::Read_SubSuperProp
}, //"sprmCHpsPos", chp.hpsPos
5457 {77, nullptr}, //"sprmCHpsPosAdj", chp.hpsPos
5459 {78, &SwWW8ImplReader::Read_Majority
}, //"?sprmCMajority", chp.fBold,
5460 //chp.fItalic, chp.fSmallCaps
5461 {80, &SwWW8ImplReader::Read_BoldBiDiUsw
}, //sprmCFBoldBi
5462 {81, &SwWW8ImplReader::Read_BoldBiDiUsw
}, //sprmCFItalicBi
5463 {82, &SwWW8ImplReader::Read_FontCode
}, //sprmCFtcBi
5464 {83, &SwWW8ImplReader::Read_Language
}, //sprmClidBi
5465 {84, &SwWW8ImplReader::Read_TextColor
}, //sprmCIcoBi
5466 {85, &SwWW8ImplReader::Read_FontSize
}, //sprmCHpsBi
5467 {86, nullptr}, //sprmCFBiDi
5468 {87, nullptr}, //sprmCFDiacColor
5469 {94, nullptr}, //"sprmPicBrcl", pic.brcl brcl
5470 //(see PIC structure
5472 {95, nullptr}, //"sprmPicScale", pic.mx,
5473 //pic.my, pic.dxaCropleft,
5474 {96, nullptr}, //"sprmPicBrcTop", pic.brcTop
5476 {97, nullptr}, //"sprmPicBrcLeft",
5477 //pic.brcLeft BRC word
5478 {98, nullptr}, //"sprmPicBrcBottom",
5479 //pic.brcBottom BRC word
5480 {99, nullptr} //"sprmPicBrcRight",
5483 static wwSprmDispatcher
aSprmSrch(aSprms
, SAL_N_ELEMENTS(aSprms
));
5487 static const wwSprmDispatcher
*GetWW6SprmDispatcher()
5489 static SprmReadInfo aSprms
[] =
5491 {0, nullptr}, // "0" default resp. error
5493 {NS_sprm::v6::sprmPIstd
, &SwWW8ImplReader::Read_StyleCode
}, // pap.istd (style code)
5494 {NS_sprm::v6::sprmPIstdPermute
, nullptr}, // pap.istd permutation
5495 {NS_sprm::v6::sprmPIncLv1
, nullptr}, // pap.istddifference
5496 {NS_sprm::v6::sprmPJc
, &SwWW8ImplReader::Read_Justify
}, // pap.jc (justification)
5497 {NS_sprm::v6::sprmPFSideBySide
, nullptr}, // pap.fSideBySide
5498 {NS_sprm::v6::sprmPFKeep
, &SwWW8ImplReader::Read_KeepLines
}, // pap.fKeep
5499 {NS_sprm::v6::sprmPFKeepFollow
, &SwWW8ImplReader::Read_KeepParas
}, // pap.fKeepFollow
5500 {NS_sprm::v6::sprmPPageBreakBefore
, &SwWW8ImplReader::Read_BreakBefore
}, // pap.fPageBreakBefore
5501 {NS_sprm::v6::sprmPBrcl
, nullptr}, // pap.brcl
5502 {NS_sprm::v6::sprmPBrcp
, nullptr}, // pap.brcp
5503 {NS_sprm::v6::sprmPAnld
, &SwWW8ImplReader::Read_ANLevelDesc
}, // pap.anld (ANLD structure)
5504 {NS_sprm::v6::sprmPNLvlAnm
, &SwWW8ImplReader::Read_ANLevelNo
}, // pap.nLvlAnm nn
5505 {NS_sprm::v6::sprmPFNoLineNumb
, &SwWW8ImplReader::Read_NoLineNumb
}, // ap.fNoLnn
5506 {NS_sprm::v6::sprmPChgTabsPapx
, &SwWW8ImplReader::Read_Tab
}, // pap.itbdMac, ...
5507 {NS_sprm::v6::sprmPDxaRight
, &SwWW8ImplReader::Read_LR
}, // pap.dxaRight
5508 {NS_sprm::v6::sprmPDxaLeft
, &SwWW8ImplReader::Read_LR
}, // pap.dxaLeft
5509 {NS_sprm::v6::sprmPNest
, nullptr}, // pap.dxaLeft
5510 {NS_sprm::v6::sprmPDxaLeft1
, &SwWW8ImplReader::Read_LR
}, // pap.dxaLeft1
5511 {NS_sprm::v6::sprmPDyaLine
, &SwWW8ImplReader::Read_LineSpace
}, // pap.lspd an LSPD
5512 {NS_sprm::v6::sprmPDyaBefore
, &SwWW8ImplReader::Read_UL
}, // pap.dyaBefore
5513 {NS_sprm::v6::sprmPDyaAfter
, &SwWW8ImplReader::Read_UL
}, // pap.dyaAfter
5514 {NS_sprm::v6::sprmPChgTabs
, nullptr}, // pap.itbdMac, pap.rgdxaTab, ...
5515 {NS_sprm::v6::sprmPFInTable
, nullptr}, // pap.fInTable
5516 {NS_sprm::v6::sprmPTtp
, &SwWW8ImplReader::Read_TabRowEnd
}, // pap.fTtp
5517 {NS_sprm::v6::sprmPDxaAbs
, nullptr}, // pap.dxaAbs
5518 {NS_sprm::v6::sprmPDyaAbs
, nullptr}, // pap.dyaAbs
5519 {NS_sprm::v6::sprmPDxaWidth
, nullptr}, // pap.dxaWidth
5520 {NS_sprm::v6::sprmPPc
, &SwWW8ImplReader::Read_ApoPPC
}, // pap.pcHorz, pap.pcVert
5521 {NS_sprm::v6::sprmPBrcTop10
, nullptr}, // pap.brcTop BRC10
5522 {NS_sprm::v6::sprmPBrcLeft10
, nullptr}, // pap.brcLeft BRC10
5523 {NS_sprm::v6::sprmPBrcBottom10
, nullptr}, // pap.brcBottom BRC10
5524 {NS_sprm::v6::sprmPBrcRight10
, nullptr}, // pap.brcRight BRC10
5525 {NS_sprm::v6::sprmPBrcBetween10
, nullptr}, // pap.brcBetween BRC10
5526 {NS_sprm::v6::sprmPBrcBar10
, nullptr}, // pap.brcBar BRC10
5527 {NS_sprm::v6::sprmPFromText10
, nullptr}, // pap.dxaFromText dxa
5528 {NS_sprm::v6::sprmPWr
, nullptr}, // pap.wr wr
5529 {NS_sprm::v6::sprmPBrcTop
, &SwWW8ImplReader::Read_Border
}, // pap.brcTop BRC
5530 {NS_sprm::v6::sprmPBrcLeft
, &SwWW8ImplReader::Read_Border
}, // pap.brcLeft BRC
5531 {NS_sprm::v6::sprmPBrcBottom
, &SwWW8ImplReader::Read_Border
}, // pap.brcBottom BRC
5532 {NS_sprm::v6::sprmPBrcRight
, &SwWW8ImplReader::Read_Border
}, // pap.brcRight BRC
5533 {NS_sprm::v6::sprmPBrcBetween
, &SwWW8ImplReader::Read_Border
}, // pap.brcBetween BRC
5534 {NS_sprm::v6::sprmPBrcBar
, nullptr}, // pap.brcBar BRC word
5535 {NS_sprm::v6::sprmPFNoAutoHyph
, &SwWW8ImplReader::Read_Hyphenation
}, // pap.fNoAutoHyph
5536 {NS_sprm::v6::sprmPWHeightAbs
, nullptr}, // pap.wHeightAbs w
5537 {NS_sprm::v6::sprmPDcs
, nullptr}, // pap.dcs DCS
5538 {NS_sprm::v6::sprmPShd
, &SwWW8ImplReader::Read_Shade
}, // pap.shd SHD
5539 {NS_sprm::v6::sprmPDyaFromText
, nullptr}, // pap.dyaFromText dya
5540 {NS_sprm::v6::sprmPDxaFromText
, nullptr}, // pap.dxaFromText dxa
5541 {NS_sprm::v6::sprmPFLocked
, nullptr}, // pap.fLocked 0 or 1 byte
5542 {NS_sprm::v6::sprmPFWidowControl
, &SwWW8ImplReader::Read_WidowControl
}, // pap.fWidowControl 0 or 1 byte
5543 {NS_sprm::v6::sprmPRuler
, nullptr},
5544 {53, nullptr}, //"??53",
5545 {54, nullptr}, //"??54",
5546 {55, nullptr}, //"??55",
5547 {56, nullptr}, //"??56",
5548 {57, nullptr}, //"??57",
5549 {58, nullptr}, //"??58",
5550 {59, nullptr}, //"??59",
5551 {60, nullptr}, //"??60",
5552 {61, nullptr}, //"??61",
5553 {62, nullptr}, //"??62",
5554 {63, nullptr}, //"??63",
5555 {64, &SwWW8ImplReader::Read_ParaBiDi
}, //"rtl bidi ?
5556 {NS_sprm::v6::sprmCFStrikeRM
, &SwWW8ImplReader::Read_CFRMarkDel
}, // chp.fRMarkDel 1 or 0 bit
5557 {NS_sprm::v6::sprmCFRMark
, &SwWW8ImplReader::Read_CFRMark
}, // chp.fRMark 1 or 0 bit
5558 {NS_sprm::v6::sprmCFFldVanish
, &SwWW8ImplReader::Read_FieldVanish
}, // chp.fFieldVanish 1 or 0 bit
5559 {NS_sprm::v6::sprmCPicLocation
, &SwWW8ImplReader::Read_PicLoc
}, // chp.fcPic and chp.fSpec
5560 {NS_sprm::v6::sprmCIbstRMark
, nullptr}, // chp.ibstRMark index into sttbRMark
5561 {NS_sprm::v6::sprmCDttmRMark
, nullptr}, // chp.dttm DTTM long
5562 {NS_sprm::v6::sprmCFData
, nullptr}, // chp.fData 1 or 0 bit
5563 {NS_sprm::v6::sprmCRMReason
, nullptr}, // chp.idslRMReason an index to a table
5564 {NS_sprm::v6::sprmCChse
, &SwWW8ImplReader::Read_CharSet
}, // chp.fChsDiff and chp.chse 3 bytes
5565 {NS_sprm::v6::sprmCSymbol
, &SwWW8ImplReader::Read_Symbol
}, // chp.fSpec, chp.chSym and chp.ftcSym
5566 {NS_sprm::v6::sprmCFOle2
, &SwWW8ImplReader::Read_Obj
}, // chp.fOle2 1 or 0 bit
5567 {76, nullptr}, //"??76",
5568 {77, nullptr}, //"??77",
5569 {78, nullptr}, //"??78",
5570 {79, nullptr}, //"??79",
5571 {NS_sprm::v6::sprmCIstd
, &SwWW8ImplReader::Read_CColl
}, // chp.istd istd, see stylesheet definition; short
5572 {NS_sprm::v6::sprmCIstdPermute
, nullptr}, // chp.istd permutation vector
5573 {NS_sprm::v6::sprmCDefault
, nullptr}, // whole CHP none variable length
5574 {NS_sprm::v6::sprmCPlain
, nullptr}, // whole CHP none 0
5575 {84, nullptr}, //"??84",
5576 {NS_sprm::v6::sprmCFBold
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fBold 0,1, 128, or 129 byte
5577 {NS_sprm::v6::sprmCFItalic
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fItalic 0,1, 128, or 129 byte
5578 {NS_sprm::v6::sprmCFStrike
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fStrike 0,1, 128, or 129 byte
5579 {NS_sprm::v6::sprmCFOutline
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fOutline 0,1, 128, or 129 byte
5580 {NS_sprm::v6::sprmCFShadow
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fShadow 0,1, 128, or 129 byte
5581 {NS_sprm::v6::sprmCFSmallCaps
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fSmallCaps 0,1, 128, or 129 byte
5582 {NS_sprm::v6::sprmCFCaps
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fCaps 0,1, 128, or 129 byte
5583 {NS_sprm::v6::sprmCFVanish
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fVanish 0,1, 128, or 129 byte
5584 {NS_sprm::v6::sprmCFtc
, &SwWW8ImplReader::Read_FontCode
}, // chp.ftc ftc word
5585 {NS_sprm::v6::sprmCKul
, &SwWW8ImplReader::Read_Underline
}, // chp.kul kul byte
5586 {NS_sprm::v6::sprmCSizePos
, nullptr}, // chp.hps, chp.hpsPos 3 bytes
5587 {NS_sprm::v6::sprmCDxaSpace
, &SwWW8ImplReader::Read_Kern
}, // chp.dxaSpace dxa word
5588 {NS_sprm::v6::sprmCLid
, &SwWW8ImplReader::Read_Language
}, // chp.lid LID word
5589 {NS_sprm::v6::sprmCIco
, &SwWW8ImplReader::Read_TextColor
}, // chp.ico ico byte
5590 {NS_sprm::v6::sprmCHps
, &SwWW8ImplReader::Read_FontSize
}, // chp.hps hps word!
5591 {NS_sprm::v6::sprmCHpsInc
, nullptr}, // chp.hps byte
5592 {NS_sprm::v6::sprmCHpsPos
, &SwWW8ImplReader::Read_SubSuperProp
}, // chp.hpsPos hps byte
5593 {NS_sprm::v6::sprmCHpsPosAdj
, nullptr}, // chp.hpsPos hps byte
5594 {NS_sprm::v6::sprmCMajority
, &SwWW8ImplReader::Read_Majority
}, // chp.fBold, chp.fItalic, chp.fSmallCaps
5595 {NS_sprm::v6::sprmCIss
, &SwWW8ImplReader::Read_SubSuper
}, // chp.iss iss byte
5596 {NS_sprm::v6::sprmCHpsNew50
, nullptr}, // chp.hps hps variable width, length always recorded as 2
5597 {NS_sprm::v6::sprmCHpsInc1
, nullptr}, // chp.hps complex variable width, length always recorded as 2
5598 {NS_sprm::v6::sprmCHpsKern
, &SwWW8ImplReader::Read_FontKern
}, // chp.hpsKern hps short
5599 {NS_sprm::v6::sprmCMajority50
, &SwWW8ImplReader::Read_Majority
}, // chp.fBold, chp.fItalic, chp.fSmallCaps, chp.fVanish, ...
5600 {NS_sprm::v6::sprmCHpsMul
, nullptr}, // chp.hps percentage to grow hps short
5601 {NS_sprm::v6::sprmCCondHyhen
, nullptr}, // chp.ysri ysri short
5602 {111, &SwWW8ImplReader::Read_AmbiguousSPRM
},//sprmCFBoldBi or font code
5603 {112, &SwWW8ImplReader::Read_AmbiguousSPRM
},//sprmCFItalicBi or font code
5604 {113, &SwWW8ImplReader::Read_FontCode
}, //sprmCFtcBi
5605 {114, &SwWW8ImplReader::Read_Language
}, //sprmClidBi
5606 {115, &SwWW8ImplReader::Read_TextColor
}, //sprmCIcoBi
5607 {116, &SwWW8ImplReader::Read_FontSize
}, //sprmCHpsBi
5608 {NS_sprm::v6::sprmCFSpec
, &SwWW8ImplReader::Read_Special
}, // chp.fSpec 1 or 0 bit
5609 {NS_sprm::v6::sprmCFObj
, &SwWW8ImplReader::Read_Obj
}, // chp.fObj 1 or 0 bit
5610 {NS_sprm::v6::sprmPicBrcl
, nullptr}, // pic.brcl brcl (see PIC structure definition) byte
5611 {NS_sprm::v6::sprmPicScale
, nullptr}, // pic.mx, pic.my, pic.dxaCropleft,
5612 {NS_sprm::v6::sprmPicBrcTop
, nullptr}, // pic.brcTop BRC word
5613 {NS_sprm::v6::sprmPicBrcLeft
, nullptr}, // pic.brcLeft BRC word
5614 {NS_sprm::v6::sprmPicBrcBottom
, nullptr}, // pic.brcBottom BRC word
5615 {NS_sprm::v6::sprmPicBrcRight
, nullptr}, // pic.brcRight BRC word
5616 {125, nullptr}, //"??125",
5617 {126, nullptr}, //"??126",
5618 {127, nullptr}, //"??127",
5619 {128, nullptr}, //"??128",
5620 {129, nullptr}, //"??129",
5621 {130, nullptr}, //"??130",
5622 {NS_sprm::v6::sprmSScnsPgn
, nullptr}, // sep.cnsPgn cns byte
5623 {NS_sprm::v6::sprmSiHeadingPgn
, nullptr}, // sep.iHeadingPgn heading number level byte
5624 {NS_sprm::v6::sprmSOlstAnm
, &SwWW8ImplReader::Read_OLST
}, // sep.olstAnm OLST variable length
5625 {134, nullptr}, //"??135",
5626 {135, nullptr}, //"??135",
5627 {NS_sprm::v6::sprmSDxaColWidth
, nullptr}, // sep.rgdxaColWidthSpacing complex 3 bytes
5628 {NS_sprm::v6::sprmSDxaColSpacing
, nullptr}, // sep.rgdxaColWidthSpacing complex 3 bytes
5629 {NS_sprm::v6::sprmSFEvenlySpaced
, nullptr}, // sep.fEvenlySpaced 1 or 0 byte
5630 {NS_sprm::v6::sprmSFProtected
, nullptr}, // sep.fUnlocked 1 or 0 byte
5631 {NS_sprm::v6::sprmSDmBinFirst
, nullptr}, // sep.dmBinFirst word
5632 {NS_sprm::v6::sprmSDmBinOther
, nullptr}, // sep.dmBinOther word
5633 {NS_sprm::v6::sprmSBkc
, nullptr}, // sep.bkc bkc byte BreakCode
5634 {NS_sprm::v6::sprmSFTitlePage
, nullptr}, // sep.fTitlePage 0 or 1 byte
5635 {NS_sprm::v6::sprmSCcolumns
, nullptr}, // sep.ccolM1 # of cols - 1 word
5636 {NS_sprm::v6::sprmSDxaColumns
, nullptr}, // sep.dxaColumns dxa word
5637 {NS_sprm::v6::sprmSFAutoPgn
, nullptr}, // sep.fAutoPgn obsolete byte
5638 {NS_sprm::v6::sprmSNfcPgn
, nullptr}, // sep.nfcPgn nfc byte
5639 {NS_sprm::v6::sprmSDyaPgn
, nullptr}, // sep.dyaPgn dya short
5640 {NS_sprm::v6::sprmSDxaPgn
, nullptr}, // sep.dxaPgn dya short
5641 {NS_sprm::v6::sprmSFPgnRestart
, nullptr}, // sep.fPgnRestart 0 or 1 byte
5642 {NS_sprm::v6::sprmSFEndnote
, nullptr}, // sep.fEndnote 0 or 1 byte
5643 {NS_sprm::v6::sprmSLnc
, nullptr}, // sep.lnc lnc byte
5644 {NS_sprm::v6::sprmSGprfIhdt
, nullptr}, // sep.grpfIhdt grpfihdt byte
5645 {NS_sprm::v6::sprmSNLnnMod
, nullptr}, // sep.nLnnMod non-neg int. word
5646 {NS_sprm::v6::sprmSDxaLnn
, nullptr}, // sep.dxaLnn dxa word
5647 {NS_sprm::v6::sprmSDyaHdrTop
, nullptr}, // sep.dyaHdrTop dya word
5648 {NS_sprm::v6::sprmSDyaHdrBottom
, nullptr}, // sep.dyaHdrBottom dya word
5649 {NS_sprm::v6::sprmSLBetween
, nullptr}, // sep.fLBetween 0 or 1 byte
5650 {NS_sprm::v6::sprmSVjc
, nullptr}, // sep.vjc vjc byte
5651 {NS_sprm::v6::sprmSLnnMin
, nullptr}, // sep.lnnMin lnn word
5652 {NS_sprm::v6::sprmSPgnStart
, nullptr}, // sep.pgnStart pgn word
5653 {NS_sprm::v6::sprmSBOrientation
, nullptr}, // sep.dmOrientPage dm byte
5654 {NS_sprm::v6::sprmSBCustomize
, nullptr}, // ?
5655 {NS_sprm::v6::sprmSXaPage
, nullptr}, // sep.xaPage xa word
5656 {NS_sprm::v6::sprmSYaPage
, nullptr}, // sep.yaPage ya word
5657 {NS_sprm::v6::sprmSDxaLeft
, nullptr}, // sep.dxaLeft dxa word
5658 {NS_sprm::v6::sprmSDxaRight
, nullptr}, // sep.dxaRight dxa word
5659 {NS_sprm::v6::sprmSDyaTop
, nullptr}, // sep.dyaTop dya word
5660 {NS_sprm::v6::sprmSDyaBottom
, nullptr}, // sep.dyaBottom dya word
5661 {NS_sprm::v6::sprmSDzaGutter
, nullptr}, // sep.dzaGutter dza word
5662 {NS_sprm::v6::sprmSDMPaperReq
, nullptr}, // sep.dmPaperReq dm word
5663 {172, nullptr}, //"??172",
5664 {173, nullptr}, //"??173",
5665 {174, nullptr}, //"??174",
5666 {175, nullptr}, //"??175",
5667 {176, nullptr}, //"??176",
5668 {177, nullptr}, //"??177",
5669 {178, nullptr}, //"??178",
5670 {179, nullptr}, //"??179",
5671 {180, nullptr}, //"??180",
5672 {181, nullptr}, //"??181",
5673 {NS_sprm::v6::sprmTJc
, nullptr}, // tap.jc jc word (low order byte is significant)
5674 {NS_sprm::v6::sprmTDxaLeft
, nullptr}, // tap.rgdxaCenter dxa word
5675 {NS_sprm::v6::sprmTDxaGapHalf
, nullptr}, // tap.dxaGapHalf, tap.rgdxaCenter dxa word
5676 {NS_sprm::v6::sprmTFCantSplit
, nullptr}, // tap.fCantSplit 1 or 0 byte
5677 {NS_sprm::v6::sprmTTableHeader
, nullptr}, // tap.fTableHeader 1 or 0 byte
5678 {NS_sprm::v6::sprmTTableBorders
, nullptr}, // tap.rgbrcTable complex 12 bytes
5679 {NS_sprm::v6::sprmTDefTable10
, nullptr}, // tap.rgdxaCenter, tap.rgtc complex variable length
5680 {NS_sprm::v6::sprmTDyaRowHeight
, nullptr}, // tap.dyaRowHeight dya word
5681 {NS_sprm::v6::sprmTDefTable
, nullptr}, // tap.rgtc complex
5682 {NS_sprm::v6::sprmTDefTableShd
, nullptr}, // tap.rgshd complex
5683 {NS_sprm::v6::sprmTTlp
, nullptr}, // tap.tlp TLP 4 bytes
5684 {NS_sprm::v6::sprmTSetBrc
, nullptr}, // tap.rgtc[].rgbrc complex 5 bytes
5685 {NS_sprm::v6::sprmTInsert
, nullptr}, // tap.rgdxaCenter, tap.rgtc complex 4 bytes
5686 {NS_sprm::v6::sprmTDelete
, nullptr}, // tap.rgdxaCenter, tap.rgtc complex word
5687 {NS_sprm::v6::sprmTDxaCol
, nullptr}, // tap.rgdxaCenter complex 4 bytes
5688 {NS_sprm::v6::sprmTMerge
, nullptr}, // tap.fFirstMerged, tap.fMerged complex word
5689 {NS_sprm::v6::sprmTSplit
, nullptr}, // tap.fFirstMerged, tap.fMerged complex word
5690 {NS_sprm::v6::sprmTSetBrc10
, nullptr}, // tap.rgtc[].rgbrc complex 5 bytes
5691 {NS_sprm::v6::sprmTSetShd
, nullptr}, // tap.rgshd complex 4 bytes
5692 {207, nullptr}, //dunno
5695 static wwSprmDispatcher
aSprmSrch(aSprms
, SAL_N_ELEMENTS(aSprms
));
5699 static const wwSprmDispatcher
*GetWW8SprmDispatcher()
5701 static SprmReadInfo aSprms
[] =
5703 {0, nullptr}, // "0" default resp. error
5705 {NS_sprm::PIstd::val
, &SwWW8ImplReader::Read_StyleCode
}, // pap.istd;istd (style code);short;
5706 {NS_sprm::PIstdPermute::val
, nullptr}, // pap.istd;permutation vector;
5708 {NS_sprm::PIncLvl::val
, nullptr}, // pap.istd, pap.lvl;difference between
5709 // istd of base PAP and istd of
5710 // PAP to be produced;byte;
5711 {NS_sprm::PJc80::val
, &SwWW8ImplReader::Read_Justify
}, // pap.jc;jc (justification);byte;
5712 {NS_sprm::LN_PFSideBySide
, nullptr}, // pap.fSideBySide;0 or 1;byte;
5713 {NS_sprm::PFKeep::val
, &SwWW8ImplReader::Read_KeepLines
}, // pap.fKeep;0 or 1;byte;
5714 {NS_sprm::PFKeepFollow::val
, &SwWW8ImplReader::Read_KeepParas
}, // pap.fKeepFollow;0 or 1;byte;
5715 {NS_sprm::PFPageBreakBefore::val
, &SwWW8ImplReader::Read_BreakBefore
}, // pap.fPageBreakBefore;0 or 1;byte;
5716 {NS_sprm::LN_PBrcl
, nullptr}, // pap.brcl;brcl;byte;
5717 {NS_sprm::LN_PBrcp
, nullptr}, // pap.brcp;brcp;byte;
5718 {NS_sprm::PIlvl::val
, &SwWW8ImplReader::Read_ListLevel
}, // pap.ilvl;ilvl;byte;
5719 {NS_sprm::PIlfo::val
, &SwWW8ImplReader::Read_LFOPosition
}, // pap.ilfo;ilfo (list index);short;
5720 {NS_sprm::PFNoLineNumb::val
, &SwWW8ImplReader::Read_NoLineNumb
}, // pap.fNoLnn;0 or 1;byte;
5721 {NS_sprm::PChgTabsPapx::val
, &SwWW8ImplReader::Read_Tab
}, // pap.itbdMac, pap.rgdxaTab, pap.rgtbd;
5722 // complex;variable length
5723 {NS_sprm::PDxaRight80::val
, &SwWW8ImplReader::Read_LR
}, // pap.dxaRight;dxa;word;
5724 {NS_sprm::PDxaLeft80::val
, &SwWW8ImplReader::Read_LR
}, // pap.dxaLeft;dxa;word;
5725 {NS_sprm::PNest80::val
, nullptr}, // pap.dxaLeft;dxa;word;
5726 {NS_sprm::PDxaLeft180::val
, &SwWW8ImplReader::Read_LR
}, // pap.dxaLeft1;dxa;word;
5727 {NS_sprm::PDyaLine::val
, &SwWW8ImplReader::Read_LineSpace
}, // pap.lspd;an LSPD, a long word
5728 // structure consisting of a short
5729 // of dyaLine followed by a short
5730 // of fMultLinespace;long;
5731 {NS_sprm::PDyaBefore::val
, &SwWW8ImplReader::Read_UL
}, // pap.dyaBefore;dya;word;
5732 {NS_sprm::PDyaAfter::val
, &SwWW8ImplReader::Read_UL
}, // pap.dyaAfter;dya;word;
5733 {NS_sprm::PChgTabs::val
, nullptr}, // pap.itbdMac, pap.rgdxaTab, pap.rgtbd;
5734 // complex;variable length;
5735 {NS_sprm::PFInTable::val
, nullptr}, // pap.fInTable;0 or 1;byte;
5736 {NS_sprm::PFTtp::val
, &SwWW8ImplReader::Read_TabRowEnd
}, // pap.fTtp;0 or 1;byte;
5737 {NS_sprm::PDxaAbs::val
, nullptr}, // pap.dxaAbs;dxa;word;
5738 {NS_sprm::PDyaAbs::val
, nullptr}, // pap.dyaAbs;dya;word;
5739 {NS_sprm::PDxaWidth::val
, nullptr}, // pap.dxaWidth;dxa;word;
5740 {NS_sprm::PPc::val
, &SwWW8ImplReader::Read_ApoPPC
}, // pap.pcHorz, pap.pcVert;complex;byte;
5741 {NS_sprm::LN_PBrcTop10
, nullptr}, // pap.brcTop;BRC10;word;
5742 {NS_sprm::LN_PBrcLeft10
, nullptr}, // pap.brcLeft;BRC10;word;
5743 {NS_sprm::LN_PBrcBottom10
, nullptr}, // pap.brcBottom;BRC10;word;
5744 {NS_sprm::LN_PBrcRight10
, nullptr}, // pap.brcRight;BRC10;word;
5745 {NS_sprm::LN_PBrcBetween10
, nullptr}, // pap.brcBetween;BRC10;word;
5746 {NS_sprm::LN_PBrcBar10
, nullptr}, // pap.brcBar;BRC10;word;
5747 {NS_sprm::LN_PDxaFromText10
, nullptr}, // pap.dxaFromText;dxa;word;
5748 {NS_sprm::PWr::val
, nullptr}, // pap.wr;wr;byte;
5749 {NS_sprm::PBrcTop80::val
, &SwWW8ImplReader::Read_Border
}, // pap.brcTop;BRC;long;
5750 {NS_sprm::PBrcLeft80::val
, &SwWW8ImplReader::Read_Border
}, // pap.brcLeft;BRC;long;
5751 {NS_sprm::PBrcBottom80::val
, &SwWW8ImplReader::Read_Border
}, // pap.brcBottom;BRC;long;
5752 {NS_sprm::PBrcRight80::val
, &SwWW8ImplReader::Read_Border
}, // pap.brcRight;BRC;long;
5753 {NS_sprm::PBrcBetween80::val
, &SwWW8ImplReader::Read_Border
}, // pap.brcBetween;BRC;long;
5754 {NS_sprm::PBrcBar80::val
, nullptr}, // pap.brcBar;BRC;long;
5755 {NS_sprm::PFNoAutoHyph::val
, &SwWW8ImplReader::Read_Hyphenation
}, // pap.fNoAutoHyph;0 or 1;byte;
5756 {NS_sprm::PWHeightAbs::val
, nullptr}, // pap.wHeightAbs;w;word;
5757 {NS_sprm::PDcs::val
, nullptr}, // pap.dcs;DCS;short;
5758 {NS_sprm::PShd80::val
, &SwWW8ImplReader::Read_Shade
}, // pap.shd;SHD;word;
5759 {NS_sprm::PDyaFromText::val
, nullptr}, // pap.dyaFromText;dya;word;
5760 {NS_sprm::PDxaFromText::val
, nullptr}, // pap.dxaFromText;dxa;word;
5761 {NS_sprm::PFLocked::val
, nullptr}, // pap.fLocked;0 or 1;byte;
5762 {NS_sprm::PFWidowControl::val
, &SwWW8ImplReader::Read_WidowControl
}, // pap.fWidowControl;0 or 1;byte
5763 {NS_sprm::LN_PRuler
, nullptr}, // variable length;
5764 {NS_sprm::PFKinsoku::val
, &SwWW8ImplReader::Read_BoolItem
}, // pap.fKinsoku;0 or 1;byte;
5765 {NS_sprm::PFWordWrap::val
, nullptr}, // pap.fWordWrap;0 or 1;byte;
5766 {NS_sprm::PFOverflowPunct::val
, &SwWW8ImplReader::Read_BoolItem
}, // pap.fOverflowPunct; 0 or 1;byte;
5767 {NS_sprm::PFTopLinePunct::val
, nullptr}, // pap.fTopLinePunct;0 or 1;byte
5768 {NS_sprm::PFAutoSpaceDE::val
, &SwWW8ImplReader::Read_BoolItem
}, // pap.fAutoSpaceDE;0 or 1;byte;
5769 {NS_sprm::PFAutoSpaceDN::val
, nullptr}, // pap.fAutoSpaceDN;0 or 1;byte;
5770 {NS_sprm::PWAlignFont::val
, &SwWW8ImplReader::Read_AlignFont
}, // pap.wAlignFont;iFa;word;
5771 {NS_sprm::PFrameTextFlow::val
, nullptr}, // pap.fVertical pap.fBackward
5772 // pap.fRotateFont;complex; word
5773 {NS_sprm::LN_PISnapBaseLine
, nullptr}, // obsolete, not applicable in
5774 // Word97 and later versions;;byte;
5775 {NS_sprm::LN_PAnld
, &SwWW8ImplReader::Read_ANLevelDesc
}, // pap.anld;;variable length;
5776 {NS_sprm::LN_PPropRMark
, nullptr}, // pap.fPropRMark;complex;
5778 {NS_sprm::POutLvl::val
, &SwWW8ImplReader::Read_POutLvl
}, // pap.lvl;has no effect if pap.istd
5779 // is < 1 or is > 9;byte;
5780 {NS_sprm::PFBiDi::val
, &SwWW8ImplReader::Read_ParaBiDi
}, // ;;byte;
5781 {NS_sprm::PFNumRMIns::val
, nullptr}, // pap.fNumRMIns;1 or 0;bit;
5782 {NS_sprm::LN_PCrLf
, nullptr}, // ;;byte;
5783 {NS_sprm::PNumRM::val
, nullptr}, // pap.numrm;;variable length;
5784 {NS_sprm::LN_PHugePapx
, nullptr}, // ;fc in the data stream to locate
5785 // the huge grpprl;long;
5786 {NS_sprm::PHugePapx::val
, nullptr}, // ;fc in the data stream to locate
5787 // the huge grpprl;long;
5788 {NS_sprm::PFUsePgsuSettings::val
, &SwWW8ImplReader::Read_UsePgsuSettings
}, // pap.fUsePgsuSettings;1 or 0;byte;
5789 {NS_sprm::PFAdjustRight::val
, nullptr}, // pap.fAdjustRight;1 or 0;byte;
5790 {NS_sprm::CFRMarkDel::val
, &SwWW8ImplReader::Read_CFRMarkDel
}, // chp.fRMarkDel;1 or 0;bit;
5791 {NS_sprm::CFRMarkIns::val
, &SwWW8ImplReader::Read_CFRMark
}, // chp.fRMark;1 or 0;bit;
5792 {NS_sprm::CFFldVanish::val
, &SwWW8ImplReader::Read_FieldVanish
}, // chp.fFieldVanish;1 or 0;bit;
5793 {NS_sprm::CPicLocation::val
, &SwWW8ImplReader::Read_PicLoc
}, // chp.fcPic and chp.fSpec;variable
5794 // length, length recorded is always 4;
5795 {NS_sprm::CIbstRMark::val
, nullptr}, // chp.ibstRMark;index into
5797 {NS_sprm::CDttmRMark::val
, nullptr}, // chp.dttmRMark;DTTM;long;
5798 {NS_sprm::CFData::val
, nullptr}, // chp.fData;1 or 0;bit;
5799 {NS_sprm::CIdslRMark::val
, nullptr}, // chp.idslRMReason;an index to
5800 // a table of strings defined in
5801 // Word 6.0 executables;short;
5802 {NS_sprm::LN_CChs
, &SwWW8ImplReader::Read_CharSet
}, // chp.fChsDiff and chp.chse;3 bytes;
5803 {NS_sprm::CSymbol::val
, &SwWW8ImplReader::Read_Symbol
}, // chp.fSpec, chp.xchSym and chp.ftcSym;
5804 // variable length, length
5805 // recorded is always 4;
5806 {NS_sprm::CFOle2::val
, &SwWW8ImplReader::Read_Obj
}, // chp.fOle2;1 or 0;bit;
5807 //NS_sprm::LN_CIdCharType, // obsolete: not applicable in Word97
5808 // and later versions
5809 {NS_sprm::CHighlight::val
, &SwWW8ImplReader::Read_CharHighlight
}, // chp.fHighlight, chp.icoHighlight;ico
5810 // (fHighlight is set to 1 iff
5811 // ico is not 0);byte;
5812 {NS_sprm::LN_CObjLocation
, &SwWW8ImplReader::Read_PicLoc
}, // chp.fcObj;FC;long;
5813 //NS_sprm::LN_CFFtcAsciSymb, ? ? ?,
5814 {NS_sprm::CIstd::val
, &SwWW8ImplReader::Read_CColl
}, // chp.istd;istd,short;
5815 {NS_sprm::CIstdPermute::val
, nullptr}, // chp.istd;permutation vector;
5817 {NS_sprm::LN_CDefault
, nullptr}, // whole CHP;none;variable length;
5818 {NS_sprm::CPlain::val
, nullptr}, // whole CHP;none;length: 0;
5819 {NS_sprm::CKcd::val
, &SwWW8ImplReader::Read_Emphasis
},
5820 {NS_sprm::CFBold::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fBold;0,1, 128, or 129;byte;
5821 {NS_sprm::CFItalic::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fItalic;0,1, 128, or 129; byte;
5822 {NS_sprm::CFStrike::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fStrike;0,1, 128, or 129; byte;
5823 {NS_sprm::CFOutline::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fOutline;0,1, 128, or 129; byte;
5824 {NS_sprm::CFShadow::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fShadow;0,1, 128, or 129; byte;
5825 {NS_sprm::CFSmallCaps::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fSmallCaps;0,1, 128, or 129;byte;
5826 {NS_sprm::CFCaps::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fCaps;0,1, 128, or 129; byte;
5827 {NS_sprm::CFVanish::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fVanish;0,1, 128, or 129; byte;
5828 //NS_sprm::LN_CFtcDefault, 0, // ftc, only used internally, never
5829 // stored in file;word;
5830 {NS_sprm::CKul::val
, &SwWW8ImplReader::Read_Underline
}, // chp.kul;kul;byte;
5831 {NS_sprm::LN_CSizePos
, nullptr}, // chp.hps, chp.hpsPos;3 bytes;
5832 {NS_sprm::CDxaSpace::val
, &SwWW8ImplReader::Read_Kern
}, // chp.dxaSpace;dxa;word;
5833 {NS_sprm::LN_CLid
, &SwWW8ImplReader::Read_Language
}, // ;only used internally, never stored;
5835 {NS_sprm::CIco::val
, &SwWW8ImplReader::Read_TextColor
}, // chp.ico;ico;byte;
5836 {NS_sprm::CHps::val
, &SwWW8ImplReader::Read_FontSize
}, // chp.hps;hps;byte;
5837 {NS_sprm::LN_CHpsInc
, nullptr}, // chp.hps;byte;
5838 {NS_sprm::CHpsPos::val
, &SwWW8ImplReader::Read_SubSuperProp
}, // chp.hpsPos;hps;byte;
5839 {NS_sprm::LN_CHpsPosAdj
, nullptr}, // chp.hpsPos;hps;byte;
5840 {NS_sprm::CMajority::val
, &SwWW8ImplReader::Read_Majority
}, // chp.fBold, chp.fItalic, chp.fStrike,
5841 // chp.fSmallCaps, chp.fVanish, chp.fCaps,
5842 // chp.hps, chp.hpsPos, chp.dxaSpace,
5843 // chp.kul, chp.ico, chp.rgftc, chp.rglid;
5844 // complex;variable length, length byte
5845 // plus size of following grpprl;
5846 {NS_sprm::CIss::val
, &SwWW8ImplReader::Read_SubSuper
}, // chp.iss;iss;byte;
5847 {NS_sprm::LN_CHpsNew50
, nullptr}, // chp.hps;hps;variable width, length
5848 // always recorded as 2;
5849 {NS_sprm::LN_CHpsInc1
, nullptr}, // chp.hps;complex; variable width,
5850 // length always recorded as 2;
5851 {NS_sprm::CHpsKern::val
, &SwWW8ImplReader::Read_FontKern
}, // chp.hpsKern;hps;short;
5852 {NS_sprm::LN_CMajority50
, &SwWW8ImplReader::Read_Majority
}, // chp.fBold, chp.fItalic, chp.fStrike,
5853 // chp.fSmallCaps, chp.fVanish, chp.fCaps,
5854 // chp.ftc, chp.hps, chp.hpsPos, chp.kul,
5855 // chp.dxaSpace, chp.ico;complex;
5857 {NS_sprm::LN_CHpsMul
, nullptr}, // chp.hps;percentage to grow hps;short;
5858 {NS_sprm::CHresi::val
, nullptr}, // ???? "sprmCYsri" chp.ysri;ysri;short;
5859 {NS_sprm::CRgFtc0::val
, &SwWW8ImplReader::Read_FontCode
}, // chp.rgftc[0];ftc for ASCII text;short;
5860 {NS_sprm::CRgFtc1::val
, &SwWW8ImplReader::Read_FontCode
}, // chp.rgftc[1];ftc for Far East text;
5862 {NS_sprm::CRgFtc2::val
, &SwWW8ImplReader::Read_FontCode
}, // chp.rgftc[2];ftc for non-Far East text;
5864 {NS_sprm::CCharScale::val
, &SwWW8ImplReader::Read_ScaleWidth
},
5865 {NS_sprm::CFDStrike::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fDStrike;;byte;
5866 {NS_sprm::CFImprint::val
, &SwWW8ImplReader::Read_Relief
}, // chp.fImprint;1 or 0;bit;
5867 {NS_sprm::CFSpec::val
, &SwWW8ImplReader::Read_Special
}, // chp.fSpec;1 or 0;bit;
5868 {NS_sprm::CFObj::val
, &SwWW8ImplReader::Read_Obj
}, // chp.fObj;1 or 0;bit;
5869 {NS_sprm::CPropRMark90::val
, &SwWW8ImplReader::Read_CPropRMark
}, // chp.fPropRMark, chp.ibstPropRMark,
5870 // chp.dttmPropRMark;Complex;variable
5871 // length always recorded as 7 bytes;
5872 {NS_sprm::CFEmboss::val
, &SwWW8ImplReader::Read_Relief
}, // chp.fEmboss;1 or 0;bit;
5873 {NS_sprm::CSfxText::val
, &SwWW8ImplReader::Read_TextAnim
}, // chp.sfxtText;text animation;byte;
5874 {NS_sprm::CFBiDi::val
, &SwWW8ImplReader::Read_Bidi
},
5875 {NS_sprm::LN_CFDiacColor
, nullptr},
5876 {NS_sprm::CFBoldBi::val
, &SwWW8ImplReader::Read_BoldBiDiUsw
},
5877 {NS_sprm::CFItalicBi::val
, &SwWW8ImplReader::Read_BoldBiDiUsw
},
5878 {NS_sprm::CFtcBi::val
, &SwWW8ImplReader::Read_FontCode
},
5879 {NS_sprm::CLidBi::val
, &SwWW8ImplReader::Read_Language
},
5880 //NS_sprm::CIcoBi::val, ? ? ?,
5881 {NS_sprm::CHpsBi::val
, &SwWW8ImplReader::Read_FontSize
},
5882 {NS_sprm::CDispFldRMark::val
, nullptr}, // chp.fDispFieldRMark,
5883 // chp.ibstDispFieldRMark,
5884 // chp.dttmDispFieldRMark;
5885 // Complex;variable length
5886 // always recorded as 39 bytes;
5887 {NS_sprm::CIbstRMarkDel::val
, nullptr}, // chp.ibstRMarkDel;index into
5889 {NS_sprm::CDttmRMarkDel::val
, nullptr}, // chp.dttmRMarkDel;DTTM;long;
5890 {NS_sprm::CBrc80::val
, &SwWW8ImplReader::Read_CharBorder
}, // chp.brc;BRC;long;
5891 {NS_sprm::CBrc::val
, &SwWW8ImplReader::Read_CharBorder
}, // chp.brc;BRC;long;
5892 {NS_sprm::CShd80::val
, &SwWW8ImplReader::Read_CharShadow
}, // chp.shd;SHD;short;
5893 {NS_sprm::CIdslRMarkDel::val
, nullptr}, // chp.idslRMReasonDel;an index to
5894 // a table of strings defined in
5895 // Word 6.0 executables;short;
5896 {NS_sprm::CFUsePgsuSettings::val
, nullptr}, // chp.fUsePgsuSettings; 1 or 0;bit;
5897 {NS_sprm::LN_CCpg
, nullptr}, // ;;word;
5898 {NS_sprm::CRgLid0_80::val
, &SwWW8ImplReader::Read_Language
}, // chp.rglid[0];
5899 // LID: for non-Far East text;word;
5900 {NS_sprm::CRgLid1_80::val
, &SwWW8ImplReader::Read_Language
}, // chp.rglid[1];
5901 // LID: for Far East text;word;
5902 {NS_sprm::CIdctHint::val
, &SwWW8ImplReader::Read_IdctHint
}, // chp.idctHint;IDCT: byte;
5903 {NS_sprm::LN_PicBrcl
, nullptr}, // pic.brcl;brcl (see PIC structure
5904 // definition);byte;
5905 {NS_sprm::LN_PicScale
, nullptr}, // pic.mx, pic.my, pic.dxaCropleft,
5906 // pic.dyaCropTop pic.dxaCropRight,
5907 // pic.dyaCropBottom;Complex;
5908 // length byte plus 12 bytes;
5909 {NS_sprm::PicBrcTop80::val
, nullptr}, // pic.brcTop;BRC;long;
5910 {NS_sprm::PicBrcLeft80::val
, nullptr}, // pic.brcLeft;BRC;long;
5911 {NS_sprm::PicBrcBottom80::val
, nullptr}, // pic.brcBottom;BRC;long;
5912 {NS_sprm::PicBrcRight80::val
, nullptr}, // pic.brcRight;BRC;long;
5913 {NS_sprm::ScnsPgn::val
, nullptr}, // sep.cnsPgn;cns;byte;
5914 {NS_sprm::SiHeadingPgn::val
, nullptr}, // sep.iHeadingPgn;heading number level;
5916 {NS_sprm::LN_SOlstAnm
, &SwWW8ImplReader::Read_OLST
}, // sep.olstAnm;OLST;variable length;
5917 {NS_sprm::SDxaColWidth::val
, nullptr}, // sep.rgdxaColWidthSpacing;complex;
5919 {NS_sprm::SDxaColSpacing::val
, nullptr}, // sep.rgdxaColWidthSpacing;complex;
5921 {NS_sprm::SFEvenlySpaced::val
, nullptr}, // sep.fEvenlySpaced; 1 or 0;byte;
5922 {NS_sprm::SFProtected::val
, nullptr}, // sep.fUnlocked;1 or 0;byte;
5923 {NS_sprm::SDmBinFirst::val
, nullptr}, // sep.dmBinFirst;;word;
5924 {NS_sprm::SDmBinOther::val
, nullptr}, // sep.dmBinOther;;word;
5925 {NS_sprm::SBkc::val
, nullptr}, // sep.bkc;bkc;byte;
5926 {NS_sprm::SFTitlePage::val
, nullptr}, // sep.fTitlePage;0 or 1;byte;
5927 {NS_sprm::SCcolumns::val
, nullptr}, // sep.ccolM1;# of cols - 1;word;
5928 {NS_sprm::SDxaColumns::val
, nullptr}, // sep.dxaColumns;dxa;word;
5929 {NS_sprm::LN_SFAutoPgn
, nullptr}, // sep.fAutoPgn;obsolete;byte;
5930 {NS_sprm::SNfcPgn::val
, nullptr}, // sep.nfcPgn;nfc;byte;
5931 {NS_sprm::LN_SDyaPgn
, nullptr}, // sep.dyaPgn;dya;short;
5932 {NS_sprm::LN_SDxaPgn
, nullptr}, // sep.dxaPgn;dya;short;
5933 {NS_sprm::SFPgnRestart::val
, nullptr}, // sep.fPgnRestart;0 or 1;byte;
5934 {NS_sprm::SFEndnote::val
, nullptr}, // sep.fEndnote;0 or 1;byte;
5935 {NS_sprm::SLnc::val
, nullptr}, // sep.lnc;lnc;byte;
5936 {NS_sprm::LN_SGprfIhdt
, nullptr}, // sep.grpfIhdt;grpfihdt;byte;
5937 {NS_sprm::SNLnnMod::val
, nullptr}, // sep.nLnnMod;non-neg int.;word;
5938 {NS_sprm::SDxaLnn::val
, nullptr}, // sep.dxaLnn;dxa;word;
5939 {NS_sprm::SDyaHdrTop::val
, nullptr}, // sep.dyaHdrTop;dya;word;
5940 {NS_sprm::SDyaHdrBottom::val
, nullptr}, // sep.dyaHdrBottom;dya;word;
5941 {NS_sprm::SLBetween::val
, nullptr}, // sep.fLBetween;0 or 1;byte;
5942 {NS_sprm::SVjc::val
, &SwWW8ImplReader::Read_TextVerticalAdjustment
}, // sep.vjc;vjc;byte;
5943 {NS_sprm::SLnnMin::val
, nullptr}, // sep.lnnMin;lnn;word;
5944 {NS_sprm::SPgnStart97::val
, nullptr}, // sep.pgnStart;pgn;word;
5945 {NS_sprm::SBOrientation::val
, nullptr}, // sep.dmOrientPage;dm;byte;
5946 //NS_sprm::LN_SBCustomize, ? ? ?,
5947 {NS_sprm::SXaPage::val
, nullptr}, // sep.xaPage;xa;word;
5948 {NS_sprm::SYaPage::val
, nullptr}, // sep.yaPage;ya;word;
5949 {0x2205, nullptr}, // ???? "sprmSDxaLeft" sep.dxaLeft;
5951 {NS_sprm::SDxaLeft::val
, nullptr}, // sep.dxaLeft;dxa;word;
5952 {NS_sprm::SDxaRight::val
, nullptr}, // sep.dxaRight;dxa;word;
5953 {NS_sprm::SDyaTop::val
, nullptr}, // sep.dyaTop;dya;word;
5954 {NS_sprm::SDyaBottom::val
, nullptr}, // sep.dyaBottom;dya;word;
5955 {NS_sprm::SDzaGutter::val
, nullptr}, // sep.dzaGutter;dza;word;
5956 {NS_sprm::SDmPaperReq::val
, nullptr}, // sep.dmPaperReq;dm;word;
5957 {NS_sprm::LN_SPropRMark
, nullptr}, // sep.fPropRMark, sep.ibstPropRMark,
5958 // sep.dttmPropRMark;complex; variable
5959 // length always recorded as 7 bytes;
5960 //NS_sprm::SFBiDi::val, ? ? ?,
5961 //NS_sprm::LN_SFFacingCol, ? ? ?,
5962 {NS_sprm::SFRTLGutter::val
, nullptr}, // set to 1 if gutter is on the right.
5963 {NS_sprm::SBrcTop80::val
, nullptr}, // sep.brcTop;BRC;long;
5964 {NS_sprm::SBrcLeft80::val
, nullptr}, // sep.brcLeft;BRC;long;
5965 {NS_sprm::SBrcBottom80::val
, nullptr}, // sep.brcBottom;BRC;long;
5966 {NS_sprm::SBrcRight80::val
, nullptr}, // sep.brcRight;BRC;long;
5967 {NS_sprm::SPgbProp::val
, nullptr}, // sep.pgbProp;word;
5968 {NS_sprm::SDxtCharSpace::val
, nullptr}, // sep.dxtCharSpace;dxt;long;
5969 {NS_sprm::SDyaLinePitch::val
, nullptr}, // sep.dyaLinePitch;dya;
5970 // WRONG:long; RIGHT:short; !
5971 //NS_sprm::SClm::val, ? ? ?,
5972 {NS_sprm::STextFlow::val
, nullptr}, // sep.wTextFlow;complex;short
5973 {NS_sprm::TJc90::val
, nullptr}, // tap.jc;jc;word
5974 // (low order byte is significant);
5975 {NS_sprm::TDxaLeft::val
, nullptr}, // tap.rgdxaCenter;dxa;word;
5976 {NS_sprm::TDxaGapHalf::val
, nullptr}, // tap.dxaGapHalf,
5977 // tap.rgdxaCenter;dxa;word;
5978 {NS_sprm::TFCantSplit90::val
, nullptr}, // tap.fCantSplit90;1 or 0;byte;
5979 {NS_sprm::TTableHeader::val
, nullptr}, // tap.fTableHeader;1 or 0;byte;
5980 {NS_sprm::TFCantSplit::val
, nullptr}, // tap.fCantSplit;1 or 0;byte;
5981 {NS_sprm::TTableBorders80::val
, nullptr}, // tap.rgbrcTable;complex;24 bytes;
5982 {NS_sprm::LN_TDefTable10
, nullptr}, // tap.rgdxaCenter, tap.rgtc;complex;
5984 {NS_sprm::TDyaRowHeight::val
, nullptr}, // tap.dyaRowHeight;dya;word;
5985 {NS_sprm::TDefTable::val
, nullptr}, // tap.rgtc;complex
5986 {NS_sprm::TDefTableShd80::val
, nullptr}, // tap.rgshd;complex
5987 {NS_sprm::TTlp::val
, nullptr}, // tap.tlp;TLP;4 bytes;
5988 //NS_sprm::TFBiDi::val, ? ? ?,
5989 //NS_sprm::LN_THTMLProps, ? ? ?,
5990 {NS_sprm::TSetBrc80::val
, nullptr}, // tap.rgtc[].rgbrc;complex;5 bytes;
5991 {NS_sprm::TInsert::val
, nullptr}, // tap.rgdxaCenter, tap.rgtc;complex;
5993 {NS_sprm::TDelete::val
, nullptr}, // tap.rgdxaCenter, tap.rgtc;complex;
5995 {NS_sprm::TDxaCol::val
, nullptr}, // tap.rgdxaCenter;complex;4 bytes;
5996 {NS_sprm::TMerge::val
, nullptr}, // tap.fFirstMerged, tap.fMerged;
5998 {NS_sprm::TSplit::val
, nullptr}, // tap.fFirstMerged, tap.fMerged;
6000 {NS_sprm::LN_TSetBrc10
, nullptr}, // tap.rgtc[].rgbrc;complex;5 bytes;
6001 {NS_sprm::LN_TSetShd80
, nullptr}, // tap.rgshd;complex;4 bytes;
6002 {NS_sprm::LN_TSetShdOdd80
, nullptr}, // tap.rgshd;complex;4 bytes;
6003 {NS_sprm::TTextFlow::val
, nullptr}, // tap.rgtc[].fVertical
6004 // tap.rgtc[].fBackward
6005 // tap.rgtc[].fRotateFont
6006 // 0 or 10 or 10 or 1;word;
6007 //NS_sprm::LN_TDiagLine, ? ? ? ,
6008 {NS_sprm::TVertMerge::val
, nullptr}, // tap.rgtc[].vertMerge;complex;variable
6009 // length always recorded as 2 bytes;
6010 {NS_sprm::TVertAlign::val
, nullptr}, // tap.rgtc[].vertAlign;complex;variable
6011 // length always recorded as 3 bytes;
6012 {NS_sprm::CFELayout::val
, &SwWW8ImplReader::Read_DoubleLine_Rotate
},
6013 {NS_sprm::PItap::val
, nullptr},
6014 {NS_sprm::TTableWidth::val
, nullptr}, // recorded as 3 bytes;
6015 {NS_sprm::TDefTableShd::val
, nullptr},
6016 {NS_sprm::TTableBorders::val
, nullptr},
6017 {NS_sprm::TBrcTopCv::val
, nullptr},
6018 {NS_sprm::TBrcLeftCv::val
, nullptr},
6019 {NS_sprm::TBrcBottomCv::val
, nullptr},
6020 {NS_sprm::TBrcRightCv::val
, nullptr},
6021 {NS_sprm::TCellPaddingDefault::val
, nullptr},
6022 {NS_sprm::TCellPadding::val
, nullptr},
6023 {0xD238, nullptr}, // undocumented sep
6024 {NS_sprm::PBrcTop::val
, &SwWW8ImplReader::Read_Border
},
6025 {NS_sprm::PBrcLeft::val
, &SwWW8ImplReader::Read_Border
},
6026 {NS_sprm::PBrcBottom::val
, &SwWW8ImplReader::Read_Border
},
6027 {NS_sprm::PBrcRight::val
, &SwWW8ImplReader::Read_Border
},
6028 {NS_sprm::PBrcBetween::val
, &SwWW8ImplReader::Read_Border
},
6029 {NS_sprm::TWidthIndent::val
, nullptr},
6030 {NS_sprm::CRgLid0::val
, &SwWW8ImplReader::Read_Language
}, // chp.rglid[0];
6031 // LID: for non-Far East text;
6032 {NS_sprm::CRgLid1::val
, nullptr}, // chp.rglid[1];
6033 // LID: for Far East text
6034 {0x6463, nullptr}, // undocumented
6035 {NS_sprm::PJc::val
, &SwWW8ImplReader::Read_RTLJustify
},
6036 {NS_sprm::PDxaLeft::val
, &SwWW8ImplReader::Read_LR
},
6037 {NS_sprm::PDxaLeft1::val
, &SwWW8ImplReader::Read_LR
},
6038 {NS_sprm::PDxaRight::val
, &SwWW8ImplReader::Read_LR
},
6039 {NS_sprm::TFAutofit::val
, nullptr},
6040 {NS_sprm::TPc::val
, nullptr},
6041 {NS_sprm::TDxaAbs::val
, nullptr},
6042 {NS_sprm::TDyaAbs::val
, nullptr},
6043 {NS_sprm::TDxaFromText::val
, nullptr},
6044 {NS_sprm::SRsid::val
, nullptr},
6045 {NS_sprm::SFpc::val
, nullptr},
6046 {NS_sprm::PFInnerTableCell::val
, &SwWW8ImplReader::Read_TabCellEnd
},
6047 {NS_sprm::PFInnerTtp::val
, &SwWW8ImplReader::Read_TabRowEnd
},
6048 {NS_sprm::CRsidProp::val
, nullptr},
6049 {NS_sprm::CRsidText::val
, nullptr},
6050 {NS_sprm::CCv::val
, &SwWW8ImplReader::Read_TextForeColor
},
6051 {NS_sprm::CCvUl::val
, &SwWW8ImplReader::Read_UnderlineColor
},
6052 {NS_sprm::PShd::val
, &SwWW8ImplReader::Read_ParaBackColor
},
6053 {NS_sprm::PRsid::val
, nullptr},
6054 {NS_sprm::TWidthBefore::val
, nullptr},
6055 {NS_sprm::TSetShdTable::val
, nullptr},
6056 {NS_sprm::TDefTableShdRaw::val
, nullptr},
6057 {NS_sprm::CShd::val
, &SwWW8ImplReader::Read_TextBackColor
},
6058 {NS_sprm::SRncFtn::val
, nullptr},
6059 {NS_sprm::PFDyaBeforeAuto::val
, &SwWW8ImplReader::Read_ParaAutoBefore
},
6060 {NS_sprm::PFDyaAfterAuto::val
, &SwWW8ImplReader::Read_ParaAutoAfter
},
6061 {NS_sprm::PFContextualSpacing::val
, &SwWW8ImplReader::Read_ParaContextualSpacing
},
6064 static wwSprmDispatcher
aSprmSrch(aSprms
, SAL_N_ELEMENTS(aSprms
));
6068 // helper routines : find SPRM
6070 const SprmReadInfo
& SwWW8ImplReader::GetSprmReadInfo(sal_uInt16 nId
) const
6072 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
6073 const wwSprmDispatcher
*pDispatcher
;
6074 if (eVersion
<= ww::eWW2
)
6075 pDispatcher
= GetWW2SprmDispatcher();
6076 else if (eVersion
< ww::eWW8
)
6077 pDispatcher
= GetWW6SprmDispatcher();
6079 pDispatcher
= GetWW8SprmDispatcher();
6081 SprmReadInfo aSrch
= {0, nullptr};
6083 const SprmReadInfo
* pFound
= pDispatcher
->search(aSrch
);
6088 pFound
= pDispatcher
->search(aSrch
);
6094 // helper routines : SPRMs
6096 void SwWW8ImplReader::EndSprm( sal_uInt16 nId
)
6098 if( ( nId
> 255 ) && ( nId
< 0x0800 ) ) return;
6100 const SprmReadInfo
& rSprm
= GetSprmReadInfo( nId
);
6103 (this->*rSprm
.pReadFnc
)( nId
, nullptr, -1 );
6106 short SwWW8ImplReader::ImportSprm(const sal_uInt8
* pPos
, sal_Int32 nMemLen
, sal_uInt16 nId
)
6109 nId
= m_xSprmParser
->GetSprmId(pPos
);
6111 OSL_ENSURE( nId
!= 0xff, "Sprm FF !!!!" );
6113 const SprmReadInfo
& rSprm
= GetSprmReadInfo(nId
);
6115 sal_Int32 nFixedLen
= m_xSprmParser
->DistanceToData(nId
);
6116 sal_Int32 nL
= m_xSprmParser
->GetSprmSize(nId
, pPos
, nMemLen
);
6119 (this->*rSprm
.pReadFnc
)(nId
, pPos
+ nFixedLen
, nL
- nFixedLen
);
6124 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */