LibreOffice Module lotuswordpro (master) 1
lwppara1.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*************************************************************************
3 *
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
6 *
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
9 *
10 * Sun Microsystems Inc., October, 2000
11 *
12 * GNU Lesser General Public License Version 2.1
13 * =============================================
14 * Copyright 2000 by Sun Microsystems, Inc.
15 * 901 San Antonio Road, Palo Alto, CA 94303, USA
16 *
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License version 2.1, as published by the Free Software Foundation.
20 *
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
25 *
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
30 *
31 *
32 * Sun Industry Standards Source License Version 1.1
33 * =================================================
34 * The contents of this file are subject to the Sun Industry Standards
35 * Source License Version 1.1 (the "License"); You may not use this file
36 * except in compliance with the License. You may obtain a copy of the
37 * License at http://www.openoffice.org/license.html.
38 *
39 * Software provided under this License is provided on an "AS IS" basis,
40 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 * See the License for the specific provisions governing your rights and
44 * obligations concerning the Software.
45 *
46 * The Initial Developer of the Original Code is: IBM Corporation
47 *
48 * Copyright: 2008 by IBM Corporation
49 *
50 * All Rights Reserved.
51 *
52 * Contributor(s): _______________________________________
53 *
54 *
55 ************************************************************************/
56/*************************************************************************
57 * @file
58 * For LWP filter architecture prototype
59 ************************************************************************/
60
61#include <memory>
62
63#include <boost/cast.hpp>
64
65#include "lwppara.hxx"
66#include <lwpglobalmgr.hxx>
67#include "lwpparaproperty.hxx"
68#include "lwpparastyle.hxx"
70#include "lwpfribheader.hxx"
71#include "lwplayout.hxx"
72
73#include "lwpstory.hxx"
74#include "lwpsilverbullet.hxx"
75#include "lwpframelayout.hxx"
76
78
79// boost::polymorphic_downcast checks and reports (using assert), if the
80// cast is incorrect (in debug builds).
81using boost::polymorphic_downcast;
82
86OUString const & LwpPara::GetContentText(bool bAllText)
87{
88// rFont = m_FontID;
89 if (bAllText)
90 {
91 m_Fribs.SetPara(this);
93 return m_AllText;
94 }
95 else
96 return m_Content;
97}
98
102void LwpPara::SetAllText(std::u16string_view sText)
103{
104 m_AllText+=sText;
105}
106
110void LwpPara::SetFirstFrib(const OUString& Content,sal_uInt32 FontID)
111{
112 m_FontID= FontID;
114}
119{
121 return pXFStyleManager->FindParaStyle(m_StyleName);
122}
127{
130}
135{
136 LwpPara* pPara;
137 sal_uInt16 otherlevel;
138 sal_uInt16 level = GetLevel();
139
140 if (level != 1)
141 {
142 pPara = dynamic_cast<LwpPara*>(GetPrevious().obj().get());
144 while (pPara)
145 {
146 bool bAlreadySeen = !aSeen.insert(pPara).second;
147 if (bAlreadySeen)
148 throw std::runtime_error("loop in conversion");
149 otherlevel = pPara->GetLevel();
150 if ((otherlevel < level) || (otherlevel && (level == 0)))
151 return pPara;
152 pPara = dynamic_cast<LwpPara*>(pPara->GetPrevious().obj().get());
153 }
154 }
155 return nullptr;
156}
157
164void LwpPara::GetParaNumber(sal_uInt16 nPosition, ParaNumbering* pParaNumbering)
165{
166 if (nPosition > 9)
167 {
168 return;
169 }
170 sal_uInt16 nCurrentPos = 0;
171
172 LwpFrib* pPreFrib = nullptr;
173 LwpFrib* pFrib = m_Fribs.GetFribs();
174 if (!pFrib)
175 {
176 return;
177 }
178
179 while (pFrib)
180 {
181 sal_uInt8 nFribType = pFrib->GetType();
182 if (nFribType == FRIB_TAG_PARANUMBER)
183 {
184 nCurrentPos++;
185 ModifierInfo* pModInfo = pFrib->GetModifiers();
186 if (pModInfo)
187 {
188 sal_uInt16 nHideLevels = pModInfo->aTxtAttrOverride.GetHideLevels();
189 if (nCurrentPos == nPosition)
190 {
191 //get prefix text frib
192 if (pPreFrib)
193 {
194 if ((pPreFrib->GetType() == FRIB_TAG_TEXT) &&
195 (pPreFrib->GetModifiers() && pPreFrib->GetModifiers()->aTxtAttrOverride.GetHideLevels() == nHideLevels))
196 {
197 pParaNumbering->pPrefix = static_cast<LwpFribText*>(pPreFrib);
198 }
199 }
200
201 //get para numbering
202 pParaNumbering->pParaNumber = static_cast<LwpFribParaNumber*>(pFrib);
203 pParaNumbering->nNumLevel = nHideLevels;
204
205 //get suffix text frib
206 pFrib = pFrib->GetNext();
207 if ( pFrib )
208 {
209 if( pFrib->GetType() == FRIB_TAG_TEXT )
210 {
211 if (
212 (pFrib->GetNext() && pFrib->GetNext()->GetType() == FRIB_TAG_TEXT) ||
213 (pFrib->GetModifiers() && pFrib->GetModifiers()->aTxtAttrOverride.GetHideLevels() == nHideLevels)
214 )
215 {
216 pParaNumbering->pSuffix = static_cast<LwpFribText*>(pFrib);
217 }
218 }
219 }
220
221 break;
222 }
223 }
224 else
225 {
226 if (nCurrentPos == nPosition)
227 {
228 //get prefix text frib
229 if (pPreFrib)
230 {
231 if (pPreFrib->GetType() == FRIB_TAG_TEXT)
232 {
233 pParaNumbering->pPrefix = static_cast<LwpFribText*>(pPreFrib);
234 }
235 }
236
237 //get para numbering
238 pParaNumbering->pParaNumber = static_cast<LwpFribParaNumber*>(pFrib);
239
240 //get suffix text frib
241 pFrib = pFrib->GetNext();
242 if ( pFrib )
243 {
244 if (pFrib->GetType() == FRIB_TAG_TEXT)
245 {
246 pParaNumbering->pSuffix = static_cast<LwpFribText*>(pFrib);
247 }
248 }
249
250 }
251 }
252 }
253 pPreFrib = pFrib;
254 if (pFrib)
255 {
256 pFrib = pFrib->GetNext();
257 }
258 }
259}
264{
265 if (base)//the latter two parameter never be null
266 {
267 over->Override(base);
269 }
270 else
271 LwpParaStyle::ApplyAlignment(pOverStyle,over);
272}
277{
278 if (base)//the latter two parameter never be null
279 {
280 over->Override(base);
281 LwpParaStyle::ApplyIndent(this,pOverStyle,base);
282 }
283 else
284 {
285 LwpParaStyle::ApplyIndent(this,pOverStyle,over);
286 }
287}
292{
293 if (base)//the latter two parameter never be null
294 {
295 if (over)
296 over->Override(base);
297 LwpParaStyle::ApplySpacing(this,pOverStyle,base);
298 }
299 else
300 LwpParaStyle::ApplySpacing(this,pOverStyle,over);
301}
302
308{
309 return dynamic_cast<LwpParaStyle*>(m_ParaStyle.obj(VO_PARASTYLE).get());
310}
311
318{
319 // get paraborder in parastyle
320 LwpParaStyle* pParaStyle = GetParaStyle();
321 if (!pParaStyle)
322 {
323 return;
324 }
325
326 LwpOverride* pBorder = pParaStyle->GetParaBorder();
327 std::unique_ptr<LwpParaBorderOverride> pFinalBorder(
328 pBorder
329 ? polymorphic_downcast<LwpParaBorderOverride*>(pBorder->clone())
331 ;
332
333 // get local border
334 pBorder = static_cast<LwpParaBorderProperty*>(pProps)->GetLocalParaBorder();
335 if (pBorder)
336 {
337 std::unique_ptr<LwpParaBorderOverride> pLocalBorder(
338 polymorphic_downcast<LwpParaBorderOverride*>(pBorder->clone()));
339 pLocalBorder->Override(pFinalBorder.get());
340 }
341
342 LwpParaStyle::ApplyParaBorder(pOverStyle, pFinalBorder.get());
343}
350{
351 // get breaks in parastyle
352 LwpParaStyle* pParaStyle = GetParaStyle();
353 if (!pParaStyle)
354 {
355 return;
356 }
357
358 LwpOverride* pBreaks = pParaStyle->GetBreaks();
359 std::unique_ptr<LwpBreaksOverride> pFinalBreaks(
360 pBreaks
361 ? polymorphic_downcast<LwpBreaksOverride*>(pBreaks->clone())
362 : new LwpBreaksOverride)
363 ;
364
365 // get local breaks
366 pBreaks = static_cast<LwpParaBreaksProperty*>(pProps)->GetLocalParaBreaks();
367 if (pBreaks)
368 {
369 std::unique_ptr<LwpBreaksOverride> const pLocalBreaks(
370 polymorphic_downcast<LwpBreaksOverride*>(pBreaks->clone()));
371 pLocalBreaks->Override(pFinalBreaks.get());
372 }
373
374 // save the breaks
375 m_pBreaks.reset( pFinalBreaks.release() );
376
378 if (m_pBreaks->IsKeepWithNext())
379 {
381 }
382 if (m_pBreaks->IsPageBreakBefore())
383 {
384 std::unique_ptr<XFParaStyle> pStyle(new XFParaStyle());
385 pStyle->SetBreaks(enumXFBreakAftPage);
386 m_BefPageBreakName = pXFStyleManager->AddStyle(std::move(pStyle)).m_pStyle->GetStyleName();
387 }
388 if (m_pBreaks->IsPageBreakAfter())
389 {
390 std::unique_ptr<XFParaStyle> pStyle(new XFParaStyle());
391 pStyle->SetBreaks(enumXFBreakAftPage);
392 m_AftPageBreakName = pXFStyleManager->AddStyle(std::move(pStyle)).m_pStyle->GetStyleName();
393 }
394 if (m_pBreaks->IsColumnBreakBefore())
395 {
396 std::unique_ptr<XFParaStyle> pStyle(new XFParaStyle());
397 pStyle->SetBreaks(enumXFBreakAftColumn);//tmp after, should change when layout read
398 m_BefColumnBreakName = pXFStyleManager->AddStyle(std::move(pStyle)).m_pStyle->GetStyleName();
399 }
400 if (m_pBreaks->IsColumnBreakAfter())
401 {
402 std::unique_ptr<XFParaStyle> pStyle(new XFParaStyle());
403 pStyle->SetBreaks(enumXFBreakAftColumn);
404 m_AftColumnBreakName = pXFStyleManager->AddStyle(std::move(pStyle)).m_pStyle->GetStyleName();
405 }
406
407// pParaStyle->ApplyBreaks(pOverStyle, &aFinalBreaks);
408}
409
415{
416 // get bulletoverride in parastyle
417 LwpParaStyle* pParaStyle = GetParaStyle();
418 if (!pParaStyle)
419 {
420 return;
421 }
422
423 if (pProps)
424 {
426 // get local bulletoverride
427 LwpBulletOverride* pLocalBullet = static_cast<LwpParaBulletProperty*>(pProps)->GetLocalParaBullet();
428 if (!pLocalBullet)
429 {
430 return;
431 }
432
433 LwpObjectID aSilverBulletID = pLocalBullet->GetSilverBullet();
434 if (aSilverBulletID.IsNull())
435 {
436 return;
437 }
438 else
439 {
440 m_bHasBullet = true;
441
442 const LwpBulletOverride& rBullet= pParaStyle->GetBulletOverride();
443 std::unique_ptr<LwpBulletOverride> xFinalBullet(rBullet.clone());
444
445 std::unique_ptr<LwpBulletOverride> const pLocalBullet2(pLocalBullet->clone());
446 pLocalBullet2->Override(xFinalBullet.get());
447
448 aSilverBulletID = xFinalBullet->GetSilverBullet();
449 m_xBullOver = std::move(xFinalBullet);
450 if (!aSilverBulletID.IsNull())
451 {
452 m_pSilverBullet = dynamic_cast<LwpSilverBullet*>(aSilverBulletID.obj(VO_SILVERBULLET).get());
453 if (m_pSilverBullet)
455 }
456
457 m_aSilverBulletID = aSilverBulletID;
458 }
459 }
460 else
461 {
462 const LwpBulletOverride& rBullOver = pParaStyle->GetBulletOverride();
465 {
466 m_bHasBullet = true;
467
469 if (m_pSilverBullet)
471 }
472
473 m_xBullOver.reset(rBullOver.clone());
474 }
475}
481{
482 // get numbering override in parastyle
483 LwpParaStyle* pParaStyle = GetParaStyle();
484 if (!pParaStyle)
485 {
486 return;
487 }
488
489 LwpNumberingOverride* pParaNumbering = pParaStyle->GetNumberingOverride();
490 std::unique_ptr<LwpNumberingOverride> pOver(new LwpNumberingOverride);
491 //Override with the local numbering, if any
492 if (pProps)
493 {
494 LwpNumberingOverride* pPropNumbering = static_cast<LwpParaNumberingProperty const *>(pProps)->GetLocalNumbering();
495 if (pPropNumbering)
496 {
497 pOver.reset(pPropNumbering->clone());
498 }
499 }
500 else
501 {
502 if (pParaNumbering)
503 {
504 pOver.reset(pParaNumbering->clone());
505 }
506 }
507
508 if (m_nFlags & VALID_LEVEL)
509 {
510 pOver->OverrideLevel(m_nLevel);
511 }
512
513 m_xParaNumbering = std::move(pOver);
514}
515
516/**************************************************************************
517 * @descr: Get property according to the property type
518**************************************************************************/
520{
521 for (auto & i : m_vProps)
522 if(i->GetType() == nPropType)
523 {
524 return i.get();
525 }
526 return nullptr;
527}
528
529/**************************************************************************
530 * @descr: Get local tab rack
531**************************************************************************/
533{
535 if(pProp)
536 {
537 return static_cast<LwpParaTabRackProperty*>(pProp)->GetTab();
538 }
539 return nullptr;
540}
541
546bool LwpPara::operator< (LwpPara const & Other)
547{
548 return m_nOrdinal < Other.m_nOrdinal;
549}
550
555bool LwpPara::ComparePagePosition(LwpVirtualLayout const * pPreLayout, LwpVirtualLayout const * pNextLayout)
556{
557 m_Fribs.SetPara(this);
558 return m_Fribs.ComparePagePosition(pPreLayout, pNextLayout);
559}
560
565{
566 LwpStory *pStory = GetStory();
567 if (!pStory)
568 return false;
569 rtl::Reference<LwpVirtualLayout> xLayout(pStory->GetLayout(nullptr));
570 return xLayout.is() && xLayout->IsCell();
571}
572
573/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual OUString GetStyleName()=0
@descr: return the style name.
void Override(LwpAlignmentOverride *other)
virtual LwpBulletOverride * clone() const override
const LwpObjectID & GetSilverBullet() const
rtl::Reference< LwpVirtualLayout > GetLayout(LwpVirtualLayout const *pStartLayout)
Definition: lwpcontent.cxx:124
LwpObjectID & GetPrevious()
Definition: lwpdlvlist.hxx:76
sal_uInt32 GetChars() const
sal_uInt16 GetLines() const
void SetPara(LwpPara *para)
Definition: lwpfribptr.hxx:87
LwpFrib * GetFribs()
Definition: lwpfribptr.hxx:89
void GatherAllText()
Definition: lwpfribptr.cxx:380
bool ComparePagePosition(LwpVirtualLayout const *pPreLayout, LwpVirtualLayout const *pNextLayout)
@descr: If the position of pPreLayout is earlier than pNextLayout, return true, or return false,...
Definition: lwpfribptr.cxx:551
LwpFrib * GetNext()
Definition: lwpfrib.hxx:96
sal_uInt8 GetType() const
Definition: lwpfrib.hxx:98
ModifierInfo * GetModifiers()
Definition: lwpfrib.hxx:114
XFStyleManager * GetXFStyleManager()
static LwpGlobalMgr * GetInstance(LwpSvStream *pSvStream=nullptr)
void Override(LwpIndentOverride *other)
virtual LwpNumberingOverride * clone() const override
object id class
Definition: lwpobjid.hxx:79
rtl::Reference< LwpObject > obj(VO_TYPE tag=VO_INVALID) const
@descr get object from object factory per the object id
Definition: lwpobjid.cxx:183
bool IsNull() const
Definition: lwpobjid.hxx:110
void SetFoundry(LwpFoundry *pFoundry)
Definition: lwpobj.hxx:137
LwpFoundry * m_pFoundry
Definition: lwpobj.hxx:91
virtual LwpOverride * clone() const =0
LwpParaBorderOverride * GetParaBorder() const
static void ApplyParaBorder(XFParaStyle *pParaStyle, LwpParaBorderOverride *pBorder)
LwpNumberingOverride * GetNumberingOverride() const
static void ApplyAlignment(XFParaStyle *pParaStyle, const LwpAlignmentOverride *pAlign)
static void ApplySpacing(LwpPara *pPara, XFParaStyle *pParaStyle, LwpSpacingOverride *pSpacing)
LwpBreaksOverride * GetBreaks() const
const LwpBulletOverride & GetBulletOverride() const
static void ApplyIndent(LwpPara *pPara, XFParaStyle *pParaStyle, const LwpIndentOverride *pIndent)
void SetAllText(std::u16string_view sText)
set text of paragraph
Definition: lwppara1.cxx:102
sal_uInt16 GetLevel() const
Definition: lwppara.hxx:291
OUString m_BefColumnBreakName
Definition: lwppara.hxx:209
bool ComparePagePosition(LwpVirtualLayout const *pPreLayout, LwpVirtualLayout const *pNextLayout)
@descr: If the two layouts in the same para, compare which layout is earlied according to frib order
Definition: lwppara1.cxx:555
@ VALID_LEVEL
Definition: lwppara.hxx:244
OUString m_StyleName
Definition: lwppara.hxx:202
OUString m_AftColumnBreakName
Definition: lwppara.hxx:207
void GatherDropcapInfo()
get drop cap info
Definition: lwppara1.cxx:126
void OverrideIndent(LwpIndentOverride *base, LwpIndentOverride *over, XFParaStyle *pOverStyle)
override indent attribute
Definition: lwppara1.cxx:276
sal_uInt16 m_nFlags
Definition: lwppara.hxx:196
void SetFirstFrib(const OUString &Content, sal_uInt32 FontID)
set first frib content
Definition: lwppara1.cxx:110
OUString m_AllText
Definition: lwppara.hxx:213
LwpDropcapLayout * m_pDropcapLayout
Definition: lwppara.hxx:228
sal_uInt32 m_nChars
Definition: lwppara.hxx:227
std::unique_ptr< LwpBulletOverride > m_xBullOver
Definition: lwppara.hxx:218
void OverrideParaBorder(LwpParaProperty *pProps, XFParaStyle *pOverStyle)
: Override paraborder style.
Definition: lwppara1.cxx:317
bool IsInCell()
check paragraph in cell or not
Definition: lwppara1.cxx:564
std::unique_ptr< LwpBreaksOverride > m_pBreaks
Definition: lwppara.hxx:204
std::vector< std::unique_ptr< LwpParaProperty > > m_vProps
Definition: lwppara.hxx:199
OUString m_BefPageBreakName
Definition: lwppara.hxx:206
void OverrideParaBreaks(LwpParaProperty *pProps, XFParaStyle *pOverStyle)
: Override parabreaks style.
Definition: lwppara1.cxx:349
bool m_bHasBullet
Definition: lwppara.hxx:215
LwpStory * GetStory()
Definition: lwppara.hxx:337
std::unique_ptr< LwpNumberingOverride > m_xParaNumbering
Definition: lwppara.hxx:219
void OverrideParaBullet(LwpParaProperty *pProps)
: Override bullet styles.
Definition: lwppara1.cxx:414
LwpPara * GetParent()
get parent paragraph
Definition: lwppara1.cxx:134
LwpFribPtr m_Fribs
Definition: lwppara.hxx:198
bool operator<(LwpPara const &Other)
@descr: Determined which para is earlier in position
Definition: lwppara1.cxx:546
LwpObjectID m_ParaStyle
Definition: lwppara.hxx:192
LwpSilverBullet * m_pSilverBullet
Definition: lwppara.hxx:217
sal_uInt16 m_nLines
Definition: lwppara.hxx:226
LwpParaStyle * GetParaStyle()
: Get parastyle object according to the objID.
Definition: lwppara1.cxx:307
sal_uInt16 m_nLevel
Definition: lwppara.hxx:197
sal_uInt32 m_FontID
Definition: lwppara.hxx:212
static void OverrideAlignment(LwpAlignmentOverride *base, LwpAlignmentOverride *over, XFParaStyle *pOverStyle)
override alignment
Definition: lwppara1.cxx:263
OUString const & GetContentText(bool bAllText=false)
get text of paragraph
Definition: lwppara1.cxx:86
sal_uInt32 m_nOrdinal
Definition: lwppara.hxx:191
OUString m_AftPageBreakName
Definition: lwppara.hxx:205
LwpTabOverride * GetLocalTabOverride()
Definition: lwppara1.cxx:532
LwpParaProperty * GetProperty(sal_uInt32 nPropType)
Definition: lwppara1.cxx:519
void OverrideParaNumbering(LwpParaProperty const *pProps)
: Override paranumbering properties.
Definition: lwppara1.cxx:480
OUString m_Content
Definition: lwppara.hxx:211
LwpObjectID m_aSilverBulletID
Definition: lwppara.hxx:216
XFParaStyle * GetXFParaStyle()
get paragraph xfstyle
Definition: lwppara1.cxx:118
void OverrideSpacing(LwpSpacingOverride *base, LwpSpacingOverride *over, XFParaStyle *pOverStyle)
override spacing
Definition: lwppara1.cxx:291
void GetParaNumber(sal_uInt16 nPosition, ParaNumbering *pParaNumbering)
: Offer prefix, paranumber and suffix according to position.
Definition: lwppara1.cxx:164
void Override(LwpSpacingOverride *other)
sal_uInt16 GetHideLevels() const
Style object for aragraph.
Definition: xfparastyle.hxx:93
void SetBreaks(enumXFBreaks breaks)
descr You can only set one break property for every para style object.
Style manager for the filter.
IXFStyleRet AddStyle(std::unique_ptr< IXFStyle > pStyle)
XFParaStyle * FindParaStyle(std::u16string_view name)
std::pair< const_iterator, bool > insert(Value &&x)
void const * base
@ VO_PARASTYLE
Definition: lwpdefs.hxx:102
@ VO_SILVERBULLET
Definition: lwpdefs.hxx:104
@ FRIB_TAG_TEXT
@ FRIB_TAG_PARANUMBER
#define PP_LOCAL_TABRACK
int i
IXFStyle * m_pStyle
Definition: xfstylecont.hxx:71
LwpTextAttributeOverride aTxtAttrOverride
Definition: lwpfrib.hxx:77
sal_uInt16 nNumLevel
Definition: lwppara.hxx:119
LwpFribParaNumber * pParaNumber
Definition: lwppara.hxx:116
LwpFribText * pPrefix
Definition: lwppara.hxx:115
LwpFribText * pSuffix
Definition: lwppara.hxx:117
unsigned char sal_uInt8
@ enumXFBreakAftColumn
Definition: xfdefs.hxx:225
@ enumXFBreakKeepWithNext
Definition: xfdefs.hxx:226
@ enumXFBreakAftPage
Definition: xfdefs.hxx:224