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 <o3tl/unit_conversion.hxx>
23 #include <svl/itemiter.hxx>
24 #include <svl/grabbagitem.hxx>
25 #include <rtl/tencinfo.h>
26 #include <sal/log.hxx>
28 #include <hintids.hxx>
29 #include <editeng/lspcitem.hxx>
30 #include <editeng/wrlmitem.hxx>
31 #include <editeng/udlnitem.hxx>
32 #include <editeng/kernitem.hxx>
33 #include <editeng/langitem.hxx>
34 #include <editeng/cmapitem.hxx>
35 #include <editeng/shdditem.hxx>
36 #include <editeng/contouritem.hxx>
37 #include <editeng/crossedoutitem.hxx>
38 #include <editeng/postitem.hxx>
39 #include <editeng/wghtitem.hxx>
40 #include <editeng/colritem.hxx>
41 #include <editeng/brushitem.hxx>
42 #include <editeng/spltitem.hxx>
43 #include <editeng/keepitem.hxx>
44 #include <editeng/orphitem.hxx>
45 #include <editeng/widwitem.hxx>
46 #include <editeng/adjustitem.hxx>
47 #include <editeng/escapementitem.hxx>
48 #include <editeng/fhgtitem.hxx>
49 #include <editeng/fontitem.hxx>
50 #include <editeng/shaditem.hxx>
51 #include <editeng/boxitem.hxx>
52 #include <editeng/ulspitem.hxx>
53 #include <editeng/lrspitem.hxx>
54 #include <editeng/tstpitem.hxx>
55 #include <editeng/autokernitem.hxx>
56 #include <editeng/paperinf.hxx>
57 #include <editeng/emphasismarkitem.hxx>
58 #include <editeng/twolinesitem.hxx>
59 #include <editeng/charscaleitem.hxx>
60 #include <editeng/charrotateitem.hxx>
61 #include <editeng/charreliefitem.hxx>
62 #include <editeng/blinkitem.hxx>
63 #include <editeng/hyphenzoneitem.hxx>
64 #include <editeng/paravertalignitem.hxx>
65 #include <editeng/pgrditem.hxx>
66 #include <editeng/frmdiritem.hxx>
67 #include <editeng/charhiddenitem.hxx>
68 #include <i18nlangtag/mslangid.hxx>
69 #include <svx/xfillit0.hxx>
70 #include <svx/xflclit.hxx>
71 #include <officecfg/Office/Writer.hxx>
72 #include "sortedarray.hxx"
73 #include "sprmids.hxx"
78 #include <IDocumentSettingAccess.hxx>
79 #include <pagedesc.hxx>
80 #include <fmtanchr.hxx>
81 #include <fmtcntnt.hxx>
82 #include <fchrfmt.hxx>
83 #include <fmthdft.hxx>
84 #include <fmtclds.hxx>
85 #include <fmtftntx.hxx>
87 #include <section.hxx>
88 #include <lineinfo.hxx>
89 #include <fmtline.hxx>
90 #include <txatbase.hxx>
91 #include <fmtflcnt.hxx>
92 #include <tgrditem.hxx>
93 #include <hfspacingitem.hxx>
94 #include <swtable.hxx>
96 #include "writerhelper.hxx"
97 #include "writerwordglue.hxx"
98 #include "ww8scan.hxx"
99 #include "ww8par2.hxx"
100 #include "ww8graf.hxx"
102 #include <fmtwrapinfluenceonobjpos.hxx>
103 #include <formatflysplit.hxx>
105 using namespace sw::util
;
106 using namespace sw::types
;
107 using namespace ::com::sun::star
;
108 using namespace nsHdFtFlags
;
112 // WW default for horizontal borders: 2.5 cm
113 constexpr auto MM_250
= o3tl::convert(25, o3tl::Length::mm
, o3tl::Length::twip
); // 1417
114 // WW default for lower border: 2.0 cm
115 constexpr auto MM_200
= o3tl::convert(20, o3tl::Length::mm
, o3tl::Length::twip
); // 1134
118 static sal_uInt8
lcl_ReadBorders(bool bVer67
, WW8_BRCVer9
* brc
, WW8PLCFx_Cp_FKP
* pPap
,
119 const WW8RStyle
* pSty
= nullptr, const WW8PLCFx_SEPX
* pSep
= nullptr);
121 Color
SwWW8ImplReader::GetCol(sal_uInt8 nIco
)
123 static const Color eSwWW8ColA
[] =
125 COL_AUTO
, COL_BLACK
, COL_LIGHTBLUE
, COL_LIGHTCYAN
, COL_LIGHTGREEN
,
126 COL_LIGHTMAGENTA
, COL_LIGHTRED
, COL_YELLOW
, COL_WHITE
, COL_BLUE
,
127 COL_CYAN
, COL_GREEN
, COL_MAGENTA
, COL_RED
, COL_BROWN
, COL_GRAY
,
131 nIco
>= SAL_N_ELEMENTS(eSwWW8ColA
), "sw.ww8",
132 "ico " << sal_uInt32(nIco
) << " >= " << SAL_N_ELEMENTS(eSwWW8ColA
));
133 return nIco
< SAL_N_ELEMENTS(eSwWW8ColA
) ? eSwWW8ColA
[nIco
] : COL_AUTO
;
136 static sal_uInt32
MSRoundTweak(sal_uInt32 x
)
141 // page attribute which are not handled via the attribute management but
142 // using ...->HasSprm
143 // (except OLST which stays a normal attribute)
144 static short ReadSprm( const WW8PLCFx_SEPX
* pSep
, sal_uInt16 nId
, short nDefaultVal
)
146 SprmResult aRes
= pSep
->HasSprm(nId
); // sprm here?
147 const sal_uInt8
* pS
= aRes
.pSprm
;
148 short nVal
= (pS
&& aRes
.nRemainingData
>= 2) ? SVBT16ToInt16(pS
) : nDefaultVal
;
152 static sal_uInt16
ReadUSprm( const WW8PLCFx_SEPX
* pSep
, sal_uInt16 nId
, short nDefaultVal
)
154 SprmResult aRes
= pSep
->HasSprm(nId
); // sprm here?
155 const sal_uInt8
* pS
= aRes
.pSprm
;
156 sal_uInt16 nVal
= (pS
&& aRes
.nRemainingData
>= 2) ? SVBT16ToUInt16(pS
) : nDefaultVal
;
160 static sal_uInt8
ReadBSprm( const WW8PLCFx_SEPX
* pSep
, sal_uInt16 nId
, sal_uInt8 nDefaultVal
)
162 SprmResult aRes
= pSep
->HasSprm(nId
); // sprm here?
163 const sal_uInt8
* pS
= aRes
.pSprm
;
164 sal_uInt8 nVal
= (pS
&& aRes
.nRemainingData
>= 1) ? *pS
: nDefaultVal
;
168 void wwSection::SetDirection()
171 switch (maSep
.wTextFlow
)
174 OSL_ENSURE(false, "Unknown layout type");
177 meDir
=SvxFrameDirection::Horizontal_LR_TB
;
180 meDir
=SvxFrameDirection::Vertical_RL_TB
;
183 //asian letters are not rotated, western are. We can't import
184 //bottom to top going left to right, we can't do this in
185 //pages, (in drawboxes we could partly hack it with a rotated
186 //drawing box, though not frame)
187 meDir
=SvxFrameDirection::Vertical_RL_TB
;
190 //asian letters are not rotated, western are. We can't import
191 meDir
=SvxFrameDirection::Vertical_RL_TB
;
194 //asian letters are rotated, western not. We can't import
195 meDir
=SvxFrameDirection::Horizontal_LR_TB
;
199 sal_uInt8 bRTLPgn
= maSep
.fBiDi
;
200 if ((meDir
== SvxFrameDirection::Horizontal_LR_TB
) && bRTLPgn
)
201 meDir
= SvxFrameDirection::Horizontal_RL_TB
;
204 bool wwSection::IsVertical() const
206 return meDir
== SvxFrameDirection::Vertical_RL_TB
|| meDir
== SvxFrameDirection::Vertical_LR_TB
;
210 This is something of festering mapping, I'm open to better ways of doing it,
211 but primarily the grid in writer is different to that in word. In writer the
212 grid elements are squares with ruby rows inbetween. While in word there is no
213 ruby stuff, and the elements are rectangles. By misusing the ruby row I can
214 handle distortions in one direction, but its all a bit of a mess:
216 void SwWW8ImplReader::SetDocumentGrid(SwFrameFormat
&rFormat
, const wwSection
&rSection
)
221 rFormat
.SetFormatAttr(SvxFrameDirectionItem(rSection
.meDir
, RES_FRAMEDIR
));
223 SwTwips nTextareaHeight
= rFormat
.GetFrameSize().GetHeight();
224 const SvxULSpaceItem
&rUL
= rFormat
.GetFormatAttr(RES_UL_SPACE
);
225 nTextareaHeight
-= rUL
.GetUpper();
226 nTextareaHeight
-= rUL
.GetLower();
228 SwTwips nTextareaWidth
= rFormat
.GetFrameSize().GetWidth();
229 const SvxLRSpaceItem
&rLR
= rFormat
.GetFormatAttr(RES_LR_SPACE
);
230 nTextareaWidth
-= rLR
.GetLeft();
231 nTextareaWidth
-= rLR
.GetRight();
233 if (rSection
.IsVertical())
234 std::swap(nTextareaHeight
, nTextareaWidth
);
236 SwTextGridItem aGrid
;
237 aGrid
.SetDisplayGrid(false);
238 aGrid
.SetPrintGrid(false);
239 SwTextGrid eType
=GRID_NONE
;
241 switch (rSection
.maSep
.clm
)
247 OSL_ENSURE(false, "Unknown grid type");
250 eType
= GRID_LINES_CHARS
;
251 aGrid
.SetSnapToChars(true);
254 eType
= GRID_LINES_CHARS
;
255 aGrid
.SetSnapToChars(false);
258 eType
= GRID_LINES_ONLY
;
262 aGrid
.SetGridType(eType
);
264 // seem to not add external leading in word, or the character would run across
265 // two line in some cases.
266 if (eType
!= GRID_NONE
)
267 m_rDoc
.getIDocumentSettingAccess().set(DocumentSettingId::ADD_EXT_LEADING
, false);
269 //force to set document as standard page mode
270 bool bSquaredMode
= false;
271 m_rDoc
.SetDefaultPageMode( bSquaredMode
);
272 aGrid
.SetSquaredMode( bSquaredMode
);
274 //Get the size of word's default styles font
275 sal_uInt32 nCharWidth
=240;
276 for (sal_uInt16 nI
= 0; nI
< m_xStyles
->GetCount(); ++nI
)
278 if (m_vColl
[nI
].m_bValid
&& m_vColl
[nI
].m_pFormat
&&
279 m_vColl
[nI
].IsWW8BuiltInDefaultStyle())
281 const SvxFontHeightItem
& rFontHeightItem
=
282 m_vColl
[nI
].m_pFormat
->GetFormatAttr(RES_CHRATR_CJK_FONTSIZE
);
283 nCharWidth
= rFontHeightItem
.GetHeight();
289 if (rSection
.maSep
.dxtCharSpace
)
291 sal_uInt32 nCharSpace
= rSection
.maSep
.dxtCharSpace
;
292 //main lives in top 20 bits, and is signed.
293 sal_Int32 nMain
= (nCharSpace
& 0xFFFFF000);
295 nCharWidth
+= nMain
*20;
297 int nFraction
= (nCharSpace
& 0x00000FFF);
298 nFraction
= (nFraction
*20)/0xFFF;
299 nCharWidth
+= nFraction
;
302 aGrid
.SetBaseWidth( writer_cast
<sal_uInt16
>(nCharWidth
));
305 sal_Int32 nLinePitch
= rSection
.maSep
.dyaLinePitch
;
306 if (nLinePitch
>= 1 && nLinePitch
<= 31680)
308 aGrid
.SetLines(writer_cast
<sal_uInt16
>(nTextareaHeight
/nLinePitch
));
309 aGrid
.SetBaseHeight(writer_cast
<sal_uInt16
>(nLinePitch
));
312 aGrid
.SetRubyHeight(0);
314 rFormat
.SetFormatAttr(aGrid
);
317 void SwWW8ImplReader::SetRelativeJustify( bool bRel
)
319 if ( m_pCurrentColl
&& StyleExists(m_nCurrentColl
) ) // importing style
320 m_vColl
[m_nCurrentColl
].m_nRelativeJustify
= bRel
? 1 : 0;
321 else if ( m_xPlcxMan
&& m_xPlcxMan
->GetPap() ) // importing paragraph
322 m_xPlcxMan
->GetPap()->nRelativeJustify
= bRel
? 1 : 0;
325 bool SwWW8ImplReader::IsRelativeJustify()
327 bool bRet
= m_xWwFib
->GetFIBVersion() >= ww::eWW8
;
330 // if relativeJustify is undefined (-1), then check the parent style.
331 if ( m_pCurrentColl
&& StyleExists(m_nCurrentColl
) )
333 sal_Int16 nRelative
= m_vColl
[m_nCurrentColl
].m_nRelativeJustify
;
334 if ( nRelative
< 0 && m_nCurrentColl
)
336 o3tl::sorted_vector
<sal_uInt16
> aVisitedStyles
;
337 bRet
= IsRelativeJustify(m_vColl
[m_nCurrentColl
].m_nBase
, aVisitedStyles
);
340 bRet
= nRelative
> 0;
342 else if ( m_xPlcxMan
&& m_xPlcxMan
->GetPap() )
344 sal_Int16 nRelative
= m_xPlcxMan
->GetPap()->nRelativeJustify
;
347 o3tl::sorted_vector
<sal_uInt16
> aVisitedStyles
;
348 bRet
= IsRelativeJustify(m_nCurrentColl
, aVisitedStyles
);
351 bRet
= nRelative
> 0;
358 bool SwWW8ImplReader::IsRelativeJustify(sal_uInt16 nColl
, o3tl::sorted_vector
<sal_uInt16
>& rVisitedStyles
)
360 assert( m_xWwFib
->GetFIBVersion() >= ww::eWW8
361 && "pointless to search styles if relative justify is impossible");
363 if ( StyleExists(nColl
) )
365 rVisitedStyles
.insert(nColl
);
366 // if relativeJustify is undefined (-1), then check the parent style.
367 sal_Int16 nRelative
= m_vColl
[nColl
].m_nRelativeJustify
;
368 if ( nColl
== 0 || nRelative
>= 0 )
369 bRet
= nRelative
> 0;
370 else if (rVisitedStyles
.find(m_vColl
[nColl
].m_nBase
) == rVisitedStyles
.end()) // detect loop in chain
371 bRet
= IsRelativeJustify(m_vColl
[nColl
].m_nBase
, rVisitedStyles
);
377 void SwWW8ImplReader::Read_ParaBiDi(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
380 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_FRAMEDIR
);
383 SvxFrameDirection eDir
=
384 *pData
? SvxFrameDirection::Horizontal_RL_TB
: SvxFrameDirection::Horizontal_LR_TB
;
386 // In eWW8+, justify can be absolute, or relative to BiDi
387 bool bBiDiSwap
= IsRelativeJustify();
390 // Only change if ParaBiDi doesn't match previous setting.
391 const bool bParentRTL
= IsRightToLeft();
392 bBiDiSwap
= (eDir
== SvxFrameDirection::Horizontal_RL_TB
&& !bParentRTL
)
393 || (eDir
== SvxFrameDirection::Horizontal_LR_TB
&& bParentRTL
);
398 const SvxAdjustItem
* pItem
= static_cast<const SvxAdjustItem
*>(GetFormatAttr(RES_PARATR_ADJUST
));
401 // no previous adjust: set appropriate default
402 if ( eDir
== SvxFrameDirection::Horizontal_LR_TB
)
403 NewAttr( SvxAdjustItem( SvxAdjust::Left
, RES_PARATR_ADJUST
) );
405 NewAttr( SvxAdjustItem( SvxAdjust::Right
, RES_PARATR_ADJUST
) );
409 // previous adjust and bidi has changed: swap Left/Right
410 const SvxAdjust eJustify
= pItem
->GetAdjust();
411 if ( eJustify
== SvxAdjust::Left
)
412 NewAttr( SvxAdjustItem( SvxAdjust::Right
, RES_PARATR_ADJUST
) );
413 else if ( eJustify
== SvxAdjust::Right
)
414 NewAttr( SvxAdjustItem( SvxAdjust::Left
, RES_PARATR_ADJUST
) );
418 NewAttr(SvxFrameDirectionItem(eDir
, RES_FRAMEDIR
));
420 if ( m_pCurrentColl
&& m_xStyles
) // in style definition
421 m_xStyles
->mbBidiChanged
= true;
425 bool wwSectionManager::SetCols(SwFrameFormat
&rFormat
, const wwSection
&rSection
,
426 sal_uInt32 nNetWidth
)
428 //sprmSCcolumns - number of columns - 1
429 const sal_Int16 nCols
= rSection
.NoCols();
431 if (nCols
< 2) //check for no columns or other weird state
434 const sal_uInt16 nNetWriterWidth
= writer_cast
<sal_uInt16
>(nNetWidth
);
435 if (nNetWriterWidth
== 0)
438 SwFormatCol aCol
; // Create SwFormatCol
440 //sprmSDxaColumns - Default distance is 1.25 cm
441 sal_Int32 nColSpace
= rSection
.StandardColSeparation();
443 const SEPr
& rSep
= rSection
.maSep
;
448 aCol
.SetLineAdj(COLADJ_TOP
); // Line
449 aCol
.SetLineHeight(100);
450 aCol
.SetLineColor(COL_BLACK
);
451 aCol
.SetLineWidth(1);
454 aCol
.Init(nCols
, writer_cast
<sal_uInt16
>(nColSpace
), nNetWriterWidth
);
456 // sprmSFEvenlySpaced
457 if (!rSep
.fEvenlySpaced
)
459 aCol
.SetOrtho_(false);
460 const sal_uInt16 maxIdx
= SAL_N_ELEMENTS(rSep
.rgdxaColumnWidthSpacing
);
461 for (sal_uInt16 i
= 0, nIdx
= 1; i
< nCols
&& nIdx
< maxIdx
; i
++, nIdx
+=2 )
463 SwColumn
* pCol
= &aCol
.GetColumns()[i
];
464 const sal_Int32 nLeft
= rSep
.rgdxaColumnWidthSpacing
[nIdx
-1]/2;
465 const sal_Int32 nRight
= rSep
.rgdxaColumnWidthSpacing
[nIdx
+1]/2;
466 const sal_Int32 nWishWidth
= rSep
.rgdxaColumnWidthSpacing
[nIdx
]
468 pCol
->SetWishWidth(writer_cast
<sal_uInt16
>(nWishWidth
));
469 pCol
->SetLeft(writer_cast
<sal_uInt16
>(nLeft
));
470 pCol
->SetRight(writer_cast
<sal_uInt16
>(nRight
));
472 aCol
.SetWishWidth(nNetWriterWidth
);
474 rFormat
.SetFormatAttr(aCol
);
478 void wwSectionManager::SetLeftRight(wwSection
&rSection
)
481 sal_uInt32 nWWLe
= MSRoundTweak(rSection
.maSep
.dxaLeft
);
482 sal_uInt32 nWWRi
= MSRoundTweak(rSection
.maSep
.dxaRight
);
483 sal_uInt32 nWWGu
= rSection
.maSep
.dzaGutter
;
486 fRTLGutter is set if the gutter is on the right, the gutter is otherwise
487 placed on the left unless the global dop options are to put it on top, that
488 case is handled in GetPageULData.
490 if (rSection
.maSep
.fRTLGutter
)
492 rSection
.m_bRtlGutter
= true;
496 if ((rSection
.m_nPgWidth
- nWWLe
- nWWRi
) < MINLAY
)
499 There are some label templates which are "broken", they specify
500 margins which make no sense e.g. Left 16.10cm, Right 16.10cm. So the
501 space left between the margins is less than 0 In word the left margin
502 is honoured and if the right margin would be past the left margin is
503 left at the left margin position.
505 Now this will work fine for importing, layout and exporting, *but* the
506 page layout dialog has a hardcoded minimum page width of 0.5cm so it
507 will report a different value than what is actually being used. i.e.
508 it will add up the values to give a wider page than is actually being
511 nWWRi
= rSection
.m_nPgWidth
- nWWLe
- MINLAY
;
514 rSection
.m_nPgLeft
= nWWLe
;
515 rSection
.m_nPgRight
= nWWRi
;
516 rSection
.m_nPgGutter
= nWWGu
;
519 void wwSectionManager::SetPage(SwPageDesc
&rInPageDesc
, SwFrameFormat
&rFormat
,
520 const wwSection
&rSection
, bool bIgnoreCols
)
523 rInPageDesc
.SetLandscape(rSection
.IsLandScape());
526 SwFormatFrameSize
aSz( rFormat
.GetFrameSize() );
527 aSz
.SetWidth(rSection
.GetPageWidth());
528 aSz
.SetHeight(SvxPaperInfo::GetSloppyPaperDimension(rSection
.GetPageHeight()));
529 rFormat
.SetFormatAttr(aSz
);
531 SvxLRSpaceItem
aLR(rSection
.GetPageLeft(), rSection
.GetPageRight(), 0, RES_LR_SPACE
);
532 aLR
.SetGutterMargin(rSection
.m_nPgGutter
);
533 rFormat
.SetFormatAttr(aLR
);
535 SfxBoolItem
aRtlGutter(RES_RTL_GUTTER
, rSection
.m_bRtlGutter
);
536 rFormat
.SetFormatAttr(aRtlGutter
);
539 SetCols(rFormat
, rSection
, rSection
.GetTextAreaWidth());
543 // Returns corrected (ODF) margin size
544 tools::Long
SetBorderDistance(bool bFromEdge
, SvxBoxItem
& aBox
, SvxBoxItemLine eLine
, tools::Long nMSMargin
)
546 const editeng::SvxBorderLine
* pLine
= aBox
.GetLine(eLine
);
549 sal_Int32 nNewMargin
= nMSMargin
;
550 sal_Int32 nNewDist
= aBox
.GetDistance(eLine
);
551 sal_Int32 nLineWidth
= pLine
->GetScaledWidth();
553 editeng::BorderDistanceFromWord(bFromEdge
, nNewMargin
, nNewDist
, nLineWidth
);
554 aBox
.SetDistance(nNewDist
, eLine
);
560 void SwWW8ImplReader::SetPageBorder(SwFrameFormat
&rFormat
, const wwSection
&rSection
)
562 if (!IsBorder(rSection
.m_brc
))
565 SfxItemSet
aSet(rFormat
.GetAttrSet());
566 short aSizeArray
[5]={0};
567 SetFlyBordersShadow(aSet
, rSection
.m_brc
, &aSizeArray
[0]);
568 SvxLRSpaceItem
aLR(aSet
.Get(RES_LR_SPACE
));
569 SvxULSpaceItem
aUL(aSet
.Get(RES_UL_SPACE
));
570 SvxBoxItem
aBox(aSet
.Get(RES_BOX
));
571 bool bFromEdge
= rSection
.maSep
.pgbOffsetFrom
== 1;
573 aLR
.SetLeft(SetBorderDistance(bFromEdge
, aBox
, SvxBoxItemLine::LEFT
, aLR
.GetLeft()));
574 aLR
.SetRight(SetBorderDistance(bFromEdge
, aBox
, SvxBoxItemLine::RIGHT
, aLR
.GetRight()));
575 aUL
.SetUpper(SetBorderDistance(bFromEdge
, aBox
, SvxBoxItemLine::TOP
, aUL
.GetUpper()));
576 aUL
.SetLower(SetBorderDistance(bFromEdge
, aBox
, SvxBoxItemLine::BOTTOM
, aUL
.GetLower()));
581 rFormat
.SetFormatAttr(aSet
);
584 void wwSectionManager::GetPageULData(const wwSection
&rSection
,
585 wwSectionManager::wwULSpaceData
& rData
) const
587 sal_Int32 nWWUp
= rSection
.maSep
.dyaTop
;
588 sal_Int32 nWWLo
= rSection
.maSep
.dyaBottom
;
589 sal_uInt32 nWWHTop
= rSection
.maSep
.dyaHdrTop
;
590 sal_uInt32 nWWFBot
= rSection
.maSep
.dyaHdrBottom
;
593 If there is gutter in 97+ and the dop says put it on top then get the
594 gutter distance and set it to the top margin. When we are "two pages
595 in one" the gutter is put at the top of odd pages, and bottom of
596 even pages, something we cannot do. So we will put it on top of all
597 pages, that way the pages are at least the right size.
599 if (!mrReader
.m_bVer67
&& mrReader
.m_xWDop
->iGutterPos
&&
600 rSection
.maSep
.fRTLGutter
)
602 nWWUp
+= rSection
.maSep
.dzaGutter
;
605 /* Check whether this section has headers / footers */
606 sal_uInt16 nHeaderMask
= WW8_HEADER_EVEN
| WW8_HEADER_ODD
;
607 sal_uInt16 nFooterMask
= WW8_FOOTER_EVEN
| WW8_FOOTER_ODD
;
608 /* Ignore the presence of a first-page header/footer unless it is enabled */
609 if( rSection
.HasTitlePage() )
611 nHeaderMask
|= WW8_HEADER_FIRST
;
612 nFooterMask
|= WW8_FOOTER_FIRST
;
614 rData
.bHasHeader
= (rSection
.maSep
.grpfIhdt
& nHeaderMask
) != 0;
615 rData
.bHasFooter
= (rSection
.maSep
.grpfIhdt
& nFooterMask
) != 0;
617 if( rData
.bHasHeader
)
619 rData
.nSwUp
= nWWHTop
; // Header -> convert
620 // #i19922# - correction:
621 // consider that <nWWUp> can be negative, compare only if it's positive
623 o3tl::make_unsigned(nWWUp
) >= nWWHTop
)
624 rData
.nSwHLo
= nWWUp
- nWWHTop
;
628 // #i19922# - minimum page header height is now 1mm
629 // use new constant <cMinHdFtHeight>
630 if (rData
.nSwHLo
< sal::static_int_cast
< sal_uInt32
>(cMinHdFtHeight
))
631 rData
.nSwHLo
= sal::static_int_cast
< sal_uInt32
>(cMinHdFtHeight
);
633 else // no header -> just use Up as-is
634 rData
.nSwUp
= std::abs(nWWUp
);
636 if( rData
.bHasFooter
)
638 rData
.nSwLo
= nWWFBot
; // footer -> convert
639 // #i19922# - correction: consider that <nWWLo> can be negative, compare only if it's positive
641 o3tl::make_unsigned(nWWLo
) >= nWWFBot
)
642 rData
.nSwFUp
= nWWLo
- nWWFBot
;
646 // #i19922# - minimum page header height is now 1mm
647 // use new constant <cMinHdFtHeight>
648 if (rData
.nSwFUp
< sal::static_int_cast
< sal_uInt32
>(cMinHdFtHeight
))
649 rData
.nSwFUp
= sal::static_int_cast
< sal_uInt32
>(cMinHdFtHeight
);
651 else // no footer -> just use Lo as-is
652 rData
.nSwLo
= std::abs(nWWLo
);
655 void wwSectionManager::SetPageULSpaceItems(SwFrameFormat
&rFormat
,
656 wwSectionManager::wwULSpaceData
const & rData
, const wwSection
&rSection
)
658 if (rData
.bHasHeader
) // ... and set Header-Lower
660 // set header height to minimum
661 if (SwFrameFormat
* pHdFormat
= const_cast<SwFrameFormat
*>(rFormat
.GetHeader().GetHeaderFormat()))
663 SvxULSpaceItem
aHdUL(pHdFormat
->GetULSpace());
664 if (!rSection
.IsFixedHeightHeader()) //normal
666 pHdFormat
->SetFormatAttr(SwFormatFrameSize(SwFrameSize::Minimum
, 0, rData
.nSwHLo
));
667 // #i19922# - minimum page header height is now 1mm
668 // use new constant <cMinHdFtHeight>
669 aHdUL
.SetLower( writer_cast
<sal_uInt16
>(rData
.nSwHLo
- cMinHdFtHeight
) );
670 pHdFormat
->SetFormatAttr(SwHeaderAndFooterEatSpacingItem(
671 RES_HEADER_FOOTER_EAT_SPACING
, true));
675 // Hack alert: these calculations are based on
676 // #112727# import negative height headers/footers as floating frames inside fixed height headers/footer
677 // #i48832# - set correct spacing between header and body.
678 const sal_Int32
nHdLowerSpace(std::max
<sal_Int32
>(0, std::abs(rSection
.maSep
.dyaTop
) - rData
.nSwUp
- rData
.nSwHLo
));
679 pHdFormat
->SetFormatAttr(SwFormatFrameSize(SwFrameSize::Fixed
, 0, rData
.nSwHLo
+ nHdLowerSpace
));
680 aHdUL
.SetLower( static_cast< sal_uInt16
>(nHdLowerSpace
) );
681 pHdFormat
->SetFormatAttr(SwHeaderAndFooterEatSpacingItem(
682 RES_HEADER_FOOTER_EAT_SPACING
, false));
684 pHdFormat
->SetFormatAttr(aHdUL
);
688 if (rData
.bHasFooter
) // ... and set footer-upper
690 if (SwFrameFormat
* pFtFormat
= const_cast<SwFrameFormat
*>(rFormat
.GetFooter().GetFooterFormat()))
692 SvxULSpaceItem
aFtUL(pFtFormat
->GetULSpace());
693 if (!rSection
.IsFixedHeightFooter()) //normal
695 pFtFormat
->SetFormatAttr(SwFormatFrameSize(SwFrameSize::Minimum
, 0, rData
.nSwFUp
));
696 // #i19922# - minimum page header height is now 1mm
697 // use new constant <cMinHdFtHeight>
698 aFtUL
.SetUpper( writer_cast
<sal_uInt16
>(rData
.nSwFUp
- cMinHdFtHeight
) );
699 pFtFormat
->SetFormatAttr(SwHeaderAndFooterEatSpacingItem(
700 RES_HEADER_FOOTER_EAT_SPACING
, true));
704 // #i48832# - set correct spacing between footer and body.
705 const sal_Int32
nFtUpperSpace(std::max
<sal_Int32
>(0, std::abs(rSection
.maSep
.dyaBottom
) - rData
.nSwLo
- rData
.nSwFUp
));
706 pFtFormat
->SetFormatAttr(SwFormatFrameSize(SwFrameSize::Fixed
, 0, rData
.nSwFUp
+ nFtUpperSpace
));
707 aFtUL
.SetUpper( static_cast< sal_uInt16
>(nFtUpperSpace
) );
708 pFtFormat
->SetFormatAttr(SwHeaderAndFooterEatSpacingItem(
709 RES_HEADER_FOOTER_EAT_SPACING
, false));
711 pFtFormat
->SetFormatAttr(aFtUL
);
715 SvxULSpaceItem
aUL(writer_cast
<sal_uInt16
>(rData
.nSwUp
),
716 writer_cast
<sal_uInt16
>(rData
.nSwLo
), RES_UL_SPACE
);
717 rFormat
.SetFormatAttr(aUL
);
720 SwSectionFormat
*wwSectionManager::InsertSection(
721 SwPaM
const & rMyPaM
, wwSection
&rSection
)
723 SwSectionData
aSection( SectionType::Content
,
724 mrReader
.m_rDoc
.GetUniqueSectionName() );
726 SfxItemSet
aSet( mrReader
.m_rDoc
.GetAttrPool(), aFrameFormatSetRange
);
728 bool bRTLPgn
= !maSegments
.empty() && maSegments
.back().IsBiDi();
729 aSet
.Put(SvxFrameDirectionItem(
730 bRTLPgn
? SvxFrameDirection::Horizontal_RL_TB
: SvxFrameDirection::Horizontal_LR_TB
, RES_FRAMEDIR
));
732 if (2 == mrReader
.m_xWDop
->fpc
)
733 aSet
.Put( SwFormatFootnoteAtTextEnd(FTNEND_ATTXTEND
));
734 if (0 == mrReader
.m_xWDop
->epc
)
735 aSet
.Put( SwFormatEndAtTextEnd(FTNEND_ATTXTEND
));
737 aSection
.SetProtectFlag(SectionIsProtected(rSection
));
740 mrReader
.m_rDoc
.InsertSwSection( rMyPaM
, aSection
, nullptr, & aSet
);
741 OSL_ENSURE(rSection
.mpSection
, "section not inserted!");
742 if (!rSection
.mpSection
)
745 SwPageDesc
*pPage
= nullptr;
746 auto aIter
= std::find_if(maSegments
.rbegin(), maSegments
.rend(),
747 [](const wwSection
& rSegment
) { return rSegment
.mpPage
!= nullptr; });
748 if (aIter
!= maSegments
.rend())
749 pPage
= aIter
->mpPage
;
751 OSL_ENSURE(pPage
, "no page outside this section!");
754 pPage
= &mrReader
.m_rDoc
.GetPageDesc(0);
756 SwSectionFormat
*pFormat
= rSection
.mpSection
->GetFormat();
757 OSL_ENSURE(pFormat
, "impossible");
761 SwFrameFormat
& rFormat
= pPage
->GetMaster();
762 const SvxLRSpaceItem
& rLR
= rFormat
.GetLRSpace();
763 tools::Long nPageLeft
= rLR
.GetLeft();
764 tools::Long nPageRight
= rLR
.GetRight();
765 tools::Long nSectionLeft
= rSection
.GetPageLeft() - nPageLeft
;
766 tools::Long nSectionRight
= rSection
.GetPageRight() - nPageRight
;
767 if ((nSectionLeft
!= 0) || (nSectionRight
!= 0))
769 SvxLRSpaceItem
aLR(nSectionLeft
, nSectionRight
, 0, RES_LR_SPACE
);
770 pFormat
->SetFormatAttr(aLR
);
773 SetCols(*pFormat
, rSection
, rSection
.GetTextAreaWidth());
777 void SwWW8ImplReader::HandleLineNumbering(const wwSection
&rSection
)
779 // check if Line Numbering must be activated or reset
780 if (!(m_bNewDoc
&& rSection
.maSep
.nLnnMod
))
783 // restart-numbering-mode: 0 per page, 1 per section, 2 never restart
784 bool bRestartLnNumPerSection
= (1 == rSection
.maSep
.lnc
);
788 SwLineNumberInfo
aInfo( m_rDoc
.GetLineNumberInfo() );
790 aInfo
.SetPaintLineNumbers(true);
792 aInfo
.SetRestartEachPage(rSection
.maSep
.lnc
== 0);
794 // A value of 0 (auto) indicates that the application MUST automatically determine positioning.
795 if ( rSection
.maSep
.dxaLnn
)
796 aInfo
.SetPosFromLeft(writer_cast
<sal_uInt16
>(rSection
.maSep
.dxaLnn
));
798 //Paint only for every n line
799 aInfo
.SetCountBy(rSection
.maSep
.nLnnMod
);
801 // to be defaulted features ( HARDCODED in MS Word 6,7,8,9 )
802 aInfo
.SetCountBlankLines(true);
803 aInfo
.SetCountInFlys(false);
804 aInfo
.SetPos( LINENUMBER_POS_LEFT
);
805 SvxNumberType aNumType
; // this sets SVX_NUM_ARABIC per default
806 aInfo
.SetNumType( aNumType
);
808 m_rDoc
.SetLineNumberInfo( aInfo
);
809 m_bNoLnNumYet
= false;
812 if ((0 < rSection
.maSep
.lnnMin
) || bRestartLnNumPerSection
)
814 SwFormatLineNumber aLN
;
815 if (const SwFormatLineNumber
* pLN
816 = static_cast<const SwFormatLineNumber
*>(GetFormatAttr(RES_LINENUMBER
)))
818 aLN
.SetCountLines( pLN
->IsCount() );
820 aLN
.SetStartValue(1 + rSection
.maSep
.lnnMin
);
822 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_LINENUMBER
);
826 wwSection::wwSection(const SwPosition
&rPos
) : maStart(rPos
.GetNode())
829 , meDir(SvxFrameDirection::Horizontal_LR_TB
)
830 , m_nPgWidth(SvxPaperInfo::GetPaperSize(PAPER_A4
).Width())
834 , mnVerticalAdjustment(drawing::TextVerticalAdjust_TOP
)
836 , mbHasFootnote(false)
840 void wwSectionManager::SetNumberingType(const wwSection
&rNewSection
,
841 SwPageDesc
&rPageDesc
)
843 // save page number format
844 static const SvxNumType aNumTyp
[5] =
846 SVX_NUM_ARABIC
, SVX_NUM_ROMAN_UPPER
, SVX_NUM_ROMAN_LOWER
,
847 SVX_NUM_CHARS_UPPER_LETTER_N
, SVX_NUM_CHARS_LOWER_LETTER_N
851 aType
.SetNumberingType( aNumTyp
[rNewSection
.maSep
.nfcPgn
] );
852 rPageDesc
.SetNumType(aType
);
855 // CreateSep is called for every section change (even at the start of
856 // the document. CreateSep also creates the pagedesc(s) and
857 // fills it/them with attributes and KF texts.
858 // This has become necessary because the translation of the various
859 // page attributes is interconnected too much.
860 void wwSectionManager::CreateSep(const tools::Long nTextPos
)
863 #i1909# section/page breaks should not occur in tables or subpage
864 elements like frames. Word itself ignores them in this case. The bug is
865 more likely that this filter created such documents in the past!
867 if (mrReader
.m_nInTable
|| mrReader
.m_bTxbxFlySection
|| mrReader
.InLocalApo())
870 WW8PLCFx_SEPX
* pSep
= mrReader
.m_xPlcxMan
->GetSepPLCF();
871 OSL_ENSURE(pSep
, "impossible!");
875 if (!maSegments
.empty() && mrReader
.m_oLastAnchorPos
&& *mrReader
.m_oLastAnchorPos
== *mrReader
.m_pPaM
->GetPoint())
878 SwPaM
pam( *mrReader
.m_oLastAnchorPos
);
879 if( pam
.Move(fnMoveBackward
, GoInNode
))
880 if( SwTextNode
* txtNode
= pam
.GetPoint()->GetNode().GetTextNode())
881 if( txtNode
->Len() == 0 )
884 mrReader
.AppendTextNode(*mrReader
.m_pPaM
->GetPoint());
887 ww::WordVersion eVer
= mrReader
.GetFib().GetFIBVersion();
889 // M.M. Create a linked section if the WkbPLCF
890 // has an entry for one at this cp
891 WW8PLCFspecial
* pWkb
= mrReader
.m_xPlcxMan
->GetWkbPLCF();
892 if (pWkb
&& pWkb
->SeekPosExact(nTextPos
) &&
893 pWkb
->Where() == nTextPos
)
897 bool bSuccess
= pWkb
->Get(nTest
, pData
);
900 OUString sSectionName
= mrReader
.m_aLinkStringMap
[SVBT16ToUInt16( static_cast<WW8_WKB
*>(pData
)->nLinkId
) ];
901 sSectionName
= mrReader
.ConvertFFileName(sSectionName
);
902 SwSectionData
aSection(SectionType::FileLink
, sSectionName
);
903 aSection
.SetLinkFileName( sSectionName
);
904 aSection
.SetProtectFlag(true);
905 // #i19922# - improvement: return value of method <Insert> not used.
906 mrReader
.m_rDoc
.InsertSwSection(*mrReader
.m_pPaM
, aSection
, nullptr, nullptr, false);
909 wwSection
aLastSection(*mrReader
.m_pPaM
->GetPoint());
910 if (!maSegments
.empty())
911 aLastSection
= maSegments
.back();
914 sal_uInt16 nLIdx
= ( ( static_cast<sal_uInt16
>(mrReader
.m_xWwFib
->m_lid
) & 0xff ) == 0x9 ) ? 1 : 0;
916 //BEGIN read section values
917 wwSection
aNewSection(*mrReader
.m_pPaM
->GetPoint());
919 static const sal_uInt16 aVer2Ids0
[] =
922 /*sprmSFTitlePage*/ 118,
924 /*sprmSCcolumns*/ 119,
925 /*sprmSDxaColumns*/ 120,
926 /*sprmSLBetween*/ 133
929 static const sal_uInt16 aVer67Ids0
[] =
931 NS_sprm::v6::sprmSBkc
,
932 NS_sprm::v6::sprmSFTitlePage
,
933 NS_sprm::v6::sprmSNfcPgn
,
934 NS_sprm::v6::sprmSCcolumns
,
935 NS_sprm::v6::sprmSDxaColumns
,
936 NS_sprm::v6::sprmSLBetween
939 static const sal_uInt16 aVer8Ids0
[] =
942 NS_sprm::SFTitlePage::val
,
943 NS_sprm::SNfcPgn::val
,
944 NS_sprm::SCcolumns::val
,
945 NS_sprm::SDxaColumns::val
,
946 NS_sprm::SLBetween::val
949 const sal_uInt16
* pIds
= eVer
<= ww::eWW2
? aVer2Ids0
: eVer
<= ww::eWW7
? aVer67Ids0
: aVer8Ids0
;
951 SprmResult aRes
= pSep
->HasSprm(pIds
[0]);
952 const sal_uInt8
* pSprmBkc
= aRes
.pSprm
;
953 if (!maSegments
.empty())
955 // Type of break: break codes are:
961 if (pSprmBkc
&& aRes
.nRemainingData
>= 1)
962 aNewSection
.maSep
.bkc
= *pSprmBkc
;
966 aNewSection
.maSep
.fTitlePage
=
967 sal_uInt8(0 != ReadBSprm( pSep
, pIds
[1], 0 ));
970 aNewSection
.maSep
.nfcPgn
= ReadBSprm( pSep
, pIds
[2], 0 );
971 if (aNewSection
.maSep
.nfcPgn
> 4)
972 aNewSection
.maSep
.nfcPgn
= 0;
974 aNewSection
.maSep
.fUnlocked
= eVer
> ww::eWW2
? ReadBSprm(pSep
, (eVer
<= ww::eWW7
? NS_sprm::v6::sprmSFProtected
: NS_sprm::SFProtected::val
), 0 ) : 0;
977 aNewSection
.maSep
.fBiDi
= eVer
>= ww::eWW8
? ReadBSprm(pSep
, NS_sprm::SFBiDi::val
, 0) : 0;
979 // Reading section property sprmSCcolumns - one less than the number of columns in the section.
980 // It must be less than MAX_NO_OF_SEP_COLUMNS according the WW8 specification.
981 aNewSection
.maSep
.ccolM1
= ReadSprm(pSep
, pIds
[3], 0 );
982 if ( aNewSection
.maSep
.ccolM1
>= MAX_NO_OF_SEP_COLUMNS
)
985 aNewSection
.maSep
.ccolM1
= MAX_NO_OF_SEP_COLUMNS
-1;
988 //sprmSDxaColumns - default distance 1.25 cm
989 aNewSection
.maSep
.dxaColumns
= ReadUSprm( pSep
, pIds
[4], 708 );
992 aNewSection
.maSep
.fLBetween
= ReadBSprm(pSep
, pIds
[5], 0 );
994 if (eVer
>= ww::eWW6
)
996 // sprmSFEvenlySpaced
997 aNewSection
.maSep
.fEvenlySpaced
=
998 sal_uInt8(ReadBSprm(pSep
, (eVer
<= ww::eWW7
? NS_sprm::v6::sprmSFEvenlySpaced
: NS_sprm::SFEvenlySpaced::val
), 1) != 0);
1000 if (aNewSection
.maSep
.ccolM1
> 0 && !aNewSection
.maSep
.fEvenlySpaced
)
1002 int nColumnDataIdx
= 0;
1003 aNewSection
.maSep
.rgdxaColumnWidthSpacing
[nColumnDataIdx
] = 0;
1005 const sal_uInt16 nColumnWidthSprmId
= ( eVer
<= ww::eWW7
? NS_sprm::v6::sprmSDxaColWidth
: NS_sprm::SDxaColWidth::val
);
1006 const sal_uInt16 nColumnSpacingSprmId
= ( eVer
<= ww::eWW7
? NS_sprm::v6::sprmSDxaColSpacing
: NS_sprm::SDxaColSpacing::val
);
1007 const sal_uInt8 nColumnCount
= static_cast< sal_uInt8
>(aNewSection
.maSep
.ccolM1
+ 1);
1008 for ( sal_uInt8 nColumn
= 0; nColumn
< nColumnCount
; ++nColumn
)
1011 SprmResult aSWRes
= pSep
->HasSprm(nColumnWidthSprmId
, nColumn
);
1012 const sal_uInt8
* pSW
= aSWRes
.pSprm
;
1014 OSL_ENSURE( pSW
, "+Sprm 136 (resp. 0xF203) (ColWidth) missing" );
1015 sal_uInt16 nWidth
= (pSW
&& aSWRes
.nRemainingData
>= 3) ? SVBT16ToUInt16(pSW
+ 1) : 1440;
1017 aNewSection
.maSep
.rgdxaColumnWidthSpacing
[++nColumnDataIdx
] = nWidth
;
1019 if ( nColumn
< nColumnCount
- 1 )
1021 //sprmSDxaColSpacing
1022 SprmResult aSDRes
= pSep
->HasSprm(nColumnSpacingSprmId
, nColumn
);
1023 const sal_uInt8
* pSD
= aSDRes
.pSprm
;
1025 OSL_ENSURE( pSD
, "+Sprm 137 (resp. 0xF204) (Colspacing) missing" );
1026 if (pSD
&& aSDRes
.nRemainingData
>= 3)
1028 nWidth
= SVBT16ToUInt16(pSD
+ 1);
1029 aNewSection
.maSep
.rgdxaColumnWidthSpacing
[++nColumnDataIdx
] = nWidth
;
1036 static const sal_uInt16 aVer2Ids1
[] =
1038 /*sprmSBOrientation*/ 137,
1039 /*sprmSXaPage*/ 139,
1040 /*sprmSYaPage*/ 140,
1041 /*sprmSDxaLeft*/ 141,
1042 /*sprmSDxaRight*/ 142,
1043 /*sprmSDzaGutter*/ 145,
1044 /*sprmSFPgnRestart*/ 125,
1045 /*sprmSPgnStart*/ 136,
1046 /*sprmSDmBinFirst*/ 115,
1047 /*sprmSDmBinOther*/ 116
1050 static const sal_uInt16 aVer67Ids1
[] =
1052 NS_sprm::v6::sprmSBOrientation
,
1053 NS_sprm::v6::sprmSXaPage
,
1054 NS_sprm::v6::sprmSYaPage
,
1055 NS_sprm::v6::sprmSDxaLeft
,
1056 NS_sprm::v6::sprmSDxaRight
,
1057 NS_sprm::v6::sprmSDzaGutter
,
1058 NS_sprm::v6::sprmSFPgnRestart
,
1059 NS_sprm::v6::sprmSPgnStart
,
1060 NS_sprm::v6::sprmSDmBinFirst
,
1061 NS_sprm::v6::sprmSDmBinOther
1064 static const sal_uInt16 aVer8Ids1
[] =
1066 NS_sprm::SBOrientation::val
,
1067 NS_sprm::SXaPage::val
,
1068 NS_sprm::SYaPage::val
,
1069 NS_sprm::SDxaLeft::val
,
1070 NS_sprm::SDxaRight::val
,
1071 NS_sprm::SDzaGutter::val
,
1072 NS_sprm::SFPgnRestart::val
,
1073 NS_sprm::SPgnStart97::val
,
1074 NS_sprm::SDmBinFirst::val
,
1075 NS_sprm::SDmBinOther::val
1078 pIds
= eVer
<= ww::eWW2
? aVer2Ids1
: eVer
<= ww::eWW7
? aVer67Ids1
: aVer8Ids1
;
1081 aNewSection
.maSep
.dmOrientPage
= ReadBSprm(pSep
, pIds
[0], 0);
1084 aNewSection
.maSep
.xaPage
= ReadUSprm(pSep
, pIds
[1], lLetterWidth
);
1085 aNewSection
.m_nPgWidth
= SvxPaperInfo::GetSloppyPaperDimension(aNewSection
.maSep
.xaPage
);
1087 aNewSection
.maSep
.yaPage
= ReadUSprm(pSep
, pIds
[2], lLetterHeight
);
1090 static const sal_uInt16 nLef
[] = { MM_250
, 1800 };
1091 static const sal_uInt16 nRig
[] = { MM_250
, 1800 };
1093 aNewSection
.maSep
.dxaLeft
= ReadUSprm( pSep
, pIds
[3], nLef
[nLIdx
]);
1094 aNewSection
.maSep
.dxaRight
= ReadUSprm( pSep
, pIds
[4], nRig
[nLIdx
]);
1096 // 2pages in 1sheet hackery ?
1097 // #i31806# but only swap if 2page in 1sheet is enabled.
1098 // it's not clear if dmOrientPage is the correct member to
1100 if(mrReader
.m_xWDop
->doptypography
.m_f2on1
&&
1101 aNewSection
.maSep
.dmOrientPage
== 2)
1102 std::swap(aNewSection
.maSep
.dxaLeft
, aNewSection
.maSep
.dxaRight
);
1104 aNewSection
.maSep
.dzaGutter
= ReadUSprm( pSep
, pIds
[5], 0);
1106 aNewSection
.maSep
.fRTLGutter
= static_cast<sal_uInt8
>(
1107 eVer
>= ww::eWW8
? ReadBSprm(pSep
, NS_sprm::SFRTLGutter::val
, 0) : 0);
1109 // Page Number Restarts - sprmSFPgnRestart
1110 aNewSection
.maSep
.fPgnRestart
= ReadBSprm(pSep
, pIds
[6], 0);
1112 aNewSection
.maSep
.pgnStart
= ReadUSprm( pSep
, pIds
[7], 0 );
1114 // if the document's first page number is unspecified, but it starts with an even page break,
1115 // then set the first page number to two
1116 if ( maSegments
.empty() && !aNewSection
.maSep
.fPgnRestart
&& pSprmBkc
&& *pSprmBkc
== 3 )
1118 aNewSection
.maSep
.pgnStart
= 2;
1119 aNewSection
.maSep
.fPgnRestart
= 1;
1122 if (eVer
>= ww::eWW6
)
1124 aRes
= pSep
->HasSprm(eVer
<= ww::eWW7
? NS_sprm::v6::sprmSiHeadingPgn
: NS_sprm::SiHeadingPgn::val
);
1125 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 1)
1126 aNewSection
.maSep
.iHeadingPgn
= *aRes
.pSprm
;
1128 aRes
= pSep
->HasSprm(eVer
<= ww::eWW7
? NS_sprm::v6::sprmSScnsPgn
: NS_sprm::ScnsPgn::val
);
1129 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 1)
1130 aNewSection
.maSep
.cnsPgn
= *aRes
.pSprm
;
1133 aRes
= pSep
->HasSprm(pIds
[8]);
1134 const sal_uInt8
* pSprmSDmBinFirst
= aRes
.pSprm
;
1135 if (pSprmSDmBinFirst
&& aRes
.nRemainingData
>= 1)
1136 aNewSection
.maSep
.dmBinFirst
= *pSprmSDmBinFirst
;
1138 aRes
= pSep
->HasSprm(pIds
[9]);
1139 const sal_uInt8
* pSprmSDmBinOther
= aRes
.pSprm
;
1140 if (pSprmSDmBinOther
&& aRes
.nRemainingData
>= 1)
1141 aNewSection
.maSep
.dmBinOther
= *pSprmSDmBinOther
;
1143 static const sal_uInt16 nTop
[] = { MM_250
, 1440 };
1144 static const sal_uInt16 nBot
[] = { MM_200
, 1440 };
1146 static const sal_uInt16 aVer2Ids2
[] =
1148 /*sprmSDyaTop*/ 143,
1149 /*sprmSDyaBottom*/ 144,
1150 /*sprmSDyaHdrTop*/ 131,
1151 /*sprmSDyaHdrBottom*/ 132,
1152 /*sprmSNLnnMod*/ 129,
1154 /*sprmSDxaLnn*/ 130,
1158 static const sal_uInt16 aVer67Ids2
[] =
1160 NS_sprm::v6::sprmSDyaTop
,
1161 NS_sprm::v6::sprmSDyaBottom
,
1162 NS_sprm::v6::sprmSDyaHdrTop
,
1163 NS_sprm::v6::sprmSDyaHdrBottom
,
1164 NS_sprm::v6::sprmSNLnnMod
,
1165 NS_sprm::v6::sprmSLnc
,
1166 NS_sprm::v6::sprmSDxaLnn
,
1167 NS_sprm::v6::sprmSLnnMin
1169 static const sal_uInt16 aVer8Ids2
[] =
1171 NS_sprm::SDyaTop::val
,
1172 NS_sprm::SDyaBottom::val
,
1173 NS_sprm::SDyaHdrTop::val
,
1174 NS_sprm::SDyaHdrBottom::val
,
1175 NS_sprm::SNLnnMod::val
,
1177 NS_sprm::SDxaLnn::val
,
1178 NS_sprm::SLnnMin::val
1181 pIds
= eVer
<= ww::eWW2
? aVer2Ids2
: eVer
<= ww::eWW7
? aVer67Ids2
: aVer8Ids2
;
1183 aNewSection
.maSep
.dyaTop
= ReadSprm( pSep
, pIds
[0], nTop
[nLIdx
] );
1184 aNewSection
.maSep
.dyaBottom
= ReadSprm( pSep
, pIds
[1], nBot
[nLIdx
] );
1185 aNewSection
.maSep
.dyaHdrTop
= ReadUSprm( pSep
, pIds
[2], 720 );
1186 aNewSection
.maSep
.dyaHdrBottom
= ReadUSprm( pSep
, pIds
[3], 720 );
1188 if (eVer
>= ww::eWW8
)
1190 aNewSection
.maSep
.wTextFlow
= ReadUSprm(pSep
, NS_sprm::STextFlow::val
, 0);
1191 aNewSection
.maSep
.clm
= ReadUSprm( pSep
, NS_sprm::SClm::val
, 0 );
1192 aNewSection
.maSep
.dyaLinePitch
= ReadUSprm(pSep
, NS_sprm::SDyaLinePitch::val
, 360);
1193 aRes
= pSep
->HasSprm(NS_sprm::SDxtCharSpace::val
);
1194 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 4)
1195 aNewSection
.maSep
.dxtCharSpace
= SVBT32ToUInt32(aRes
.pSprm
);
1198 sal_uInt16 pgbProp
= ReadSprm( pSep
, NS_sprm::SPgbProp::val
, 0 );
1199 aNewSection
.maSep
.pgbApplyTo
= pgbProp
& 0x0007;
1200 aNewSection
.maSep
.pgbPageDepth
= (pgbProp
& 0x0018) >> 3;
1201 aNewSection
.maSep
.pgbOffsetFrom
= (pgbProp
& 0x00E0) >> 5;
1203 aNewSection
.mnBorders
= ::lcl_ReadBorders(false, aNewSection
.m_brc
, nullptr, nullptr, pSep
);
1206 // check if Line Numbering must be activated or reset
1207 SprmResult aSprmSNLnnMod
= pSep
->HasSprm(pIds
[4]);
1208 if (aSprmSNLnnMod
.pSprm
&& aSprmSNLnnMod
.nRemainingData
>= 1)
1209 aNewSection
.maSep
.nLnnMod
= *aSprmSNLnnMod
.pSprm
;
1211 SprmResult aSprmSLnc
= pSep
->HasSprm(pIds
[5]);
1212 if (aSprmSLnc
.pSprm
&& aSprmSLnc
.nRemainingData
>= 1)
1213 aNewSection
.maSep
.lnc
= *aSprmSLnc
.pSprm
;
1215 SprmResult aSprmSDxaLnn
= pSep
->HasSprm(pIds
[6]);
1216 if (aSprmSDxaLnn
.pSprm
&& aSprmSDxaLnn
.nRemainingData
>= 2)
1217 aNewSection
.maSep
.dxaLnn
= SVBT16ToUInt16(aSprmSDxaLnn
.pSprm
);
1219 SprmResult aSprmSLnnMin
= pSep
->HasSprm(pIds
[7]);
1220 if (aSprmSLnnMin
.pSprm
&& aSprmSLnnMin
.nRemainingData
>= 1)
1221 aNewSection
.maSep
.lnnMin
= *aSprmSLnnMin
.pSprm
;
1223 if (eVer
<= ww::eWW7
)
1224 aNewSection
.maSep
.grpfIhdt
= ReadBSprm(pSep
, eVer
<= ww::eWW2
? 128 : 153, 0);
1225 else if (mrReader
.m_xHdFt
)
1227 aNewSection
.maSep
.grpfIhdt
= WW8_HEADER_ODD
| WW8_FOOTER_ODD
1228 | WW8_HEADER_FIRST
| WW8_FOOTER_FIRST
;
1230 // It is possible for a first page header to be provided
1231 // for this section, but not actually shown in this section. In this
1232 // case (aNewSection.maSep.grpfIhdt & WW8_HEADER_FIRST) will be nonzero
1233 // but aNewSection.HasTitlePage() will be false.
1234 // Likewise for first page footer.
1236 if (mrReader
.m_xWDop
->fFacingPages
)
1237 aNewSection
.maSep
.grpfIhdt
|= WW8_HEADER_EVEN
| WW8_FOOTER_EVEN
;
1239 //See if we have a header or footer for each enabled possibility
1240 //if we do not then we inherit the previous sections header/footer,
1241 for (int nI
= 0, nMask
= 1; nI
< 6; ++nI
, nMask
<<= 1)
1243 if (aNewSection
.maSep
.grpfIhdt
& nMask
)
1245 WW8_CP nStart
, nLen
;
1246 mrReader
.m_xHdFt
->GetTextPosExact( static_cast< short >(nI
+ ( maSegments
.size() + 1) * 6), nStart
, nLen
);
1247 //No header or footer, inherit previous one, or set to zero
1248 //if no previous one
1252 maSegments
.empty() ||
1253 !(maSegments
.back().maSep
.grpfIhdt
& nMask
)
1256 aNewSection
.maSep
.grpfIhdt
&= ~nMask
;
1263 SetLeftRight(aNewSection
);
1264 //END read section values
1266 if (eVer
>= ww::eWW8
)
1267 aNewSection
.SetDirection();
1269 mrReader
.HandleLineNumbering(aNewSection
);
1270 maSegments
.push_back(aNewSection
);
1273 void SwWW8ImplReader::CopyPageDescHdFt(const SwPageDesc
* pOrgPageDesc
,
1274 SwPageDesc
* pNewPageDesc
, sal_uInt8 nCode
)
1276 // copy odd header content section
1277 if( nCode
& WW8_HEADER_ODD
)
1279 m_rDoc
.CopyHeader(pOrgPageDesc
->GetMaster(),
1280 pNewPageDesc
->GetMaster() );
1282 // copy odd footer content section
1283 if( nCode
& WW8_FOOTER_ODD
)
1285 m_rDoc
.CopyFooter(pOrgPageDesc
->GetMaster(),
1286 pNewPageDesc
->GetMaster());
1288 // copy even header content section
1289 if( nCode
& WW8_HEADER_EVEN
)
1291 m_rDoc
.CopyHeader(pOrgPageDesc
->GetLeft(),
1292 pNewPageDesc
->GetLeft());
1294 // copy even footer content section
1295 if( nCode
& WW8_FOOTER_EVEN
)
1297 m_rDoc
.CopyFooter(pOrgPageDesc
->GetLeft(),
1298 pNewPageDesc
->GetLeft());
1300 // copy first page header content section
1301 if( nCode
& WW8_HEADER_FIRST
)
1303 m_rDoc
.CopyHeader(pOrgPageDesc
->GetFirstMaster(),
1304 pNewPageDesc
->GetFirstMaster());
1306 // copy first page footer content section
1307 if( nCode
& WW8_FOOTER_FIRST
)
1309 m_rDoc
.CopyFooter(pOrgPageDesc
->GetFirstMaster(),
1310 pNewPageDesc
->GetFirstMaster());
1314 // helper functions for graphics, Apos and tables
1316 // Read BoRder Control structure
1317 // nBrcVer should be set to the version of the BRC record being read (6, 8 or 9)
1318 // This will be converted to the latest format (9).
1319 static bool SetWW8_BRC(int nBrcVer
, WW8_BRCVer9
& rVar
, const sal_uInt8
* pS
, size_t nLen
)
1324 if (nBrcVer
== 9 && nLen
>= sizeof(WW8_BRCVer9
))
1325 rVar
= *reinterpret_cast<const WW8_BRCVer9
*>(pS
);
1326 else if (nBrcVer
== 8 && nLen
>= sizeof(WW8_BRC
))
1327 rVar
= WW8_BRCVer9(*reinterpret_cast<const WW8_BRC
*>(pS
));
1328 else if (nLen
>= sizeof(WW8_BRCVer6
)) // nBrcVer == 6
1329 rVar
= WW8_BRCVer9(WW8_BRC(*reinterpret_cast<const WW8_BRCVer6
*>(pS
)));
1332 return nullptr != pS
;
1335 static sal_uInt8
lcl_ReadBorders(bool bVer67
, WW8_BRCVer9
* brc
, WW8PLCFx_Cp_FKP
* pPap
,
1336 const WW8RStyle
* pSty
, const WW8PLCFx_SEPX
* pSep
)
1339 //returns a sal_uInt8 filled with a bit for each position that had a sprm
1340 //setting that border
1342 sal_uInt8 nBorder
= 0;
1347 SprmResult a8Sprm
[4];
1348 if (pSep
->Find4Sprms(
1349 NS_sprm::SBrcTop80::val
, NS_sprm::SBrcLeft80::val
,
1350 NS_sprm::SBrcBottom80::val
, NS_sprm::SBrcRight80::val
,
1351 a8Sprm
[0], a8Sprm
[1], a8Sprm
[2], a8Sprm
[3]))
1353 for( int i
= 0; i
< 4; ++i
)
1354 nBorder
|= int(SetWW8_BRC(8, brc
[i
], a8Sprm
[i
].pSprm
, a8Sprm
[i
].nRemainingData
))<<i
;
1357 // Version 9 BRCs if present will override version 8
1358 SprmResult a9Sprm
[4];
1359 if (pSep
->Find4Sprms(
1360 NS_sprm::SBrcTop::val
, NS_sprm::SBrcLeft::val
,
1361 NS_sprm::SBrcBottom::val
, NS_sprm::SBrcRight::val
,
1362 a9Sprm
[0], a9Sprm
[1], a9Sprm
[2], a9Sprm
[3]))
1364 for( int i
= 0; i
< 4; ++i
)
1365 nBorder
|= int(SetWW8_BRC(9, brc
[i
], a9Sprm
[i
].pSprm
, a9Sprm
[i
].nRemainingData
))<<i
;
1372 static const sal_uInt16 aVer67Ids
[5] = {
1373 NS_sprm::v6::sprmPBrcTop
,
1374 NS_sprm::v6::sprmPBrcLeft
,
1375 NS_sprm::v6::sprmPBrcBottom
,
1376 NS_sprm::v6::sprmPBrcRight
,
1377 NS_sprm::v6::sprmPBrcBetween
1380 static const sal_uInt16 aVer8Ids
[5] = {
1381 NS_sprm::PBrcTop80::val
,
1382 NS_sprm::PBrcLeft80::val
,
1383 NS_sprm::PBrcBottom80::val
,
1384 NS_sprm::PBrcRight80::val
,
1385 NS_sprm::PBrcBetween80::val
1388 static const sal_uInt16 aVer9Ids
[5] = {
1389 NS_sprm::PBrcTop::val
,
1390 NS_sprm::PBrcLeft::val
,
1391 NS_sprm::PBrcBottom::val
,
1392 NS_sprm::PBrcRight::val
,
1393 NS_sprm::PBrcBetween::val
1400 for( int i
= 0; i
< 5; ++i
)
1402 SprmResult
aRes(pPap
->HasSprm(aVer67Ids
[i
]));
1403 nBorder
|= int(SetWW8_BRC(6 , brc
[i
], aRes
.pSprm
, aRes
.nRemainingData
))<<i
;
1408 for( int i
= 0; i
< 5; ++i
)
1410 SprmResult
aRes(pPap
->HasSprm(aVer8Ids
[i
]));
1411 nBorder
|= int(SetWW8_BRC(8 , brc
[i
], aRes
.pSprm
, aRes
.nRemainingData
))<<i
;
1413 // Version 9 BRCs if present will override version 8
1414 for( int i
= 0; i
< 5; ++i
)
1416 SprmResult
aRes(pPap
->HasSprm(aVer9Ids
[i
]));
1417 nBorder
|= int(SetWW8_BRC(9 , brc
[i
], aRes
.pSprm
, aRes
.nRemainingData
))<<i
;
1425 for( int i
= 0; i
< 5; ++i
)
1427 SprmResult
aRes(pSty
->HasParaSprm(aVer67Ids
[i
]));
1428 nBorder
|= int(SetWW8_BRC(6 , brc
[i
], aRes
.pSprm
, aRes
.nRemainingData
))<<i
;
1433 for( int i
= 0; i
< 5; ++i
)
1435 SprmResult
aRes(pSty
->HasParaSprm(aVer8Ids
[i
]));
1436 nBorder
|= int(SetWW8_BRC(8 , brc
[i
], aRes
.pSprm
, aRes
.nRemainingData
))<<i
;
1438 // Version 9 BRCs if present will override version 8
1439 for( int i
= 0; i
< 5; ++i
)
1441 SprmResult
aRes(pSty
->HasParaSprm(aVer9Ids
[i
]));
1442 nBorder
|= int(SetWW8_BRC(9 , brc
[i
], aRes
.pSprm
, aRes
.nRemainingData
))<<i
;
1447 OSL_ENSURE( pSty
|| pPap
, "WW8PLCFx_Cp_FKP and WW8RStyle "
1448 "and WW8PLCFx_SEPX is 0" );
1455 static void GetLineIndex(SvxBoxItem
&rBox
, short nLineThickness
, short nSpace
,
1456 sal_uInt32 cv
, short nIdx
, SvxBoxItemLine nOOIndex
, sal_uInt16 nWWIndex
,
1459 // LO cannot handle outset/inset (new in WW9 BRC) so fall back same as WW8
1460 if ( nIdx
== 0x1A || nIdx
== 0x1B )
1462 nIdx
= (nIdx
== 0x1A) ? 0x12 : 0x11;
1466 SvxBorderLineStyle
const eStyle(
1467 ::editeng::ConvertBorderStyleFromWord(nIdx
));
1469 ::editeng::SvxBorderLine aLine
;
1470 aLine
.SetBorderLineStyle( eStyle
);
1471 double const fConverted( (SvxBorderLineStyle::NONE
== eStyle
) ? 0.0 :
1472 ::editeng::ConvertBorderWidthFromWord(eStyle
, nLineThickness
, nIdx
));
1473 aLine
.SetWidth(fConverted
);
1475 //No AUTO for borders as yet, so if AUTO, use BLACK
1476 Color col
= (cv
==0xff000000) ? COL_BLACK
: msfilter::util::BGRToRGB(cv
);
1478 aLine
.SetColor(col
);
1481 pSize
[nWWIndex
] = fConverted
+ nSpace
;
1483 rBox
.SetLine(&aLine
, nOOIndex
);
1484 rBox
.SetDistance(nSpace
, nOOIndex
);
1488 static void Set1Border(SvxBoxItem
&rBox
, const WW8_BRCVer9
& rBor
, SvxBoxItemLine nOOIndex
,
1489 sal_uInt16 nWWIndex
, short *pSize
, const bool bIgnoreSpace
)
1492 short nLineThickness
= rBor
.DetermineBorderProperties(&nSpace
);
1494 GetLineIndex(rBox
, nLineThickness
, bIgnoreSpace
? 0 : nSpace
,
1495 rBor
.cv(), rBor
.brcType(), nOOIndex
, nWWIndex
, pSize
);
1499 static bool lcl_IsBorder(const WW8_BRCVer9
* pbrc
, bool bChkBtwn
= false)
1501 return pbrc
[WW8_TOP
].brcType() || // brcType != 0
1502 pbrc
[WW8_LEFT
].brcType() ||
1503 pbrc
[WW8_BOT
].brcType() ||
1504 pbrc
[WW8_RIGHT
].brcType() ||
1505 (bChkBtwn
&& pbrc
[WW8_BETW
].brcType());
1508 bool SwWW8ImplReader::IsBorder(const WW8_BRCVer9
* pbrc
, bool bChkBtwn
)
1510 return lcl_IsBorder(pbrc
, bChkBtwn
);
1513 bool SwWW8ImplReader::SetBorder(SvxBoxItem
& rBox
, const WW8_BRCVer9
* pbrc
,
1514 short *pSizeArray
, sal_uInt8 nSetBorders
)
1516 bool bChange
= false;
1517 static const std::pair
<sal_uInt16
, SvxBoxItemLine
> aIdArr
[] =
1519 { WW8_TOP
, SvxBoxItemLine::TOP
},
1520 { WW8_LEFT
, SvxBoxItemLine::LEFT
},
1521 { WW8_RIGHT
, SvxBoxItemLine::RIGHT
},
1522 { WW8_BOT
, SvxBoxItemLine::BOTTOM
},
1523 { WW8_BETW
, SvxBoxItemLine::BOTTOM
}
1526 for( int i
= 0; i
< 4; ++i
)
1528 // filter out the invalid borders
1529 const WW8_BRCVer9
& rB
= pbrc
[ aIdArr
[ i
].first
];
1530 if( !rB
.isNil() && rB
.brcType() )
1532 Set1Border(rBox
, rB
, aIdArr
[i
].second
, aIdArr
[i
].first
, pSizeArray
, false);
1535 else if ( nSetBorders
& (1 << aIdArr
[i
].first
) )
1540 If a style has borders set,and the para attributes attempt remove
1541 the borders, then this is perfectly acceptable, so we shouldn't
1542 ignore this blank entry
1544 nSetBorders has a bit set for each location that a sprm set a
1545 border, so with a sprm set, but no border, then disable the
1548 rBox
.SetLine( nullptr, aIdArr
[ i
].second
);
1554 bool SwWW8ImplReader::SetShadow(SvxShadowItem
& rShadow
, const short *pSizeArray
,
1555 const WW8_BRCVer9
& aRightBrc
)
1557 bool bRet
= aRightBrc
.fShadow() && pSizeArray
&& pSizeArray
[WW8_RIGHT
];
1560 rShadow
.SetColor(COL_BLACK
);
1562 short nVal
= aRightBrc
.DetermineBorderProperties();
1566 rShadow
.SetWidth(nVal
);
1567 rShadow
.SetLocation(SvxShadowLocation::BottomRight
);
1573 void SwWW8ImplReader::GetBorderDistance(const WW8_BRCVer9
* pbrc
,
1574 tools::Rectangle
& rInnerDist
)
1576 rInnerDist
= tools::Rectangle( pbrc
[ 1 ].dptSpace() * 20,
1577 pbrc
[ 0 ].dptSpace() * 20,
1578 pbrc
[ 3 ].dptSpace() * 20,
1579 pbrc
[ 2 ].dptSpace() * 20 );
1582 bool SwWW8ImplReader::SetFlyBordersShadow(SfxItemSet
& rFlySet
,
1583 const WW8_BRCVer9
*pbrc
, short *pSizeArray
)
1585 bool bShadowed
= false;
1588 SvxBoxItem
aBox( RES_BOX
);
1589 SetBorder(aBox
, pbrc
, pSizeArray
);
1591 rFlySet
.Put( aBox
);
1594 SvxShadowItem
aShadow( RES_SHADOW
);
1595 if( SetShadow( aShadow
, pSizeArray
, pbrc
[WW8_RIGHT
] ))
1598 rFlySet
.Put( aShadow
);
1606 // for computing the minimal FrameSize
1607 #define MAX_BORDER_SIZE 210 // max. size of border
1608 #define MAX_EMPTY_BORDER 10 // for off-by-one errors, at least 1
1610 static void FlySecur1(short& rSize
, const bool bBorder
)
1612 short nMin
= MINFLY
+
1613 (bBorder
? MAX_BORDER_SIZE
: MAX_EMPTY_BORDER
);
1619 static bool SetValSprm( sal_Int16
* pVar
, WW8PLCFx_Cp_FKP
* pPap
, sal_uInt16 nId
)
1621 SprmResult aS
= pPap
->HasSprm(nId
);
1622 if (aS
.pSprm
&& aS
.nRemainingData
>= 2)
1623 *pVar
= static_cast<sal_Int16
>(SVBT16ToUInt16(aS
.pSprm
));
1624 return aS
.pSprm
!= nullptr;
1627 static bool SetValSprm( sal_Int16
* pVar
, const WW8RStyle
* pStyle
, sal_uInt16 nId
)
1629 SprmResult aS
= pStyle
->HasParaSprm(nId
);
1630 if (aS
.pSprm
&& aS
.nRemainingData
>= 2)
1631 *pVar
= static_cast<sal_Int16
>(SVBT16ToUInt16(aS
.pSprm
));
1632 return aS
.pSprm
!= nullptr;
1636 #i1930 revealed that sprm 0x360D (sprmTPc) as used in tables can affect the frame
1637 around the table. Its full structure is not fully understood as yet.
1639 void WW8FlyPara::ApplyTabPos(const WW8_TablePos
*pTabPos
)
1643 nTDxaAbs
= pTabPos
->nTDxaAbs
;
1644 nTDyaAbs
= pTabPos
->nTDyaAbs
;
1645 nTPc
= pTabPos
->nTPc
;
1646 nLeftMargin
= pTabPos
->nLeftMargin
;
1647 nRightMargin
= pTabPos
->nRightMargin
;
1648 nUpperMargin
= pTabPos
->nUpperMargin
;
1649 nLowerMargin
= pTabPos
->nLowerMargin
;
1650 nPWr
= pTabPos
->nPWr
;
1654 WW8FlyPara::WW8FlyPara(bool bIsVer67
, const WW8FlyPara
* pSrc
/* = 0 */)
1657 memcpy( this, pSrc
, sizeof( WW8FlyPara
) ); // Copy-Ctor
1669 nPWr
= 2; // Default: wrapping
1670 bBorderLines
= false;
1677 bool WW8FlyPara::operator==(const WW8FlyPara
& rSrc
) const
1680 Compare the parts that word seems to compare for equivalence.
1681 Interestingly being autoheight or absolute height (the & 0x7fff) doesn't
1686 (nTDxaAbs
== rSrc
.nTDxaAbs
) &&
1687 (nTDyaAbs
== rSrc
.nTDyaAbs
) &&
1688 ((nSp45
& 0x7fff) == (rSrc
.nSp45
& 0x7fff)) &&
1689 (nSp28
== rSrc
.nSp28
) &&
1690 (nLeftMargin
== rSrc
.nLeftMargin
) &&
1691 (nRightMargin
== rSrc
.nRightMargin
) &&
1692 (nUpperMargin
== rSrc
.nUpperMargin
) &&
1693 (nLowerMargin
== rSrc
.nLowerMargin
) &&
1694 (nTPc
== rSrc
.nTPc
) &&
1699 // Read for normal text
1700 void WW8FlyPara::Read(sal_uInt8 nOrigSprmTPc
, WW8PLCFx_Cp_FKP
* pPap
)
1704 SetValSprm( &nTDxaAbs
, pPap
, 26 ); // X-position //sprmPDxaAbs
1705 //set in me or in parent style
1706 mbVertSet
|= SetValSprm( &nTDyaAbs
, pPap
, 27 ); // Y-position //sprmPDyaAbs
1707 SetValSprm( &nSp45
, pPap
, 45 ); // height //sprmPWHeightAbs
1708 SetValSprm( &nSp28
, pPap
, 28 ); // width //sprmPDxaWidth
1709 SetValSprm( &nLeftMargin
, pPap
, 49 ); // L-border //sprmPDxaFromText
1710 SetValSprm( &nRightMargin
, pPap
, 49 ); // R-border //sprmPDxaFromText
1711 SetValSprm( &nUpperMargin
, pPap
, 48 ); // U-border //sprmPDyaFromText
1712 SetValSprm( &nLowerMargin
, pPap
, 48 ); // D-border //sprmPDyaFromText
1714 SprmResult aS
= pPap
->HasSprm(NS_sprm::v6::sprmPWr
);
1715 if (aS
.pSprm
&& aS
.nRemainingData
>= 1)
1720 SetValSprm( &nTDxaAbs
, pPap
, NS_sprm::PDxaAbs::val
); // X-position
1721 //set in me or in parent style
1722 mbVertSet
|= SetValSprm( &nTDyaAbs
, pPap
, NS_sprm::PDyaAbs::val
); // Y-position
1723 SetValSprm( &nSp45
, pPap
, NS_sprm::PWHeightAbs::val
); // height
1724 SetValSprm( &nSp28
, pPap
, NS_sprm::PDxaWidth::val
); // width
1725 SetValSprm( &nLeftMargin
, pPap
, NS_sprm::PDxaFromText::val
); // L-border
1726 SetValSprm( &nRightMargin
, pPap
, NS_sprm::PDxaFromText::val
); // R-border
1727 SetValSprm( &nUpperMargin
, pPap
, NS_sprm::PDyaFromText::val
); // U-border
1728 SetValSprm( &nLowerMargin
, pPap
, NS_sprm::PDyaFromText::val
); // D-border
1730 SprmResult aS
= pPap
->HasSprm(NS_sprm::PWr::val
); // wrapping
1731 if (aS
.pSprm
&& aS
.nRemainingData
>= 1)
1735 if( ::lcl_ReadBorders( bVer67
, brc
, pPap
)) // borders
1736 bBorderLines
= ::lcl_IsBorder( brc
);
1740 Appears that with no dyaAbs set then the actual vert anchoring set is
1741 ignored and we remain relative to text, so if that is the case we are 0
1742 from para anchor, so we update the frame to have explicitly this type of
1746 nTPc
= (nOrigSprmTPc
& 0xCF) | 0x20;
1748 nTPc
= nOrigSprmTPc
;
1751 void WW8FlyPara::ReadFull(sal_uInt8 nOrigSprmTPc
, SwWW8ImplReader
* pIo
)
1753 std::shared_ptr
<WW8PLCFMan
> xPlcxMan
= pIo
->m_xPlcxMan
;
1754 WW8PLCFx_Cp_FKP
* pPap
= xPlcxMan
->GetPapPLCF();
1756 Read(nOrigSprmTPc
, pPap
); // read Apo parameter
1758 do{ // block for quick exit
1759 if( nSp45
!= 0 /* || nSp28 != 0 */ )
1760 break; // bGrafApo only automatic for height
1761 if( pIo
->m_xWwFib
->m_fComplex
)
1762 break; // (*pPap)++ does not work for FastSave
1763 // -> for FastSave, no test for graphics APO
1764 SvStream
* pIoStrm
= pIo
->m_pStrm
;
1765 sal_uInt64 nPos
= pIoStrm
->Tell();
1766 WW8PLCFxSave1 aSave
;
1767 xPlcxMan
->GetPap()->Save( aSave
);
1770 do{ // block for quick exit
1773 if (!checkRead(*pIoStrm
, nText
, 2)) // read text
1776 if( nText
[0] != 0x01 || nText
[1] != 0x0d )// only graphics + CR?
1779 pPap
->advance(); // next line
1783 SprmResult aS
= pPap
->HasSprm( bVer67
? NS_sprm::v6::sprmPPc
: NS_sprm::PPc::val
);
1785 // no -> graphics Apo
1786 if (!aS
.pSprm
|| aS
.nRemainingData
< 1)
1789 break; // end of APO
1792 ww::WordVersion eVer
= pIo
->GetFib().GetFIBVersion();
1793 WW8FlyPara
*pNowStyleApo
=nullptr;
1794 sal_uInt16 nColl
= pPap
->GetIstd();
1796 o3tl::sorted_vector
<sal_uInt16
> aSeenStyles
;
1797 ww::sti eSti
= eVer
< ww::eWW6
? ww::GetCanonicalStiFromStc(nColl
) : static_cast<ww::sti
>(nColl
);
1798 while (eSti
!= ww::stiNil
&& static_cast<size_t>(nColl
) < pIo
->m_vColl
.size() && nullptr == (pNowStyleApo
= pIo
->m_vColl
[nColl
].m_xWWFly
.get()))
1800 aSeenStyles
.insert(nColl
);
1802 nColl
= pIo
->m_vColl
[nColl
].m_nBase
;
1804 if (aSeenStyles
.find(nColl
) != aSeenStyles
.end())
1806 SAL_WARN("sw.ww8", "loop in style chain");
1810 eSti
= eVer
< ww::eWW6
? ww::GetCanonicalStiFromStc(nColl
) : static_cast<ww::sti
>(nColl
);
1813 WW8FlyPara
aF(bVer67
, pNowStyleApo
);
1814 // new FlaPara for comparison
1815 aF
.Read(*aS
.pSprm
, pPap
); // WWPara for new Para
1816 if( !( aF
== *this ) ) // same APO? (or a new one?)
1817 bGrafApo
= true; // no -> 1-line APO
1820 while( false ); // block for quick exit
1822 xPlcxMan
->GetPap()->Restore( aSave
);
1823 pIoStrm
->Seek( nPos
);
1824 }while( false ); // block for quick exit
1827 // read for Apo definitions in Styledefs
1828 void WW8FlyPara::Read(sal_uInt8 nOrigSprmTPc
, WW8RStyle
const * pStyle
)
1832 SetValSprm( &nTDxaAbs
, pStyle
, NS_sprm::v6::sprmPDxaAbs
); // X-position
1833 //set in me or in parent style
1834 mbVertSet
|= SetValSprm(&nTDyaAbs
, pStyle
, NS_sprm::v6::sprmPDyaAbs
); // Y-position
1835 SetValSprm( &nSp45
, pStyle
, NS_sprm::v6::sprmPWHeightAbs
); // height
1836 SetValSprm( &nSp28
, pStyle
, NS_sprm::v6::sprmPDxaWidth
); // width
1837 SetValSprm( &nLeftMargin
, pStyle
, NS_sprm::v6::sprmPDxaFromText
); // L-border
1838 SetValSprm( &nRightMargin
, pStyle
, NS_sprm::v6::sprmPDxaFromText
); // R-border
1839 SetValSprm( &nUpperMargin
, pStyle
, NS_sprm::v6::sprmPDyaFromText
); // U-border
1840 SetValSprm( &nLowerMargin
, pStyle
, NS_sprm::v6::sprmPDyaFromText
); // D-border
1842 SprmResult aS
= pStyle
->HasParaSprm( NS_sprm::v6::sprmPWr
); // wrapping
1843 if (aS
.pSprm
&& aS
.nRemainingData
>= 1)
1848 SetValSprm( &nTDxaAbs
, pStyle
, NS_sprm::PDxaAbs::val
); // X-position
1849 //set in me or in parent style
1850 mbVertSet
|= SetValSprm(&nTDyaAbs
, pStyle
, NS_sprm::PDyaAbs::val
); // Y-position
1851 SetValSprm( &nSp45
, pStyle
, NS_sprm::PWHeightAbs::val
); // height
1852 SetValSprm( &nSp28
, pStyle
, NS_sprm::PDxaWidth::val
); // width
1853 SetValSprm( &nLeftMargin
, pStyle
, NS_sprm::PDxaFromText::val
); // L-border
1854 SetValSprm( &nRightMargin
, pStyle
, NS_sprm::PDxaFromText::val
); // R-border
1855 SetValSprm( &nUpperMargin
, pStyle
, NS_sprm::PDyaFromText::val
); // U-border
1856 SetValSprm( &nLowerMargin
, pStyle
, NS_sprm::PDyaFromText::val
); // D-border
1858 SprmResult aS
= pStyle
->HasParaSprm( NS_sprm::PWr::val
); // wrapping
1859 if (aS
.pSprm
&& aS
.nRemainingData
>= 1)
1863 if (::lcl_ReadBorders(bVer67
, brc
, nullptr, pStyle
)) // border
1864 bBorderLines
= ::lcl_IsBorder(brc
);
1868 Appears that with no dyaAbs set then the actual vert anchoring set is
1869 ignored and we remain relative to text, so if that is the case we are 0
1870 from para anchor, so we update the frame to have explicitly this type of
1874 nTPc
= (nOrigSprmTPc
& 0xCF) | 0x20;
1876 nTPc
= nOrigSprmTPc
;
1879 bool WW8FlyPara::IsEmpty() const
1881 WW8FlyPara
aEmpty(bVer67
);
1883 wr of 0 like 2 appears to me to be equivalent for checking here. See
1884 #107103# if wrong, so given that the empty is 2, if we are 0 then set
1885 empty to 0 to make 0 equiv to 2 for empty checking
1887 OSL_ENSURE(aEmpty
.nPWr
== 2, "this is not what we expect for nPWr");
1888 if (this->nPWr
== 0)
1890 return aEmpty
== *this;
1893 // #i18732# - changes made on behalf of CMC
1894 WW8SwFlyPara::WW8SwFlyPara( SwPaM
& rPaM
,
1895 SwWW8ImplReader
& rIo
,
1897 const sal_uInt32 nWWPgTop
,
1898 const sal_uInt32 nPgWidth
,
1899 const sal_Int32 nIniFlyDx
,
1900 const sal_Int32 nIniFlyDy
):
1903 nLeftMargin(rWW
.nLeftMargin
),
1904 nRightMargin(rWW
.nRightMargin
),
1905 nUpperMargin(rWW
.nUpperMargin
),
1906 nLowerMargin(rWW
.nLowerMargin
),
1909 nNetWidth(rWW
.nSp28
),
1910 eHeightFix(SwFrameSize::Fixed
),
1911 eHRel(text::RelOrientation::PAGE_FRAME
),
1912 eVRel(text::RelOrientation::FRAME
),
1913 eVAlign(text::VertOrientation::NONE
),
1914 eHAlign(text::HoriOrientation::NONE
),
1915 nXBind(( rWW
.nTPc
& 0xc0 ) >> 6),
1916 nYBind(( rWW
.nTPc
& 0x30 ) >> 4),
1917 nNewNetWidth(MINFLY
),
1924 case 0: // ST_Wrap: auto
1925 eSurround
= css::text::WrapTextMode_DYNAMIC
;
1927 case 1: // ST_Wrap: notBeside
1928 case 3: // ST_Wrap: none
1929 eSurround
= css::text::WrapTextMode_NONE
;
1931 case 2: // ST_Wrap: around
1932 case 4: // ST_Wrap: tight
1933 eSurround
= css::text::WrapTextMode_PARALLEL
;
1935 case 5: // St_Wrap: through
1936 eSurround
= css::text::WrapTextMode_THROUGH
;
1939 eSurround
= css::text::WrapTextMode_DYNAMIC
;
1943 #95905#, #83307# seems to have gone away now, so re-enable parallel
1944 wrapping support for frames in headers/footers. I don't know if we truly
1945 have an explicitly specified behaviour for these circumstances.
1948 if( nHeight
& 0x8000 )
1951 eHeightFix
= SwFrameSize::Minimum
;
1954 if( nHeight
<= MINFLY
)
1955 { // no data, or bad data
1956 eHeightFix
= SwFrameSize::Minimum
;
1960 if( nWidth
<= 10 ) // auto width
1963 nWidth
= nNetWidth
=
1964 msword_cast
<sal_Int16
>(nPgWidth
? nPgWidth
: 2268); // 4 cm
1966 if( nWidth
<= MINFLY
)
1967 nWidth
= nNetWidth
= MINFLY
; // minimum width
1970 See issue #i9178# for the 9 anchoring options, and make sure they stay
1971 working if you modify the anchoring logic here.
1974 // If the Fly is aligned left, right, up, or down,
1975 // the outer text distance will be ignored, because otherwise
1976 // the Fly will end up in the wrong position.
1977 // The only problem is with inside/outside.
1979 //#i53725# - absolute positioned objects have to be
1980 // anchored at-paragraph to assure its correct anchor position.
1981 rIo
.m_oLastAnchorPos
.emplace(*rPaM
.GetPoint());
1985 case 0: //relative to margin
1986 eVRel
= text::RelOrientation::PAGE_PRINT_AREA
;
1988 case 1: //relative to page
1989 eVRel
= text::RelOrientation::PAGE_FRAME
;
1991 default: //relative to text
1992 // put in initialization part eVRel = text::RelOrientation::FRAME;
1997 switch( rWW
.nTDyaAbs
) // particular Y-positions ?
2000 // Specifies that the parent object shall be vertically aligned in line
2001 // with the surrounding text (i.e. shall not allow any text wrapping around it)
2002 eVRel
= text::RelOrientation::FRAME
;
2005 eVAlign
= text::VertOrientation::TOP
;
2010 eVAlign
= text::VertOrientation::CENTER
;
2013 eVAlign
= text::VertOrientation::BOTTOM
;
2018 nYPos
= rWW
.nTDyaAbs
+ static_cast<short>(nIniFlyDy
);
2019 break; // corrections from ini file
2022 switch( rWW
.nTDxaAbs
) // particular X-positions ?
2025 eHAlign
= text::HoriOrientation::LEFT
;
2029 eHAlign
= text::HoriOrientation::CENTER
;
2032 eHAlign
= text::HoriOrientation::RIGHT
;
2036 eHAlign
= text::HoriOrientation::LEFT
;
2040 eHAlign
= text::HoriOrientation::RIGHT
;
2044 nXPos
= rWW
.nTDxaAbs
+ static_cast<short>(nIniFlyDx
);
2045 break; // corrections from ini file
2049 switch (nXBind
) // X - binding -> transform coordinates
2051 case 0: //relative to column
2052 eHRel
= text::RelOrientation::FRAME
;
2054 case 1: //relative to margin
2055 eHRel
= text::RelOrientation::PAGE_PRINT_AREA
;
2057 default: //relative to page
2058 // put in initialization part eHRel= text::RelOrientation::PAGE_FRAME;
2062 // #i36649# - adjustments for certain horizontal alignments
2063 // Note: These special adjustments found by an investigation of documents
2064 // containing frames with different left/right border distances and
2065 // distances to text. The outcome is somehow strange.
2066 // Note: These adjustments causes wrong horizontal positions for frames,
2067 // which are aligned inside|outside to page|margin on even pages,
2068 // the left and right border distances are different.
2069 // no adjustments possible, if frame has automatic width.
2070 // determine left border distance
2071 sal_Int16
nLeBorderMgn( 0 );
2074 WW8_BRCVer9
&rBrc
= rWW
.brc
[WW8_LEFT
];
2075 sal_Int16 nTemp
= rBrc
.DetermineBorderProperties(&nLeBorderMgn
);
2076 nLeBorderMgn
= nLeBorderMgn
+ nTemp
;
2078 // determine right border distance
2079 sal_Int16
nRiBorderMgn( 0 );
2082 WW8_BRCVer9
&rBrc
= rWW
.brc
[WW8_RIGHT
];
2083 sal_Int16 nTemp
= rBrc
.DetermineBorderProperties(&nRiBorderMgn
);
2084 nRiBorderMgn
= nRiBorderMgn
+ nTemp
;
2086 if ( !bAutoWidth
&& eHAlign
== text::HoriOrientation::LEFT
&& eHRel
== text::RelOrientation::PAGE_FRAME
)
2088 // convert 'left to page' to
2089 // 'from left -<width>-<2*left border distance>-<right wrap distance>
2090 // to page text area'
2091 eHAlign
= text::HoriOrientation::NONE
;
2092 eHRel
= text::RelOrientation::PAGE_PRINT_AREA
;
2093 nXPos
= -nWidth
- (2*nLeBorderMgn
) - rWW
.nRightMargin
;
2094 // re-set left wrap distance
2095 nLeftMargin
= rWW
.nLeftMargin
;
2097 else if ( !bAutoWidth
&& eHAlign
== text::HoriOrientation::RIGHT
&& eHRel
== text::RelOrientation::PAGE_FRAME
)
2099 // convert 'right to page' to
2100 // 'from left <right border distance-left border distance>+<left wrap distance>
2101 // to right page border'
2102 eHAlign
= text::HoriOrientation::NONE
;
2103 eHRel
= text::RelOrientation::PAGE_RIGHT
;
2104 nXPos
= ( nRiBorderMgn
- nLeBorderMgn
) + rWW
.nLeftMargin
;
2105 // re-set right wrap distance
2106 nRightMargin
= rWW
.nRightMargin
;
2108 else if ( !bAutoWidth
&& eHAlign
== text::HoriOrientation::LEFT
&& eHRel
== text::RelOrientation::PAGE_PRINT_AREA
)
2110 // convert 'left to margin' to
2111 // 'from left -<left border distance> to page text area'
2112 eHAlign
= text::HoriOrientation::NONE
;
2113 eHRel
= text::RelOrientation::PAGE_PRINT_AREA
;
2114 nXPos
= -nLeBorderMgn
;
2115 // re-set left wrap distance
2116 nLeftMargin
= rWW
.nLeftMargin
;
2118 else if ( !bAutoWidth
&& eHAlign
== text::HoriOrientation::RIGHT
&& eHRel
== text::RelOrientation::PAGE_PRINT_AREA
)
2120 // convert 'right to margin' to
2121 // 'from left -<width>-<left border distance> to right page border'
2122 eHAlign
= text::HoriOrientation::NONE
;
2123 eHRel
= text::RelOrientation::PAGE_RIGHT
;
2124 nXPos
= -nWidth
- nLeBorderMgn
;
2125 // re-set right wrap distance
2126 nRightMargin
= rWW
.nRightMargin
;
2128 else if (rWW
.bBorderLines
)
2132 Word has a curious bug where the offset stored do not take into
2133 account the internal distance from the corner both
2135 WW8_BRCVer9
&rBrc
= rWW
.brc
[WW8_LEFT
];
2136 sal_Int16 nLeLMgn
= 0;
2137 sal_Int16 nTemp
= rBrc
.DetermineBorderProperties(&nLeLMgn
);
2138 nLeLMgn
= nLeLMgn
+ nTemp
;
2142 if (eHAlign
== text::HoriOrientation::LEFT
)
2143 eHAlign
= text::HoriOrientation::NONE
;
2144 nXPos
= nXPos
- nLeLMgn
;
2148 // adjustments for certain vertical alignments
2149 if ( eVAlign
== text::VertOrientation::NONE
&& eVRel
== text::RelOrientation::PAGE_PRINT_AREA
)
2151 // convert "<X> from top page text area" to
2152 // "<X + page top margin> from page"
2153 eVRel
= text::RelOrientation::PAGE_FRAME
;
2154 nYPos
= static_cast< sal_Int16
>( nYPos
+ nWWPgTop
);
2157 FlySecur1( nWidth
, rWW
.bBorderLines
); // Do the borders match ?
2158 FlySecur1( nHeight
, rWW
.bBorderLines
);
2162 // If a Fly in WW has automatic width, this has to be simulated
2163 // by modifying the Fly width (fixed in SW) afterwards.
2164 // This can increase or decrease the Fly width, because the default value
2165 // is set without knowledge of the contents.
2166 void WW8SwFlyPara::BoxUpWidth( tools::Long nInWidth
)
2168 if( bAutoWidth
&& nInWidth
> nNewNetWidth
)
2169 nNewNetWidth
= nInWidth
;
2172 SwFlyFrameFormat
* WW8SwFlyPara::GetFlyFormat() const
2176 return static_cast<SwFlyFrameFormat
*>(m_xFlyFormat
->GetFormat());
2179 void WW8SwFlyPara::SetFlyFormat(SwFlyFrameFormat
* pNewFlyFormat
)
2182 m_xFlyFormat
.reset(new FrameDeleteWatch(pNewFlyFormat
));
2184 m_xFlyFormat
.reset();
2187 // The class WW8FlySet is derived from SfxItemSetFixed and does not
2188 // provide more, but is easier to handle for me.
2189 // WW8FlySet-ctor for Apos and graphics Apos
2190 WW8FlySet::WW8FlySet(SwWW8ImplReader
& rReader
, const WW8FlyPara
* pFW
,
2191 const WW8SwFlyPara
* pFS
, bool bGraf
)
2192 : SfxItemSetFixed(rReader
.m_rDoc
.GetAttrPool())
2194 Reader::ResetFrameFormatAttrs(*this); // remove distance/border
2196 Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_LR_TB
, RES_FRAMEDIR
));
2198 /*Below can all go when we have from left in rtl mode*/
2199 SwTwips nXPos
= pFS
->nXPos
;
2200 sal_Int16 eHRel
= pFS
->eHRel
;
2201 rReader
.MiserableRTLGraphicsHack(nXPos
, pFS
->nWidth
, pFS
->eHAlign
, eHRel
);
2202 /*Above can all go when we have from left in rtl mode*/
2203 Put( SwFormatHoriOrient(nXPos
, pFS
->eHAlign
, pFS
->eHRel
, pFS
->bTogglePos
));
2204 Put( SwFormatVertOrient( pFS
->nYPos
, pFS
->eVAlign
, pFS
->eVRel
) );
2206 if (pFS
->nLeftMargin
|| pFS
->nRightMargin
) // set borders
2207 Put(SvxLRSpaceItem(pFS
->nLeftMargin
, pFS
->nRightMargin
, 0, RES_LR_SPACE
));
2209 if (pFS
->nUpperMargin
|| pFS
->nLowerMargin
)
2210 Put(SvxULSpaceItem(pFS
->nUpperMargin
, pFS
->nLowerMargin
, RES_UL_SPACE
));
2212 //we no longer need to hack around the header/footer problems
2213 SwFormatSurround
aSurround(pFS
->eSurround
);
2214 if ( pFS
->eSurround
== css::text::WrapTextMode_DYNAMIC
)
2215 aSurround
.SetAnchorOnly( true );
2218 short aSizeArray
[5]={0};
2219 SwWW8ImplReader::SetFlyBordersShadow(*this,pFW
->brc
,&aSizeArray
[0]);
2221 // the 5th parameter is always 0, thus we lose nothing due to the cast
2224 // #i35017# - constant name has changed
2225 Put( SwFormatWrapInfluenceOnObjPos(
2226 text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE
) );
2231 Put( SwFormatAnchor(WW8SwFlyPara::eAnchor
) );
2234 //Ordinarily with frames, the border width and spacing is
2235 //placed outside the frame, making it larger. With these
2236 //types of frames, the left right thickness and space makes
2237 //it wider, but the top bottom spacing and border thickness
2239 Put( SwFormatFrameSize( pFS
->eHeightFix
, pFS
->nWidth
+
2240 aSizeArray
[WW8_LEFT
] + aSizeArray
[WW8_RIGHT
],
2244 // WW8FlySet-ctor for character bound graphics
2245 WW8FlySet::WW8FlySet( SwWW8ImplReader
& rReader
, const SwPaM
* pPaM
,
2246 const WW8_PIC
& rPic
, tools::Long nWidth
, tools::Long nHeight
)
2247 : SfxItemSetFixed
<RES_FRMATR_BEGIN
,RES_FRMATR_END
-1>(rReader
.m_rDoc
.GetAttrPool())
2249 Init(rReader
, pPaM
);
2251 Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_LR_TB
, RES_FRAMEDIR
));
2253 short aSizeArray
[5]={0};
2255 If we have set borders then in word the graphic is displaced from the left
2256 and top the width of the borders of those sides, and then the shadow
2257 itself is drawn to the bottom and right of the displaced graphic. In word
2258 the total size is that of the graphic plus the borders, plus the total
2259 shadow around all edges, for this translation the top and left shadow
2260 region is translated spacing around the graphic to those sides, and the
2261 bottom and right shadow size is added to the graphic size.
2263 WW8_BRCVer9 brcVer9
[4];
2264 for (int i
= 0; i
< 4; i
++)
2265 brcVer9
[i
] = WW8_BRCVer9(rPic
.rgbrc
[i
]);
2266 if (SwWW8ImplReader::SetFlyBordersShadow( *this, brcVer9
, &aSizeArray
[0]))
2268 Put(SvxLRSpaceItem( aSizeArray
[WW8_LEFT
], 0, 0, RES_LR_SPACE
) );
2269 Put(SvxULSpaceItem( aSizeArray
[WW8_TOP
], 0, RES_UL_SPACE
));
2270 aSizeArray
[WW8_RIGHT
]*=2;
2271 aSizeArray
[WW8_BOT
]*=2;
2274 Put( SwFormatFrameSize( SwFrameSize::Fixed
, nWidth
+aSizeArray
[WW8_LEFT
]+
2275 aSizeArray
[WW8_RIGHT
], nHeight
+aSizeArray
[WW8_TOP
]
2276 + aSizeArray
[WW8_BOT
]) );
2279 void WW8FlySet::Init(const SwWW8ImplReader
& rReader
, const SwPaM
* pPaM
)
2281 Reader::ResetFrameFormatAttrs(*this); // remove distance/borders
2283 Put(SvxLRSpaceItem(RES_LR_SPACE
)); //inline writer ole2 objects start with 0.2cm l/r
2284 SwFormatAnchor
aAnchor(RndStdIds::FLY_AS_CHAR
);
2286 aAnchor
.SetAnchor(pPaM
->GetPoint());
2289 //The horizontal default is on the baseline, the vertical is centered
2290 //around the character center it appears
2291 if (rReader
.m_aSectionManager
.CurrentSectionIsVertical())
2292 Put(SwFormatVertOrient(0, text::VertOrientation::CHAR_CENTER
,text::RelOrientation::CHAR
));
2294 Put(SwFormatVertOrient(0, text::VertOrientation::TOP
, text::RelOrientation::FRAME
));
2297 WW8DupProperties::WW8DupProperties(SwDoc
&rDoc
, SwWW8FltControlStack
*pStack
)
2298 : m_pCtrlStck(pStack
),
2299 m_aChrSet(rDoc
.GetAttrPool()),
2300 m_aParSet(rDoc
.GetAttrPool())
2302 //Close any open character properties and duplicate them inside the
2304 size_t nCnt
= m_pCtrlStck
->size();
2305 for (size_t i
=0; i
< nCnt
; ++i
)
2307 const SwFltStackEntry
& rEntry
= (*m_pCtrlStck
)[ i
];
2310 if (isCHRATR(rEntry
.m_pAttr
->Which()))
2312 m_aChrSet
.Put( *rEntry
.m_pAttr
);
2315 else if (isPARATR(rEntry
.m_pAttr
->Which()))
2317 m_aParSet
.Put( *rEntry
.m_pAttr
);
2323 void WW8DupProperties::Insert(const SwPosition
&rPos
)
2325 for (const SfxItemSet
* pSet
: {&m_aChrSet
, &m_aParSet
})
2329 SfxItemIter
aIter( *pSet
);
2330 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
2333 m_pCtrlStck
->NewAttr(rPos
, *pItem
);
2334 } while ((pItem
= aIter
.NextItem()));
2339 void SwWW8ImplReader::MoveInsideFly(const SwFrameFormat
*pFlyFormat
)
2341 WW8DupProperties
aDup(m_rDoc
, m_xCtrlStck
.get());
2343 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), 0, false);
2345 // set Pam in FlyFrame
2346 const SwFormatContent
& rContent
= pFlyFormat
->GetContent();
2347 OSL_ENSURE( rContent
.GetContentIdx(), "No content prepared." );
2348 m_pPaM
->GetPoint()->Assign( rContent
.GetContentIdx()->GetIndex() + 1 );
2350 aDup
.Insert(*m_pPaM
->GetPoint());
2353 SwTwips
SwWW8ImplReader::MoveOutsideFly(SwFrameFormat
*pFlyFormat
,
2354 const SwPosition
&rPos
, bool bTableJoin
)
2356 SwTwips nRetWidth
= 0;
2359 // Close all attributes, because otherwise attributes can appear
2360 // that extend out of Flys
2361 WW8DupProperties
aDup(m_rDoc
, m_xCtrlStck
.get());
2362 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), 0, false);
2366 If this fly frame consists entirely of one table inside a frame
2367 followed by an empty paragraph then we want to delete the empty
2368 paragraph so as to get the frame to autoshrink to the size of the
2369 table to emulate words behaviour closer.
2373 const SwNodeIndex
* pNodeIndex
= pFlyFormat
->GetContent().
2377 SwNodeIndex
aIdx( *pNodeIndex
, 1 ),
2378 aEnd( *pNodeIndex
->GetNode().EndOfSectionNode() );
2382 if(aIdx
.GetNode().IsTableNode())
2384 SwTableNode
*pTable
= aIdx
.GetNode().GetTableNode();
2385 aIdx
= *aIdx
.GetNode().EndOfSectionNode();
2387 if ( (aIdx
< aEnd
) && aIdx
.GetNode().IsTextNode() )
2389 SwTextNode
*pNd
= aIdx
.GetNode().GetTextNode();
2391 if (aIdx
== aEnd
&& pNd
&& pNd
->GetText().isEmpty())
2393 //An extra pre-created by writer unused paragraph
2395 //delete after import is complete rather than now
2396 //to avoid the complication of managing uncommitted
2397 //ctrlstack properties that refer to it.
2398 m_aExtraneousParas
.insert(pNd
);
2400 SwTable
& rTable
= pTable
->GetTable();
2401 SwFrameFormat
* pTableFormat
= rTable
.GetFrameFormat();
2405 SwFormatFrameSize aSize
= pTableFormat
->GetFrameSize();
2406 aSize
.SetHeightSizeType(SwFrameSize::Minimum
);
2407 aSize
.SetHeight(MINLAY
);
2408 pFlyFormat
->SetFormatAttr(aSize
);
2409 SwFormatHoriOrient aHori
= pTableFormat
->GetHoriOrient();
2410 // passing the table orientation of
2411 // LEFT_AND_WIDTH to the frame seems to
2412 // work better than FULL, especially if the
2413 // table width exceeds the page width, however
2414 // I am not brave enough to set it in all
2416 pTableFormat
->SetFormatAttr( SwFormatHoriOrient(0, ( aHori
.GetHoriOrient() == text::HoriOrientation::LEFT_AND_WIDTH
) ? ::text::HoriOrientation::LEFT_AND_WIDTH
: text::HoriOrientation::FULL
) );
2417 nRetWidth
= aSize
.GetWidth();
2426 *m_pPaM
->GetPoint() = rPos
;
2427 aDup
.Insert(*m_pPaM
->GetPoint());
2431 std::unique_ptr
<WW8FlyPara
> SwWW8ImplReader::ConstructApo(const ApoTestResults
&rApo
,
2432 const WW8_TablePos
*pTabPos
)
2434 OSL_ENSURE(rApo
.HasFrame() || pTabPos
,
2435 "If no frame found, *MUST* be in a table");
2437 std::unique_ptr
<WW8FlyPara
> pRet(new WW8FlyPara(m_bVer67
, rApo
.mpStyleApo
));
2439 // find APO parameter and test for bGrafApo
2440 if (rApo
.HasFrame())
2441 pRet
->ReadFull(rApo
.m_nSprm29
, this);
2443 pRet
->ApplyTabPos(pTabPos
);
2445 if (pRet
->IsEmpty())
2452 bool SwWW8ImplReader::IsDropCap() const
2454 // Find the DCS (Drop Cap Specifier) for the paragraph
2455 // if does not exist or if the first three bits are 0
2456 // then there is no dropcap on the paragraph
2457 WW8PLCFx_Cp_FKP
*pPap
= m_xPlcxMan
? m_xPlcxMan
->GetPapPLCF() : nullptr;
2462 aDCS
= pPap
->HasSprm(NS_sprm::v6::sprmPDcs
);
2464 aDCS
= m_xPlcxMan
->GetPapPLCF()->HasSprm(NS_sprm::PDcs::val
);
2465 if (aDCS
.pSprm
&& aDCS
.nRemainingData
>= 2)
2468 fdct short :3 0007 drop cap type
2471 2 drop cap in margin
2473 short nDCS
= SVBT16ToUInt16(aDCS
.pSprm
);
2481 bool SwWW8ImplReader::StartApo(const ApoTestResults
&rApo
, const WW8_TablePos
*pTabPos
)
2483 m_xWFlyPara
= ConstructApo(rApo
, pTabPos
);
2487 // <WW8SwFlyPara> constructor has changed - new 4th parameter
2488 // containing WW8 page top margin.
2489 m_xSFlyPara
.reset(new WW8SwFlyPara( *m_pPaM
, *this, *m_xWFlyPara
,
2490 m_aSectionManager
.GetWWPageTopMargin(),
2491 m_aSectionManager
.GetTextAreaWidth(),
2492 m_nIniFlyDx
, m_nIniFlyDy
));
2494 // If this paragraph is a Dropcap set the flag and we will deal with it later
2498 m_xCurrentItemSet
.reset(new SfxItemSet(m_rDoc
.GetAttrPool(), svl::Items
<RES_CHRATR_BEGIN
, RES_PARATR_END
- 1>));
2502 if (!m_xWFlyPara
->bGrafApo
)
2505 // Within the GrafApo text attributes have to be ignored, because
2506 // they would apply to the following lines. The frame is only inserted
2507 // if it is not merely positioning a single image. If it is an image
2508 // frame, pWFlyPara and pSFlyPara are retained and the resulting
2509 // attributes applied to the image when inserting the image.
2511 WW8FlySet
aFlySet(*this, m_xWFlyPara
.get(), m_xSFlyPara
.get(), false);
2513 // ofz#34749 we shouldn't anchor anything into an 'extra' paragraph scheduled for
2514 // removal at end of import, but check if that scenario is happening
2515 m_aExtraneousParas
.remove_if_present(m_pPaM
->GetPointNode().GetTextNode());
2519 if (m_xFormatOfJustInsertedApo
)
2521 // We just inserted a floating table and we'll insert a next one.
2522 SwFrameFormat
* pFormat
= m_xFormatOfJustInsertedApo
->GetFormat();
2525 const SwNode
* pAnchorNode
= pFormat
->GetAnchor().GetAnchorNode();
2526 SwPosition
* pPoint
= m_pPaM
->GetPoint();
2527 if (pAnchorNode
&& *pAnchorNode
== pPoint
->GetNode())
2529 // The two fly frames would have the same anchor position, leading to
2530 // potentially overlapping text, prevent that.
2531 AppendTextNode(*pPoint
);
2536 // Map a positioned table to a split fly.
2537 aFlySet
.Put(SwFormatFlySplit(true));
2539 if (pTabPos
->nTFNoAllowOverlap
)
2541 // text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE is not the default and is set in
2542 // the WW8FlySet ctor already, keep that unchanged.
2543 SwFormatWrapInfluenceOnObjPos
aInfluence(aFlySet
.Get(RES_WRAP_INFLUENCE_ON_OBJPOS
));
2544 aInfluence
.SetAllowOverlap(false);
2545 aFlySet
.Put(aInfluence
);
2549 m_xSFlyPara
->SetFlyFormat(m_rDoc
.MakeFlySection(WW8SwFlyPara::eAnchor
,
2550 m_pPaM
->GetPoint(), &aFlySet
));
2551 OSL_ENSURE(m_xSFlyPara
->GetFlyFormat()->GetAnchor().GetAnchorId() ==
2552 WW8SwFlyPara::eAnchor
, "Not the anchor type requested!");
2554 if (SwFlyFrameFormat
* pFlyFormat
= m_xSFlyPara
->GetFlyFormat())
2559 SdrObject
* pOurNewObject
= CreateContactObject(pFlyFormat
);
2560 m_xWWZOrder
->InsertTextLayerObject(pOurNewObject
);
2563 if (RndStdIds::FLY_AS_CHAR
!= WW8SwFlyPara::eAnchor
&& m_xSFlyPara
->GetFlyFormat())
2565 m_xAnchorStck
->AddAnchor(*m_pPaM
->GetPoint(), m_xSFlyPara
->GetFlyFormat());
2568 // remember Pos in body text
2569 m_xSFlyPara
->xMainTextPos
= m_rDoc
.CreateUnoCursor(*m_pPaM
->GetPoint());
2571 //remove fltanchors, otherwise they will be closed inside the
2572 //frame, which makes no sense, restore them after the frame is
2574 m_xSFlyPara
->xOldAnchorStck
= std::move(m_xAnchorStck
);
2575 m_xAnchorStck
.reset(new SwWW8FltAnchorStack(m_rDoc
, m_nFieldFlags
));
2577 if (SwFlyFrameFormat
* pFlyFormat
= m_xSFlyPara
->GetFlyFormat())
2578 MoveInsideFly(pFlyFormat
);
2580 // 1) ReadText() is not called recursively because the length of
2581 // the Apo is unknown at that time, and ReadText() needs it.
2582 // 2) the CtrlStck is not re-created.
2583 // the Char attributes continue (trouble with Sw-attributes)
2584 // Para attributes must be reset at the end of every paragraph,
2585 // i.e. at the end of a paragraph there must not be para attributes
2591 void wwSectionManager::JoinNode(const SwPosition
&rPos
, const SwNode
&rNode
)
2593 if ((!maSegments
.empty()) && (maSegments
.back().maStart
== rPos
.GetNode()))
2594 maSegments
.back().maStart
.Assign(rNode
);
2597 bool SwWW8ImplReader::JoinNode(SwPaM
&rPam
, bool bStealAttr
)
2600 rPam
.GetPoint()->SetContent(0); // go to start of paragraph
2602 SwNodeIndex
aPref(rPam
.GetPoint()->GetNode(), -1);
2604 if (SwTextNode
* pNode
= aPref
.GetNode().GetTextNode())
2606 m_aSectionManager
.JoinNode(*rPam
.GetPoint(), aPref
.GetNode());
2607 rPam
.GetPoint()->Assign(*pNode
, pNode
->GetText().getLength());
2609 m_xCtrlStck
->StealAttr(rPam
.GetPoint()->GetNode());
2611 if (m_oLastAnchorPos
|| m_xPreviousNode
|| (m_xSFlyPara
&& m_xSFlyPara
->xMainTextPos
))
2613 SwNodeIndex
aToBeJoined(aPref
, 1);
2615 if (m_oLastAnchorPos
)
2617 //If the last anchor pos is here, then clear the anchor pos.
2618 //This "last anchor pos" is only used for fixing up the
2619 //positions of things anchored to page breaks and here
2620 //we are removing the last paragraph of a frame, so there
2621 //cannot be a page break at this point so we can
2622 //safely reset m_pLastAnchorPos to avoid any dangling
2623 //SwContentIndex's pointing into the deleted paragraph
2624 SwNodeIndex
aLastAnchorPos(m_oLastAnchorPos
->GetNode());
2625 if (aLastAnchorPos
== aToBeJoined
)
2626 m_oLastAnchorPos
.reset();
2629 if (m_xPreviousNode
)
2631 //If the drop character start pos is here, then clear it.
2632 SwNodeIndex
aDropCharPos(*m_xPreviousNode
->GetTextNode());
2633 if (aDropCharPos
== aToBeJoined
)
2634 m_xPreviousNode
.reset();
2637 if (m_xSFlyPara
&& m_xSFlyPara
->xMainTextPos
)
2639 // If an open apo pos is here, then clear it before
2640 // JoinNext destroys it
2641 SwNodeIndex
aOpenApoPos(m_xSFlyPara
->xMainTextPos
->GetPoint()->GetNode());
2642 if (aOpenApoPos
== aToBeJoined
)
2643 m_xSFlyPara
->xMainTextPos
.reset();
2654 //In auto-width word frames negative after-indent values are ignored
2655 void SwWW8ImplReader::StripNegativeAfterIndent(SwFrameFormat
const *pFlyFormat
)
2657 const SwNodeIndex
* pSttNd
= pFlyFormat
->GetContent().GetContentIdx();
2661 SwNodeIndex
aIdx(*pSttNd
, 1);
2662 SwNodeIndex
aEnd(*pSttNd
->GetNode().EndOfSectionNode());
2665 SwTextNode
*pNd
= aIdx
.GetNode().GetTextNode();
2668 const SvxRightMarginItem
& rRightMargin(pNd
->GetAttr(RES_MARGIN_RIGHT
));
2669 if (rRightMargin
.GetRight() < 0)
2671 SvxRightMarginItem
rightMargin(rRightMargin
);
2672 rightMargin
.SetRight(0);
2673 pNd
->SetAttr(rightMargin
);
2680 void SwWW8ImplReader::StopApo()
2682 OSL_ENSURE(m_xWFlyPara
, "no pWFlyPara to close");
2685 if (m_xWFlyPara
->bGrafApo
)
2687 // image frame that has not been inserted: delete empty paragraph + attr
2688 JoinNode(*m_pPaM
, true);
2693 if (!m_xSFlyPara
->xMainTextPos
)
2695 OSL_ENSURE(m_xSFlyPara
->xMainTextPos
, "StopApo: xMainTextPos is nullptr");
2700 What we are doing with this temporary nodeindex is as follows: The
2701 stack of attributes normally only places them into the document when
2702 the current insertion point has passed them by. Otherwise the end
2703 point of the attribute gets pushed along with the insertion point. The
2704 insertion point is moved and the properties committed during
2705 MoveOutsideFly. We also may want to remove the final paragraph in the
2706 frame, but we need to wait until the properties for that frame text
2707 have been committed otherwise they will be lost. So we first get a
2708 handle to the last the filter inserted. After the attributes are
2709 committed, if that paragraph exists we join it with the para after it
2710 that comes with the frame by default so that as normal we don't end up
2711 with one more paragraph than we wanted.
2713 SwNodeIndex
aPref(m_pPaM
->GetPoint()->GetNode(), -1);
2716 MoveOutsideFly(m_xSFlyPara
->GetFlyFormat(), *m_xSFlyPara
->xMainTextPos
->GetPoint());
2718 m_xSFlyPara
->BoxUpWidth(nNewWidth
);
2720 Color
aBg(ColorTransparency
, 0xFE, 0xFF, 0xFF, 0xFF); //Transparent by default
2722 SwTextNode
* pNd
= aPref
.GetNode().GetTextNode();
2723 SwTextNode
* pJoinNext
= nullptr;
2724 if (pNd
&& m_xSFlyPara
->GetFlyFormat())
2728 Take the last paragraph background colour and fill the frame with
2729 it. Otherwise, make it transparent, this appears to be how MSWord
2732 const SfxPoolItem
&rItm
= pNd
->SwContentNode::GetAttr(RES_BACKGROUND
);
2733 const SvxBrushItem
&rBrush
= static_cast<const SvxBrushItem
&>(rItm
);
2734 if (rBrush
.GetColor() != COL_AUTO
)
2735 aBg
= rBrush
.GetColor();
2737 if (m_oLastAnchorPos
)
2739 //If the last anchor pos is here, then clear the anchor pos.
2740 //This "last anchor pos" is only used for fixing up the
2741 //positions of things anchored to page breaks and here
2742 //we are removing the last paragraph of a frame, so there
2743 //cannot be a page break at this point so we can
2744 //safely reset m_pLastAnchorPos to avoid any dangling
2745 //SwContentIndex's pointing into the deleted paragraph
2746 SwNodeIndex
aLastAnchorPos(m_oLastAnchorPos
->GetNode());
2747 SwNodeIndex
aToBeJoined(aPref
, 1);
2748 if (aLastAnchorPos
== aToBeJoined
)
2749 m_oLastAnchorPos
.reset();
2752 //Get rid of extra empty paragraph
2756 if (SwFlyFrameFormat
* pFlyFormat
= m_xSFlyPara
->GetFlyFormat())
2757 pFlyFormat
->SetFormatAttr(SvxBrushItem(aBg
, RES_BACKGROUND
));
2759 DeleteAnchorStack();
2761 pJoinNext
->JoinNext();
2763 m_xAnchorStck
= std::move(m_xSFlyPara
->xOldAnchorStck
);
2765 // When inserting a graphic into the fly frame using the auto
2766 // function, the extension of the SW-fly has to be set
2767 // manually as the SW fly has no auto function to adjust the
2769 if (m_xSFlyPara
->nNewNetWidth
> MINFLY
&& m_xSFlyPara
->GetFlyFormat()) // BoxUpWidth ?
2771 tools::Long nW
= m_xSFlyPara
->nNewNetWidth
;
2772 nW
+= m_xSFlyPara
->nWidth
- m_xSFlyPara
->nNetWidth
; // border for it
2773 m_xSFlyPara
->GetFlyFormat()->SetFormatAttr(
2774 SwFormatFrameSize(m_xSFlyPara
->eHeightFix
, nW
, m_xSFlyPara
->nHeight
));
2777 Word set *no* width meaning it's an automatic width. The
2778 SwFlyPara reader will have already set a fallback width of the
2779 printable regions width, so we should reuse it. Despite the related
2780 problems with layout addressed with a hack in WW8FlyPara's constructor
2781 #i27204# Added AutoWidth setting. Left the old CalculateFlySize in place
2782 so that if the user unselects autowidth, the width doesn't max out
2784 else if (!m_xWFlyPara
->nSp28
&& m_xSFlyPara
->GetFlyFormat())
2786 using namespace sw::util
;
2787 SfxItemSet
aFlySet( m_xSFlyPara
->GetFlyFormat()->GetAttrSet() );
2789 SwFormatFrameSize
aSize(aFlySet
.Get(RES_FRM_SIZE
));
2791 aFlySet
.ClearItem(RES_FRM_SIZE
);
2795 CalculateFlySize(aFlySet
, m_xSFlyPara
->xMainTextPos
->GetPoint()->GetNode(),
2796 m_xSFlyPara
->nWidth
);
2799 nNewWidth
= aFlySet
.Get(RES_FRM_SIZE
).GetWidth();
2801 aSize
.SetWidth(nNewWidth
);
2802 aSize
.SetWidthSizeType(SwFrameSize::Variable
);
2804 m_xSFlyPara
->GetFlyFormat()->SetFormatAttr(aSize
);
2807 m_xSFlyPara
->xMainTextPos
.reset();
2808 // To create the SwFrames when inserting into an existing document, fltshell.cxx
2809 // will call pFlyFrame->MakeFrames() when setting the FltAnchor attribute
2814 if (m_xSFlyPara
&& m_xSFlyPara
->GetFlyFormat())
2815 m_xFormatOfJustInsertedApo
.reset(new FrameDeleteWatch(m_xSFlyPara
->GetFlyFormat()));
2817 m_xSFlyPara
.reset();
2818 m_xWFlyPara
.reset();
2821 // TestSameApo() returns if it's the same Apo or a different one
2822 bool SwWW8ImplReader::TestSameApo(const ApoTestResults
&rApo
,
2823 const WW8_TablePos
*pTabPos
)
2827 OSL_ENSURE(m_xWFlyPara
, " Where is my pWFlyPara ? ");
2831 // We need to a full comparison (excepting borders) to identify all
2832 // combinations style/hard correctly. For this reason we create a
2833 // temporary WW8FlyPara (depending on if style or not), apply the
2834 // hard attributes and then compare.
2837 WW8FlyPara
aF(m_bVer67
, rApo
.mpStyleApo
);
2838 // WWPara for current para
2839 if (rApo
.HasFrame())
2840 aF
.Read(rApo
.m_nSprm29
, m_xPlcxMan
->GetPapPLCF());
2841 aF
.ApplyTabPos(pTabPos
);
2843 return aF
== *m_xWFlyPara
;
2846 void SwWW8ImplReader::NewAttr( const SfxPoolItem
& rAttr
,
2847 const bool bFirstLineOfStSet
,
2848 const bool bLeftIndentSet
)
2850 if( m_bNoAttrImport
) // for ignoring styles during doc inserts
2855 OSL_ENSURE(rAttr
.Which() != RES_FLTR_REDLINE
, "redline in style!");
2856 m_pCurrentColl
->SetFormatAttr(rAttr
);
2858 else if (m_xCurrentItemSet
)
2860 m_xCurrentItemSet
->Put(rAttr
);
2862 else if (rAttr
.Which() == RES_FLTR_REDLINE
)
2864 m_xRedlineStack
->open(*m_pPaM
->GetPoint(), rAttr
);
2868 m_xCtrlStck
->NewAttr(*m_pPaM
->GetPoint(), rAttr
);
2870 if ( bFirstLineOfStSet
)
2872 const SwNode
* pNd
= &(m_pPaM
->GetPoint()->GetNode());
2873 m_aTextNodesHavingFirstLineOfstSet
.insert( pNd
);
2876 if ( bLeftIndentSet
)
2878 const SwNode
* pNd
= &(m_pPaM
->GetPoint()->GetNode());
2879 m_aTextNodesHavingLeftIndentSet
.insert( pNd
);
2883 if (m_pPostProcessAttrsInfo
&& m_pPostProcessAttrsInfo
->mbCopy
)
2884 m_pPostProcessAttrsInfo
->mItemSet
.Put(rAttr
);
2887 // fetches attribute from FormatColl / Stack / Doc
2888 const SfxPoolItem
* SwWW8ImplReader::GetFormatAttr( sal_uInt16 nWhich
)
2890 const SfxPoolItem
* pRet
= nullptr;
2892 pRet
= &(m_pCurrentColl
->GetFormatAttr(nWhich
));
2893 else if (m_xCurrentItemSet
)
2895 pRet
= m_xCurrentItemSet
->GetItem(nWhich
);
2897 pRet
= m_pStandardFormatColl
? &(m_pStandardFormatColl
->GetFormatAttr(nWhich
)) : nullptr;
2899 pRet
= &m_rDoc
.GetAttrPool().GetDefaultItem(nWhich
);
2901 else if (m_xPlcxMan
&& m_xPlcxMan
->GetDoingDrawTextBox())
2903 pRet
= m_xCtrlStck
->GetStackAttr(*m_pPaM
->GetPoint(), nWhich
);
2906 if (m_nCurrentColl
< m_vColl
.size() && m_vColl
[m_nCurrentColl
].m_pFormat
&&
2907 m_vColl
[m_nCurrentColl
].m_bColl
)
2909 pRet
= &(m_vColl
[m_nCurrentColl
].m_pFormat
->GetFormatAttr(nWhich
));
2913 pRet
= m_pStandardFormatColl
? &(m_pStandardFormatColl
->GetFormatAttr(nWhich
)) : nullptr;
2915 pRet
= &m_rDoc
.GetAttrPool().GetDefaultItem(nWhich
);
2918 pRet
= m_xCtrlStck
->GetFormatAttr(*m_pPaM
->GetPoint(), nWhich
);
2922 // The methods get as parameters the token id and the length of the following
2923 // parameters according to the table in WWScan.cxx.
2924 void SwWW8ImplReader::Read_Special(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
2931 m_bSpec
= ( *pData
!= 0 );
2934 // Read_Obj is used for fObj and for fOle2 !
2935 void SwWW8ImplReader::Read_Obj(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
2941 m_bObj
= 0 != *pData
;
2943 if( m_bObj
&& m_nPicLocFc
&& m_bEmbeddObj
)
2945 if (!m_aFieldStack
.empty() && m_aFieldStack
.back().mnFieldId
== 56)
2947 // For LINK fields, store the nObjLocFc value in the field entry
2948 m_aFieldStack
.back().mnObjLocFc
= m_nPicLocFc
;
2952 m_nObjLocFc
= m_nPicLocFc
;
2958 void SwWW8ImplReader::Read_PicLoc(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
2963 m_bSpec
= false; // Is this always correct?
2967 m_nPicLocFc
= SVBT32ToUInt32( pData
);
2970 if( m_bObj
&& m_nPicLocFc
&& m_bEmbeddObj
)
2971 m_nObjLocFc
= m_nPicLocFc
;
2975 void SwWW8ImplReader::Read_POutLvl(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
2979 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_PARATR_OUTLINELEVEL
);
2983 if (m_pCurrentColl
!= nullptr)
2985 SwWW8StyInf
* pSI
= GetStyle(m_nCurrentColl
);
2986 if (pSI
&& pSI
->m_bColl
&& pSI
->m_pFormat
)
2988 pSI
->mnWW8OutlineLevel
=
2989 static_cast< sal_uInt8
>( ( (pData
&& nLen
>= 1) ? *pData
: 0 ) );
2990 auto nLevel
= SwWW8StyInf::WW8OutlineLevelToOutlinelevel(pSI
->mnWW8OutlineLevel
);
2993 SwTextFormatColl
* pTextFormatColl
= static_cast<SwTextFormatColl
*>(pSI
->m_pFormat
);
2994 pTextFormatColl
->DeleteAssignmentToListLevelOfOutlineStyle();
2996 NewAttr(SfxUInt16Item(RES_PARATR_OUTLINELEVEL
, nLevel
));
2999 else if (m_pPaM
!= nullptr)
3001 const sal_uInt8 nOutlineLevel
3002 = SwWW8StyInf::WW8OutlineLevelToOutlinelevel(
3003 static_cast<sal_uInt8
>(((pData
&& nLen
>= 1) ? *pData
: 0)));
3004 NewAttr(SfxUInt16Item(RES_PARATR_OUTLINELEVEL
, nOutlineLevel
));
3008 void SwWW8ImplReader::Read_Symbol(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3013 if (nLen
< (m_bVer67
? 3 : 4))
3015 //otherwise disable after we print the char
3016 if (m_xPlcxMan
&& m_xPlcxMan
->GetDoingDrawTextBox())
3017 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_FONT
);
3022 // Make new Font-Attribute
3023 // (will be closed in SwWW8ImplReader::ReadChars() )
3025 //Will not be added to the charencoding stack, for styles the real
3026 //font setting will be put in as the styles charset, and for plain
3027 //text encoding for symbols is moot. Drawing boxes will check bSymbol
3028 //themselves so they don't need to add it to the stack either.
3029 if (SetNewFontAttr(SVBT16ToUInt16( pData
), false, RES_CHRATR_FONT
))
3031 SetNewFontAttr(SVBT16ToUInt16( pData
), false, RES_CHRATR_CJK_FONT
);
3032 SetNewFontAttr(SVBT16ToUInt16( pData
), false, RES_CHRATR_CTL_FONT
);
3035 //convert single byte from MS1252 to Unicode
3036 m_cSymbol
= OUString(
3037 reinterpret_cast<const char*>(pData
+2), 1,
3038 RTL_TEXTENCODING_MS_1252
).toChar();
3042 //already is Unicode
3043 m_cSymbol
= SVBT16ToUInt16( pData
+2 );
3050 SwWW8StyInf
*SwWW8ImplReader::GetStyle(sal_uInt16 nColl
) const
3052 return const_cast<SwWW8StyInf
*>(nColl
< m_vColl
.size() ? &m_vColl
[nColl
] : nullptr);
3055 // Read_BoldUsw for italic, bold, small caps, majuscule, struck out,
3056 // contour and shadow
3057 void SwWW8ImplReader::Read_BoldUsw( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
3059 const int nContiguousWestern
= 8;
3060 const int nWestern
= nContiguousWestern
+ 1;
3061 const int nEastern
= 2;
3063 const int nIds
= nWestern
+ nEastern
+ nCTL
;
3064 static const sal_uInt16 nEndIds
[ nIds
] =
3066 RES_CHRATR_WEIGHT
, RES_CHRATR_POSTURE
,
3067 RES_CHRATR_CROSSEDOUT
, RES_CHRATR_CONTOUR
,
3068 RES_CHRATR_SHADOWED
, RES_CHRATR_CASEMAP
,
3069 RES_CHRATR_CASEMAP
, RES_CHRATR_HIDDEN
,
3071 RES_CHRATR_CROSSEDOUT
,
3073 RES_CHRATR_CJK_WEIGHT
, RES_CHRATR_CJK_POSTURE
,
3075 RES_CHRATR_CTL_WEIGHT
, RES_CHRATR_CTL_POSTURE
3078 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
3081 // the attribute number for "double strike-through" breaks rank
3082 if (NS_sprm::CFDStrike::val
== nId
)
3083 nI
= nContiguousWestern
; // The out of sequence western id
3086 // The contiguous western ids
3087 if (eVersion
<= ww::eWW2
)
3088 nI
= static_cast< sal_uInt8
>(nId
- 60);
3089 else if (eVersion
< ww::eWW8
)
3090 nI
= static_cast< sal_uInt8
>(nId
- NS_sprm::v6::sprmCFBold
);
3092 nI
= static_cast< sal_uInt8
>(nId
- NS_sprm::CFBold::val
);
3095 sal_uInt16 nMask
= 1 << nI
;
3101 if (eVersion
<= ww::eWW6
)
3103 // reset the CTL Weight and Posture, because they are the same as their
3104 // western equivalents in ww6
3105 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nEndIds
[ nWestern
+ nEastern
+ nI
] );
3107 // reset the CJK Weight and Posture, because they are the same as their
3108 // western equivalents in word
3109 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nEndIds
[ nWestern
+ nI
] );
3111 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nEndIds
[ nI
] );
3112 m_xCtrlStck
->SetToggleAttr(nI
, false);
3115 // value: 0 = off, 1 = on, 128 = like style, 129 contrary to style
3116 bool bOn
= *pData
& 1;
3117 SwWW8StyInf
* pSI
= GetStyle(m_nCurrentColl
);
3118 if (m_xPlcxMan
&& eVersion
> ww::eWW2
)
3120 SprmResult aCharIstd
=
3121 m_xPlcxMan
->GetChpPLCF()->HasSprm(m_bVer67
? NS_sprm::v6::sprmCIstd
: NS_sprm::CIstd::val
);
3122 if (aCharIstd
.pSprm
&& aCharIstd
.nRemainingData
>= 2)
3123 pSI
= GetStyle(SVBT16ToUInt16(aCharIstd
.pSprm
));
3126 if( m_pCurrentColl
) // StyleDef -> remember flags
3130 // The style based on has Bit 7 set ?
3132 pSI
->m_nBase
< m_vColl
.size() && (*pData
& 0x80) &&
3133 (m_vColl
[pSI
->m_nBase
].m_n81Flags
& nMask
)
3136 bOn
= !bOn
; // invert
3140 pSI
->m_n81Flags
|= nMask
; // set flag
3142 pSI
->m_n81Flags
&= ~nMask
; // delete flag
3148 // in text -> look at flags
3149 if( *pData
& 0x80 ) // bit 7 set?
3151 if (pSI
&& pSI
->m_n81Flags
& nMask
) // and in StyleDef at ?
3152 bOn
= !bOn
; // then invert
3153 // remember on stack that this is a toggle-attribute
3154 m_xCtrlStck
->SetToggleAttr(nI
, true);
3158 SetToggleAttr( nI
, bOn
);
3161 void SwWW8ImplReader::Read_Bidi(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3163 if (nLen
< 1) //Property end
3166 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(),RES_CHRATR_BIDIRTL
);
3168 else //Property start
3171 sal_uInt8 nBidi
= *pData
;
3172 NewAttr( SfxInt16Item( RES_CHRATR_BIDIRTL
, (nBidi
!=0)? 1 : 0 ) );
3177 tdf#91916, #i8726, #i42685# there is an ambiguity
3178 around certain properties as to what they mean,
3179 which appears to be a problem with different versions
3180 of the file format where properties conflict, i.e.
3182 ooo40606-2.doc, magic is a699
3183 : 0x6f 0x4 0x0 0x71 0x4 0x0
3184 ooo40635-1.doc, magic is a699
3185 : 0x6f 0x4 0x0 0x71 0x4 0x0
3186 ooo31093/SIMPCHIN.doc, magic is a699
3187 : 0x6f 0x2 0x0 0x70 0x0 0x0 0x71 0x2 0x0
3188 : 0x6f 0x5 0x0 0x70 0x5 0x0
3189 ooo31093/TRADCHIN.doc, magic is a699
3190 : 0x6f 0x1 0x0 0x70 0x0 0x0 0x71 0x1 0x0
3191 ooo31093/JAPANESE.doc, magic is a697
3192 : 0x6f 0x2 0x0 0x70 0x0 0x0 0x71 0x2 0x0
3193 ooo31093/KOREAN.doc, magic is a698
3194 : 0x6f 0x2 0x0 0x70 0x0 0x0 0x71 0x2 0x0
3195 ooo31093-1.doc, magic is a698
3196 : 0x6f 0x5 0x0 0x70 0x5 0x0
3197 ooo31093-1.doc, magic is a698
3198 : 0x6f 0x5 0x0 0x70 0x5 0x0
3202 ooo27954-1.doc, magic is a5dc
3203 : 0x6f 0x1 0x81 0x71 0x2 0x4 0x0 0x74 0x2 0x20 0x0
3205 ooo33251-1.doc, magic is a5dc
3206 : 0x6f 0x1 0x81 0x71 0x2 0x3 0x0 0x74 0x2 0x1c 0x0
3210 So we have the same sprm values, but different payloads, where
3211 the a5dc versions appear to use a len argument, followed by len
3212 bytes, while the a698<->a699 versions use a 2byte argument
3214 commit c2213db9ed70c1fd546482d22e36e4029c10aa45
3216 INTEGRATION: CWS tl28 (1.169.24); FILE MERGED
3217 2006/10/25 13:40:41 tl 1.169.24.2: RESYNC: (1.169-1.170); FILE MERGED
3218 2006/09/20 11:55:50 hbrinkm 1.169.24.1: #i42685# applied patch
3220 changed 0x6f and 0x70 from Read_BoldBiDiUsw to Read_FontCode for all versions.
3222 In the Word for Window 2 spec we have...
3230 as see in GetWW2SprmDispatcher, different numbers, but the sequence starts with
3231 the same sprmCMajority as appears before 0x6f in word 6/95
3233 I think the easiest explanation is that the CJK Word for Window 95, or whatever
3234 the product was went rogue, and did their own things with at least first three
3235 slots after sprmCMajority to do a different thing. I have no reason to think Tono
3236 was wrong with what they do in the a698<->a699 versions, but with magic
3237 a5dc they probably did mean sprmCFBoldBi, sprmCFItalicBi cause they have that 0x81
3238 pattern which has significance for those types of properties.
3240 void SwWW8ImplReader::Read_AmbiguousSPRM(sal_uInt16 nId
, const sal_uInt8
* pData
,
3243 if (m_xWwFib
->m_wIdent
>= 0xa697 && m_xWwFib
->m_wIdent
<= 0xa699)
3245 Read_FontCode(nId
, pData
, nLen
);
3249 Read_BoldBiDiUsw(nId
, pData
, nLen
);
3253 // Read_BoldUsw for BiDi Italic, Bold
3254 void SwWW8ImplReader::Read_BoldBiDiUsw(sal_uInt16 nId
, const sal_uInt8
* pData
,
3257 static const sal_uInt16 nEndIds
[2] =
3259 RES_CHRATR_CTL_WEIGHT
, RES_CHRATR_CTL_POSTURE
,
3263 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
3264 if (eVersion
<= ww::eWW2
)
3265 nI
= static_cast< sal_uInt8
>(nId
- 80);
3266 else if (eVersion
< ww::eWW8
)
3267 nI
= static_cast< sal_uInt8
>(nId
- 111);
3269 nI
= static_cast< sal_uInt8
>(nId
- NS_sprm::CFBoldBi::val
);
3271 OSL_ENSURE(nI
<= 1, "not happening");
3275 sal_uInt16 nMask
= 1 << nI
;
3279 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(),nEndIds
[nI
]);
3280 m_xCtrlStck
->SetToggleBiDiAttr(nI
, false);
3283 bool bOn
= *pData
& 1;
3284 SwWW8StyInf
* pSI
= GetStyle(m_nCurrentColl
);
3287 SprmResult aCharIstd
=
3288 m_xPlcxMan
->GetChpPLCF()->HasSprm(m_bVer67
? NS_sprm::v6::sprmCIstd
: NS_sprm::CIstd::val
);
3289 if (aCharIstd
.pSprm
&& aCharIstd
.nRemainingData
>= 2)
3290 pSI
= GetStyle(SVBT16ToUInt16(aCharIstd
.pSprm
));
3293 if (m_pCurrentColl
&& eVersion
> ww::eWW2
) // StyleDef -> remember flags
3297 if( pSI
->m_nBase
< m_vColl
.size() // Style Based on
3298 && ( *pData
& 0x80 ) // bit 7 set?
3299 && ( m_vColl
[pSI
->m_nBase
].m_n81BiDiFlags
& nMask
) ) // base mask?
3300 bOn
= !bOn
; // invert
3303 pSI
->m_n81BiDiFlags
|= nMask
; // set flag
3305 pSI
->m_n81BiDiFlags
&= ~nMask
; // delete flag
3311 // in text -> look at flags
3312 if (*pData
& 0x80) // Bit 7 set?
3314 if (pSI
&& pSI
->m_n81BiDiFlags
& nMask
) // and in StyleDef at ?
3315 bOn
= !bOn
; // then invert
3316 // remember on stack that this is a toggle-attribute
3317 m_xCtrlStck
->SetToggleBiDiAttr(nI
, true);
3321 SetToggleBiDiAttr(nI
, bOn
);
3324 void SwWW8ImplReader::SetToggleBiDiAttr(sal_uInt8 nAttrId
, bool bOn
)
3330 SvxWeightItem
aAttr( bOn
? WEIGHT_BOLD
: WEIGHT_NORMAL
, RES_CHRATR_WEIGHT
);
3331 aAttr
.SetWhich( RES_CHRATR_CTL_WEIGHT
);
3337 SvxPostureItem
aAttr( bOn
? ITALIC_NORMAL
: ITALIC_NONE
, RES_CHRATR_POSTURE
);
3338 aAttr
.SetWhich( RES_CHRATR_CTL_POSTURE
);
3343 OSL_ENSURE(false, "Unhandled unknown bidi toggle attribute");
3349 void SwWW8ImplReader::SetToggleAttr(sal_uInt8 nAttrId
, bool bOn
)
3351 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
3357 SvxWeightItem
aAttr( bOn
? WEIGHT_BOLD
: WEIGHT_NORMAL
, RES_CHRATR_WEIGHT
);
3359 aAttr
.SetWhich( RES_CHRATR_CJK_WEIGHT
);
3361 if (eVersion
<= ww::eWW6
)
3363 aAttr
.SetWhich( RES_CHRATR_CTL_WEIGHT
);
3370 SvxPostureItem
aAttr( bOn
? ITALIC_NORMAL
: ITALIC_NONE
, RES_CHRATR_POSTURE
);
3372 aAttr
.SetWhich( RES_CHRATR_CJK_POSTURE
);
3374 if (eVersion
<= ww::eWW6
)
3376 aAttr
.SetWhich( RES_CHRATR_CTL_POSTURE
);
3382 NewAttr(SvxCrossedOutItem(bOn
? STRIKEOUT_SINGLE
: STRIKEOUT_NONE
, RES_CHRATR_CROSSEDOUT
));
3385 NewAttr( SvxContourItem( bOn
, RES_CHRATR_CONTOUR
) );
3388 NewAttr( SvxShadowedItem( bOn
, RES_CHRATR_SHADOWED
) );
3391 NewAttr( SvxCaseMapItem( bOn
? SvxCaseMap::SmallCaps
3392 : SvxCaseMap::NotMapped
, RES_CHRATR_CASEMAP
) );
3395 NewAttr( SvxCaseMapItem( bOn
? SvxCaseMap::Uppercase
3396 : SvxCaseMap::NotMapped
, RES_CHRATR_CASEMAP
) );
3399 if (m_pPaM
->GetPoint()->GetContentIndex() == 0 && m_xFormatOfJustInsertedApo
)
3401 // We just inserted a frame and we're at the next paragraph start.
3402 SwFrameFormat
* pFormat
= m_xFormatOfJustInsertedApo
->GetFormat();
3405 SwNode
* pAnchorNode
= pFormat
->GetAnchor().GetAnchorNode();
3406 if (pAnchorNode
&& *pAnchorNode
== m_pPaM
->GetPoint()->GetNode())
3408 // The anchor paragraph would be hidden, leading to hiding the frame as
3409 // well, prevent that.
3415 NewAttr(SvxCharHiddenItem(bOn
, RES_CHRATR_HIDDEN
));
3418 NewAttr( SvxCrossedOutItem( bOn
? STRIKEOUT_DOUBLE
3419 : STRIKEOUT_NONE
, RES_CHRATR_CROSSEDOUT
) );
3422 OSL_ENSURE(false, "Unhandled unknown toggle attribute");
3427 void SwWW8ImplReader::ChkToggleAttr_( sal_uInt16 nOldStyle81Mask
,
3428 sal_uInt16 nNewStyle81Mask
)
3430 sal_uInt16 i
= 1, nToggleAttrFlags
= m_xCtrlStck
->GetToggleAttrFlags();
3431 for (sal_uInt8 n
= 0; n
< 7; ++n
, i
<<= 1)
3434 (i
& nToggleAttrFlags
) &&
3435 ((i
& nOldStyle81Mask
) != (i
& nNewStyle81Mask
))
3438 SetToggleAttr(n
, (i
& nOldStyle81Mask
));
3443 void SwWW8ImplReader::ChkToggleBiDiAttr_( sal_uInt16 nOldStyle81Mask
,
3444 sal_uInt16 nNewStyle81Mask
)
3446 sal_uInt16 i
= 1, nToggleAttrFlags
= m_xCtrlStck
->GetToggleBiDiAttrFlags();
3447 for (sal_uInt8 n
= 0; n
< 7; ++n
, i
<<= 1)
3450 (i
& nToggleAttrFlags
) &&
3451 ((i
& nOldStyle81Mask
) != (i
& nNewStyle81Mask
))
3454 SetToggleBiDiAttr(n
, (i
& nOldStyle81Mask
));
3459 void SwWW8ImplReader::Read_SubSuper( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3463 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_ESCAPEMENT
);
3472 nEs
= DFLT_ESC_AUTO_SUPER
;
3473 nProp
= DFLT_ESC_PROP
;
3476 nEs
= DFLT_ESC_AUTO_SUB
;
3477 nProp
= DFLT_ESC_PROP
;
3484 NewAttr( SvxEscapementItem( nEs
, nProp
, RES_CHRATR_ESCAPEMENT
) );
3487 SwFrameFormat
*SwWW8ImplReader::ContainsSingleInlineGraphic(const SwPaM
&rRegion
)
3490 For inline graphics and objects word has a hacked in feature to use
3491 subscripting to force the graphic into a centered position on the line, so
3492 we must check when applying sub/super to see if it the subscript range
3493 contains only a single graphic, and if that graphic is anchored as
3494 RndStdIds::FLY_AS_CHAR and then we can change its anchoring to centered in the line.
3496 SwFrameFormat
*pRet
=nullptr;
3497 SwNodeIndex
aBegin(rRegion
.Start()->GetNode());
3498 const sal_Int32
nBegin(rRegion
.Start()->GetContentIndex());
3499 SwNodeIndex
aEnd(rRegion
.End()->GetNode());
3500 const sal_Int32
nEnd(rRegion
.End()->GetContentIndex());
3501 const SwTextNode
* pTNd
;
3502 const SwTextAttr
* pTFlyAttr
;
3504 aBegin
== aEnd
&& nBegin
== nEnd
- 1 &&
3505 nullptr != (pTNd
= aBegin
.GetNode().GetTextNode()) &&
3506 nullptr != (pTFlyAttr
= pTNd
->GetTextAttrForCharAt(nBegin
, RES_TXTATR_FLYCNT
))
3509 const SwFormatFlyCnt
& rFly
= pTFlyAttr
->GetFlyCnt();
3510 SwFrameFormat
*pFlyFormat
= rFly
.GetFrameFormat();
3512 (RndStdIds::FLY_AS_CHAR
== pFlyFormat
->GetAnchor().GetAnchorId()))
3520 bool SwWW8ImplReader::ConvertSubToGraphicPlacement()
3523 For inline graphics and objects word has a hacked in feature to use
3524 subscripting to force the graphic into a centered position on the line, so
3525 we must check when applying sub/super to see if it the subscript range
3526 contains only a single graphic, and if that graphic is anchored as
3527 RndStdIds::FLY_AS_CHAR and then we can change its anchoring to centered in the line.
3529 bool bIsGraphicPlacementHack
= false;
3531 if (m_xCtrlStck
->GetFormatStackAttr(RES_CHRATR_ESCAPEMENT
, &nPos
))
3533 SwPaM
aRegion(*m_pPaM
->GetPoint());
3535 SwFltPosition
aMkPos((*m_xCtrlStck
)[nPos
].m_aMkPos
);
3536 SwFltPosition
aPtPos(*m_pPaM
->GetPoint());
3538 SwFrameFormat
*pFlyFormat
= nullptr;
3539 if (SwFltStackEntry::MakeRegion(m_rDoc
, aRegion
, SwFltStackEntry::RegionMode::NoCheck
, aMkPos
, aPtPos
)
3540 && nullptr != (pFlyFormat
= ContainsSingleInlineGraphic(aRegion
)))
3542 m_xCtrlStck
->DeleteAndDestroy(nPos
);
3543 pFlyFormat
->SetFormatAttr(SwFormatVertOrient(0, text::VertOrientation::CHAR_CENTER
, text::RelOrientation::CHAR
));
3544 bIsGraphicPlacementHack
= true;
3547 return bIsGraphicPlacementHack
;
3550 void SwWW8ImplReader::Read_SubSuperProp( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3552 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
3554 if (nLen
< (eVersion
<= ww::eWW2
? 1 : 2))
3556 if (!ConvertSubToGraphicPlacement())
3557 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_ESCAPEMENT
);
3561 // if the fontsize for these characters is specified, make sure it is updated first
3564 const sal_uInt16 nFontsizeID
= m_bVer67
? NS_sprm::v6::sprmCHps
: NS_sprm::CHps::val
;
3565 const SprmResult aFontsize
= m_xPlcxMan
->GetChpPLCF()->HasSprm( nFontsizeID
, /*bFindFirst=*/false );
3566 if ( aFontsize
.pSprm
&& aFontsize
.nRemainingData
)
3567 Read_FontSize(nFontsizeID
, aFontsize
.pSprm
, aFontsize
.nRemainingData
);
3570 // font position in HalfPoints
3571 short nPos
= eVersion
<= ww::eWW2
? static_cast< sal_Int8
>( *pData
) : SVBT16ToInt16( pData
);
3572 sal_Int32 nPos2
= nPos
* ( 10 * 100 ); // HalfPoints in 100 * tw
3573 const SvxFontHeightItem
* pF
3574 = static_cast<const SvxFontHeightItem
*>(GetFormatAttr(RES_CHRATR_FONTSIZE
));
3575 OSL_ENSURE(pF
, "Expected to have the fontheight available here");
3577 // #i59022: Check ensure nHeight != 0. Div by zero otherwise.
3578 sal_Int32 nHeight
= 240;
3579 if (pF
!= nullptr && pF
->GetHeight() != 0)
3580 nHeight
= pF
->GetHeight();
3581 nPos2
/= nHeight
; // ... now in % (rounded)
3582 if( nPos2
> MAX_ESC_POS
)
3583 nPos2
= MAX_ESC_POS
;
3584 if( nPos2
< -MAX_ESC_POS
)
3585 nPos2
= -MAX_ESC_POS
;
3586 SvxEscapementItem
aEs( static_cast<short>(nPos2
), 100, RES_CHRATR_ESCAPEMENT
);
3590 void SwWW8ImplReader::Read_Underline( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3592 FontLineStyle eUnderline
= LINESTYLE_NONE
;
3593 bool bWordLine
= false;
3596 // Parameter: 0 = none, 1 = single, 2 = by Word,
3597 // 3 = double, 4 = dotted, 5 = hidden
3598 // 6 = thick, 7 = dash, 8 = dot(not used)
3599 // 9 = dotdash 10 = dotdotdash 11 = wave
3602 case 2: bWordLine
= true;
3604 case 1: eUnderline
= LINESTYLE_SINGLE
; break;
3605 case 3: eUnderline
= LINESTYLE_DOUBLE
; break;
3606 case 4: eUnderline
= LINESTYLE_DOTTED
; break;
3607 case 7: eUnderline
= LINESTYLE_DASH
; break;
3608 case 9: eUnderline
= LINESTYLE_DASHDOT
; break;
3609 case 10:eUnderline
= LINESTYLE_DASHDOTDOT
; break;
3610 case 6: eUnderline
= LINESTYLE_BOLD
; break;
3611 case 11:eUnderline
= LINESTYLE_WAVE
; break;
3612 case 20:eUnderline
= LINESTYLE_BOLDDOTTED
; break;
3613 case 23:eUnderline
= LINESTYLE_BOLDDASH
; break;
3614 case 39:eUnderline
= LINESTYLE_LONGDASH
; break;
3615 case 55:eUnderline
= LINESTYLE_BOLDLONGDASH
; break;
3616 case 25:eUnderline
= LINESTYLE_BOLDDASHDOT
; break;
3617 case 26:eUnderline
= LINESTYLE_BOLDDASHDOTDOT
;break;
3618 case 27:eUnderline
= LINESTYLE_BOLDWAVE
; break;
3619 case 43:eUnderline
= LINESTYLE_DOUBLEWAVE
; break;
3623 // if necessary, mix up stack and exit!
3626 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_UNDERLINE
);
3627 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_WORDLINEMODE
);
3631 NewAttr( SvxUnderlineItem( eUnderline
, RES_CHRATR_UNDERLINE
));
3633 NewAttr(SvxWordLineModeItem(true, RES_CHRATR_WORDLINEMODE
));
3638 //The last three vary, measurements, rotation ? ?
3639 NoBracket 78 CA 06 - 02 00 00 02 34 52
3640 () 78 CA 06 - 02 01 00 02 34 52
3641 [] 78 CA 06 - 02 02 00 02 34 52
3642 <> 78 CA 06 - 02 03 00 02 34 52
3643 {} 78 CA 06 - 02 04 00 02 34 52
3645 void SwWW8ImplReader::Read_DoubleLine_Rotate( sal_uInt16
, const sal_uInt8
* pData
,
3648 if (nLen
< 0) // close the tag
3650 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_TWO_LINES
);
3651 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_ROTATE
);
3653 else if( pData
&& 6 == nLen
)
3657 case 2: // double line
3659 sal_Unicode cStt
= 0, cEnd
= 0;
3660 switch( SVBT16ToUInt16( pData
+1 ) )
3662 case 1: cStt
= '('; cEnd
= ')'; break;
3663 case 2: cStt
= '['; cEnd
= ']'; break;
3664 case 3: cStt
= '<'; cEnd
= '>'; break;
3665 case 4: cStt
= '{'; cEnd
= '}'; break;
3667 NewAttr( SvxTwoLinesItem( true, cStt
, cEnd
, RES_CHRATR_TWO_LINES
));
3671 case 1: // rotated characters
3673 bool bFitToLine
= 0 != *(pData
+1);
3674 NewAttr( SvxCharRotateItem( 900_deg10
, bFitToLine
, RES_CHRATR_ROTATE
));
3681 void SwWW8ImplReader::Read_TextColor( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3683 //Has newer colour variant, ignore this old variant
3684 if (!m_bVer67
&& m_xPlcxMan
&& m_xPlcxMan
->GetChpPLCF()->HasSprm(NS_sprm::CCv::val
).pSprm
)
3688 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_COLOR
);
3691 sal_uInt8 b
= *pData
; // parameter: 0 = Auto, 1..16 colors
3693 if( b
> 16 ) // unknown -> Black
3696 NewAttr( SvxColorItem(GetCol(b
), RES_CHRATR_COLOR
));
3697 if (m_pCurrentColl
&& m_xStyles
)
3698 m_xStyles
->mbTextColChanged
= true;
3702 void SwWW8ImplReader::Read_TextForeColor(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3705 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_COLOR
);
3708 Color aColor
= msfilter::util::BGRToRGB(SVBT32ToUInt32(pData
));
3710 // At least when transparency is 0xff and the color is black, Word renders that as black.
3711 if (aColor
.IsTransparent() && aColor
!= COL_AUTO
)
3713 aColor
.SetAlpha(255);
3716 NewAttr(SvxColorItem(aColor
, RES_CHRATR_COLOR
));
3717 if (m_pCurrentColl
&& m_xStyles
)
3718 m_xStyles
->mbTextColChanged
= true;
3722 void SwWW8ImplReader::Read_UnderlineColor(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
3726 //because the UnderlineColor is not a standalone attribute in SW, it belongs to the underline attribute.
3727 //And, the .doc file stores attributes separately, this attribute ends here, the "underline"
3728 //attribute also terminates (if the character next owns underline, that will be a new underline attribute).
3729 //so nothing is left to be done here.
3734 if ( m_pCurrentColl
) //importing style
3736 if( SfxItemState::SET
== m_pCurrentColl
->GetItemState( RES_CHRATR_UNDERLINE
, false ) )
3740 const SwAttrSet
& aSet
= m_pCurrentColl
->GetAttrSet();
3741 std::unique_ptr
<SvxUnderlineItem
> pUnderline(aSet
.Get(RES_CHRATR_UNDERLINE
, false).Clone());
3742 pUnderline
->SetColor( msfilter::util::BGRToRGB(SVBT32ToUInt32(pData
)) );
3743 m_pCurrentColl
->SetFormatAttr( *pUnderline
);
3747 else if (m_xCurrentItemSet
)
3749 if ( SfxItemState::SET
== m_xCurrentItemSet
->GetItemState( RES_CHRATR_UNDERLINE
, false ) )
3753 std::unique_ptr
<SvxUnderlineItem
> pUnderline(m_xCurrentItemSet
->Get(RES_CHRATR_UNDERLINE
, false).Clone());
3754 pUnderline
->SetColor( msfilter::util::BGRToRGB(SVBT32ToUInt32(pData
)) );
3755 m_xCurrentItemSet
->Put( std::move(pUnderline
) );
3761 SvxUnderlineItem
* pUnderlineAttr
= const_cast<SvxUnderlineItem
*>(static_cast<const SvxUnderlineItem
*>(m_xCtrlStck
->GetOpenStackAttr( *m_pPaM
->GetPoint(), RES_CHRATR_UNDERLINE
)));
3762 if (pUnderlineAttr
&& nLen
>= 4)
3763 pUnderlineAttr
->SetColor( msfilter::util::BGRToRGB(SVBT32ToUInt32( pData
) ));
3767 bool SwWW8ImplReader::GetFontParams( sal_uInt16 nFCode
, FontFamily
& reFamily
,
3768 OUString
& rName
, FontPitch
& rePitch
, rtl_TextEncoding
& reCharSet
)
3770 // the definitions that are the base for these tables are in windows.h
3771 static const FontPitch ePitchA
[] =
3773 PITCH_DONTKNOW
, PITCH_FIXED
, PITCH_VARIABLE
, PITCH_DONTKNOW
3776 static const FontFamily eFamilyA
[] =
3778 FAMILY_DONTKNOW
, FAMILY_ROMAN
, FAMILY_SWISS
, FAMILY_MODERN
,
3779 FAMILY_SCRIPT
, FAMILY_DECORATIVE
, FAMILY_DONTKNOW
, FAMILY_DONTKNOW
3782 const WW8_FFN
* pF
= m_xFonts
->GetFont( nFCode
); // Info for it
3783 if( !pF
) // font number unknown ?
3784 return false; // then ignore
3786 rName
= pF
->sFontname
;
3789 rePitch
= ePitchA
[pF
->aFFNBase
.prg
];
3792 if( 77 == pF
->aFFNBase
.chs
) // Mac font in Mac Charset or
3793 reCharSet
= m_eTextCharSet
; // translated to ANSI charset
3796 // #i52786#, for word 67 we'll assume that ANSI is basically invalid,
3797 // might be true for (above) mac as well, but would need a mac example
3798 // that exercises this to be sure
3799 if (m_bVer67
&& pF
->aFFNBase
.chs
== 0)
3800 reCharSet
= RTL_TEXTENCODING_DONTKNOW
;
3802 reCharSet
= rtl_getTextEncodingFromWindowsCharset(pF
->aFFNBase
.chs
);
3805 // make sure Font Family Code is set correctly
3806 // at least for the most important fonts
3807 // ( might be set wrong when Doc was not created by
3808 // Winword but by third party program like Applixware... )
3809 if (rName
.startsWithIgnoreAsciiCase("Tms Rmn") ||
3810 rName
.startsWithIgnoreAsciiCase("Timmons") ||
3811 rName
.startsWithIgnoreAsciiCase("CG Times") ||
3812 rName
.startsWithIgnoreAsciiCase("MS Serif") ||
3813 rName
.startsWithIgnoreAsciiCase("Garamond") ||
3814 rName
.startsWithIgnoreAsciiCase("Times Roman") ||
3815 rName
.startsWithIgnoreAsciiCase("Times New Roman"))
3817 reFamily
= FAMILY_ROMAN
;
3819 else if (rName
.startsWithIgnoreAsciiCase("Helv") ||
3820 rName
.startsWithIgnoreAsciiCase("Arial") ||
3821 rName
.startsWithIgnoreAsciiCase("Univers") ||
3822 rName
.startsWithIgnoreAsciiCase("LinePrinter") ||
3823 rName
.startsWithIgnoreAsciiCase("Lucida Sans") ||
3824 rName
.startsWithIgnoreAsciiCase("Small Fonts") ||
3825 rName
.startsWithIgnoreAsciiCase("MS Sans Serif"))
3827 reFamily
= FAMILY_SWISS
;
3831 reFamily
= eFamilyA
[pF
->aFFNBase
.ff
];
3837 bool SwWW8ImplReader::SetNewFontAttr(sal_uInt16 nFCode
, bool bSetEnums
,
3843 rtl_TextEncoding eSrcCharSet
;
3845 if( !GetFontParams( nFCode
, eFamily
, aName
, ePitch
, eSrcCharSet
) )
3847 //If we fail (and are not doing a style) then put something into the
3848 //character encodings stack anyway so that the property end that pops
3849 //off the stack will keep in sync
3850 if (!m_pCurrentColl
&& IsListOrDropcap())
3852 if (nWhich
== RES_CHRATR_CJK_FONT
)
3854 if (!m_aFontSrcCJKCharSets
.empty())
3856 eSrcCharSet
= m_aFontSrcCJKCharSets
.top();
3860 eSrcCharSet
= RTL_TEXTENCODING_DONTKNOW
;
3863 m_aFontSrcCJKCharSets
.push(eSrcCharSet
);
3867 if (!m_aFontSrcCharSets
.empty())
3869 eSrcCharSet
= m_aFontSrcCharSets
.top();
3873 eSrcCharSet
= RTL_TEXTENCODING_DONTKNOW
;
3876 m_aFontSrcCharSets
.push(eSrcCharSet
);
3882 rtl_TextEncoding eDstCharSet
= eSrcCharSet
;
3884 SvxFontItem
aFont( eFamily
, aName
, OUString(), ePitch
, eDstCharSet
, nWhich
);
3888 if( m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size() ) // StyleDef
3893 case RES_CHRATR_FONT
:
3894 m_vColl
[m_nCurrentColl
].m_eLTRFontSrcCharSet
= eSrcCharSet
;
3896 case RES_CHRATR_CTL_FONT
:
3897 m_vColl
[m_nCurrentColl
].m_eRTLFontSrcCharSet
= eSrcCharSet
;
3899 case RES_CHRATR_CJK_FONT
:
3900 m_vColl
[m_nCurrentColl
].m_eCJKFontSrcCharSet
= eSrcCharSet
;
3904 else if (IsListOrDropcap())
3906 //Add character text encoding to stack
3907 if (nWhich
== RES_CHRATR_CJK_FONT
)
3908 m_aFontSrcCJKCharSets
.push(eSrcCharSet
);
3910 m_aFontSrcCharSets
.push(eSrcCharSet
);
3914 NewAttr( aFont
); // ...and insert
3919 void SwWW8ImplReader::ResetCharSetVars()
3921 OSL_ENSURE(!m_aFontSrcCharSets
.empty(),"no charset to remove");
3922 if (!m_aFontSrcCharSets
.empty())
3923 m_aFontSrcCharSets
.pop();
3926 void SwWW8ImplReader::ResetCJKCharSetVars()
3928 OSL_ENSURE(!m_aFontSrcCJKCharSets
.empty(),"no charset to remove");
3929 if (!m_aFontSrcCJKCharSets
.empty())
3930 m_aFontSrcCJKCharSets
.pop();
3933 void SwWW8ImplReader::openFont(sal_uInt16 nFCode
, sal_uInt16 nId
)
3935 if (SetNewFontAttr(nFCode
, true, nId
) && m_pCurrentColl
&& m_xStyles
)
3937 // remember for simulating default font
3938 if (RES_CHRATR_CJK_FONT
== nId
)
3939 m_xStyles
->mbCJKFontChanged
= true;
3940 else if (RES_CHRATR_CTL_FONT
== nId
)
3941 m_xStyles
->mbCTLFontChanged
= true;
3943 m_xStyles
->mbFontChanged
= true;
3947 void SwWW8ImplReader::closeFont(sal_uInt16 nId
)
3949 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nId
);
3950 if (nId
== RES_CHRATR_CJK_FONT
)
3951 ResetCJKCharSetVars();
3957 Turn font on or off:
3959 void SwWW8ImplReader::Read_FontCode( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
3961 //Note: this function needs to be able to run multiple times on the same data.
3962 //It is called by Read_SubSuperProp to ensure that the current fontsize is known.
3964 if (m_bSymbol
) // if bSymbol, the symbol's font
3967 // (see sprmCSymbol) is valid!
3971 case NS_sprm::CRgFtc2::val
: //"Other" font, override with BiDi if it exists
3972 case NS_sprm::CFtcBi::val
: //BiDi Font
3973 nId
= RES_CHRATR_CTL_FONT
;
3975 case NS_sprm::v6::sprmCFtc
: //WW6
3977 case NS_sprm::CRgFtc0::val
:
3978 nId
= RES_CHRATR_FONT
;
3981 case NS_sprm::CRgFtc1::val
:
3982 nId
= RES_CHRATR_CJK_FONT
;
3988 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
3990 if (nLen
< 2) // end of attribute
3992 if (eVersion
<= ww::eWW6
)
3994 closeFont(RES_CHRATR_CTL_FONT
);
3995 closeFont(RES_CHRATR_CJK_FONT
);
4001 sal_uInt16 nFCode
= SVBT16ToUInt16( pData
); // font number
4002 openFont(nFCode
, nId
);
4003 if (eVersion
<= ww::eWW6
)
4005 openFont(nFCode
, RES_CHRATR_CJK_FONT
);
4006 openFont(nFCode
, RES_CHRATR_CTL_FONT
);
4011 void SwWW8ImplReader::Read_FontSize( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4016 case NS_sprm::v6::sprmCHps
:
4017 case NS_sprm::CHps::val
:
4018 nId
= RES_CHRATR_FONTSIZE
;
4022 case NS_sprm::CHpsBi::val
:
4023 nId
= RES_CHRATR_CTL_FONTSIZE
;
4029 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
4031 if (nLen
< (eVersion
<= ww::eWW2
? 1 : 2)) // end of attribute
4033 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nId
);
4034 if (eVersion
<= ww::eWW6
) // reset additionally the CTL size
4035 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_CTL_FONTSIZE
);
4036 if (RES_CHRATR_FONTSIZE
== nId
) // reset additionally the CJK size
4037 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_CJK_FONTSIZE
);
4041 // Font-Size in half points e.g. 10 = 1440 / ( 72 * 2 )
4042 sal_uLong nFSize
= eVersion
<= ww::eWW2
? *pData
: SVBT16ToUInt16(pData
);
4045 SvxFontHeightItem
aSz( nFSize
, 100, nId
);
4047 if (RES_CHRATR_FONTSIZE
== nId
) // set additionally the CJK size
4049 aSz
.SetWhich( RES_CHRATR_CJK_FONTSIZE
);
4052 if (eVersion
<= ww::eWW6
) // set additionally the CTL size
4054 aSz
.SetWhich( RES_CHRATR_CTL_FONTSIZE
);
4057 if (m_pCurrentColl
&& m_xStyles
) // Style-Def ?
4059 // remember for simulating default font size
4060 if (nId
== RES_CHRATR_CTL_FONTSIZE
)
4061 m_xStyles
->mbFCTLSizeChanged
= true;
4064 m_xStyles
->mbFSizeChanged
= true;
4065 if (eVersion
<= ww::eWW6
)
4066 m_xStyles
->mbFCTLSizeChanged
= true;
4072 void SwWW8ImplReader::Read_CharSet(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4075 { // end of attribute
4076 m_eHardCharSet
= RTL_TEXTENCODING_DONTKNOW
;
4079 sal_uInt8 nfChsDiff
= *pData
;
4081 if (nfChsDiff
&& nLen
>= 2)
4082 m_eHardCharSet
= rtl_getTextEncodingFromWindowsCharset( *(pData
+ 1) );
4084 m_eHardCharSet
= RTL_TEXTENCODING_DONTKNOW
;
4087 void SwWW8ImplReader::Read_Language( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4091 case NS_sprm::v6::sprmCLid
:
4092 case NS_sprm::CRgLid0_80::val
:
4093 case NS_sprm::CRgLid0::val
:
4094 nId
= RES_CHRATR_LANGUAGE
;
4096 case NS_sprm::CRgLid1_80::val
:
4097 case NS_sprm::CRgLid1::val
:
4098 nId
= RES_CHRATR_CJK_LANGUAGE
;
4102 case NS_sprm::CLidBi::val
:
4103 nId
= RES_CHRATR_CTL_LANGUAGE
;
4109 if (nLen
< 2) // end of attribute
4110 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nId
);
4113 sal_uInt16 nLang
= SVBT16ToUInt16( pData
); // Language-Id
4114 NewAttr(SvxLanguageItem(LanguageType(nLang
), nId
));
4119 Turn on character style:
4121 void SwWW8ImplReader::Read_CColl( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4123 if (nLen
< 2) // end of attribute
4125 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_TXTATR_CHARFMT
);
4129 sal_uInt16 nId
= SVBT16ToUInt16( pData
); // Style-Id (NOT Sprm-Id!)
4131 if( nId
>= m_vColl
.size() || !m_vColl
[nId
].m_pFormat
// invalid Id?
4132 || m_vColl
[nId
].m_bColl
) // or paragraph style?
4133 return; // then ignore
4135 // if current on loading a TOX field, and current trying to apply a hyperlink character style,
4136 // just ignore. For the hyperlinks inside TOX in MS Word is not same with a common hyperlink
4137 // Character styles: without underline and blue font color. And such type style will be applied in others
4139 if (m_bLoadingTOXCache
&& m_vColl
[nId
].GetWWStyleId() == ww::stiHyperlink
)
4144 NewAttr( SwFormatCharFormat( static_cast<SwCharFormat
*>(m_vColl
[nId
].m_pFormat
) ) );
4145 m_nCharFormat
= static_cast<short>(nId
);
4149 Narrower or wider than normal:
4151 void SwWW8ImplReader::Read_Kern( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4153 if (nLen
< 2) // end of attribute
4155 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_KERNING
);
4158 sal_Int16 nKern
= SVBT16ToUInt16( pData
); // Kerning in Twips
4159 NewAttr( SvxKerningItem( nKern
, RES_CHRATR_KERNING
) );
4162 void SwWW8ImplReader::Read_FontKern( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4164 if (nLen
< 2) // end of attribute
4166 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_AUTOKERN
);
4169 sal_Int16 nAutoKern
= SVBT16ToUInt16( pData
); // Kerning in Twips
4170 NewAttr(SvxAutoKernItem(static_cast<bool>(nAutoKern
), RES_CHRATR_AUTOKERN
));
4173 void SwWW8ImplReader::Read_CharShadow( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4175 //Has newer colour variant, ignore this old variant
4176 if (!m_bVer67
&& m_xPlcxMan
&& m_xPlcxMan
->GetChpPLCF()->HasSprm(NS_sprm::CShd::val
).pSprm
)
4181 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_BACKGROUND
);
4186 aSHD
.SetWWValue( *reinterpret_cast<SVBT16
const *>(pData
) );
4187 SwWW8Shade
aSh( m_bVer67
, aSHD
);
4189 NewAttr( SvxBrushItem( aSh
.m_aColor
, RES_CHRATR_BACKGROUND
));
4191 // Add a marker to the grabbag indicating that character background was imported from MSO shading
4192 SfxGrabBagItem aGrabBag
= *static_cast<const SfxGrabBagItem
*>(GetFormatAttr(RES_CHRATR_GRABBAG
));
4193 std::map
<OUString
, css::uno::Any
>& rMap
= aGrabBag
.GetGrabBag();
4194 rMap
.insert(std::pair
<OUString
, css::uno::Any
>("CharShadingMarker",uno::Any(true)));
4199 void SwWW8ImplReader::Read_TextBackColor(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4203 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_BACKGROUND
);
4207 OSL_ENSURE(nLen
== 10, "Len of para back colour not 10!");
4210 Color
aColour(ExtractColour(pData
, m_bVer67
));
4211 NewAttr(SvxBrushItem(aColour
, RES_CHRATR_BACKGROUND
));
4213 // Add a marker to the grabbag indicating that character background was imported from MSO shading
4214 SfxGrabBagItem aGrabBag
= *static_cast<const SfxGrabBagItem
*>(GetFormatAttr(RES_CHRATR_GRABBAG
));
4215 std::map
<OUString
, css::uno::Any
>& rMap
= aGrabBag
.GetGrabBag();
4216 rMap
.insert(std::pair
<OUString
, css::uno::Any
>("CharShadingMarker",uno::Any(true)));
4221 void SwWW8ImplReader::Read_CharHighlight(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4223 // MS Word completely ignores character highlighting in character styles.
4224 if ( m_pCurrentColl
&& m_pCurrentColl
->Which() == RES_CHRFMT
)
4229 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_HIGHLIGHT
);
4233 sal_uInt8 b
= *pData
; // Parameter: 0 = Auto, 1..16 colors
4235 if( b
> 16 ) // invalid -> Black
4236 b
= 0; // Auto -> Black
4238 Color
aCol(GetCol(b
));
4239 NewAttr( SvxBrushItem( aCol
, RES_CHRATR_HIGHLIGHT
));
4243 void SwWW8ImplReader::Read_NoLineNumb(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4245 if (nLen
< 0) // end of attribute
4247 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_LINENUMBER
);
4250 SwFormatLineNumber aLN
;
4251 if (const SwFormatLineNumber
* pLN
4252 = static_cast<const SwFormatLineNumber
*>(GetFormatAttr(RES_LINENUMBER
)))
4254 aLN
.SetStartValue( pLN
->GetStartValue() );
4257 aLN
.SetCountLines(pData
&& nLen
>= 1 && (0 == *pData
));
4261 static bool lcl_HasExplicitLeft(const WW8PLCFMan
*pPlcxMan
, bool bVer67
)
4263 WW8PLCFx_Cp_FKP
*pPap
= pPlcxMan
? pPlcxMan
->GetPapPLCF() : nullptr;
4267 return pPap
->HasSprm(NS_sprm::v6::sprmPDxaLeft
).pSprm
;
4269 return (pPap
->HasSprm(NS_sprm::PDxaLeft80::val
).pSprm
|| pPap
->HasSprm(NS_sprm::PDxaLeft::val
).pSprm
);
4275 void SwWW8ImplReader::Read_LR( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4277 if (nLen
< 2) // end of attribute
4279 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_MARGIN_FIRSTLINE
);
4280 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_MARGIN_TEXTLEFT
);
4281 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_MARGIN_RIGHT
);
4285 short nPara
= SVBT16ToUInt16( pData
);
4287 SfxPoolItem
const* pItem(GetFormatAttr(RES_MARGIN_FIRSTLINE
));
4288 ::std::unique_ptr
<SvxFirstLineIndentItem
> pFirstLine(pItem
4289 ? static_cast<SvxFirstLineIndentItem
*>(pItem
->Clone())
4290 : new SvxFirstLineIndentItem(RES_MARGIN_FIRSTLINE
));
4291 pItem
= GetFormatAttr(RES_MARGIN_TEXTLEFT
);
4292 ::std::unique_ptr
<SvxTextLeftMarginItem
> pLeftMargin(pItem
4293 ? static_cast<SvxTextLeftMarginItem
*>(pItem
->Clone())
4294 : new SvxTextLeftMarginItem(RES_MARGIN_TEXTLEFT
));
4295 pItem
= GetFormatAttr(RES_MARGIN_RIGHT
);
4296 ::std::unique_ptr
<SvxRightMarginItem
> pRightMargin(pItem
4297 ? static_cast<SvxRightMarginItem
*>(pItem
->Clone())
4298 : new SvxRightMarginItem(RES_MARGIN_RIGHT
));
4300 // Fix the regression issue: #i99822#: Discussion?
4301 // Since the list level formatting doesn't apply into paragraph style
4302 // for list levels of mode LABEL_ALIGNMENT.(see ww8par3.cxx
4303 // W8ImplReader::RegisterNumFormatOnTextNode).
4304 // Need to apply the list format to the paragraph here.
4305 SwTextNode
* pTextNode
= m_pPaM
->GetPointNode().GetTextNode();
4307 && pTextNode
->AreListLevelIndentsApplicable() != ::sw::ListLevelIndents::No
)
4309 SwNumRule
* pNumRule
= pTextNode
->GetNumRule();
4312 sal_uInt8 nLvl
= static_cast< sal_uInt8
>(pTextNode
->GetActualListLevel());
4313 const SwNumFormat
* pFormat
= pNumRule
->GetNumFormat( nLvl
);
4314 if ( pFormat
&& pFormat
->GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT
)
4316 pLeftMargin
->SetTextLeft(pFormat
->GetIndentAt());
4317 pFirstLine
->SetTextFirstLineOffset(static_cast<short>(pFormat
->GetFirstLineIndent()));
4318 // make paragraph have hard-set indent attributes
4319 pTextNode
->SetAttr(*pLeftMargin
);
4320 pTextNode
->SetAttr(*pFirstLine
);
4326 The older word sprms mean left/right, while the new ones mean before/after.
4327 Writer now also works with before after, so when we see old left/right and
4328 we're RTL. We swap them
4330 if (IsRightToLeft())
4334 //Left becomes after;
4335 case NS_sprm::v6::sprmPDxaLeft
:
4336 nId
= NS_sprm::v6::sprmPDxaRight
;
4338 case NS_sprm::PDxaLeft80::val
:
4339 nId
= NS_sprm::PDxaRight80::val
;
4341 //Right becomes before;
4342 case NS_sprm::v6::sprmPDxaRight
:
4343 nId
= NS_sprm::v6::sprmPDxaLeft
;
4345 case NS_sprm::PDxaRight80::val
:
4346 nId
= NS_sprm::PDxaLeft80::val
;
4351 bool bFirstLinOfstSet( false ); // #i103711#
4352 bool bLeftIndentSet( false ); // #i105414#
4357 case NS_sprm::v6::sprmPDxaLeft
:
4358 case NS_sprm::PDxaLeft80::val
:
4359 case NS_sprm::PDxaLeft::val
:
4360 pLeftMargin
->SetTextLeft(nPara
);
4361 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size())
4363 m_vColl
[m_nCurrentColl
].m_bListRelevantIndentSet
= true;
4365 bLeftIndentSet
= true; // #i105414#
4368 case NS_sprm::v6::sprmPDxaLeft1
:
4369 case NS_sprm::PDxaLeft180::val
:
4370 case NS_sprm::PDxaLeft1::val
:
4372 As part of an attempt to break my spirit ww 8+ formats can contain
4373 ww 7- lists. If they do and the list is part of the style, then
4374 when removing the list from a paragraph of that style there
4375 appears to be a bug where the hanging indent value which the list
4376 set is still factored into the left indent of the paragraph. Its
4377 not listed in the winword dialogs, but it is clearly there. So if
4378 our style has a broken ww 7- list and we know that the list has
4379 been removed then we will factor the original list applied hanging
4380 into our calculation.
4382 if (m_xPlcxMan
&& m_nCurrentColl
< m_vColl
.size() && m_vColl
[m_nCurrentColl
].m_bHasBrokenWW6List
)
4384 SprmResult aIsZeroed
= m_xPlcxMan
->GetPapPLCF()->HasSprm(NS_sprm::PIlfo::val
);
4385 if (aIsZeroed
.pSprm
&& aIsZeroed
.nRemainingData
>= 1 && *aIsZeroed
.pSprm
== 0)
4387 const SvxFirstLineIndentItem
& rFirstLine
=
4388 m_vColl
[m_nCurrentColl
].m_pFormat
->GetFormatAttr(RES_MARGIN_FIRSTLINE
);
4389 nPara
= nPara
- rFirstLine
.GetTextFirstLineOffset();
4393 pFirstLine
->SetTextFirstLineOffset(nPara
);
4395 if (!m_pCurrentColl
)
4397 if (const SwTextNode
* pNode
= m_pPaM
->GetPointNode().GetTextNode())
4399 if ( const SwNumFormat
*pNumFormat
= GetNumFormatFromTextNode(*pNode
) )
4401 if (!lcl_HasExplicitLeft(m_xPlcxMan
.get(), m_bVer67
))
4403 pLeftMargin
->SetTextLeft(pNumFormat
->GetIndentAt());
4405 // If have not explicit left, set number format list tab position is doc default tab
4406 const SvxTabStopItem
*pDefaultStopItem
= m_rDoc
.GetAttrPool().GetPoolDefaultItem(RES_PARATR_TABSTOP
);
4407 if ( pDefaultStopItem
&& pDefaultStopItem
->Count() > 0 )
4408 const_cast<SwNumFormat
*>(pNumFormat
)->SetListtabPos( const_cast<SvxTabStop
&>((*pDefaultStopItem
)[0]).GetTabPos() );
4413 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size())
4415 m_vColl
[m_nCurrentColl
].m_bListRelevantIndentSet
= true;
4417 bFirstLinOfstSet
= true; // #i103711#
4420 case NS_sprm::v6::sprmPDxaRight
:
4421 case NS_sprm::PDxaRight80::val
:
4422 case NS_sprm::PDxaRight::val
:
4423 pRightMargin
->SetRight(nPara
);
4429 NewAttr(*pFirstLine
, bFirstLinOfstSet
, false); // #i103711#, #i105414#
4430 NewAttr(*pLeftMargin
, false, bLeftIndentSet
);
4431 NewAttr(*pRightMargin
, false, false);
4435 void SwWW8ImplReader::Read_LineSpace( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4437 // comment see Read_UL()
4438 if (m_bStyNormal
&& m_bWWBugNormal
)
4441 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
4443 if (nLen
< (eVersion
<= ww::eWW2
? 3 : 4))
4445 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_LINESPACING
);
4446 if( !( m_nIniFlags
& WW8FL_NO_IMPLPASP
) )
4447 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_UL_SPACE
);
4451 short nSpace
= SVBT16ToUInt16( pData
);
4452 short nMulti
= (eVersion
<= ww::eWW2
) ? 1 : SVBT16ToUInt16( pData
+ 2 );
4454 SvxLineSpaceRule eLnSpc
;
4458 eLnSpc
= SvxLineSpaceRule::Fix
;
4461 eLnSpc
= SvxLineSpaceRule::Min
;
4463 // WW has implicit additional paragraph spacing depending on
4464 // the line spacing. It is, for "exactly", 0.8 * line spacing "before"
4465 // and 0.2 * line spacing "after".
4466 // For "at least", it is 1 * line spacing "before" and 0 * line spacing "after".
4467 // For "multiple", it is 0 "before" and min(0cm, FontSize*(nFach-1)) "after".
4469 // SW also has implicit line spacing. It is, for "at least"
4470 // 1 * line spacing "before" and 0 "after".
4471 // For proportional, it is min(0cm, FontSize*(nFach-1)) both "before" and "after".
4473 sal_uInt16 nSpaceTw
= 0;
4475 SvxLineSpacingItem
aLSpc( LINE_SPACE_DEFAULT_HEIGHT
, RES_PARATR_LINESPACING
);
4477 if( 1 == nMulti
) // MultilineSpace ( proportional )
4479 tools::Long n
= nSpace
* 10 / 24; // WW: 240 = 100%, SW: 100 = 100%
4481 // here n is in [0..13653]
4482 aLSpc
.SetPropLineSpace( o3tl::narrowing
<sal_uInt16
>(n
) );
4483 const SvxFontHeightItem
* pH
= static_cast<const SvxFontHeightItem
*>(
4484 GetFormatAttr( RES_CHRATR_FONTSIZE
));
4485 nSpaceTw
= o3tl::narrowing
<sal_uInt16
>( n
* pH
->GetHeight() / 100 );
4487 else // Fixed / Minimum
4489 // for negative space, the distance is "exact", otherwise "at least"
4490 nSpaceTw
= o3tl::narrowing
<sal_uInt16
>(nSpace
);
4491 aLSpc
.SetLineHeight( nSpaceTw
);
4492 aLSpc
.SetLineSpaceRule( eLnSpc
);
4496 m_xSFlyPara
->nLineSpace
= nSpaceTw
; // linespace for graphics APOs
4499 //#i18519# AutoSpace value depends on Dop fDontUseHTMLAutoSpacing setting
4500 sal_uInt16
SwWW8ImplReader::GetParagraphAutoSpace(bool fDontUseHTMLAutoSpacing
)
4502 if (fDontUseHTMLAutoSpacing
)
4503 return 100; //Seems to be always 5points in this case
4505 return 280; //Seems to be always 14points in this case
4508 void SwWW8ImplReader::Read_ParaAutoBefore(sal_uInt16
, const sal_uInt8
*pData
, short nLen
)
4512 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_UL_SPACE
);
4518 SvxULSpaceItem
aUL(*static_cast<const SvxULSpaceItem
*>(GetFormatAttr(RES_UL_SPACE
)));
4519 aUL
.SetUpper(GetParagraphAutoSpace(m_xWDop
->fDontUseHTMLAutoSpacing
));
4521 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size())
4522 m_vColl
[m_nCurrentColl
].m_bParaAutoBefore
= true;
4524 m_bParaAutoBefore
= true;
4528 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size())
4529 m_vColl
[m_nCurrentColl
].m_bParaAutoBefore
= false;
4531 m_bParaAutoBefore
= false;
4535 void SwWW8ImplReader::Read_ParaAutoAfter(sal_uInt16
, const sal_uInt8
*pData
, short nLen
)
4539 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_UL_SPACE
);
4545 SvxULSpaceItem
aUL(*static_cast<const SvxULSpaceItem
*>(GetFormatAttr(RES_UL_SPACE
)));
4546 aUL
.SetLower(GetParagraphAutoSpace(m_xWDop
->fDontUseHTMLAutoSpacing
));
4548 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size())
4549 m_vColl
[m_nCurrentColl
].m_bParaAutoAfter
= true;
4551 m_bParaAutoAfter
= true;
4555 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size())
4556 m_vColl
[m_nCurrentColl
].m_bParaAutoAfter
= false;
4558 m_bParaAutoAfter
= false;
4563 void SwWW8ImplReader::Read_UL( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4565 // A workaround for an error in WW: For nProduct == 0c03d, usually
4566 // DyaAfter 240 (delta y distance after, comment of the translator)
4567 // is incorrectly inserted into style "Normal", even though it isn't there.
4568 // Using the ini flag WW8FL_NO_STY_DYA you can force this behavior for other
4569 // WW versions as well.
4570 // OSL_ENSURE( !bStyNormal || bWWBugNormal, "+This Document may point to a bug
4571 // in the WW version used for creating it. If the Styles <Standard> resp.
4572 // <Normal> differentiate between WW and SW in paragraph or line spacing,
4573 // then please send this Document to SH.");
4574 // bWWBugNormal is not a sufficient criterion for this distance being wrong.
4579 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_UL_SPACE
);
4582 short nPara
= SVBT16ToUInt16( pData
);
4586 SvxULSpaceItem
aUL( *static_cast<const SvxULSpaceItem
*>(GetFormatAttr( RES_UL_SPACE
)));
4591 case NS_sprm::v6::sprmPDyaBefore
:
4592 case NS_sprm::PDyaBefore::val
:
4593 aUL
.SetUpper( nPara
);
4596 case NS_sprm::v6::sprmPDyaAfter
:
4597 case NS_sprm::PDyaAfter::val
:
4598 aUL
.SetLower( nPara
);
4607 void SwWW8ImplReader::Read_ParaContextualSpacing( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4611 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_UL_SPACE
);
4614 SvxULSpaceItem
aUL( *static_cast<const SvxULSpaceItem
*>(GetFormatAttr( RES_UL_SPACE
)));
4615 aUL
.SetContextValue(*pData
!= 0);
4619 void SwWW8ImplReader::Read_LineBreakClear(sal_uInt16
/*nId*/, const sal_uInt8
* pData
, short nLen
)
4621 if (nLen
== -1 && m_oLineBreakClear
.has_value())
4623 SwTextNode
* pText
= m_pPaM
->GetPointNode().GetTextNode();
4624 sal_Int32 nPos
= m_pPaM
->GetPoint()->GetContentIndex();
4625 if (!pText
|| !nPos
)
4627 // There should have been a linebreak char.
4631 // Replace the linebreak char with a clearing break.
4634 m_pPaM
->GetMark()->AdjustContent(-1);
4635 m_rDoc
.getIDocumentContentOperations().DeleteRange(*m_pPaM
);
4636 m_pPaM
->DeleteMark();
4637 SwFormatLineBreak
aLineBreak(*m_oLineBreakClear
);
4638 m_oLineBreakClear
.reset();
4639 pText
->InsertItem(aLineBreak
, nPos
, nPos
);
4647 sal_uInt8 nClear
= pData
[0];
4653 auto eClear
= static_cast<SwLineBreakClear
>(nClear
);
4654 m_oLineBreakClear
= eClear
;
4657 void SwWW8ImplReader::Read_IdctHint( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4659 // sprmcidcthint (opcode 0x286f) specifies a script bias for the text in the run.
4660 // for unicode characters that are shared between far east and non-far east scripts,
4661 // this property determines what font and language the character will use.
4662 // when this value is 0, text properties bias towards non-far east properties.
4663 // when this value is 1, text properties bias towards far east properties.
4664 // when this value is 2, text properties bias towards complex properties.
4665 if (nLen
< 1) //Property end
4667 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(),RES_CHRATR_IDCTHINT
);
4669 else //Property start
4671 NewAttr(SfxInt16Item(RES_CHRATR_IDCTHINT
, *pData
));
4675 void SwWW8ImplReader::Read_Justify( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4679 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_ADJUST
);
4683 SvxAdjust
eAdjust(SvxAdjust::Left
);
4684 bool bDistributed
= false;
4691 eAdjust
= SvxAdjust::Center
;
4694 eAdjust
= SvxAdjust::Right
;
4697 eAdjust
= SvxAdjust::Block
;
4700 eAdjust
= SvxAdjust::Block
;
4701 bDistributed
= true;
4704 SvxAdjustItem
aAdjust(eAdjust
, RES_PARATR_ADJUST
);
4706 aAdjust
.SetLastBlock(SvxAdjust::Block
);
4709 SetRelativeJustify( nId
!= NS_sprm::PJc80::val
);
4712 bool SwWW8ImplReader::IsRightToLeft()
4717 aDir
= m_xPlcxMan
->GetPapPLCF()->HasSprm(NS_sprm::PFBiDi::val
);
4718 if (aDir
.pSprm
&& aDir
.nRemainingData
>= 1)
4719 bRTL
= *aDir
.pSprm
!= 0;
4722 const SvxFrameDirectionItem
* pItem
=
4723 static_cast<const SvxFrameDirectionItem
*>(GetFormatAttr(RES_FRAMEDIR
));
4724 if (pItem
&& (pItem
->GetValue() == SvxFrameDirection::Horizontal_RL_TB
))
4730 void SwWW8ImplReader::Read_RTLJustify( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4734 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_ADJUST
);
4738 //If we are in a ltr paragraph this is the same as normal Justify,
4739 //If we are in a rtl paragraph the meaning is reversed.
4740 if (!IsRightToLeft())
4741 Read_Justify(nId
, pData
, nLen
);
4744 SvxAdjust
eAdjust(SvxAdjust::Right
);
4745 bool bDistributed
= false;
4752 eAdjust
= SvxAdjust::Center
;
4755 eAdjust
= SvxAdjust::Left
;
4758 eAdjust
= SvxAdjust::Block
;
4761 eAdjust
= SvxAdjust::Block
;
4762 bDistributed
= true;
4765 SvxAdjustItem
aAdjust(eAdjust
, RES_PARATR_ADJUST
);
4767 aAdjust
.SetLastBlock(SvxAdjust::Block
);
4770 SetRelativeJustify( true );
4774 void SwWW8ImplReader::Read_BoolItem( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4778 case NS_sprm::PFKinsoku::val
:
4779 nId
= RES_PARATR_FORBIDDEN_RULES
;
4781 case NS_sprm::PFOverflowPunct::val
:
4782 nId
= RES_PARATR_HANGINGPUNCTUATION
;
4784 case NS_sprm::PFAutoSpaceDE::val
:
4785 nId
= RES_PARATR_SCRIPTSPACE
;
4788 OSL_ENSURE( false, "wrong Id" );
4793 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), nId
);
4796 std::unique_ptr
<SfxBoolItem
> pI(static_cast<SfxBoolItem
*>(GetDfltAttr( nId
)->Clone()));
4797 pI
->SetValue( 0 != *pData
);
4802 void SwWW8ImplReader::Read_Emphasis( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4805 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_EMPHASIS_MARK
);
4809 //Check to see if there is an up and coming cjk language property. If
4810 //there is use it, if there is not fall back to the currently set one.
4811 //Only the cjk language setting seems to matter to word, the western
4815 aLang
= m_xPlcxMan
->GetChpPLCF()->HasSprm(NS_sprm::CRgLid1_80::val
);
4817 if (aLang
.pSprm
&& aLang
.nRemainingData
>= 2)
4818 nLang
= LanguageType(SVBT16ToUInt16(aLang
.pSprm
));
4821 nLang
= static_cast<const SvxLanguageItem
*>(
4822 GetFormatAttr(RES_CHRATR_CJK_LANGUAGE
))->GetLanguage();
4825 FontEmphasisMark nVal
;
4829 nVal
= FontEmphasisMark::NONE
;
4832 if (MsLangId::isKorean(nLang
) || MsLangId::isTraditionalChinese(nLang
))
4833 nVal
= (FontEmphasisMark::Circle
| FontEmphasisMark::PosAbove
);
4834 else if (nLang
== LANGUAGE_JAPANESE
)
4835 nVal
= (FontEmphasisMark::Accent
| FontEmphasisMark::PosAbove
);
4837 nVal
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosBelow
);
4840 nVal
= (FontEmphasisMark::Circle
| FontEmphasisMark::PosAbove
);
4843 nVal
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosBelow
);
4846 if (MsLangId::isSimplifiedChinese(nLang
))
4847 nVal
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosBelow
);
4849 nVal
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosAbove
);
4852 nVal
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosAbove
);
4856 NewAttr( SvxEmphasisMarkItem( nVal
, RES_CHRATR_EMPHASIS_MARK
) );
4860 void SwWW8ImplReader::Read_ScaleWidth( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
4863 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_SCALEW
);
4866 sal_uInt16 nVal
= SVBT16ToUInt16( pData
);
4867 //The number must be between 1 and 600
4868 if (nVal
< 1 || nVal
> 600)
4870 NewAttr( SvxCharScaleWidthItem( nVal
, RES_CHRATR_SCALEW
) );
4874 void SwWW8ImplReader::Read_Relief( sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
4877 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_RELIEF
);
4882 // not so easy because this is also a toggle attribute!
4883 // 2 x emboss on -> no emboss !!!
4884 // the actual value must be searched over the stack / template
4886 const SvxCharReliefItem
* pOld
= static_cast<const SvxCharReliefItem
*>(
4887 GetFormatAttr( RES_CHRATR_RELIEF
));
4888 FontRelief nNewValue
= NS_sprm::CFImprint::val
== nId
? FontRelief::Engraved
4889 : ( NS_sprm::CFEmboss::val
== nId
? FontRelief::Embossed
4890 : FontRelief::NONE
);
4891 if( pOld
->GetValue() == nNewValue
)
4893 if( FontRelief::NONE
!= nNewValue
)
4894 nNewValue
= FontRelief::NONE
;
4896 NewAttr( SvxCharReliefItem( nNewValue
, RES_CHRATR_RELIEF
));
4901 void SwWW8ImplReader::Read_TextAnim(sal_uInt16
/*nId*/, const sal_uInt8
* pData
, short nLen
)
4904 m_xCtrlStck
->SetAttr(*m_pPaM
->GetPoint(), RES_CHRATR_BLINK
);
4911 // The 7 animated text effects available in word all get
4912 // mapped to a blinking text effect in LibreOffice
4913 // 0 no animation 1 Las Vegas lights
4914 // 2 background blink 3 sparkle text
4915 // 4 marching ants 5 marching red ants
4917 bBlink
= *pData
> 0 && *pData
< 7;
4919 NewAttr(SvxBlinkItem(bBlink
, RES_CHRATR_BLINK
));
4924 SwWW8Shade::SwWW8Shade(bool bVer67
, const WW8_SHD
& rSHD
)
4926 sal_uInt8 b
= rSHD
.GetFore();
4927 OSL_ENSURE(b
< 17, "ww8: colour out of range");
4931 Color
nFore(SwWW8ImplReader::GetCol(b
));
4934 OSL_ENSURE(b
< 17, "ww8: colour out of range");
4938 Color
nBack(SwWW8ImplReader::GetCol(b
));
4940 b
= rSHD
.GetStyle(bVer67
);
4942 SetShade(nFore
, nBack
, b
);
4945 void SwWW8Shade::SetShade(Color nFore
, Color nBack
, sal_uInt16 nIndex
)
4947 static const sal_uLong eMSGrayScale
[] =
4967 333, // 14 Dark Horizontal
4968 333, // 15 Dark Vertical
4969 333, // 16 Dark Forward Diagonal
4970 333, // 17 Dark Backward Diagonal
4971 333, // 18 Dark Cross
4972 333, // 19 Dark Diagonal Cross
4973 333, // 20 Horizontal
4975 333, // 22 Forward Diagonal
4976 333, // 23 Backward Diagonal
4978 333, // 25 Diagonal Cross
4979 // Undefined values in DOC spec-sheet
4989 // Different shading types
4990 25, // 35 [available in DOC, not available in DOCX]
4991 75, // 36 [available in DOC, not available in DOCX]
4994 175, // 39 [available in DOC, not available in DOCX]
4995 225, // 40 [available in DOC, not available in DOCX]
4996 275, // 41 [available in DOC, not available in DOCX]
4997 325, // 42 [available in DOC, not available in DOCX]
5000 425, // 45 [available in DOC, not available in DOCX]
5002 475, // 47 [available in DOC, not available in DOCX]
5003 525, // 48 [available in DOC, not available in DOCX]
5005 575, // 50 [available in DOC, not available in DOCX]
5008 675, // 53 [available in DOC, not available in DOCX]
5009 725, // 54 [available in DOC, not available in DOCX]
5010 775, // 55 [available in DOC, not available in DOCX]
5011 825, // 56 [available in DOC, not available in DOCX]
5014 925, // 59 [available in DOC, not available in DOCX]
5016 975 // 61 [available in DOC, not available in DOCX]
5019 //NO auto for shading so Foreground: Auto = Black
5020 if (nFore
== COL_AUTO
)
5023 //NO auto for shading so background: Auto = White
5024 Color nUseBack
= nBack
;
5025 if (nUseBack
== COL_AUTO
)
5026 nUseBack
= COL_WHITE
;
5028 if( nIndex
>= SAL_N_ELEMENTS( eMSGrayScale
) )
5031 sal_uLong nWW8BrushStyle
= eMSGrayScale
[nIndex
];
5033 switch (nWW8BrushStyle
)
5035 case 0: // Null-Brush
5040 Color
aForeColor(nFore
);
5041 Color
aBackColor(nUseBack
);
5043 sal_uInt32 nRed
= aForeColor
.GetRed() * nWW8BrushStyle
;
5044 sal_uInt32 nGreen
= aForeColor
.GetGreen() * nWW8BrushStyle
;
5045 sal_uInt32 nBlue
= aForeColor
.GetBlue() * nWW8BrushStyle
;
5046 nRed
+= aBackColor
.GetRed() * (1000 - nWW8BrushStyle
);
5047 nGreen
+= aBackColor
.GetGreen()* (1000 - nWW8BrushStyle
);
5048 nBlue
+= aBackColor
.GetBlue() * (1000 - nWW8BrushStyle
);
5050 m_aColor
= Color( nRed
/1000, nGreen
/1000, nBlue
/1000 );
5056 void SwWW8ImplReader::Read_Shade( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5058 if (!m_bVer67
&& m_xPlcxMan
&& m_xPlcxMan
->GetPapPLCF()->HasSprm(NS_sprm::PShd::val
).pSprm
)
5064 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), XATTR_FILLSTYLE
);
5065 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), XATTR_FILLCOLOR
);
5070 aSHD
.SetWWValue( *reinterpret_cast<SVBT16
const *>(pData
) );
5071 SwWW8Shade
aSh( m_bVer67
, aSHD
);
5073 NewAttr( XFillStyleItem(drawing::FillStyle_SOLID
) );
5074 NewAttr( XFillColorItem(OUString(), aSh
.m_aColor
) );
5078 void SwWW8ImplReader::Read_ParaBackColor(sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5083 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), XATTR_FILLSTYLE
);
5084 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), XATTR_FILLCOLOR
);
5088 OSL_ENSURE(nLen
== 10, "Len of para back colour not 10!");
5092 const Color aColor
= ExtractColour(pData
, m_bVer67
);
5093 NewAttr( XFillColorItem(OUString(), aColor
) );
5094 if ( aColor
== COL_AUTO
)
5095 NewAttr( XFillStyleItem(drawing::FillStyle_NONE
) );
5097 NewAttr( XFillStyleItem(drawing::FillStyle_SOLID
) );
5101 Color
SwWW8ImplReader::ExtractColour(const sal_uInt8
* &rpData
, bool bVer67
)
5103 OSL_ENSURE(!bVer67
, "Impossible");
5104 Color nFore
= msfilter::util::BGRToRGB(SVBT32ToUInt32(rpData
));
5106 Color nBack
= msfilter::util::BGRToRGB(SVBT32ToUInt32(rpData
));
5108 sal_uInt16 nIndex
= SVBT16ToUInt16(rpData
);
5110 //Being a transparent background colour doesn't actually show the page
5111 //background through, it merely acts like white
5112 if (nBack
== Color(ColorTransparency
, 0xFF000000))
5114 OSL_ENSURE(nBack
== COL_AUTO
|| !nBack
.IsTransparent(),
5115 "ww8: don't know what to do with such a transparent bg colour, report");
5116 SwWW8Shade
aShade(nFore
, nBack
, nIndex
);
5117 return aShade
.m_aColor
;
5120 void SwWW8ImplReader::Read_TextVerticalAdjustment( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5125 drawing::TextVerticalAdjust nVA
= drawing::TextVerticalAdjust_TOP
;
5129 nVA
= drawing::TextVerticalAdjust_CENTER
;
5132 nVA
= drawing::TextVerticalAdjust_BLOCK
;
5135 nVA
= drawing::TextVerticalAdjust_BOTTOM
;
5140 m_aSectionManager
.SetCurrentSectionVerticalAdjustment( nVA
);
5143 void SwWW8ImplReader::Read_Border(sal_uInt16
, const sal_uInt8
*, short nLen
)
5149 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_BOX
);
5150 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_SHADOW
);
5151 m_bHasBorder
= false;
5154 else if( !m_bHasBorder
)
5156 // the borders on all four sides are bundled. That
5157 // simplifies the administration, i.e., the box does not have
5158 // to be put on and removed from CtrlStack 4 times.
5159 m_bHasBorder
= true;
5161 WW8_BRCVer9_5 aBrcs
; // Top, Left, Bottom, Right, Between
5164 if( m_pCurrentColl
)
5165 nBorder
= ::lcl_ReadBorders(m_bVer67
, aBrcs
, nullptr, m_xStyles
.get());
5167 nBorder
= ::lcl_ReadBorders(m_bVer67
, aBrcs
, m_xPlcxMan
? m_xPlcxMan
->GetPapPLCF() : nullptr);
5169 if( nBorder
) // Border
5171 bool bIsB
= IsBorder(aBrcs
, true);
5172 if (!InLocalApo() || !bIsB
|| (m_xWFlyPara
&& !m_xWFlyPara
->bBorderLines
))
5174 // Do not turn *on* borders in APO, since otherwise
5175 // I get the Fly border twice;
5176 // but only when it is set on in the Fly, skip it;
5177 // otherwise there is none at all!
5179 // even if no border is set, the attribute has to be set,
5180 // otherwise it's not possible to turn off the style attribute.
5181 const SvxBoxItem
* pBox
5182 = static_cast<const SvxBoxItem
*>(GetFormatAttr( RES_BOX
));
5183 std::shared_ptr
<SvxBoxItem
> aBox(std::make_shared
<SvxBoxItem
>(RES_BOX
));
5185 aBox
.reset(pBox
->Clone());
5186 short aSizeArray
[5]={0};
5188 SetBorder(*aBox
, aBrcs
, &aSizeArray
[0], nBorder
);
5190 tools::Rectangle aInnerDist
;
5191 GetBorderDistance( aBrcs
, aInnerDist
);
5193 if (nBorder
& (1 << WW8_LEFT
))
5194 aBox
->SetDistance( o3tl::narrowing
<sal_uInt16
>(aInnerDist
.Left()), SvxBoxItemLine::LEFT
);
5196 if (nBorder
& (1 << WW8_TOP
))
5197 aBox
->SetDistance( o3tl::narrowing
<sal_uInt16
>(aInnerDist
.Top()), SvxBoxItemLine::TOP
);
5199 if (nBorder
& (1 << WW8_RIGHT
))
5200 aBox
->SetDistance( o3tl::narrowing
<sal_uInt16
>(aInnerDist
.Right()), SvxBoxItemLine::RIGHT
);
5202 if (nBorder
& (1 << WW8_BOT
))
5203 aBox
->SetDistance( o3tl::narrowing
<sal_uInt16
>(aInnerDist
.Bottom()), SvxBoxItemLine::BOTTOM
);
5207 SvxShadowItem
aS(RES_SHADOW
);
5208 // Word only allows shadows on visible borders
5209 if ( aBox
->CalcLineSpace( SvxBoxItemLine::RIGHT
) )
5210 SetShadow( aS
, &aSizeArray
[0], aBrcs
[WW8_RIGHT
] );
5217 void SwWW8ImplReader::Read_CharBorder(sal_uInt16 nId
, const sal_uInt8
* pData
, short nLen
)
5219 //Ignore this old border type
5220 //if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(NS_sprm::CBrc::val))
5225 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_BOX
);
5226 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_CHRATR_SHADOW
);
5230 const SvxBoxItem
* pBox
5231 = static_cast<const SvxBoxItem
*>(GetFormatAttr( RES_CHRATR_BOX
));
5234 std::unique_ptr
<SvxBoxItem
> aBoxItem(pBox
->Clone());
5236 int nBrcVer
= (nId
== NS_sprm::CBrc::val
) ? 9 : (m_bVer67
? 6 : 8);
5238 SetWW8_BRC(nBrcVer
, aBrc
, pData
, nLen
);
5240 Set1Border(*aBoxItem
, aBrc
, SvxBoxItemLine::TOP
, 0, nullptr, true);
5241 Set1Border(*aBoxItem
, aBrc
, SvxBoxItemLine::BOTTOM
, 0, nullptr, true);
5242 Set1Border(*aBoxItem
, aBrc
, SvxBoxItemLine::LEFT
, 0, nullptr, true);
5243 Set1Border(*aBoxItem
, aBrc
, SvxBoxItemLine::RIGHT
, 0, nullptr, true);
5244 NewAttr( *aBoxItem
);
5246 short aSizeArray
[WW8_RIGHT
+1]={0}; aSizeArray
[WW8_RIGHT
] = 1;
5247 SvxShadowItem
aShadowItem(RES_CHRATR_SHADOW
);
5248 // Word only allows shadows on visible borders
5249 if ( aBoxItem
->CalcLineSpace( SvxBoxItemLine::RIGHT
) )
5250 SetShadow( aShadowItem
, &aSizeArray
[0], aBrc
);
5251 NewAttr( aShadowItem
);
5256 void SwWW8ImplReader::Read_Hyphenation( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5258 // set Hyphenation flag
5260 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_HYPHENZONE
);
5263 SvxHyphenZoneItem
aAttr(
5264 *static_cast<const SvxHyphenZoneItem
*>(GetFormatAttr( RES_PARATR_HYPHENZONE
) ));
5266 aAttr
.SetHyphen( 0 == *pData
); // sic !
5270 aAttr
.GetMinLead() = 2;
5271 aAttr
.GetMinTrail() = 2;
5272 aAttr
.GetMaxHyphens() = 0;
5279 void SwWW8ImplReader::Read_WidowControl( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5283 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_WIDOWS
);
5284 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_ORPHANS
);
5288 sal_uInt8 nL
= ( *pData
& 1 ) ? 2 : 0;
5290 NewAttr( SvxWidowsItem( nL
, RES_PARATR_WIDOWS
) ); // Off -> nLines = 0
5291 NewAttr( SvxOrphansItem( nL
, RES_PARATR_ORPHANS
) );
5293 if( m_pCurrentColl
&& m_xStyles
) // Style-Def ?
5294 m_xStyles
->mbWidowsChanged
= true; // save for simulation
5299 void SwWW8ImplReader::Read_UsePgsuSettings(sal_uInt16
,const sal_uInt8
* pData
,short nLen
)
5302 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_SNAPTOGRID
);
5306 NewAttr( SvxParaGridItem(false, RES_PARATR_SNAPTOGRID
) );
5308 NewAttr( SvxParaGridItem(*pData
, RES_PARATR_SNAPTOGRID
) );
5312 void SwWW8ImplReader::Read_AlignFont( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5315 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_VERTALIGN
);
5318 sal_uInt16 nVal
= SVBT16ToUInt16( pData
);
5319 SvxParaVertAlignItem::Align nAlign
;
5323 nAlign
= SvxParaVertAlignItem::Align::Top
;
5326 nAlign
= SvxParaVertAlignItem::Align::Center
;
5329 nAlign
= SvxParaVertAlignItem::Align::Baseline
;
5332 nAlign
= SvxParaVertAlignItem::Align::Bottom
;
5335 nAlign
= SvxParaVertAlignItem::Align::Automatic
;
5338 nAlign
= SvxParaVertAlignItem::Align::Automatic
;
5339 OSL_ENSURE(false,"Unknown paragraph vertical align");
5342 NewAttr( SvxParaVertAlignItem( nAlign
, RES_PARATR_VERTALIGN
) );
5346 void SwWW8ImplReader::Read_KeepLines( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5349 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_PARATR_SPLIT
);
5351 NewAttr( SvxFormatSplitItem( ( *pData
& 1 ) == 0, RES_PARATR_SPLIT
) );
5354 void SwWW8ImplReader::Read_KeepParas( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5357 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_KEEP
);
5359 NewAttr( SvxFormatKeepItem( ( *pData
& 1 ) != 0 , RES_KEEP
) );
5362 void SwWW8ImplReader::Read_BreakBefore( sal_uInt16
, const sal_uInt8
* pData
, short nLen
)
5365 m_xCtrlStck
->SetAttr( *m_pPaM
->GetPoint(), RES_BREAK
);
5367 NewAttr( SvxFormatBreakItem(
5368 ( *pData
& 1 ) ? SvxBreak::PageBefore
: SvxBreak::NONE
, RES_BREAK
) );
5371 void SwWW8ImplReader::Read_ApoPPC( sal_uInt16
, const sal_uInt8
* pData
, short )
5373 if (m_pCurrentColl
&& m_nCurrentColl
< m_vColl
.size()) // only for Styledef, otherwise solved differently
5375 SwWW8StyInf
& rSI
= m_vColl
[m_nCurrentColl
];
5377 rSI
.m_xWWFly
= std::make_shared
<WW8FlyPara
>(m_bVer67
);
5378 rSI
.m_xWWFly
->Read(*pData
, m_xStyles
.get());
5379 if (rSI
.m_xWWFly
->IsEmpty())
5381 m_vColl
[m_nCurrentColl
].m_xWWFly
.reset();
5386 bool SwWW8ImplReader::ParseTabPos(WW8_TablePos
*pTabPos
, WW8PLCFx_Cp_FKP
* pPap
)
5389 memset(pTabPos
, 0, sizeof(WW8_TablePos
));
5390 // sprmTPc contains a PositionCodeOperand structure that specifies the origin
5391 // that is used to calculate the table position when it is absolutely positioned
5392 SprmResult aRes
= pPap
->HasSprm(NS_sprm::TPc::val
);
5393 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 1)
5395 pTabPos
->nTPc
= *aRes
.pSprm
;
5396 pTabPos
->nPWr
= 2; //Possible fail area, always parallel wrap
5397 aRes
= pPap
->HasSprm(NS_sprm::TDxaAbs::val
);
5398 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 2)
5399 pTabPos
->nTDxaAbs
= SVBT16ToUInt16(aRes
.pSprm
);
5400 aRes
= pPap
->HasSprm(NS_sprm::TDyaAbs::val
);
5401 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 2)
5402 pTabPos
->nTDyaAbs
= SVBT16ToUInt16(aRes
.pSprm
);
5403 aRes
= pPap
->HasSprm(NS_sprm::TDxaFromText::val
);
5404 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 2)
5405 pTabPos
->nLeftMargin
= SVBT16ToUInt16(aRes
.pSprm
);
5406 aRes
= pPap
->HasSprm(NS_sprm::TDxaFromTextRight::val
);
5407 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 2)
5408 pTabPos
->nRightMargin
= SVBT16ToUInt16(aRes
.pSprm
);
5409 aRes
= pPap
->HasSprm(NS_sprm::TDyaFromText::val
);
5410 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 2)
5411 pTabPos
->nUpperMargin
= SVBT16ToUInt16(aRes
.pSprm
);
5412 aRes
= pPap
->HasSprm(NS_sprm::TDyaFromTextBottom::val
);
5413 if (aRes
.pSprm
&& aRes
.nRemainingData
>= 2)
5414 pTabPos
->nLowerMargin
= SVBT16ToUInt16(aRes
.pSprm
);
5416 aRes
= pPap
->HasSprm(NS_sprm::TFNoAllowOverlap::val
);
5419 // Remember the no-overlap request, to be consumed in SwWW8ImplReader::StartApo().
5420 pTabPos
->nTFNoAllowOverlap
= *aRes
.pSprm
;
5428 // page attribute won't be used as attribute anymore
5430 tools::Long
SwWW8ImplReader::ImportExtSprm(WW8PLCFManResult
* pRes
)
5432 // array for reading of the extended ( self-defined ) SPRMs
5433 typedef tools::Long (SwWW8ImplReader::*FNReadRecordExt
)(WW8PLCFManResult
*);
5435 static const FNReadRecordExt aWwSprmTab
[] =
5437 /* 0 (256) */ &SwWW8ImplReader::Read_Footnote
, // FootNote
5438 /* 1 (257) */ &SwWW8ImplReader::Read_Footnote
, // EndNote
5439 /* 2 (258) */ &SwWW8ImplReader::Read_Field
, // Field
5440 /* 3 (259) */ &SwWW8ImplReader::Read_Book
, // Bookmark
5441 /* 4 (260) */ &SwWW8ImplReader::Read_And
, // Annotation
5442 /* 5 (261) */ &SwWW8ImplReader::Read_AtnBook
, // Annotationmark
5443 /* 6 (262) */ &SwWW8ImplReader::Read_FactoidBook
// Smart tag bookmark
5446 if( pRes
->nSprmId
< 280 )
5448 sal_uInt8 nIdx
= static_cast< sal_uInt8
>(pRes
->nSprmId
- eFTN
);
5449 if( nIdx
< SAL_N_ELEMENTS(aWwSprmTab
)
5450 && aWwSprmTab
[nIdx
] )
5451 return (this->*aWwSprmTab
[nIdx
])(pRes
);
5459 void SwWW8ImplReader::EndExtSprm(sal_uInt16 nSprmId
)
5461 typedef sal_uInt16 (SwWW8ImplReader::*FNReadRecordExt
)();
5463 static const FNReadRecordExt aWwSprmTab
[] =
5465 /* 0 (256) */ &SwWW8ImplReader::End_Footnote
, // FootNote
5466 /* 1 (257) */ &SwWW8ImplReader::End_Footnote
, // EndNote
5467 /* 2 (258) */ &SwWW8ImplReader::End_Field
, // Field
5468 /* 3 (259) */ nullptr, // Bookmark
5469 /* 4 (260) */ nullptr // Annotation
5472 sal_uInt8 nIdx
= static_cast< sal_uInt8
>(nSprmId
- eFTN
);
5473 if( nIdx
< SAL_N_ELEMENTS(aWwSprmTab
)
5474 && aWwSprmTab
[nIdx
] )
5475 (this->*aWwSprmTab
[nIdx
])();
5478 // arrays for reading the SPRMs
5480 // function for reading of SPRMs. Par1: SprmId
5481 typedef void (SwWW8ImplReader::*FNReadRecord
)( sal_uInt16
, const sal_uInt8
*, short );
5486 FNReadRecord pReadFnc
;
5489 static bool operator<(const SprmReadInfo
&rFirst
, const SprmReadInfo
&rSecond
)
5491 return (rFirst
.nId
< rSecond
.nId
);
5494 typedef ww::SortedArray
<SprmReadInfo
> wwSprmDispatcher
;
5496 static const wwSprmDispatcher
*GetWW2SprmDispatcher()
5498 static SprmReadInfo aSprms
[] =
5500 {0, nullptr}, // "0" default resp. error
5501 // will be skipped! ,
5502 {2, &SwWW8ImplReader::Read_StyleCode
}, //"sprmPIstd", pap.istd
5504 {3, nullptr}, //"sprmPIstdPermute", pap.istd
5506 {4, nullptr}, //"sprmPIncLv1",
5507 //pap.istddifference
5508 {5, &SwWW8ImplReader::Read_Justify
}, //"sprmPJc", pap.jc
5510 {6, nullptr}, //"sprmPFSideBySide",
5512 {7, &SwWW8ImplReader::Read_KeepLines
}, //"sprmPFKeep", pap.fKeep
5513 {8, &SwWW8ImplReader::Read_KeepParas
}, //"sprmPFKeepFollow ",
5515 {9, &SwWW8ImplReader::Read_BreakBefore
}, //"sprmPPageBreakBefore",
5516 //pap.fPageBreakBefore
5517 {10, nullptr}, //"sprmPBrcl", pap.brcl
5518 {11, nullptr}, //"sprmPBrcp ", pap.brcp
5519 {12, &SwWW8ImplReader::Read_ANLevelDesc
}, //"sprmPAnld", pap.anld (ANLD
5521 {13, &SwWW8ImplReader::Read_ANLevelNo
}, //"sprmPNLvlAnm", pap.nLvlAnm
5523 {14, &SwWW8ImplReader::Read_NoLineNumb
}, //"sprmPFNoLineNumb", ap.fNoLnn
5524 {15, &SwWW8ImplReader::Read_Tab
}, //"?sprmPChgTabsPapx",
5526 {16, &SwWW8ImplReader::Read_LR
}, //"sprmPDxaRight", pap.dxaRight
5527 {17, &SwWW8ImplReader::Read_LR
}, //"sprmPDxaLeft", pap.dxaLeft
5528 {18, nullptr}, //"sprmPNest", pap.dxaLeft
5529 {19, &SwWW8ImplReader::Read_LR
}, //"sprmPDxaLeft1", pap.dxaLeft1
5530 {20, &SwWW8ImplReader::Read_LineSpace
}, //"sprmPDyaLine", pap.lspd
5532 {21, &SwWW8ImplReader::Read_UL
}, //"sprmPDyaBefore",
5534 {22, &SwWW8ImplReader::Read_UL
}, //"sprmPDyaAfter", pap.dyaAfter
5535 {23, nullptr}, //"?sprmPChgTabs", pap.itbdMac,
5537 {24, nullptr}, //"sprmPFInTable", pap.fInTable
5538 {25, &SwWW8ImplReader::Read_TabRowEnd
}, //"sprmPTtp", pap.fTtp
5539 {26, nullptr}, //"sprmPDxaAbs", pap.dxaAbs
5540 {27, nullptr}, //"sprmPDyaAbs", pap.dyaAbs
5541 {28, nullptr}, //"sprmPDxaWidth", pap.dxaWidth
5542 {29, &SwWW8ImplReader::Read_ApoPPC
}, //"sprmPPc", pap.pcHorz,
5544 {30, nullptr}, //"sprmPBrcTop10", pap.brcTop
5546 {31, nullptr}, //"sprmPBrcLeft10",
5548 {32, nullptr}, //"sprmPBrcBottom10",
5549 //pap.brcBottom BRC10
5550 {33, nullptr}, //"sprmPBrcRight10",
5551 //pap.brcRight BRC10
5552 {34, nullptr}, //"sprmPBrcBetween10",
5553 //pap.brcBetween BRC10
5554 {35, nullptr}, //"sprmPBrcBar10", pap.brcBar
5556 {36, nullptr}, //"sprmPFromText10",
5557 //pap.dxaFromText dxa
5558 {37, nullptr}, //"sprmPWr", pap.wr wr
5559 {38, &SwWW8ImplReader::Read_Border
}, //"sprmPBrcTop", pap.brcTop BRC
5560 {39, &SwWW8ImplReader::Read_Border
}, //"sprmPBrcLeft",
5562 {40, &SwWW8ImplReader::Read_Border
}, //"sprmPBrcBottom",
5564 {41, &SwWW8ImplReader::Read_Border
}, //"sprmPBrcRight",
5566 {42, &SwWW8ImplReader::Read_Border
}, //"sprmPBrcBetween",
5567 //pap.brcBetween BRC
5568 {43, nullptr}, //"sprmPBrcBar", pap.brcBar
5570 {44, &SwWW8ImplReader::Read_Hyphenation
}, //"sprmPFNoAutoHyph",
5572 {45, nullptr}, //"sprmPWHeightAbs",
5574 {46, nullptr}, //"sprmPDcs", pap.dcs DCS
5575 {47, &SwWW8ImplReader::Read_Shade
}, //"sprmPShd", pap.shd SHD
5576 {48, nullptr}, //"sprmPDyaFromText",
5577 //pap.dyaFromText dya
5578 {49, nullptr}, //"sprmPDxaFromText",
5579 //pap.dxaFromText dxa
5580 {50, nullptr}, //"sprmPFLocked", pap.fLocked
5582 {51, &SwWW8ImplReader::Read_WidowControl
}, //"sprmPFWidowControl",
5583 //pap.fWidowControl 0 or 1 byte
5584 {52, nullptr}, //"?sprmPRuler 52",
5585 {53, nullptr}, //"??53",
5586 {54, nullptr}, //"??54",
5587 {55, nullptr}, //"??55",
5588 {56, nullptr}, //"??56",
5589 {57, nullptr}, //"??57",
5590 {58, nullptr}, //"??58",
5591 {59, nullptr}, //"??59",
5593 {60, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFBold", chp.fBold 0,1,
5595 {61, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFItalic", chp.fItalic
5596 //0,1, 128, or 129 byte
5597 {62, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFStrike", chp.fStrike
5598 //0,1, 128, or 129 byte
5599 {63, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFOutline", chp.fOutline
5600 //0,1, 128, or 129 byte
5601 {64, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFShadow", chp.fShadow
5602 //0,1, 128, or 129 byte
5603 {65, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFSmallCaps",
5604 //chp.fSmallCaps 0,1, 128, or
5606 {66, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFCaps", chp.fCaps 0,1,
5608 {67, &SwWW8ImplReader::Read_BoldUsw
}, //"sprmCFVanish", chp.fVanish
5609 //0,1, 128, or 129 byte
5610 {68, &SwWW8ImplReader::Read_FontCode
}, //"sprmCFtc", chp.ftc ftc word
5611 {69, &SwWW8ImplReader::Read_Underline
}, // "sprmCKul", chp.kul kul byte
5612 {70, nullptr}, //"sprmCSizePos", chp.hps,
5613 //chp.hpsPos 3 bytes
5614 {71, &SwWW8ImplReader::Read_Kern
}, //"sprmCDxaSpace",
5615 //chp.dxaSpace dxa word
5616 {72, &SwWW8ImplReader::Read_Language
}, //"sprmCLid", chp.lid LID word
5617 {73, &SwWW8ImplReader::Read_TextColor
}, //"sprmCIco", chp.ico ico byte
5618 {74, &SwWW8ImplReader::Read_FontSize
}, //"sprmCHps", chp.hps hps word!
5619 {75, nullptr}, //"sprmCHpsInc", chp.hps byte
5620 {76, &SwWW8ImplReader::Read_SubSuperProp
}, //"sprmCHpsPos", chp.hpsPos
5622 {77, nullptr}, //"sprmCHpsPosAdj", chp.hpsPos
5624 {78, &SwWW8ImplReader::Read_Majority
}, //"?sprmCMajority", chp.fBold,
5625 //chp.fItalic, chp.fSmallCaps
5626 {80, &SwWW8ImplReader::Read_BoldBiDiUsw
}, //sprmCFBoldBi
5627 {81, &SwWW8ImplReader::Read_BoldBiDiUsw
}, //sprmCFItalicBi
5628 {82, &SwWW8ImplReader::Read_FontCode
}, //sprmCFtcBi
5629 {83, &SwWW8ImplReader::Read_Language
}, //sprmClidBi
5630 {84, &SwWW8ImplReader::Read_TextColor
}, //sprmCIcoBi
5631 {85, &SwWW8ImplReader::Read_FontSize
}, //sprmCHpsBi
5632 {86, nullptr}, //sprmCFBiDi
5633 {87, nullptr}, //sprmCFDiacColor
5634 {94, nullptr}, //"sprmPicBrcl", pic.brcl brcl
5635 //(see PIC structure
5637 {95, nullptr}, //"sprmPicScale", pic.mx,
5638 //pic.my, pic.dxaCropleft,
5639 {96, nullptr}, //"sprmPicBrcTop", pic.brcTop
5641 {97, nullptr}, //"sprmPicBrcLeft",
5642 //pic.brcLeft BRC word
5643 {98, nullptr}, //"sprmPicBrcBottom",
5644 //pic.brcBottom BRC word
5645 {99, nullptr} //"sprmPicBrcRight",
5648 static wwSprmDispatcher
aSprmSrch(aSprms
, SAL_N_ELEMENTS(aSprms
));
5652 static const wwSprmDispatcher
*GetWW6SprmDispatcher()
5654 static SprmReadInfo aSprms
[] =
5656 {0, nullptr}, // "0" default resp. error
5658 {NS_sprm::v6::sprmPIstd
, &SwWW8ImplReader::Read_StyleCode
}, // pap.istd (style code)
5659 {NS_sprm::v6::sprmPIstdPermute
, nullptr}, // pap.istd permutation
5660 {NS_sprm::v6::sprmPIncLv1
, nullptr}, // pap.istddifference
5661 {NS_sprm::v6::sprmPJc
, &SwWW8ImplReader::Read_Justify
}, // pap.jc (justification)
5662 {NS_sprm::v6::sprmPFSideBySide
, nullptr}, // pap.fSideBySide
5663 {NS_sprm::v6::sprmPFKeep
, &SwWW8ImplReader::Read_KeepLines
}, // pap.fKeep
5664 {NS_sprm::v6::sprmPFKeepFollow
, &SwWW8ImplReader::Read_KeepParas
}, // pap.fKeepFollow
5665 {NS_sprm::v6::sprmPPageBreakBefore
, &SwWW8ImplReader::Read_BreakBefore
}, // pap.fPageBreakBefore
5666 {NS_sprm::v6::sprmPBrcl
, nullptr}, // pap.brcl
5667 {NS_sprm::v6::sprmPBrcp
, nullptr}, // pap.brcp
5668 {NS_sprm::v6::sprmPAnld
, &SwWW8ImplReader::Read_ANLevelDesc
}, // pap.anld (ANLD structure)
5669 {NS_sprm::v6::sprmPNLvlAnm
, &SwWW8ImplReader::Read_ANLevelNo
}, // pap.nLvlAnm nn
5670 {NS_sprm::v6::sprmPFNoLineNumb
, &SwWW8ImplReader::Read_NoLineNumb
}, // ap.fNoLnn
5671 {NS_sprm::v6::sprmPChgTabsPapx
, &SwWW8ImplReader::Read_Tab
}, // pap.itbdMac, ...
5672 {NS_sprm::v6::sprmPDxaRight
, &SwWW8ImplReader::Read_LR
}, // pap.dxaRight
5673 {NS_sprm::v6::sprmPDxaLeft
, &SwWW8ImplReader::Read_LR
}, // pap.dxaLeft
5674 {NS_sprm::v6::sprmPNest
, nullptr}, // pap.dxaLeft
5675 {NS_sprm::v6::sprmPDxaLeft1
, &SwWW8ImplReader::Read_LR
}, // pap.dxaLeft1
5676 {NS_sprm::v6::sprmPDyaLine
, &SwWW8ImplReader::Read_LineSpace
}, // pap.lspd an LSPD
5677 {NS_sprm::v6::sprmPDyaBefore
, &SwWW8ImplReader::Read_UL
}, // pap.dyaBefore
5678 {NS_sprm::v6::sprmPDyaAfter
, &SwWW8ImplReader::Read_UL
}, // pap.dyaAfter
5679 {NS_sprm::v6::sprmPChgTabs
, nullptr}, // pap.itbdMac, pap.rgdxaTab, ...
5680 {NS_sprm::v6::sprmPFInTable
, nullptr}, // pap.fInTable
5681 {NS_sprm::v6::sprmPTtp
, &SwWW8ImplReader::Read_TabRowEnd
}, // pap.fTtp
5682 {NS_sprm::v6::sprmPDxaAbs
, nullptr}, // pap.dxaAbs
5683 {NS_sprm::v6::sprmPDyaAbs
, nullptr}, // pap.dyaAbs
5684 {NS_sprm::v6::sprmPDxaWidth
, nullptr}, // pap.dxaWidth
5685 {NS_sprm::v6::sprmPPc
, &SwWW8ImplReader::Read_ApoPPC
}, // pap.pcHorz, pap.pcVert
5686 {NS_sprm::v6::sprmPBrcTop10
, nullptr}, // pap.brcTop BRC10
5687 {NS_sprm::v6::sprmPBrcLeft10
, nullptr}, // pap.brcLeft BRC10
5688 {NS_sprm::v6::sprmPBrcBottom10
, nullptr}, // pap.brcBottom BRC10
5689 {NS_sprm::v6::sprmPBrcRight10
, nullptr}, // pap.brcRight BRC10
5690 {NS_sprm::v6::sprmPBrcBetween10
, nullptr}, // pap.brcBetween BRC10
5691 {NS_sprm::v6::sprmPBrcBar10
, nullptr}, // pap.brcBar BRC10
5692 {NS_sprm::v6::sprmPFromText10
, nullptr}, // pap.dxaFromText dxa
5693 {NS_sprm::v6::sprmPWr
, nullptr}, // pap.wr wr
5694 {NS_sprm::v6::sprmPBrcTop
, &SwWW8ImplReader::Read_Border
}, // pap.brcTop BRC
5695 {NS_sprm::v6::sprmPBrcLeft
, &SwWW8ImplReader::Read_Border
}, // pap.brcLeft BRC
5696 {NS_sprm::v6::sprmPBrcBottom
, &SwWW8ImplReader::Read_Border
}, // pap.brcBottom BRC
5697 {NS_sprm::v6::sprmPBrcRight
, &SwWW8ImplReader::Read_Border
}, // pap.brcRight BRC
5698 {NS_sprm::v6::sprmPBrcBetween
, &SwWW8ImplReader::Read_Border
}, // pap.brcBetween BRC
5699 {NS_sprm::v6::sprmPBrcBar
, nullptr}, // pap.brcBar BRC word
5700 {NS_sprm::v6::sprmPFNoAutoHyph
, &SwWW8ImplReader::Read_Hyphenation
}, // pap.fNoAutoHyph
5701 {NS_sprm::v6::sprmPWHeightAbs
, nullptr}, // pap.wHeightAbs w
5702 {NS_sprm::v6::sprmPDcs
, nullptr}, // pap.dcs DCS
5703 {NS_sprm::v6::sprmPShd
, &SwWW8ImplReader::Read_Shade
}, // pap.shd SHD
5704 {NS_sprm::v6::sprmPDyaFromText
, nullptr}, // pap.dyaFromText dya
5705 {NS_sprm::v6::sprmPDxaFromText
, nullptr}, // pap.dxaFromText dxa
5706 {NS_sprm::v6::sprmPFLocked
, nullptr}, // pap.fLocked 0 or 1 byte
5707 {NS_sprm::v6::sprmPFWidowControl
, &SwWW8ImplReader::Read_WidowControl
}, // pap.fWidowControl 0 or 1 byte
5708 {NS_sprm::v6::sprmPRuler
, nullptr},
5709 {53, nullptr}, //"??53",
5710 {54, nullptr}, //"??54",
5711 {55, nullptr}, //"??55",
5712 {56, nullptr}, //"??56",
5713 {57, nullptr}, //"??57",
5714 {58, nullptr}, //"??58",
5715 {59, nullptr}, //"??59",
5716 {60, nullptr}, //"??60",
5717 {61, nullptr}, //"??61",
5718 {62, nullptr}, //"??62",
5719 {63, nullptr}, //"??63",
5720 {64, &SwWW8ImplReader::Read_ParaBiDi
}, //"rtl bidi ?
5721 {NS_sprm::v6::sprmCFStrikeRM
, &SwWW8ImplReader::Read_CFRMarkDel
}, // chp.fRMarkDel 1 or 0 bit
5722 {NS_sprm::v6::sprmCFRMark
, &SwWW8ImplReader::Read_CFRMark
}, // chp.fRMark 1 or 0 bit
5723 {NS_sprm::v6::sprmCFFldVanish
, &SwWW8ImplReader::Read_FieldVanish
}, // chp.fFieldVanish 1 or 0 bit
5724 {NS_sprm::v6::sprmCPicLocation
, &SwWW8ImplReader::Read_PicLoc
}, // chp.fcPic and chp.fSpec
5725 {NS_sprm::v6::sprmCIbstRMark
, nullptr}, // chp.ibstRMark index into sttbRMark
5726 {NS_sprm::v6::sprmCDttmRMark
, nullptr}, // chp.dttm DTTM long
5727 {NS_sprm::v6::sprmCFData
, nullptr}, // chp.fData 1 or 0 bit
5728 {NS_sprm::v6::sprmCRMReason
, nullptr}, // chp.idslRMReason an index to a table
5729 {NS_sprm::v6::sprmCChse
, &SwWW8ImplReader::Read_CharSet
}, // chp.fChsDiff and chp.chse 3 bytes
5730 {NS_sprm::v6::sprmCSymbol
, &SwWW8ImplReader::Read_Symbol
}, // chp.fSpec, chp.chSym and chp.ftcSym
5731 {NS_sprm::v6::sprmCFOle2
, &SwWW8ImplReader::Read_Obj
}, // chp.fOle2 1 or 0 bit
5732 {76, nullptr}, //"??76",
5733 {77, nullptr}, //"??77",
5734 {78, nullptr}, //"??78",
5735 {79, nullptr}, //"??79",
5736 {NS_sprm::v6::sprmCIstd
, &SwWW8ImplReader::Read_CColl
}, // chp.istd istd, see stylesheet definition; short
5737 {NS_sprm::v6::sprmCIstdPermute
, nullptr}, // chp.istd permutation vector
5738 {NS_sprm::v6::sprmCDefault
, nullptr}, // whole CHP none variable length
5739 {NS_sprm::v6::sprmCPlain
, nullptr}, // whole CHP none 0
5740 {84, nullptr}, //"??84",
5741 {NS_sprm::v6::sprmCFBold
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fBold 0,1, 128, or 129 byte
5742 {NS_sprm::v6::sprmCFItalic
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fItalic 0,1, 128, or 129 byte
5743 {NS_sprm::v6::sprmCFStrike
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fStrike 0,1, 128, or 129 byte
5744 {NS_sprm::v6::sprmCFOutline
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fOutline 0,1, 128, or 129 byte
5745 {NS_sprm::v6::sprmCFShadow
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fShadow 0,1, 128, or 129 byte
5746 {NS_sprm::v6::sprmCFSmallCaps
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fSmallCaps 0,1, 128, or 129 byte
5747 {NS_sprm::v6::sprmCFCaps
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fCaps 0,1, 128, or 129 byte
5748 {NS_sprm::v6::sprmCFVanish
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fVanish 0,1, 128, or 129 byte
5749 {NS_sprm::v6::sprmCFtc
, &SwWW8ImplReader::Read_FontCode
}, // chp.ftc ftc word
5750 {NS_sprm::v6::sprmCKul
, &SwWW8ImplReader::Read_Underline
}, // chp.kul kul byte
5751 {NS_sprm::v6::sprmCSizePos
, nullptr}, // chp.hps, chp.hpsPos 3 bytes
5752 {NS_sprm::v6::sprmCDxaSpace
, &SwWW8ImplReader::Read_Kern
}, // chp.dxaSpace dxa word
5753 {NS_sprm::v6::sprmCLid
, &SwWW8ImplReader::Read_Language
}, // chp.lid LID word
5754 {NS_sprm::v6::sprmCIco
, &SwWW8ImplReader::Read_TextColor
}, // chp.ico ico byte
5755 {NS_sprm::v6::sprmCHps
, &SwWW8ImplReader::Read_FontSize
}, // chp.hps hps word!
5756 {NS_sprm::v6::sprmCHpsInc
, nullptr}, // chp.hps byte
5757 {NS_sprm::v6::sprmCHpsPos
, &SwWW8ImplReader::Read_SubSuperProp
}, // chp.hpsPos hps byte
5758 {NS_sprm::v6::sprmCHpsPosAdj
, nullptr}, // chp.hpsPos hps byte
5759 {NS_sprm::v6::sprmCMajority
, &SwWW8ImplReader::Read_Majority
}, // chp.fBold, chp.fItalic, chp.fSmallCaps
5760 {NS_sprm::v6::sprmCIss
, &SwWW8ImplReader::Read_SubSuper
}, // chp.iss iss byte
5761 {NS_sprm::v6::sprmCHpsNew50
, nullptr}, // chp.hps hps variable width, length always recorded as 2
5762 {NS_sprm::v6::sprmCHpsInc1
, nullptr}, // chp.hps complex variable width, length always recorded as 2
5763 {NS_sprm::v6::sprmCHpsKern
, &SwWW8ImplReader::Read_FontKern
}, // chp.hpsKern hps short
5764 {NS_sprm::v6::sprmCMajority50
, &SwWW8ImplReader::Read_Majority
}, // chp.fBold, chp.fItalic, chp.fSmallCaps, chp.fVanish, ...
5765 {NS_sprm::v6::sprmCHpsMul
, nullptr}, // chp.hps percentage to grow hps short
5766 {NS_sprm::v6::sprmCCondHyhen
, nullptr}, // chp.ysri ysri short
5767 {111, &SwWW8ImplReader::Read_AmbiguousSPRM
},//sprmCFBoldBi or font code
5768 {112, &SwWW8ImplReader::Read_AmbiguousSPRM
},//sprmCFItalicBi or font code
5769 {113, &SwWW8ImplReader::Read_FontCode
}, //sprmCFtcBi
5770 {114, &SwWW8ImplReader::Read_Language
}, //sprmClidBi
5771 {115, &SwWW8ImplReader::Read_TextColor
}, //sprmCIcoBi
5772 {116, &SwWW8ImplReader::Read_FontSize
}, //sprmCHpsBi
5773 {NS_sprm::v6::sprmCFSpec
, &SwWW8ImplReader::Read_Special
}, // chp.fSpec 1 or 0 bit
5774 {NS_sprm::v6::sprmCFObj
, &SwWW8ImplReader::Read_Obj
}, // chp.fObj 1 or 0 bit
5775 {NS_sprm::v6::sprmPicBrcl
, nullptr}, // pic.brcl brcl (see PIC structure definition) byte
5776 {NS_sprm::v6::sprmPicScale
, nullptr}, // pic.mx, pic.my, pic.dxaCropleft,
5777 {NS_sprm::v6::sprmPicBrcTop
, nullptr}, // pic.brcTop BRC word
5778 {NS_sprm::v6::sprmPicBrcLeft
, nullptr}, // pic.brcLeft BRC word
5779 {NS_sprm::v6::sprmPicBrcBottom
, nullptr}, // pic.brcBottom BRC word
5780 {NS_sprm::v6::sprmPicBrcRight
, nullptr}, // pic.brcRight BRC word
5781 {125, nullptr}, //"??125",
5782 {126, nullptr}, //"??126",
5783 {127, nullptr}, //"??127",
5784 {128, nullptr}, //"??128",
5785 {129, nullptr}, //"??129",
5786 {130, nullptr}, //"??130",
5787 {NS_sprm::v6::sprmSScnsPgn
, nullptr}, // sep.cnsPgn cns byte
5788 {NS_sprm::v6::sprmSiHeadingPgn
, nullptr}, // sep.iHeadingPgn heading number level byte
5789 {NS_sprm::v6::sprmSOlstAnm
, &SwWW8ImplReader::Read_OLST
}, // sep.olstAnm OLST variable length
5790 {134, nullptr}, //"??135",
5791 {135, nullptr}, //"??135",
5792 {NS_sprm::v6::sprmSDxaColWidth
, nullptr}, // sep.rgdxaColWidthSpacing complex 3 bytes
5793 {NS_sprm::v6::sprmSDxaColSpacing
, nullptr}, // sep.rgdxaColWidthSpacing complex 3 bytes
5794 {NS_sprm::v6::sprmSFEvenlySpaced
, nullptr}, // sep.fEvenlySpaced 1 or 0 byte
5795 {NS_sprm::v6::sprmSFProtected
, nullptr}, // sep.fUnlocked 1 or 0 byte
5796 {NS_sprm::v6::sprmSDmBinFirst
, nullptr}, // sep.dmBinFirst word
5797 {NS_sprm::v6::sprmSDmBinOther
, nullptr}, // sep.dmBinOther word
5798 {NS_sprm::v6::sprmSBkc
, nullptr}, // sep.bkc bkc byte BreakCode
5799 {NS_sprm::v6::sprmSFTitlePage
, nullptr}, // sep.fTitlePage 0 or 1 byte
5800 {NS_sprm::v6::sprmSCcolumns
, nullptr}, // sep.ccolM1 # of cols - 1 word
5801 {NS_sprm::v6::sprmSDxaColumns
, nullptr}, // sep.dxaColumns dxa word
5802 {NS_sprm::v6::sprmSFAutoPgn
, nullptr}, // sep.fAutoPgn obsolete byte
5803 {NS_sprm::v6::sprmSNfcPgn
, nullptr}, // sep.nfcPgn nfc byte
5804 {NS_sprm::v6::sprmSDyaPgn
, nullptr}, // sep.dyaPgn dya short
5805 {NS_sprm::v6::sprmSDxaPgn
, nullptr}, // sep.dxaPgn dya short
5806 {NS_sprm::v6::sprmSFPgnRestart
, nullptr}, // sep.fPgnRestart 0 or 1 byte
5807 {NS_sprm::v6::sprmSFEndnote
, nullptr}, // sep.fEndnote 0 or 1 byte
5808 {NS_sprm::v6::sprmSLnc
, nullptr}, // sep.lnc lnc byte
5809 {NS_sprm::v6::sprmSGprfIhdt
, nullptr}, // sep.grpfIhdt grpfihdt byte
5810 {NS_sprm::v6::sprmSNLnnMod
, nullptr}, // sep.nLnnMod non-neg int. word
5811 {NS_sprm::v6::sprmSDxaLnn
, nullptr}, // sep.dxaLnn dxa word
5812 {NS_sprm::v6::sprmSDyaHdrTop
, nullptr}, // sep.dyaHdrTop dya word
5813 {NS_sprm::v6::sprmSDyaHdrBottom
, nullptr}, // sep.dyaHdrBottom dya word
5814 {NS_sprm::v6::sprmSLBetween
, nullptr}, // sep.fLBetween 0 or 1 byte
5815 {NS_sprm::v6::sprmSVjc
, nullptr}, // sep.vjc vjc byte
5816 {NS_sprm::v6::sprmSLnnMin
, nullptr}, // sep.lnnMin lnn word
5817 {NS_sprm::v6::sprmSPgnStart
, nullptr}, // sep.pgnStart pgn word
5818 {NS_sprm::v6::sprmSBOrientation
, nullptr}, // sep.dmOrientPage dm byte
5819 {NS_sprm::v6::sprmSBCustomize
, nullptr}, // ?
5820 {NS_sprm::v6::sprmSXaPage
, nullptr}, // sep.xaPage xa word
5821 {NS_sprm::v6::sprmSYaPage
, nullptr}, // sep.yaPage ya word
5822 {NS_sprm::v6::sprmSDxaLeft
, nullptr}, // sep.dxaLeft dxa word
5823 {NS_sprm::v6::sprmSDxaRight
, nullptr}, // sep.dxaRight dxa word
5824 {NS_sprm::v6::sprmSDyaTop
, nullptr}, // sep.dyaTop dya word
5825 {NS_sprm::v6::sprmSDyaBottom
, nullptr}, // sep.dyaBottom dya word
5826 {NS_sprm::v6::sprmSDzaGutter
, nullptr}, // sep.dzaGutter dza word
5827 {NS_sprm::v6::sprmSDMPaperReq
, nullptr}, // sep.dmPaperReq dm word
5828 {172, nullptr}, //"??172",
5829 {173, nullptr}, //"??173",
5830 {174, nullptr}, //"??174",
5831 {175, nullptr}, //"??175",
5832 {176, nullptr}, //"??176",
5833 {177, nullptr}, //"??177",
5834 {178, nullptr}, //"??178",
5835 {179, nullptr}, //"??179",
5836 {180, nullptr}, //"??180",
5837 {181, nullptr}, //"??181",
5838 {NS_sprm::v6::sprmTJc
, nullptr}, // tap.jc jc word (low order byte is significant)
5839 {NS_sprm::v6::sprmTDxaLeft
, nullptr}, // tap.rgdxaCenter dxa word
5840 {NS_sprm::v6::sprmTDxaGapHalf
, nullptr}, // tap.dxaGapHalf, tap.rgdxaCenter dxa word
5841 {NS_sprm::v6::sprmTFCantSplit
, nullptr}, // tap.fCantSplit 1 or 0 byte
5842 {NS_sprm::v6::sprmTTableHeader
, nullptr}, // tap.fTableHeader 1 or 0 byte
5843 {NS_sprm::v6::sprmTTableBorders
, nullptr}, // tap.rgbrcTable complex 12 bytes
5844 {NS_sprm::v6::sprmTDefTable10
, nullptr}, // tap.rgdxaCenter, tap.rgtc complex variable length
5845 {NS_sprm::v6::sprmTDyaRowHeight
, nullptr}, // tap.dyaRowHeight dya word
5846 {NS_sprm::v6::sprmTDefTable
, nullptr}, // tap.rgtc complex
5847 {NS_sprm::v6::sprmTDefTableShd
, nullptr}, // tap.rgshd complex
5848 {NS_sprm::v6::sprmTTlp
, nullptr}, // tap.tlp TLP 4 bytes
5849 {NS_sprm::v6::sprmTSetBrc
, nullptr}, // tap.rgtc[].rgbrc complex 5 bytes
5850 {NS_sprm::v6::sprmTInsert
, nullptr}, // tap.rgdxaCenter, tap.rgtc complex 4 bytes
5851 {NS_sprm::v6::sprmTDelete
, nullptr}, // tap.rgdxaCenter, tap.rgtc complex word
5852 {NS_sprm::v6::sprmTDxaCol
, nullptr}, // tap.rgdxaCenter complex 4 bytes
5853 {NS_sprm::v6::sprmTMerge
, nullptr}, // tap.fFirstMerged, tap.fMerged complex word
5854 {NS_sprm::v6::sprmTSplit
, nullptr}, // tap.fFirstMerged, tap.fMerged complex word
5855 {NS_sprm::v6::sprmTSetBrc10
, nullptr}, // tap.rgtc[].rgbrc complex 5 bytes
5856 {NS_sprm::v6::sprmTSetShd
, nullptr}, // tap.rgshd complex 4 bytes
5857 {207, nullptr}, //dunno
5860 static wwSprmDispatcher
aSprmSrch(aSprms
, SAL_N_ELEMENTS(aSprms
));
5864 static const wwSprmDispatcher
*GetWW8SprmDispatcher()
5866 static SprmReadInfo aSprms
[] =
5868 {0, nullptr}, // "0" default resp. error
5870 {NS_sprm::PIstd::val
, &SwWW8ImplReader::Read_StyleCode
}, // pap.istd;istd (style code);short;
5871 {NS_sprm::PIstdPermute::val
, nullptr}, // pap.istd;permutation vector;
5873 {NS_sprm::PIncLvl::val
, nullptr}, // pap.istd, pap.lvl;difference between
5874 // istd of base PAP and istd of
5875 // PAP to be produced;byte;
5876 {NS_sprm::PJc80::val
, &SwWW8ImplReader::Read_Justify
}, // pap.jc;jc (justification);byte;
5877 {NS_sprm::LN_PFSideBySide
, nullptr}, // pap.fSideBySide;0 or 1;byte;
5878 {NS_sprm::PFKeep::val
, &SwWW8ImplReader::Read_KeepLines
}, // pap.fKeep;0 or 1;byte;
5879 {NS_sprm::PFKeepFollow::val
, &SwWW8ImplReader::Read_KeepParas
}, // pap.fKeepFollow;0 or 1;byte;
5880 {NS_sprm::PFPageBreakBefore::val
, &SwWW8ImplReader::Read_BreakBefore
}, // pap.fPageBreakBefore;0 or 1;byte;
5881 {NS_sprm::LN_PBrcl
, nullptr}, // pap.brcl;brcl;byte;
5882 {NS_sprm::LN_PBrcp
, nullptr}, // pap.brcp;brcp;byte;
5883 {NS_sprm::PIlvl::val
, &SwWW8ImplReader::Read_ListLevel
}, // pap.ilvl;ilvl;byte;
5884 {NS_sprm::PIlfo::val
, &SwWW8ImplReader::Read_LFOPosition
}, // pap.ilfo;ilfo (list index);short;
5885 {NS_sprm::PFNoLineNumb::val
, &SwWW8ImplReader::Read_NoLineNumb
}, // pap.fNoLnn;0 or 1;byte;
5886 {NS_sprm::PChgTabsPapx::val
, &SwWW8ImplReader::Read_Tab
}, // pap.itbdMac, pap.rgdxaTab, pap.rgtbd;
5887 // complex;variable length
5888 {NS_sprm::PDxaRight80::val
, &SwWW8ImplReader::Read_LR
}, // pap.dxaRight;dxa;word;
5889 {NS_sprm::PDxaLeft80::val
, &SwWW8ImplReader::Read_LR
}, // pap.dxaLeft;dxa;word;
5890 {NS_sprm::PNest80::val
, nullptr}, // pap.dxaLeft;dxa;word;
5891 {NS_sprm::PDxaLeft180::val
, &SwWW8ImplReader::Read_LR
}, // pap.dxaLeft1;dxa;word;
5892 {NS_sprm::PDyaLine::val
, &SwWW8ImplReader::Read_LineSpace
}, // pap.lspd;an LSPD, a long word
5893 // structure consisting of a short
5894 // of dyaLine followed by a short
5895 // of fMultLinespace;long;
5896 {NS_sprm::PDyaBefore::val
, &SwWW8ImplReader::Read_UL
}, // pap.dyaBefore;dya;word;
5897 {NS_sprm::PDyaAfter::val
, &SwWW8ImplReader::Read_UL
}, // pap.dyaAfter;dya;word;
5898 {NS_sprm::PChgTabs::val
, nullptr}, // pap.itbdMac, pap.rgdxaTab, pap.rgtbd;
5899 // complex;variable length;
5900 {NS_sprm::PFInTable::val
, nullptr}, // pap.fInTable;0 or 1;byte;
5901 {NS_sprm::PFTtp::val
, &SwWW8ImplReader::Read_TabRowEnd
}, // pap.fTtp;0 or 1;byte;
5902 {NS_sprm::PDxaAbs::val
, nullptr}, // pap.dxaAbs;dxa;word;
5903 {NS_sprm::PDyaAbs::val
, nullptr}, // pap.dyaAbs;dya;word;
5904 {NS_sprm::PDxaWidth::val
, nullptr}, // pap.dxaWidth;dxa;word;
5905 {NS_sprm::PPc::val
, &SwWW8ImplReader::Read_ApoPPC
}, // pap.pcHorz, pap.pcVert;complex;byte;
5906 {NS_sprm::LN_PBrcTop10
, nullptr}, // pap.brcTop;BRC10;word;
5907 {NS_sprm::LN_PBrcLeft10
, nullptr}, // pap.brcLeft;BRC10;word;
5908 {NS_sprm::LN_PBrcBottom10
, nullptr}, // pap.brcBottom;BRC10;word;
5909 {NS_sprm::LN_PBrcRight10
, nullptr}, // pap.brcRight;BRC10;word;
5910 {NS_sprm::LN_PBrcBetween10
, nullptr}, // pap.brcBetween;BRC10;word;
5911 {NS_sprm::LN_PBrcBar10
, nullptr}, // pap.brcBar;BRC10;word;
5912 {NS_sprm::LN_PDxaFromText10
, nullptr}, // pap.dxaFromText;dxa;word;
5913 {NS_sprm::PWr::val
, nullptr}, // pap.wr;wr;byte;
5914 {NS_sprm::PBrcTop80::val
, &SwWW8ImplReader::Read_Border
}, // pap.brcTop;BRC;long;
5915 {NS_sprm::PBrcLeft80::val
, &SwWW8ImplReader::Read_Border
}, // pap.brcLeft;BRC;long;
5916 {NS_sprm::PBrcBottom80::val
, &SwWW8ImplReader::Read_Border
}, // pap.brcBottom;BRC;long;
5917 {NS_sprm::PBrcRight80::val
, &SwWW8ImplReader::Read_Border
}, // pap.brcRight;BRC;long;
5918 {NS_sprm::PBrcBetween80::val
, &SwWW8ImplReader::Read_Border
}, // pap.brcBetween;BRC;long;
5919 {NS_sprm::PBrcBar80::val
, nullptr}, // pap.brcBar;BRC;long;
5920 {NS_sprm::PFNoAutoHyph::val
, &SwWW8ImplReader::Read_Hyphenation
}, // pap.fNoAutoHyph;0 or 1;byte;
5921 {NS_sprm::PWHeightAbs::val
, nullptr}, // pap.wHeightAbs;w;word;
5922 {NS_sprm::PDcs::val
, nullptr}, // pap.dcs;DCS;short;
5923 {NS_sprm::PShd80::val
, &SwWW8ImplReader::Read_Shade
}, // pap.shd;SHD;word;
5924 {NS_sprm::PDyaFromText::val
, nullptr}, // pap.dyaFromText;dya;word;
5925 {NS_sprm::PDxaFromText::val
, nullptr}, // pap.dxaFromText;dxa;word;
5926 {NS_sprm::PFLocked::val
, nullptr}, // pap.fLocked;0 or 1;byte;
5927 {NS_sprm::PFWidowControl::val
, &SwWW8ImplReader::Read_WidowControl
}, // pap.fWidowControl;0 or 1;byte
5928 {NS_sprm::LN_PRuler
, nullptr}, // variable length;
5929 {NS_sprm::PFKinsoku::val
, &SwWW8ImplReader::Read_BoolItem
}, // pap.fKinsoku;0 or 1;byte;
5930 {NS_sprm::PFWordWrap::val
, nullptr}, // pap.fWordWrap;0 or 1;byte;
5931 {NS_sprm::PFOverflowPunct::val
, &SwWW8ImplReader::Read_BoolItem
}, // pap.fOverflowPunct; 0 or 1;byte;
5932 {NS_sprm::PFTopLinePunct::val
, nullptr}, // pap.fTopLinePunct;0 or 1;byte
5933 {NS_sprm::PFAutoSpaceDE::val
, &SwWW8ImplReader::Read_BoolItem
}, // pap.fAutoSpaceDE;0 or 1;byte;
5934 {NS_sprm::PFAutoSpaceDN::val
, nullptr}, // pap.fAutoSpaceDN;0 or 1;byte;
5935 {NS_sprm::PWAlignFont::val
, &SwWW8ImplReader::Read_AlignFont
}, // pap.wAlignFont;iFa;word;
5936 {NS_sprm::PFrameTextFlow::val
, nullptr}, // pap.fVertical pap.fBackward
5937 // pap.fRotateFont;complex; word
5938 {NS_sprm::LN_PISnapBaseLine
, nullptr}, // obsolete, not applicable in
5939 // Word97 and later versions;;byte;
5940 {NS_sprm::LN_PAnld
, &SwWW8ImplReader::Read_ANLevelDesc
}, // pap.anld;;variable length;
5941 {NS_sprm::LN_PPropRMark
, nullptr}, // pap.fPropRMark;complex;
5943 {NS_sprm::POutLvl::val
, &SwWW8ImplReader::Read_POutLvl
}, // pap.lvl;has no effect if pap.istd
5944 // is < 1 or is > 9;byte;
5945 {NS_sprm::PFBiDi::val
, &SwWW8ImplReader::Read_ParaBiDi
}, // ;;byte;
5946 {NS_sprm::PFNumRMIns::val
, nullptr}, // pap.fNumRMIns;1 or 0;bit;
5947 {NS_sprm::LN_PCrLf
, nullptr}, // ;;byte;
5948 {NS_sprm::PNumRM::val
, nullptr}, // pap.numrm;;variable length;
5949 {NS_sprm::LN_PHugePapx
, nullptr}, // ;fc in the data stream to locate
5950 // the huge grpprl;long;
5951 {NS_sprm::PHugePapx::val
, nullptr}, // ;fc in the data stream to locate
5952 // the huge grpprl;long;
5953 {NS_sprm::PFUsePgsuSettings::val
, &SwWW8ImplReader::Read_UsePgsuSettings
}, // pap.fUsePgsuSettings;1 or 0;byte;
5954 {NS_sprm::PFAdjustRight::val
, nullptr}, // pap.fAdjustRight;1 or 0;byte;
5955 {NS_sprm::CFRMarkDel::val
, &SwWW8ImplReader::Read_CFRMarkDel
}, // chp.fRMarkDel;1 or 0;bit;
5956 {NS_sprm::CFRMarkIns::val
, &SwWW8ImplReader::Read_CFRMark
}, // chp.fRMark;1 or 0;bit;
5957 {NS_sprm::CFFldVanish::val
, &SwWW8ImplReader::Read_FieldVanish
}, // chp.fFieldVanish;1 or 0;bit;
5958 {NS_sprm::CPicLocation::val
, &SwWW8ImplReader::Read_PicLoc
}, // chp.fcPic and chp.fSpec;variable
5959 // length, length recorded is always 4;
5960 {NS_sprm::CIbstRMark::val
, nullptr}, // chp.ibstRMark;index into
5962 {NS_sprm::CDttmRMark::val
, nullptr}, // chp.dttmRMark;DTTM;long;
5963 {NS_sprm::CFData::val
, nullptr}, // chp.fData;1 or 0;bit;
5964 {NS_sprm::CIdslRMark::val
, nullptr}, // chp.idslRMReason;an index to
5965 // a table of strings defined in
5966 // Word 6.0 executables;short;
5967 {NS_sprm::LN_CChs
, &SwWW8ImplReader::Read_CharSet
}, // chp.fChsDiff and chp.chse;3 bytes;
5968 {NS_sprm::CSymbol::val
, &SwWW8ImplReader::Read_Symbol
}, // chp.fSpec, chp.xchSym and chp.ftcSym;
5969 // variable length, length
5970 // recorded is always 4;
5971 {NS_sprm::CFOle2::val
, &SwWW8ImplReader::Read_Obj
}, // chp.fOle2;1 or 0;bit;
5972 //NS_sprm::LN_CIdCharType, // obsolete: not applicable in Word97
5973 // and later versions
5974 {NS_sprm::CHighlight::val
, &SwWW8ImplReader::Read_CharHighlight
}, // chp.fHighlight, chp.icoHighlight;ico
5975 // (fHighlight is set to 1 iff
5976 // ico is not 0);byte;
5977 {NS_sprm::LN_CObjLocation
, &SwWW8ImplReader::Read_PicLoc
}, // chp.fcObj;FC;long;
5978 //NS_sprm::LN_CFFtcAsciSymb, ? ? ?,
5979 {NS_sprm::CIstd::val
, &SwWW8ImplReader::Read_CColl
}, // chp.istd;istd,short;
5980 {NS_sprm::CIstdPermute::val
, nullptr}, // chp.istd;permutation vector;
5982 {NS_sprm::LN_CDefault
, nullptr}, // whole CHP;none;variable length;
5983 {NS_sprm::CPlain::val
, nullptr}, // whole CHP;none;length: 0;
5984 {NS_sprm::CKcd::val
, &SwWW8ImplReader::Read_Emphasis
},
5985 {NS_sprm::CFBold::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fBold;0,1, 128, or 129;byte;
5986 {NS_sprm::CFItalic::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fItalic;0,1, 128, or 129; byte;
5987 {NS_sprm::CFStrike::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fStrike;0,1, 128, or 129; byte;
5988 {NS_sprm::CFOutline::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fOutline;0,1, 128, or 129; byte;
5989 {NS_sprm::CFShadow::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fShadow;0,1, 128, or 129; byte;
5990 {NS_sprm::CFSmallCaps::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fSmallCaps;0,1, 128, or 129;byte;
5991 {NS_sprm::CFCaps::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fCaps;0,1, 128, or 129; byte;
5992 {NS_sprm::CFVanish::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fVanish;0,1, 128, or 129; byte;
5993 //NS_sprm::LN_CFtcDefault, 0, // ftc, only used internally, never
5994 // stored in file;word;
5995 {NS_sprm::CKul::val
, &SwWW8ImplReader::Read_Underline
}, // chp.kul;kul;byte;
5996 {NS_sprm::LN_CSizePos
, nullptr}, // chp.hps, chp.hpsPos;3 bytes;
5997 {NS_sprm::CDxaSpace::val
, &SwWW8ImplReader::Read_Kern
}, // chp.dxaSpace;dxa;word;
5998 {NS_sprm::LN_CLid
, &SwWW8ImplReader::Read_Language
}, // ;only used internally, never stored;
6000 {NS_sprm::CIco::val
, &SwWW8ImplReader::Read_TextColor
}, // chp.ico;ico;byte;
6001 {NS_sprm::CHps::val
, &SwWW8ImplReader::Read_FontSize
}, // chp.hps;hps;byte;
6002 {NS_sprm::LN_CHpsInc
, nullptr}, // chp.hps;byte;
6003 {NS_sprm::CHpsPos::val
, &SwWW8ImplReader::Read_SubSuperProp
}, // chp.hpsPos;hps;byte;
6004 {NS_sprm::LN_CHpsPosAdj
, nullptr}, // chp.hpsPos;hps;byte;
6005 {NS_sprm::CMajority::val
, &SwWW8ImplReader::Read_Majority
}, // chp.fBold, chp.fItalic, chp.fStrike,
6006 // chp.fSmallCaps, chp.fVanish, chp.fCaps,
6007 // chp.hps, chp.hpsPos, chp.dxaSpace,
6008 // chp.kul, chp.ico, chp.rgftc, chp.rglid;
6009 // complex;variable length, length byte
6010 // plus size of following grpprl;
6011 {NS_sprm::CIss::val
, &SwWW8ImplReader::Read_SubSuper
}, // chp.iss;iss;byte;
6012 {NS_sprm::LN_CHpsNew50
, nullptr}, // chp.hps;hps;variable width, length
6013 // always recorded as 2;
6014 {NS_sprm::LN_CHpsInc1
, nullptr}, // chp.hps;complex; variable width,
6015 // length always recorded as 2;
6016 {NS_sprm::CHpsKern::val
, &SwWW8ImplReader::Read_FontKern
}, // chp.hpsKern;hps;short;
6017 {NS_sprm::LN_CMajority50
, &SwWW8ImplReader::Read_Majority
}, // chp.fBold, chp.fItalic, chp.fStrike,
6018 // chp.fSmallCaps, chp.fVanish, chp.fCaps,
6019 // chp.ftc, chp.hps, chp.hpsPos, chp.kul,
6020 // chp.dxaSpace, chp.ico;complex;
6022 {NS_sprm::LN_CHpsMul
, nullptr}, // chp.hps;percentage to grow hps;short;
6023 {NS_sprm::CHresi::val
, nullptr}, // ???? "sprmCYsri" chp.ysri;ysri;short;
6024 {NS_sprm::CRgFtc0::val
, &SwWW8ImplReader::Read_FontCode
}, // chp.rgftc[0];ftc for ASCII text;short;
6025 {NS_sprm::CRgFtc1::val
, &SwWW8ImplReader::Read_FontCode
}, // chp.rgftc[1];ftc for Far East text;
6027 {NS_sprm::CRgFtc2::val
, &SwWW8ImplReader::Read_FontCode
}, // chp.rgftc[2];ftc for non-Far East text;
6029 {NS_sprm::CCharScale::val
, &SwWW8ImplReader::Read_ScaleWidth
},
6030 {NS_sprm::CFDStrike::val
, &SwWW8ImplReader::Read_BoldUsw
}, // chp.fDStrike;;byte;
6031 {NS_sprm::CFImprint::val
, &SwWW8ImplReader::Read_Relief
}, // chp.fImprint;1 or 0;bit;
6032 {NS_sprm::CFSpec::val
, &SwWW8ImplReader::Read_Special
}, // chp.fSpec;1 or 0;bit;
6033 {NS_sprm::CFObj::val
, &SwWW8ImplReader::Read_Obj
}, // chp.fObj;1 or 0;bit;
6034 {NS_sprm::CPropRMark90::val
, &SwWW8ImplReader::Read_CPropRMark
}, // chp.fPropRMark, chp.ibstPropRMark,
6035 // chp.dttmPropRMark;Complex;variable
6036 // length always recorded as 7 bytes;
6037 {NS_sprm::CFEmboss::val
, &SwWW8ImplReader::Read_Relief
}, // chp.fEmboss;1 or 0;bit;
6038 {NS_sprm::CSfxText::val
, &SwWW8ImplReader::Read_TextAnim
}, // chp.sfxtText;text animation;byte;
6039 {NS_sprm::CFBiDi::val
, &SwWW8ImplReader::Read_Bidi
},
6040 {NS_sprm::LN_CFDiacColor
, nullptr},
6041 {NS_sprm::CFBoldBi::val
, &SwWW8ImplReader::Read_BoldBiDiUsw
},
6042 {NS_sprm::CFItalicBi::val
, &SwWW8ImplReader::Read_BoldBiDiUsw
},
6043 {NS_sprm::CFtcBi::val
, &SwWW8ImplReader::Read_FontCode
},
6044 {NS_sprm::CLidBi::val
, &SwWW8ImplReader::Read_Language
},
6045 //NS_sprm::CIcoBi::val, ? ? ?,
6046 {NS_sprm::CHpsBi::val
, &SwWW8ImplReader::Read_FontSize
},
6047 {NS_sprm::CDispFldRMark::val
, nullptr}, // chp.fDispFieldRMark,
6048 // chp.ibstDispFieldRMark,
6049 // chp.dttmDispFieldRMark;
6050 // Complex;variable length
6051 // always recorded as 39 bytes;
6052 {NS_sprm::CIbstRMarkDel::val
, nullptr}, // chp.ibstRMarkDel;index into
6054 {NS_sprm::CDttmRMarkDel::val
, nullptr}, // chp.dttmRMarkDel;DTTM;long;
6055 {NS_sprm::CBrc80::val
, &SwWW8ImplReader::Read_CharBorder
}, // chp.brc;BRC;long;
6056 {NS_sprm::CBrc::val
, &SwWW8ImplReader::Read_CharBorder
}, // chp.brc;BRC;long;
6057 {NS_sprm::CShd80::val
, &SwWW8ImplReader::Read_CharShadow
}, // chp.shd;SHD;short;
6058 {NS_sprm::CIdslRMarkDel::val
, nullptr}, // chp.idslRMReasonDel;an index to
6059 // a table of strings defined in
6060 // Word 6.0 executables;short;
6061 {NS_sprm::CFUsePgsuSettings::val
, nullptr}, // chp.fUsePgsuSettings; 1 or 0;bit;
6062 {NS_sprm::LN_CCpg
, nullptr}, // ;;word;
6063 {NS_sprm::CRgLid0_80::val
, &SwWW8ImplReader::Read_Language
}, // chp.rglid[0];
6064 // LID: for non-Far East text;word;
6065 {NS_sprm::CRgLid1_80::val
, &SwWW8ImplReader::Read_Language
}, // chp.rglid[1];
6066 // LID: for Far East text;word;
6067 {NS_sprm::CIdctHint::val
, &SwWW8ImplReader::Read_IdctHint
}, // chp.idctHint;IDCT: byte;
6068 {NS_sprm::LN_PicBrcl
, nullptr}, // pic.brcl;brcl (see PIC structure
6069 // definition);byte;
6070 {NS_sprm::LN_PicScale
, nullptr}, // pic.mx, pic.my, pic.dxaCropleft,
6071 // pic.dyaCropTop pic.dxaCropRight,
6072 // pic.dyaCropBottom;Complex;
6073 // length byte plus 12 bytes;
6074 {NS_sprm::PicBrcTop80::val
, nullptr}, // pic.brcTop;BRC;long;
6075 {NS_sprm::PicBrcLeft80::val
, nullptr}, // pic.brcLeft;BRC;long;
6076 {NS_sprm::PicBrcBottom80::val
, nullptr}, // pic.brcBottom;BRC;long;
6077 {NS_sprm::PicBrcRight80::val
, nullptr}, // pic.brcRight;BRC;long;
6078 {NS_sprm::ScnsPgn::val
, nullptr}, // sep.cnsPgn;cns;byte;
6079 {NS_sprm::SiHeadingPgn::val
, nullptr}, // sep.iHeadingPgn;heading number level;
6081 {NS_sprm::LN_SOlstAnm
, &SwWW8ImplReader::Read_OLST
}, // sep.olstAnm;OLST;variable length;
6082 {NS_sprm::SDxaColWidth::val
, nullptr}, // sep.rgdxaColWidthSpacing;complex;
6084 {NS_sprm::SDxaColSpacing::val
, nullptr}, // sep.rgdxaColWidthSpacing;complex;
6086 {NS_sprm::SFEvenlySpaced::val
, nullptr}, // sep.fEvenlySpaced; 1 or 0;byte;
6087 {NS_sprm::SFProtected::val
, nullptr}, // sep.fUnlocked;1 or 0;byte;
6088 {NS_sprm::SDmBinFirst::val
, nullptr}, // sep.dmBinFirst;;word;
6089 {NS_sprm::SDmBinOther::val
, nullptr}, // sep.dmBinOther;;word;
6090 {NS_sprm::SBkc::val
, nullptr}, // sep.bkc;bkc;byte;
6091 {NS_sprm::SFTitlePage::val
, nullptr}, // sep.fTitlePage;0 or 1;byte;
6092 {NS_sprm::SCcolumns::val
, nullptr}, // sep.ccolM1;# of cols - 1;word;
6093 {NS_sprm::SDxaColumns::val
, nullptr}, // sep.dxaColumns;dxa;word;
6094 {NS_sprm::LN_SFAutoPgn
, nullptr}, // sep.fAutoPgn;obsolete;byte;
6095 {NS_sprm::SNfcPgn::val
, nullptr}, // sep.nfcPgn;nfc;byte;
6096 {NS_sprm::LN_SDyaPgn
, nullptr}, // sep.dyaPgn;dya;short;
6097 {NS_sprm::LN_SDxaPgn
, nullptr}, // sep.dxaPgn;dya;short;
6098 {NS_sprm::SFPgnRestart::val
, nullptr}, // sep.fPgnRestart;0 or 1;byte;
6099 {NS_sprm::SFEndnote::val
, nullptr}, // sep.fEndnote;0 or 1;byte;
6100 {NS_sprm::SLnc::val
, nullptr}, // sep.lnc;lnc;byte;
6101 {NS_sprm::LN_SGprfIhdt
, nullptr}, // sep.grpfIhdt;grpfihdt;byte;
6102 {NS_sprm::SNLnnMod::val
, nullptr}, // sep.nLnnMod;non-neg int.;word;
6103 {NS_sprm::SDxaLnn::val
, nullptr}, // sep.dxaLnn;dxa;word;
6104 {NS_sprm::SDyaHdrTop::val
, nullptr}, // sep.dyaHdrTop;dya;word;
6105 {NS_sprm::SDyaHdrBottom::val
, nullptr}, // sep.dyaHdrBottom;dya;word;
6106 {NS_sprm::SLBetween::val
, nullptr}, // sep.fLBetween;0 or 1;byte;
6107 {NS_sprm::SVjc::val
, &SwWW8ImplReader::Read_TextVerticalAdjustment
}, // sep.vjc;vjc;byte;
6108 {NS_sprm::SLnnMin::val
, nullptr}, // sep.lnnMin;lnn;word;
6109 {NS_sprm::SPgnStart97::val
, nullptr}, // sep.pgnStart;pgn;word;
6110 {NS_sprm::SBOrientation::val
, nullptr}, // sep.dmOrientPage;dm;byte;
6111 //NS_sprm::LN_SBCustomize, ? ? ?,
6112 {NS_sprm::SXaPage::val
, nullptr}, // sep.xaPage;xa;word;
6113 {NS_sprm::SYaPage::val
, nullptr}, // sep.yaPage;ya;word;
6114 {0x2205, nullptr}, // ???? "sprmSDxaLeft" sep.dxaLeft;
6116 {NS_sprm::SDxaLeft::val
, nullptr}, // sep.dxaLeft;dxa;word;
6117 {NS_sprm::SDxaRight::val
, nullptr}, // sep.dxaRight;dxa;word;
6118 {NS_sprm::SDyaTop::val
, nullptr}, // sep.dyaTop;dya;word;
6119 {NS_sprm::SDyaBottom::val
, nullptr}, // sep.dyaBottom;dya;word;
6120 {NS_sprm::SDzaGutter::val
, nullptr}, // sep.dzaGutter;dza;word;
6121 {NS_sprm::SDmPaperReq::val
, nullptr}, // sep.dmPaperReq;dm;word;
6122 {NS_sprm::LN_SPropRMark
, nullptr}, // sep.fPropRMark, sep.ibstPropRMark,
6123 // sep.dttmPropRMark;complex; variable
6124 // length always recorded as 7 bytes;
6125 //NS_sprm::SFBiDi::val, ? ? ?,
6126 //NS_sprm::LN_SFFacingCol, ? ? ?,
6127 {NS_sprm::SFRTLGutter::val
, nullptr}, // set to 1 if gutter is on the right.
6128 {NS_sprm::SBrcTop80::val
, nullptr}, // sep.brcTop;BRC;long;
6129 {NS_sprm::SBrcLeft80::val
, nullptr}, // sep.brcLeft;BRC;long;
6130 {NS_sprm::SBrcBottom80::val
, nullptr}, // sep.brcBottom;BRC;long;
6131 {NS_sprm::SBrcRight80::val
, nullptr}, // sep.brcRight;BRC;long;
6132 {NS_sprm::SPgbProp::val
, nullptr}, // sep.pgbProp;word;
6133 {NS_sprm::SDxtCharSpace::val
, nullptr}, // sep.dxtCharSpace;dxt;long;
6134 {NS_sprm::SDyaLinePitch::val
, nullptr}, // sep.dyaLinePitch;dya;
6135 // WRONG:long; RIGHT:short; !
6136 //NS_sprm::SClm::val, ? ? ?,
6137 {NS_sprm::STextFlow::val
, nullptr}, // sep.wTextFlow;complex;short
6138 {NS_sprm::TJc90::val
, nullptr}, // tap.jc;jc;word
6139 // (low order byte is significant);
6140 {NS_sprm::TDxaLeft::val
, nullptr}, // tap.rgdxaCenter;dxa;word;
6141 {NS_sprm::TDxaGapHalf::val
, nullptr}, // tap.dxaGapHalf,
6142 // tap.rgdxaCenter;dxa;word;
6143 {NS_sprm::TFCantSplit90::val
, nullptr}, // tap.fCantSplit90;1 or 0;byte;
6144 {NS_sprm::TTableHeader::val
, nullptr}, // tap.fTableHeader;1 or 0;byte;
6145 {NS_sprm::TFCantSplit::val
, nullptr}, // tap.fCantSplit;1 or 0;byte;
6146 {NS_sprm::TTableBorders80::val
, nullptr}, // tap.rgbrcTable;complex;24 bytes;
6147 {NS_sprm::LN_TDefTable10
, nullptr}, // tap.rgdxaCenter, tap.rgtc;complex;
6149 {NS_sprm::TDyaRowHeight::val
, nullptr}, // tap.dyaRowHeight;dya;word;
6150 {NS_sprm::TDefTable::val
, nullptr}, // tap.rgtc;complex
6151 {NS_sprm::TDefTableShd80::val
, nullptr}, // tap.rgshd;complex
6152 {NS_sprm::TTlp::val
, nullptr}, // tap.tlp;TLP;4 bytes;
6153 //NS_sprm::TFBiDi::val, ? ? ?,
6154 //NS_sprm::LN_THTMLProps, ? ? ?,
6155 {NS_sprm::TSetBrc80::val
, nullptr}, // tap.rgtc[].rgbrc;complex;5 bytes;
6156 {NS_sprm::TInsert::val
, nullptr}, // tap.rgdxaCenter, tap.rgtc;complex;
6158 {NS_sprm::TDelete::val
, nullptr}, // tap.rgdxaCenter, tap.rgtc;complex;
6160 {NS_sprm::TDxaCol::val
, nullptr}, // tap.rgdxaCenter;complex;4 bytes;
6161 {NS_sprm::TMerge::val
, nullptr}, // tap.fFirstMerged, tap.fMerged;
6163 {NS_sprm::TSplit::val
, nullptr}, // tap.fFirstMerged, tap.fMerged;
6165 {NS_sprm::LN_TSetBrc10
, nullptr}, // tap.rgtc[].rgbrc;complex;5 bytes;
6166 {NS_sprm::LN_TSetShd80
, nullptr}, // tap.rgshd;complex;4 bytes;
6167 {NS_sprm::LN_TSetShdOdd80
, nullptr}, // tap.rgshd;complex;4 bytes;
6168 {NS_sprm::TTextFlow::val
, nullptr}, // tap.rgtc[].fVertical
6169 // tap.rgtc[].fBackward
6170 // tap.rgtc[].fRotateFont
6171 // 0 or 10 or 10 or 1;word;
6172 //NS_sprm::LN_TDiagLine, ? ? ? ,
6173 {NS_sprm::TVertMerge::val
, nullptr}, // tap.rgtc[].vertMerge;complex;variable
6174 // length always recorded as 2 bytes;
6175 {NS_sprm::TVertAlign::val
, nullptr}, // tap.rgtc[].vertAlign;complex;variable
6176 // length always recorded as 3 bytes;
6177 {NS_sprm::CFELayout::val
, &SwWW8ImplReader::Read_DoubleLine_Rotate
},
6178 {NS_sprm::PItap::val
, nullptr},
6179 {NS_sprm::TTableWidth::val
, nullptr}, // recorded as 3 bytes;
6180 {NS_sprm::TDefTableShd::val
, nullptr},
6181 {NS_sprm::TTableBorders::val
, nullptr},
6182 {NS_sprm::TBrcTopCv::val
, nullptr},
6183 {NS_sprm::TBrcLeftCv::val
, nullptr},
6184 {NS_sprm::TBrcBottomCv::val
, nullptr},
6185 {NS_sprm::TBrcRightCv::val
, nullptr},
6186 {NS_sprm::TCellPaddingDefault::val
, nullptr},
6187 {NS_sprm::TCellPadding::val
, nullptr},
6188 {0xD238, nullptr}, // undocumented sep
6189 {NS_sprm::PBrcTop::val
, &SwWW8ImplReader::Read_Border
},
6190 {NS_sprm::PBrcLeft::val
, &SwWW8ImplReader::Read_Border
},
6191 {NS_sprm::PBrcBottom::val
, &SwWW8ImplReader::Read_Border
},
6192 {NS_sprm::PBrcRight::val
, &SwWW8ImplReader::Read_Border
},
6193 {NS_sprm::PBrcBetween::val
, &SwWW8ImplReader::Read_Border
},
6194 {NS_sprm::TWidthIndent::val
, nullptr},
6195 {NS_sprm::CRgLid0::val
, &SwWW8ImplReader::Read_Language
}, // chp.rglid[0];
6196 // LID: for non-Far East text;
6197 {NS_sprm::CRgLid1::val
, nullptr}, // chp.rglid[1];
6198 // LID: for Far East text
6199 {0x6463, nullptr}, // undocumented
6200 {NS_sprm::PJc::val
, &SwWW8ImplReader::Read_RTLJustify
},
6201 {NS_sprm::PDxaLeft::val
, &SwWW8ImplReader::Read_LR
},
6202 {NS_sprm::PDxaLeft1::val
, &SwWW8ImplReader::Read_LR
},
6203 {NS_sprm::PDxaRight::val
, &SwWW8ImplReader::Read_LR
},
6204 {NS_sprm::TFAutofit::val
, nullptr},
6205 {NS_sprm::TPc::val
, nullptr},
6206 {NS_sprm::TDxaAbs::val
, nullptr},
6207 {NS_sprm::TDyaAbs::val
, nullptr},
6208 {NS_sprm::TDxaFromText::val
, nullptr},
6209 {NS_sprm::SRsid::val
, nullptr},
6210 {NS_sprm::SFpc::val
, nullptr},
6211 {NS_sprm::PFInnerTableCell::val
, &SwWW8ImplReader::Read_TabCellEnd
},
6212 {NS_sprm::PFInnerTtp::val
, &SwWW8ImplReader::Read_TabRowEnd
},
6213 {NS_sprm::CRsidProp::val
, nullptr},
6214 {NS_sprm::CRsidText::val
, nullptr},
6215 {NS_sprm::CCv::val
, &SwWW8ImplReader::Read_TextForeColor
},
6216 {NS_sprm::CCvUl::val
, &SwWW8ImplReader::Read_UnderlineColor
},
6217 {NS_sprm::PShd::val
, &SwWW8ImplReader::Read_ParaBackColor
},
6218 {NS_sprm::PRsid::val
, nullptr},
6219 {NS_sprm::TWidthBefore::val
, nullptr},
6220 {NS_sprm::TSetShdTable::val
, nullptr},
6221 {NS_sprm::TDefTableShdRaw::val
, nullptr},
6222 {NS_sprm::CShd::val
, &SwWW8ImplReader::Read_TextBackColor
},
6223 {NS_sprm::SRncFtn::val
, nullptr},
6224 {NS_sprm::PFDyaBeforeAuto::val
, &SwWW8ImplReader::Read_ParaAutoBefore
},
6225 {NS_sprm::PFDyaAfterAuto::val
, &SwWW8ImplReader::Read_ParaAutoAfter
},
6226 {NS_sprm::PFContextualSpacing::val
, &SwWW8ImplReader::Read_ParaContextualSpacing
},
6227 {NS_sprm::CLbcCRJ::val
, &SwWW8ImplReader::Read_LineBreakClear
},
6230 static wwSprmDispatcher
aSprmSrch(aSprms
, SAL_N_ELEMENTS(aSprms
));
6234 // helper routines : find SPRM
6236 const SprmReadInfo
& SwWW8ImplReader::GetSprmReadInfo(sal_uInt16 nId
) const
6238 ww::WordVersion eVersion
= m_xWwFib
->GetFIBVersion();
6239 const wwSprmDispatcher
*pDispatcher
;
6240 if (eVersion
<= ww::eWW2
)
6241 pDispatcher
= GetWW2SprmDispatcher();
6242 else if (eVersion
< ww::eWW8
)
6243 pDispatcher
= GetWW6SprmDispatcher();
6245 pDispatcher
= GetWW8SprmDispatcher();
6247 SprmReadInfo aSrch
= {0, nullptr};
6249 const SprmReadInfo
* pFound
= pDispatcher
->search(aSrch
);
6254 pFound
= pDispatcher
->search(aSrch
);
6260 // helper routines : SPRMs
6262 void SwWW8ImplReader::EndSprm( sal_uInt16 nId
)
6264 if( ( nId
> 255 ) && ( nId
< 0x0800 ) ) return;
6266 const SprmReadInfo
& rSprm
= GetSprmReadInfo( nId
);
6269 (this->*rSprm
.pReadFnc
)( nId
, nullptr, -1 );
6272 short SwWW8ImplReader::ImportSprm(const sal_uInt8
* pPos
, sal_Int32 nMemLen
, sal_uInt16 nId
)
6275 nId
= m_oSprmParser
->GetSprmId(pPos
);
6277 OSL_ENSURE( nId
!= 0xff, "Sprm FF !!!!" );
6279 const SprmReadInfo
& rSprm
= GetSprmReadInfo(nId
);
6281 sal_Int32 nFixedLen
= m_oSprmParser
->DistanceToData(nId
);
6282 sal_Int32 nL
= m_oSprmParser
->GetSprmSize(nId
, pPos
, nMemLen
);
6285 (this->*rSprm
.pReadFnc
)(nId
, pPos
+ nFixedLen
, nL
- nFixedLen
);
6290 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */