/// <summary> /// Method that will set properties to be inherited by this branch renderer's /// children and will iterate over all children in order to draw them. /// </summary> /// <param name="context"> /// the object that knows the place to draw this element and /// maintains its state /// </param> protected internal override void DoDraw(SvgDrawContext context) { if (GetChildren().Count > 0) { // if branch has no children, don't do anything PdfCanvas currentCanvas = context.GetCurrentCanvas(); if (performRootTransformations) { currentCanvas.BeginText(); //Current transformation matrix results in the character glyphs being mirrored, correct with inverse tf AffineTransform rootTf; if (this.ContainsAbsolutePositionChange()) { rootTf = GetTextTransform(this.GetAbsolutePositionChanges(), context); } else { rootTf = new AffineTransform(TEXTFLIP); } currentCanvas.SetTextMatrix(rootTf); //Reset context of text move context.ResetTextMove(); //Apply relative move if (this.ContainsRelativeMove()) { float[] rootMove = this.GetRelativeTranslation(); context.AddTextMove(rootMove[0], -rootMove[1]); } //-y to account for the text-matrix transform we do in the text root to account for the coordinates //handle white-spaces if (!whiteSpaceProcessed) { SvgTextUtil.ProcessWhiteSpace(this, true); } } ApplyTextRenderingMode(currentCanvas); if (this.attributesAndStyles != null) { ResolveFontSize(); ResolveFont(context); currentCanvas.SetFontAndSize(font, fontSize); foreach (ISvgTextNodeRenderer c in children) { float childLength = c.GetTextContentLength(fontSize, font); if (c.ContainsAbsolutePositionChange()) { //TODO: DEVSIX-2507 support rotate and other attributes float[][] absolutePositions = c.GetAbsolutePositionChanges(); AffineTransform newTransform = GetTextTransform(absolutePositions, context); //overwrite the last transformation stored in the context context.SetLastTextTransform(newTransform); //Apply transformation currentCanvas.SetTextMatrix(newTransform); //Absolute position changes requires resetting the current text move in the context context.ResetTextMove(); } //Handle Text-Anchor declarations float textAnchorCorrection = GetTextAnchorAlignmentCorrection(childLength); if (!CssUtils.CompareFloats(0f, textAnchorCorrection)) { context.AddTextMove(textAnchorCorrection, 0); } //Move needs to happen before the saving of the state in order for it to cascade beyond if (c.ContainsRelativeMove()) { float[] childMove = c.GetRelativeTranslation(); context.AddTextMove(childMove[0], -childMove[1]); } //-y to account for the text-matrix transform we do in the text root to account for the coordinates currentCanvas.SaveState(); c.Draw(context); context.AddTextMove(childLength, 0); currentCanvas.RestoreState(); //Restore transformation matrix if (!context.GetLastTextTransform().IsIdentity()) { currentCanvas.SetTextMatrix(context.GetLastTextTransform()); } } if (performRootTransformations) { currentCanvas.EndText(); } } } }