public override void Draw(DrawContext drawContext) { LayoutTaggingHelper taggingHelper = GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); // We want to reach the actual tag from logical structure tree, in order to set custom properties, for // which iText doesn't provide convenient API at the moment. Specifically we are aiming at setting /ID // entry in structure element dictionary corresponding to the table header cell. Here we are creating tag // for the current element in logical structure tree right at the beginning of #draw method. // If this particular instance of header cell is paging artifact it would be marked so by layouting // engine and it would not allow to create a tag (return value of the method would be 'false'). // If this particular instance of header cell is the header which is to be tagged, a tag will be created. // It's safe to create a tag at this moment, it will be picked up and placed at correct position in the // logical structure tree later by layout engine. TagTreePointer p = new TagTreePointer(pdfDocument); if (taggingHelper.CreateTag(this, p)) { // After the tag is created, we can fetch low level entity PdfStructElem // in order to work with it directly. These changes would be directly reflected // in the PDF file inner structure. PdfStructElem structElem = tagContext.GetPointerStructElem(p); PdfDictionary structElemDict = structElem.GetPdfObject(); structElemDict.Put(PdfName.ID, headerId); idTree.AddEntry(headerId.GetValue(), structElemDict); } base.Draw(drawContext); }
/// <summary>Draws margin boxes.</summary> /// <param name="pageNumber">the page</param> /// <param name="pdfDocument"> /// the /// <see cref="iText.Kernel.Pdf.PdfDocument"/> /// to which content is written /// </param> /// <param name="documentRenderer">the document renderer</param> private void DrawMarginBoxes(int pageNumber, PdfDocument pdfDocument, DocumentRenderer documentRenderer) { if (properties.GetResolvedPageMarginBoxes().IsEmpty()) { return; } PdfPage page = pdfDocument.GetPage(pageNumber); foreach (PageMarginBoxContextNode marginBoxContentNode in properties.GetResolvedPageMarginBoxes()) { IElement curBoxElement = ProcessMarginBoxContent(marginBoxContentNode, pageNumber, context); IRenderer renderer = curBoxElement.CreateRendererSubTree(); RemoveAreaBreaks(renderer); renderer.SetParent(documentRenderer); bool isTagged = pdfDocument.IsTagged(); if (isTagged) { LayoutTaggingHelper taggingHelper = renderer.GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); LayoutTaggingHelper.AddTreeHints(taggingHelper, renderer); } LayoutResult result = renderer.Layout(new LayoutContext(new LayoutArea(pageNumber, marginBoxContentNode.GetPageMarginBoxRectangle ()))); IRenderer rendererToDraw = result.GetStatus() == LayoutResult.FULL ? renderer : result.GetSplitRenderer(); if (rendererToDraw != null) { TagTreePointer tagPointer = null; TagTreePointer backupPointer = null; PdfPage backupPage = null; if (isTagged) { tagPointer = pdfDocument.GetTagStructureContext().GetAutoTaggingPointer(); backupPage = tagPointer.GetCurrentPage(); backupPointer = new TagTreePointer(tagPointer); tagPointer.MoveToRoot(); tagPointer.SetPageForTagging(page); } rendererToDraw.SetParent(documentRenderer).Draw(new DrawContext(page.GetDocument(), new PdfCanvas(page), isTagged )); if (isTagged) { tagPointer.SetPageForTagging(backupPage); tagPointer.MoveToPointer(backupPointer); } } else { // marginBoxElements have overflow property set to HIDDEN, therefore it is not expected to neither get // LayoutResult other than FULL nor get no split renderer (result NOTHING) even if result is not FULL ILog logger = LogManager.GetLogger(typeof(iText.Html2pdf.Attach.Impl.Layout.PageContextProcessor)); logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.PAGE_MARGIN_BOX_CONTENT_CANNOT_BE_DRAWN , marginBoxContentNode.GetMarginBoxName())); } } }
protected internal virtual void CreateAndAddRendererSubTree(IElement element) { IRenderer rendererSubTreeRoot = element.CreateRendererSubTree(); LayoutTaggingHelper taggingHelper = InitTaggingHelperIfNeeded(); if (taggingHelper != null) { taggingHelper.AddKidsHint(pdfDocument.GetTagStructureContext().GetAutoTaggingPointer(), JavaCollectionsUtil .SingletonList <IRenderer>(rendererSubTreeRoot)); } EnsureRootRendererNotNull().AddChild(rendererSubTreeRoot); }
private IRenderer CreateRendererFromElement(IElement element, DocumentRenderer documentRenderer, PdfDocument pdfDocument) { if (element != null) { IRenderer renderer = element.CreateRendererSubTree(); RemoveAreaBreaks(renderer); renderer.SetParent(documentRenderer); if (pdfDocument.IsTagged()) { LayoutTaggingHelper taggingHelper = renderer.GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); LayoutTaggingHelper.AddTreeHints(taggingHelper, renderer); } return(renderer); } return(null); }
/// <summary> /// This method correctly closes the /// <see cref="RootRenderer"/> /// instance. /// There might be hanging elements, like in case of /// <see cref="iText.Layout.Properties.Property.KEEP_WITH_NEXT"/> /// is set to true /// and when no consequent element has been added. This method addresses such situations. /// </summary> public virtual void Close() { AddAllWaitingNextPageRenderers(); if (keepWithNextHangingRenderer != null) { keepWithNextHangingRenderer.SetProperty(Property.KEEP_WITH_NEXT, false); IRenderer rendererToBeAdded = keepWithNextHangingRenderer; keepWithNextHangingRenderer = null; AddChild(rendererToBeAdded); } if (!immediateFlush) { Flush(); } FlushWaitingDrawingElements(); LayoutTaggingHelper taggingHelper = this.GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); if (taggingHelper != null) { taggingHelper.ReleaseAllHints(); } }
protected internal override LayoutArea UpdateCurrentArea(LayoutResult overflowResult) { FlushWaitingDrawingElements(); LayoutTaggingHelper taggingHelper = this.GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); if (taggingHelper != null) { taggingHelper.ReleaseFinishedHints(); } AreaBreak areaBreak = overflowResult != null && overflowResult.GetAreaBreak() != null?overflowResult.GetAreaBreak () : null; if (areaBreak != null && areaBreak.GetAreaType() == AreaBreakType.LAST_PAGE) { while (currentPageNumber < document.GetPdfDocument().GetNumberOfPages()) { MoveToNextPage(); } } else { MoveToNextPage(); } PageSize customPageSize = areaBreak != null?areaBreak.GetPageSize() : null; while (document.GetPdfDocument().GetNumberOfPages() >= currentPageNumber && document.GetPdfDocument().GetPage (currentPageNumber).IsFlushed()) { currentPageNumber++; } PageSize lastPageSize = EnsureDocumentHasNPages(currentPageNumber, customPageSize); if (lastPageSize == null) { lastPageSize = new PageSize(document.GetPdfDocument().GetPage(currentPageNumber).GetTrimBox()); } return(currentArea = new RootLayoutArea(currentPageNumber, GetCurrentPageEffectiveArea(lastPageSize))); }
public override void AddChild(IRenderer renderer) { LayoutTaggingHelper taggingHelper = this.GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); if (taggingHelper != null) { LayoutTaggingHelper.AddTreeHints(taggingHelper, renderer); } // Some positioned renderers might have been fetched from non-positioned child and added to this renderer, // so we use this generic mechanism of determining which renderers have been just added. int numberOfChildRenderers = childRenderers.Count; int numberOfPositionedChildRenderers = positionedRenderers.Count; base.AddChild(renderer); IList <IRenderer> addedRenderers = new List <IRenderer>(1); IList <IRenderer> addedPositionedRenderers = new List <IRenderer>(1); while (childRenderers.Count > numberOfChildRenderers) { addedRenderers.Add(childRenderers[numberOfChildRenderers]); childRenderers.JRemoveAt(numberOfChildRenderers); } while (positionedRenderers.Count > numberOfPositionedChildRenderers) { addedPositionedRenderers.Add(positionedRenderers[numberOfPositionedChildRenderers]); positionedRenderers.JRemoveAt(numberOfPositionedChildRenderers); } bool marginsCollapsingEnabled = true.Equals(GetPropertyAsBoolean(Property.COLLAPSING_MARGINS)); if (currentArea == null) { UpdateCurrentAndInitialArea(null); if (marginsCollapsingEnabled) { marginsCollapseHandler = new MarginsCollapseHandler(this, null); } } // Static layout for (int i = 0; currentArea != null && i < addedRenderers.Count; i++) { renderer = addedRenderers[i]; bool rendererIsFloat = FloatingHelper.IsRendererFloating(renderer); bool clearanceOverflowsToNextPage = FloatingHelper.IsClearanceApplied(waitingNextPageRenderers, renderer.GetProperty <ClearPropertyValue?>(Property.CLEAR)); if (rendererIsFloat && (floatOverflowedCompletely || clearanceOverflowsToNextPage)) { waitingNextPageRenderers.Add(renderer); floatOverflowedCompletely = true; continue; } ProcessWaitingKeepWithNextElement(renderer); IList <IRenderer> resultRenderers = new List <IRenderer>(); LayoutResult result = null; RootLayoutArea storedArea = null; RootLayoutArea nextStoredArea = null; MarginsCollapseInfo childMarginsInfo = null; if (marginsCollapsingEnabled && currentArea != null && renderer != null) { childMarginsInfo = marginsCollapseHandler.StartChildMarginsHandling(renderer, currentArea.GetBBox()); } while (clearanceOverflowsToNextPage || currentArea != null && renderer != null && (result = renderer.SetParent (this).Layout(new LayoutContext(currentArea.Clone(), childMarginsInfo, floatRendererAreas))).GetStatus () != LayoutResult.FULL) { bool currentAreaNeedsToBeUpdated = false; if (clearanceOverflowsToNextPage) { result = new LayoutResult(LayoutResult.NOTHING, null, null, renderer); currentAreaNeedsToBeUpdated = true; } if (result.GetStatus() == LayoutResult.PARTIAL) { if (rendererIsFloat) { waitingNextPageRenderers.Add(result.GetOverflowRenderer()); break; } else { ProcessRenderer(result.GetSplitRenderer(), resultRenderers); if (nextStoredArea != null) { currentArea = nextStoredArea; currentPageNumber = nextStoredArea.GetPageNumber(); nextStoredArea = null; } else { currentAreaNeedsToBeUpdated = true; } } } else { if (result.GetStatus() == LayoutResult.NOTHING && !clearanceOverflowsToNextPage) { if (result.GetOverflowRenderer() is ImageRenderer) { float imgHeight = ((ImageRenderer)result.GetOverflowRenderer()).GetOccupiedArea().GetBBox().GetHeight(); if (!floatRendererAreas.IsEmpty() || currentArea.GetBBox().GetHeight() < imgHeight && !currentArea.IsEmptyArea ()) { if (rendererIsFloat) { waitingNextPageRenderers.Add(result.GetOverflowRenderer()); floatOverflowedCompletely = true; break; } currentAreaNeedsToBeUpdated = true; } else { ((ImageRenderer)result.GetOverflowRenderer()).AutoScale(currentArea); result.GetOverflowRenderer().SetProperty(Property.FORCED_PLACEMENT, true); ILog logger = LogManager.GetLogger(typeof(RootRenderer)); logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "")); } } else { if (currentArea.IsEmptyArea() && result.GetAreaBreak() == null) { if (true.Equals(result.GetOverflowRenderer().GetModelElement().GetProperty <bool?>(Property.KEEP_TOGETHER)) ) { result.GetOverflowRenderer().GetModelElement().SetProperty(Property.KEEP_TOGETHER, false); ILog logger = LogManager.GetLogger(typeof(RootRenderer)); logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "KeepTogether property will be ignored." )); if (storedArea != null) { nextStoredArea = currentArea; currentArea = storedArea; currentPageNumber = storedArea.GetPageNumber(); } storedArea = currentArea; } else { if (null != result.GetCauseOfNothing() && true.Equals(result.GetCauseOfNothing().GetProperty <bool?>(Property .KEEP_TOGETHER))) { // set KEEP_TOGETHER false on the deepest parent (maybe the element itself) to have KEEP_TOGETHER == true IRenderer theDeepestKeptTogether = result.GetCauseOfNothing(); IRenderer parent; while (null == theDeepestKeptTogether.GetModelElement() || null == theDeepestKeptTogether.GetModelElement( ).GetOwnProperty <bool?>(Property.KEEP_TOGETHER)) { parent = ((AbstractRenderer)theDeepestKeptTogether).parent; if (parent == null) { break; } theDeepestKeptTogether = parent; } theDeepestKeptTogether.GetModelElement().SetProperty(Property.KEEP_TOGETHER, false); ILog logger = LogManager.GetLogger(typeof(RootRenderer)); logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "KeepTogether property of inner element will be ignored." )); } else { if (!true.Equals(renderer.GetProperty <bool?>(Property.FORCED_PLACEMENT))) { result.GetOverflowRenderer().SetProperty(Property.FORCED_PLACEMENT, true); ILog logger = LogManager.GetLogger(typeof(RootRenderer)); logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, "")); } else { // FORCED_PLACEMENT was already set to the renderer and // LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA message was logged. // This else-clause should never be hit, otherwise there is a bug in FORCED_PLACEMENT implementation. System.Diagnostics.Debug.Assert(false); // Still handling this case in order to avoid nasty infinite loops. break; } } } } else { storedArea = currentArea; if (nextStoredArea != null) { currentArea = nextStoredArea; currentPageNumber = nextStoredArea.GetPageNumber(); nextStoredArea = null; } else { if (rendererIsFloat) { waitingNextPageRenderers.Add(result.GetOverflowRenderer()); floatOverflowedCompletely = true; break; } currentAreaNeedsToBeUpdated = true; } } } } } renderer = result.GetOverflowRenderer(); if (marginsCollapsingEnabled) { marginsCollapseHandler.EndChildMarginsHandling(currentArea.GetBBox()); } if (currentAreaNeedsToBeUpdated) { UpdateCurrentAndInitialArea(result); } if (marginsCollapsingEnabled) { marginsCollapseHandler = new MarginsCollapseHandler(this, null); childMarginsInfo = marginsCollapseHandler.StartChildMarginsHandling(renderer, currentArea.GetBBox()); } clearanceOverflowsToNextPage = clearanceOverflowsToNextPage && FloatingHelper.IsClearanceApplied(waitingNextPageRenderers , renderer.GetProperty <ClearPropertyValue?>(Property.CLEAR)); } if (marginsCollapsingEnabled) { marginsCollapseHandler.EndChildMarginsHandling(currentArea.GetBBox()); } if (null != result && null != result.GetSplitRenderer()) { renderer = result.GetSplitRenderer(); } // Keep renderer until next element is added for future keep with next adjustments if (renderer != null && result != null) { if (true.Equals(renderer.GetProperty <bool?>(Property.KEEP_WITH_NEXT))) { if (true.Equals(renderer.GetProperty <bool?>(Property.FORCED_PLACEMENT))) { ILog logger = LogManager.GetLogger(typeof(RootRenderer)); logger.Warn(iText.IO.LogMessageConstant.ELEMENT_WAS_FORCE_PLACED_KEEP_WITH_NEXT_WILL_BE_IGNORED); ShrinkCurrentAreaAndProcessRenderer(renderer, resultRenderers, result); } else { keepWithNextHangingRenderer = renderer; keepWithNextHangingRendererLayoutResult = result; } } else { if (result.GetStatus() != LayoutResult.NOTHING) { ShrinkCurrentAreaAndProcessRenderer(renderer, resultRenderers, result); } } } } for (int i = 0; i < addedPositionedRenderers.Count; i++) { positionedRenderers.Add(addedPositionedRenderers[i]); renderer = positionedRenderers[positionedRenderers.Count - 1]; int?positionedPageNumber = renderer.GetProperty <int?>(Property.PAGE_NUMBER); if (positionedPageNumber == null) { positionedPageNumber = currentPageNumber; } LayoutArea layoutArea; // For position=absolute, if none of the top, bottom, left, right properties are provided, // the content should be displayed in the flow of the current content, not overlapping it. // The behavior is just if it would be statically positioned except it does not affect other elements if (Convert.ToInt32(LayoutPosition.ABSOLUTE).Equals(renderer.GetProperty <int?>(Property.POSITION)) && AbstractRenderer .NoAbsolutePositionInfo(renderer)) { layoutArea = new LayoutArea((int)positionedPageNumber, currentArea.GetBBox().Clone()); } else { layoutArea = new LayoutArea((int)positionedPageNumber, initialCurrentArea.GetBBox().Clone()); } Rectangle fullBbox = layoutArea.GetBBox().Clone(); PreparePositionedRendererAndAreaForLayout(renderer, fullBbox, layoutArea.GetBBox()); renderer.Layout(new PositionedLayoutContext(new LayoutArea(layoutArea.GetPageNumber(), fullBbox), layoutArea )); if (immediateFlush) { FlushSingleRenderer(renderer); positionedRenderers.JRemoveAt(positionedRenderers.Count - 1); } } }
private LayoutResult InitializeListSymbols(LayoutContext layoutContext) { if (!HasOwnProperty(Property.LIST_SYMBOLS_INITIALIZED)) { IList <IRenderer> symbolRenderers = new List <IRenderer>(); int listItemNum = (int)this.GetProperty <int?>(Property.LIST_START, 1); for (int i = 0; i < childRenderers.Count; i++) { childRenderers[i].SetParent(this); listItemNum = (childRenderers[i].GetProperty <int?>(Property.LIST_SYMBOL_ORDINAL_VALUE) != null) ? (int)childRenderers [i].GetProperty <int?>(Property.LIST_SYMBOL_ORDINAL_VALUE) : listItemNum; IRenderer currentSymbolRenderer = MakeListSymbolRenderer(listItemNum, childRenderers[i]); if (BaseDirection.RIGHT_TO_LEFT.Equals(this.GetProperty <BaseDirection?>(Property.BASE_DIRECTION))) { currentSymbolRenderer.SetProperty(Property.BASE_DIRECTION, BaseDirection.RIGHT_TO_LEFT); } LayoutResult listSymbolLayoutResult = null; if (currentSymbolRenderer != null) { ++listItemNum; currentSymbolRenderer.SetParent(childRenderers[i]); listSymbolLayoutResult = currentSymbolRenderer.Layout(layoutContext); currentSymbolRenderer.SetParent(null); } childRenderers[i].SetParent(null); bool isForcedPlacement = true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT)); bool listSymbolNotFit = listSymbolLayoutResult != null && listSymbolLayoutResult.GetStatus() != LayoutResult .FULL; // TODO DEVSIX-1001: partially not fitting list symbol not shown at all, however this might be improved if (listSymbolNotFit && isForcedPlacement) { currentSymbolRenderer = null; } symbolRenderers.Add(currentSymbolRenderer); if (listSymbolNotFit && !isForcedPlacement) { return(new LayoutResult(LayoutResult.NOTHING, null, null, this, listSymbolLayoutResult.GetCauseOfNothing() )); } } float maxSymbolWidth = 0; for (int i = 0; i < childRenderers.Count; i++) { IRenderer symbolRenderer = symbolRenderers[i]; if (symbolRenderer != null) { IRenderer listItemRenderer = childRenderers[i]; if ((ListSymbolPosition)GetListItemOrListProperty(listItemRenderer, this, Property.LIST_SYMBOL_POSITION) != ListSymbolPosition.INSIDE) { maxSymbolWidth = Math.Max(maxSymbolWidth, symbolRenderer.GetOccupiedArea().GetBBox().GetWidth()); } } } float?symbolIndent = this.GetPropertyAsFloat(Property.LIST_SYMBOL_INDENT); listItemNum = 0; foreach (IRenderer childRenderer in childRenderers) { childRenderer.SetParent(this); childRenderer.DeleteOwnProperty(Property.MARGIN_LEFT); UnitValue marginLeftUV = childRenderer.GetProperty(Property.MARGIN_LEFT, UnitValue.CreatePointValue(0f)); if (!marginLeftUV.IsPointValue()) { ILog logger = LogManager.GetLogger(typeof(iText.Layout.Renderer.ListRenderer)); logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.PROPERTY_IN_PERCENTS_NOT_SUPPORTED, Property .MARGIN_LEFT)); } float calculatedMargin = marginLeftUV.GetValue(); if ((ListSymbolPosition)GetListItemOrListProperty(childRenderer, this, Property.LIST_SYMBOL_POSITION) == ListSymbolPosition .DEFAULT) { calculatedMargin += maxSymbolWidth + (float)(symbolIndent != null ? symbolIndent : 0f); } childRenderer.SetProperty(Property.MARGIN_LEFT, UnitValue.CreatePointValue(calculatedMargin)); IRenderer symbolRenderer = symbolRenderers[listItemNum++]; ((ListItemRenderer)childRenderer).AddSymbolRenderer(symbolRenderer, maxSymbolWidth); if (symbolRenderer != null) { LayoutTaggingHelper taggingHelper = this.GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); if (taggingHelper != null) { if (symbolRenderer is LineRenderer) { taggingHelper.SetRoleHint(symbolRenderer.GetChildRenderers()[1], StandardRoles.LBL); } else { taggingHelper.SetRoleHint(symbolRenderer, StandardRoles.LBL); } } } } } return(null); }
public override void Draw(DrawContext drawContext) { if (occupiedArea == null) { ILog logger = LogManager.GetLogger(typeof(iText.Layout.Renderer.ImageRenderer)); logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.OCCUPIED_AREA_HAS_NOT_BEEN_INITIALIZED, "Drawing won't be performed.")); return; } bool isRelativePosition = IsRelativePosition(); if (isRelativePosition) { ApplyRelativePositioningTranslation(false); } bool isTagged = drawContext.IsTaggingEnabled(); LayoutTaggingHelper taggingHelper = null; bool isArtifact = false; TagTreePointer tagPointer = null; if (isTagged) { taggingHelper = this.GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); if (taggingHelper == null) { isArtifact = true; } else { isArtifact = taggingHelper.IsArtifact(this); if (!isArtifact) { tagPointer = taggingHelper.UseAutoTaggingPointerAndRememberItsPosition(this); if (taggingHelper.CreateTag(this, tagPointer)) { tagPointer.GetProperties().AddAttributes(0, AccessibleAttributesApplier.GetLayoutAttributes(this, tagPointer )); } } } } BeginTransformationIfApplied(drawContext.GetCanvas()); float?angle = this.GetPropertyAsFloat(Property.ROTATION_ANGLE); if (angle != null) { drawContext.GetCanvas().SaveState(); ApplyConcatMatrix(drawContext, angle); } base.Draw(drawContext); bool clipImageInAViewOfBorderRadius = ClipBackgroundArea(drawContext, ApplyMargins(GetOccupiedAreaBBox(), false), true); ApplyMargins(occupiedArea.GetBBox(), false); ApplyBorderBox(occupiedArea.GetBBox(), GetBorders(), false); if (fixedYPosition == null) { fixedYPosition = occupiedArea.GetBBox().GetY() + pivotY; } if (fixedXPosition == null) { fixedXPosition = occupiedArea.GetBBox().GetX(); } if (angle != null) { fixedXPosition += rotatedDeltaX; fixedYPosition -= rotatedDeltaY; drawContext.GetCanvas().RestoreState(); } PdfCanvas canvas = drawContext.GetCanvas(); if (isTagged) { if (isArtifact) { canvas.OpenTag(new CanvasArtifact()); } else { canvas.OpenTag(tagPointer.GetTagReference()); } } PdfXObject xObject = ((Image)(GetModelElement())).GetXObject(); BeginElementOpacityApplying(drawContext); canvas.AddXObject(xObject, matrix[0], matrix[1], matrix[2], matrix[3], (float)fixedXPosition + deltaX, (float )fixedYPosition); EndElementOpacityApplying(drawContext); EndTransformationIfApplied(drawContext.GetCanvas()); if (true.Equals(GetPropertyAsBoolean(Property.FLUSH_ON_DRAW))) { xObject.Flush(); } if (isTagged) { canvas.CloseTag(); } if (clipImageInAViewOfBorderRadius) { canvas.RestoreState(); } if (isRelativePosition) { ApplyRelativePositioningTranslation(true); } ApplyBorderBox(occupiedArea.GetBBox(), GetBorders(), true); ApplyMargins(occupiedArea.GetBBox(), true); if (isTagged && !isArtifact) { taggingHelper.FinishTaggingHint(this); taggingHelper.RestoreAutoTaggingPointerPosition(this); } }
public override void Draw(DrawContext drawContext) { if (occupiedArea == null) { ILog logger = LogManager.GetLogger(typeof(iText.Layout.Renderer.ListItemRenderer)); logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.OCCUPIED_AREA_HAS_NOT_BEEN_INITIALIZED, "Drawing won't be performed.")); return; } if (drawContext.IsTaggingEnabled()) { LayoutTaggingHelper taggingHelper = this.GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); if (taggingHelper != null) { if (symbolRenderer != null) { LayoutTaggingHelper.AddTreeHints(taggingHelper, symbolRenderer); } if (taggingHelper.IsArtifact(this)) { taggingHelper.MarkArtifactHint(symbolRenderer); } else { TaggingHintKey hintKey = LayoutTaggingHelper.GetHintKey(this); TaggingHintKey parentHint = taggingHelper.GetAccessibleParentHint(hintKey); if (parentHint != null && !(StandardRoles.LI.Equals(parentHint.GetAccessibleElement().GetAccessibilityProperties ().GetRole()))) { TaggingDummyElement listItemIntermediate = new TaggingDummyElement(StandardRoles.LI); IList <TaggingHintKey> intermediateKid = JavaCollectionsUtil.SingletonList <TaggingHintKey>(LayoutTaggingHelper .GetOrCreateHintKey(listItemIntermediate)); taggingHelper.ReplaceKidHint(hintKey, intermediateKid); if (symbolRenderer != null) { taggingHelper.AddKidsHint(listItemIntermediate, JavaCollectionsUtil.SingletonList <IRenderer>(symbolRenderer )); } taggingHelper.AddKidsHint(listItemIntermediate, JavaCollectionsUtil.SingletonList <IRenderer>(this)); } } } } base.Draw(drawContext); // It will be null in case of overflow (only the "split" part will contain symbol renderer. if (symbolRenderer != null && !symbolAddedInside) { bool isRtl = BaseDirection.RIGHT_TO_LEFT.Equals(this.GetProperty <BaseDirection?>(Property.BASE_DIRECTION)); symbolRenderer.SetParent(this); float x = isRtl ? occupiedArea.GetBBox().GetRight() : occupiedArea.GetBBox().GetLeft(); ListSymbolPosition symbolPosition = (ListSymbolPosition)ListRenderer.GetListItemOrListProperty(this, parent , Property.LIST_SYMBOL_POSITION); if (symbolPosition != ListSymbolPosition.DEFAULT) { float?symbolIndent = this.GetPropertyAsFloat(Property.LIST_SYMBOL_INDENT); if (isRtl) { x += (symbolAreaWidth + (float)(symbolIndent == null ? 0 : symbolIndent)); } else { x -= (symbolAreaWidth + (float)(symbolIndent == null ? 0 : symbolIndent)); } if (symbolPosition == ListSymbolPosition.OUTSIDE) { if (isRtl) { UnitValue marginRightUV = this.GetPropertyAsUnitValue(Property.MARGIN_RIGHT); if (!marginRightUV.IsPointValue()) { ILog logger = LogManager.GetLogger(typeof(iText.Layout.Renderer.ListItemRenderer)); logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.PROPERTY_IN_PERCENTS_NOT_SUPPORTED, Property .MARGIN_RIGHT)); } x -= marginRightUV.GetValue(); } else { UnitValue marginLeftUV = this.GetPropertyAsUnitValue(Property.MARGIN_LEFT); if (!marginLeftUV.IsPointValue()) { ILog logger = LogManager.GetLogger(typeof(iText.Layout.Renderer.ListItemRenderer)); logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.PROPERTY_IN_PERCENTS_NOT_SUPPORTED, Property .MARGIN_LEFT)); } x += marginLeftUV.GetValue(); } } } ApplyMargins(occupiedArea.GetBBox(), false); ApplyBorderBox(occupiedArea.GetBBox(), false); if (childRenderers.Count > 0) { float?yLine = null; for (int i = 0; i < childRenderers.Count; i++) { if (childRenderers[i].GetOccupiedArea().GetBBox().GetHeight() > 0) { yLine = ((AbstractRenderer)childRenderers[i]).GetFirstYLineRecursively(); if (yLine != null) { break; } } } if (yLine != null) { if (symbolRenderer is LineRenderer) { symbolRenderer.Move(0, (float)yLine - ((LineRenderer)symbolRenderer).GetYLine()); } else { symbolRenderer.Move(0, (float)yLine - symbolRenderer.GetOccupiedArea().GetBBox().GetY()); } } else { symbolRenderer.Move(0, occupiedArea.GetBBox().GetY() + occupiedArea.GetBBox().GetHeight() - (symbolRenderer .GetOccupiedArea().GetBBox().GetY() + symbolRenderer.GetOccupiedArea().GetBBox().GetHeight())); } } else { if (symbolRenderer is TextRenderer) { ((TextRenderer)symbolRenderer).MoveYLineTo(occupiedArea.GetBBox().GetY() + occupiedArea.GetBBox().GetHeight () - CalculateAscenderDescender()[0]); } else { symbolRenderer.Move(0, occupiedArea.GetBBox().GetY() + occupiedArea.GetBBox().GetHeight() - symbolRenderer .GetOccupiedArea().GetBBox().GetHeight() - symbolRenderer.GetOccupiedArea().GetBBox().GetY()); } } ApplyBorderBox(occupiedArea.GetBBox(), true); ApplyMargins(occupiedArea.GetBBox(), true); ListSymbolAlignment listSymbolAlignment = (ListSymbolAlignment)parent.GetProperty <ListSymbolAlignment?>(Property .LIST_SYMBOL_ALIGNMENT, isRtl ? ListSymbolAlignment.LEFT : ListSymbolAlignment.RIGHT); float dxPosition = x - symbolRenderer.GetOccupiedArea().GetBBox().GetX(); if (listSymbolAlignment == ListSymbolAlignment.RIGHT) { if (!isRtl) { dxPosition += symbolAreaWidth - symbolRenderer.GetOccupiedArea().GetBBox().GetWidth(); } } else { if (listSymbolAlignment == ListSymbolAlignment.LEFT) { if (isRtl) { dxPosition -= (symbolAreaWidth - symbolRenderer.GetOccupiedArea().GetBBox().GetWidth()); } } } if (symbolRenderer is LineRenderer) { if (isRtl) { symbolRenderer.Move(dxPosition - symbolRenderer.GetOccupiedArea().GetBBox().GetWidth(), 0); } else { symbolRenderer.Move(dxPosition, 0); } } else { symbolRenderer.Move(dxPosition, 0); } if (symbolRenderer.GetOccupiedArea().GetBBox().GetRight() > parent.GetOccupiedArea().GetBBox().GetLeft()) { BeginElementOpacityApplying(drawContext); symbolRenderer.Draw(drawContext); EndElementOpacityApplying(drawContext); } } }
private LayoutTaggingHelper InitTaggingHelperIfNeeded() { return(defaultLayoutTaggingHelper == null && pdfDocument.IsTagged() ? defaultLayoutTaggingHelper = new LayoutTaggingHelper (pdfDocument, immediateFlush) : defaultLayoutTaggingHelper); }
protected void ManipulatePdf(String dest) { PdfDocument pdfDocument = new PdfDocument(new PdfWriter(dest)); pdfDocument.SetTagged(); Document doc = new Document(pdfDocument); Table table = new Table(UnitValue.CreatePercentArray(3)).UseAllAvailableWidth(); // Initialize ID strings beforehand. Every ID should be unique across the document PdfString[] headersId = { // Since '/ID' is a `byte string` according to specification we are not passing // encoding to the constructor of the PdfString new PdfString("header_id_0"), new PdfString("header_id_1"), new PdfString("header_id_2") }; PdfName idTreeName = new PdfName("IDTree"); PdfNameTree idTree = new PdfNameTree(pdfDocument.GetCatalog(), idTreeName); for (int i = 0; i < 3; ++i) { Cell c = new Cell().Add(new Paragraph("Header " + (i + 1))); c.GetAccessibilityProperties().SetRole(StandardRoles.TH); table.AddHeaderCell(c); PdfString headerId = headersId[i]; // Use custom renderer for cell header element in order to add ID to its tag CellRenderer renderer = new StructIdCellRenderer(c, doc, headerId, idTree); c.SetNextRenderer(renderer); } List <TaggingHintKey> colSpanHints = new List <TaggingHintKey>(); for (int i = 0; i < 4; i++) { Cell c; if (i < 3) { c = new Cell().Add(new Paragraph((i + 1).ToString())); } else { // Colspan creation c = new Cell(1, 3).Add(new Paragraph((i + 1).ToString())); } if (i < 3) { // Correct table tagging requires marking which headers correspond to the given cell. // The correspondence is defined by header cells tags IDs. For table cells without // col/row spans it's easy to reference a header: just add proper // PdfStructureAttributes to it. Table cells with col spans are processed below. PdfStructureAttributes tableAttributes = new PdfStructureAttributes("Table"); PdfArray headers; headers = new PdfArray(headersId[i % headersId.Length]); tableAttributes.GetPdfObject().Put(PdfName.Headers, headers); c.GetAccessibilityProperties().AddAttributes(tableAttributes); } else { // When we add PdfStructureAttributes to the element these attributes override any // attributes generated for it automatically. E.g. cells with colspan require properly // generated attributes which describe the colspan (e.g. which columns this cell spans). // So here we will use a different approach: fetch the tag which will be created for // the cell and modify attributes object directly. TaggingHintKey colSpanCellHint = LayoutTaggingHelper.GetOrCreateHintKey(c); colSpanHints.Add(colSpanCellHint); } table.AddCell(c); } doc.Add(table); // After table has been drawn on the page, we can modify the colspan cells tags foreach (TaggingHintKey colSpanHint in colSpanHints) { WaitingTagsManager waitingTagsManager = pdfDocument.GetTagStructureContext().GetWaitingTagsManager(); TagTreePointer p = new TagTreePointer(pdfDocument); // Move tag pointer to the colspan cell using its hint if (!waitingTagsManager.TryMovePointerToWaitingTag(p, colSpanHint)) { // It is not expected to happen ever if immediate-flush is enabled (which is by default), // otherwise this should be done after the flush throw new InvalidOperationException("A work-around does not work. A tag for the cell is " + "not created or cannot be found."); } foreach (PdfStructureAttributes attr in p.GetProperties().GetAttributesList()) { if ("Table".Equals(attr.GetAttributeAsEnum("O"))) { // Specify all the headers for the column spanning (all of 3) PdfArray headers = new PdfArray(headersId); attr.GetPdfObject().Put(PdfName.Headers, headers); break; } } } pdfDocument.GetStructTreeRoot().GetPdfObject().Put(idTreeName, idTree.BuildTree() .MakeIndirect(pdfDocument)); doc.Close(); }