| OLD | NEW |
| (Empty) |
| 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 "xfa/src/fxfa/parser/xfa_layout_pagemgr_new.h" | |
| 8 | |
| 9 #include "xfa/src/fxfa/fm2js/xfa_fm2jsapi.h" | |
| 10 #include "xfa/src/fxfa/parser/xfa_docdata.h" | |
| 11 #include "xfa/src/fxfa/parser/xfa_doclayout.h" | |
| 12 #include "xfa/src/fxfa/parser/xfa_document.h" | |
| 13 #include "xfa/src/fxfa/parser/xfa_document_datamerger_imp.h" | |
| 14 #include "xfa/src/fxfa/parser/xfa_document_layout_imp.h" | |
| 15 #include "xfa/src/fxfa/parser/xfa_layout_appadapter.h" | |
| 16 #include "xfa/src/fxfa/parser/xfa_layout_itemlayout.h" | |
| 17 #include "xfa/src/fxfa/parser/xfa_localemgr.h" | |
| 18 #include "xfa/src/fxfa/parser/xfa_object.h" | |
| 19 #include "xfa/src/fxfa/parser/xfa_parser.h" | |
| 20 #include "xfa/src/fxfa/parser/xfa_script.h" | |
| 21 #include "xfa/src/fxfa/parser/xfa_utils.h" | |
| 22 | |
| 23 CXFA_LayoutPageMgr::CXFA_LayoutPageMgr(CXFA_LayoutProcessor* pLayoutProcessor) | |
| 24 : m_pLayoutProcessor(pLayoutProcessor), | |
| 25 m_pTemplatePageSetRoot(nullptr), | |
| 26 m_pPageSetLayoutItemRoot(nullptr), | |
| 27 m_pPageSetCurRoot(nullptr), | |
| 28 m_pCurrentContainerRecord(nullptr), | |
| 29 m_pCurPageArea(nullptr), | |
| 30 m_nAvailPages(0), | |
| 31 m_nCurPageCount(0), | |
| 32 m_ePageSetMode(XFA_ATTRIBUTEENUM_OrderedOccurrence), | |
| 33 m_bCreateOverFlowPage(FALSE) {} | |
| 34 CXFA_LayoutPageMgr::~CXFA_LayoutPageMgr() { | |
| 35 ClearData(); | |
| 36 CXFA_LayoutItem* pLayoutItem = GetRootLayoutItem(); | |
| 37 CXFA_LayoutItem* pNextLayout = NULL; | |
| 38 for (; pLayoutItem; pLayoutItem = pNextLayout) { | |
| 39 pNextLayout = pLayoutItem->m_pNextSibling; | |
| 40 XFA_ReleaseLayoutItem(pLayoutItem); | |
| 41 } | |
| 42 } | |
| 43 FX_BOOL CXFA_LayoutPageMgr::InitLayoutPage(CXFA_Node* pFormNode) { | |
| 44 PrepareLayout(); | |
| 45 CXFA_Node* pTemplateNode = pFormNode->GetTemplateNode(); | |
| 46 if (!pTemplateNode) { | |
| 47 return FALSE; | |
| 48 } | |
| 49 m_pTemplatePageSetRoot = pTemplateNode->GetProperty(0, XFA_ELEMENT_PageSet); | |
| 50 ASSERT(m_pTemplatePageSetRoot); | |
| 51 if (m_pPageSetLayoutItemRoot) { | |
| 52 m_pPageSetLayoutItemRoot->m_pParent = NULL; | |
| 53 m_pPageSetLayoutItemRoot->m_pFirstChild = NULL; | |
| 54 m_pPageSetLayoutItemRoot->m_pNextSibling = NULL; | |
| 55 m_pPageSetLayoutItemRoot->m_pFormNode = m_pTemplatePageSetRoot; | |
| 56 } else { | |
| 57 m_pPageSetLayoutItemRoot = | |
| 58 new CXFA_ContainerLayoutItem(m_pTemplatePageSetRoot); | |
| 59 } | |
| 60 m_pPageSetCurRoot = m_pPageSetLayoutItemRoot; | |
| 61 m_pTemplatePageSetRoot->SetUserData(XFA_LAYOUTITEMKEY, | |
| 62 (void*)m_pPageSetLayoutItemRoot); | |
| 63 XFA_ATTRIBUTEENUM eRelation = | |
| 64 m_pTemplatePageSetRoot->GetEnum(XFA_ATTRIBUTE_Relation); | |
| 65 if (eRelation != XFA_ATTRIBUTEENUM_Unknown) { | |
| 66 m_ePageSetMode = eRelation; | |
| 67 } | |
| 68 InitPageSetMap(); | |
| 69 CXFA_Node* pPageArea = NULL; | |
| 70 int32_t iCount = 0; | |
| 71 for (pPageArea = m_pTemplatePageSetRoot->GetNodeItem(XFA_NODEITEM_FirstChild); | |
| 72 pPageArea; | |
| 73 pPageArea = pPageArea->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
| 74 if (pPageArea->GetClassID() == XFA_ELEMENT_PageArea) { | |
| 75 iCount++; | |
| 76 if (pPageArea->GetFirstChildByClass(XFA_ELEMENT_ContentArea)) { | |
| 77 return TRUE; | |
| 78 } | |
| 79 } | |
| 80 } | |
| 81 if (iCount > 0) { | |
| 82 return FALSE; | |
| 83 } | |
| 84 CXFA_Document* pDocument = pTemplateNode->GetDocument(); | |
| 85 IXFA_ObjFactory* pObjFactory = pDocument->GetParser()->GetFactory(); | |
| 86 pPageArea = m_pTemplatePageSetRoot->GetChild(0, XFA_ELEMENT_PageArea); | |
| 87 if (!pPageArea) { | |
| 88 pPageArea = pObjFactory->CreateNode(m_pTemplatePageSetRoot->GetPacketID(), | |
| 89 XFA_ELEMENT_PageArea); | |
| 90 if (!pPageArea) { | |
| 91 return FALSE; | |
| 92 } | |
| 93 m_pTemplatePageSetRoot->InsertChild(pPageArea, NULL); | |
| 94 pPageArea->SetFlag(XFA_NODEFLAG_Initialized); | |
| 95 } | |
| 96 CXFA_Node* pContentArea = pPageArea->GetChild(0, XFA_ELEMENT_ContentArea); | |
| 97 if (!pContentArea) { | |
| 98 pContentArea = pObjFactory->CreateNode(pPageArea->GetPacketID(), | |
| 99 XFA_ELEMENT_ContentArea); | |
| 100 if (!pContentArea) { | |
| 101 return FALSE; | |
| 102 } | |
| 103 pPageArea->InsertChild(pContentArea, NULL); | |
| 104 pContentArea->SetFlag(XFA_NODEFLAG_Initialized); | |
| 105 pContentArea->SetMeasure(XFA_ATTRIBUTE_X, | |
| 106 CXFA_Measurement(0.25f, XFA_UNIT_In)); | |
| 107 pContentArea->SetMeasure(XFA_ATTRIBUTE_Y, | |
| 108 CXFA_Measurement(0.25f, XFA_UNIT_In)); | |
| 109 pContentArea->SetMeasure(XFA_ATTRIBUTE_W, | |
| 110 CXFA_Measurement(8.0f, XFA_UNIT_In)); | |
| 111 pContentArea->SetMeasure(XFA_ATTRIBUTE_H, | |
| 112 CXFA_Measurement(10.5f, XFA_UNIT_In)); | |
| 113 } | |
| 114 CXFA_Node* pMedium = pPageArea->GetChild(0, XFA_ELEMENT_Medium); | |
| 115 if (!pMedium) { | |
| 116 pMedium = | |
| 117 pObjFactory->CreateNode(pPageArea->GetPacketID(), XFA_ELEMENT_Medium); | |
| 118 if (!pContentArea) { | |
| 119 return FALSE; | |
| 120 } | |
| 121 pPageArea->InsertChild(pMedium, NULL); | |
| 122 pMedium->SetFlag(XFA_NODEFLAG_Initialized); | |
| 123 pMedium->SetMeasure(XFA_ATTRIBUTE_Short, | |
| 124 CXFA_Measurement(8.5f, XFA_UNIT_In)); | |
| 125 pMedium->SetMeasure(XFA_ATTRIBUTE_Long, | |
| 126 CXFA_Measurement(11.0f, XFA_UNIT_In)); | |
| 127 } | |
| 128 return TRUE; | |
| 129 } | |
| 130 FX_BOOL CXFA_LayoutPageMgr::PrepareFirstPage(CXFA_Node* pRootSubform) { | |
| 131 FX_BOOL bProBreakBefore = FALSE; | |
| 132 CXFA_Node* pBreakBeforeNode = NULL; | |
| 133 while (pRootSubform) { | |
| 134 for (CXFA_Node* pBreakNode = | |
| 135 pRootSubform->GetNodeItem(XFA_NODEITEM_FirstChild); | |
| 136 pBreakNode; | |
| 137 pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
| 138 XFA_ELEMENT eType = pBreakNode->GetClassID(); | |
| 139 if (eType == XFA_ELEMENT_BreakBefore || | |
| 140 (eType == XFA_ELEMENT_Break && | |
| 141 pBreakNode->GetEnum(XFA_ATTRIBUTE_Before) != | |
| 142 XFA_ATTRIBUTEENUM_Auto)) { | |
| 143 bProBreakBefore = TRUE; | |
| 144 pBreakBeforeNode = pBreakNode; | |
| 145 break; | |
| 146 } | |
| 147 } | |
| 148 if (bProBreakBefore) { | |
| 149 break; | |
| 150 } | |
| 151 bProBreakBefore = TRUE; | |
| 152 pRootSubform = pRootSubform->GetFirstChildByClass(XFA_ELEMENT_Subform); | |
| 153 while (pRootSubform && | |
| 154 !XFA_ItemLayoutProcessor_IsTakingSpace(pRootSubform)) { | |
| 155 pRootSubform = pRootSubform->GetNextSameClassSibling(XFA_ELEMENT_Subform); | |
| 156 } | |
| 157 } | |
| 158 CXFA_Node *pLeader, *pTrailer; | |
| 159 if (pBreakBeforeNode && | |
| 160 ExecuteBreakBeforeOrAfter(pBreakBeforeNode, TRUE, pLeader, pTrailer)) { | |
| 161 m_pCurrentContainerRecord = m_rgProposedContainerRecord.GetHeadPosition(); | |
| 162 return TRUE; | |
| 163 } | |
| 164 return AppendNewPage(TRUE); | |
| 165 } | |
| 166 FX_BOOL CXFA_LayoutPageMgr::AppendNewPage(FX_BOOL bFirstTemPage) { | |
| 167 if (m_pCurrentContainerRecord != | |
| 168 m_rgProposedContainerRecord.GetTailPosition()) { | |
| 169 return TRUE; | |
| 170 } | |
| 171 CXFA_Node* pPageNode = GetNextAvailPageArea(NULL); | |
| 172 if (!pPageNode) { | |
| 173 return FALSE; | |
| 174 } | |
| 175 if (bFirstTemPage && m_pCurrentContainerRecord == NULL) { | |
| 176 m_pCurrentContainerRecord = m_rgProposedContainerRecord.GetHeadPosition(); | |
| 177 } | |
| 178 return !bFirstTemPage || m_pCurrentContainerRecord; | |
| 179 } | |
| 180 static void XFA_LayoutItemMgr_ReorderLayoutItemToTail( | |
| 181 CXFA_ContainerLayoutItem* pLayoutItem) { | |
| 182 CXFA_ContainerLayoutItem* pParentLayoutItem = | |
| 183 (CXFA_ContainerLayoutItem*)pLayoutItem->m_pParent; | |
| 184 if (!pParentLayoutItem) { | |
| 185 return; | |
| 186 } | |
| 187 pParentLayoutItem->RemoveChild(pLayoutItem); | |
| 188 pParentLayoutItem->AddChild(pLayoutItem); | |
| 189 } | |
| 190 static void XFA_LayoutItemMgr_RemoveLayoutItem( | |
| 191 CXFA_ContainerLayoutItem* pLayoutItem) { | |
| 192 CXFA_ContainerLayoutItem* pParentLayoutItem = | |
| 193 (CXFA_ContainerLayoutItem*)pLayoutItem->m_pParent; | |
| 194 if (!pParentLayoutItem) { | |
| 195 return; | |
| 196 } | |
| 197 pParentLayoutItem->RemoveChild(pLayoutItem); | |
| 198 } | |
| 199 void CXFA_LayoutPageMgr::RemoveLayoutRecord(CXFA_ContainerRecord* pNewRecord, | |
| 200 CXFA_ContainerRecord* pPrevRecord) { | |
| 201 if (!pNewRecord || !pPrevRecord) { | |
| 202 return; | |
| 203 } | |
| 204 if (pNewRecord->pCurPageSet != pPrevRecord->pCurPageSet) { | |
| 205 XFA_LayoutItemMgr_RemoveLayoutItem(pNewRecord->pCurPageSet); | |
| 206 return; | |
| 207 } | |
| 208 if (pNewRecord->pCurPageArea != pPrevRecord->pCurPageArea) { | |
| 209 XFA_LayoutItemMgr_RemoveLayoutItem(pNewRecord->pCurPageArea); | |
| 210 return; | |
| 211 } | |
| 212 if (pNewRecord->pCurContentArea != pPrevRecord->pCurContentArea) { | |
| 213 XFA_LayoutItemMgr_RemoveLayoutItem(pNewRecord->pCurContentArea); | |
| 214 return; | |
| 215 } | |
| 216 } | |
| 217 void CXFA_LayoutPageMgr::ReorderPendingLayoutRecordToTail( | |
| 218 CXFA_ContainerRecord* pNewRecord, | |
| 219 CXFA_ContainerRecord* pPrevRecord) { | |
| 220 if (!pNewRecord || !pPrevRecord) { | |
| 221 return; | |
| 222 } | |
| 223 if (pNewRecord->pCurPageSet != pPrevRecord->pCurPageSet) { | |
| 224 XFA_LayoutItemMgr_ReorderLayoutItemToTail(pNewRecord->pCurPageSet); | |
| 225 return; | |
| 226 } | |
| 227 if (pNewRecord->pCurPageArea != pPrevRecord->pCurPageArea) { | |
| 228 XFA_LayoutItemMgr_ReorderLayoutItemToTail(pNewRecord->pCurPageArea); | |
| 229 return; | |
| 230 } | |
| 231 if (pNewRecord->pCurContentArea != pPrevRecord->pCurContentArea) { | |
| 232 XFA_LayoutItemMgr_ReorderLayoutItemToTail(pNewRecord->pCurContentArea); | |
| 233 return; | |
| 234 } | |
| 235 } | |
| 236 void CXFA_LayoutPageMgr::SubmitContentItem( | |
| 237 CXFA_ContentLayoutItem* pContentLayoutItem, | |
| 238 XFA_ItemLayoutProcessorResult eStatus) { | |
| 239 if (pContentLayoutItem) { | |
| 240 GetCurrentContainerRecord()->pCurContentArea->AddChild(pContentLayoutItem); | |
| 241 m_bCreateOverFlowPage = FALSE; | |
| 242 } | |
| 243 if (eStatus != XFA_ItemLayoutProcessorResult_Done) { | |
| 244 if (eStatus == XFA_ItemLayoutProcessorResult_PageFullBreak && | |
| 245 m_pCurrentContainerRecord == | |
| 246 m_rgProposedContainerRecord.GetTailPosition()) { | |
| 247 AppendNewPage(); | |
| 248 } | |
| 249 m_pCurrentContainerRecord = m_rgProposedContainerRecord.GetTailPosition(); | |
| 250 m_pCurPageArea = GetCurrentContainerRecord()->pCurPageArea->m_pFormNode; | |
| 251 } | |
| 252 } | |
| 253 FX_FLOAT CXFA_LayoutPageMgr::GetAvailHeight() { | |
| 254 CXFA_ContainerLayoutItem* pLayoutItem = | |
| 255 GetCurrentContainerRecord()->pCurContentArea; | |
| 256 if (!pLayoutItem || !pLayoutItem->m_pFormNode) | |
| 257 return 0.0f; | |
| 258 FX_FLOAT fAvailHeight = | |
| 259 pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt); | |
| 260 if (fAvailHeight >= XFA_LAYOUT_FLOAT_PERCISION) | |
| 261 return fAvailHeight; | |
| 262 if (m_pCurrentContainerRecord == | |
| 263 m_rgProposedContainerRecord.GetHeadPosition()) { | |
| 264 return 0.0f; | |
| 265 } | |
| 266 return XFA_LAYOUT_FLOAT_MAX; | |
| 267 } | |
| 268 static CXFA_Node* XFA_ResolveBreakTarget(CXFA_Node* pPageSetRoot, | |
| 269 FX_BOOL bNewExprStyle, | |
| 270 CFX_WideStringC& wsTargetExpr) { | |
| 271 CXFA_Document* pDocument = pPageSetRoot->GetDocument(); | |
| 272 if (wsTargetExpr.IsEmpty()) { | |
| 273 return NULL; | |
| 274 } | |
| 275 CFX_WideString wsTargetAll = wsTargetExpr; | |
| 276 wsTargetAll.TrimLeft(); | |
| 277 wsTargetAll.TrimRight(); | |
| 278 int32_t iSpliteIndex = 0; | |
| 279 FX_BOOL bTargetAllFind = TRUE; | |
| 280 while (iSpliteIndex != -1) { | |
| 281 CFX_WideString wsTargetExpr; | |
| 282 int32_t iSpliteNextIndex = 0; | |
| 283 if (!bTargetAllFind) { | |
| 284 iSpliteNextIndex = wsTargetAll.Find(' ', iSpliteIndex); | |
| 285 wsTargetExpr = | |
| 286 wsTargetAll.Mid(iSpliteIndex, iSpliteNextIndex - iSpliteIndex); | |
| 287 } else { | |
| 288 wsTargetExpr = wsTargetAll; | |
| 289 } | |
| 290 if (wsTargetExpr.IsEmpty()) { | |
| 291 return NULL; | |
| 292 } | |
| 293 bTargetAllFind = FALSE; | |
| 294 if (wsTargetExpr.GetAt(0) == '#') { | |
| 295 CXFA_Node* pNode = pDocument->GetNodeByID( | |
| 296 ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Template)), | |
| 297 wsTargetExpr.Mid(1)); | |
| 298 if (pNode) { | |
| 299 return pNode; | |
| 300 } | |
| 301 } else if (bNewExprStyle) { | |
| 302 CFX_WideString wsProcessedTarget = wsTargetExpr; | |
| 303 if (wsTargetExpr.Left(4) == FX_WSTRC(L"som(") && | |
| 304 wsTargetExpr.Right(1) == FX_WSTRC(L")")) { | |
| 305 wsProcessedTarget = wsTargetExpr.Mid(4, wsTargetExpr.GetLength() - 5); | |
| 306 } | |
| 307 XFA_RESOLVENODE_RS rs; | |
| 308 int32_t iCount = pDocument->GetScriptContext()->ResolveObjects( | |
| 309 pPageSetRoot, wsProcessedTarget, rs, | |
| 310 XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties | | |
| 311 XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Siblings | | |
| 312 XFA_RESOLVENODE_Parent); | |
| 313 if (iCount > 0 && rs.nodes[0]->IsNode()) { | |
| 314 return rs.nodes[0]->AsNode(); | |
| 315 } | |
| 316 } | |
| 317 iSpliteIndex = iSpliteNextIndex; | |
| 318 } | |
| 319 return NULL; | |
| 320 } | |
| 321 | |
| 322 FX_BOOL XFA_LayoutPageMgr_RunBreakTestScript(CXFA_Node* pTestScript) { | |
| 323 CFX_WideString wsExpression; | |
| 324 pTestScript->TryContent(wsExpression); | |
| 325 if (wsExpression.IsEmpty()) { | |
| 326 return TRUE; | |
| 327 } | |
| 328 return pTestScript->GetDocument()->GetParser()->GetNotify()->RunScript( | |
| 329 pTestScript, pTestScript->GetNodeItem(XFA_NODEITEM_Parent, | |
| 330 XFA_OBJECTTYPE_ContainerNode)); | |
| 331 } | |
| 332 CXFA_ContainerRecord* CXFA_LayoutPageMgr::CreateContainerRecord( | |
| 333 CXFA_Node* pPageNode, | |
| 334 FX_BOOL bCreateNew) { | |
| 335 CXFA_ContainerRecord* pNewRecord = new CXFA_ContainerRecord(); | |
| 336 if (m_pCurrentContainerRecord) { | |
| 337 if (!IsPageSetRootOrderedOccurrence() || pPageNode == NULL) { | |
| 338 *pNewRecord = *GetCurrentContainerRecord(); | |
| 339 m_rgProposedContainerRecord.AddTail(pNewRecord); | |
| 340 return pNewRecord; | |
| 341 } | |
| 342 CXFA_Node* pPageSet = pPageNode->GetNodeItem(XFA_NODEITEM_Parent); | |
| 343 if (!bCreateNew) { | |
| 344 if (pPageSet == m_pTemplatePageSetRoot) { | |
| 345 pNewRecord->pCurPageSet = m_pPageSetCurRoot; | |
| 346 } else { | |
| 347 CXFA_ContainerLayoutItem* pParentLayoutItem = | |
| 348 (CXFA_ContainerLayoutItem*)pPageSet->GetUserData(XFA_LAYOUTITEMKEY); | |
| 349 if (pParentLayoutItem == NULL) { | |
| 350 pParentLayoutItem = m_pPageSetCurRoot; | |
| 351 } | |
| 352 pNewRecord->pCurPageSet = pParentLayoutItem; | |
| 353 } | |
| 354 } else { | |
| 355 CXFA_ContainerLayoutItem* pParentPageSetLayout = NULL; | |
| 356 if (pPageSet == GetCurrentContainerRecord()->pCurPageSet->m_pFormNode) { | |
| 357 pParentPageSetLayout = | |
| 358 (CXFA_ContainerLayoutItem*)GetCurrentContainerRecord() | |
| 359 ->pCurPageSet->m_pParent; | |
| 360 } else { | |
| 361 pParentPageSetLayout = | |
| 362 (CXFA_ContainerLayoutItem*)pPageSet->GetNodeItem( | |
| 363 XFA_NODEITEM_Parent) | |
| 364 ->GetUserData(XFA_LAYOUTITEMKEY); | |
| 365 } | |
| 366 CXFA_ContainerLayoutItem* pPageSetLayoutItem = | |
| 367 new CXFA_ContainerLayoutItem(pPageSet); | |
| 368 pPageSet->SetUserData(XFA_LAYOUTITEMKEY, (void*)pPageSetLayoutItem); | |
| 369 if (pParentPageSetLayout == NULL) { | |
| 370 CXFA_ContainerLayoutItem* pPrePageSet = m_pPageSetLayoutItemRoot; | |
| 371 while (pPrePageSet->m_pNextSibling) { | |
| 372 pPrePageSet = (CXFA_ContainerLayoutItem*)pPrePageSet->m_pNextSibling; | |
| 373 } | |
| 374 pPrePageSet->m_pNextSibling = pPageSetLayoutItem; | |
| 375 m_pPageSetCurRoot = pPageSetLayoutItem; | |
| 376 } else { | |
| 377 pParentPageSetLayout->AddChild(pPageSetLayoutItem); | |
| 378 } | |
| 379 pNewRecord->pCurPageSet = pPageSetLayoutItem; | |
| 380 } | |
| 381 } else { | |
| 382 if (pPageNode) { | |
| 383 CXFA_Node* pPageSet = pPageNode->GetNodeItem(XFA_NODEITEM_Parent); | |
| 384 if (pPageSet == m_pTemplatePageSetRoot) { | |
| 385 pNewRecord->pCurPageSet = m_pPageSetLayoutItemRoot; | |
| 386 } else { | |
| 387 CXFA_ContainerLayoutItem* pPageSetLayoutItem = | |
| 388 new CXFA_ContainerLayoutItem(pPageSet); | |
| 389 pPageSet->SetUserData(XFA_LAYOUTITEMKEY, (void*)pPageSetLayoutItem); | |
| 390 m_pPageSetLayoutItemRoot->AddChild(pPageSetLayoutItem); | |
| 391 pNewRecord->pCurPageSet = pPageSetLayoutItem; | |
| 392 } | |
| 393 } else { | |
| 394 pNewRecord->pCurPageSet = m_pPageSetLayoutItemRoot; | |
| 395 } | |
| 396 } | |
| 397 m_rgProposedContainerRecord.AddTail(pNewRecord); | |
| 398 return pNewRecord; | |
| 399 } | |
| 400 void CXFA_LayoutPageMgr::AddPageAreaLayoutItem(CXFA_ContainerRecord* pNewRecord, | |
| 401 CXFA_Node* pNewPageArea) { | |
| 402 CXFA_ContainerLayoutItem* pNewPageAreaLayoutItem = NULL; | |
| 403 if (m_PageArray.GetSize() > m_nAvailPages) { | |
| 404 CXFA_ContainerLayoutItem* pContainerItem = m_PageArray[m_nAvailPages]; | |
| 405 pContainerItem->m_pFormNode = pNewPageArea; | |
| 406 m_nAvailPages++; | |
| 407 pNewPageAreaLayoutItem = pContainerItem; | |
| 408 } else { | |
| 409 IXFA_Notify* pNotify = | |
| 410 pNewPageArea->GetDocument()->GetParser()->GetNotify(); | |
| 411 CXFA_ContainerLayoutItem* pContainerItem = | |
| 412 (CXFA_ContainerLayoutItem*)pNotify->OnCreateLayoutItem(pNewPageArea); | |
| 413 m_PageArray.Add(pContainerItem); | |
| 414 m_nAvailPages++; | |
| 415 pNotify->OnPageEvent(pContainerItem, XFA_PAGEEVENT_PageAdded, | |
| 416 (void*)(uintptr_t)m_nAvailPages); | |
| 417 pNewPageAreaLayoutItem = pContainerItem; | |
| 418 } | |
| 419 pNewRecord->pCurPageSet->AddChild(pNewPageAreaLayoutItem); | |
| 420 pNewRecord->pCurPageArea = pNewPageAreaLayoutItem; | |
| 421 pNewRecord->pCurContentArea = NULL; | |
| 422 } | |
| 423 void CXFA_LayoutPageMgr::AddContentAreaLayoutItem( | |
| 424 CXFA_ContainerRecord* pNewRecord, | |
| 425 CXFA_Node* pContentArea) { | |
| 426 if (pContentArea == NULL) { | |
| 427 pNewRecord->pCurContentArea = NULL; | |
| 428 return; | |
| 429 } | |
| 430 CXFA_ContainerLayoutItem* pNewContentAreaLayoutItem = | |
| 431 new CXFA_ContainerLayoutItem(pContentArea); | |
| 432 ASSERT(pNewRecord->pCurPageArea); | |
| 433 pNewRecord->pCurPageArea->AddChild(pNewContentAreaLayoutItem); | |
| 434 pNewRecord->pCurContentArea = pNewContentAreaLayoutItem; | |
| 435 } | |
| 436 class CXFA_TraverseStrategy_PageSetContainerLayoutItem { | |
| 437 public: | |
| 438 static inline CXFA_ContainerLayoutItem* GetFirstChild( | |
| 439 CXFA_ContainerLayoutItem* pLayoutItem) { | |
| 440 if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_PageSet) { | |
| 441 CXFA_ContainerLayoutItem* pChildItem = | |
| 442 (CXFA_ContainerLayoutItem*)pLayoutItem->m_pFirstChild; | |
| 443 while (pChildItem && | |
| 444 pChildItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageSet) { | |
| 445 pChildItem = (CXFA_ContainerLayoutItem*)pChildItem->m_pNextSibling; | |
| 446 } | |
| 447 return pChildItem; | |
| 448 } | |
| 449 return NULL; | |
| 450 } | |
| 451 static inline CXFA_ContainerLayoutItem* GetNextSibling( | |
| 452 CXFA_ContainerLayoutItem* pLayoutItem) { | |
| 453 CXFA_ContainerLayoutItem* pChildItem = | |
| 454 (CXFA_ContainerLayoutItem*)pLayoutItem->m_pNextSibling; | |
| 455 while (pChildItem && | |
| 456 pChildItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageSet) { | |
| 457 pChildItem = (CXFA_ContainerLayoutItem*)pChildItem->m_pNextSibling; | |
| 458 } | |
| 459 return pChildItem; | |
| 460 } | |
| 461 static inline CXFA_ContainerLayoutItem* GetParent( | |
| 462 CXFA_ContainerLayoutItem* pLayoutItem) { | |
| 463 return (CXFA_ContainerLayoutItem*)pLayoutItem->m_pParent; | |
| 464 } | |
| 465 }; | |
| 466 void CXFA_LayoutPageMgr::FinishPaginatedPageSets() { | |
| 467 CXFA_ContainerLayoutItem* pRootPageSetLayoutItem = m_pPageSetLayoutItemRoot; | |
| 468 for (; pRootPageSetLayoutItem; | |
| 469 pRootPageSetLayoutItem = | |
| 470 (CXFA_ContainerLayoutItem*)pRootPageSetLayoutItem->m_pNextSibling) { | |
| 471 CXFA_NodeIteratorTemplate<CXFA_ContainerLayoutItem, | |
| 472 CXFA_TraverseStrategy_PageSetContainerLayoutItem> | |
| 473 sIterator(pRootPageSetLayoutItem); | |
| 474 for (CXFA_ContainerLayoutItem* pPageSetLayoutItem = sIterator.GetCurrent(); | |
| 475 pPageSetLayoutItem; pPageSetLayoutItem = sIterator.MoveToNext()) { | |
| 476 XFA_ATTRIBUTEENUM ePageRelation = | |
| 477 pPageSetLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Relation); | |
| 478 switch (ePageRelation) { | |
| 479 case XFA_ATTRIBUTEENUM_OrderedOccurrence: | |
| 480 default: { ProcessLastPageSet(); } break; | |
| 481 case XFA_ATTRIBUTEENUM_SimplexPaginated: | |
| 482 case XFA_ATTRIBUTEENUM_DuplexPaginated: { | |
| 483 CXFA_LayoutItem* pLastPageAreaLayoutItem = NULL; | |
| 484 int32_t nPageAreaCount = 0; | |
| 485 for (CXFA_LayoutItem* pPageAreaLayoutItem = | |
| 486 pPageSetLayoutItem->m_pFirstChild; | |
| 487 pPageAreaLayoutItem; | |
| 488 pPageAreaLayoutItem = pPageAreaLayoutItem->m_pNextSibling) { | |
| 489 if (pPageAreaLayoutItem->m_pFormNode->GetClassID() != | |
| 490 XFA_ELEMENT_PageArea) { | |
| 491 continue; | |
| 492 } | |
| 493 nPageAreaCount++; | |
| 494 pLastPageAreaLayoutItem = pPageAreaLayoutItem; | |
| 495 } | |
| 496 if (!pLastPageAreaLayoutItem) { | |
| 497 break; | |
| 498 } | |
| 499 if (!FindPageAreaFromPageSet_SimplexDuplex( | |
| 500 pPageSetLayoutItem->m_pFormNode, NULL, NULL, NULL, TRUE, TRUE, | |
| 501 nPageAreaCount == 1 ? XFA_ATTRIBUTEENUM_Only | |
| 502 : XFA_ATTRIBUTEENUM_Last) && | |
| 503 (nPageAreaCount == 1 && | |
| 504 !FindPageAreaFromPageSet_SimplexDuplex( | |
| 505 pPageSetLayoutItem->m_pFormNode, NULL, NULL, NULL, TRUE, | |
| 506 TRUE, XFA_ATTRIBUTEENUM_Last))) { | |
| 507 break; | |
| 508 } | |
| 509 CXFA_Node* pNode = m_pCurPageArea; | |
| 510 XFA_ATTRIBUTEENUM eCurChoice = | |
| 511 pNode->GetEnum(XFA_ATTRIBUTE_PagePosition); | |
| 512 if (eCurChoice == XFA_ATTRIBUTEENUM_Last) { | |
| 513 XFA_ATTRIBUTEENUM eOddOrEven = XFA_ATTRIBUTEENUM_Any; | |
| 514 pNode->TryEnum(XFA_ATTRIBUTE_OddOrEven, eOddOrEven); | |
| 515 XFA_ATTRIBUTEENUM eLastChoice = | |
| 516 pLastPageAreaLayoutItem->m_pFormNode->GetEnum( | |
| 517 XFA_ATTRIBUTE_PagePosition); | |
| 518 if (eLastChoice == XFA_ATTRIBUTEENUM_First && | |
| 519 (ePageRelation == XFA_ATTRIBUTEENUM_SimplexPaginated || | |
| 520 eOddOrEven != XFA_ATTRIBUTEENUM_Odd)) { | |
| 521 CXFA_ContainerRecord* pRecord = CreateContainerRecord(); | |
| 522 AddPageAreaLayoutItem(pRecord, pNode); | |
| 523 break; | |
| 524 } | |
| 525 } | |
| 526 FX_BOOL bUsable = TRUE; | |
| 527 CFX_ArrayTemplate<FX_FLOAT> rgUsedHeights; | |
| 528 for (CXFA_LayoutItem* pChildLayoutItem = | |
| 529 pLastPageAreaLayoutItem->m_pFirstChild; | |
| 530 pChildLayoutItem; | |
| 531 pChildLayoutItem = pChildLayoutItem->m_pNextSibling) { | |
| 532 if (pChildLayoutItem->m_pFormNode->GetClassID() != | |
| 533 XFA_ELEMENT_ContentArea) { | |
| 534 continue; | |
| 535 } | |
| 536 FX_FLOAT fUsedHeight = 0; | |
| 537 for (CXFA_LayoutItem* pContentChildLayoutItem = | |
| 538 pChildLayoutItem->m_pFirstChild; | |
| 539 pContentChildLayoutItem; | |
| 540 pContentChildLayoutItem = | |
| 541 pContentChildLayoutItem->m_pNextSibling) { | |
| 542 if (CXFA_ContentLayoutItem* pContent = | |
| 543 pContentChildLayoutItem->AsContentLayoutItem()) { | |
| 544 fUsedHeight += pContent->m_sSize.y; | |
| 545 } | |
| 546 } | |
| 547 rgUsedHeights.Add(fUsedHeight); | |
| 548 } | |
| 549 int32_t iCurContentAreaIndex = -1; | |
| 550 for (CXFA_Node* pContentAreaNode = | |
| 551 pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
| 552 pContentAreaNode; | |
| 553 pContentAreaNode = | |
| 554 pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
| 555 if (pContentAreaNode->GetClassID() != XFA_ELEMENT_ContentArea) { | |
| 556 continue; | |
| 557 } | |
| 558 iCurContentAreaIndex++; | |
| 559 if (rgUsedHeights[iCurContentAreaIndex] > | |
| 560 pContentAreaNode->GetMeasure(XFA_ATTRIBUTE_H) | |
| 561 .ToUnit(XFA_UNIT_Pt) + | |
| 562 XFA_LAYOUT_FLOAT_PERCISION) { | |
| 563 bUsable = FALSE; | |
| 564 break; | |
| 565 } | |
| 566 } | |
| 567 if (bUsable) { | |
| 568 CXFA_LayoutItem* pChildLayoutItem = | |
| 569 pLastPageAreaLayoutItem->m_pFirstChild; | |
| 570 CXFA_Node* pContentAreaNode = | |
| 571 pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
| 572 pLastPageAreaLayoutItem->m_pFormNode = pNode; | |
| 573 while (pChildLayoutItem && pContentAreaNode) { | |
| 574 if (pChildLayoutItem->m_pFormNode->GetClassID() != | |
| 575 XFA_ELEMENT_ContentArea) { | |
| 576 pChildLayoutItem = pChildLayoutItem->m_pNextSibling; | |
| 577 continue; | |
| 578 } | |
| 579 if (pContentAreaNode->GetClassID() != XFA_ELEMENT_ContentArea) { | |
| 580 pContentAreaNode = | |
| 581 pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling); | |
| 582 continue; | |
| 583 } | |
| 584 pChildLayoutItem->m_pFormNode = pContentAreaNode; | |
| 585 pChildLayoutItem = pChildLayoutItem->m_pNextSibling; | |
| 586 pContentAreaNode = | |
| 587 pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling); | |
| 588 } | |
| 589 } else if (pNode->GetEnum(XFA_ATTRIBUTE_PagePosition) == | |
| 590 XFA_ATTRIBUTEENUM_Last) { | |
| 591 CXFA_ContainerRecord* pRecord = CreateContainerRecord(); | |
| 592 AddPageAreaLayoutItem(pRecord, pNode); | |
| 593 } | |
| 594 } break; | |
| 595 } | |
| 596 } | |
| 597 } | |
| 598 } | |
| 599 int32_t CXFA_LayoutPageMgr::GetPageCount() const { | |
| 600 return m_PageArray.GetSize(); | |
| 601 } | |
| 602 IXFA_LayoutPage* CXFA_LayoutPageMgr::GetPage(int32_t index) const { | |
| 603 if (index < 0 || index >= m_PageArray.GetSize()) | |
| 604 return nullptr; | |
| 605 return m_PageArray[index]; | |
| 606 } | |
| 607 int32_t CXFA_LayoutPageMgr::GetPageIndex(const IXFA_LayoutPage* pPage) const { | |
| 608 // FIXME: Find() method should take const. | |
| 609 return m_PageArray.Find(static_cast<CXFA_ContainerLayoutItem*>( | |
| 610 const_cast<IXFA_LayoutPage*>(pPage))); | |
| 611 } | |
| 612 FX_BOOL CXFA_LayoutPageMgr::RunBreak(XFA_ELEMENT eBreakType, | |
| 613 XFA_ATTRIBUTEENUM eTargetType, | |
| 614 CXFA_Node* pTarget, | |
| 615 FX_BOOL bStartNew) { | |
| 616 FX_BOOL bRet = FALSE; | |
| 617 switch (eTargetType) { | |
| 618 case XFA_ATTRIBUTEENUM_ContentArea: | |
| 619 if (pTarget && pTarget->GetClassID() != XFA_ELEMENT_ContentArea) { | |
| 620 pTarget = NULL; | |
| 621 } | |
| 622 if (!pTarget || !m_pCurrentContainerRecord || | |
| 623 pTarget != | |
| 624 GetCurrentContainerRecord()->pCurContentArea->m_pFormNode || | |
| 625 bStartNew) { | |
| 626 CXFA_Node* pPageArea = NULL; | |
| 627 if (pTarget) { | |
| 628 pPageArea = pTarget->GetNodeItem(XFA_NODEITEM_Parent); | |
| 629 } | |
| 630 pPageArea = GetNextAvailPageArea(pPageArea, pTarget); | |
| 631 bRet = pPageArea != NULL; | |
| 632 } | |
| 633 break; | |
| 634 case XFA_ATTRIBUTEENUM_PageArea: | |
| 635 if (pTarget && pTarget->GetClassID() != XFA_ELEMENT_PageArea) { | |
| 636 pTarget = NULL; | |
| 637 } | |
| 638 if (!pTarget || !m_pCurrentContainerRecord || | |
| 639 pTarget != GetCurrentContainerRecord()->pCurPageArea->m_pFormNode || | |
| 640 bStartNew) { | |
| 641 CXFA_Node* pPageArea = GetNextAvailPageArea(pTarget, NULL, TRUE); | |
| 642 bRet = pPageArea != NULL; | |
| 643 } | |
| 644 break; | |
| 645 case XFA_ATTRIBUTEENUM_PageOdd: | |
| 646 if (pTarget && pTarget->GetClassID() != XFA_ELEMENT_PageArea) { | |
| 647 pTarget = NULL; | |
| 648 } | |
| 649 if (m_nAvailPages % 2 != 1 || !m_pCurrentContainerRecord || | |
| 650 (pTarget && | |
| 651 pTarget != GetCurrentContainerRecord()->pCurPageArea->m_pFormNode) || | |
| 652 bStartNew) { | |
| 653 if (m_nAvailPages % 2 == 1) { | |
| 654 } | |
| 655 } | |
| 656 break; | |
| 657 case XFA_ATTRIBUTEENUM_PageEven: | |
| 658 if (pTarget && pTarget->GetClassID() != XFA_ELEMENT_PageArea) { | |
| 659 pTarget = NULL; | |
| 660 } | |
| 661 if (m_nAvailPages % 2 != 0 || !m_pCurrentContainerRecord || | |
| 662 (pTarget && | |
| 663 pTarget != GetCurrentContainerRecord()->pCurPageArea->m_pFormNode) || | |
| 664 bStartNew) { | |
| 665 if (m_nAvailPages % 2 == 0) { | |
| 666 } | |
| 667 } | |
| 668 break; | |
| 669 case XFA_ATTRIBUTEENUM_Auto: | |
| 670 default: | |
| 671 break; | |
| 672 } | |
| 673 return bRet; | |
| 674 } | |
| 675 FX_BOOL CXFA_LayoutPageMgr::ExecuteBreakBeforeOrAfter( | |
| 676 CXFA_Node* pCurNode, | |
| 677 FX_BOOL bBefore, | |
| 678 CXFA_Node*& pBreakLeaderTemplate, | |
| 679 CXFA_Node*& pBreakTrailerTemplate) { | |
| 680 XFA_ELEMENT eType = pCurNode->GetClassID(); | |
| 681 switch (eType) { | |
| 682 case XFA_ELEMENT_BreakBefore: | |
| 683 case XFA_ELEMENT_BreakAfter: { | |
| 684 CFX_WideStringC wsBreakLeader, wsBreakTrailer; | |
| 685 CXFA_Node* pFormNode = pCurNode->GetNodeItem( | |
| 686 XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode); | |
| 687 CXFA_Node* pContainer = pFormNode->GetTemplateNode(); | |
| 688 FX_BOOL bStartNew = pCurNode->GetInteger(XFA_ATTRIBUTE_StartNew) != 0; | |
| 689 CXFA_Node* pScript = pCurNode->GetFirstChildByClass(XFA_ELEMENT_Script); | |
| 690 if (pScript && !XFA_LayoutPageMgr_RunBreakTestScript(pScript)) { | |
| 691 return FALSE; | |
| 692 } | |
| 693 CFX_WideStringC wsTarget = pCurNode->GetCData(XFA_ATTRIBUTE_Target); | |
| 694 CXFA_Node* pTarget = | |
| 695 XFA_ResolveBreakTarget(m_pTemplatePageSetRoot, TRUE, wsTarget); | |
| 696 wsBreakTrailer = pCurNode->GetCData(XFA_ATTRIBUTE_Trailer); | |
| 697 wsBreakLeader = pCurNode->GetCData(XFA_ATTRIBUTE_Leader); | |
| 698 pBreakLeaderTemplate = | |
| 699 XFA_ResolveBreakTarget(pContainer, TRUE, wsBreakLeader); | |
| 700 pBreakTrailerTemplate = | |
| 701 XFA_ResolveBreakTarget(pContainer, TRUE, wsBreakTrailer); | |
| 702 if (RunBreak(eType, pCurNode->GetEnum(XFA_ATTRIBUTE_TargetType), pTarget, | |
| 703 bStartNew)) { | |
| 704 return TRUE; | |
| 705 } else { | |
| 706 if (m_rgProposedContainerRecord.GetCount() > 0 && | |
| 707 m_pCurrentContainerRecord == | |
| 708 m_rgProposedContainerRecord.GetHeadPosition() && | |
| 709 eType == XFA_ELEMENT_BreakBefore) { | |
| 710 CXFA_Node* pParentNode = pFormNode->GetNodeItem( | |
| 711 XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode); | |
| 712 if (!pParentNode || | |
| 713 pFormNode != | |
| 714 pParentNode->GetNodeItem(XFA_NODEITEM_FirstChild, | |
| 715 XFA_OBJECTTYPE_ContainerNode)) { | |
| 716 break; | |
| 717 } | |
| 718 pParentNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent); | |
| 719 if (!pParentNode || pParentNode->GetClassID() != XFA_ELEMENT_Form) { | |
| 720 break; | |
| 721 } | |
| 722 return TRUE; | |
| 723 } | |
| 724 } | |
| 725 } break; | |
| 726 case XFA_ELEMENT_Break: { | |
| 727 FX_BOOL bStartNew = pCurNode->GetInteger(XFA_ATTRIBUTE_StartNew) != 0; | |
| 728 CFX_WideStringC wsTarget = pCurNode->GetCData( | |
| 729 bBefore ? XFA_ATTRIBUTE_BeforeTarget : XFA_ATTRIBUTE_AfterTarget); | |
| 730 CXFA_Node* pTarget = | |
| 731 XFA_ResolveBreakTarget(m_pTemplatePageSetRoot, TRUE, wsTarget); | |
| 732 if (RunBreak(bBefore ? XFA_ELEMENT_BreakBefore : XFA_ELEMENT_BreakAfter, | |
| 733 pCurNode->GetEnum(bBefore ? XFA_ATTRIBUTE_Before | |
| 734 : XFA_ATTRIBUTE_After), | |
| 735 pTarget, bStartNew)) { | |
| 736 return TRUE; | |
| 737 } | |
| 738 } break; | |
| 739 default: | |
| 740 break; | |
| 741 } | |
| 742 return FALSE; | |
| 743 } | |
| 744 static void XFA_SetLayoutGeneratedNodeFlag(CXFA_Node* pNode) { | |
| 745 pNode->SetFlag(XFA_NODEFLAG_LayoutGeneratedNode, TRUE, FALSE); | |
| 746 pNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE, FALSE); | |
| 747 } | |
| 748 FX_BOOL CXFA_LayoutPageMgr::ProcessBreakBeforeOrAfter( | |
| 749 CXFA_Node* pBreakNode, | |
| 750 FX_BOOL bBefore, | |
| 751 CXFA_Node*& pBreakLeaderNode, | |
| 752 CXFA_Node*& pBreakTrailerNode, | |
| 753 FX_BOOL& bCreatePage) { | |
| 754 CXFA_Node *pLeaderTemplate = NULL, *pTrailerTemplate = NULL; | |
| 755 CXFA_Node* pFormNode = pBreakNode->GetNodeItem(XFA_NODEITEM_Parent, | |
| 756 XFA_OBJECTTYPE_ContainerNode); | |
| 757 if (XFA_ItemLayoutProcessor_IsTakingSpace(pFormNode)) { | |
| 758 bCreatePage = ExecuteBreakBeforeOrAfter(pBreakNode, bBefore, | |
| 759 pLeaderTemplate, pTrailerTemplate); | |
| 760 CXFA_Document* pDocument = pBreakNode->GetDocument(); | |
| 761 CXFA_Node* pDataScope = NULL; | |
| 762 pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent, | |
| 763 XFA_OBJECTTYPE_ContainerNode); | |
| 764 if (pLeaderTemplate) { | |
| 765 if (!pDataScope) { | |
| 766 pDataScope = XFA_DataMerge_FindDataScope(pFormNode); | |
| 767 } | |
| 768 pBreakLeaderNode = pDocument->DataMerge_CopyContainer( | |
| 769 pLeaderTemplate, pFormNode, pDataScope, TRUE); | |
| 770 pDocument->DataMerge_UpdateBindingRelations(pBreakLeaderNode); | |
| 771 XFA_SetLayoutGeneratedNodeFlag(pBreakLeaderNode); | |
| 772 } | |
| 773 if (pTrailerTemplate) { | |
| 774 if (!pDataScope) { | |
| 775 pDataScope = XFA_DataMerge_FindDataScope(pFormNode); | |
| 776 } | |
| 777 pBreakTrailerNode = pDocument->DataMerge_CopyContainer( | |
| 778 pTrailerTemplate, pFormNode, pDataScope, TRUE); | |
| 779 pDocument->DataMerge_UpdateBindingRelations(pBreakTrailerNode); | |
| 780 XFA_SetLayoutGeneratedNodeFlag(pBreakTrailerNode); | |
| 781 } | |
| 782 return TRUE; | |
| 783 } | |
| 784 return FALSE; | |
| 785 } | |
| 786 FX_BOOL CXFA_LayoutPageMgr::ProcessBookendLeaderOrTrailer( | |
| 787 CXFA_Node* pBookendNode, | |
| 788 FX_BOOL bLeader, | |
| 789 CXFA_Node*& pBookendAppendNode) { | |
| 790 CXFA_Node* pLeaderTemplate = NULL; | |
| 791 CXFA_Node* pFormNode = pBookendNode->GetNodeItem( | |
| 792 XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode); | |
| 793 if (ResolveBookendLeaderOrTrailer(pBookendNode, bLeader, pLeaderTemplate)) { | |
| 794 CXFA_Document* pDocument = pBookendNode->GetDocument(); | |
| 795 CXFA_Node* pDataScope = NULL; | |
| 796 if (pLeaderTemplate) { | |
| 797 if (!pDataScope) { | |
| 798 pDataScope = XFA_DataMerge_FindDataScope(pFormNode); | |
| 799 } | |
| 800 pBookendAppendNode = pDocument->DataMerge_CopyContainer( | |
| 801 pLeaderTemplate, pFormNode, pDataScope, TRUE); | |
| 802 pDocument->DataMerge_UpdateBindingRelations(pBookendAppendNode); | |
| 803 XFA_SetLayoutGeneratedNodeFlag(pBookendAppendNode); | |
| 804 return TRUE; | |
| 805 } | |
| 806 } | |
| 807 return FALSE; | |
| 808 } | |
| 809 CXFA_Node* CXFA_LayoutPageMgr::BreakOverflow(CXFA_Node* pOverflowNode, | |
| 810 CXFA_Node*& pLeaderTemplate, | |
| 811 CXFA_Node*& pTrailerTemplate, | |
| 812 FX_BOOL bCreatePage) { | |
| 813 CFX_WideStringC wsOverflowLeader, wsOverflowTrailer; | |
| 814 CXFA_Node* pContainer = | |
| 815 pOverflowNode->GetNodeItem(XFA_NODEITEM_Parent, | |
| 816 XFA_OBJECTTYPE_ContainerNode) | |
| 817 ->GetTemplateNode(); | |
| 818 if (pOverflowNode->GetClassID() == XFA_ELEMENT_Break) { | |
| 819 CFX_WideStringC wsOverflowLeader; | |
| 820 CFX_WideStringC wsOverflowTarget; | |
| 821 CFX_WideStringC wsOverflowTrailer; | |
| 822 pOverflowNode->TryCData(XFA_ATTRIBUTE_OverflowLeader, wsOverflowLeader); | |
| 823 pOverflowNode->TryCData(XFA_ATTRIBUTE_OverflowTrailer, wsOverflowTrailer); | |
| 824 pOverflowNode->TryCData(XFA_ATTRIBUTE_OverflowTarget, wsOverflowTarget); | |
| 825 if (!wsOverflowLeader.IsEmpty() || !wsOverflowTrailer.IsEmpty() || | |
| 826 !wsOverflowTarget.IsEmpty()) { | |
| 827 if (!wsOverflowTarget.IsEmpty() && bCreatePage && | |
| 828 !m_bCreateOverFlowPage) { | |
| 829 CXFA_Node* pTarget = XFA_ResolveBreakTarget(m_pTemplatePageSetRoot, | |
| 830 TRUE, wsOverflowTarget); | |
| 831 if (pTarget) { | |
| 832 m_bCreateOverFlowPage = TRUE; | |
| 833 switch (pTarget->GetClassID()) { | |
| 834 case XFA_ELEMENT_PageArea: | |
| 835 RunBreak(XFA_ELEMENT_Overflow, XFA_ATTRIBUTEENUM_PageArea, | |
| 836 pTarget, TRUE); | |
| 837 break; | |
| 838 case XFA_ELEMENT_ContentArea: | |
| 839 RunBreak(XFA_ELEMENT_Overflow, XFA_ATTRIBUTEENUM_ContentArea, | |
| 840 pTarget, TRUE); | |
| 841 break; | |
| 842 default: | |
| 843 break; | |
| 844 } | |
| 845 } | |
| 846 } | |
| 847 if (!bCreatePage) { | |
| 848 pLeaderTemplate = | |
| 849 XFA_ResolveBreakTarget(pContainer, TRUE, wsOverflowLeader); | |
| 850 pTrailerTemplate = | |
| 851 XFA_ResolveBreakTarget(pContainer, TRUE, wsOverflowTrailer); | |
| 852 } | |
| 853 return pOverflowNode; | |
| 854 } | |
| 855 return NULL; | |
| 856 } else if (pOverflowNode->GetClassID() == XFA_ELEMENT_Overflow) { | |
| 857 CFX_WideStringC wsOverflowTarget; | |
| 858 pOverflowNode->TryCData(XFA_ATTRIBUTE_Leader, wsOverflowLeader); | |
| 859 pOverflowNode->TryCData(XFA_ATTRIBUTE_Trailer, wsOverflowTrailer); | |
| 860 pOverflowNode->TryCData(XFA_ATTRIBUTE_Target, wsOverflowTarget); | |
| 861 if (!wsOverflowTarget.IsEmpty() && bCreatePage && !m_bCreateOverFlowPage) { | |
| 862 CXFA_Node* pTarget = XFA_ResolveBreakTarget(m_pTemplatePageSetRoot, TRUE, | |
| 863 wsOverflowTarget); | |
| 864 if (pTarget) { | |
| 865 m_bCreateOverFlowPage = TRUE; | |
| 866 switch (pTarget->GetClassID()) { | |
| 867 case XFA_ELEMENT_PageArea: | |
| 868 RunBreak(XFA_ELEMENT_Overflow, XFA_ATTRIBUTEENUM_PageArea, pTarget, | |
| 869 TRUE); | |
| 870 break; | |
| 871 case XFA_ELEMENT_ContentArea: | |
| 872 RunBreak(XFA_ELEMENT_Overflow, XFA_ATTRIBUTEENUM_ContentArea, | |
| 873 pTarget, TRUE); | |
| 874 break; | |
| 875 default: | |
| 876 break; | |
| 877 } | |
| 878 } | |
| 879 } | |
| 880 if (!bCreatePage) { | |
| 881 pLeaderTemplate = | |
| 882 XFA_ResolveBreakTarget(pContainer, TRUE, wsOverflowLeader); | |
| 883 pTrailerTemplate = | |
| 884 XFA_ResolveBreakTarget(pContainer, TRUE, wsOverflowTrailer); | |
| 885 } | |
| 886 return pOverflowNode; | |
| 887 } | |
| 888 return NULL; | |
| 889 } | |
| 890 FX_BOOL CXFA_LayoutPageMgr::ProcessOverflow(CXFA_Node* pFormNode, | |
| 891 CXFA_Node*& pLeaderNode, | |
| 892 CXFA_Node*& pTrailerNode, | |
| 893 FX_BOOL bDataMerge, | |
| 894 FX_BOOL bCreatePage) { | |
| 895 if (pFormNode == NULL) { | |
| 896 return FALSE; | |
| 897 } | |
| 898 CXFA_Node *pLeaderTemplate = NULL, *pTrailerTemplate = NULL; | |
| 899 FX_BOOL bIsOverflowNode = FALSE; | |
| 900 if (pFormNode->GetClassID() == XFA_ELEMENT_Overflow || | |
| 901 pFormNode->GetClassID() == XFA_ELEMENT_Break) { | |
| 902 bIsOverflowNode = TRUE; | |
| 903 } | |
| 904 for (CXFA_Node* pCurNode = | |
| 905 bIsOverflowNode ? pFormNode | |
| 906 : pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
| 907 pCurNode; pCurNode = pCurNode->GetNodeItem((XFA_NODEITEM_NextSibling))) { | |
| 908 if (BreakOverflow(pCurNode, pLeaderTemplate, pTrailerTemplate, | |
| 909 bCreatePage)) { | |
| 910 if (bIsOverflowNode) { | |
| 911 pFormNode = pCurNode->GetNodeItem(XFA_NODEITEM_Parent); | |
| 912 } | |
| 913 CXFA_Document* pDocument = pCurNode->GetDocument(); | |
| 914 CXFA_Node* pDataScope = NULL; | |
| 915 if (pLeaderTemplate) { | |
| 916 if (!pDataScope) { | |
| 917 pDataScope = XFA_DataMerge_FindDataScope(pFormNode); | |
| 918 } | |
| 919 pLeaderNode = pDocument->DataMerge_CopyContainer( | |
| 920 pLeaderTemplate, pFormNode, pDataScope, TRUE); | |
| 921 pDocument->DataMerge_UpdateBindingRelations(pLeaderNode); | |
| 922 XFA_SetLayoutGeneratedNodeFlag(pLeaderNode); | |
| 923 } | |
| 924 if (pTrailerTemplate) { | |
| 925 if (!pDataScope) { | |
| 926 pDataScope = XFA_DataMerge_FindDataScope(pFormNode); | |
| 927 } | |
| 928 pTrailerNode = pDocument->DataMerge_CopyContainer( | |
| 929 pTrailerTemplate, pFormNode, pDataScope, TRUE); | |
| 930 pDocument->DataMerge_UpdateBindingRelations(pTrailerNode); | |
| 931 XFA_SetLayoutGeneratedNodeFlag(pTrailerNode); | |
| 932 } | |
| 933 return TRUE; | |
| 934 } | |
| 935 if (bIsOverflowNode) { | |
| 936 break; | |
| 937 } | |
| 938 } | |
| 939 return FALSE; | |
| 940 } | |
| 941 FX_BOOL CXFA_LayoutPageMgr::ResolveBookendLeaderOrTrailer( | |
| 942 CXFA_Node* pBookendNode, | |
| 943 FX_BOOL bLeader, | |
| 944 CXFA_Node*& pBookendAppendTemplate) { | |
| 945 CFX_WideStringC wsBookendLeader; | |
| 946 CXFA_Node* pContainer = | |
| 947 pBookendNode->GetNodeItem(XFA_NODEITEM_Parent, | |
| 948 XFA_OBJECTTYPE_ContainerNode) | |
| 949 ->GetTemplateNode(); | |
| 950 if (pBookendNode->GetClassID() == XFA_ELEMENT_Break) { | |
| 951 pBookendNode->TryCData( | |
| 952 bLeader ? XFA_ATTRIBUTE_BookendLeader : XFA_ATTRIBUTE_BookendTrailer, | |
| 953 wsBookendLeader); | |
| 954 if (!wsBookendLeader.IsEmpty()) { | |
| 955 pBookendAppendTemplate = | |
| 956 XFA_ResolveBreakTarget(pContainer, FALSE, wsBookendLeader); | |
| 957 return TRUE; | |
| 958 } | |
| 959 return FALSE; | |
| 960 } else if (pBookendNode->GetClassID() == XFA_ELEMENT_Bookend) { | |
| 961 pBookendNode->TryCData( | |
| 962 bLeader ? XFA_ATTRIBUTE_Leader : XFA_ATTRIBUTE_Trailer, | |
| 963 wsBookendLeader); | |
| 964 pBookendAppendTemplate = | |
| 965 XFA_ResolveBreakTarget(pContainer, TRUE, wsBookendLeader); | |
| 966 return TRUE; | |
| 967 } | |
| 968 return FALSE; | |
| 969 } | |
| 970 FX_BOOL CXFA_LayoutPageMgr::FindPageAreaFromPageSet( | |
| 971 CXFA_Node* pPageSet, | |
| 972 CXFA_Node* pStartChild, | |
| 973 CXFA_Node* pTargetPageArea, | |
| 974 CXFA_Node* pTargetContentArea, | |
| 975 FX_BOOL bNewPage, | |
| 976 FX_BOOL bQuery) { | |
| 977 if (pPageSet == NULL && pStartChild == NULL) { | |
| 978 return FALSE; | |
| 979 } | |
| 980 if (IsPageSetRootOrderedOccurrence()) { | |
| 981 return FindPageAreaFromPageSet_Ordered(pPageSet, pStartChild, | |
| 982 pTargetPageArea, pTargetContentArea, | |
| 983 bNewPage, bQuery); | |
| 984 } | |
| 985 XFA_ATTRIBUTEENUM ePreferredPosition = m_pCurrentContainerRecord | |
| 986 ? XFA_ATTRIBUTEENUM_Rest | |
| 987 : XFA_ATTRIBUTEENUM_First; | |
| 988 return FindPageAreaFromPageSet_SimplexDuplex( | |
| 989 pPageSet, pStartChild, pTargetPageArea, pTargetContentArea, bNewPage, | |
| 990 bQuery, ePreferredPosition); | |
| 991 } | |
| 992 FX_BOOL CXFA_LayoutPageMgr::FindPageAreaFromPageSet_Ordered( | |
| 993 CXFA_Node* pPageSet, | |
| 994 CXFA_Node* pStartChild, | |
| 995 CXFA_Node* pTargetPageArea, | |
| 996 CXFA_Node* pTargetContentArea, | |
| 997 FX_BOOL bNewPage, | |
| 998 FX_BOOL bQuery) { | |
| 999 int32_t iPageSetCount = 0; | |
| 1000 if (!pStartChild && !bQuery) { | |
| 1001 m_pPageSetMap.Lookup(pPageSet, iPageSetCount); | |
| 1002 int32_t iMax = -1; | |
| 1003 CXFA_Node* pOccurNode = pPageSet->GetFirstChildByClass(XFA_ELEMENT_Occur); | |
| 1004 if (pOccurNode) { | |
| 1005 pOccurNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE); | |
| 1006 } | |
| 1007 if (iMax >= 0 && iMax <= iPageSetCount) { | |
| 1008 return FALSE; | |
| 1009 } | |
| 1010 } | |
| 1011 FX_BOOL bRes = FALSE; | |
| 1012 CXFA_Node* pCurrentNode = | |
| 1013 pStartChild ? pStartChild->GetNodeItem(XFA_NODEITEM_NextSibling) | |
| 1014 : pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild); | |
| 1015 for (; pCurrentNode; | |
| 1016 pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
| 1017 if (pCurrentNode->GetClassID() == XFA_ELEMENT_PageArea) { | |
| 1018 if ((pTargetPageArea == pCurrentNode || pTargetPageArea == NULL)) { | |
| 1019 if (pCurrentNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea) == | |
| 1020 NULL) { | |
| 1021 if (pTargetPageArea == pCurrentNode) { | |
| 1022 CreateMinPageRecord(pCurrentNode, TRUE); | |
| 1023 pTargetPageArea = NULL; | |
| 1024 } | |
| 1025 continue; | |
| 1026 } | |
| 1027 if (!bQuery) { | |
| 1028 CXFA_ContainerRecord* pNewRecord = | |
| 1029 CreateContainerRecord(pCurrentNode, pStartChild == NULL); | |
| 1030 AddPageAreaLayoutItem(pNewRecord, pCurrentNode); | |
| 1031 if (pTargetContentArea == NULL) { | |
| 1032 pTargetContentArea = | |
| 1033 pCurrentNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea); | |
| 1034 } | |
| 1035 AddContentAreaLayoutItem(pNewRecord, pTargetContentArea); | |
| 1036 } | |
| 1037 m_pCurPageArea = pCurrentNode; | |
| 1038 m_nCurPageCount = 1; | |
| 1039 bRes = TRUE; | |
| 1040 break; | |
| 1041 } | |
| 1042 if (!bQuery) { | |
| 1043 CreateMinPageRecord(pCurrentNode, FALSE); | |
| 1044 } | |
| 1045 } else if (pCurrentNode->GetClassID() == XFA_ELEMENT_PageSet) { | |
| 1046 if (FindPageAreaFromPageSet_Ordered(pCurrentNode, NULL, pTargetPageArea, | |
| 1047 pTargetContentArea, bNewPage, | |
| 1048 bQuery)) { | |
| 1049 bRes = TRUE; | |
| 1050 break; | |
| 1051 } | |
| 1052 if (!bQuery) { | |
| 1053 CreateMinPageSetRecord(pCurrentNode, TRUE); | |
| 1054 } | |
| 1055 } | |
| 1056 } | |
| 1057 if (!pStartChild && bRes && !bQuery) { | |
| 1058 m_pPageSetMap.SetAt(pPageSet, ++iPageSetCount); | |
| 1059 } | |
| 1060 return bRes; | |
| 1061 } | |
| 1062 FX_BOOL CXFA_LayoutPageMgr::FindPageAreaFromPageSet_SimplexDuplex( | |
| 1063 CXFA_Node* pPageSet, | |
| 1064 CXFA_Node* pStartChild, | |
| 1065 CXFA_Node* pTargetPageArea, | |
| 1066 CXFA_Node* pTargetContentArea, | |
| 1067 FX_BOOL bNewPage, | |
| 1068 FX_BOOL bQuery, | |
| 1069 XFA_ATTRIBUTEENUM ePreferredPosition) { | |
| 1070 const XFA_ATTRIBUTEENUM eFallbackPosition = XFA_ATTRIBUTEENUM_Any; | |
| 1071 CXFA_Node *pPreferredPageArea = NULL, *pFallbackPageArea = NULL; | |
| 1072 CXFA_Node* pCurrentNode = NULL; | |
| 1073 if (!pStartChild || pStartChild->GetClassID() == XFA_ELEMENT_PageArea) { | |
| 1074 pCurrentNode = pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild); | |
| 1075 } else { | |
| 1076 pCurrentNode = pStartChild->GetNodeItem(XFA_NODEITEM_NextSibling); | |
| 1077 } | |
| 1078 for (; pCurrentNode; | |
| 1079 pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
| 1080 if (pCurrentNode->GetClassID() == XFA_ELEMENT_PageArea) { | |
| 1081 if (!MatchPageAreaOddOrEven(pCurrentNode, FALSE)) { | |
| 1082 continue; | |
| 1083 } | |
| 1084 XFA_ATTRIBUTEENUM eCurPagePosition = | |
| 1085 pCurrentNode->GetEnum(XFA_ATTRIBUTE_PagePosition); | |
| 1086 if (ePreferredPosition == XFA_ATTRIBUTEENUM_Last) { | |
| 1087 if (eCurPagePosition != ePreferredPosition) { | |
| 1088 continue; | |
| 1089 } | |
| 1090 if (m_ePageSetMode == XFA_ATTRIBUTEENUM_SimplexPaginated || | |
| 1091 pCurrentNode->GetEnum(XFA_ATTRIBUTE_OddOrEven) == | |
| 1092 XFA_ATTRIBUTEENUM_Any) { | |
| 1093 pPreferredPageArea = pCurrentNode; | |
| 1094 break; | |
| 1095 } | |
| 1096 CXFA_ContainerRecord* pNewRecord = CreateContainerRecord(); | |
| 1097 AddPageAreaLayoutItem(pNewRecord, pCurrentNode); | |
| 1098 AddContentAreaLayoutItem(pNewRecord, pCurrentNode->GetFirstChildByClass( | |
| 1099 XFA_ELEMENT_ContentArea)); | |
| 1100 pPreferredPageArea = pCurrentNode; | |
| 1101 return FALSE; | |
| 1102 } else if (ePreferredPosition == XFA_ATTRIBUTEENUM_Only) { | |
| 1103 if (eCurPagePosition != ePreferredPosition) { | |
| 1104 continue; | |
| 1105 } | |
| 1106 if (m_ePageSetMode != XFA_ATTRIBUTEENUM_DuplexPaginated || | |
| 1107 pCurrentNode->GetEnum(XFA_ATTRIBUTE_OddOrEven) == | |
| 1108 XFA_ATTRIBUTEENUM_Any) { | |
| 1109 pPreferredPageArea = pCurrentNode; | |
| 1110 break; | |
| 1111 } | |
| 1112 return FALSE; | |
| 1113 } | |
| 1114 if ((pTargetPageArea == pCurrentNode || pTargetPageArea == NULL)) { | |
| 1115 if (pCurrentNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea) == | |
| 1116 NULL) { | |
| 1117 if (pTargetPageArea == pCurrentNode) { | |
| 1118 CXFA_ContainerRecord* pNewRecord = CreateContainerRecord(); | |
| 1119 AddPageAreaLayoutItem(pNewRecord, pCurrentNode); | |
| 1120 pTargetPageArea = NULL; | |
| 1121 } | |
| 1122 continue; | |
| 1123 } | |
| 1124 if ((ePreferredPosition == XFA_ATTRIBUTEENUM_Rest && | |
| 1125 eCurPagePosition == XFA_ATTRIBUTEENUM_Any) || | |
| 1126 eCurPagePosition == ePreferredPosition) { | |
| 1127 pPreferredPageArea = pCurrentNode; | |
| 1128 break; | |
| 1129 } else if (eCurPagePosition == eFallbackPosition && | |
| 1130 !pFallbackPageArea) { | |
| 1131 pFallbackPageArea = pCurrentNode; | |
| 1132 } | |
| 1133 } else if (pTargetPageArea && | |
| 1134 !MatchPageAreaOddOrEven(pTargetPageArea, FALSE)) { | |
| 1135 CXFA_ContainerRecord* pNewRecord = CreateContainerRecord(); | |
| 1136 AddPageAreaLayoutItem(pNewRecord, pCurrentNode); | |
| 1137 AddContentAreaLayoutItem(pNewRecord, pCurrentNode->GetFirstChildByClass( | |
| 1138 XFA_ELEMENT_ContentArea)); | |
| 1139 } | |
| 1140 } else if (pCurrentNode->GetClassID() == XFA_ELEMENT_PageSet) { | |
| 1141 if (FindPageAreaFromPageSet_SimplexDuplex( | |
| 1142 pCurrentNode, NULL, pTargetPageArea, pTargetContentArea, bNewPage, | |
| 1143 bQuery, ePreferredPosition)) { | |
| 1144 break; | |
| 1145 } | |
| 1146 } | |
| 1147 } | |
| 1148 CXFA_Node* pCurPageArea = NULL; | |
| 1149 if (pPreferredPageArea) { | |
| 1150 pCurPageArea = pPreferredPageArea; | |
| 1151 } else if (pFallbackPageArea) { | |
| 1152 pCurPageArea = pFallbackPageArea; | |
| 1153 } | |
| 1154 if (!pCurPageArea) { | |
| 1155 return FALSE; | |
| 1156 } | |
| 1157 if (!bQuery) { | |
| 1158 CXFA_ContainerRecord* pNewRecord = CreateContainerRecord(); | |
| 1159 AddPageAreaLayoutItem(pNewRecord, pCurPageArea); | |
| 1160 if (pTargetContentArea == NULL) { | |
| 1161 pTargetContentArea = | |
| 1162 pCurPageArea->GetFirstChildByClass(XFA_ELEMENT_ContentArea); | |
| 1163 } | |
| 1164 AddContentAreaLayoutItem(pNewRecord, pTargetContentArea); | |
| 1165 } | |
| 1166 m_pCurPageArea = pCurPageArea; | |
| 1167 return TRUE; | |
| 1168 } | |
| 1169 FX_BOOL CXFA_LayoutPageMgr::MatchPageAreaOddOrEven(CXFA_Node* pPageArea, | |
| 1170 FX_BOOL bLastMatch) { | |
| 1171 if (m_ePageSetMode != XFA_ATTRIBUTEENUM_DuplexPaginated) { | |
| 1172 return TRUE; | |
| 1173 } | |
| 1174 XFA_ATTRIBUTEENUM eOddOrEven = XFA_ATTRIBUTEENUM_Any; | |
| 1175 pPageArea->TryEnum(XFA_ATTRIBUTE_OddOrEven, eOddOrEven); | |
| 1176 if (eOddOrEven != XFA_ATTRIBUTEENUM_Any) { | |
| 1177 int32_t iPageCount = GetPageCount(); | |
| 1178 if (bLastMatch) { | |
| 1179 return eOddOrEven == XFA_ATTRIBUTEENUM_Odd ? iPageCount % 2 == 1 | |
| 1180 : iPageCount % 2 == 0; | |
| 1181 } | |
| 1182 return eOddOrEven == XFA_ATTRIBUTEENUM_Odd ? iPageCount % 2 == 0 | |
| 1183 : iPageCount % 2 == 1; | |
| 1184 } | |
| 1185 return TRUE; | |
| 1186 } | |
| 1187 CXFA_Node* CXFA_LayoutPageMgr::GetNextAvailPageArea( | |
| 1188 CXFA_Node* pTargetPageArea, | |
| 1189 CXFA_Node* pTargetContentArea, | |
| 1190 FX_BOOL bNewPage, | |
| 1191 FX_BOOL bQuery) { | |
| 1192 if (m_pCurPageArea == NULL) { | |
| 1193 FindPageAreaFromPageSet(m_pTemplatePageSetRoot, NULL, pTargetPageArea, | |
| 1194 pTargetContentArea, bNewPage, bQuery); | |
| 1195 ASSERT(m_pCurPageArea); | |
| 1196 return m_pCurPageArea; | |
| 1197 } | |
| 1198 if (pTargetPageArea == NULL || pTargetPageArea == m_pCurPageArea) { | |
| 1199 if (!bNewPage && GetNextContentArea(pTargetContentArea)) { | |
| 1200 return m_pCurPageArea; | |
| 1201 } | |
| 1202 if (IsPageSetRootOrderedOccurrence()) { | |
| 1203 int32_t iMax = -1; | |
| 1204 CXFA_Node* pOccurNode = | |
| 1205 m_pCurPageArea->GetFirstChildByClass(XFA_ELEMENT_Occur); | |
| 1206 if (pOccurNode) { | |
| 1207 pOccurNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE); | |
| 1208 } | |
| 1209 if ((iMax < 0 || m_nCurPageCount < iMax)) { | |
| 1210 if (!bQuery) { | |
| 1211 CXFA_ContainerRecord* pNewRecord = | |
| 1212 CreateContainerRecord(m_pCurPageArea); | |
| 1213 AddPageAreaLayoutItem(pNewRecord, m_pCurPageArea); | |
| 1214 if (pTargetContentArea == NULL) { | |
| 1215 pTargetContentArea = | |
| 1216 m_pCurPageArea->GetFirstChildByClass(XFA_ELEMENT_ContentArea); | |
| 1217 } | |
| 1218 AddContentAreaLayoutItem(pNewRecord, pTargetContentArea); | |
| 1219 } | |
| 1220 m_nCurPageCount++; | |
| 1221 return m_pCurPageArea; | |
| 1222 } | |
| 1223 } | |
| 1224 } | |
| 1225 if (!bQuery && IsPageSetRootOrderedOccurrence()) { | |
| 1226 CreateMinPageRecord(m_pCurPageArea, FALSE, TRUE); | |
| 1227 } | |
| 1228 if (FindPageAreaFromPageSet(m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent), | |
| 1229 m_pCurPageArea, pTargetPageArea, | |
| 1230 pTargetContentArea, bNewPage, bQuery)) { | |
| 1231 return m_pCurPageArea; | |
| 1232 } | |
| 1233 CXFA_Node* pPageSet = m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent); | |
| 1234 while (TRUE) { | |
| 1235 if (FindPageAreaFromPageSet(pPageSet, NULL, pTargetPageArea, | |
| 1236 pTargetContentArea, bNewPage, bQuery)) { | |
| 1237 return m_pCurPageArea; | |
| 1238 } | |
| 1239 if (!bQuery && IsPageSetRootOrderedOccurrence()) { | |
| 1240 CreateMinPageSetRecord(pPageSet); | |
| 1241 } | |
| 1242 if (FindPageAreaFromPageSet(NULL, pPageSet, pTargetPageArea, | |
| 1243 pTargetContentArea, bNewPage, bQuery)) { | |
| 1244 return m_pCurPageArea; | |
| 1245 } | |
| 1246 if (pPageSet == m_pTemplatePageSetRoot) { | |
| 1247 break; | |
| 1248 } | |
| 1249 pPageSet = pPageSet->GetNodeItem(XFA_NODEITEM_Parent); | |
| 1250 } | |
| 1251 return NULL; | |
| 1252 } | |
| 1253 static FX_BOOL XFA_LayoutPageMgr_CheckContentAreaNotUsed( | |
| 1254 CXFA_ContainerLayoutItem* pPageAreaLayoutItem, | |
| 1255 CXFA_Node* pContentArea, | |
| 1256 CXFA_ContainerLayoutItem*& pContentAreaLayoutItem) { | |
| 1257 for (CXFA_ContainerLayoutItem* pLayoutItem = | |
| 1258 (CXFA_ContainerLayoutItem*)pPageAreaLayoutItem->m_pFirstChild; | |
| 1259 pLayoutItem; | |
| 1260 pLayoutItem = (CXFA_ContainerLayoutItem*)pLayoutItem->m_pNextSibling) { | |
| 1261 if (pLayoutItem->m_pFormNode == pContentArea) { | |
| 1262 if (pLayoutItem->m_pFirstChild == NULL) { | |
| 1263 pContentAreaLayoutItem = pLayoutItem; | |
| 1264 return TRUE; | |
| 1265 } | |
| 1266 return FALSE; | |
| 1267 } | |
| 1268 } | |
| 1269 return TRUE; | |
| 1270 } | |
| 1271 FX_BOOL CXFA_LayoutPageMgr::GetNextContentArea(CXFA_Node* pContentArea) { | |
| 1272 CXFA_Node* pCurContentNode = | |
| 1273 GetCurrentContainerRecord()->pCurContentArea->m_pFormNode; | |
| 1274 if (pContentArea == NULL) { | |
| 1275 pContentArea = | |
| 1276 pCurContentNode->GetNextSameClassSibling(XFA_ELEMENT_ContentArea); | |
| 1277 if (pContentArea == NULL) { | |
| 1278 return FALSE; | |
| 1279 } | |
| 1280 } else { | |
| 1281 if (pContentArea->GetNodeItem(XFA_NODEITEM_Parent) != m_pCurPageArea) { | |
| 1282 return FALSE; | |
| 1283 } | |
| 1284 CXFA_ContainerLayoutItem* pContentAreaLayout = NULL; | |
| 1285 if (!XFA_LayoutPageMgr_CheckContentAreaNotUsed( | |
| 1286 GetCurrentContainerRecord()->pCurPageArea, pContentArea, | |
| 1287 pContentAreaLayout)) { | |
| 1288 return FALSE; | |
| 1289 } | |
| 1290 if (pContentAreaLayout) { | |
| 1291 if (pContentAreaLayout->m_pFormNode != pCurContentNode) { | |
| 1292 CXFA_ContainerRecord* pNewRecord = CreateContainerRecord(); | |
| 1293 pNewRecord->pCurContentArea = pContentAreaLayout; | |
| 1294 return TRUE; | |
| 1295 } else { | |
| 1296 return FALSE; | |
| 1297 } | |
| 1298 } | |
| 1299 } | |
| 1300 CXFA_ContainerRecord* pNewRecord = CreateContainerRecord(); | |
| 1301 AddContentAreaLayoutItem(pNewRecord, pContentArea); | |
| 1302 return TRUE; | |
| 1303 } | |
| 1304 void CXFA_LayoutPageMgr::InitPageSetMap() { | |
| 1305 if (!IsPageSetRootOrderedOccurrence()) { | |
| 1306 return; | |
| 1307 } | |
| 1308 CXFA_NodeIterator sIterator(m_pTemplatePageSetRoot); | |
| 1309 for (CXFA_Node* pPageSetNode = sIterator.GetCurrent(); pPageSetNode; | |
| 1310 pPageSetNode = sIterator.MoveToNext()) { | |
| 1311 if (pPageSetNode->GetClassID() == XFA_ELEMENT_PageSet) { | |
| 1312 XFA_ATTRIBUTEENUM eRelation = | |
| 1313 pPageSetNode->GetEnum(XFA_ATTRIBUTE_Relation); | |
| 1314 if (eRelation == XFA_ATTRIBUTEENUM_OrderedOccurrence) { | |
| 1315 m_pPageSetMap.SetAt(pPageSetNode, 0); | |
| 1316 } | |
| 1317 } | |
| 1318 } | |
| 1319 } | |
| 1320 int32_t CXFA_LayoutPageMgr::CreateMinPageRecord(CXFA_Node* pPageArea, | |
| 1321 FX_BOOL bTargetPageArea, | |
| 1322 FX_BOOL bCreateLast) { | |
| 1323 if (pPageArea == NULL) { | |
| 1324 return 0; | |
| 1325 } | |
| 1326 CXFA_Node* pOccurNode = pPageArea->GetFirstChildByClass(XFA_ELEMENT_Occur); | |
| 1327 int32_t iMin = 0; | |
| 1328 if ((pOccurNode && pOccurNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, FALSE)) || | |
| 1329 bTargetPageArea) { | |
| 1330 CXFA_Node* pContentArea = | |
| 1331 pPageArea->GetFirstChildByClass(XFA_ELEMENT_ContentArea); | |
| 1332 if (iMin < 1 && bTargetPageArea && !pContentArea) { | |
| 1333 iMin = 1; | |
| 1334 } | |
| 1335 int32_t i = 0; | |
| 1336 if (bCreateLast) { | |
| 1337 i = m_nCurPageCount; | |
| 1338 } | |
| 1339 for (; i < iMin; i++) { | |
| 1340 CXFA_ContainerRecord* pNewRecord = CreateContainerRecord(); | |
| 1341 AddPageAreaLayoutItem(pNewRecord, pPageArea); | |
| 1342 AddContentAreaLayoutItem(pNewRecord, pContentArea); | |
| 1343 } | |
| 1344 } | |
| 1345 return iMin; | |
| 1346 } | |
| 1347 void CXFA_LayoutPageMgr::CreateMinPageSetRecord(CXFA_Node* pPageSet, | |
| 1348 FX_BOOL bCreateAll) { | |
| 1349 if (pPageSet == NULL) { | |
| 1350 return; | |
| 1351 } | |
| 1352 int32_t iCurSetCount = 0; | |
| 1353 if (!m_pPageSetMap.Lookup(pPageSet, iCurSetCount)) { | |
| 1354 return; | |
| 1355 } | |
| 1356 if (bCreateAll) { | |
| 1357 iCurSetCount = 0; | |
| 1358 } | |
| 1359 CXFA_Node* pOccurNode = pPageSet->GetFirstChildByClass(XFA_ELEMENT_Occur); | |
| 1360 int32_t iMin = 0; | |
| 1361 if (pOccurNode && pOccurNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, FALSE)) { | |
| 1362 if (iCurSetCount < iMin) { | |
| 1363 for (int32_t i = 0; i < iMin - iCurSetCount; i++) { | |
| 1364 for (CXFA_Node* pCurrentPageNode = | |
| 1365 pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild); | |
| 1366 pCurrentPageNode; pCurrentPageNode = pCurrentPageNode->GetNodeItem( | |
| 1367 XFA_NODEITEM_NextSibling)) { | |
| 1368 if (pCurrentPageNode->GetClassID() == XFA_ELEMENT_PageArea) { | |
| 1369 CreateMinPageRecord(pCurrentPageNode, FALSE); | |
| 1370 } else if (pCurrentPageNode->GetClassID() == XFA_ELEMENT_PageSet) { | |
| 1371 CreateMinPageSetRecord(pCurrentPageNode, TRUE); | |
| 1372 } | |
| 1373 } | |
| 1374 } | |
| 1375 m_pPageSetMap.SetAt(pPageSet, iMin); | |
| 1376 } | |
| 1377 } | |
| 1378 } | |
| 1379 void CXFA_LayoutPageMgr::CreateNextMinRecord(CXFA_Node* pRecordNode) { | |
| 1380 if (pRecordNode == NULL) { | |
| 1381 return; | |
| 1382 } | |
| 1383 for (CXFA_Node* pCurrentNode = | |
| 1384 pRecordNode->GetNodeItem(XFA_NODEITEM_NextSibling); | |
| 1385 pCurrentNode; | |
| 1386 pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
| 1387 if (pCurrentNode->GetClassID() == XFA_ELEMENT_PageArea) { | |
| 1388 CreateMinPageRecord(pCurrentNode, FALSE); | |
| 1389 } else if (pCurrentNode->GetClassID() == XFA_ELEMENT_PageSet) { | |
| 1390 CreateMinPageSetRecord(pCurrentNode, TRUE); | |
| 1391 } | |
| 1392 } | |
| 1393 } | |
| 1394 void CXFA_LayoutPageMgr::ProcessLastPageSet() { | |
| 1395 CreateMinPageRecord(m_pCurPageArea, FALSE, TRUE); | |
| 1396 CreateNextMinRecord(m_pCurPageArea); | |
| 1397 CXFA_Node* pPageSet = m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent); | |
| 1398 while (TRUE) { | |
| 1399 CreateMinPageSetRecord(pPageSet); | |
| 1400 if (pPageSet == m_pTemplatePageSetRoot) { | |
| 1401 break; | |
| 1402 } | |
| 1403 CreateNextMinRecord(pPageSet); | |
| 1404 pPageSet = pPageSet->GetNodeItem(XFA_NODEITEM_Parent); | |
| 1405 } | |
| 1406 } | |
| 1407 FX_BOOL CXFA_LayoutPageMgr::GetNextAvailContentHeight(FX_FLOAT fChildHeight) { | |
| 1408 CXFA_Node* pCurContentNode = | |
| 1409 GetCurrentContainerRecord()->pCurContentArea->m_pFormNode; | |
| 1410 if (pCurContentNode == NULL) { | |
| 1411 return FALSE; | |
| 1412 } | |
| 1413 pCurContentNode = | |
| 1414 pCurContentNode->GetNextSameClassSibling(XFA_ELEMENT_ContentArea); | |
| 1415 if (pCurContentNode) { | |
| 1416 FX_FLOAT fNextContentHeight = | |
| 1417 pCurContentNode->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt); | |
| 1418 return fNextContentHeight > fChildHeight; | |
| 1419 } | |
| 1420 CXFA_Node* pPageNode = GetCurrentContainerRecord()->pCurPageArea->m_pFormNode; | |
| 1421 CXFA_Node* pOccurNode = pPageNode->GetFirstChildByClass(XFA_ELEMENT_Occur); | |
| 1422 int32_t iMax = 0; | |
| 1423 if (pOccurNode && pOccurNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE)) { | |
| 1424 if (m_nCurPageCount == iMax) { | |
| 1425 CXFA_Node* pSrcPage = m_pCurPageArea; | |
| 1426 int32_t nSrcPageCount = m_nCurPageCount; | |
| 1427 FX_POSITION psSrcRecord = m_rgProposedContainerRecord.GetTailPosition(); | |
| 1428 CXFA_Node* pNextPage = GetNextAvailPageArea(NULL, NULL, FALSE, TRUE); | |
| 1429 m_pCurPageArea = pSrcPage; | |
| 1430 m_nCurPageCount = nSrcPageCount; | |
| 1431 CXFA_ContainerRecord* pPrevRecord = | |
| 1432 (CXFA_ContainerRecord*)m_rgProposedContainerRecord.GetNext( | |
| 1433 psSrcRecord); | |
| 1434 while (psSrcRecord) { | |
| 1435 FX_POSITION psSaveRecord = psSrcRecord; | |
| 1436 CXFA_ContainerRecord* pInsertRecord = | |
| 1437 (CXFA_ContainerRecord*)m_rgProposedContainerRecord.GetNext( | |
| 1438 psSrcRecord); | |
| 1439 RemoveLayoutRecord(pInsertRecord, pPrevRecord); | |
| 1440 delete pInsertRecord; | |
| 1441 m_rgProposedContainerRecord.RemoveAt(psSaveRecord); | |
| 1442 } | |
| 1443 if (pNextPage) { | |
| 1444 CXFA_Node* pContentArea = | |
| 1445 pNextPage->GetFirstChildByClass(XFA_ELEMENT_ContentArea); | |
| 1446 if (pContentArea) { | |
| 1447 FX_FLOAT fNextContentHeight = | |
| 1448 pContentArea->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt); | |
| 1449 if (fNextContentHeight > fChildHeight) { | |
| 1450 return TRUE; | |
| 1451 } | |
| 1452 } | |
| 1453 } | |
| 1454 return FALSE; | |
| 1455 } | |
| 1456 } | |
| 1457 CXFA_Node* pContentArea = | |
| 1458 pPageNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea); | |
| 1459 FX_FLOAT fNextContentHeight = | |
| 1460 pContentArea->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt); | |
| 1461 if (fNextContentHeight < XFA_LAYOUT_FLOAT_PERCISION) { | |
| 1462 return TRUE; | |
| 1463 } | |
| 1464 if (fNextContentHeight > fChildHeight) { | |
| 1465 return TRUE; | |
| 1466 } | |
| 1467 return FALSE; | |
| 1468 } | |
| 1469 void CXFA_LayoutPageMgr::ClearData() { | |
| 1470 ClearRecordList(); | |
| 1471 } | |
| 1472 void CXFA_LayoutPageMgr::ClearRecordList() { | |
| 1473 if (!m_pTemplatePageSetRoot) { | |
| 1474 return; | |
| 1475 } | |
| 1476 if (m_rgProposedContainerRecord.GetCount() > 0) { | |
| 1477 FX_POSITION sPos; | |
| 1478 sPos = m_rgProposedContainerRecord.GetHeadPosition(); | |
| 1479 while (sPos) { | |
| 1480 CXFA_ContainerRecord* pRecord = | |
| 1481 (CXFA_ContainerRecord*)m_rgProposedContainerRecord.GetNext(sPos); | |
| 1482 delete pRecord; | |
| 1483 } | |
| 1484 m_rgProposedContainerRecord.RemoveAll(); | |
| 1485 } | |
| 1486 m_pCurrentContainerRecord = NULL; | |
| 1487 m_pCurPageArea = NULL; | |
| 1488 m_nCurPageCount = 0; | |
| 1489 m_bCreateOverFlowPage = FALSE; | |
| 1490 m_pPageSetMap.RemoveAll(); | |
| 1491 } | |
| 1492 CXFA_LayoutItem* CXFA_LayoutPageMgr::FindOrCreateLayoutItem( | |
| 1493 CXFA_Node* pFormNode) { | |
| 1494 return pFormNode->GetDocument()->GetParser()->GetNotify()->OnCreateLayoutItem( | |
| 1495 pFormNode); | |
| 1496 } | |
| 1497 static void XFA_SyncRemoveLayoutItem(CXFA_LayoutItem* pParentLayoutItem, | |
| 1498 IXFA_Notify* pNotify, | |
| 1499 IXFA_DocLayout* pDocLayout) { | |
| 1500 CXFA_LayoutItem* pNextLayoutItem; | |
| 1501 CXFA_LayoutItem* pCurLayoutItem = pParentLayoutItem->m_pFirstChild; | |
| 1502 while (pCurLayoutItem) { | |
| 1503 pNextLayoutItem = pCurLayoutItem->m_pNextSibling; | |
| 1504 if (pCurLayoutItem->m_pFirstChild) { | |
| 1505 XFA_SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout); | |
| 1506 } | |
| 1507 pNotify->OnLayoutEvent(pDocLayout, pCurLayoutItem, | |
| 1508 XFA_LAYOUTEVENT_ItemRemoving); | |
| 1509 delete pCurLayoutItem; | |
| 1510 pCurLayoutItem = pNextLayoutItem; | |
| 1511 } | |
| 1512 } | |
| 1513 void CXFA_LayoutPageMgr::SaveLayoutItem(CXFA_LayoutItem* pParentLayoutItem) { | |
| 1514 CXFA_LayoutItem* pNextLayoutItem; | |
| 1515 CXFA_LayoutItem* pCurLayoutItem = pParentLayoutItem->m_pFirstChild; | |
| 1516 while (pCurLayoutItem) { | |
| 1517 pNextLayoutItem = pCurLayoutItem->m_pNextSibling; | |
| 1518 if (pCurLayoutItem->IsContentLayoutItem()) { | |
| 1519 FX_DWORD dwFlag = pCurLayoutItem->m_pFormNode->GetFlag(); | |
| 1520 if (dwFlag & (XFA_NODEFLAG_HasRemoved)) { | |
| 1521 IXFA_Notify* pNotify = | |
| 1522 m_pTemplatePageSetRoot->GetDocument()->GetParser()->GetNotify(); | |
| 1523 IXFA_DocLayout* pDocLayout = | |
| 1524 m_pTemplatePageSetRoot->GetDocument()->GetDocLayout(); | |
| 1525 if (pCurLayoutItem->m_pFirstChild) { | |
| 1526 XFA_SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout); | |
| 1527 } | |
| 1528 pNotify->OnLayoutEvent(pDocLayout, pCurLayoutItem, | |
| 1529 XFA_LAYOUTEVENT_ItemRemoving); | |
| 1530 delete pCurLayoutItem; | |
| 1531 pCurLayoutItem = pNextLayoutItem; | |
| 1532 continue; | |
| 1533 } | |
| 1534 if (dwFlag & XFA_NODEFLAG_LayoutGeneratedNode) { | |
| 1535 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> | |
| 1536 sIterator(pCurLayoutItem->m_pFormNode); | |
| 1537 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; | |
| 1538 pNode = sIterator.MoveToNext()) { | |
| 1539 pNode->SetFlag(XFA_NODEFLAG_UnusedNode, TRUE, FALSE); | |
| 1540 } | |
| 1541 } | |
| 1542 } | |
| 1543 if (pCurLayoutItem->m_pFirstChild) { | |
| 1544 SaveLayoutItem(pCurLayoutItem); | |
| 1545 } | |
| 1546 pCurLayoutItem->m_pParent = NULL; | |
| 1547 pCurLayoutItem->m_pNextSibling = NULL; | |
| 1548 pCurLayoutItem->m_pFirstChild = NULL; | |
| 1549 if (!pCurLayoutItem->IsContentLayoutItem() && | |
| 1550 pCurLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageArea) { | |
| 1551 delete pCurLayoutItem; | |
| 1552 } | |
| 1553 pCurLayoutItem = pNextLayoutItem; | |
| 1554 } | |
| 1555 } | |
| 1556 CXFA_Node* CXFA_LayoutPageMgr::QueryOverflow( | |
| 1557 CXFA_Node* pFormNode, | |
| 1558 CXFA_LayoutContext* pLayoutContext) { | |
| 1559 for (CXFA_Node* pCurNode = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
| 1560 pCurNode; pCurNode = pCurNode->GetNodeItem((XFA_NODEITEM_NextSibling))) { | |
| 1561 if (pCurNode->GetClassID() == XFA_ELEMENT_Break) { | |
| 1562 CFX_WideStringC wsOverflowLeader; | |
| 1563 CFX_WideStringC wsOverflowTarget; | |
| 1564 CFX_WideStringC wsOverflowTrailer; | |
| 1565 pCurNode->TryCData(XFA_ATTRIBUTE_OverflowLeader, wsOverflowLeader); | |
| 1566 pCurNode->TryCData(XFA_ATTRIBUTE_OverflowTrailer, wsOverflowTrailer); | |
| 1567 pCurNode->TryCData(XFA_ATTRIBUTE_OverflowTarget, wsOverflowTarget); | |
| 1568 if (!wsOverflowLeader.IsEmpty() || !wsOverflowTrailer.IsEmpty() || | |
| 1569 !wsOverflowTarget.IsEmpty()) { | |
| 1570 return pCurNode; | |
| 1571 } | |
| 1572 return NULL; | |
| 1573 } else if (pCurNode->GetClassID() == XFA_ELEMENT_Overflow) { | |
| 1574 return pCurNode; | |
| 1575 } | |
| 1576 } | |
| 1577 return NULL; | |
| 1578 } | |
| 1579 void CXFA_LayoutPageMgr::MergePageSetContents() { | |
| 1580 CXFA_Document* pDocument = m_pTemplatePageSetRoot->GetDocument(); | |
| 1581 IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify(); | |
| 1582 IXFA_DocLayout* pDocLayout = pDocument->GetDocLayout(); | |
| 1583 CXFA_ContainerLayoutItem* pRootLayout = GetRootLayoutItem(); | |
| 1584 { | |
| 1585 for (int32_t iIndex = 0; iIndex < pDocument->m_pPendingPageSet.GetSize(); | |
| 1586 iIndex++) { | |
| 1587 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> | |
| 1588 sIterator(pDocument->m_pPendingPageSet.GetAt(iIndex)); | |
| 1589 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; | |
| 1590 pNode = sIterator.MoveToNext()) { | |
| 1591 if (pNode->IsContainerNode()) { | |
| 1592 CXFA_Node* pBindNode = pNode->GetBindData(); | |
| 1593 if (pBindNode) { | |
| 1594 pBindNode->RemoveBindItem(pNode); | |
| 1595 pNode->SetObject(XFA_ATTRIBUTE_BindingNode, NULL); | |
| 1596 } | |
| 1597 } | |
| 1598 pNode->SetFlag(XFA_NODEFLAG_UnusedNode); | |
| 1599 } | |
| 1600 } | |
| 1601 } | |
| 1602 int32_t iIndex = 0; | |
| 1603 CXFA_Node* pPendingPageSet = NULL; | |
| 1604 for (; pRootLayout; | |
| 1605 pRootLayout = (CXFA_ContainerLayoutItem*)pRootLayout->m_pNextSibling) { | |
| 1606 pPendingPageSet = NULL; | |
| 1607 CXFA_NodeIteratorTemplate< | |
| 1608 CXFA_ContainerLayoutItem, | |
| 1609 CXFA_TraverseStrategy_ContentAreaContainerLayoutItem> | |
| 1610 iterator(pRootLayout); | |
| 1611 CXFA_ContainerLayoutItem* pRootPageSetContainerItem = iterator.GetCurrent(); | |
| 1612 ASSERT(pRootPageSetContainerItem->m_pFormNode->GetClassID() == | |
| 1613 XFA_ELEMENT_PageSet); | |
| 1614 if (iIndex < pDocument->m_pPendingPageSet.GetSize()) { | |
| 1615 pPendingPageSet = pDocument->m_pPendingPageSet.GetAt(iIndex); | |
| 1616 iIndex++; | |
| 1617 } | |
| 1618 if (!pPendingPageSet) { | |
| 1619 if (pRootPageSetContainerItem->m_pFormNode->GetPacketID() == | |
| 1620 XFA_XDPPACKET_Template) { | |
| 1621 pPendingPageSet = | |
| 1622 pRootPageSetContainerItem->m_pFormNode->CloneTemplateToForm(FALSE); | |
| 1623 } else { | |
| 1624 pPendingPageSet = pRootPageSetContainerItem->m_pFormNode; | |
| 1625 } | |
| 1626 } | |
| 1627 if (pRootPageSetContainerItem->m_pFormNode->GetUserData( | |
| 1628 XFA_LAYOUTITEMKEY) == pRootPageSetContainerItem) { | |
| 1629 pRootPageSetContainerItem->m_pFormNode->SetUserData(XFA_LAYOUTITEMKEY, | |
| 1630 NULL); | |
| 1631 } | |
| 1632 pRootPageSetContainerItem->m_pFormNode = pPendingPageSet; | |
| 1633 pPendingPageSet->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE); | |
| 1634 for (CXFA_ContainerLayoutItem* pContainerItem = iterator.MoveToNext(); | |
| 1635 pContainerItem; pContainerItem = iterator.MoveToNext()) { | |
| 1636 CXFA_Node* pNode = pContainerItem->m_pFormNode; | |
| 1637 if (pNode->GetPacketID() != XFA_XDPPACKET_Template) { | |
| 1638 continue; | |
| 1639 } | |
| 1640 switch (pNode->GetClassID()) { | |
| 1641 case XFA_ELEMENT_PageSet: { | |
| 1642 CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode; | |
| 1643 pContainerItem->m_pFormNode = XFA_NodeMerge_CloneOrMergeContainer( | |
| 1644 pDocument, pParentNode, pContainerItem->m_pFormNode, TRUE); | |
| 1645 } break; | |
| 1646 case XFA_ELEMENT_PageArea: { | |
| 1647 CXFA_ContainerLayoutItem* pFormLayout = pContainerItem; | |
| 1648 CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode; | |
| 1649 FX_BOOL bIsExistForm = TRUE; | |
| 1650 for (int32_t iLevel = 0; iLevel < 3; iLevel++) { | |
| 1651 pFormLayout = (CXFA_ContainerLayoutItem*)pFormLayout->m_pFirstChild; | |
| 1652 if (iLevel == 2) { | |
| 1653 while (pFormLayout && | |
| 1654 !XFA_ItemLayoutProcessor_IsTakingSpace( | |
| 1655 pFormLayout->m_pFormNode)) { | |
| 1656 pFormLayout = | |
| 1657 (CXFA_ContainerLayoutItem*)pFormLayout->m_pNextSibling; | |
| 1658 } | |
| 1659 } | |
| 1660 if (pFormLayout == NULL) { | |
| 1661 bIsExistForm = FALSE; | |
| 1662 break; | |
| 1663 } | |
| 1664 } | |
| 1665 if (bIsExistForm) { | |
| 1666 CXFA_Node* pNewSubform = pFormLayout->m_pFormNode; | |
| 1667 if (pContainerItem->m_pOldSubform && | |
| 1668 pContainerItem->m_pOldSubform != pNewSubform) { | |
| 1669 CXFA_Node* pExistingNode = XFA_DataMerge_FindFormDOMInstance( | |
| 1670 pDocument, pContainerItem->m_pFormNode->GetClassID(), | |
| 1671 pContainerItem->m_pFormNode->GetNameHash(), pParentNode); | |
| 1672 CXFA_ContainerIterator sIterator(pExistingNode); | |
| 1673 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; | |
| 1674 pNode = sIterator.MoveToNext()) { | |
| 1675 if (pNode->GetClassID() != XFA_ELEMENT_ContentArea) { | |
| 1676 CXFA_LayoutItem* pLayoutItem = static_cast<CXFA_LayoutItem*>( | |
| 1677 pNode->GetUserData(XFA_LAYOUTITEMKEY)); | |
| 1678 if (pLayoutItem) { | |
| 1679 pNotify->OnLayoutEvent(pDocLayout, pLayoutItem, | |
| 1680 XFA_LAYOUTEVENT_ItemRemoving); | |
| 1681 delete pLayoutItem; | |
| 1682 } | |
| 1683 } | |
| 1684 } | |
| 1685 if (pExistingNode) { | |
| 1686 pParentNode->RemoveChild(pExistingNode); | |
| 1687 } | |
| 1688 } | |
| 1689 pContainerItem->m_pOldSubform = pNewSubform; | |
| 1690 } | |
| 1691 pContainerItem->m_pFormNode = pDocument->DataMerge_CopyContainer( | |
| 1692 pContainerItem->m_pFormNode, pParentNode, | |
| 1693 ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record)), TRUE); | |
| 1694 } break; | |
| 1695 case XFA_ELEMENT_ContentArea: { | |
| 1696 CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode; | |
| 1697 for (CXFA_Node* pChildNode = | |
| 1698 pParentNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
| 1699 pChildNode; | |
| 1700 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
| 1701 if (pChildNode->GetTemplateNode() != pContainerItem->m_pFormNode) { | |
| 1702 continue; | |
| 1703 } | |
| 1704 pContainerItem->m_pFormNode = pChildNode; | |
| 1705 break; | |
| 1706 } | |
| 1707 } break; | |
| 1708 default: | |
| 1709 break; | |
| 1710 } | |
| 1711 } | |
| 1712 if (!pPendingPageSet->GetNodeItem(XFA_NODEITEM_Parent)) { | |
| 1713 CXFA_Node* pFormToplevelSubform = | |
| 1714 pDocument->GetXFAObject(XFA_HASHCODE_Form) | |
| 1715 ->AsNode() | |
| 1716 ->GetFirstChildByClass(XFA_ELEMENT_Subform); | |
| 1717 pFormToplevelSubform->InsertChild(pPendingPageSet); | |
| 1718 } | |
| 1719 pDocument->DataMerge_UpdateBindingRelations(pPendingPageSet); | |
| 1720 pPendingPageSet->SetFlag(XFA_NODEFLAG_Initialized); | |
| 1721 } | |
| 1722 pPendingPageSet = GetRootLayoutItem()->m_pFormNode; | |
| 1723 while (pPendingPageSet) { | |
| 1724 CXFA_Node* pNextPendingPageSet = | |
| 1725 pPendingPageSet->GetNextSameClassSibling(XFA_ELEMENT_PageSet); | |
| 1726 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> | |
| 1727 sIterator(pPendingPageSet); | |
| 1728 CXFA_Node* pNode = sIterator.GetCurrent(); | |
| 1729 while (pNode) { | |
| 1730 if (pNode->HasFlag(XFA_NODEFLAG_UnusedNode)) { | |
| 1731 if (pNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) { | |
| 1732 XFA_ELEMENT eCurId = pNode->GetClassID(); | |
| 1733 if (eCurId == XFA_ELEMENT_PageArea || eCurId == XFA_ELEMENT_PageSet) { | |
| 1734 CXFA_ContainerIterator iteChild(pNode); | |
| 1735 CXFA_Node* pChildNode = iteChild.MoveToNext(); | |
| 1736 for (; pChildNode; pChildNode = iteChild.MoveToNext()) { | |
| 1737 CXFA_LayoutItem* pLayoutItem = static_cast<CXFA_LayoutItem*>( | |
| 1738 pChildNode->GetUserData(XFA_LAYOUTITEMKEY)); | |
| 1739 if (pLayoutItem) { | |
| 1740 pNotify->OnLayoutEvent(pDocLayout, pLayoutItem, | |
| 1741 XFA_LAYOUTEVENT_ItemRemoving); | |
| 1742 delete pLayoutItem; | |
| 1743 } | |
| 1744 } | |
| 1745 } else if (eCurId != XFA_ELEMENT_ContentArea) { | |
| 1746 CXFA_LayoutItem* pLayoutItem = static_cast<CXFA_LayoutItem*>( | |
| 1747 pNode->GetUserData(XFA_LAYOUTITEMKEY)); | |
| 1748 if (pLayoutItem) { | |
| 1749 pNotify->OnLayoutEvent(pDocLayout, pLayoutItem, | |
| 1750 XFA_LAYOUTEVENT_ItemRemoving); | |
| 1751 delete pLayoutItem; | |
| 1752 } | |
| 1753 } | |
| 1754 CXFA_Node* pNext = sIterator.SkipChildrenAndMoveToNext(); | |
| 1755 pNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pNode); | |
| 1756 pNode = pNext; | |
| 1757 } else { | |
| 1758 pNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE); | |
| 1759 pNode->SetFlag(XFA_NODEFLAG_Initialized); | |
| 1760 pNode = sIterator.MoveToNext(); | |
| 1761 } | |
| 1762 } else { | |
| 1763 pNode->SetFlag(XFA_NODEFLAG_Initialized); | |
| 1764 pNode = sIterator.MoveToNext(); | |
| 1765 } | |
| 1766 } | |
| 1767 pPendingPageSet = pNextPendingPageSet; | |
| 1768 } | |
| 1769 } | |
| 1770 void CXFA_LayoutPageMgr::LayoutPageSetContents() { | |
| 1771 CXFA_ContainerLayoutItem* pRootLayoutItem = GetRootLayoutItem(); | |
| 1772 for (; pRootLayoutItem; | |
| 1773 pRootLayoutItem = | |
| 1774 (CXFA_ContainerLayoutItem*)pRootLayoutItem->m_pNextSibling) { | |
| 1775 CXFA_NodeIteratorTemplate< | |
| 1776 CXFA_ContainerLayoutItem, | |
| 1777 CXFA_TraverseStrategy_ContentAreaContainerLayoutItem> | |
| 1778 iterator(pRootLayoutItem); | |
| 1779 for (CXFA_ContainerLayoutItem* pContainerItem = iterator.GetCurrent(); | |
| 1780 pContainerItem; pContainerItem = iterator.MoveToNext()) { | |
| 1781 CXFA_Node* pNode = pContainerItem->m_pFormNode; | |
| 1782 switch (pNode->GetClassID()) { | |
| 1783 case XFA_ELEMENT_PageArea: | |
| 1784 m_pLayoutProcessor->GetRootRootItemLayoutProcessor() | |
| 1785 ->DoLayoutPageArea(pContainerItem); | |
| 1786 break; | |
| 1787 default: | |
| 1788 break; | |
| 1789 } | |
| 1790 } | |
| 1791 } | |
| 1792 } | |
| 1793 void XFA_SyncContainer(IXFA_Notify* pNotify, | |
| 1794 IXFA_DocLayout* pDocLayout, | |
| 1795 CXFA_LayoutItem* pContainerItem, | |
| 1796 FX_DWORD dwRelevant, | |
| 1797 FX_BOOL bVisible, | |
| 1798 int32_t nPageIndex) { | |
| 1799 FX_BOOL bVisibleItem = FALSE; | |
| 1800 FX_DWORD dwStatus = 0; | |
| 1801 FX_DWORD dwRelevantContainer = 0; | |
| 1802 if (bVisible) { | |
| 1803 XFA_ATTRIBUTEENUM eAttributeValue = | |
| 1804 pContainerItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Presence); | |
| 1805 if (eAttributeValue == XFA_ATTRIBUTEENUM_Visible || | |
| 1806 eAttributeValue == XFA_ATTRIBUTEENUM_Unknown) { | |
| 1807 bVisibleItem = TRUE; | |
| 1808 } | |
| 1809 dwRelevantContainer = | |
| 1810 XFA_GetRelevant(pContainerItem->m_pFormNode, dwRelevant); | |
| 1811 dwStatus = | |
| 1812 (bVisibleItem ? XFA_LAYOUTSTATUS_Visible : 0) | dwRelevantContainer; | |
| 1813 } | |
| 1814 pNotify->OnLayoutEvent(pDocLayout, pContainerItem, XFA_LAYOUTEVENT_ItemAdded, | |
| 1815 (void*)(uintptr_t)nPageIndex, | |
| 1816 (void*)(uintptr_t)dwStatus); | |
| 1817 for (CXFA_LayoutItem* pChild = pContainerItem->m_pFirstChild; pChild; | |
| 1818 pChild = pChild->m_pNextSibling) { | |
| 1819 if (pChild->IsContentLayoutItem()) { | |
| 1820 XFA_SyncContainer(pNotify, pDocLayout, pChild, dwRelevantContainer, | |
| 1821 bVisibleItem, nPageIndex); | |
| 1822 } | |
| 1823 } | |
| 1824 } | |
| 1825 void CXFA_LayoutPageMgr::SyncLayoutData() { | |
| 1826 MergePageSetContents(); | |
| 1827 LayoutPageSetContents(); | |
| 1828 IXFA_Notify* pNotify = | |
| 1829 m_pTemplatePageSetRoot->GetDocument()->GetParser()->GetNotify(); | |
| 1830 int32_t nPageIdx = -1; | |
| 1831 CXFA_ContainerLayoutItem* pRootLayoutItem = GetRootLayoutItem(); | |
| 1832 for (; pRootLayoutItem; | |
| 1833 pRootLayoutItem = | |
| 1834 (CXFA_ContainerLayoutItem*)pRootLayoutItem->m_pNextSibling) { | |
| 1835 CXFA_NodeIteratorTemplate< | |
| 1836 CXFA_ContainerLayoutItem, | |
| 1837 CXFA_TraverseStrategy_ContentAreaContainerLayoutItem> | |
| 1838 iteratorParent(pRootLayoutItem); | |
| 1839 for (CXFA_ContainerLayoutItem* pContainerItem = iteratorParent.GetCurrent(); | |
| 1840 pContainerItem; pContainerItem = iteratorParent.MoveToNext()) { | |
| 1841 switch (pContainerItem->m_pFormNode->GetClassID()) { | |
| 1842 case XFA_ELEMENT_PageArea: { | |
| 1843 nPageIdx++; | |
| 1844 FX_DWORD dwRelevant = | |
| 1845 XFA_LAYOUTSTATUS_Viewable | XFA_LAYOUTSTATUS_Printable; | |
| 1846 CXFA_NodeIteratorTemplate<CXFA_LayoutItem, | |
| 1847 CXFA_TraverseStrategy_LayoutItem> | |
| 1848 iterator(pContainerItem); | |
| 1849 CXFA_LayoutItem* pChildLayoutItem = iterator.GetCurrent(); | |
| 1850 while (pChildLayoutItem) { | |
| 1851 CXFA_ContentLayoutItem* pContentItem = | |
| 1852 pChildLayoutItem->AsContentLayoutItem(); | |
| 1853 if (!pContentItem) { | |
| 1854 pChildLayoutItem = iterator.MoveToNext(); | |
| 1855 continue; | |
| 1856 } | |
| 1857 FX_BOOL bVisible = | |
| 1858 (pContentItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Presence) == | |
| 1859 XFA_ATTRIBUTEENUM_Visible); | |
| 1860 FX_DWORD dwRelevantChild = | |
| 1861 XFA_GetRelevant(pContentItem->m_pFormNode, dwRelevant); | |
| 1862 XFA_SyncContainer(pNotify, m_pLayoutProcessor, pContentItem, | |
| 1863 dwRelevantChild, bVisible, nPageIdx); | |
| 1864 pChildLayoutItem = iterator.SkipChildrenAndMoveToNext(); | |
| 1865 } | |
| 1866 } break; | |
| 1867 default: | |
| 1868 break; | |
| 1869 } | |
| 1870 } | |
| 1871 } | |
| 1872 int32_t nPage = m_PageArray.GetSize(); | |
| 1873 for (int32_t i = nPage - 1; i >= m_nAvailPages; i--) { | |
| 1874 CXFA_ContainerLayoutItem* pPage = m_PageArray[i]; | |
| 1875 m_PageArray.RemoveAt(i); | |
| 1876 pNotify->OnPageEvent(pPage, XFA_PAGEEVENT_PageRemoved); | |
| 1877 delete pPage; | |
| 1878 } | |
| 1879 ClearRecordList(); | |
| 1880 } | |
| 1881 void XFA_ReleaseLayoutItem_NoPageArea(CXFA_LayoutItem* pLayoutItem) { | |
| 1882 CXFA_LayoutItem *pNext, *pNode = pLayoutItem->m_pFirstChild; | |
| 1883 while (pNode) { | |
| 1884 pNext = pNode->m_pNextSibling; | |
| 1885 pNode->m_pParent = NULL; | |
| 1886 XFA_ReleaseLayoutItem_NoPageArea(pNode); | |
| 1887 pNode = pNext; | |
| 1888 } | |
| 1889 if (pLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageArea) { | |
| 1890 delete pLayoutItem; | |
| 1891 } | |
| 1892 } | |
| 1893 void CXFA_LayoutPageMgr::PrepareLayout() { | |
| 1894 m_pPageSetCurRoot = NULL; | |
| 1895 m_ePageSetMode = XFA_ATTRIBUTEENUM_OrderedOccurrence; | |
| 1896 m_nAvailPages = 0; | |
| 1897 ClearRecordList(); | |
| 1898 if (!m_pPageSetLayoutItemRoot) { | |
| 1899 return; | |
| 1900 } | |
| 1901 CXFA_ContainerLayoutItem* pRootLayoutItem = m_pPageSetLayoutItemRoot; | |
| 1902 if (pRootLayoutItem && | |
| 1903 pRootLayoutItem->m_pFormNode->GetPacketID() == XFA_XDPPACKET_Form) { | |
| 1904 CXFA_Node* pPageSetFormNode = pRootLayoutItem->m_pFormNode; | |
| 1905 pRootLayoutItem->m_pFormNode->GetDocument()->m_pPendingPageSet.RemoveAll(); | |
| 1906 if (pPageSetFormNode->HasFlag(XFA_NODEFLAG_HasRemoved)) { | |
| 1907 XFA_ReleaseLayoutItem(pRootLayoutItem); | |
| 1908 m_pPageSetLayoutItemRoot = NULL; | |
| 1909 pRootLayoutItem = NULL; | |
| 1910 pPageSetFormNode = NULL; | |
| 1911 m_PageArray.RemoveAll(); | |
| 1912 } | |
| 1913 while (pPageSetFormNode) { | |
| 1914 CXFA_Node* pNextPageSet = | |
| 1915 pPageSetFormNode->GetNextSameClassSibling(XFA_ELEMENT_PageSet); | |
| 1916 pPageSetFormNode->GetNodeItem(XFA_NODEITEM_Parent) | |
| 1917 ->RemoveChild(pPageSetFormNode, FALSE); | |
| 1918 pRootLayoutItem->m_pFormNode->GetDocument()->m_pPendingPageSet.Add( | |
| 1919 pPageSetFormNode); | |
| 1920 pPageSetFormNode = pNextPageSet; | |
| 1921 } | |
| 1922 } | |
| 1923 pRootLayoutItem = m_pPageSetLayoutItemRoot; | |
| 1924 CXFA_ContainerLayoutItem* pNextLayout = NULL; | |
| 1925 for (; pRootLayoutItem; pRootLayoutItem = pNextLayout) { | |
| 1926 pNextLayout = (CXFA_ContainerLayoutItem*)pRootLayoutItem->m_pNextSibling; | |
| 1927 SaveLayoutItem(pRootLayoutItem); | |
| 1928 delete pRootLayoutItem; | |
| 1929 } | |
| 1930 m_pPageSetLayoutItemRoot = NULL; | |
| 1931 } | |
| OLD | NEW |