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"
CPDF_LayoutElement()8 CPDF_LayoutElement::CPDF_LayoutElement()
9 {
10 m_pTaggedElement = NULL;
11 m_pParentElement = NULL;
12 }
~CPDF_LayoutElement()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 }
ConvertLayoutType(FX_BSTR name)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 }
ConvertLayoutType(LayoutType type)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 }
ConvertLayoutAttr(LayoutAttr attr)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 }
ConvertLayoutEnum(CFX_ByteStringC Enum)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 }
GetType()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 }
CountAttrValues(LayoutAttr attr_type)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 }
GetEnumAttr(LayoutAttr attr_type,int index)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 }
GetAttrOwner(LayoutAttr attr_type)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 }
GetNumberAttr(LayoutAttr attr_type,int index)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 }
GetColorAttr(LayoutAttr attr_type,int index)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 }
GetDefaultFloatValue(LayoutAttr attr_type)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 }
GetDefaultColorValue(LayoutAttr attr_type)535 FX_COLORREF CPDF_LayoutElement::GetDefaultColorValue(LayoutAttr attr_type)
536 {
537 return -1;
538 }
GetDefaultNameValue(LayoutAttr attr_type)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 }
IsInheritable(LayoutAttr type)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 }
CountChildren()597 int CPDF_LayoutElement::CountChildren()
598 {
599 return m_ChildArray.GetSize();
600 }
GetChild(int index)601 IPDF_LayoutElement* CPDF_LayoutElement::GetChild(int index)
602 {
603 return (IPDF_LayoutElement*)m_ChildArray.GetAt(index);
604 }
GetParent()605 IPDF_LayoutElement* CPDF_LayoutElement::GetParent()
606 {
607 return m_pParentElement;
608 }
CountObjects()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 }
GetObject(int index)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 }
AddObject(CPDF_PageObject * pObj)630 FX_BOOL CPDF_LayoutElement::AddObject(CPDF_PageObject* pObj)
631 {
632 return m_ObjArray.Add(pObj);
633 }
Create_LayoutProvider_TaggedPDF(CPDF_PageObjects * pPage)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 }
CPDF_LayoutProvider_TaggedPDF()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 }
~CPDF_LayoutProvider_TaggedPDF()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 }
ProcessElement(CPDF_LayoutElement * pParent,CPDF_StructElement * pTaggedElement)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 }
StartLoad(IFX_Pause * pPause)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 }
Continue()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 }
GetPosition()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