Home | History | Annotate | Download | only in reflow
      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 = new CPDF_LayoutProvider_TaggedPDF;
    640     pProvider->Init(pPage);
    641     return pProvider;
    642 }
    643 CPDF_LayoutProvider_TaggedPDF::CPDF_LayoutProvider_TaggedPDF()
    644 {
    645     m_pPause = NULL;
    646     m_pRoot = NULL;
    647     m_pPageTree = NULL;
    648     m_pCurTaggedElement = NULL;
    649 }
    650 CPDF_LayoutProvider_TaggedPDF::~CPDF_LayoutProvider_TaggedPDF()
    651 {
    652     m_pCurTaggedElement = NULL;
    653     m_pPause = NULL;
    654     if(m_pRoot) {
    655         delete m_pRoot;
    656     }
    657     m_pRoot = NULL;
    658     if(m_pPageTree) {
    659         delete m_pPageTree;
    660     }
    661     m_pPageTree = NULL;
    662 }
    663 void CPDF_LayoutProvider_TaggedPDF::ProcessElement(CPDF_LayoutElement*pParent, CPDF_StructElement* pTaggedElement)
    664 {
    665     if(!pTaggedElement) {
    666         return;
    667     }
    668     if(!pParent) {
    669         m_Status = LayoutError;
    670         return;
    671     }
    672     CPDF_LayoutElement* pElement = new CPDF_LayoutElement;
    673     pElement->m_pParentElement = pParent;
    674     pElement->m_pTaggedElement = pTaggedElement;
    675     pParent->m_ChildArray.Add(pElement);
    676     int count = pTaggedElement->CountKids();
    677     for(int i = 0; i < count; i++) {
    678         CPDF_StructKid Kid = pTaggedElement->GetKid(i);
    679         switch(Kid.m_Type) {
    680             case CPDF_StructKid::Element: {
    681                     ProcessElement(pElement, Kid.m_Element.m_pElement);
    682                     if(m_Status != LayoutReady) {
    683                         return ;
    684                     }
    685                 }
    686                 break;
    687             case CPDF_StructKid::PageContent: {
    688                     int count = m_pPage->CountObjects();
    689                     FX_POSITION pos = m_pPage->GetFirstObjectPosition();
    690                     if(!pos) {
    691                         m_Status = LayoutError;
    692                         return ;
    693                     }
    694                     while (pos) {
    695                         CPDF_PageObject* pObj = m_pPage->GetNextObject(pos);
    696                         int pbjMCID = pObj->m_ContentMark.GetMCID();
    697                         if((FX_DWORD)(pObj->m_ContentMark.GetMCID()) == Kid.m_PageContent.m_ContentId) {
    698                             pElement->AddObject(pObj);
    699                         }
    700                     }
    701                 }
    702                 break;
    703             case CPDF_StructKid::StreamContent:
    704             case CPDF_StructKid::Object:
    705             default:
    706                 break;
    707         }
    708     }
    709 }
    710 LayoutStatus CPDF_LayoutProvider_TaggedPDF::StartLoad(IFX_Pause* pPause)
    711 {
    712     m_pPause = pPause;
    713     if(m_pPage->m_pDocument && m_pPage->m_pFormDict) {
    714         m_pPageTree = CPDF_StructTree::LoadPage(m_pPage->m_pDocument, m_pPage->m_pFormDict);
    715     }
    716     if(!m_pPageTree) {
    717         m_Status = LayoutError;
    718         return LayoutError;
    719     }
    720     int count = m_pPageTree->CountTopElements();
    721     if(count == 0) {
    722         m_Status = LayoutError;
    723         return LayoutError;
    724     }
    725     m_pRoot = new CPDF_LayoutElement;
    726     for(int i = 0; i < count; i++) {
    727         CPDF_StructElement* pElement = m_pPageTree->GetTopElement(i);
    728         if(pElement) {
    729             ProcessElement(m_pRoot, pElement);
    730             if(m_Status != LayoutReady) {
    731                 return m_Status;
    732             }
    733         }
    734     }
    735     m_pCurTaggedElement = NULL;
    736     m_Status = LayoutFinished;
    737     return LayoutFinished;
    738 }
    739 LayoutStatus CPDF_LayoutProvider_TaggedPDF::Continue()
    740 {
    741     if(!m_pCurTaggedElement) {
    742         return LayoutError;
    743     }
    744     if(m_Status != LayoutToBeContinued) {
    745         return LayoutError;
    746     }
    747     m_Status = LayoutReady;
    748     int count = m_pPageTree->CountTopElements();
    749     for(int i = 0; i < count; i++) {
    750         CPDF_StructElement* pElement = m_pPageTree->GetTopElement(i);
    751         if(pElement) {
    752             ProcessElement(m_pRoot, pElement);
    753             if(m_Status != LayoutReady) {
    754                 return m_Status;
    755             }
    756         }
    757     }
    758     m_pCurTaggedElement = NULL;
    759     m_Status = LayoutFinished;
    760     return LayoutFinished;
    761 }
    762 int CPDF_LayoutProvider_TaggedPDF::GetPosition()
    763 {
    764     if(m_TopElementIndex == 0) {
    765         return 0;
    766     }
    767     int count = m_pPageTree->CountTopElements();
    768     return m_TopElementIndex / count * 100;
    769 }
    770