Exemple #1
0
        /// <summary>Transforms root tags in a way that complies with the tagged PDF specification.</summary>
        /// <remarks>
        /// Transforms root tags in a way that complies with the tagged PDF specification.
        /// Depending on PDF version behaviour may differ.
        /// <br />
        /// ISO 32000-1 (PDF 1.7 and lower)
        /// 14.8.4.2 Grouping Elements
        /// <br />
        /// "In a tagged PDF document, the structure tree shall contain a single top-level element; that is,
        /// the structure tree root (identified by the StructTreeRoot entry in the document catalogue) shall
        /// have only one child in its K (kids) array. If the PDF file contains a complete document, the structure
        /// type Document should be used for this top-level element in the logical structure hierarchy. If the file
        /// contains a well-formed document fragment, one of the structure types Part, Art, Sect, or Div may be used instead."
        /// <br />
        /// For PDF 2.0 and higher root tag is allowed to have only the Document role.
        /// </remarks>
        public virtual void NormalizeDocumentRootTag()
        {
            // in this method we could deal with existing document, so we don't won't to throw exceptions here
            bool forbid = forbidUnknownRoles;

            forbidUnknownRoles = false;
            IList <IStructureNode> rootKids = document.GetStructTreeRoot().GetKids();
            IRoleMappingResolver   mapping  = null;

            if (rootKids.Count > 0)
            {
                PdfStructElem firstKid = (PdfStructElem)rootKids[0];
                mapping = ResolveMappingToStandardOrDomainSpecificRole(firstKid.GetRole().GetValue(), firstKid.GetNamespace
                                                                           ());
            }
            if (rootKids.Count == 1 && mapping != null && mapping.CurrentRoleIsStandard() && IsRoleAllowedToBeRoot(mapping
                                                                                                                   .GetRole()))
            {
                rootTagElement = (PdfStructElem)rootKids[0];
            }
            else
            {
                document.GetStructTreeRoot().GetPdfObject().Remove(PdfName.K);
                rootTagElement = new RootTagNormalizer(this, rootTagElement, document).MakeSingleStandardRootTag(rootKids);
            }
            forbidUnknownRoles = forbid;
        }
Exemple #2
0
        private void SetNamespaceForNewTagsBasedOnExistingRoot()
        {
            IList <IStructureNode> rootKids = document.GetStructTreeRoot().GetKids();

            if (rootKids.Count > 0)
            {
                PdfStructElem        firstKid        = (PdfStructElem)rootKids[0];
                IRoleMappingResolver resolvedMapping = ResolveMappingToStandardOrDomainSpecificRole(firstKid.GetRole().GetValue
                                                                                                        (), firstKid.GetNamespace());
                if (resolvedMapping == null || !resolvedMapping.CurrentRoleIsStandard())
                {
                    ILog   logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.Tagutils.TagStructureContext));
                    String nsStr;
                    if (firstKid.GetNamespace() != null)
                    {
                        nsStr = firstKid.GetNamespace().GetNamespaceName();
                    }
                    else
                    {
                        nsStr = StandardNamespaces.GetDefault();
                    }
                    logger.Warn(String.Format(iText.IO.LogMessageConstant.EXISTING_TAG_STRUCTURE_ROOT_IS_NOT_STANDARD, firstKid
                                              .GetRole().GetValue(), nsStr));
                }
                if (resolvedMapping == null || !StandardNamespaces.PDF_1_7.Equals(resolvedMapping.GetNamespace().GetNamespaceName
                                                                                      ()))
                {
                    documentDefaultNamespace = FetchNamespace(StandardNamespaces.PDF_2_0);
                }
            }
            else
            {
                documentDefaultNamespace = FetchNamespace(StandardNamespaces.PDF_2_0);
            }
        }
