@@ -66,6 +66,70 @@ static const char* tag_name_from_type(SkPDF::DocumentStructureType type) {
6666 SK_ABORT (" bad tag" );
6767}
6868
69+ SkPDF::AttributeList::AttributeList () = default;
70+
71+ SkPDF::AttributeList::~AttributeList () = default ;
72+
73+ void SkPDF::AttributeList::appendInt (
74+ const char * owner, const char * name, int value) {
75+ if (!fAttrs )
76+ fAttrs = SkPDFMakeArray ();
77+ std::unique_ptr<SkPDFDict> attrDict = SkPDFMakeDict ();
78+ attrDict->insertName (" O" , owner);
79+ attrDict->insertInt (name, value);
80+ fAttrs ->appendObject (std::move (attrDict));
81+ }
82+
83+ void SkPDF::AttributeList::appendFloat (
84+ const char * owner, const char * name, float value) {
85+ if (!fAttrs )
86+ fAttrs = SkPDFMakeArray ();
87+ std::unique_ptr<SkPDFDict> attrDict = SkPDFMakeDict ();
88+ attrDict->insertName (" O" , owner);
89+ attrDict->insertScalar (name, value);
90+ fAttrs ->appendObject (std::move (attrDict));
91+ }
92+
93+ void SkPDF::AttributeList::appendString (
94+ const char * owner, const char * name, const char * value) {
95+ if (!fAttrs )
96+ fAttrs = SkPDFMakeArray ();
97+ std::unique_ptr<SkPDFDict> attrDict = SkPDFMakeDict ();
98+ attrDict->insertName (" O" , owner);
99+ attrDict->insertName (name, value);
100+ fAttrs ->appendObject (std::move (attrDict));
101+ }
102+
103+ void SkPDF::AttributeList::appendFloatArray (
104+ const char * owner, const char * name, const std::vector<float >& value) {
105+ if (!fAttrs )
106+ fAttrs = SkPDFMakeArray ();
107+ std::unique_ptr<SkPDFDict> attrDict = SkPDFMakeDict ();
108+ attrDict->insertName (" O" , owner);
109+ std::unique_ptr<SkPDFArray> pdfArray = SkPDFMakeArray ();
110+ for (float element : value) {
111+ pdfArray->appendScalar (element);
112+ }
113+ attrDict->insertObject (name, std::move (pdfArray));
114+ fAttrs ->appendObject (std::move (attrDict));
115+ }
116+
117+ void SkPDF::AttributeList::appendStringArray (
118+ const char * owner,
119+ const char * name,
120+ const std::vector<SkString>& value) {
121+ if (!fAttrs )
122+ fAttrs = SkPDFMakeArray ();
123+ std::unique_ptr<SkPDFDict> attrDict = SkPDFMakeDict ();
124+ attrDict->insertName (" O" , owner);
125+ std::unique_ptr<SkPDFArray> pdfArray = SkPDFMakeArray ();
126+ for (SkString element : value) {
127+ pdfArray->appendName (element);
128+ }
129+ attrDict->insertObject (name, std::move (pdfArray));
130+ fAttrs ->appendObject (std::move (attrDict));
131+ }
132+
69133struct SkPDFTagNode {
70134 SkPDFTagNode* fChildren = nullptr ;
71135 size_t fChildCount = 0 ;
@@ -82,16 +146,18 @@ struct SkPDFTagNode {
82146 kYes ,
83147 kNo ,
84148 } fCanDiscard = kUnknown ;
149+ std::unique_ptr<SkPDFArray> fAttributes ;
85150};
86151
87152SkPDFTagTree::SkPDFTagTree () : fArena(4 * sizeof (SkPDFTagNode)) {}
88153
89154SkPDFTagTree::~SkPDFTagTree () = default ;
90155
91- static void copy (const SkPDF::StructureElementNode& node,
92- SkPDFTagNode* dst,
93- SkArenaAlloc* arena,
94- SkTHashMap<int , SkPDFTagNode*>* nodeMap) {
156+ // static
157+ void SkPDFTagTree::Copy (SkPDF::StructureElementNode& node,
158+ SkPDFTagNode* dst,
159+ SkArenaAlloc* arena,
160+ SkTHashMap<int , SkPDFTagNode*>* nodeMap) {
95161 nodeMap->set (node.fNodeId , dst);
96162 size_t childCount = node.fChildCount ;
97163 SkPDFTagNode* children = arena->makeArray <SkPDFTagNode>(childCount);
@@ -100,14 +166,15 @@ static void copy(const SkPDF::StructureElementNode& node,
100166 dst->fType = node.fType ;
101167 dst->fChildren = children;
102168 for (size_t i = 0 ; i < childCount; ++i) {
103- copy (node.fChildren [i], &children[i], arena, nodeMap);
169+ Copy (node.fChildren [i], &children[i], arena, nodeMap);
104170 }
171+ dst->fAttributes = std::move (node.fAttributes .fAttrs );
105172}
106173
107- void SkPDFTagTree::init (const SkPDF::StructureElementNode* node) {
174+ void SkPDFTagTree::init (SkPDF::StructureElementNode* node) {
108175 if (node) {
109176 fRoot = fArena .make <SkPDFTagNode>();
110- copy (*node, fRoot , &fArena , &fNodeMap );
177+ Copy (*node, fRoot , &fArena , &fNodeMap );
111178 }
112179}
113180
@@ -184,6 +251,13 @@ SkPDFIndirectReference prepare_tag_tree_to_emit(SkPDFIndirectReference parent,
184251 dict.insertName (" S" , tag_name_from_type (node->fType ));
185252 dict.insertRef (" P" , parent);
186253 dict.insertObject (" K" , std::move (kids));
254+ SkString idString;
255+ idString.printf (" %d" , node->fNodeId );
256+ dict.insertName (" ID" , idString.c_str ());
257+ if (node->fAttributes ) {
258+ dict.insertObject (" A" , std::move (node->fAttributes ));
259+ }
260+
187261 return doc->emit (dict, ref);
188262}
189263
@@ -223,4 +297,3 @@ SkPDFIndirectReference SkPDFTagTree::makeStructTreeRoot(SkPDFDocument* doc) {
223297 structTreeRoot.insertRef (" ParentTree" , doc->emit (parentTree));
224298 return doc->emit (structTreeRoot, ref);
225299}
226-
0 commit comments