/** * <summary>Shows text.</summary> * <param name="text">Text to show.</param> * <param name="lineAlignment">Line alignment. It can be: * <list type="bullet"> * <item><see cref="LineAlignmentEnum"/></item> * <item><see cref="Length">: arbitrary super-/sub-script, depending on whether the value is * positive or not.</item> * </list> * </param> * <returns>Last shown character index.</returns> */ public int ShowText( string text, object lineAlignment ) { if (currentRow == null || text == null) { return(0); } ContentScanner.GraphicsState state = baseComposer.State; fonts::Font font = state.Font; double fontSize = state.FontSize; double lineHeight = font.GetLineHeight(fontSize); double baseLine = font.GetAscent(fontSize); lineAlignment = ResolveLineAlignment(lineAlignment); TextFitter textFitter = new TextFitter( text, 0, font, fontSize, hyphenation, hyphenationCharacter ); int textLength = text.Length; int index = 0; while (true) { if (currentRow.Width == 0) // Current row has just begun. { // Removing leading space... while (true) { if (index == textLength) // Text end reached. { goto endTextShowing; } else if (text[index] != ' ') // No more leading spaces. { break; } index++; } } if (OperationUtils.Compare(currentRow.Y + lineHeight, frame.Height) == 1) // Text's height exceeds block's remaining vertical space. { // Terminate the current row and exit! EndRow(false); goto endTextShowing; } // Does the text fit? if (textFitter.Fit( index, frame.Width - currentRow.Width, // Remaining row width. currentRow.SpaceCount == 0 )) { // Get the fitting text! string textChunk = textFitter.FittedText; double textChunkWidth = textFitter.FittedWidth; PointF textChunkLocation = new PointF( (float)currentRow.Width, (float)currentRow.Y ); // Insert the fitting text! RowObject obj; { obj = new RowObject( RowObject.TypeEnum.Text, baseComposer.BeginLocalState(), // Opens the row object's local state. lineHeight, textChunkWidth, CountOccurrence(' ', textChunk), lineAlignment, baseLine ); baseComposer.ShowText(textChunk, textChunkLocation); baseComposer.End(); // Closes the row object's local state. } AddRowObject(obj, lineAlignment); index = textFitter.EndIndex; } // Evaluating trailing text... while (true) { if (index == textLength) // Text end reached. { goto endTextShowing; } switch (text[index]) { case '\r': break; case '\n': // New paragraph! index++; ShowBreak(); goto endTrailParsing; default: // New row (within the same paragraph)! EndRow(false); BeginRow(); goto endTrailParsing; } index++; } endTrailParsing :; } endTextShowing :; if (index >= 0 && lineAlignment.Equals(LineAlignmentEnum.BaseLine)) { lastFontSize = fontSize; } return(index); }
public override ContentObject ToInlineObject(PrimitiveComposer composer) { ContentObject barcodeObject = composer.BeginLocalState(); { fonts::Font font = fonts::PdfType1Font.Load(composer.Scanner.Contents.Document, fonts::PdfType1Font.FamilyEnum.Helvetica, false, false); double fontSize = (DigitGlyphWidth / font.GetWidth(code.Substring(0, 1), 1)); // 1. Bars. { double elementX = DigitWidth; int[] elementWidths = GetElementWidths(); double guardBarIndentY = DigitHeight / 2; bool isBar = true; for (int elementIndex = 0; elementIndex < elementWidths.Length; elementIndex++) { double elementWidth = elementWidths[elementIndex]; // Dark element? /* * NOTE: EAN symbol elements alternate bars to spaces. */ if (isBar) { composer.DrawRectangle( SKRect.Create( (float)elementX, 0, (float)elementWidth, (float)(BarHeight + ( // Guard bar? Array.BinarySearch <int>(GuardBarIndexes, elementIndex) >= 0 ? guardBarIndentY // Guard bar. : 0 // Symbol character. )) ) ); } elementX += elementWidth; isBar = !isBar; } composer.Fill(); } // 2. Digits. { composer.SetFont(font, fontSize); double digitY = BarHeight + (DigitHeight - (font.GetAscent(fontSize))) / 2; // Showing the digits... for (int digitIndex = 0; digitIndex < 13; digitIndex++) { string digit = code.Substring(digitIndex, 1); double pX = DigitGlyphXs[digitIndex] // Digit position. - font.GetWidth(digit, fontSize) / 2; // Centering. // Show the current digit! composer.ShowText( digit, new SKPoint((float)pX, (float)digitY) ); } } composer.End(); } return(barcodeObject); }
public FormXObject Build( ) { bool isRound = type == TypeEnum.Round; bool isStriped = type == TypeEnum.Striped; double textScale = .5; double borderWidth = this.borderWidth.GetValue(width); double doubleBorderGap = borderDoubled ? borderWidth : 0; double fontSize = 10; fontSize *= ((width - (isStriped ? 2 : doubleBorderGap * 2 + (borderWidth * (borderDoubled ? 1.5 : 1) * 2) + width * (isRound ? .15 : .05))) / textScale) / font.GetWidth(text, fontSize); float height = (float)(isRound ? width : (font.GetAscent(fontSize) * 1.2 + doubleBorderGap * 2 + (borderWidth * (borderDoubled ? 1.5 : 1) * 2))); SizeF size = new SizeF(width, height); FormXObject appearance = new FormXObject(document, size); { PrimitiveComposer composer = new PrimitiveComposer(appearance); if (color != null) { composer.SetStrokeColor(color); composer.SetFillColor(color); } composer.SetTextScale(textScale); composer.SetFont(font, fontSize); composer.ShowText(text, new PointF(size.Width / 2, (float)(size.Height / 2 - font.GetDescent(fontSize) * .4)), XAlignmentEnum.Center, YAlignmentEnum.Middle, 0); double borderRadius = isRound ? 0 : this.borderRadius.GetValue((size.Width + size.Height) / 2); RectangleF prevBorderBox = appearance.Box; for (int borderStep = 0, borderStepLimit = (borderDoubled ? 2 : 1); borderStep < borderStepLimit; borderStep++) { if (borderStep == 0) { composer.SetLineWidth(borderWidth); } else { composer.SetLineWidth(composer.State.LineWidth / 2); } float lineWidth = (float)(borderStep > 0 ? composer.State.LineWidth / 2 : borderWidth); float marginY = (float)(lineWidth / 2 + (borderStep > 0 ? composer.State.LineWidth + doubleBorderGap : 0)); float marginX = isStriped ? 0 : marginY; RectangleF borderBox = new RectangleF(prevBorderBox.X + marginX, prevBorderBox.Y + marginY, prevBorderBox.Width - marginX * 2, prevBorderBox.Height - marginY * 2); if (isRound) { composer.DrawEllipse(borderBox); } else { if (isStriped) { composer.DrawLine(new PointF(borderBox.Left, borderBox.Top), new PointF(borderBox.Right, borderBox.Top)); composer.DrawLine(new PointF(borderBox.Left, borderBox.Bottom), new PointF(borderBox.Right, borderBox.Bottom)); } else { composer.DrawRectangle(borderBox, borderRadius * (1 - .5 * borderStep)); } } composer.Stroke(); prevBorderBox = borderBox; } composer.Flush(); } return(appearance); }