TextRendering.cs
- //
- // This code is part of Document Solutions for Imaging demos.
- // Copyright (c) MESCIUS inc. All rights reserved.
- //
- using System;
- using System.IO;
- using System.Drawing;
- using GrapeCity.Documents.Imaging;
- using GrapeCity.Documents.Text;
- using GrapeCity.Documents.Drawing;
- using GCTEXT = GrapeCity.Documents.Text;
- using GCDRAW = GrapeCity.Documents.Drawing;
-
- namespace DsImagingWeb.Demos
- {
- // Demonstrates the basics of rendering text in DsImaging.
- // The two main approaches are:
- // - using the MeasureString/DrawString pair, or
- // - using the TextLayout directly.
- // While the first approach may be easier in simple cases,
- // the second approach (using TextLayout) is much more powerful
- // and generally speaking yields better performance.
- // Please read the comments in code below for more details.
- public class TextRendering
- {
- public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
- {
- var bmp = new GcBitmap(pixelSize.Width, pixelSize.Height, true, dpi, dpi);
- var Inch = dpi;
- const float fontSize = 14;
- using (var g = bmp.CreateGraphics(Color.White))
- {
- // TextFormat class is used throughout all DsImaging text rendering to specify
- // font and other character formatting:
- var tf = new TextFormat()
- {
- Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf")),
- FontSize = fontSize
- };
-
- // 1.
- // The easiest way to render a short string on a page at an arbitrary location,
- // when you are 100% sure that the string will fit in the available space,
- // is to use the GcGraphics.DrawString() overload accepting just the point
- // at which to draw the string:
- g.DrawString(
- "1. Test string. Please read the extensive comments in this sample's code.\r\n" +
- "(Note that line breaks are allowed even in the simplest DrawString overload.)",
- tf, new PointF(Inch, Inch));
-
- // 2.
- // Another overload taking a rectangle instead, plus alignment and wrapping
- // options, is also available and provides a bit more flexibility:
- g.DrawString(
- "2. A longer test string which will probably need more than the allocated " +
- "4 inches so quite possibly will wrap to show that DrawString can do that.",
- tf,
- new RectangleF(Inch, Inch * 2, Inch * 4, Inch), // the layout rectangle
- // The rest 3 args are optional, passing defaults here for illustration:
- TextAlignment.Leading, // leading (left for LTR languages) text align
- ParagraphAlignment.Near, // near (top for top-to-bottom flow) para align
- true); // word wrap
-
- // 3.
- // Complementary to DrawString, a MeasureString() method is available
- // (with several different overloads), and can be used in pair with
- // DrawString when more control over text layout is needed:
- const string tstr3 = "3. Test string to demo MeasureString() used with DrawString().";
-
- SizeF layoutSize = new SizeF(Inch * 3, Inch * 0.8f); // available size
- SizeF s = g.MeasureString(tstr3, tf, layoutSize, out int fitCharCount);
- // Show the passed in size in red, the measured size in blue,
- // and draw the string within the returned size as bounds:
- PointF pt = new PointF(Inch, Inch * 3);
- g.DrawRectangle(new RectangleF(pt, layoutSize), Color.Red);
- g.DrawRectangle(new RectangleF(pt, s), Color.Blue);
- g.DrawString(tstr3, tf, new RectangleF(pt, s));
-
- // 4.
- // A much more powerful and with better performance, way to render text
- // is to use TextLayout. (TextLayout is used anyway by DrawString/MeasureString,
- // so when you use TextLayout directly, you basically cut the work in half.)
- // A TextLayout instance represents one or more paragraphs of text, with
- // the same paragraph formatting (character formats may be different,
- // see {MultiFormattedText}).
- var tl = g.CreateTextLayout();
- // To add text, use Append() or AppendLine() methods:
- tl.Append("4. First test string added to TextLayout. ", tf);
- tl.Append("Second test string added to TextLayout, continuing the same paragraph. ", tf);
- tl.AppendLine(); // Add a line break, effectively starting a new paragraph
- tl.Append("Third test string added to TextLayout, a new paragraph. ", tf);
- tl.Append("Fourth test string, with a different char formatting. ",
- new TextFormat(tf)
- {
- Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "timesbi.ttf")),
- FontSize = fontSize,
- FontBold = true,
- FontItalic = true,
- ForeColor = Color.DarkSeaGreen,
- });
- // Text can be added to TextLayout without explicit TextFormat:
- tl.Append("Fifth test string, using the TextLayout's default format.");
- // ...but in that case at least the Font must be specified on the
- // TextLayout's DefaultFormat, otherwise PerformLayout (below) will fail:
- tl.DefaultFormat.Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "timesi.ttf"));
- tl.DefaultFormat.FontSize = fontSize;
-
- // Specify the layout, such as max available size etc.
- // Here we only provide the max width, but many more parameters can be set:
- tl.MaxWidth = g.Width - Inch * 2;
- // Paragraph formatting can also be set, here we set first line offset,
- // spacing between paragraphs and line spacing:
- tl.FirstLineIndent = Inch * 0.5f;
- tl.ParagraphSpacing = Inch * 0.05f;
- tl.LineSpacingScaleFactor = 0.8f;
-
- // When all text has been added, and layout options specified,
- // the TextLayout needs to calculate the glyphs needed to render
- // the text, and perform the layout. This can be done with a
- // single call:
- tl.PerformLayout(true);
-
- // Now we can draw it on the page:
- pt = new PointF(Inch, Inch * 4);
- g.DrawTextLayout(tl, pt);
- // TextLayout provides info about the text including the measured bounds
- // and much more. Here we draw the bounding box in orange red:
- g.DrawRectangle(new RectangleF(pt, tl.ContentRectangle.Size), Color.OrangeRed);
-
- // 5.
- // TextLayout can be re-used to draw different paragraph(s), this can be useful
- // when you need to render a different text with the same paragraph formatting.
- // The Clear() call removes the text but preserves paragraph formatting:
- tl.Clear();
- tl.Append("5. This is text rendered re-using the same TextLayout. ");
- tl.Append("More text added to TextLayout being re-used, continuing the same paragraph. ", tf);
- tl.Append("And finally, some more text added.", tf);
- // The necessary call to calculate the glyphs and perform layout:
- tl.PerformLayout(true);
- // Render the text:
- g.DrawTextLayout(tl, new PointF(Inch, Inch * 5));
- // Draw border around the whole image:
- g.DrawRectangle(new RectangleF(0, 0, bmp.Width, bmp.Height), Color.DarkSlateBlue, 4);
- }
- // Done:
- return bmp;
- }
- }
- }
-