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 "layoutprovider_taggedpdf.h" 8 CPDF_LayoutElement::CPDF_LayoutElement() 9 { 10 m_pTaggedElement = NULL; 11 m_pParentElement = NULL; 12 } 13 CPDF_LayoutElement::~CPDF_LayoutElement() 14 { 15 m_ObjArray.RemoveAll(); 16 int size = m_ChildArray.GetSize(); 17 for(int i = 0; i < size; i++) { 18 CPDF_LayoutElement* pChild = (CPDF_LayoutElement*)m_ChildArray.GetAt(i); 19 delete pChild; 20 pChild = NULL; 21 } 22 m_ChildArray.RemoveAll(); 23 } 24 LayoutType CPDF_LayoutElement::ConvertLayoutType(FX_BSTR name) 25 { 26 if(name == (const char*)("Document")) { 27 return LayoutDocument; 28 } else if(name == (const char*)("Part")) { 29 return LayoutPart; 30 } else if(name == (const char*)("Art")) { 31 return LayoutArt; 32 } else if(name == (const char*)("Sect")) { 33 return LayoutSect; 34 } else if(name == (const char*)("Div")) { 35 return LayoutDiv; 36 } else if(name == (const char*)("BlockQuote")) { 37 return LayoutBlockQuote; 38 } else if(name == (const char*)("Caption")) { 39 return LayoutCaption; 40 } else if(name == (const char*)("TOC")) { 41 return LayoutTOC; 42 } else if(name == (const char*)("TOCI")) { 43 return LayoutTOCI; 44 } else if(name == (const char*)("Index")) { 45 return LayoutIndex; 46 } else if(name == (const char*)("NonStruct")) { 47 return LayoutNonStruct; 48 } else if(name == (const char*)("Private")) { 49 return LayoutPrivate; 50 } else if(name == (const char*)("P")) { 51 return LayoutParagraph; 52 } else if(name == (const char*)("H")) { 53 return LayoutHeading; 54 } else if(name == (const char*)("H1")) { 55 return LayoutHeading1; 56 } else if(name == (const char*)("H2")) { 57 return LayoutHeading2; 58 } else if(name == (const char*)("H3")) { 59 return LayoutHeading3; 60 } else if(name == (const char*)("H4")) { 61 return LayoutHeading4; 62 } else if(name == (const char*)("H5")) { 63 return LayoutHeading5; 64 } else if(name == (const char*)("H6")) { 65 return LayoutHeading6; 66 } else if(name == (const char*)("L")) { 67 return LayoutList; 68 } else if(name == (const char*)("LI")) { 69 return LayoutListItem; 70 } else if(name == (const char*)("Lbl")) { 71 return LayoutListLabel; 72 } else if(name == (const char*)("LBody")) { 73 return LayoutListBody; 74 } else if(name == (const char*)("Table")) { 75 return LayoutTable; 76 } else if(name == (const char*)("TR")) { 77 return LayoutTableRow; 78 } else if(name == (const char*)("TH")) { 79 return LayoutTableHeaderCell; 80 } else if(name == (const char*)("TD")) { 81 return LayoutTableDataCell; 82 } else if(name == (const char*)("THead")) { 83 return LayoutTableHeaderGroup; 84 } else if(name == (const char*)("TBody")) { 85 return LayoutTableBodyGroup; 86 } else if(name == (const char*)("TFoot")) { 87 return LayoutTableFootGroup; 88 } else if(name == (const char*)("Span")) { 89 return LayoutSpan; 90 } else if(name == (const char*)("Quote")) { 91 return LayoutQuote; 92 } else if(name == (const char*)("Note")) { 93 return LayoutNote; 94 } else if(name == (const char*)("Reference")) { 95 return LayoutReference; 96 } else if(name == (const char*)("BibEntry")) { 97 return LayoutBibEntry; 98 } else if(name == (const char*)("Code")) { 99 return LayoutCode; 100 } else if(name == (const char*)("Link")) { 101 return LayoutLink; 102 } else if(name == (const char*)("Annot")) { 103 return LayoutAnnot; 104 } else if(name == (const char*)("Ruby")) { 105 return LayoutRuby; 106 } else if(name == (const char*)("RB")) { 107 return LayoutRubyBase; 108 } else if(name == (const char*)("RT")) { 109 return LayoutRubyAnnot; 110 } else if(name == (const char*)("RP")) { 111 return LayoutRubyPunc; 112 } else if(name == (const char*)("Warichu")) { 113 return LayoutWarichu; 114 } else if(name == (const char*)("WT")) { 115 return LayoutWarichuText; 116 } else if(name == (const char*)("WP")) { 117 return LayoutWarichuPunc; 118 } else if(name == (const char*)("Figure")) { 119 return LayoutFigure; 120 } else if(name == (const char*)("Formula")) { 121 return LayoutFormula; 122 } else if(name == (const char*)("Form")) { 123 return LayoutForm; 124 } else { 125 return LayoutUnknown; 126 } 127 } 128 CFX_ByteStringC CPDF_LayoutElement::ConvertLayoutType(LayoutType type) 129 { 130 FX_BSTR name = ""; 131 if(type == LayoutArifact) { 132 return "Arifact"; 133 } else if( type == LayoutDocument) { 134 return "Document"; 135 } else if( type == LayoutPart) { 136 return "Part"; 137 } else if( type == LayoutArt) { 138 return "Art"; 139 } else if( type == LayoutSect) { 140 return "Sect"; 141 } else if( type == LayoutDiv) { 142 return "Div"; 143 } else if( type == LayoutBlockQuote) { 144 return "BlockQuote"; 145 } else if( type == LayoutCaption) { 146 return "Caption"; 147 } else if( type == LayoutTOC) { 148 return "TOC"; 149 } else if( type == LayoutTOCI) { 150 return "TOCI"; 151 } else if( type == LayoutIndex) { 152 return "Index"; 153 } else if( type == LayoutNonStruct) { 154 return "NonStruct"; 155 } else if( type == LayoutPrivate) { 156 return "Private"; 157 } else if( type == LayoutParagraph) { 158 return "P"; 159 } else if( type == LayoutHeading) { 160 return "H"; 161 } else if( type == LayoutHeading1) { 162 return "H1"; 163 } else if( type == LayoutHeading2) { 164 return "H2"; 165 } else if( type == LayoutHeading3) { 166 return "H3"; 167 } else if( type == LayoutHeading4) { 168 return "H4"; 169 } else if( type == LayoutHeading5) { 170 return "H5"; 171 } else if( type == LayoutHeading6) { 172 return "H6"; 173 } else if( type == LayoutList) { 174 return "L"; 175 } else if( type == LayoutListItem) { 176 return "LI"; 177 } else if( type == LayoutListLabel) { 178 return "Lbl"; 179 } else if( type == LayoutListBody) { 180 return "LBody"; 181 } else if( type == LayoutTable) { 182 return "Table"; 183 } else if( type == LayoutTableRow) { 184 return "TR"; 185 } else if( type == LayoutTableHeaderCell) { 186 return "TH"; 187 } else if( type == LayoutTableDataCell) { 188 return "TD"; 189 } else if( type == LayoutTableHeaderGroup) { 190 return "THead"; 191 } else if( type == LayoutTableBodyGroup) { 192 return "TBody"; 193 } else if( type == LayoutTableFootGroup) { 194 return "TFoot"; 195 } else if( type == LayoutSpan) { 196 return "Span"; 197 } else if( type == LayoutQuote) { 198 return "Quote"; 199 } else if( type == LayoutNote) { 200 return "Note"; 201 } else if( type == LayoutReference) { 202 return "Reference"; 203 } else if( type == LayoutBibEntry) { 204 return "BibEntry"; 205 } else if( type == LayoutCode) { 206 return "Code"; 207 } else if( type == LayoutLink) { 208 return "Link"; 209 } else if( type == LayoutAnnot) { 210 return "Annot"; 211 } else if( type == LayoutRuby) { 212 return "Ruby"; 213 } else if( type == LayoutRubyBase) { 214 return "RB"; 215 } else if( type == LayoutRubyAnnot) { 216 return "RT"; 217 } else if( type == LayoutRubyPunc) { 218 return "RP"; 219 } else if( type == LayoutWarichu) { 220 return "Warichu"; 221 } else if( type == LayoutWarichuText) { 222 return "WT"; 223 } else if( type == LayoutWarichuPunc) { 224 return "WP"; 225 } else if( type == LayoutFigure) { 226 return "Figure"; 227 } else if( type == LayoutFormula) { 228 return "Formula"; 229 } else if( type == LayoutForm) { 230 return "Form"; 231 } 232 return name; 233 } 234 CFX_ByteStringC CPDF_LayoutElement::ConvertLayoutAttr(LayoutAttr attr) 235 { 236 switch(attr) { 237 case LayoutArtifactType: 238 return "Type"; 239 case LayoutArtifactAttached: 240 return "Attached"; 241 case LayoutArtifactSubType: 242 return "Subtype"; 243 case LayoutPlacement: 244 return "Placement"; 245 case LayoutWritingMode: 246 return "WritingMode"; 247 case LayoutBackgroundColor: 248 return "BackgroundColor"; 249 case LayoutBorderColor: 250 return "BorderColor"; 251 case LayoutBorderStyle: 252 return "BorderStyle"; 253 case LayoutBorderThickness: 254 return "BorderThickness"; 255 case LayoutPadding: 256 return "Padding"; 257 case LayoutColor: 258 return "Color"; 259 case LayoutSpaceBefore: 260 return "SpaceBefore"; 261 case LayoutSpaceAfter: 262 return "SpaceAfter"; 263 case LayoutStartIndent: 264 return "StartIndent"; 265 case LayoutEndIndent: 266 return "EndIndent"; 267 case LayoutTextIndent: 268 return "TextIndent"; 269 case LayoutTextAlign: 270 return "TextAlign"; 271 case LayoutBBox: 272 return "BBox"; 273 case LayoutWidth: 274 return "Width"; 275 case LayoutHeight: 276 return "Height"; 277 case LayoutBlockAlign: 278 return "BlockAlign"; 279 case LayoutInlineAlign: 280 return "InlineAlign"; 281 case LayoutTBorderStyle: 282 return "TBorderStyle"; 283 case LayoutTPadding: 284 return "TPadding"; 285 case LayoutBaselineShift: 286 return "BaselineShift"; 287 case LayoutLineHeight: 288 return "LineHeight"; 289 case LayoutTextDecorationColor: 290 return "TextDecorationColor"; 291 case LayoutTextDecorationThickness: 292 return "TextDecorationThickness"; 293 case LayoutTextDecorationType: 294 return "TextDecorationType"; 295 case LayoutRubyAlign: 296 return "RubyAlign"; 297 case LayoutRubyPosition: 298 return "RubyPosition"; 299 case LayoutGlyphOrientationVertical: 300 return "GlyphOrientationVertical"; 301 case LayoutColumnCount: 302 return "ColumnCount"; 303 case LayoutColumnGap: 304 return "ColumnGap"; 305 case LayoutColumnWidths: 306 return "ColumnWidths"; 307 case LayoutListNumbering: 308 return "ListNumbering"; 309 case LayoutFieldRole: 310 return "Role"; 311 case LayoutFieldChecked: 312 return "checked"; 313 case LayoutFieldDesc: 314 return "Desc"; 315 case LayoutRowSpan: 316 return "RowSpan"; 317 case LayoutColSpan: 318 return "ColSpan"; 319 case LayoutTableHeaders: 320 return "Headers"; 321 case LayoutTableHeaderScope: 322 return "Scope"; 323 case LayoutTableSummary: 324 return "Summary"; 325 default: 326 return ""; 327 } 328 } 329 LayoutEnum CPDF_LayoutElement::ConvertLayoutEnum(CFX_ByteStringC Enum) 330 { 331 if(Enum == "Block") { 332 return LayoutBlock; 333 } else if (Enum == "Inline") { 334 return LayoutInline; 335 } else if (Enum == "Before") { 336 return LayoutBefore; 337 } else if (Enum == "Start") { 338 return LayoutStart; 339 } else if (Enum == "End") { 340 return LayoutEnd; 341 } else if (Enum == "LrTb") { 342 return LayoutLrTb; 343 } else if (Enum == "RlTb") { 344 return LayoutRlTb; 345 } else if (Enum == "TbRl") { 346 return LayoutTbRl; 347 } else if (Enum == "None") { 348 return LayoutNone; 349 } else if (Enum == "Hidden") { 350 return LayoutHidden; 351 } else if (Enum == "Dotted") { 352 return LayoutDotted; 353 } else if (Enum == "Dashed") { 354 return LayoutDashed; 355 } else if (Enum == "Solid") { 356 return LayoutSolid; 357 } else if (Enum == "Double") { 358 return LayoutDouble; 359 } else if (Enum == "Groove") { 360 return LayoutGroove; 361 } else if (Enum == "Ridge") { 362 return LayoutRidge; 363 } else if (Enum == "Inset") { 364 return LayoutInset; 365 } else if (Enum == "Outset") { 366 return LayoutOutset; 367 } else if (Enum == "Normal") { 368 return LayoutNormal; 369 } else if (Enum == "Auto") { 370 return LayoutAuto; 371 } else if (Enum == "Center") { 372 return LayoutCenter; 373 } else if (Enum == "Justify") { 374 return LayoutJustify; 375 } else if (Enum == "Middle") { 376 return LayoutMiddle; 377 } else if (Enum == "Underline") { 378 return LayoutUnderline; 379 } else if (Enum == "Overline") { 380 return LayoutOverline; 381 } else if (Enum == "LineThrough") { 382 return LayoutLineThrough; 383 } else if (Enum == "Distribute") { 384 return LayoutDistribute; 385 } else if (Enum == "Disc") { 386 return LayoutDisc; 387 } else if (Enum == "Circle") { 388 return LayoutCircle; 389 } else if (Enum == "Square") { 390 return LayoutSquare; 391 } else if (Enum == "Decimal") { 392 return LayoutDecimal; 393 } else if (Enum == "UpperRoman") { 394 return LayoutUpperRoman; 395 } else if (Enum == "LowerRoman") { 396 return LayoutLowerRoman; 397 } else if (Enum == "UpperAlpha") { 398 return LayoutUpperAlpha; 399 } else if (Enum == "LowerAlpha") { 400 return LayoutLowerAlpha; 401 } else if (Enum == "rb") { 402 return LayoutRB; 403 } else if (Enum == "cb") { 404 return LayoutCB; 405 } else if (Enum == "pb") { 406 return LayoutPB; 407 } else if (Enum == "tv") { 408 return LayoutTV; 409 } else if (Enum == "on") { 410 return LayoutOn; 411 } else if (Enum == "off") { 412 return LayoutOff; 413 } else if (Enum == "neutral") { 414 return LayoutNeutral; 415 } else if (Enum == "Row") { 416 return LayoutRow; 417 } else if (Enum == "Column") { 418 return LayoutColumn; 419 } else if (Enum == "Both") { 420 return LayoutBoth; 421 } else if (Enum == "Left") { 422 return LayoutLeft; 423 } else if (Enum == "Top") { 424 return LayoutTop; 425 } else if (Enum == "Bottom") { 426 return LayoutBottom; 427 } else if (Enum == "Right") { 428 return LayoutRight; 429 } else if (Enum == "Pagination") { 430 return LayoutPagination; 431 } else if (Enum == "Layout") { 432 return LayoutLayout; 433 } else if (Enum == "Page") { 434 return LayoutPage; 435 } else if (Enum == "Background") { 436 return LayoutBackground; 437 } else if (Enum == "Header") { 438 return LayoutHeader; 439 } else if (Enum == "Footer") { 440 return LayoutFooter; 441 } else if (Enum == "Watermark") { 442 return LayoutWatermark; 443 } else { 444 return LayoutInvalid; 445 } 446 } 447 LayoutType CPDF_LayoutElement::GetType() 448 { 449 if(!m_pTaggedElement) { 450 return LayoutUnknown; 451 } 452 CFX_ByteString name = m_pTaggedElement->GetType(); 453 return this->ConvertLayoutType(name); 454 } 455 int CPDF_LayoutElement::CountAttrValues(LayoutAttr attr_type) 456 { 457 if(!m_pTaggedElement) { 458 return 0; 459 } 460 CPDF_Object* pObj = m_pTaggedElement->GetAttr(GetAttrOwner(attr_type), ConvertLayoutAttr(attr_type), IsInheritable(attr_type)); 461 if(pObj) { 462 return 1; 463 } else { 464 return 0; 465 } 466 } 467 LayoutEnum CPDF_LayoutElement::GetEnumAttr(LayoutAttr attr_type, int index) 468 { 469 if(!m_pTaggedElement) { 470 return LayoutInvalid; 471 } 472 CFX_ByteStringC owner = GetAttrOwner(attr_type); 473 CFX_ByteStringC default_value = GetDefaultNameValue(attr_type); 474 CFX_ByteStringC AttrName = ConvertLayoutAttr(attr_type); 475 CFX_ByteString AttrValue = m_pTaggedElement->GetName(owner, AttrName, default_value, IsInheritable(attr_type), index); 476 return ConvertLayoutEnum(AttrValue); 477 } 478 CFX_ByteStringC CPDF_LayoutElement::GetAttrOwner(LayoutAttr attr_type) 479 { 480 switch(attr_type) { 481 case LayoutListNumbering: 482 return "List"; 483 case LayoutFieldRole: 484 case LayoutFieldChecked : 485 case LayoutFieldDesc: 486 return "PrintField"; 487 case LayoutRowSpan: 488 case LayoutColSpan: 489 case LayoutTableHeaders: 490 case LayoutTableHeaderScope: 491 case LayoutTableSummary: 492 return "Table"; 493 default: 494 return "Layout"; 495 } 496 } 497 FX_FLOAT CPDF_LayoutElement::GetNumberAttr(LayoutAttr attr_type, int index) 498 { 499 if(!m_pTaggedElement) { 500 return 0; 501 } 502 CFX_ByteStringC owner = GetAttrOwner(attr_type); 503 FX_FLOAT default_value = GetDefaultFloatValue(attr_type); 504 CFX_ByteStringC AttrName = ConvertLayoutAttr(attr_type); 505 FX_FLOAT f = m_pTaggedElement->GetNumber(owner, AttrName, default_value, IsInheritable(attr_type), index); 506 if(attr_type == LayoutWidth && !f) { 507 f = m_pTaggedElement->GetNumber("Table", AttrName, default_value, IsInheritable(attr_type), index); 508 } 509 return f; 510 } 511 FX_COLORREF CPDF_LayoutElement::GetColorAttr(LayoutAttr attr_type, int index) 512 { 513 if(!m_pTaggedElement) { 514 return 0; 515 } 516 CFX_ByteStringC owner = GetAttrOwner(attr_type); 517 FX_COLORREF default_value = GetDefaultColorValue(attr_type); 518 CFX_ByteStringC AttrName = ConvertLayoutAttr(attr_type); 519 FX_ARGB f = m_pTaggedElement->GetColor(owner, AttrName, default_value, IsInheritable(attr_type), index); 520 return f; 521 } 522 FX_FLOAT CPDF_LayoutElement::GetDefaultFloatValue(LayoutAttr attr_type) 523 { 524 switch(attr_type) { 525 case LayoutColumnCount: 526 return 1; 527 case LayoutRowSpan: 528 return 1; 529 case LayoutColSpan: 530 return 1; 531 default: 532 return 0; 533 } 534 } 535 FX_COLORREF CPDF_LayoutElement::GetDefaultColorValue(LayoutAttr attr_type) 536 { 537 return -1; 538 } 539 CFX_ByteStringC CPDF_LayoutElement::GetDefaultNameValue(LayoutAttr attr_type) 540 { 541 switch(attr_type) { 542 case LayoutPlacement: 543 return "Inline"; 544 case LayoutWritingMode: 545 return "LrTb"; 546 case LayoutBorderStyle: 547 return "None"; 548 case LayoutTextAlign: 549 return "Start"; 550 case LayoutBlockAlign: 551 return "Before"; 552 case LayoutInlineAlign: 553 return "Start"; 554 case LayoutTBorderStyle: 555 return "None"; 556 case LayoutTextDecorationType: 557 return "None"; 558 case LayoutRubyAlign: 559 return "Distribute"; 560 case LayoutRubyPosition: 561 return "Before"; 562 case LayoutGlyphOrientationVertical: 563 return "Auto"; 564 case LayoutListNumbering: 565 return "None"; 566 case LayoutFieldRole: 567 return "None"; 568 default: 569 return ""; 570 } 571 } 572 FX_BOOL CPDF_LayoutElement::IsInheritable(LayoutAttr type) 573 { 574 switch(type) { 575 case LayoutWritingMode: 576 case LayoutTextAlign: 577 case LayoutBlockAlign: 578 case LayoutInlineAlign: 579 case LayoutLineHeight: 580 case LayoutGlyphOrientationVertical: 581 case LayoutRubyAlign: 582 case LayoutRubyPosition: 583 case LayoutBorderThickness: 584 case LayoutStartIndent: 585 case LayoutEndIndent: 586 case LayoutTextIndent: 587 case LayoutTPadding: 588 case LayoutTextDecorationThickness: 589 case LayoutBorderColor: 590 case LayoutColor: 591 case LayoutTextDecorationColor: 592 return TRUE; 593 default: 594 return FALSE; 595 } 596 } 597 int CPDF_LayoutElement::CountChildren() 598 { 599 return m_ChildArray.GetSize(); 600 } 601 IPDF_LayoutElement* CPDF_LayoutElement::GetChild(int index) 602 { 603 return (IPDF_LayoutElement*)m_ChildArray.GetAt(index); 604 } 605 IPDF_LayoutElement* CPDF_LayoutElement::GetParent() 606 { 607 return m_pParentElement; 608 } 609 int CPDF_LayoutElement::CountObjects() 610 { 611 if(m_pTaggedElement == NULL) { 612 return 0; 613 } 614 CFX_PtrArray* pObj = &m_ObjArray; 615 int size = pObj->GetSize(); 616 return size; 617 } 618 CPDF_PageObject* CPDF_LayoutElement::GetObject(int index) 619 { 620 if(m_pTaggedElement == NULL) { 621 return NULL; 622 } 623 CFX_PtrArray *pObj = &m_ObjArray; 624 int size = pObj->GetSize(); 625 if(index < size) { 626 return (CPDF_PageObject*)pObj->GetAt(index); 627 } 628 return NULL; 629 } 630 FX_BOOL CPDF_LayoutElement::AddObject(CPDF_PageObject* pObj) 631 { 632 return m_ObjArray.Add(pObj); 633 } 634 IPDF_LayoutProvider* IPDF_LayoutProvider::Create_LayoutProvider_TaggedPDF(CPDF_PageObjects* pPage) 635 { 636 if(pPage == NULL) { 637 return NULL; 638 } 639 CPDF_LayoutProvider_TaggedPDF* pProvider = FX_NEW CPDF_LayoutProvider_TaggedPDF; 640 if (!pProvider) { 641 return NULL; 642 } 643 pProvider->Init(pPage); 644 return pProvider; 645 } 646 CPDF_LayoutProvider_TaggedPDF::CPDF_LayoutProvider_TaggedPDF() 647 { 648 m_pPause = NULL; 649 m_pRoot = NULL; 650 m_pPageTree = NULL; 651 m_pCurTaggedElement = NULL; 652 } 653 CPDF_LayoutProvider_TaggedPDF::~CPDF_LayoutProvider_TaggedPDF() 654 { 655 m_pCurTaggedElement = NULL; 656 m_pPause = NULL; 657 if(m_pRoot) { 658 delete m_pRoot; 659 } 660 m_pRoot = NULL; 661 if(m_pPageTree) { 662 delete m_pPageTree; 663 } 664 m_pPageTree = NULL; 665 } 666 void CPDF_LayoutProvider_TaggedPDF::ProcessElement(CPDF_LayoutElement*pParent, CPDF_StructElement* pTaggedElement) 667 { 668 if(!pTaggedElement) { 669 return; 670 } 671 if(!pParent) { 672 m_Status = LayoutError; 673 return; 674 } 675 CPDF_LayoutElement* pElement = FX_NEW CPDF_LayoutElement; 676 if (!pElement) { 677 m_Status = LayoutError; 678 return; 679 } 680 pElement->m_pParentElement = pParent; 681 pElement->m_pTaggedElement = pTaggedElement; 682 pParent->m_ChildArray.Add(pElement); 683 int count = pTaggedElement->CountKids(); 684 for(int i = 0; i < count; i++) { 685 CPDF_StructKid Kid = pTaggedElement->GetKid(i); 686 switch(Kid.m_Type) { 687 case CPDF_StructKid::Element: { 688 ProcessElement(pElement, Kid.m_Element.m_pElement); 689 if(m_Status != LayoutReady) { 690 return ; 691 } 692 } 693 break; 694 case CPDF_StructKid::PageContent: { 695 int count = m_pPage->CountObjects(); 696 FX_POSITION pos = m_pPage->GetFirstObjectPosition(); 697 if(!pos) { 698 m_Status = LayoutError; 699 return ; 700 } 701 while (pos) { 702 CPDF_PageObject* pObj = m_pPage->GetNextObject(pos); 703 int pbjMCID = pObj->m_ContentMark.GetMCID(); 704 if((FX_DWORD)(pObj->m_ContentMark.GetMCID()) == Kid.m_PageContent.m_ContentId) { 705 pElement->AddObject(pObj); 706 } 707 } 708 } 709 break; 710 case CPDF_StructKid::StreamContent: 711 case CPDF_StructKid::Object: 712 default: 713 break; 714 } 715 } 716 } 717 LayoutStatus CPDF_LayoutProvider_TaggedPDF::StartLoad(IFX_Pause* pPause) 718 { 719 m_pPause = pPause; 720 if(m_pPage->m_pDocument && m_pPage->m_pFormDict) { 721 m_pPageTree = CPDF_StructTree::LoadPage(m_pPage->m_pDocument, m_pPage->m_pFormDict); 722 } 723 if(!m_pPageTree) { 724 m_Status = LayoutError; 725 return LayoutError; 726 } 727 int count = m_pPageTree->CountTopElements(); 728 if(count == 0) { 729 m_Status = LayoutError; 730 return LayoutError; 731 } 732 m_pRoot = FX_NEW CPDF_LayoutElement; 733 if (!m_pRoot) { 734 m_Status = LayoutError; 735 return LayoutError; 736 } 737 for(int i = 0; i < count; i++) { 738 CPDF_StructElement* pElement = m_pPageTree->GetTopElement(i); 739 if(pElement) { 740 ProcessElement(m_pRoot, pElement); 741 if(m_Status != LayoutReady) { 742 return m_Status; 743 } 744 } 745 } 746 m_pCurTaggedElement = NULL; 747 m_Status = LayoutFinished; 748 return LayoutFinished; 749 } 750 LayoutStatus CPDF_LayoutProvider_TaggedPDF::Continue() 751 { 752 if(!m_pCurTaggedElement) { 753 return LayoutError; 754 } 755 if(m_Status != LayoutToBeContinued) { 756 return LayoutError; 757 } 758 m_Status = LayoutReady; 759 int count = m_pPageTree->CountTopElements(); 760 for(int i = 0; i < count; i++) { 761 CPDF_StructElement* pElement = m_pPageTree->GetTopElement(i); 762 if(pElement) { 763 ProcessElement(m_pRoot, pElement); 764 if(m_Status != LayoutReady) { 765 return m_Status; 766 } 767 } 768 } 769 m_pCurTaggedElement = NULL; 770 m_Status = LayoutFinished; 771 return LayoutFinished; 772 } 773 int CPDF_LayoutProvider_TaggedPDF::GetPosition() 774 { 775 if(m_TopElementIndex == 0) { 776 return 0; 777 } 778 int count = m_pPageTree->CountTopElements(); 779 return m_TopElementIndex / count * 100; 780 } 781