* Check if a field dictionary represents a terminal field. * * A field is terminal if: * - It has no /Kids, OR * - Its /Kids contain widgets (no /T) rather than child fields (have /T)
(dict: PdfDict, registry: ObjectRegistry)
| 263 | * - Its /Kids contain widgets (no /T) rather than child fields (have /T) |
| 264 | */ |
| 265 | function checkIsTerminalField(dict: PdfDict, registry: ObjectRegistry): boolean { |
| 266 | const resolve = registry.resolve.bind(registry); |
| 267 | const kids = dict.getArray("Kids", resolve); |
| 268 | |
| 269 | if (!kids || kids.length === 0) { |
| 270 | return true; |
| 271 | } |
| 272 | |
| 273 | // Check the first kid - if it has /T, these are child fields (non-terminal) |
| 274 | // If it has no /T, these are widgets (terminal) |
| 275 | let firstKid = kids.at(0); |
| 276 | |
| 277 | if (!firstKid) { |
| 278 | return true; |
| 279 | } |
| 280 | |
| 281 | let firstKidDict: PdfDict | null = null; |
| 282 | |
| 283 | if (firstKid instanceof PdfRef) { |
| 284 | firstKid = registry.resolve(firstKid) ?? undefined; |
| 285 | } |
| 286 | |
| 287 | if (firstKid instanceof PdfDict) { |
| 288 | firstKidDict = firstKid; |
| 289 | } |
| 290 | |
| 291 | if (!firstKidDict) { |
| 292 | return true; |
| 293 | } |
| 294 | |
| 295 | // If first kid has /T, it's a child field → parent is non-terminal |
| 296 | // If first kid has no /T, it's a widget → parent is terminal |
| 297 | return !firstKidDict.has("T"); |
| 298 | } |