1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include <algorithm> 8 9 #include "xfa/src/foxitlib.h" 10 #include "xfa/src/fxfa/src/common/xfa_utils.h" 11 #include "xfa/src/fxfa/src/common/xfa_object.h" 12 #include "xfa/src/fxfa/src/common/xfa_document.h" 13 #include "xfa/src/fxfa/src/common/xfa_parser.h" 14 #include "xfa/src/fxfa/src/common/xfa_script.h" 15 #include "xfa/src/fxfa/src/common/xfa_docdata.h" 16 #include "xfa/src/fxfa/src/common/xfa_doclayout.h" 17 #include "xfa/src/fxfa/src/common/xfa_localemgr.h" 18 #include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h" 19 #include "xfa_document_layout_imp.h" 20 #include "xfa_layout_itemlayout.h" 21 #include "xfa_layout_pagemgr_new.h" 22 #include "xfa_layout_appadapter.h" 23 CXFA_ItemLayoutProcessor::CXFA_ItemLayoutProcessor(CXFA_Node* pNode, 24 CXFA_LayoutPageMgr* pPageMgr) 25 : m_bKeepBreakFinish(FALSE), 26 m_bIsProcessKeep(FALSE), 27 m_pKeepHeadNode(nullptr), 28 m_pKeepTailNode(nullptr), 29 m_pFormNode(pNode), 30 m_pLayoutItem(nullptr), 31 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_ 32 m_pOldLayoutItem(nullptr), 33 #else 34 m_pPageMgrCreateItem(nullptr), 35 #endif 36 m_pCurChildNode(XFA_LAYOUT_INVALIDNODE), 37 m_pCurChildPreprocessor(nullptr), 38 m_nCurChildNodeStage(XFA_ItemLayoutProcessorStages_None), 39 m_fUsedSize(0), 40 m_pPageMgr(pPageMgr), 41 m_bBreakPending(TRUE), 42 m_fLastRowWidth(0), 43 m_fLastRowY(0), 44 m_fWidthLimite(0), 45 m_bUseInheriated(FALSE), 46 m_ePreProcessRs(XFA_ItemLayoutProcessorResult_Done), 47 m_bHasAvailHeight(TRUE) { 48 FXSYS_assert(m_pFormNode && (m_pFormNode->IsContainerNode() || 49 m_pFormNode->GetClassID() == XFA_ELEMENT_Form)); 50 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_ 51 m_pOldLayoutItem = 52 (CXFA_ContentLayoutItem*)m_pFormNode->GetUserData(XFA_LAYOUTITEMKEY); 53 #endif 54 } 55 CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::CreateContentLayoutItem( 56 CXFA_Node* pFormNode) { 57 if (!pFormNode) { 58 return NULL; 59 } 60 CXFA_ContentLayoutItem* pLayoutItem = NULL; 61 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_ 62 if (m_pOldLayoutItem) { 63 pLayoutItem = m_pOldLayoutItem; 64 m_pOldLayoutItem = m_pOldLayoutItem->m_pNext; 65 return pLayoutItem; 66 } 67 pLayoutItem = (CXFA_ContentLayoutItem*)pFormNode->GetDocument() 68 ->GetParser() 69 ->GetNotify() 70 ->OnCreateLayoutItem(pFormNode); 71 #else 72 pLayoutItem = 73 (CXFA_ContentLayoutItem*)m_pPageMgrCreateItem->FindOrCreateLayoutItem( 74 pFormNode); 75 #endif 76 CXFA_ContentLayoutItem* pPrevLayoutItem = 77 (CXFA_ContentLayoutItem*)pFormNode->GetUserData(XFA_LAYOUTITEMKEY); 78 if (pPrevLayoutItem) { 79 while (pPrevLayoutItem->m_pNext) { 80 pPrevLayoutItem = pPrevLayoutItem->m_pNext; 81 } 82 pPrevLayoutItem->m_pNext = pLayoutItem; 83 pLayoutItem->m_pPrev = pPrevLayoutItem; 84 } else { 85 pFormNode->SetUserData(XFA_LAYOUTITEMKEY, pLayoutItem); 86 } 87 return pLayoutItem; 88 } 89 FX_BOOL CXFA_ItemLayoutProcessor::FindLayoutItemSplitPos( 90 CXFA_ContentLayoutItem* pLayoutItem, 91 FX_FLOAT fCurVerticalOffset, 92 FX_FLOAT& fProposedSplitPos, 93 FX_BOOL& bAppChange, 94 FX_BOOL bCalculateMargin) { 95 CXFA_Node* pFormNode = pLayoutItem->m_pFormNode; 96 if (fProposedSplitPos > fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION && 97 fProposedSplitPos <= fCurVerticalOffset + pLayoutItem->m_sSize.y - 98 XFA_LAYOUT_FLOAT_PERCISION) { 99 switch (pFormNode->GetIntact()) { 100 case XFA_ATTRIBUTEENUM_None: { 101 FX_BOOL bAnyChanged = FALSE; 102 CXFA_Document* pDocument = pFormNode->GetDocument(); 103 IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify(); 104 FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0; 105 CXFA_Node* pMarginNode = 106 pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin); 107 if (pMarginNode && bCalculateMargin) { 108 fCurTopMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset) 109 .ToUnit(XFA_UNIT_Pt); 110 fCurBottomMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset) 111 .ToUnit(XFA_UNIT_Pt); 112 } 113 FX_BOOL bChanged = TRUE; 114 while (bChanged) { 115 bChanged = FALSE; 116 { 117 FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurVerticalOffset; 118 if (pNotify->FindSplitPos(pFormNode, pLayoutItem->GetIndex(), 119 fRelSplitPos)) { 120 bAnyChanged = TRUE; 121 bChanged = TRUE; 122 fProposedSplitPos = fCurVerticalOffset + fRelSplitPos; 123 bAppChange = TRUE; 124 if (fProposedSplitPos <= 125 fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) { 126 return TRUE; 127 } 128 } 129 } 130 FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurBottomMargin; 131 for (CXFA_ContentLayoutItem* pChildItem = 132 (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild; 133 pChildItem; 134 pChildItem = 135 (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) { 136 FX_FLOAT fChildOffset = 137 fCurVerticalOffset + fCurTopMargin + pChildItem->m_sPos.y; 138 FX_BOOL bAppChange = FALSE; 139 if (FindLayoutItemSplitPos(pChildItem, fChildOffset, fRelSplitPos, 140 bAppChange, bCalculateMargin)) { 141 if (fRelSplitPos - fChildOffset < XFA_LAYOUT_FLOAT_PERCISION && 142 bAppChange) { 143 fProposedSplitPos = fRelSplitPos - fCurTopMargin; 144 } else { 145 fProposedSplitPos = fRelSplitPos + fCurBottomMargin; 146 } 147 bAnyChanged = TRUE; 148 bChanged = TRUE; 149 if (fProposedSplitPos <= 150 fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) { 151 return TRUE; 152 } 153 if (bAnyChanged) { 154 break; 155 } 156 } 157 } 158 } 159 return bAnyChanged; 160 } break; 161 case XFA_ATTRIBUTEENUM_ContentArea: 162 case XFA_ATTRIBUTEENUM_PageArea: { 163 fProposedSplitPos = fCurVerticalOffset; 164 return TRUE; 165 } 166 default: 167 return FALSE; 168 } 169 } 170 return FALSE; 171 } 172 static XFA_ATTRIBUTEENUM XFA_ItemLayoutProcessor_GetLayout( 173 CXFA_Node* pFormNode, 174 FX_BOOL& bRootForceTb) { 175 bRootForceTb = FALSE; 176 XFA_ATTRIBUTEENUM eLayoutMode; 177 if (pFormNode->TryEnum(XFA_ATTRIBUTE_Layout, eLayoutMode, FALSE)) { 178 return eLayoutMode; 179 } 180 CXFA_Node* pParentNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent); 181 if (pParentNode && pParentNode->GetClassID() == XFA_ELEMENT_Form) { 182 bRootForceTb = TRUE; 183 return XFA_ATTRIBUTEENUM_Tb; 184 } 185 return XFA_ATTRIBUTEENUM_Position; 186 } 187 static FX_BOOL XFA_ExistContainerKeep(CXFA_Node* pCurNode, FX_BOOL bPreFind) { 188 if (pCurNode == NULL || !XFA_ItemLayoutProcessor_IsTakingSpace(pCurNode)) { 189 return FALSE; 190 } 191 XFA_NODEITEM eItemType = XFA_NODEITEM_PrevSibling; 192 if (!bPreFind) { 193 eItemType = XFA_NODEITEM_NextSibling; 194 } 195 CXFA_Node* pPreContainer = 196 pCurNode->GetNodeItem(eItemType, XFA_OBJECTTYPE_ContainerNode); 197 if (pPreContainer == NULL) { 198 return FALSE; 199 } 200 CXFA_Node* pKeep = pCurNode->GetFirstChildByClass(XFA_ELEMENT_Keep); 201 if (pKeep) { 202 XFA_ATTRIBUTEENUM ePrevious; 203 XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Previous; 204 if (!bPreFind) { 205 eKeepType = XFA_ATTRIBUTE_Next; 206 } 207 if (pKeep->TryEnum(eKeepType, ePrevious, FALSE)) { 208 if (ePrevious == XFA_ATTRIBUTEENUM_ContentArea || 209 ePrevious == XFA_ATTRIBUTEENUM_PageArea) { 210 return TRUE; 211 } 212 } 213 } 214 pKeep = pPreContainer->GetFirstChildByClass(XFA_ELEMENT_Keep); 215 if (!pKeep) { 216 return FALSE; 217 } 218 XFA_ATTRIBUTEENUM eNext; 219 XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Next; 220 if (!bPreFind) { 221 eKeepType = XFA_ATTRIBUTE_Previous; 222 } 223 if (!pKeep->TryEnum(eKeepType, eNext, FALSE)) { 224 return FALSE; 225 } 226 if (eNext == XFA_ATTRIBUTEENUM_ContentArea || 227 eNext == XFA_ATTRIBUTEENUM_PageArea) { 228 return TRUE; 229 } 230 return FALSE; 231 } 232 FX_FLOAT CXFA_ItemLayoutProcessor::FindSplitPos(FX_FLOAT fProposedSplitPos) { 233 ASSERT(m_pLayoutItem); 234 XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); 235 FX_BOOL bCalculateMargin = TRUE; 236 if (eLayout == XFA_ATTRIBUTEENUM_Position) { 237 bCalculateMargin = FALSE; 238 } 239 while (fProposedSplitPos > XFA_LAYOUT_FLOAT_PERCISION) { 240 FX_BOOL bAppChange = FALSE; 241 if (!FindLayoutItemSplitPos(m_pLayoutItem, 0, fProposedSplitPos, bAppChange, 242 bCalculateMargin)) { 243 break; 244 } 245 } 246 return fProposedSplitPos; 247 } 248 void CXFA_ItemLayoutProcessor::SplitLayoutItem( 249 CXFA_ContentLayoutItem* pLayoutItem, 250 CXFA_ContentLayoutItem* pSecondParent, 251 FX_FLOAT fSplitPos) { 252 FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0; 253 XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); 254 FX_BOOL bCalculateMargin = TRUE; 255 if (eLayout == XFA_ATTRIBUTEENUM_Position) { 256 bCalculateMargin = FALSE; 257 } 258 CXFA_Node* pMarginNode = 259 pLayoutItem->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin); 260 if (pMarginNode && bCalculateMargin) { 261 fCurTopMargin = 262 pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt); 263 fCurBottomMargin = 264 pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt); 265 } 266 CXFA_ContentLayoutItem* pSecondLayoutItem = NULL; 267 if (m_pCurChildPreprocessor && 268 m_pCurChildPreprocessor->m_pFormNode == pLayoutItem->m_pFormNode) { 269 pSecondLayoutItem = m_pCurChildPreprocessor->CreateContentLayoutItem( 270 pLayoutItem->m_pFormNode); 271 } else { 272 pSecondLayoutItem = CreateContentLayoutItem(pLayoutItem->m_pFormNode); 273 } 274 pSecondLayoutItem->m_sPos.x = pLayoutItem->m_sPos.x; 275 pSecondLayoutItem->m_sSize.x = pLayoutItem->m_sSize.x; 276 pSecondLayoutItem->m_sPos.y = 0; 277 pSecondLayoutItem->m_sSize.y = pLayoutItem->m_sSize.y - fSplitPos; 278 pLayoutItem->m_sSize.y -= pSecondLayoutItem->m_sSize.y; 279 if (pLayoutItem->m_pFirstChild) { 280 pSecondLayoutItem->m_sSize.y += fCurTopMargin; 281 } 282 if (pSecondParent) { 283 pSecondParent->AddChild(pSecondLayoutItem); 284 if (fCurTopMargin > 0 && pLayoutItem->m_pFirstChild) { 285 pSecondParent->m_sSize.y += fCurTopMargin; 286 CXFA_ContentLayoutItem* pParentItem = 287 (CXFA_ContentLayoutItem*)pSecondParent->m_pParent; 288 while (pParentItem) { 289 pParentItem->m_sSize.y += fCurTopMargin; 290 pParentItem = (CXFA_ContentLayoutItem*)pParentItem->m_pParent; 291 } 292 } 293 } else { 294 pSecondLayoutItem->m_pParent = pLayoutItem->m_pParent; 295 pSecondLayoutItem->m_pNextSibling = pLayoutItem->m_pNextSibling; 296 pLayoutItem->m_pNextSibling = pSecondLayoutItem; 297 } 298 CXFA_ContentLayoutItem* pChildren = 299 (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild; 300 pLayoutItem->m_pFirstChild = NULL; 301 FX_FLOAT lHeightForKeep = 0; 302 CFX_ArrayTemplate<CXFA_ContentLayoutItem*> keepLayoutItems; 303 FX_FLOAT fAddMarginHeight = 0; 304 for (CXFA_ContentLayoutItem* pChildItem = pChildren, * pChildNext = NULL; 305 pChildItem; pChildItem = pChildNext) { 306 pChildNext = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling; 307 pChildItem->m_pNextSibling = NULL; 308 if (fSplitPos <= fCurTopMargin + pChildItem->m_sPos.y + fCurBottomMargin + 309 XFA_LAYOUT_FLOAT_PERCISION) { 310 if (!XFA_ExistContainerKeep(pChildItem->m_pFormNode, TRUE)) { 311 pChildItem->m_sPos.y -= fSplitPos - fCurBottomMargin; 312 pChildItem->m_sPos.y += lHeightForKeep; 313 pChildItem->m_sPos.y += fAddMarginHeight; 314 pSecondLayoutItem->AddChild(pChildItem); 315 } else { 316 if (lHeightForKeep < XFA_LAYOUT_FLOAT_PERCISION) { 317 for (int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize(); 318 iIndex++) { 319 CXFA_ContentLayoutItem* pPreItem = keepLayoutItems[iIndex]; 320 pLayoutItem->RemoveChild(pPreItem); 321 pPreItem->m_sPos.y -= fSplitPos; 322 if (pPreItem->m_sPos.y < 0) { 323 pPreItem->m_sPos.y = 0; 324 } 325 if (pPreItem->m_sPos.y + pPreItem->m_sSize.y > lHeightForKeep) { 326 pPreItem->m_sPos.y = lHeightForKeep; 327 lHeightForKeep += pPreItem->m_sSize.y; 328 pSecondLayoutItem->m_sSize.y += pPreItem->m_sSize.y; 329 if (pSecondParent) { 330 pSecondParent->m_sSize.y += pPreItem->m_sSize.y; 331 } 332 } 333 pSecondLayoutItem->AddChild(pPreItem); 334 } 335 } 336 pChildItem->m_sPos.y -= fSplitPos; 337 pChildItem->m_sPos.y += lHeightForKeep; 338 pChildItem->m_sPos.y += fAddMarginHeight; 339 pSecondLayoutItem->AddChild(pChildItem); 340 } 341 } else if (fSplitPos + XFA_LAYOUT_FLOAT_PERCISION >= 342 fCurTopMargin + fCurBottomMargin + pChildItem->m_sPos.y + 343 pChildItem->m_sSize.y) { 344 pLayoutItem->AddChild(pChildItem); 345 if (XFA_ExistContainerKeep(pChildItem->m_pFormNode, FALSE)) { 346 keepLayoutItems.Add(pChildItem); 347 } else { 348 keepLayoutItems.RemoveAll(); 349 } 350 } else { 351 FX_FLOAT fOldHeight = pSecondLayoutItem->m_sSize.y; 352 SplitLayoutItem( 353 pChildItem, pSecondLayoutItem, 354 fSplitPos - fCurTopMargin - fCurBottomMargin - pChildItem->m_sPos.y); 355 fAddMarginHeight = pSecondLayoutItem->m_sSize.y - fOldHeight; 356 pLayoutItem->AddChild(pChildItem); 357 } 358 } 359 } 360 void CXFA_ItemLayoutProcessor::SplitLayoutItem(FX_FLOAT fSplitPos) { 361 ASSERT(m_pLayoutItem); 362 SplitLayoutItem(m_pLayoutItem, NULL, fSplitPos); 363 return; 364 } 365 366 IXFA_LayoutPage* CXFA_LayoutItem::GetPage() const { 367 for (CXFA_LayoutItem* pCurNode = const_cast<CXFA_LayoutItem*>(this); pCurNode; 368 pCurNode = pCurNode->m_pParent) { 369 if (pCurNode->m_pFormNode->GetClassID() == XFA_ELEMENT_PageArea) 370 return static_cast<CXFA_ContainerLayoutItem*>(pCurNode); 371 } 372 return nullptr; 373 } 374 375 CXFA_Node* CXFA_LayoutItem::GetFormNode() const { 376 return m_pFormNode; 377 } 378 379 void CXFA_LayoutItem::GetRect(CFX_RectF& rtLayout, FX_BOOL bRelative) const { 380 ASSERT(m_bIsContentLayoutItem); 381 const CXFA_ContentLayoutItem* pThis = 382 static_cast<const CXFA_ContentLayoutItem*>(this); 383 CFX_PointF sPos = pThis->m_sPos; 384 CFX_SizeF sSize = pThis->m_sSize; 385 if (!bRelative) { 386 for (CXFA_LayoutItem* pLayoutItem = pThis->m_pParent; pLayoutItem; 387 pLayoutItem = pLayoutItem->m_pParent) { 388 if (CXFA_ContentLayoutItem* pContent = 389 pLayoutItem->AsContentLayoutItem()) { 390 sPos += pContent->m_sPos; 391 if (CXFA_Node* pMarginNode = 392 pLayoutItem->m_pFormNode->GetFirstChildByClass( 393 XFA_ELEMENT_Margin)) { 394 sPos.Add(pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset) 395 .ToUnit(XFA_UNIT_Pt), 396 pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset) 397 .ToUnit(XFA_UNIT_Pt)); 398 } 399 } else { 400 if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) { 401 sPos.Add(pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_X) 402 .ToUnit(XFA_UNIT_Pt), 403 pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Y) 404 .ToUnit(XFA_UNIT_Pt)); 405 break; 406 } else if (pLayoutItem->m_pFormNode->GetClassID() == 407 XFA_ELEMENT_PageArea) { 408 break; 409 } 410 } 411 } 412 } 413 rtLayout.Set(sPos.x, sPos.y, sSize.x, sSize.y); 414 } 415 416 CXFA_LayoutItem* CXFA_LayoutItem::GetParent() const { 417 return m_pParent; 418 } 419 420 const CXFA_LayoutItem* CXFA_LayoutItem::GetFirst() const { 421 ASSERT(m_bIsContentLayoutItem); 422 const CXFA_ContentLayoutItem* pCurNode = 423 static_cast<const CXFA_ContentLayoutItem*>(this); 424 while (pCurNode->m_pPrev) { 425 pCurNode = pCurNode->m_pPrev; 426 } 427 return pCurNode; 428 } 429 430 CXFA_LayoutItem* CXFA_LayoutItem::GetFirst() { 431 ASSERT(m_bIsContentLayoutItem); 432 CXFA_ContentLayoutItem* pCurNode = static_cast<CXFA_ContentLayoutItem*>(this); 433 while (pCurNode->m_pPrev) { 434 pCurNode = pCurNode->m_pPrev; 435 } 436 return pCurNode; 437 } 438 439 CXFA_LayoutItem* CXFA_LayoutItem::GetLast() { 440 ASSERT(m_bIsContentLayoutItem); 441 CXFA_ContentLayoutItem* pCurNode = static_cast<CXFA_ContentLayoutItem*>(this); 442 while (pCurNode->m_pNext) { 443 pCurNode = pCurNode->m_pNext; 444 } 445 return pCurNode; 446 } 447 448 const CXFA_LayoutItem* CXFA_LayoutItem::GetLast() const { 449 ASSERT(m_bIsContentLayoutItem); 450 const CXFA_ContentLayoutItem* pCurNode = 451 static_cast<const CXFA_ContentLayoutItem*>(this); 452 while (pCurNode->m_pNext) { 453 pCurNode = pCurNode->m_pNext; 454 } 455 return pCurNode; 456 } 457 458 CXFA_LayoutItem* CXFA_LayoutItem::GetPrev() const { 459 ASSERT(m_bIsContentLayoutItem); 460 return static_cast<const CXFA_ContentLayoutItem*>(this)->m_pPrev; 461 } 462 463 CXFA_LayoutItem* CXFA_LayoutItem::GetNext() const { 464 ASSERT(m_bIsContentLayoutItem); 465 return static_cast<const CXFA_ContentLayoutItem*>(this)->m_pNext; 466 } 467 468 int32_t CXFA_LayoutItem::GetIndex() const { 469 ASSERT(m_bIsContentLayoutItem); 470 int32_t iIndex = 0; 471 const CXFA_ContentLayoutItem* pCurNode = 472 static_cast<const CXFA_ContentLayoutItem*>(this); 473 while (pCurNode->m_pPrev) { 474 pCurNode = pCurNode->m_pPrev; 475 ++iIndex; 476 } 477 return iIndex; 478 } 479 480 int32_t CXFA_LayoutItem::GetCount() const { 481 ASSERT(m_bIsContentLayoutItem); 482 int32_t iCount = GetIndex() + 1; 483 const CXFA_ContentLayoutItem* pCurNode = 484 static_cast<const CXFA_ContentLayoutItem*>(this); 485 while (pCurNode->m_pNext) { 486 pCurNode = pCurNode->m_pNext; 487 iCount++; 488 } 489 return iCount; 490 } 491 492 void CXFA_LayoutItem::AddChild(CXFA_LayoutItem* pChildItem) { 493 if (pChildItem->m_pParent) { 494 pChildItem->m_pParent->RemoveChild(pChildItem); 495 } 496 pChildItem->m_pParent = this; 497 if (m_pFirstChild == NULL) { 498 m_pFirstChild = pChildItem; 499 } else { 500 CXFA_LayoutItem* pExistingChildItem = m_pFirstChild; 501 while (pExistingChildItem->m_pNextSibling) { 502 pExistingChildItem = pExistingChildItem->m_pNextSibling; 503 } 504 pExistingChildItem->m_pNextSibling = pChildItem; 505 } 506 } 507 void CXFA_LayoutItem::AddHeadChild(CXFA_LayoutItem* pChildItem) { 508 if (pChildItem->m_pParent) { 509 pChildItem->m_pParent->RemoveChild(pChildItem); 510 } 511 pChildItem->m_pParent = this; 512 if (m_pFirstChild == NULL) { 513 m_pFirstChild = pChildItem; 514 } else { 515 CXFA_LayoutItem* pExistingChildItem = m_pFirstChild; 516 m_pFirstChild = pChildItem; 517 m_pFirstChild->m_pNextSibling = pExistingChildItem; 518 } 519 } 520 void CXFA_LayoutItem::InsertChild(CXFA_LayoutItem* pBeforeItem, 521 CXFA_LayoutItem* pChildItem) { 522 if (pBeforeItem->m_pParent != this) { 523 return; 524 } 525 if (pChildItem->m_pParent) { 526 pChildItem->m_pParent = NULL; 527 } 528 pChildItem->m_pParent = this; 529 CXFA_LayoutItem* pExistingChildItem = pBeforeItem->m_pNextSibling; 530 pBeforeItem->m_pNextSibling = pChildItem; 531 pChildItem->m_pNextSibling = pExistingChildItem; 532 } 533 void CXFA_LayoutItem::RemoveChild(CXFA_LayoutItem* pChildItem) { 534 if (pChildItem->m_pParent != this) { 535 return; 536 } 537 if (m_pFirstChild == pChildItem) { 538 m_pFirstChild = pChildItem->m_pNextSibling; 539 } else { 540 CXFA_LayoutItem* pExistingChildItem = m_pFirstChild; 541 while (pExistingChildItem && 542 pExistingChildItem->m_pNextSibling != pChildItem) { 543 pExistingChildItem = pExistingChildItem->m_pNextSibling; 544 } 545 if (pExistingChildItem) { 546 pExistingChildItem->m_pNextSibling = pChildItem->m_pNextSibling; 547 } 548 } 549 pChildItem->m_pNextSibling = NULL; 550 pChildItem->m_pParent = NULL; 551 } 552 CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::ExtractLayoutItem() { 553 CXFA_ContentLayoutItem* pLayoutItem = m_pLayoutItem; 554 if (pLayoutItem) { 555 m_pLayoutItem = (CXFA_ContentLayoutItem*)pLayoutItem->m_pNextSibling; 556 pLayoutItem->m_pNextSibling = NULL; 557 } 558 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_ 559 if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done && 560 ToContentLayoutItem(m_pOldLayoutItem)) { 561 if (m_pOldLayoutItem->m_pPrev) { 562 m_pOldLayoutItem->m_pPrev->m_pNext = NULL; 563 } 564 IXFA_Notify* pNotify = 565 m_pOldLayoutItem->m_pFormNode->GetDocument()->GetParser()->GetNotify(); 566 IXFA_DocLayout* pDocLayout = 567 m_pOldLayoutItem->m_pFormNode->GetDocument()->GetDocLayout(); 568 CXFA_ContentLayoutItem* pOldLayoutItem = m_pOldLayoutItem; 569 while (pOldLayoutItem) { 570 CXFA_ContentLayoutItem* pNextOldLayoutItem = pOldLayoutItem->m_pNext; 571 pNotify->OnLayoutEvent(pDocLayout, pOldLayoutItem, 572 XFA_LAYOUTEVENT_ItemRemoving); 573 delete pOldLayoutItem; 574 pOldLayoutItem = pNextOldLayoutItem; 575 } 576 m_pOldLayoutItem = NULL; 577 } 578 #endif 579 return pLayoutItem; 580 } 581 static FX_BOOL XFA_ItemLayoutProcessor_FindBreakNode( 582 CXFA_Node* pContainerNode, 583 CXFA_Node*& pCurActionNode, 584 XFA_ItemLayoutProcessorStages& nCurStage, 585 FX_BOOL bBreakBefore) { 586 FX_BOOL bFindRs = FALSE; 587 for (CXFA_Node* pBreakNode = pContainerNode; pBreakNode; 588 pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { 589 XFA_ATTRIBUTE eAttributeType = XFA_ATTRIBUTE_Before; 590 if (!bBreakBefore) { 591 eAttributeType = XFA_ATTRIBUTE_After; 592 } 593 switch (pBreakNode->GetClassID()) { 594 case XFA_ELEMENT_BreakBefore: { 595 if (bBreakBefore) { 596 pCurActionNode = pBreakNode; 597 nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore; 598 bFindRs = TRUE; 599 } 600 } break; 601 case XFA_ELEMENT_BreakAfter: { 602 if (!bBreakBefore) { 603 pCurActionNode = pBreakNode; 604 nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter; 605 bFindRs = TRUE; 606 } 607 } break; 608 case XFA_ELEMENT_Break: 609 if (pBreakNode->GetEnum(eAttributeType) != XFA_ATTRIBUTEENUM_Auto) { 610 pCurActionNode = pBreakNode; 611 nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore; 612 if (!bBreakBefore) { 613 nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter; 614 } 615 bFindRs = TRUE; 616 break; 617 } 618 default: 619 break; 620 } 621 if (bFindRs) { 622 break; 623 } 624 } 625 return bFindRs; 626 } 627 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_ 628 static void XFA_DeleteLayoutGeneratedNode(CXFA_Node* pGenerateNode) { 629 IXFA_Notify* pNotify = pGenerateNode->GetDocument()->GetParser()->GetNotify(); 630 IXFA_DocLayout* pDocLayout = pGenerateNode->GetDocument()->GetDocLayout(); 631 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator( 632 pGenerateNode); 633 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; 634 pNode = sIterator.MoveToNext()) { 635 CXFA_ContentLayoutItem* pCurLayoutItem = 636 (CXFA_ContentLayoutItem*)pNode->GetUserData(XFA_LAYOUTITEMKEY); 637 CXFA_ContentLayoutItem* pNextLayoutItem = NULL; 638 while (pCurLayoutItem) { 639 pNextLayoutItem = pCurLayoutItem->m_pNext; 640 pNotify->OnLayoutEvent(pDocLayout, pCurLayoutItem, 641 XFA_LAYOUTEVENT_ItemRemoving); 642 delete pCurLayoutItem; 643 pCurLayoutItem = pNextLayoutItem; 644 } 645 } 646 pGenerateNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pGenerateNode); 647 } 648 #endif 649 void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode( 650 CXFA_Node*& pCurActionNode, 651 XFA_ItemLayoutProcessorStages& nCurStage, 652 CXFA_Node* pParentContainer, 653 FX_BOOL bUsePageBreak) { 654 CXFA_Node* pEntireContainer = pParentContainer; 655 CXFA_Node* pChildContainer = XFA_LAYOUT_INVALIDNODE; 656 switch (nCurStage) { 657 case XFA_ItemLayoutProcessorStages_BreakBefore: 658 case XFA_ItemLayoutProcessorStages_BreakAfter: { 659 pChildContainer = pCurActionNode->GetNodeItem(XFA_NODEITEM_Parent); 660 } break; 661 case XFA_ItemLayoutProcessorStages_Keep: 662 case XFA_ItemLayoutProcessorStages_Container: 663 pChildContainer = pCurActionNode; 664 break; 665 default: 666 pChildContainer = XFA_LAYOUT_INVALIDNODE; 667 break; 668 } 669 switch (nCurStage) { 670 case XFA_ItemLayoutProcessorStages_Keep: { 671 CXFA_Node* pBreakAfterNode = 672 pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild); 673 if (!m_bKeepBreakFinish && 674 XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode, 675 nCurStage, FALSE)) { 676 return; 677 } 678 goto CheckNextChildContainer; 679 } 680 case XFA_ItemLayoutProcessorStages_None: { 681 pCurActionNode = XFA_LAYOUT_INVALIDNODE; 682 case XFA_ItemLayoutProcessorStages_BookendLeader: 683 for (CXFA_Node* pBookendNode = 684 pCurActionNode == XFA_LAYOUT_INVALIDNODE 685 ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild) 686 : pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling); 687 pBookendNode; pBookendNode = pBookendNode->GetNodeItem( 688 XFA_NODEITEM_NextSibling)) { 689 switch (pBookendNode->GetClassID()) { 690 case XFA_ELEMENT_Bookend: 691 case XFA_ELEMENT_Break: 692 pCurActionNode = pBookendNode; 693 nCurStage = XFA_ItemLayoutProcessorStages_BookendLeader; 694 return; 695 default: 696 break; 697 } 698 } 699 } 700 { 701 pCurActionNode = XFA_LAYOUT_INVALIDNODE; 702 case XFA_ItemLayoutProcessorStages_BreakBefore: 703 if (pCurActionNode != XFA_LAYOUT_INVALIDNODE) { 704 CXFA_Node* pBreakBeforeNode = 705 pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling); 706 if (!m_bKeepBreakFinish && 707 XFA_ItemLayoutProcessor_FindBreakNode( 708 pBreakBeforeNode, pCurActionNode, nCurStage, TRUE)) { 709 return; 710 } 711 if (m_bIsProcessKeep) { 712 if (ProcessKeepNodesForBreakBefore(pCurActionNode, nCurStage, 713 pChildContainer)) { 714 return; 715 } 716 goto CheckNextChildContainer; 717 } 718 pCurActionNode = pChildContainer; 719 nCurStage = XFA_ItemLayoutProcessorStages_Container; 720 return; 721 } 722 goto CheckNextChildContainer; 723 } 724 case XFA_ItemLayoutProcessorStages_Container: { 725 pCurActionNode = XFA_LAYOUT_INVALIDNODE; 726 case XFA_ItemLayoutProcessorStages_BreakAfter: { 727 if (pCurActionNode == XFA_LAYOUT_INVALIDNODE) { 728 CXFA_Node* pBreakAfterNode = 729 pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild); 730 if (!m_bKeepBreakFinish && 731 XFA_ItemLayoutProcessor_FindBreakNode( 732 pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) { 733 return; 734 } 735 } else { 736 CXFA_Node* pBreakAfterNode = 737 pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling); 738 if (XFA_ItemLayoutProcessor_FindBreakNode( 739 pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) { 740 return; 741 } 742 } 743 goto CheckNextChildContainer; 744 } 745 } 746 CheckNextChildContainer : { 747 CXFA_Node* pNextChildContainer = 748 pChildContainer == XFA_LAYOUT_INVALIDNODE 749 ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild, 750 XFA_OBJECTTYPE_ContainerNode) 751 : pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling, 752 XFA_OBJECTTYPE_ContainerNode); 753 while (pNextChildContainer && 754 pNextChildContainer->HasFlag(XFA_NODEFLAG_LayoutGeneratedNode)) { 755 CXFA_Node* pSaveNode = pNextChildContainer; 756 pNextChildContainer = pNextChildContainer->GetNodeItem( 757 XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode); 758 #ifdef _XFA_LAYOUTITEM_ProcessCACHE_ 759 if (pSaveNode->HasFlag(XFA_NODEFLAG_UnusedNode)) { 760 XFA_DeleteLayoutGeneratedNode(pSaveNode); 761 } 762 #endif 763 } 764 if (!pNextChildContainer) { 765 goto NoMoreChildContainer; 766 } 767 FX_BOOL bLastKeep = FALSE; 768 if (ProcessKeepNodesForCheckNext(pCurActionNode, nCurStage, 769 pNextChildContainer, bLastKeep)) { 770 return; 771 } 772 if (!m_bKeepBreakFinish && !bLastKeep && 773 XFA_ItemLayoutProcessor_FindBreakNode( 774 pNextChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild), 775 pCurActionNode, nCurStage, TRUE)) { 776 return; 777 } 778 pCurActionNode = pNextChildContainer; 779 if (m_bIsProcessKeep) { 780 nCurStage = XFA_ItemLayoutProcessorStages_Keep; 781 } else { 782 nCurStage = XFA_ItemLayoutProcessorStages_Container; 783 } 784 return; 785 } 786 NoMoreChildContainer : { 787 pCurActionNode = XFA_LAYOUT_INVALIDNODE; 788 case XFA_ItemLayoutProcessorStages_BookendTrailer: 789 for (CXFA_Node* pBookendNode = 790 pCurActionNode == XFA_LAYOUT_INVALIDNODE 791 ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild) 792 : pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling); 793 pBookendNode; pBookendNode = pBookendNode->GetNodeItem( 794 XFA_NODEITEM_NextSibling)) { 795 switch (pBookendNode->GetClassID()) { 796 case XFA_ELEMENT_Bookend: 797 case XFA_ELEMENT_Break: 798 pCurActionNode = pBookendNode; 799 nCurStage = XFA_ItemLayoutProcessorStages_BookendTrailer; 800 return; 801 default: 802 break; 803 } 804 } 805 } 806 default: 807 pCurActionNode = NULL; 808 nCurStage = XFA_ItemLayoutProcessorStages_Done; 809 } 810 } 811 FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepNodesForCheckNext( 812 CXFA_Node*& pCurActionNode, 813 XFA_ItemLayoutProcessorStages& nCurStage, 814 CXFA_Node*& pNextContainer, 815 FX_BOOL& bLastKeepNode) { 816 FX_BOOL bCanSplite = pNextContainer->GetIntact() == XFA_ATTRIBUTEENUM_None; 817 FX_BOOL bNextKeep = FALSE; 818 if (XFA_ExistContainerKeep(pNextContainer, FALSE)) { 819 bNextKeep = TRUE; 820 } 821 if (bNextKeep && !bCanSplite) { 822 if (!m_bIsProcessKeep && !m_bKeepBreakFinish) { 823 m_pKeepHeadNode = pNextContainer; 824 m_bIsProcessKeep = TRUE; 825 } 826 } else { 827 if (m_bIsProcessKeep && m_pKeepHeadNode != NULL) { 828 m_pKeepTailNode = pNextContainer; 829 if (!m_bKeepBreakFinish && 830 XFA_ItemLayoutProcessor_FindBreakNode( 831 pNextContainer->GetNodeItem(XFA_NODEITEM_FirstChild), 832 pCurActionNode, nCurStage, TRUE)) { 833 return TRUE; 834 } else { 835 pNextContainer = m_pKeepHeadNode; 836 m_bKeepBreakFinish = TRUE; 837 m_pKeepHeadNode = NULL; 838 m_pKeepTailNode = NULL; 839 m_bIsProcessKeep = FALSE; 840 } 841 } else { 842 if (m_bKeepBreakFinish) { 843 bLastKeepNode = TRUE; 844 } 845 m_bKeepBreakFinish = FALSE; 846 } 847 } 848 return FALSE; 849 } 850 FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepNodesForBreakBefore( 851 CXFA_Node*& pCurActionNode, 852 XFA_ItemLayoutProcessorStages& nCurStage, 853 CXFA_Node* pContainerNode) { 854 if (m_pKeepTailNode == pContainerNode) { 855 pCurActionNode = m_pKeepHeadNode; 856 m_bKeepBreakFinish = TRUE; 857 m_pKeepHeadNode = NULL; 858 m_pKeepTailNode = NULL; 859 m_bIsProcessKeep = FALSE; 860 nCurStage = XFA_ItemLayoutProcessorStages_Container; 861 return TRUE; 862 } 863 CXFA_Node* pBreakAfterNode = 864 pContainerNode->GetNodeItem(XFA_NODEITEM_FirstChild); 865 if (XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode, 866 nCurStage, FALSE)) { 867 return TRUE; 868 } 869 return FALSE; 870 } 871 FX_BOOL XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode) { 872 XFA_ATTRIBUTEENUM ePresence = pNode->GetEnum(XFA_ATTRIBUTE_Presence); 873 return ePresence == XFA_ATTRIBUTEENUM_Visible || 874 ePresence == XFA_ATTRIBUTEENUM_Invisible; 875 } 876 static inline void XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize( 877 CXFA_Node* pFormNode, 878 FX_FLOAT& fContainerWidth, 879 FX_FLOAT& fContainerHeight, 880 FX_BOOL& bContainerWidthAutoSize, 881 FX_BOOL& bContainerHeightAutoSize) { 882 fContainerWidth = 0; 883 fContainerHeight = 0; 884 bContainerWidthAutoSize = TRUE; 885 bContainerHeightAutoSize = TRUE; 886 XFA_ELEMENT eClassID = pFormNode->GetClassID(); 887 CXFA_Measurement mTmpValue; 888 if (bContainerWidthAutoSize && 889 (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup) && 890 pFormNode->TryMeasure(XFA_ATTRIBUTE_W, mTmpValue, FALSE) && 891 mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) { 892 fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt); 893 bContainerWidthAutoSize = FALSE; 894 } 895 if (bContainerHeightAutoSize && 896 (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup) && 897 pFormNode->TryMeasure(XFA_ATTRIBUTE_H, mTmpValue, FALSE) && 898 mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) { 899 fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt); 900 bContainerHeightAutoSize = FALSE; 901 } 902 if (bContainerWidthAutoSize && eClassID == XFA_ELEMENT_Subform && 903 pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxW, mTmpValue, FALSE) && 904 mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) { 905 fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt); 906 bContainerWidthAutoSize = FALSE; 907 } 908 if (bContainerHeightAutoSize && eClassID == XFA_ELEMENT_Subform && 909 pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxH, mTmpValue, FALSE) && 910 mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) { 911 fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt); 912 bContainerHeightAutoSize = FALSE; 913 } 914 } 915 static inline void 916 XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize( 917 CXFA_Node* pFormNode, 918 FX_BOOL bContainerWidthAutoSize, 919 FX_FLOAT fContentCalculatedWidth, 920 FX_FLOAT& fContainerWidth, 921 FX_BOOL bContainerHeightAutoSize, 922 FX_FLOAT fContentCalculatedHeight, 923 FX_FLOAT& fContainerHeight) { 924 CXFA_Node* pMarginNode = pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin); 925 CXFA_Measurement mTmpValue; 926 if (bContainerWidthAutoSize) { 927 fContainerWidth = fContentCalculatedWidth; 928 if (pMarginNode) { 929 if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_LeftInset, mTmpValue, FALSE)) { 930 fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt); 931 } 932 if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_RightInset, mTmpValue, FALSE)) { 933 fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt); 934 } 935 } 936 } 937 if (bContainerHeightAutoSize) { 938 fContainerHeight = fContentCalculatedHeight; 939 if (pMarginNode) { 940 if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_TopInset, mTmpValue, FALSE)) { 941 fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt); 942 } 943 if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_BottomInset, mTmpValue, 944 FALSE)) { 945 fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt); 946 } 947 } 948 } 949 } 950 void CXFA_ItemLayoutProcessor::CalculatePositionedContainerPos( 951 CXFA_Node* pNode, 952 FX_FLOAT fWidth, 953 FX_FLOAT fHeight, 954 FX_FLOAT& fAbsoluteX, 955 FX_FLOAT& fAbsoluteY) { 956 XFA_ATTRIBUTEENUM eAnchorType = pNode->GetEnum(XFA_ATTRIBUTE_AnchorType); 957 int32_t nAnchorType = 0; 958 switch (eAnchorType) { 959 case XFA_ATTRIBUTEENUM_TopLeft: 960 nAnchorType = 0; 961 break; 962 case XFA_ATTRIBUTEENUM_TopCenter: 963 nAnchorType = 1; 964 break; 965 case XFA_ATTRIBUTEENUM_TopRight: 966 nAnchorType = 2; 967 break; 968 case XFA_ATTRIBUTEENUM_MiddleLeft: 969 nAnchorType = 3; 970 break; 971 case XFA_ATTRIBUTEENUM_MiddleCenter: 972 nAnchorType = 4; 973 break; 974 case XFA_ATTRIBUTEENUM_MiddleRight: 975 nAnchorType = 5; 976 break; 977 case XFA_ATTRIBUTEENUM_BottomLeft: 978 nAnchorType = 6; 979 break; 980 case XFA_ATTRIBUTEENUM_BottomCenter: 981 nAnchorType = 7; 982 break; 983 case XFA_ATTRIBUTEENUM_BottomRight: 984 nAnchorType = 8; 985 break; 986 default: 987 break; 988 } 989 static const uint8_t nNextPos[4][9] = {{0, 1, 2, 3, 4, 5, 6, 7, 8}, 990 {6, 3, 0, 7, 4, 1, 8, 5, 2}, 991 {8, 7, 6, 5, 4, 3, 2, 1, 0}, 992 {2, 5, 8, 1, 4, 7, 0, 3, 6}}; 993 994 FX_FLOAT fAnchorX = pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt); 995 FX_FLOAT fAnchorY = pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt); 996 int32_t nRotate = 997 FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue()); 998 nRotate = XFA_MapRotation(nRotate) / 90; 999 int32_t nAbsoluteAnchorType = nNextPos[nRotate][nAnchorType]; 1000 fAbsoluteX = fAnchorX; 1001 fAbsoluteY = fAnchorY; 1002 switch (nAbsoluteAnchorType / 3) { 1003 case 1: 1004 fAbsoluteY -= fHeight / 2; 1005 break; 1006 case 2: 1007 fAbsoluteY -= fHeight; 1008 break; 1009 default: 1010 break; 1011 } 1012 switch (nAbsoluteAnchorType % 3) { 1013 case 1: 1014 fAbsoluteX -= fWidth / 2; 1015 break; 1016 case 2: 1017 fAbsoluteX -= fWidth; 1018 break; 1019 default: 1020 break; 1021 } 1022 } 1023 FX_BOOL CXFA_ItemLayoutProcessor::IncrementRelayoutNode( 1024 CXFA_LayoutProcessor* pLayoutProcessor, 1025 CXFA_Node* pNode, 1026 CXFA_Node* pParentNode) { 1027 return FALSE; 1028 } 1029 void CXFA_ItemLayoutProcessor::DoLayoutPageArea( 1030 CXFA_ContainerLayoutItem* pPageAreaLayoutItem) { 1031 CXFA_Node* pFormNode = pPageAreaLayoutItem->m_pFormNode; 1032 CXFA_Node* pCurChildNode = XFA_LAYOUT_INVALIDNODE; 1033 XFA_ItemLayoutProcessorStages nCurChildNodeStage = 1034 XFA_ItemLayoutProcessorStages_None; 1035 CXFA_LayoutItem* pBeforeItem = NULL; 1036 for (XFA_ItemLayoutProcessor_GotoNextContainerNode( 1037 pCurChildNode, nCurChildNodeStage, pFormNode, FALSE); 1038 pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode( 1039 pCurChildNode, nCurChildNodeStage, pFormNode, FALSE)) { 1040 if (nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) { 1041 continue; 1042 } 1043 if (pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) { 1044 continue; 1045 } 1046 CXFA_ItemLayoutProcessor* pProcessor = 1047 new CXFA_ItemLayoutProcessor(pCurChildNode, NULL); 1048 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_ 1049 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem; 1050 #endif 1051 pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX); 1052 if (!pProcessor->HasLayoutItem()) { 1053 delete pProcessor; 1054 continue; 1055 } 1056 FX_FLOAT fWidth, fHeight; 1057 pProcessor->GetCurrentComponentSize(fWidth, fHeight); 1058 FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0; 1059 CalculatePositionedContainerPos(pCurChildNode, fWidth, fHeight, fAbsoluteX, 1060 fAbsoluteY); 1061 pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY); 1062 CXFA_LayoutItem* pProcessItem = pProcessor->ExtractLayoutItem(); 1063 if (pBeforeItem == NULL) { 1064 pPageAreaLayoutItem->AddHeadChild(pProcessItem); 1065 } else { 1066 pPageAreaLayoutItem->InsertChild(pBeforeItem, pProcessItem); 1067 } 1068 pBeforeItem = pProcessItem; 1069 delete pProcessor; 1070 } 1071 pBeforeItem = NULL; 1072 CXFA_LayoutItem* pLayoutItem = pPageAreaLayoutItem->m_pFirstChild; 1073 while (pLayoutItem) { 1074 if (!pLayoutItem->IsContentLayoutItem() || 1075 pLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_Draw) { 1076 pLayoutItem = pLayoutItem->m_pNextSibling; 1077 continue; 1078 } 1079 if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_Draw) { 1080 CXFA_LayoutItem* pNextLayoutItem = pLayoutItem->m_pNextSibling; 1081 pPageAreaLayoutItem->RemoveChild(pLayoutItem); 1082 if (pBeforeItem == NULL) { 1083 pPageAreaLayoutItem->AddHeadChild(pLayoutItem); 1084 } else { 1085 pPageAreaLayoutItem->InsertChild(pBeforeItem, pLayoutItem); 1086 } 1087 pBeforeItem = pLayoutItem; 1088 pLayoutItem = pNextLayoutItem; 1089 } 1090 } 1091 } 1092 void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer( 1093 CXFA_LayoutContext* pContext) { 1094 if (m_pLayoutItem != NULL) { 1095 return; 1096 } 1097 m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); 1098 FX_BOOL bIgnoreXY = (m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) != 1099 XFA_ATTRIBUTEENUM_Position); 1100 FX_FLOAT fContainerWidth = 0, fContainerHeight = 0; 1101 FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE; 1102 XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize( 1103 m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, 1104 bContainerHeightAutoSize); 1105 FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0; 1106 FX_FLOAT fHiddenContentCalculatedWidth = 0, 1107 fHiddenContentCalculatedHeight = 0; 1108 if (m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) { 1109 XFA_ItemLayoutProcessor_GotoNextContainerNode( 1110 m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE); 1111 } 1112 int32_t iColIndex = 0; 1113 for (; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode( 1114 m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) { 1115 if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) { 1116 continue; 1117 } 1118 if (m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) { 1119 continue; 1120 } 1121 CXFA_ItemLayoutProcessor* pProcessor = 1122 new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr); 1123 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_ 1124 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem; 1125 #endif 1126 if (pContext && pContext->m_prgSpecifiedColumnWidths) { 1127 int32_t iColSpan = m_pCurChildNode->GetInteger(XFA_ATTRIBUTE_ColSpan); 1128 if (iColSpan <= 1129 pContext->m_prgSpecifiedColumnWidths->GetSize() - iColIndex) { 1130 pContext->m_fCurColumnWidth = 0; 1131 pContext->m_bCurColumnWidthAvaiable = TRUE; 1132 if (iColSpan == -1) { 1133 iColSpan = pContext->m_prgSpecifiedColumnWidths->GetSize(); 1134 } 1135 for (int32_t i = 0; i < iColSpan; i++) { 1136 pContext->m_fCurColumnWidth += 1137 pContext->m_prgSpecifiedColumnWidths->GetAt(iColIndex + i); 1138 } 1139 if (pContext->m_fCurColumnWidth == 0) { 1140 pContext->m_bCurColumnWidthAvaiable = FALSE; 1141 } 1142 iColIndex += iColSpan; 1143 } 1144 } 1145 pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, 1146 pContext); 1147 if (!pProcessor->HasLayoutItem()) { 1148 delete pProcessor; 1149 continue; 1150 } 1151 FX_FLOAT fWidth, fHeight; 1152 pProcessor->GetCurrentComponentSize(fWidth, fHeight); 1153 FX_BOOL bChangeParentSize = FALSE; 1154 if (XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) { 1155 bChangeParentSize = TRUE; 1156 } 1157 FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0; 1158 if (!bIgnoreXY) { 1159 CalculatePositionedContainerPos(m_pCurChildNode, fWidth, fHeight, 1160 fAbsoluteX, fAbsoluteY); 1161 } 1162 pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY); 1163 if (bContainerWidthAutoSize) { 1164 FX_FLOAT fChildSuppliedWidth = fAbsoluteX + fWidth; 1165 if (bChangeParentSize) { 1166 if (fContentCalculatedWidth < fChildSuppliedWidth) { 1167 fContentCalculatedWidth = fChildSuppliedWidth; 1168 } 1169 } else { 1170 if (fHiddenContentCalculatedWidth < fChildSuppliedWidth && 1171 m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) { 1172 fHiddenContentCalculatedWidth = fChildSuppliedWidth; 1173 } 1174 } 1175 } 1176 if (bContainerHeightAutoSize) { 1177 FX_FLOAT fChildSuppliedHeight = fAbsoluteY + fHeight; 1178 if (bChangeParentSize) { 1179 if (fContentCalculatedHeight < fChildSuppliedHeight) { 1180 fContentCalculatedHeight = fChildSuppliedHeight; 1181 } 1182 } else { 1183 if (fHiddenContentCalculatedHeight < fChildSuppliedHeight && 1184 m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) { 1185 fHiddenContentCalculatedHeight = fChildSuppliedHeight; 1186 } 1187 } 1188 } 1189 m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem()); 1190 delete pProcessor; 1191 } 1192 XFA_VERSION eVersion = m_pFormNode->GetDocument()->GetCurVersionMode(); 1193 if (fContentCalculatedWidth == 0 && eVersion < XFA_VERSION_207) { 1194 fContentCalculatedWidth = fHiddenContentCalculatedWidth; 1195 } 1196 if (fContentCalculatedHeight == 0 && eVersion < XFA_VERSION_207) { 1197 fContentCalculatedHeight = fHiddenContentCalculatedHeight; 1198 } 1199 XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize( 1200 m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, 1201 fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, 1202 fContainerHeight); 1203 SetCurrentComponentSize(fContainerWidth, fContainerHeight); 1204 } 1205 static inline void XFA_ItemLayoutProcessor_UpdateWidgetSize( 1206 CXFA_ContentLayoutItem* pLayoutItem, 1207 FX_FLOAT& fWidth, 1208 FX_FLOAT& fHeight) { 1209 CXFA_Node* pNode = pLayoutItem->m_pFormNode; 1210 ASSERT(pNode); 1211 XFA_ELEMENT eClassID = pNode->GetClassID(); 1212 switch (eClassID) { 1213 case XFA_ELEMENT_Subform: 1214 case XFA_ELEMENT_Area: 1215 case XFA_ELEMENT_ExclGroup: 1216 case XFA_ELEMENT_SubformSet: { 1217 if (fWidth < -XFA_LAYOUT_FLOAT_PERCISION) { 1218 fWidth = pLayoutItem->m_sSize.x; 1219 } 1220 if (fHeight < -XFA_LAYOUT_FLOAT_PERCISION) { 1221 fHeight = pLayoutItem->m_sSize.y; 1222 } 1223 break; 1224 } 1225 case XFA_ELEMENT_Draw: 1226 case XFA_ELEMENT_Field: { 1227 pNode->GetDocument()->GetParser()->GetNotify()->StartFieldDrawLayout( 1228 pNode, fWidth, fHeight); 1229 break; 1230 } 1231 default: 1232 ASSERT(FALSE); 1233 } 1234 } 1235 static inline void XFA_ItemLayoutProcessor_RelocateTableRowCells( 1236 CXFA_ContentLayoutItem* pLayoutRow, 1237 const CFX_ArrayTemplate<FX_FLOAT>& rgSpecifiedColumnWidths, 1238 XFA_ATTRIBUTEENUM eLayout) { 1239 FX_FLOAT fContainerWidth = 0, fContainerHeight = 0; 1240 FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE; 1241 XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize( 1242 pLayoutRow->m_pFormNode, fContainerWidth, fContainerHeight, 1243 bContainerWidthAutoSize, bContainerHeightAutoSize); 1244 CXFA_Node* pMarginNode = 1245 pLayoutRow->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin); 1246 FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0; 1247 if (pMarginNode) { 1248 fLeftInset = 1249 pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt); 1250 fTopInset = 1251 pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt); 1252 fRightInset = 1253 pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt); 1254 fBottomInset = 1255 pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt); 1256 } 1257 FX_FLOAT fContentWidthLimit = 1258 bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX 1259 : fContainerWidth - fLeftInset - fRightInset; 1260 FX_FLOAT fContentCurrentHeight = 1261 pLayoutRow->m_sSize.y - fTopInset - fBottomInset; 1262 FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0; 1263 FX_FLOAT fCurrentColX = 0; 1264 int32_t nCurrentColIdx = 0; 1265 FX_BOOL bMetWholeRowCell = FALSE; 1266 for (CXFA_ContentLayoutItem* pLayoutChild = 1267 (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild; 1268 pLayoutChild; 1269 pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) { 1270 int32_t nOriginalColSpan = 1271 pLayoutChild->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan); 1272 int32_t nColSpan = nOriginalColSpan; 1273 FX_FLOAT fColSpanWidth = 0; 1274 if (nColSpan == -1 || 1275 nCurrentColIdx + nColSpan > rgSpecifiedColumnWidths.GetSize()) { 1276 nColSpan = rgSpecifiedColumnWidths.GetSize() - nCurrentColIdx; 1277 } 1278 for (int32_t i = 0; i < nColSpan; i++) { 1279 fColSpanWidth += rgSpecifiedColumnWidths[nCurrentColIdx + i]; 1280 } 1281 if (nColSpan != nOriginalColSpan) { 1282 fColSpanWidth = bMetWholeRowCell ? 0 : std::max(fColSpanWidth, 1283 pLayoutChild->m_sSize.y); 1284 } 1285 if (nOriginalColSpan == -1) { 1286 bMetWholeRowCell = TRUE; 1287 } 1288 pLayoutChild->m_sPos.Set(fCurrentColX, 0); 1289 pLayoutChild->m_sSize.x = fColSpanWidth; 1290 if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) { 1291 fCurrentColX += fColSpanWidth; 1292 nCurrentColIdx += nColSpan; 1293 FX_FLOAT fNewHeight = 1294 bContainerHeightAutoSize ? -1 : fContentCurrentHeight; 1295 XFA_ItemLayoutProcessor_UpdateWidgetSize(pLayoutChild, fColSpanWidth, 1296 fNewHeight); 1297 pLayoutChild->m_sSize.y = fNewHeight; 1298 if (bContainerHeightAutoSize) { 1299 FX_FLOAT fChildSuppliedHeight = pLayoutChild->m_sSize.y; 1300 if (fContentCalculatedHeight < fChildSuppliedHeight) { 1301 fContentCalculatedHeight = fChildSuppliedHeight; 1302 } 1303 } 1304 } 1305 } 1306 if (bContainerHeightAutoSize) { 1307 for (CXFA_ContentLayoutItem* pLayoutChild = 1308 (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild; 1309 pLayoutChild; 1310 pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) { 1311 XFA_ItemLayoutProcessor_UpdateWidgetSize( 1312 pLayoutChild, pLayoutChild->m_sSize.x, fContentCalculatedHeight); 1313 FX_FLOAT fOldChildHeight = pLayoutChild->m_sSize.y; 1314 pLayoutChild->m_sSize.y = fContentCalculatedHeight; 1315 CXFA_Node* pParaNode = 1316 pLayoutChild->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Para); 1317 if (pParaNode && pLayoutChild->m_pFirstChild) { 1318 FX_FLOAT fOffHeight = fContentCalculatedHeight - fOldChildHeight; 1319 XFA_ATTRIBUTEENUM eVType = pParaNode->GetEnum(XFA_ATTRIBUTE_VAlign); 1320 switch (eVType) { 1321 case XFA_ATTRIBUTEENUM_Middle: 1322 fOffHeight = fOffHeight / 2; 1323 break; 1324 case XFA_ATTRIBUTEENUM_Bottom: 1325 break; 1326 case XFA_ATTRIBUTEENUM_Top: 1327 default: 1328 fOffHeight = 0; 1329 break; 1330 } 1331 if (fOffHeight > 0) { 1332 for (CXFA_ContentLayoutItem* pInnerLayoutChild = 1333 (CXFA_ContentLayoutItem*)pLayoutChild->m_pFirstChild; 1334 pInnerLayoutChild; 1335 pInnerLayoutChild = 1336 (CXFA_ContentLayoutItem*)pInnerLayoutChild->m_pNextSibling) { 1337 pInnerLayoutChild->m_sPos.y += fOffHeight; 1338 } 1339 } 1340 } 1341 } 1342 } 1343 if (bContainerWidthAutoSize) { 1344 FX_FLOAT fChildSuppliedWidth = fCurrentColX; 1345 if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && 1346 fContentWidthLimit > fChildSuppliedWidth) { 1347 fChildSuppliedWidth = fContentWidthLimit; 1348 } 1349 if (fContentCalculatedWidth < fChildSuppliedWidth) { 1350 fContentCalculatedWidth = fChildSuppliedWidth; 1351 } 1352 } else { 1353 fContentCalculatedWidth = fContainerWidth - fLeftInset - fRightInset; 1354 } 1355 if (pLayoutRow->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) == 1356 XFA_ATTRIBUTEENUM_Rl_row) { 1357 for (CXFA_ContentLayoutItem* pLayoutChild = 1358 (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild; 1359 pLayoutChild; 1360 pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) { 1361 pLayoutChild->m_sPos.x = fContentCalculatedWidth - 1362 pLayoutChild->m_sPos.x - pLayoutChild->m_sSize.x; 1363 } 1364 } 1365 XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize( 1366 pLayoutRow->m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, 1367 fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, 1368 fContainerHeight); 1369 pLayoutRow->m_sSize.Set(fContainerWidth, fContainerHeight); 1370 } 1371 void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode) { 1372 if (m_pLayoutItem != NULL) { 1373 return; 1374 } 1375 if (pLayoutNode == NULL) { 1376 pLayoutNode = m_pFormNode; 1377 } 1378 ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE); 1379 m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); 1380 FX_FLOAT fContainerWidth = 0, fContainerHeight = 0; 1381 FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE; 1382 XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize( 1383 m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, 1384 bContainerHeightAutoSize); 1385 FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0; 1386 CXFA_Node* pMarginNode = 1387 m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin); 1388 FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0; 1389 if (pMarginNode) { 1390 fLeftInset = 1391 pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt); 1392 fTopInset = 1393 pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt); 1394 fRightInset = 1395 pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt); 1396 fBottomInset = 1397 pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt); 1398 } 1399 FX_FLOAT fContentWidthLimit = 1400 bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX 1401 : fContainerWidth - fLeftInset - fRightInset; 1402 CFX_WideStringC wsColumnWidths; 1403 if (pLayoutNode->TryCData(XFA_ATTRIBUTE_ColumnWidths, wsColumnWidths)) { 1404 CFX_WideStringArray widths; 1405 if (FX_SeparateStringW(wsColumnWidths.GetPtr(), wsColumnWidths.GetLength(), 1406 L' ', widths) > 0) { 1407 int32_t iCols = widths.GetSize(); 1408 CFX_WideString wsWidth; 1409 for (int32_t i = 0; i < iCols; i++) { 1410 wsWidth = widths[i]; 1411 wsWidth.TrimLeft(L' '); 1412 if (!wsWidth.IsEmpty()) { 1413 CXFA_Measurement measure(wsWidth); 1414 m_rgSpecifiedColumnWidths.Add(measure.ToUnit(XFA_UNIT_Pt)); 1415 } 1416 } 1417 } 1418 } 1419 int32_t iSpecifiedColumnCount = m_rgSpecifiedColumnWidths.GetSize(); 1420 CXFA_LayoutContext layoutContext; 1421 layoutContext.m_prgSpecifiedColumnWidths = &m_rgSpecifiedColumnWidths; 1422 CXFA_LayoutContext* pLayoutContext = 1423 iSpecifiedColumnCount > 0 ? &layoutContext : NULL; 1424 if (m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) { 1425 XFA_ItemLayoutProcessor_GotoNextContainerNode( 1426 m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE); 1427 } 1428 for (; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode( 1429 m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) { 1430 layoutContext.m_bCurColumnWidthAvaiable = FALSE; 1431 layoutContext.m_fCurColumnWidth = 0; 1432 if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) { 1433 continue; 1434 } 1435 CXFA_ItemLayoutProcessor* pProcessor = 1436 new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr); 1437 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_ 1438 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem; 1439 #endif 1440 pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, 1441 pLayoutContext); 1442 if (!pProcessor->HasLayoutItem()) { 1443 delete pProcessor; 1444 continue; 1445 } 1446 m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem()); 1447 delete pProcessor; 1448 } 1449 int32_t iRowCount = 0, iColCount = 0; 1450 { 1451 CFX_ArrayTemplate<CXFA_ContentLayoutItem*> rgRowItems; 1452 CFX_ArrayTemplate<int32_t> rgRowItemsSpan; 1453 CFX_ArrayTemplate<FX_FLOAT> rgRowItemsWidth; 1454 for (CXFA_ContentLayoutItem* pLayoutChild = 1455 (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild; 1456 pLayoutChild; 1457 pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) { 1458 if (pLayoutChild->m_pFormNode->GetClassID() != XFA_ELEMENT_Subform) { 1459 continue; 1460 } 1461 if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) { 1462 continue; 1463 } 1464 XFA_ATTRIBUTEENUM eLayout = 1465 pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); 1466 if (eLayout != XFA_ATTRIBUTEENUM_Row && 1467 eLayout != XFA_ATTRIBUTEENUM_Rl_row) { 1468 continue; 1469 } 1470 if (CXFA_ContentLayoutItem* pRowLayoutCell = 1471 (CXFA_ContentLayoutItem*)pLayoutChild->m_pFirstChild) { 1472 rgRowItems.Add(pRowLayoutCell); 1473 int32_t iColSpan = 1474 pRowLayoutCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan); 1475 rgRowItemsSpan.Add(iColSpan); 1476 rgRowItemsWidth.Add(pRowLayoutCell->m_sSize.x); 1477 } 1478 } 1479 iRowCount = rgRowItems.GetSize(); 1480 iColCount = 0; 1481 FX_BOOL bMoreColumns = TRUE; 1482 while (bMoreColumns) { 1483 bMoreColumns = FALSE; 1484 FX_BOOL bAutoCol = FALSE; 1485 for (int32_t i = 0; i < iRowCount; i++) { 1486 while (rgRowItems[i] != NULL && (rgRowItemsSpan[i] <= 0 || 1487 !XFA_ItemLayoutProcessor_IsTakingSpace( 1488 rgRowItems[i]->m_pFormNode))) { 1489 CXFA_ContentLayoutItem* pNewCell = 1490 (CXFA_ContentLayoutItem*)rgRowItems[i]->m_pNextSibling; 1491 if (rgRowItemsSpan[i] < 0 && XFA_ItemLayoutProcessor_IsTakingSpace( 1492 rgRowItems[i]->m_pFormNode)) { 1493 pNewCell = NULL; 1494 } 1495 rgRowItems[i] = pNewCell; 1496 rgRowItemsSpan[i] = 1497 pNewCell 1498 ? pNewCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan) 1499 : 0; 1500 rgRowItemsWidth[i] = pNewCell ? pNewCell->m_sSize.x : 0; 1501 } 1502 CXFA_ContentLayoutItem* pCell = rgRowItems[i]; 1503 if (!pCell) { 1504 continue; 1505 } 1506 bMoreColumns = TRUE; 1507 if (rgRowItemsSpan[i] == 1) { 1508 if (iColCount >= iSpecifiedColumnCount) { 1509 for (int32_t j = 0, c = iColCount + 1 - 1510 m_rgSpecifiedColumnWidths.GetSize(); 1511 j < c; j++) { 1512 m_rgSpecifiedColumnWidths.Add(0); 1513 } 1514 } 1515 if (m_rgSpecifiedColumnWidths[iColCount] < 1516 XFA_LAYOUT_FLOAT_PERCISION) { 1517 bAutoCol = TRUE; 1518 } 1519 if (bAutoCol && 1520 m_rgSpecifiedColumnWidths[iColCount] < rgRowItemsWidth[i]) { 1521 m_rgSpecifiedColumnWidths[iColCount] = rgRowItemsWidth[i]; 1522 } 1523 } 1524 } 1525 if (bMoreColumns) { 1526 FX_FLOAT fFinalColumnWidth = m_rgSpecifiedColumnWidths[iColCount]; 1527 for (int32_t i = 0; i < iRowCount; i++) { 1528 if (!rgRowItems[i]) { 1529 continue; 1530 } 1531 rgRowItemsSpan[i]--; 1532 rgRowItemsWidth[i] -= fFinalColumnWidth; 1533 } 1534 iColCount++; 1535 } 1536 } 1537 } 1538 FX_FLOAT fCurrentRowY = 0; 1539 for (CXFA_ContentLayoutItem* pLayoutChild = 1540 (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild; 1541 pLayoutChild; 1542 pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) { 1543 if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) { 1544 continue; 1545 } 1546 if (pLayoutChild->m_pFormNode->GetClassID() == XFA_ELEMENT_Subform) { 1547 XFA_ATTRIBUTEENUM eSubformLayout = 1548 pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); 1549 if (eSubformLayout == XFA_ATTRIBUTEENUM_Row || 1550 eSubformLayout == XFA_ATTRIBUTEENUM_Rl_row) { 1551 XFA_ItemLayoutProcessor_RelocateTableRowCells( 1552 pLayoutChild, m_rgSpecifiedColumnWidths, eSubformLayout); 1553 } 1554 } 1555 pLayoutChild->m_sPos.y = fCurrentRowY; 1556 if (bContainerWidthAutoSize) { 1557 pLayoutChild->m_sPos.x = 0; 1558 } else { 1559 switch (pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) { 1560 case XFA_ATTRIBUTEENUM_Left: 1561 default: 1562 pLayoutChild->m_sPos.x = 0; 1563 break; 1564 case XFA_ATTRIBUTEENUM_Center: 1565 pLayoutChild->m_sPos.x = 1566 (fContentWidthLimit - pLayoutChild->m_sSize.x) / 2; 1567 break; 1568 case XFA_ATTRIBUTEENUM_Right: 1569 pLayoutChild->m_sPos.x = fContentWidthLimit - pLayoutChild->m_sSize.x; 1570 break; 1571 } 1572 } 1573 if (bContainerWidthAutoSize) { 1574 FX_FLOAT fChildSuppliedWidth = 1575 pLayoutChild->m_sPos.x + pLayoutChild->m_sSize.x; 1576 if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && 1577 fContentWidthLimit > fChildSuppliedWidth) { 1578 fChildSuppliedWidth = fContentWidthLimit; 1579 } 1580 if (fContentCalculatedWidth < fChildSuppliedWidth) { 1581 fContentCalculatedWidth = fChildSuppliedWidth; 1582 } 1583 } 1584 fCurrentRowY += pLayoutChild->m_sSize.y; 1585 } 1586 if (bContainerHeightAutoSize) { 1587 FX_FLOAT fChildSuppliedHeight = fCurrentRowY; 1588 if (fContentCalculatedHeight < fChildSuppliedHeight) { 1589 fContentCalculatedHeight = fChildSuppliedHeight; 1590 } 1591 } 1592 XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize( 1593 m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, 1594 fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, 1595 fContainerHeight); 1596 SetCurrentComponentSize(fContainerWidth, fContainerHeight); 1597 } 1598 static uint8_t XFA_ItemLayoutProcessor_HAlignEnumToInt( 1599 XFA_ATTRIBUTEENUM eHAlign) { 1600 switch (eHAlign) { 1601 case XFA_ATTRIBUTEENUM_Center: 1602 return 1; 1603 case XFA_ATTRIBUTEENUM_Right: 1604 return 2; 1605 case XFA_ATTRIBUTEENUM_Left: 1606 default: 1607 return 0; 1608 } 1609 } 1610 static void XFA_ItemLayoutProcessor_UpdatePendedItemLayout( 1611 CXFA_ItemLayoutProcessor* pProcessor, 1612 CXFA_ContentLayoutItem* pLayoutItem) { 1613 XFA_ATTRIBUTEENUM eLayout = 1614 pLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); 1615 switch (eLayout) { 1616 case XFA_ATTRIBUTEENUM_Row: 1617 case XFA_ATTRIBUTEENUM_Rl_row: 1618 XFA_ItemLayoutProcessor_RelocateTableRowCells( 1619 pLayoutItem, pProcessor->m_rgSpecifiedColumnWidths, eLayout); 1620 break; 1621 default: 1622 break; 1623 } 1624 } 1625 FX_BOOL CXFA_ItemLayoutProcessor::IsAddNewRowForTrailer( 1626 CXFA_ContentLayoutItem* pTrailerItem) { 1627 if (!pTrailerItem) { 1628 return FALSE; 1629 } 1630 FX_FLOAT fWidth = pTrailerItem->m_sSize.x; 1631 XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); 1632 if (eLayout != XFA_ATTRIBUTEENUM_Tb && m_fWidthLimite > fWidth) { 1633 return FALSE; 1634 } 1635 return TRUE; 1636 } 1637 static void XFA_ItemLayoutProcessor_AddTrailerBeforeSplit( 1638 CXFA_ItemLayoutProcessor* pProcessor, 1639 FX_FLOAT fSplitPos, 1640 CXFA_ContentLayoutItem* pTrailerLayoutItem, 1641 FX_BOOL bUseInherited = FALSE) { 1642 if (!pTrailerLayoutItem) { 1643 return; 1644 } 1645 FX_FLOAT fHeight = pTrailerLayoutItem->m_sSize.y; 1646 if (bUseInherited) { 1647 FX_FLOAT fNewSplitPos = 0; 1648 if (fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) { 1649 fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight); 1650 } 1651 if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) { 1652 pProcessor->SplitLayoutItem(fNewSplitPos); 1653 } 1654 return; 1655 } 1656 XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, 1657 pTrailerLayoutItem); 1658 CXFA_Node* pMarginNode = 1659 pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin); 1660 FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0; 1661 if (pMarginNode) { 1662 fLeftInset = 1663 pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt); 1664 fTopInset = 1665 pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt); 1666 fRightInset = 1667 pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt); 1668 fBottomInset = 1669 pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt); 1670 } 1671 if (!pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem)) { 1672 pTrailerLayoutItem->m_sPos.y = pProcessor->m_fLastRowY; 1673 pTrailerLayoutItem->m_sPos.x = pProcessor->m_fLastRowWidth; 1674 pProcessor->m_pLayoutItem->m_sSize.x += pTrailerLayoutItem->m_sSize.x; 1675 pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem); 1676 return; 1677 } 1678 FX_FLOAT fNewSplitPos = 0; 1679 if (fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) { 1680 fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight); 1681 } 1682 if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) { 1683 pProcessor->SplitLayoutItem(fNewSplitPos); 1684 pTrailerLayoutItem->m_sPos.y = fNewSplitPos - fTopInset - fBottomInset; 1685 } else { 1686 pTrailerLayoutItem->m_sPos.y = fSplitPos - fTopInset - fBottomInset; 1687 } 1688 switch (pTrailerLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) { 1689 case XFA_ATTRIBUTEENUM_Left: 1690 default: 1691 pTrailerLayoutItem->m_sPos.x = fLeftInset; 1692 break; 1693 case XFA_ATTRIBUTEENUM_Right: 1694 pTrailerLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x - 1695 fRightInset - 1696 pTrailerLayoutItem->m_sSize.x; 1697 break; 1698 case XFA_ATTRIBUTEENUM_Center: 1699 pTrailerLayoutItem->m_sPos.x = 1700 (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset - 1701 pTrailerLayoutItem->m_sSize.x) / 1702 2; 1703 break; 1704 } 1705 pProcessor->m_pLayoutItem->m_sSize.y += fHeight; 1706 pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem); 1707 }; 1708 static void XFA_ItemLayoutProcessor_AddLeaderAfterSplit( 1709 CXFA_ItemLayoutProcessor* pProcessor, 1710 CXFA_ContentLayoutItem* pLeaderLayoutItem) { 1711 XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, pLeaderLayoutItem); 1712 CXFA_Node* pMarginNode = 1713 pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin); 1714 FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0; 1715 if (pMarginNode) { 1716 fLeftInset = 1717 pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt); 1718 fTopInset = 1719 pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt); 1720 fRightInset = 1721 pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt); 1722 fBottomInset = 1723 pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt); 1724 } 1725 FX_FLOAT fHeight = pLeaderLayoutItem->m_sSize.y; 1726 for (CXFA_ContentLayoutItem* pChildItem = 1727 (CXFA_ContentLayoutItem*)pProcessor->m_pLayoutItem->m_pFirstChild; 1728 pChildItem; 1729 pChildItem = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) { 1730 pChildItem->m_sPos.y += fHeight; 1731 } 1732 pLeaderLayoutItem->m_sPos.y = 0; 1733 switch (pLeaderLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) { 1734 case XFA_ATTRIBUTEENUM_Left: 1735 default: 1736 pLeaderLayoutItem->m_sPos.x = fLeftInset; 1737 break; 1738 case XFA_ATTRIBUTEENUM_Right: 1739 pLeaderLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x - 1740 fRightInset - pLeaderLayoutItem->m_sSize.x; 1741 break; 1742 case XFA_ATTRIBUTEENUM_Center: 1743 pLeaderLayoutItem->m_sPos.x = 1744 (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset - 1745 pLeaderLayoutItem->m_sSize.x) / 1746 2; 1747 break; 1748 } 1749 pProcessor->m_pLayoutItem->m_sSize.y += fHeight; 1750 pProcessor->m_pLayoutItem->AddChild(pLeaderLayoutItem); 1751 }; 1752 static void XFA_ItemLayoutProcessor_AddPendingNode( 1753 CXFA_ItemLayoutProcessor* pProcessor, 1754 CXFA_Node* pPendingNode, 1755 FX_BOOL bBreakPending) { 1756 pProcessor->m_rgPendingNodes.AddTail(pPendingNode); 1757 pProcessor->m_bBreakPending = bBreakPending; 1758 } 1759 static FX_FLOAT XFA_ItemLayoutProcessor_InsertPendingItems( 1760 CXFA_ItemLayoutProcessor* pProcessor, 1761 CXFA_Node* pCurChildNode) { 1762 FX_FLOAT fTotalHeight = 0; 1763 if (pProcessor->m_rgPendingNodes.GetCount() < 1) { 1764 return fTotalHeight; 1765 } 1766 if (pProcessor->m_pLayoutItem == NULL) { 1767 pProcessor->m_pLayoutItem = 1768 pProcessor->CreateContentLayoutItem(pCurChildNode); 1769 pProcessor->m_pLayoutItem->m_sSize.Set(0, 0); 1770 } 1771 while (pProcessor->m_rgPendingNodes.GetCount() > 0) { 1772 FX_POSITION pos = pProcessor->m_rgPendingNodes.GetHeadPosition(); 1773 CXFA_Node* pPendingNode = 1774 (CXFA_Node*)pProcessor->m_rgPendingNodes.GetAt(pos); 1775 pProcessor->m_rgPendingNodes.RemoveAt(pos); 1776 CXFA_ContentLayoutItem* pPendingLayoutItem = NULL; 1777 CXFA_ItemLayoutProcessor* pPendingProcessor = 1778 new CXFA_ItemLayoutProcessor(pPendingNode, NULL); 1779 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_ 1780 pPendingProcessor->m_pPageMgrCreateItem = pProcessor->m_pPageMgrCreateItem; 1781 #endif 1782 pPendingProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX); 1783 pPendingLayoutItem = pPendingProcessor->HasLayoutItem() 1784 ? pPendingProcessor->ExtractLayoutItem() 1785 : NULL; 1786 delete pPendingProcessor; 1787 if (pPendingLayoutItem) { 1788 XFA_ItemLayoutProcessor_AddLeaderAfterSplit(pProcessor, 1789 pPendingLayoutItem); 1790 if (pProcessor->m_bBreakPending) { 1791 fTotalHeight += pPendingLayoutItem->m_sSize.y; 1792 } 1793 } 1794 } 1795 return fTotalHeight; 1796 } 1797 FX_FLOAT CXFA_ItemLayoutProcessor::InsertKeepLayoutItems() { 1798 FX_FLOAT fTotalHeight = 0; 1799 if (m_arrayKeepItems.GetSize()) { 1800 if (m_pLayoutItem == NULL) { 1801 m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); 1802 m_pLayoutItem->m_sSize.Set(0, 0); 1803 } 1804 for (int32_t iIndex = m_arrayKeepItems.GetSize() - 1; iIndex >= 0; 1805 iIndex--) { 1806 XFA_ItemLayoutProcessor_AddLeaderAfterSplit(this, 1807 m_arrayKeepItems[iIndex]); 1808 fTotalHeight += m_arrayKeepItems[iIndex]->m_sSize.y; 1809 } 1810 m_arrayKeepItems.RemoveAll(); 1811 } 1812 return fTotalHeight; 1813 } 1814 FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepForSplite( 1815 CXFA_ItemLayoutProcessor* pParentProcessor, 1816 CXFA_ItemLayoutProcessor* pChildProcessor, 1817 XFA_ItemLayoutProcessorResult eRetValue, 1818 CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& rgCurLineLayoutItem, 1819 FX_FLOAT& fContentCurRowAvailWidth, 1820 FX_FLOAT& fContentCurRowHeight, 1821 FX_FLOAT& fContentCurRowY, 1822 FX_BOOL& bAddedItemInRow, 1823 FX_BOOL& bForceEndPage, 1824 XFA_ItemLayoutProcessorResult& result) { 1825 if (pParentProcessor == NULL || pChildProcessor == NULL) { 1826 return FALSE; 1827 } 1828 if (pParentProcessor->m_pCurChildNode->GetIntact() != 1829 XFA_ATTRIBUTEENUM_None || 1830 !pChildProcessor->m_bHasAvailHeight) { 1831 if (XFA_ExistContainerKeep(pParentProcessor->m_pCurChildNode, TRUE)) { 1832 FX_FLOAT fChildWidth, fChildHeight; 1833 pChildProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight); 1834 CFX_ArrayTemplate<CXFA_ContentLayoutItem*> keepLayoutItems; 1835 if (pParentProcessor->JudgePutNextPage(pParentProcessor->m_pLayoutItem, 1836 fChildHeight, keepLayoutItems)) { 1837 m_arrayKeepItems.RemoveAll(); 1838 for (int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize(); iIndex++) { 1839 CXFA_ContentLayoutItem* pItem = keepLayoutItems.GetAt(iIndex); 1840 pParentProcessor->m_pLayoutItem->RemoveChild(pItem); 1841 fContentCurRowY -= pItem->m_sSize.y; 1842 m_arrayKeepItems.Add(pItem); 1843 } 1844 bAddedItemInRow = TRUE; 1845 bForceEndPage = TRUE; 1846 result = XFA_ItemLayoutProcessorResult_PageFullBreak; 1847 return TRUE; 1848 } 1849 rgCurLineLayoutItem.Add(pChildProcessor->ExtractLayoutItem()); 1850 bAddedItemInRow = TRUE; 1851 fContentCurRowAvailWidth -= fChildWidth; 1852 if (fContentCurRowHeight < fChildHeight) { 1853 fContentCurRowHeight = fChildHeight; 1854 } 1855 result = eRetValue; 1856 return TRUE; 1857 } 1858 } 1859 return FALSE; 1860 } 1861 FX_BOOL CXFA_ItemLayoutProcessor::JudgePutNextPage( 1862 CXFA_ContentLayoutItem* pParentLayoutItem, 1863 FX_FLOAT fChildHeight, 1864 CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& pKeepItems) { 1865 if (pParentLayoutItem == NULL) { 1866 return FALSE; 1867 } 1868 FX_FLOAT fItemsHeight = 0; 1869 for (CXFA_ContentLayoutItem* pChildLayoutItem = 1870 (CXFA_ContentLayoutItem*)pParentLayoutItem->m_pFirstChild; 1871 pChildLayoutItem; 1872 pChildLayoutItem = 1873 (CXFA_ContentLayoutItem*)pChildLayoutItem->m_pNextSibling) { 1874 if (XFA_ExistContainerKeep(pChildLayoutItem->m_pFormNode, FALSE)) { 1875 pKeepItems.Add(pChildLayoutItem); 1876 fItemsHeight += pChildLayoutItem->m_sSize.y; 1877 } else { 1878 pKeepItems.RemoveAll(); 1879 fItemsHeight = 0; 1880 } 1881 } 1882 fItemsHeight += fChildHeight; 1883 if (m_pPageMgr->GetNextAvailContentHeight(fItemsHeight)) { 1884 return TRUE; 1885 } 1886 return FALSE; 1887 } 1888 void CXFA_ItemLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode) { 1889 if (!pFormNode) { 1890 return; 1891 } 1892 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator( 1893 pFormNode); 1894 for (CXFA_Node* pNode = sIterator.MoveToNext(); pNode; 1895 pNode = sIterator.MoveToNext()) { 1896 if (pNode->IsContainerNode()) { 1897 CXFA_Node* pBindNode = pNode->GetBindData(); 1898 if (pBindNode) { 1899 pBindNode->RemoveBindItem(pNode); 1900 pNode->SetObject(XFA_ATTRIBUTE_BindingNode, NULL); 1901 } 1902 } 1903 pNode->SetFlag(XFA_NODEFLAG_UnusedNode); 1904 } 1905 } 1906 void CXFA_ItemLayoutProcessor::ProcessUnUseOverFlow( 1907 CXFA_Node* pLeaderNode, 1908 CXFA_Node* pTrailerNode, 1909 CXFA_ContentLayoutItem* pTrailerItem, 1910 CXFA_Node* pFormNode) { 1911 ProcessUnUseBinds(pLeaderNode); 1912 ProcessUnUseBinds(pTrailerNode); 1913 if (pFormNode == NULL) { 1914 return; 1915 } 1916 if (pFormNode->GetClassID() == XFA_ELEMENT_Overflow || 1917 pFormNode->GetClassID() == XFA_ELEMENT_Break) { 1918 pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent); 1919 } 1920 if (pLeaderNode && pFormNode) { 1921 pFormNode->RemoveChild(pLeaderNode); 1922 } 1923 if (pTrailerNode && pFormNode) { 1924 pFormNode->RemoveChild(pTrailerNode); 1925 } 1926 if (pTrailerItem) { 1927 XFA_ReleaseLayoutItem(pTrailerItem); 1928 } 1929 } 1930 static XFA_ItemLayoutProcessorResult XFA_ItemLayoutProcessor_InsertFlowedItem( 1931 CXFA_ItemLayoutProcessor* pThis, 1932 CXFA_ItemLayoutProcessor*& pProcessor, 1933 FX_BOOL bContainerWidthAutoSize, 1934 FX_BOOL bContainerHeightAutoSize, 1935 FX_FLOAT fContainerHeight, 1936 XFA_ATTRIBUTEENUM eFlowStrategy, 1937 uint8_t& uCurHAlignState, 1938 CFX_ArrayTemplate<CXFA_ContentLayoutItem*>(&rgCurLineLayoutItems)[3], 1939 FX_BOOL bUseBreakControl, 1940 FX_FLOAT fAvailHeight, 1941 FX_FLOAT fRealHeight, 1942 FX_FLOAT& fContentCurRowY, 1943 FX_FLOAT& fContentWidthLimit, 1944 FX_FLOAT& fContentCurRowAvailWidth, 1945 FX_FLOAT& fContentCurRowHeight, 1946 FX_BOOL& bAddedItemInRow, 1947 FX_BOOL& bForceEndPage, 1948 CXFA_LayoutContext* pLayoutContext = NULL, 1949 FX_BOOL bNewRow = FALSE) { 1950 FX_BOOL bTakeSpace = 1951 XFA_ItemLayoutProcessor_IsTakingSpace(pProcessor->m_pFormNode); 1952 uint8_t uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt( 1953 pThis->m_pCurChildNode->GetEnum(XFA_ATTRIBUTE_HAlign)); 1954 if (bContainerWidthAutoSize) { 1955 uHAlign = 0; 1956 } 1957 if ((eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb && uHAlign < uCurHAlignState) || 1958 (eFlowStrategy == XFA_ATTRIBUTEENUM_Rl_tb && uHAlign > uCurHAlignState)) { 1959 return XFA_ItemLayoutProcessorResult_RowFullBreak; 1960 } 1961 uCurHAlignState = uHAlign; 1962 FX_BOOL bIsOwnSplite = 1963 pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None; 1964 FX_BOOL bUseRealHeight = 1965 bTakeSpace && bContainerHeightAutoSize && bIsOwnSplite && 1966 pProcessor->m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetIntact() == 1967 XFA_ATTRIBUTEENUM_None; 1968 FX_BOOL bIsTransHeight = bTakeSpace; 1969 if (bIsTransHeight && !bIsOwnSplite) { 1970 FX_BOOL bRootForceTb = FALSE; 1971 XFA_ATTRIBUTEENUM eLayoutStrategy = XFA_ItemLayoutProcessor_GetLayout( 1972 pProcessor->m_pFormNode, bRootForceTb); 1973 if (eLayoutStrategy == XFA_ATTRIBUTEENUM_Lr_tb || 1974 eLayoutStrategy == XFA_ATTRIBUTEENUM_Rl_tb) { 1975 bIsTransHeight = FALSE; 1976 } 1977 } 1978 FX_BOOL bUseInherited = FALSE; 1979 CXFA_LayoutContext layoutContext; 1980 if (pThis->m_pPageMgr) { 1981 CXFA_Node* pOverflowNode = 1982 pThis->m_pPageMgr->QueryOverflow(pThis->m_pFormNode); 1983 if (pOverflowNode) { 1984 layoutContext.m_pOverflowNode = pOverflowNode; 1985 layoutContext.m_pOverflowProcessor = pThis; 1986 pLayoutContext = &layoutContext; 1987 } 1988 } 1989 XFA_ItemLayoutProcessorResult eRetValue = XFA_ItemLayoutProcessorResult_Done; 1990 if (!bNewRow || 1991 pProcessor->m_ePreProcessRs == XFA_ItemLayoutProcessorResult_Done) { 1992 eRetValue = pProcessor->DoLayout( 1993 bTakeSpace ? bUseBreakControl : FALSE, 1994 bUseRealHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX, 1995 bIsTransHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX, 1996 pLayoutContext); 1997 pProcessor->m_ePreProcessRs = eRetValue; 1998 } else { 1999 eRetValue = pProcessor->m_ePreProcessRs; 2000 pProcessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult_Done; 2001 } 2002 if (pProcessor->HasLayoutItem() == FALSE) { 2003 return eRetValue; 2004 } 2005 FX_FLOAT fChildWidth, fChildHeight; 2006 pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight); 2007 if (bUseRealHeight && fRealHeight < XFA_LAYOUT_FLOAT_PERCISION) { 2008 fRealHeight = XFA_LAYOUT_FLOAT_MAX; 2009 fAvailHeight = XFA_LAYOUT_FLOAT_MAX; 2010 } 2011 if (!bTakeSpace || 2012 (fChildWidth <= fContentCurRowAvailWidth + XFA_LAYOUT_FLOAT_PERCISION) || 2013 (fContentWidthLimit - fContentCurRowAvailWidth <= 2014 XFA_LAYOUT_FLOAT_PERCISION)) { 2015 CXFA_Node *pOverflowLeaderNode = NULL, *pOverflowTrailerNode = NULL, 2016 *pFormNode = NULL; 2017 CXFA_ContentLayoutItem* pTrailerLayoutItem = NULL; 2018 FX_BOOL bIsAddTrailerHeight = FALSE; 2019 if (pThis->m_pPageMgr && 2020 pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) { 2021 pFormNode = pThis->m_pPageMgr->QueryOverflow(pProcessor->m_pFormNode); 2022 if (pFormNode == NULL && pLayoutContext && 2023 pLayoutContext->m_pOverflowProcessor) { 2024 pFormNode = pLayoutContext->m_pOverflowNode; 2025 bUseInherited = TRUE; 2026 } 2027 if (pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, 2028 pOverflowTrailerNode, FALSE, 2029 FALSE)) { 2030 if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowTrailerNode)) { 2031 if (pOverflowTrailerNode) { 2032 CXFA_ItemLayoutProcessor* pOverflowLeaderProcessor = 2033 new CXFA_ItemLayoutProcessor(pOverflowTrailerNode, NULL); 2034 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_ 2035 pOverflowLeaderProcessor->m_pPageMgrCreateItem = 2036 pProcessor->m_pPageMgrCreateItem; 2037 #endif 2038 pOverflowLeaderProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX); 2039 pTrailerLayoutItem = 2040 pOverflowLeaderProcessor->HasLayoutItem() 2041 ? pOverflowLeaderProcessor->ExtractLayoutItem() 2042 : NULL; 2043 delete pOverflowLeaderProcessor; 2044 } 2045 if (bUseInherited) { 2046 bIsAddTrailerHeight = 2047 pThis->IsAddNewRowForTrailer(pTrailerLayoutItem); 2048 } else { 2049 bIsAddTrailerHeight = 2050 pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem); 2051 } 2052 if (bIsAddTrailerHeight) { 2053 FX_FLOAT fTrailerHeight = pTrailerLayoutItem->m_sSize.y; 2054 fChildHeight += fTrailerHeight; 2055 bIsAddTrailerHeight = TRUE; 2056 } 2057 } 2058 } 2059 } 2060 if (!bTakeSpace || 2061 fContentCurRowY + fChildHeight <= 2062 fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION || 2063 (!bContainerHeightAutoSize && 2064 pThis->m_fUsedSize + fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION >= 2065 fContainerHeight)) { 2066 if (!bTakeSpace || eRetValue == XFA_ItemLayoutProcessorResult_Done) { 2067 if (pProcessor->m_bUseInheriated) { 2068 if (pTrailerLayoutItem) { 2069 XFA_ItemLayoutProcessor_AddTrailerBeforeSplit( 2070 pProcessor, fChildHeight, pTrailerLayoutItem); 2071 } 2072 if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) { 2073 XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, 2074 pOverflowLeaderNode, FALSE); 2075 } 2076 pProcessor->m_bUseInheriated = FALSE; 2077 } else { 2078 if (bIsAddTrailerHeight) { 2079 fChildHeight -= pTrailerLayoutItem->m_sSize.y; 2080 } 2081 pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, 2082 pOverflowTrailerNode, 2083 pTrailerLayoutItem, pFormNode); 2084 } 2085 CXFA_ContentLayoutItem* pChildLayoutItem = 2086 pProcessor->ExtractLayoutItem(); 2087 if (XFA_ExistContainerKeep(pProcessor->m_pFormNode, FALSE) && 2088 pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) { 2089 pThis->m_arrayKeepItems.Add(pChildLayoutItem); 2090 } else { 2091 pThis->m_arrayKeepItems.RemoveAll(); 2092 } 2093 rgCurLineLayoutItems[uHAlign].Add(pChildLayoutItem); 2094 bAddedItemInRow = TRUE; 2095 if (bTakeSpace) { 2096 fContentCurRowAvailWidth -= fChildWidth; 2097 if (fContentCurRowHeight < fChildHeight) { 2098 fContentCurRowHeight = fChildHeight; 2099 } 2100 } 2101 return XFA_ItemLayoutProcessorResult_Done; 2102 } else { 2103 if (eRetValue == XFA_ItemLayoutProcessorResult_PageFullBreak) { 2104 if (pProcessor->m_bUseInheriated) { 2105 if (pTrailerLayoutItem) { 2106 XFA_ItemLayoutProcessor_AddTrailerBeforeSplit( 2107 pProcessor, fChildHeight, pTrailerLayoutItem); 2108 } 2109 if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) { 2110 XFA_ItemLayoutProcessor_AddPendingNode( 2111 pProcessor, pOverflowLeaderNode, FALSE); 2112 } 2113 pProcessor->m_bUseInheriated = FALSE; 2114 } else { 2115 if (bIsAddTrailerHeight) { 2116 fChildHeight -= pTrailerLayoutItem->m_sSize.y; 2117 } 2118 pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, 2119 pOverflowTrailerNode, 2120 pTrailerLayoutItem, pFormNode); 2121 } 2122 } 2123 rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem()); 2124 bAddedItemInRow = TRUE; 2125 fContentCurRowAvailWidth -= fChildWidth; 2126 if (fContentCurRowHeight < fChildHeight) { 2127 fContentCurRowHeight = fChildHeight; 2128 } 2129 return eRetValue; 2130 } 2131 } else { 2132 XFA_ItemLayoutProcessorResult eResult; 2133 if (pThis->ProcessKeepForSplite( 2134 pThis, pProcessor, eRetValue, rgCurLineLayoutItems[uHAlign], 2135 fContentCurRowAvailWidth, fContentCurRowHeight, fContentCurRowY, 2136 bAddedItemInRow, bForceEndPage, eResult)) { 2137 return eResult; 2138 } 2139 bForceEndPage = TRUE; 2140 FX_FLOAT fSplitPos = 2141 pProcessor->FindSplitPos(fAvailHeight - fContentCurRowY); 2142 if (fSplitPos > XFA_LAYOUT_FLOAT_PERCISION) { 2143 XFA_ATTRIBUTEENUM eLayout = 2144 pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); 2145 if (eLayout == XFA_ATTRIBUTEENUM_Tb && 2146 eRetValue == XFA_ItemLayoutProcessorResult_Done) { 2147 pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, 2148 pOverflowTrailerNode, 2149 pTrailerLayoutItem, pFormNode); 2150 rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem()); 2151 bAddedItemInRow = TRUE; 2152 if (bTakeSpace) { 2153 fContentCurRowAvailWidth -= fChildWidth; 2154 if (fContentCurRowHeight < fChildHeight) { 2155 fContentCurRowHeight = fChildHeight; 2156 } 2157 } 2158 return XFA_ItemLayoutProcessorResult_PageFullBreak; 2159 } 2160 CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL; 2161 if (pThis->m_pPageMgr && !pProcessor->m_bUseInheriated && 2162 eRetValue != XFA_ItemLayoutProcessorResult_PageFullBreak) { 2163 pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode, 2164 pTempTrailerNode, FALSE, TRUE); 2165 } 2166 if (pTrailerLayoutItem && bIsAddTrailerHeight) { 2167 XFA_ItemLayoutProcessor_AddTrailerBeforeSplit( 2168 pProcessor, fSplitPos, pTrailerLayoutItem, bUseInherited); 2169 } else { 2170 pProcessor->SplitLayoutItem(fSplitPos); 2171 } 2172 if (bUseInherited) { 2173 pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, 2174 pOverflowTrailerNode, 2175 pTrailerLayoutItem, pFormNode); 2176 pThis->m_bUseInheriated = TRUE; 2177 } else { 2178 if (pProcessor->m_pLayoutItem->m_pFirstChild && 2179 pProcessor->m_pLayoutItem->m_pFirstChild->m_pNextSibling == 2180 NULL && 2181 pProcessor->m_pLayoutItem->m_pFirstChild->m_pFormNode->HasFlag( 2182 XFA_NODEFLAG_LayoutGeneratedNode)) { 2183 pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, 2184 pOverflowTrailerNode, 2185 pTrailerLayoutItem, pFormNode); 2186 } else { 2187 if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) { 2188 XFA_ItemLayoutProcessor_AddPendingNode( 2189 pProcessor, pOverflowLeaderNode, FALSE); 2190 } 2191 } 2192 } 2193 if (pProcessor->m_pLayoutItem->m_pNextSibling) { 2194 pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight); 2195 rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem()); 2196 bAddedItemInRow = TRUE; 2197 if (bTakeSpace) { 2198 fContentCurRowAvailWidth -= fChildWidth; 2199 if (fContentCurRowHeight < fChildHeight) { 2200 fContentCurRowHeight = fChildHeight; 2201 } 2202 } 2203 } 2204 return XFA_ItemLayoutProcessorResult_PageFullBreak; 2205 } else if (fContentCurRowY <= XFA_LAYOUT_FLOAT_PERCISION) { 2206 pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight); 2207 if (pProcessor->m_pPageMgr->GetNextAvailContentHeight(fChildHeight)) { 2208 CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL; 2209 if (pThis->m_pPageMgr) { 2210 if (pFormNode == NULL && pLayoutContext != NULL) { 2211 pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode; 2212 } 2213 pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode, 2214 pTempTrailerNode, FALSE, TRUE); 2215 } 2216 if (bUseInherited) { 2217 pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, 2218 pOverflowTrailerNode, 2219 pTrailerLayoutItem, pFormNode); 2220 pThis->m_bUseInheriated = TRUE; 2221 } 2222 return XFA_ItemLayoutProcessorResult_PageFullBreak; 2223 } 2224 rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem()); 2225 bAddedItemInRow = TRUE; 2226 if (bTakeSpace) { 2227 fContentCurRowAvailWidth -= fChildWidth; 2228 if (fContentCurRowHeight < fChildHeight) { 2229 fContentCurRowHeight = fChildHeight; 2230 } 2231 } 2232 if (eRetValue == XFA_ItemLayoutProcessorResult_Done) { 2233 bForceEndPage = FALSE; 2234 } 2235 return eRetValue; 2236 } else { 2237 XFA_ATTRIBUTEENUM eLayout = 2238 pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); 2239 if (pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None && 2240 eLayout == XFA_ATTRIBUTEENUM_Tb) { 2241 if (pThis->m_pPageMgr) { 2242 pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, 2243 pOverflowTrailerNode, FALSE, 2244 TRUE); 2245 } 2246 if (pTrailerLayoutItem) { 2247 XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fSplitPos, 2248 pTrailerLayoutItem); 2249 } 2250 if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) { 2251 XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, 2252 pOverflowLeaderNode, FALSE); 2253 } 2254 } else { 2255 if (eRetValue == XFA_ItemLayoutProcessorResult_Done) { 2256 if (pFormNode == NULL && pLayoutContext != NULL) { 2257 pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode; 2258 } 2259 if (pThis->m_pPageMgr) { 2260 pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, 2261 pOverflowTrailerNode, FALSE, 2262 TRUE); 2263 } 2264 if (bUseInherited) { 2265 pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, 2266 pOverflowTrailerNode, 2267 pTrailerLayoutItem, pFormNode); 2268 pThis->m_bUseInheriated = TRUE; 2269 } 2270 } 2271 } 2272 return XFA_ItemLayoutProcessorResult_PageFullBreak; 2273 } 2274 } 2275 } else { 2276 return XFA_ItemLayoutProcessorResult_RowFullBreak; 2277 } 2278 return XFA_ItemLayoutProcessorResult_Done; 2279 } 2280 XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer( 2281 FX_BOOL bUseBreakControl, 2282 XFA_ATTRIBUTEENUM eFlowStrategy, 2283 FX_FLOAT fHeightLimit, 2284 FX_FLOAT fRealHeight, 2285 CXFA_LayoutContext* pContext, 2286 FX_BOOL bRootForceTb) { 2287 m_bHasAvailHeight = TRUE; 2288 FX_FLOAT fContainerWidth = 0, fContainerHeight = 0; 2289 FX_BOOL bBreakDone = FALSE; 2290 FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE; 2291 FX_BOOL bForceEndPage = FALSE; 2292 FX_BOOL bIsManualBreak = FALSE; 2293 if (m_pCurChildPreprocessor) { 2294 m_pCurChildPreprocessor->m_ePreProcessRs = 2295 XFA_ItemLayoutProcessorResult_Done; 2296 } 2297 XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize( 2298 m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, 2299 bContainerHeightAutoSize); 2300 if (pContext && pContext->m_bCurColumnWidthAvaiable) { 2301 bContainerWidthAutoSize = FALSE; 2302 fContainerWidth = pContext->m_fCurColumnWidth; 2303 } 2304 if (!bContainerHeightAutoSize) { 2305 fContainerHeight -= m_fUsedSize; 2306 } 2307 if (!bContainerHeightAutoSize) { 2308 CXFA_Node* pParentNode = m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent); 2309 FX_BOOL bFocrTb = FALSE; 2310 if (pParentNode && 2311 XFA_ItemLayoutProcessor_GetLayout(pParentNode, bFocrTb) == 2312 XFA_ATTRIBUTEENUM_Row) { 2313 CXFA_Node* pChildContainer = m_pFormNode->GetNodeItem( 2314 XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode); 2315 if (pChildContainer && 2316 pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling, 2317 XFA_OBJECTTYPE_ContainerNode)) { 2318 fContainerHeight = 0; 2319 bContainerHeightAutoSize = TRUE; 2320 } 2321 } 2322 } 2323 CXFA_Node* pMarginNode = 2324 m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin); 2325 FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0; 2326 if (pMarginNode) { 2327 fLeftInset = 2328 pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt); 2329 fTopInset = 2330 pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt); 2331 fRightInset = 2332 pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt); 2333 fBottomInset = 2334 pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt); 2335 } 2336 FX_FLOAT fContentWidthLimit = 2337 bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX 2338 : fContainerWidth - fLeftInset - fRightInset; 2339 FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0; 2340 FX_FLOAT fAvailHeight = fHeightLimit - fTopInset - fBottomInset; 2341 if (fAvailHeight < 0) { 2342 m_bHasAvailHeight = FALSE; 2343 } 2344 fRealHeight = fRealHeight - fTopInset - fBottomInset; 2345 FX_FLOAT fContentCurRowY = 0; 2346 CXFA_ContentLayoutItem* pLayoutChild = NULL; 2347 if (m_pLayoutItem != NULL) { 2348 if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done && 2349 eFlowStrategy != XFA_ATTRIBUTEENUM_Tb) { 2350 pLayoutChild = (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild; 2351 for (CXFA_ContentLayoutItem* pLayoutNext = pLayoutChild; pLayoutNext; 2352 pLayoutNext = (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) { 2353 if (pLayoutNext->m_sPos.y != pLayoutChild->m_sPos.y) { 2354 pLayoutChild = pLayoutNext; 2355 } 2356 } 2357 } 2358 for (CXFA_ContentLayoutItem* pLayoutTempChild = 2359 (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild; 2360 pLayoutTempChild != pLayoutChild; 2361 pLayoutTempChild = 2362 (CXFA_ContentLayoutItem*)pLayoutTempChild->m_pNextSibling) { 2363 if (XFA_ItemLayoutProcessor_IsTakingSpace( 2364 pLayoutTempChild->m_pFormNode)) { 2365 FX_FLOAT fChildContentWidth = 2366 pLayoutTempChild->m_sPos.x + pLayoutTempChild->m_sSize.x; 2367 FX_FLOAT fChildContentHeight = 2368 pLayoutTempChild->m_sPos.y + pLayoutTempChild->m_sSize.y; 2369 if (fContentCalculatedWidth < fChildContentWidth) { 2370 fContentCalculatedWidth = fChildContentWidth; 2371 } 2372 if (fContentCalculatedHeight < fChildContentHeight) { 2373 fContentCalculatedHeight = fChildContentHeight; 2374 } 2375 } 2376 } 2377 if (pLayoutChild) { 2378 fContentCurRowY = pLayoutChild->m_sPos.y; 2379 } else { 2380 fContentCurRowY = fContentCalculatedHeight; 2381 } 2382 } 2383 fContentCurRowY += InsertKeepLayoutItems(); 2384 if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_None) { 2385 XFA_ItemLayoutProcessor_GotoNextContainerNode( 2386 m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE); 2387 } 2388 fContentCurRowY += 2389 XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode); 2390 if (m_pCurChildPreprocessor && 2391 m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Container) { 2392 if (XFA_ExistContainerKeep(m_pCurChildPreprocessor->GetFormNode(), FALSE)) { 2393 m_pKeepHeadNode = m_pCurChildNode; 2394 m_bIsProcessKeep = TRUE; 2395 m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Keep; 2396 } 2397 } 2398 while (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done) { 2399 FX_FLOAT fContentCurRowHeight = 0; 2400 FX_FLOAT fContentCurRowAvailWidth = fContentWidthLimit; 2401 m_fWidthLimite = fContentCurRowAvailWidth; 2402 CFX_ArrayTemplate<CXFA_ContentLayoutItem*> rgCurLineLayoutItems[3]; 2403 uint8_t uCurHAlignState = 2404 (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb ? 0 : 2); 2405 if (pLayoutChild) { 2406 for (CXFA_ContentLayoutItem* pLayoutNext = pLayoutChild; pLayoutNext; 2407 pLayoutNext = (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) { 2408 if (pLayoutNext->m_pNextSibling == NULL && m_pCurChildPreprocessor && 2409 m_pCurChildPreprocessor->m_pFormNode == pLayoutNext->m_pFormNode) { 2410 pLayoutNext->m_pNext = m_pCurChildPreprocessor->m_pLayoutItem; 2411 m_pCurChildPreprocessor->m_pLayoutItem = pLayoutNext; 2412 break; 2413 } 2414 uint8_t uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt( 2415 pLayoutNext->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)); 2416 rgCurLineLayoutItems[uHAlign].Add(pLayoutNext); 2417 if (eFlowStrategy == XFA_ATTRIBUTEENUM_Lr_tb) { 2418 if (uHAlign > uCurHAlignState) { 2419 uCurHAlignState = uHAlign; 2420 } 2421 } else if (uHAlign < uCurHAlignState) { 2422 uCurHAlignState = uHAlign; 2423 } 2424 if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutNext->m_pFormNode)) { 2425 if (pLayoutNext->m_sSize.y > fContentCurRowHeight) { 2426 fContentCurRowHeight = pLayoutNext->m_sSize.y; 2427 } 2428 fContentCurRowAvailWidth -= pLayoutNext->m_sSize.x; 2429 } 2430 } 2431 if ((CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild == 2432 pLayoutChild) { 2433 m_pLayoutItem->m_pFirstChild = NULL; 2434 } else { 2435 CXFA_ContentLayoutItem* pLayoutNext = 2436 (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild; 2437 for (; pLayoutNext; 2438 pLayoutNext = 2439 (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) { 2440 if ((CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling == 2441 pLayoutChild) { 2442 pLayoutNext->m_pNextSibling = NULL; 2443 break; 2444 } 2445 } 2446 } 2447 CXFA_ContentLayoutItem* pLayoutNextTemp = 2448 (CXFA_ContentLayoutItem*)pLayoutChild; 2449 while (pLayoutNextTemp) { 2450 pLayoutNextTemp->m_pParent = NULL; 2451 CXFA_ContentLayoutItem* pSaveLayoutNext = 2452 (CXFA_ContentLayoutItem*)pLayoutNextTemp->m_pNextSibling; 2453 pLayoutNextTemp->m_pNextSibling = NULL; 2454 pLayoutNextTemp = pSaveLayoutNext; 2455 } 2456 pLayoutChild = NULL; 2457 } 2458 while (m_pCurChildNode) { 2459 CXFA_ItemLayoutProcessor* pProcessor = NULL; 2460 FX_BOOL bAddedItemInRow = FALSE; 2461 fContentCurRowY += 2462 XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode); 2463 switch (m_nCurChildNodeStage) { 2464 case XFA_ItemLayoutProcessorStages_Keep: 2465 case XFA_ItemLayoutProcessorStages_None: 2466 break; 2467 case XFA_ItemLayoutProcessorStages_BreakBefore: { 2468 for (int32_t iIndex = 0; iIndex < m_arrayKeepItems.GetSize(); 2469 iIndex++) { 2470 CXFA_ContentLayoutItem* pItem = m_arrayKeepItems.GetAt(iIndex); 2471 m_pLayoutItem->RemoveChild(pItem); 2472 fContentCalculatedHeight -= pItem->m_sSize.y; 2473 } 2474 CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL; 2475 FX_BOOL bCreatePage = FALSE; 2476 if (bUseBreakControl && m_pPageMgr && 2477 m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, TRUE, 2478 pLeaderNode, pTrailerNode, 2479 bCreatePage) && 2480 m_pFormNode->GetClassID() != XFA_ELEMENT_Form && bCreatePage) { 2481 if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) { 2482 XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE); 2483 } 2484 if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) { 2485 if (m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetClassID() == 2486 XFA_ELEMENT_Form && 2487 m_pLayoutItem == NULL) { 2488 XFA_ItemLayoutProcessor_AddPendingNode(this, pTrailerNode, 2489 TRUE); 2490 } else { 2491 CXFA_ItemLayoutProcessor* pProcessor = 2492 new CXFA_ItemLayoutProcessor(pTrailerNode, NULL); 2493 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_ 2494 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem; 2495 #endif 2496 XFA_ItemLayoutProcessor_InsertFlowedItem( 2497 this, pProcessor, bContainerWidthAutoSize, 2498 bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, 2499 uCurHAlignState, rgCurLineLayoutItems, FALSE, 2500 XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, 2501 fContentWidthLimit, fContentCurRowAvailWidth, 2502 fContentCurRowHeight, bAddedItemInRow, bForceEndPage, 2503 pContext); 2504 delete pProcessor; 2505 pProcessor = NULL; 2506 } 2507 } 2508 XFA_ItemLayoutProcessor_GotoNextContainerNode( 2509 m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE); 2510 bForceEndPage = TRUE; 2511 bIsManualBreak = TRUE; 2512 goto SuspendAndCreateNewRow; 2513 } 2514 } break; 2515 case XFA_ItemLayoutProcessorStages_BreakAfter: { 2516 XFA_ItemLayoutProcessorResult eResult; 2517 CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL; 2518 FX_BOOL bCreatePage = FALSE; 2519 if (bUseBreakControl && m_pPageMgr && 2520 m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, FALSE, 2521 pLeaderNode, pTrailerNode, 2522 bCreatePage) && 2523 m_pFormNode->GetClassID() != XFA_ELEMENT_Form) { 2524 if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) { 2525 CXFA_ItemLayoutProcessor* pProcessor = 2526 new CXFA_ItemLayoutProcessor(pTrailerNode, NULL); 2527 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_ 2528 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem; 2529 #endif 2530 eResult = XFA_ItemLayoutProcessor_InsertFlowedItem( 2531 this, pProcessor, bContainerWidthAutoSize, 2532 bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, 2533 uCurHAlignState, rgCurLineLayoutItems, FALSE, 2534 XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, 2535 fContentWidthLimit, fContentCurRowAvailWidth, 2536 fContentCurRowHeight, bAddedItemInRow, bForceEndPage, 2537 pContext); 2538 delete pProcessor; 2539 pProcessor = NULL; 2540 } 2541 if (!bCreatePage) { 2542 if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) { 2543 CalculateRowChildPosition( 2544 rgCurLineLayoutItems, eFlowStrategy, 2545 bContainerHeightAutoSize, bContainerWidthAutoSize, 2546 fContentCalculatedWidth, fContentCalculatedHeight, 2547 fContentCurRowY, fContentCurRowHeight, fContentWidthLimit); 2548 rgCurLineLayoutItems->RemoveAll(); 2549 CXFA_ItemLayoutProcessor* pProcessor = 2550 new CXFA_ItemLayoutProcessor(pLeaderNode, NULL); 2551 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_ 2552 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem; 2553 #endif 2554 XFA_ItemLayoutProcessor_InsertFlowedItem( 2555 this, pProcessor, bContainerWidthAutoSize, 2556 bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, 2557 uCurHAlignState, rgCurLineLayoutItems, FALSE, 2558 XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, 2559 fContentWidthLimit, fContentCurRowAvailWidth, 2560 fContentCurRowHeight, bAddedItemInRow, bForceEndPage, 2561 pContext); 2562 delete pProcessor; 2563 pProcessor = NULL; 2564 } 2565 } else { 2566 if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) { 2567 XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE); 2568 } 2569 } 2570 XFA_ItemLayoutProcessor_GotoNextContainerNode( 2571 m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE); 2572 if (bCreatePage) { 2573 bForceEndPage = TRUE; 2574 bIsManualBreak = TRUE; 2575 if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done) { 2576 bBreakDone = TRUE; 2577 } 2578 } 2579 goto SuspendAndCreateNewRow; 2580 } 2581 } break; 2582 case XFA_ItemLayoutProcessorStages_BookendLeader: { 2583 CXFA_Node* pLeaderNode = NULL; 2584 if (m_pCurChildPreprocessor) { 2585 pProcessor = m_pCurChildPreprocessor; 2586 m_pCurChildPreprocessor = NULL; 2587 } else if (m_pPageMgr && 2588 m_pPageMgr->ProcessBookendLeaderOrTrailer( 2589 m_pCurChildNode, TRUE, pLeaderNode)) { 2590 pProcessor = new CXFA_ItemLayoutProcessor(pLeaderNode, m_pPageMgr); 2591 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_ 2592 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem; 2593 #endif 2594 } 2595 if (pProcessor) { 2596 if (XFA_ItemLayoutProcessor_InsertFlowedItem( 2597 this, pProcessor, bContainerWidthAutoSize, 2598 bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, 2599 uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl, 2600 fAvailHeight, fRealHeight, fContentCurRowY, 2601 fContentWidthLimit, fContentCurRowAvailWidth, 2602 fContentCurRowHeight, bAddedItemInRow, bForceEndPage, 2603 pContext) != XFA_ItemLayoutProcessorResult_Done) { 2604 goto SuspendAndCreateNewRow; 2605 } else { 2606 delete pProcessor; 2607 pProcessor = NULL; 2608 } 2609 } 2610 } break; 2611 case XFA_ItemLayoutProcessorStages_BookendTrailer: { 2612 CXFA_Node* pTrailerNode = NULL; 2613 if (m_pCurChildPreprocessor) { 2614 pProcessor = m_pCurChildPreprocessor; 2615 m_pCurChildPreprocessor = NULL; 2616 } else if (m_pPageMgr && 2617 m_pPageMgr->ProcessBookendLeaderOrTrailer( 2618 m_pCurChildNode, FALSE, pTrailerNode)) { 2619 pProcessor = new CXFA_ItemLayoutProcessor(pTrailerNode, m_pPageMgr); 2620 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_ 2621 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem; 2622 #endif 2623 } 2624 if (pProcessor) { 2625 if (XFA_ItemLayoutProcessor_InsertFlowedItem( 2626 this, pProcessor, bContainerWidthAutoSize, 2627 bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, 2628 uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl, 2629 fAvailHeight, fRealHeight, fContentCurRowY, 2630 fContentWidthLimit, fContentCurRowAvailWidth, 2631 fContentCurRowHeight, bAddedItemInRow, bForceEndPage, 2632 pContext) != XFA_ItemLayoutProcessorResult_Done) { 2633 goto SuspendAndCreateNewRow; 2634 } else { 2635 delete pProcessor; 2636 pProcessor = NULL; 2637 } 2638 } 2639 } break; 2640 case XFA_ItemLayoutProcessorStages_Container: 2641 ASSERT(m_pCurChildNode->IsContainerNode()); 2642 if (m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) { 2643 break; 2644 } 2645 if (fContentCurRowY >= fHeightLimit + XFA_LAYOUT_FLOAT_PERCISION && 2646 XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) { 2647 bForceEndPage = TRUE; 2648 goto SuspendAndCreateNewRow; 2649 } 2650 if (m_pCurChildNode->IsContainerNode()) { 2651 FX_BOOL bNewRow = FALSE; 2652 if (m_pCurChildPreprocessor) { 2653 pProcessor = m_pCurChildPreprocessor; 2654 m_pCurChildPreprocessor = NULL; 2655 bNewRow = TRUE; 2656 } else { 2657 pProcessor = 2658 new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr); 2659 #ifndef _XFA_LAYOUTITEM_ProcessCACHE_ 2660 pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem; 2661 #endif 2662 } 2663 XFA_ItemLayoutProcessor_InsertPendingItems(pProcessor, 2664 m_pCurChildNode); 2665 XFA_ItemLayoutProcessorResult rs = 2666 XFA_ItemLayoutProcessor_InsertFlowedItem( 2667 this, pProcessor, bContainerWidthAutoSize, 2668 bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, 2669 uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl, 2670 fAvailHeight, fRealHeight, fContentCurRowY, 2671 fContentWidthLimit, fContentCurRowAvailWidth, 2672 fContentCurRowHeight, bAddedItemInRow, bForceEndPage, 2673 pContext, bNewRow); 2674 switch (rs) { 2675 case XFA_ItemLayoutProcessorResult_ManualBreak: 2676 bIsManualBreak = TRUE; 2677 case XFA_ItemLayoutProcessorResult_PageFullBreak: 2678 bForceEndPage = TRUE; 2679 case XFA_ItemLayoutProcessorResult_RowFullBreak: 2680 goto SuspendAndCreateNewRow; 2681 case XFA_ItemLayoutProcessorResult_Done: 2682 default: 2683 fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems( 2684 pProcessor, m_pCurChildNode); 2685 delete pProcessor; 2686 pProcessor = NULL; 2687 } 2688 } 2689 break; 2690 case XFA_ItemLayoutProcessorStages_Done: 2691 break; 2692 default: 2693 break; 2694 } 2695 XFA_ItemLayoutProcessor_GotoNextContainerNode( 2696 m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE); 2697 if (bAddedItemInRow && eFlowStrategy == XFA_ATTRIBUTEENUM_Tb) { 2698 break; 2699 } else { 2700 continue; 2701 } 2702 SuspendAndCreateNewRow: 2703 if (pProcessor) { 2704 m_pCurChildPreprocessor = pProcessor; 2705 } 2706 break; 2707 } 2708 CalculateRowChildPosition(rgCurLineLayoutItems, eFlowStrategy, 2709 bContainerHeightAutoSize, bContainerWidthAutoSize, 2710 fContentCalculatedWidth, fContentCalculatedHeight, 2711 fContentCurRowY, fContentCurRowHeight, 2712 fContentWidthLimit, bRootForceTb); 2713 m_fWidthLimite = fContentCurRowAvailWidth; 2714 if (bForceEndPage) { 2715 break; 2716 } 2717 } 2718 FX_BOOL bRetValue = 2719 (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done && 2720 m_rgPendingNodes.GetCount() == 0); 2721 if (bBreakDone) { 2722 bRetValue = FALSE; 2723 } 2724 XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize( 2725 m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, 2726 fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, 2727 fContainerHeight); 2728 if (fContainerHeight >= XFA_LAYOUT_FLOAT_PERCISION || m_pLayoutItem || 2729 bRetValue) { 2730 if (m_pLayoutItem == NULL) { 2731 m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); 2732 } 2733 if (fContainerHeight < 0) { 2734 fContainerHeight = 0; 2735 } 2736 SetCurrentComponentSize(fContainerWidth, fContainerHeight); 2737 if (bForceEndPage) { 2738 m_fUsedSize = 0; 2739 } else { 2740 m_fUsedSize += m_pLayoutItem->m_sSize.y; 2741 } 2742 } 2743 return bRetValue 2744 ? XFA_ItemLayoutProcessorResult_Done 2745 : (bIsManualBreak ? XFA_ItemLayoutProcessorResult_ManualBreak 2746 : XFA_ItemLayoutProcessorResult_PageFullBreak); 2747 } 2748 FX_BOOL CXFA_ItemLayoutProcessor::CalculateRowChildPosition( 2749 CFX_ArrayTemplate<CXFA_ContentLayoutItem*>(&rgCurLineLayoutItems)[3], 2750 XFA_ATTRIBUTEENUM eFlowStrategy, 2751 FX_BOOL bContainerHeightAutoSize, 2752 FX_BOOL bContainerWidthAutoSize, 2753 FX_FLOAT& fContentCalculatedWidth, 2754 FX_FLOAT& fContentCalculatedHeight, 2755 FX_FLOAT& fContentCurRowY, 2756 FX_FLOAT fContentCurRowHeight, 2757 FX_FLOAT fContentWidthLimit, 2758 FX_BOOL bRootForceTb) { 2759 int32_t nGroupLengths[3] = {0, 0, 0}; 2760 FX_FLOAT fGroupWidths[3] = {0, 0, 0}; 2761 int32_t nTotalLength = 0; 2762 for (int32_t i = 0; i < 3; i++) { 2763 nGroupLengths[i] = rgCurLineLayoutItems[i].GetSize(); 2764 for (int32_t c = nGroupLengths[i], j = 0; j < c; j++) { 2765 nTotalLength++; 2766 if (XFA_ItemLayoutProcessor_IsTakingSpace( 2767 rgCurLineLayoutItems[i][j]->m_pFormNode)) { 2768 fGroupWidths[i] += rgCurLineLayoutItems[i][j]->m_sSize.x; 2769 } 2770 } 2771 } 2772 if (!nTotalLength) { 2773 if (bContainerHeightAutoSize) { 2774 FX_FLOAT fNewHeight = fContentCurRowY; 2775 if (fContentCalculatedHeight > fNewHeight) { 2776 fContentCalculatedHeight = fNewHeight; 2777 } 2778 } 2779 return FALSE; 2780 } 2781 if (m_pLayoutItem == NULL) { 2782 m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); 2783 } 2784 if (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb) { 2785 FX_FLOAT fCurPos; 2786 fCurPos = 0; 2787 for (int32_t c = nGroupLengths[0], j = 0; j < c; j++) { 2788 if (bRootForceTb) { 2789 FX_FLOAT fAbsoluteX, fAbsoluteY; 2790 CalculatePositionedContainerPos(rgCurLineLayoutItems[0][j]->m_pFormNode, 2791 rgCurLineLayoutItems[0][j]->m_sSize.x, 2792 rgCurLineLayoutItems[0][j]->m_sSize.y, 2793 fAbsoluteX, fAbsoluteY); 2794 rgCurLineLayoutItems[0][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY); 2795 } else { 2796 rgCurLineLayoutItems[0][j]->m_sPos.Set(fCurPos, fContentCurRowY); 2797 if (XFA_ItemLayoutProcessor_IsTakingSpace( 2798 rgCurLineLayoutItems[0][j]->m_pFormNode)) { 2799 fCurPos += rgCurLineLayoutItems[0][j]->m_sSize.x; 2800 } 2801 } 2802 m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]); 2803 m_fLastRowWidth = fCurPos; 2804 } 2805 fCurPos = (fContentWidthLimit + fGroupWidths[0] - fGroupWidths[1] - 2806 fGroupWidths[2]) / 2807 2; 2808 for (int32_t c = nGroupLengths[1], j = 0; j < c; j++) { 2809 if (bRootForceTb) { 2810 FX_FLOAT fAbsoluteX, fAbsoluteY; 2811 CalculatePositionedContainerPos(rgCurLineLayoutItems[1][j]->m_pFormNode, 2812 rgCurLineLayoutItems[1][j]->m_sSize.x, 2813 rgCurLineLayoutItems[1][j]->m_sSize.y, 2814 fAbsoluteX, fAbsoluteY); 2815 rgCurLineLayoutItems[1][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY); 2816 } else { 2817 rgCurLineLayoutItems[1][j]->m_sPos.Set(fCurPos, fContentCurRowY); 2818 if (XFA_ItemLayoutProcessor_IsTakingSpace( 2819 rgCurLineLayoutItems[1][j]->m_pFormNode)) { 2820 fCurPos += rgCurLineLayoutItems[1][j]->m_sSize.x; 2821 } 2822 } 2823 m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]); 2824 m_fLastRowWidth = fCurPos; 2825 } 2826 fCurPos = fContentWidthLimit - fGroupWidths[2]; 2827 for (int32_t c = nGroupLengths[2], j = 0; j < c; j++) { 2828 if (bRootForceTb) { 2829 FX_FLOAT fAbsoluteX, fAbsoluteY; 2830 CalculatePositionedContainerPos(rgCurLineLayoutItems[2][j]->m_pFormNode, 2831 rgCurLineLayoutItems[2][j]->m_sSize.x, 2832 rgCurLineLayoutItems[2][j]->m_sSize.y, 2833 fAbsoluteX, fAbsoluteY); 2834 rgCurLineLayoutItems[2][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY); 2835 } else { 2836 rgCurLineLayoutItems[2][j]->m_sPos.Set(fCurPos, fContentCurRowY); 2837 if (XFA_ItemLayoutProcessor_IsTakingSpace( 2838 rgCurLineLayoutItems[2][j]->m_pFormNode)) { 2839 fCurPos += rgCurLineLayoutItems[2][j]->m_sSize.x; 2840 } 2841 } 2842 m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]); 2843 m_fLastRowWidth = fCurPos; 2844 } 2845 } else { 2846 FX_FLOAT fCurPos; 2847 fCurPos = fGroupWidths[0]; 2848 for (int32_t c = nGroupLengths[0], j = 0; j < c; j++) { 2849 if (XFA_ItemLayoutProcessor_IsTakingSpace( 2850 rgCurLineLayoutItems[0][j]->m_pFormNode)) { 2851 fCurPos -= rgCurLineLayoutItems[0][j]->m_sSize.x; 2852 } 2853 rgCurLineLayoutItems[0][j]->m_sPos.Set(fCurPos, fContentCurRowY); 2854 m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]); 2855 m_fLastRowWidth = fCurPos; 2856 } 2857 fCurPos = (fContentWidthLimit + fGroupWidths[0] + fGroupWidths[1] - 2858 fGroupWidths[2]) / 2859 2; 2860 for (int32_t c = nGroupLengths[1], j = 0; j < c; j++) { 2861 if (XFA_ItemLayoutProcessor_IsTakingSpace( 2862 rgCurLineLayoutItems[1][j]->m_pFormNode)) { 2863 fCurPos -= rgCurLineLayoutItems[1][j]->m_sSize.x; 2864 } 2865 rgCurLineLayoutItems[1][j]->m_sPos.Set(fCurPos, fContentCurRowY); 2866 m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]); 2867 m_fLastRowWidth = fCurPos; 2868 } 2869 fCurPos = fContentWidthLimit; 2870 for (int32_t c = nGroupLengths[2], j = 0; j < c; j++) { 2871 if (XFA_ItemLayoutProcessor_IsTakingSpace( 2872 rgCurLineLayoutItems[2][j]->m_pFormNode)) { 2873 fCurPos -= rgCurLineLayoutItems[2][j]->m_sSize.x; 2874 } 2875 rgCurLineLayoutItems[2][j]->m_sPos.Set(fCurPos, fContentCurRowY); 2876 m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]); 2877 m_fLastRowWidth = fCurPos; 2878 } 2879 } 2880 m_fLastRowY = fContentCurRowY; 2881 fContentCurRowY += fContentCurRowHeight; 2882 if (bContainerWidthAutoSize) { 2883 FX_FLOAT fChildSuppliedWidth = fGroupWidths[0]; 2884 if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && 2885 fContentWidthLimit > fChildSuppliedWidth) { 2886 fChildSuppliedWidth = fContentWidthLimit; 2887 } 2888 if (fContentCalculatedWidth < fChildSuppliedWidth) { 2889 fContentCalculatedWidth = fChildSuppliedWidth; 2890 } 2891 } 2892 if (bContainerHeightAutoSize) { 2893 FX_FLOAT fChildSuppliedHeight = fContentCurRowY; 2894 if (fContentCalculatedHeight < fChildSuppliedHeight) { 2895 fContentCalculatedHeight = fChildSuppliedHeight; 2896 } 2897 } 2898 return TRUE; 2899 } 2900 CXFA_Node* CXFA_ItemLayoutProcessor::GetSubformSetParent( 2901 CXFA_Node* pSubformSet) { 2902 if (pSubformSet && pSubformSet->GetClassID() == XFA_ELEMENT_SubformSet) { 2903 CXFA_Node* pParent = pSubformSet->GetNodeItem(XFA_NODEITEM_Parent); 2904 while (pParent) { 2905 if (pParent->GetClassID() != XFA_ELEMENT_SubformSet) { 2906 return pParent; 2907 } 2908 pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent); 2909 } 2910 } 2911 return pSubformSet; 2912 } 2913 void CXFA_ItemLayoutProcessor::DoLayoutField() { 2914 if (m_pLayoutItem != NULL) { 2915 return; 2916 } 2917 ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE); 2918 m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); 2919 if (!m_pLayoutItem) { 2920 return; 2921 } 2922 CXFA_Document* pDocument = m_pFormNode->GetDocument(); 2923 IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify(); 2924 FX_FLOAT fHeight = -1; 2925 FX_FLOAT fWidth = -1; 2926 pNotify->StartFieldDrawLayout(m_pFormNode, fWidth, fHeight); 2927 int32_t nRotate = 2928 FXSYS_round(m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue()); 2929 nRotate = XFA_MapRotation(nRotate); 2930 if (nRotate == 90 || nRotate == 270) { 2931 FX_FLOAT fTmp = fWidth; 2932 fWidth = fHeight; 2933 fHeight = fTmp; 2934 } 2935 SetCurrentComponentSize(fWidth, fHeight); 2936 } 2937 XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayout( 2938 FX_BOOL bUseBreakControl, 2939 FX_FLOAT fHeightLimit, 2940 FX_FLOAT fRealHeight, 2941 CXFA_LayoutContext* pContext) { 2942 XFA_ELEMENT eClassID = m_pFormNode->GetClassID(); 2943 switch (eClassID) { 2944 case XFA_ELEMENT_Subform: 2945 case XFA_ELEMENT_Area: 2946 case XFA_ELEMENT_ExclGroup: 2947 case XFA_ELEMENT_SubformSet: { 2948 FX_BOOL bRootForceTb = FALSE; 2949 CXFA_Node* pLayoutNode = GetSubformSetParent(m_pFormNode); 2950 XFA_ATTRIBUTEENUM eLayoutStrategy = 2951 XFA_ItemLayoutProcessor_GetLayout(pLayoutNode, bRootForceTb); 2952 switch (eLayoutStrategy) { 2953 case XFA_ATTRIBUTEENUM_Tb: 2954 case XFA_ATTRIBUTEENUM_Lr_tb: 2955 case XFA_ATTRIBUTEENUM_Rl_tb: 2956 return DoLayoutFlowedContainer(bUseBreakControl, eLayoutStrategy, 2957 fHeightLimit, fRealHeight, pContext, 2958 bRootForceTb); 2959 case XFA_ATTRIBUTEENUM_Position: 2960 case XFA_ATTRIBUTEENUM_Row: 2961 case XFA_ATTRIBUTEENUM_Rl_row: 2962 default: 2963 DoLayoutPositionedContainer(pContext); 2964 m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done; 2965 return XFA_ItemLayoutProcessorResult_Done; 2966 case XFA_ATTRIBUTEENUM_Table: 2967 DoLayoutTableContainer(pLayoutNode); 2968 m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done; 2969 return XFA_ItemLayoutProcessorResult_Done; 2970 } 2971 } 2972 case XFA_ELEMENT_Draw: 2973 case XFA_ELEMENT_Field: 2974 DoLayoutField(); 2975 m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done; 2976 return XFA_ItemLayoutProcessorResult_Done; 2977 case XFA_ELEMENT_ContentArea: 2978 return XFA_ItemLayoutProcessorResult_Done; 2979 default: 2980 return XFA_ItemLayoutProcessorResult_Done; 2981 } 2982 } 2983 void CXFA_ItemLayoutProcessor::GetCurrentComponentPos(FX_FLOAT& fAbsoluteX, 2984 FX_FLOAT& fAbsoluteY) { 2985 ASSERT(m_pLayoutItem); 2986 fAbsoluteX = m_pLayoutItem->m_sPos.x; 2987 fAbsoluteY = m_pLayoutItem->m_sPos.y; 2988 } 2989 void CXFA_ItemLayoutProcessor::GetCurrentComponentSize(FX_FLOAT& fWidth, 2990 FX_FLOAT& fHeight) { 2991 ASSERT(m_pLayoutItem); 2992 fWidth = m_pLayoutItem->m_sSize.x; 2993 fHeight = m_pLayoutItem->m_sSize.y; 2994 } 2995 void CXFA_ItemLayoutProcessor::SetCurrentComponentPos(FX_FLOAT fAbsoluteX, 2996 FX_FLOAT fAbsoluteY) { 2997 ASSERT(m_pLayoutItem); 2998 m_pLayoutItem->m_sPos.Set(fAbsoluteX, fAbsoluteY); 2999 } 3000 void CXFA_ItemLayoutProcessor::SetCurrentComponentSize(FX_FLOAT fWidth, 3001 FX_FLOAT fHeight) { 3002 ASSERT(m_pLayoutItem); 3003 m_pLayoutItem->m_sSize.Set(fWidth, fHeight); 3004 } 3005 FX_BOOL CXFA_ItemLayoutProcessor::JudgeLeaderOrTrailerForOccur( 3006 CXFA_Node* pFormNode) { 3007 if (pFormNode == NULL) { 3008 return FALSE; 3009 } 3010 CXFA_Node* pTemplate = pFormNode->GetTemplateNode(); 3011 if (!pTemplate) { 3012 pTemplate = pFormNode; 3013 } 3014 CXFA_Occur NodeOccur = pTemplate->GetFirstChildByClass(XFA_ELEMENT_Occur); 3015 int32_t iMax = NodeOccur.GetMax(); 3016 if (iMax > -1) { 3017 int32_t iCount = 3018 (int32_t)(uintptr_t)m_PendingNodesCount.GetValueAt(pTemplate); 3019 if (iCount >= iMax) { 3020 return FALSE; 3021 } 3022 iCount++; 3023 m_PendingNodesCount.SetAt(pTemplate, (void*)(uintptr_t)(iCount)); 3024 return TRUE; 3025 } 3026 return TRUE; 3027 } 3028