Exemple #3
0
        /// <summary>
        /// Gets an instance of the
        /// <see cref="IRoleMappingResolver"/>
        /// which is already in the "resolved" state: it returns
        /// role in the standard or domain-specific namespace for the
        /// <see cref="IRoleMappingResolver.GetRole()"/>
        /// and
        /// <see cref="IRoleMappingResolver.GetNamespace()"/>
        /// methods calls which correspond to the mapping of the given role; or null if the given role is not mapped to the standard or domain-specific one.
        /// </summary>
        /// <param name="role">a role in the given namespace which mapping is to be resolved.</param>
        /// <param name="namespace">
        /// a
        /// <see cref="iText.Kernel.Pdf.Tagging.PdfNamespace"/>
        /// which this role belongs to.
        /// </param>
        /// <returns>
        /// an instance of the
        /// <see cref="IRoleMappingResolver"/>
        /// which returns false
        /// for the
        /// <see cref="IRoleMappingResolver.CurrentRoleShallBeMappedToStandard()"/>
        /// method call; if mapping cannot be resolved
        /// to this state, this method returns null, which means that the given role
        /// in the specified namespace is not mapped to the standard role in the standard namespace.
        /// </returns>
        public virtual IRoleMappingResolver ResolveMappingToStandardOrDomainSpecificRole(String role, PdfNamespace
                                                                                         @namespace)
        {
            IRoleMappingResolver mappingResolver = GetRoleMappingResolver(role, @namespace);

            mappingResolver.ResolveNextMapping();
            int i = 0;
            // reasonably large arbitrary number that will help to avoid a possible infinite loop
            int maxIters = 100;

            while (mappingResolver.CurrentRoleShallBeMappedToStandard())
            {
                if (++i > maxIters)
                {
                    ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.Tagutils.TagStructureContext));
                    logger.Error(ComposeTooMuchTransitiveMappingsException(role, @namespace));
                    return(null);
                }
                if (!mappingResolver.ResolveNextMapping())
                {
                    return(null);
                }
            }
            return(mappingResolver);
        }
        public static PdfStructureAttributes GetLayoutAttributes(AbstractRenderer renderer, TagTreePointer taggingPointer
                                                                 )
        {
            IRoleMappingResolver resolvedMapping = ResolveMappingToStandard(taggingPointer);

            if (resolvedMapping == null)
            {
                return(null);
            }
            String        role       = resolvedMapping.GetRole();
            int           tagType    = AccessibleTypes.IdentifyType(role);
            PdfDictionary attributes = new PdfDictionary();

            attributes.Put(PdfName.O, PdfName.Layout);
            //TODO WritingMode attribute applying when needed
            ApplyCommonLayoutAttributes(renderer, attributes);
            if (tagType == AccessibleTypes.BlockLevel)
            {
                ApplyBlockLevelLayoutAttributes(role, renderer, attributes);
            }
            if (tagType == AccessibleTypes.InlineLevel)
            {
                ApplyInlineLevelLayoutAttributes(renderer, attributes);
            }
            if (tagType == AccessibleTypes.Illustration)
            {
                ApplyIllustrationLayoutAttributes(renderer, attributes);
            }
            return(attributes.Size() > 1 ? new PdfStructureAttributes(attributes) : null);
        }
        public static PdfStructureAttributes GetTableAttributes(AbstractRenderer renderer, TagTreePointer taggingPointer
                                                                )
        {
            IRoleMappingResolver resolvedMapping = ResolveMappingToStandard(taggingPointer);

            if (resolvedMapping == null || !StandardRoles.TD.Equals(resolvedMapping.GetRole()) && !StandardRoles.TH.Equals
                    (resolvedMapping.GetRole()))
            {
                return(null);
            }
            PdfDictionary attributes = new PdfDictionary();

            attributes.Put(PdfName.O, PdfName.Table);
            if (renderer.GetModelElement() is Cell)
            {
                Cell cell = (Cell)renderer.GetModelElement();
                if (cell.GetRowspan() != 1)
                {
                    attributes.Put(PdfName.RowSpan, new PdfNumber(cell.GetRowspan()));
                }
                if (cell.GetColspan() != 1)
                {
                    attributes.Put(PdfName.ColSpan, new PdfNumber(cell.GetColspan()));
                }
            }
            return(attributes.Size() > 1 ? new PdfStructureAttributes(attributes) : null);
        }
        public static PdfStructureAttributes GetListAttributes(AbstractRenderer renderer, TagTreePointer taggingPointer
                                                               )
        {
            IRoleMappingResolver resolvedMapping = null;

            resolvedMapping = ResolveMappingToStandard(taggingPointer);
            if (resolvedMapping == null || !StandardRoles.L.Equals(resolvedMapping.GetRole()))
            {
                return(null);
            }
            PdfDictionary attributes = new PdfDictionary();

            attributes.Put(PdfName.O, PdfName.List);
            Object listSymbol       = renderer.GetProperty <Object>(Property.LIST_SYMBOL);
            bool   tagStructurePdf2 = IsTagStructurePdf2(resolvedMapping.GetNamespace());

            if (listSymbol is ListNumberingType)
            {
                ListNumberingType numberingType = (ListNumberingType)listSymbol;
                attributes.Put(PdfName.ListNumbering, TransformNumberingTypeToName(numberingType, tagStructurePdf2));
            }
            else
            {
                if (tagStructurePdf2)
                {
                    if (listSymbol is IListSymbolFactory)
                    {
                        attributes.Put(PdfName.ListNumbering, PdfName.Ordered);
                    }
                    else
                    {
                        attributes.Put(PdfName.ListNumbering, PdfName.Unordered);
                    }
                }
            }
            return(attributes.Size() > 1 ? new PdfStructureAttributes(attributes) : null);
        }
Exemple #7
0
        private void LogCreatedRootTagHasMappingIssue(PdfNamespace rootTagOriginalNs, IRoleMappingResolver mapping
                                                      )
        {
            String origRootTagNs = "";

            if (rootTagOriginalNs != null && rootTagOriginalNs.GetNamespaceName() != null)
            {
                origRootTagNs = " in \"" + rootTagOriginalNs.GetNamespaceName() + "\" namespace";
            }
            String mappingRole = " to ";

            if (mapping != null)
            {
                mappingRole += "\"" + mapping.GetRole() + "\"";
                if (mapping.GetNamespace() != null && !StandardNamespaces.PDF_1_7.Equals(mapping.GetNamespace().GetNamespaceName
                                                                                             ()))
                {
                    mappingRole += " in \"" + mapping.GetNamespace().GetNamespaceName() + "\" namespace";
                }
            }
            else
            {
                mappingRole += "not standard role";
            }
            ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.Tagutils.RootTagNormalizer));

            logger.Warn(String.Format(iText.IO.LogMessageConstant.CREATED_ROOT_TAG_HAS_MAPPING, origRootTagNs, mappingRole
                                      ));
        }