LayoutDemos.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 System.Collections.Generic;
- using System.Linq;
- using System.Numerics;
- using GrapeCity.Documents.Drawing;
- using GrapeCity.Documents.Text;
- using GrapeCity.Documents.Imaging;
- using GrapeCity.Documents.Layout;
- using GrapeCity.Documents.Layout.Composition;
- using GCTEXT = GrapeCity.Documents.Text;
- using GCDRAW = GrapeCity.Documents.Drawing;
-
- namespace DsImagingWeb.Demos
- {
- // This integrated demo shows how to use helper classes
- // in the GrapeCity.Documents.Layout.Composition namespace
- // to create complex and flexible constraint-based layouts
- // with custom z-order and clipping.
- public class LayoutDemos
- {
- static readonly Color
- PageColor = Color.FromArgb(39, 41, 43),
- BoxColor = Color.FromArgb(230, 230, 230),
- CodeColor = Color.FromArgb(132, 211, 232),
- RectColor = Color.FromArgb(64, 126, 148),
- DescColor = Color.White;
- delegate void DrawLayoutSample(GcGraphics g, Size pageSize);
- static readonly Dictionary<string, DrawLayoutSample> c_samples = new Dictionary<string, DrawLayoutSample>()
- {
- { "DrawSample1", DrawSample1 },
- { "DrawSample2", DrawSample2 },
- { "DrawSample3", DrawSample3 },
- { "DrawSample4", DrawSample4 },
- { "DrawSample5", DrawSample5 },
- { "DrawSample6", DrawSample6 },
- { "DrawSample7", DrawSample7 },
- { "DrawSample8", DrawSample8 },
- };
-
- public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
- {
- if (!c_samples.TryGetValue(sampleParams[3], out DrawLayoutSample drawSample))
- throw new Exception($"Unknown parameterized sample: {sampleParams[3]}");
-
- var bmp = new GcBitmap(pixelSize.Width, pixelSize.Height, opaque, dpi, dpi);
- using var g = bmp.CreateGraphics(PageColor);
- drawSample(g, pixelSize);
-
- return bmp;
- }
-
- public static List<string[]> GetSampleParamsList()
- {
- return new List<string[]>()
- {
- // Strings are name, description, info. Rest are arbitrary strings:
- new string[] { "Figures 1-4", "Figures 1-4: horizontal, vertical, alignment constraint and guidelines",
- null,
- "DrawSample1" },
- new string[] { "Figure 5", "Figure 5: Barrier constraint anchored to two visuals",
- null,
- "DrawSample2" },
- new string[] { "Figure 6", "Figure 6: Horizontal chain with weighted widths",
- null,
- "DrawSample3" },
- new string[] { "Figure 7", "Figure 7: Horizontal chain with evenly distributed rectangles and margins",
- null,
- "DrawSample4" },
- new string[] { "Figure 8", "Figure 8: Horizontal chain with evenly distributed rectangles, no margins",
- null,
- "DrawSample5" },
- new string[] { "Figure 9", "Figure 9: Weighted horizontal chain without margins",
- null,
- "DrawSample6" },
- new string[] { "Figure 10", "Figure 10: Horizontal chain with weighted margins and packed rectangles",
- null,
- "DrawSample7" },
- new string[] { "Text Flow", "Text flow in and around non-rectangular contours",
- null,
- "DrawSample8" },
- };
- }
-
- // Figures 1-4: horizontal, vertical, alignment constraint and guidelines.
- static void DrawSample1(GcGraphics g, Size _)
- {
- g.Transform = Matrix3x2.CreateScale(1.4f);
-
- // The Surface object can layout Visuals and draw them on the graphics.
- var surf = new Surface();
-
- // view1
-
- // The View object represents a group of Visuals with a transformation matrix.
- var view1 = surf.CreateView(250, 150).Translate(50, 40);
-
- // Visual is an element with the associated LayoutRect used for its
- // positioning/ and a delegate that draws its content on the graphics.
- var v = view1.CreateVisual(DrawView);
- v.Tag = new FigureCaption(1, "A horizontal constraint to the parent:",
- "rA.SetLeft(null, AnchorParam.Left, 90);");
- v.LayoutRect.AnchorExact(null);
-
- v = view1.CreateVisual(DrawRect);
- var rA = v.LayoutRect;
- rA.SetLeft(null, AnchorParam.Left, 90);
- rA.SetWidth(70);
- rA.SetHeight(40);
- rA.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "A";
-
- var r = view1.CreateVisual(DrawLineWithLeftArrow).LayoutRect;
- r.AnchorTopBottom(rA, 0, 0);
- r.SetLeft(null, AnchorParam.Left);
- r.SetRight(rA, AnchorParam.Left);
-
- // view2
- var view2 = surf.CreateView(250, 150).Translate(350, 40);
- v = view2.CreateVisual(DrawView);
- v.Tag = new FigureCaption(2, "An offset horizontal alignment constraint:",
- "rB.SetLeft(rA, AnchorParam.Left, 40);");
- v.LayoutRect.AnchorExact(null);
-
- v = view2.CreateVisual(DrawRect);
- rA = v.LayoutRect;
- rA.AnchorTopLeft(null, 15, 70, 110, 60);
- v.Tag = "A";
-
- v = view2.CreateVisual(DrawRect);
- var rB = v.LayoutRect;
- rB.SetLeft(rA, AnchorParam.Left, 40);
- rB.SetWidth(60);
- rB.SetHeight(35);
- rB.SetTop(rA, AnchorParam.Bottom, 20);
- v.Tag = "B";
-
- r = view2.CreateVisual(DrawVertLineWithLeftArrow).LayoutRect;
- r.SetTop(rA, AnchorParam.VerticalCenter);
- r.SetBottom(rB, AnchorParam.VerticalCenter);
- r.SetLeft(rA, AnchorParam.Left);
- r.SetRight(rB, AnchorParam.Left);
-
- // view3
- var view3 = surf.CreateView(250, 150).Translate(50, 260);
- v = view3.CreateVisual(DrawView);
- v.Tag = new FigureCaption(3, "Horizontal and vertical constraints:",
- "rB.SetLeft(rA, AnchorParam.Right, 50);\n" +
- "rC.SetTop(rA, AnchorParam.Bottom, 40);");
- v.LayoutRect.AnchorExact(null);
-
- v = view3.CreateVisual(DrawRect);
- rA = v.LayoutRect;
- rA.AnchorTopLeft(null, 15, 30, 70, 40);
- v.Tag = "A";
-
- v = view3.CreateVisual(DrawRect);
- rB = v.LayoutRect;
- rB.SetLeft(rA, AnchorParam.Right, 50);
- rB.SetWidth(70);
- rB.SetHeight(40);
- rB.SetTop(rA, AnchorParam.Top);
- v.Tag = "B";
-
- v = view3.CreateVisual(DrawRect);
- var rC = v.LayoutRect;
- rC.SetTop(rA, AnchorParam.Bottom, 40);
- rC.SetWidth(70);
- rC.SetHeight(40);
- rC.SetLeft(rA, AnchorParam.Left);
- v.Tag = "C";
-
- r = view3.CreateVisual(DrawLineWithLeftArrow).LayoutRect;
- r.AnchorTopBottom(rA, 0, 0);
- r.SetLeft(rA, AnchorParam.Right);
- r.SetRight(rB, AnchorParam.Left);
-
- r = view3.CreateVisual(DrawLineWithUpArrow).LayoutRect;
- r.AnchorLeftRight(rA, 0, 0);
- r.SetTop(rA, AnchorParam.Bottom);
- r.SetBottom(rC, AnchorParam.Top);
-
- // view4
- var view4 = surf.CreateView(250, 150).Translate(350, 260);
- var layoutView = view4.LayoutView;
- v = view4.CreateVisual(DrawView);
- v.Tag = new FigureCaption(4, "A rectangle constrained to a guideline:",
- "var anchorPoint = layoutView.CreatePoint(0.25f, 0);\n" +
- "rA.SetLeft(anchorPoint, 60);");
- v.LayoutRect.AnchorExact(null);
-
- // An anchor point can work as the guideline on the X or the Y axes.
- var anchorPoint = layoutView.CreatePoint(0.25f, 0);
-
- v = view4.CreateVisual(DrawVertGuideline);
- var rG = v.LayoutRect;
- rG.SetLeft(anchorPoint);
- rG.AnchorVerticalLine(null);
- v.Tag = "25 %";
-
- v = view4.CreateVisual(DrawRect);
- rA = v.LayoutRect;
- rA.SetLeft(anchorPoint, 60);
- rA.SetWidth(70);
- rA.SetHeight(40);
- rA.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "A";
-
- r = view4.CreateVisual(DrawLineWithLeftArrow).LayoutRect;
- r.AnchorTopBottom(rA, 0, 0);
- r.SetLeft(rG, AnchorParam.Left);
- r.SetRight(rA, AnchorParam.Left);
-
- surf.Render(g);
- }
-
- // Figure 5: Barrier constraint anchored to two visuals.
- static void DrawSample2(GcGraphics g, Size _)
- {
- g.Transform = Matrix3x2.CreateScale(2);
-
- var surf = new Surface();
-
- // View1
- var view1 = surf.CreateView(350, 160).Translate(30, 30);
- view1.CreateVisual(DrawView).LayoutRect.AnchorExact(null);
-
- var v = view1.CreateVisual(DrawRect);
- var rA = v.LayoutRect;
- rA.AnchorTopLeft(null, 30, 50, 60, 40);
- v.Tag = "A";
-
- v = view1.CreateVisual(DrawRect);
- var rB = v.LayoutRect;
- rB.AnchorTopLeft(null, 90, 50, 90, 40);
- v.Tag = "B";
-
- v = view1.CreateVisual(DrawVertGuideline);
- var rG = v.LayoutRect;
-
- // Adding multiple MinLeft constraints to the same rectangle creates
- // a barrier to be used as the base for other rectangles.
- rG.AppendMinLeft(rA, AnchorParam.Right);
- rG.AppendMinLeft(rB, AnchorParam.Right);
-
- rG.AnchorVerticalLine(null);
-
- v = view1.CreateVisual(DrawRect);
- var rC = v.LayoutRect;
- rC.AppendMinLeft(rA, AnchorParam.Right, 50);
- rC.AppendMinLeft(rB, AnchorParam.Right, 50);
- rC.SetWidth(70);
- rC.SetHeight(40);
- rC.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "C";
-
- var r = view1.CreateVisual(DrawLineWithLeftArrow).LayoutRect;
- r.AnchorTopBottom(rC, 0, 0);
- r.SetLeft(rG, AnchorParam.Right);
- r.SetRight(rC, AnchorParam.Left);
-
- // View2
- var view2 = surf.CreateView(350, 160).Translate(30, 210);
- v = view2.CreateVisual(DrawView);
- v.Tag = new FigureCaption(5, "C is constrained to a barrier, which moves based on\n" +
- "the position and size of both A and B:",
- "rC.AppendMinLeft(rA, AnchorParam.Right, 50);\n" +
- "rC.AppendMinLeft(rB, AnchorParam.Right, 50);");
- v.LayoutRect.AnchorExact(null);
-
- v = view2.CreateVisual(DrawRect);
- rA = v.LayoutRect;
- rA.AnchorTopLeft(null, 30, 50, 130, 40);
- v.Tag = "A";
-
- v = view2.CreateVisual(DrawRect);
- rB = v.LayoutRect;
- rB.AnchorTopLeft(null, 90, 50, 90, 40);
- v.Tag = "B";
-
- v = view2.CreateVisual(DrawVertGuideline);
- rG = v.LayoutRect;
- rG.AppendMinLeft(rA, AnchorParam.Right);
- rG.AppendMinLeft(rB, AnchorParam.Right);
- rG.AnchorVerticalLine(null);
-
- v = view2.CreateVisual(DrawRect);
- rC = v.LayoutRect;
- rC.AppendMinLeft(rA, AnchorParam.Right, 50);
- rC.AppendMinLeft(rB, AnchorParam.Right, 50);
- rC.SetWidth(70);
- rC.SetHeight(40);
- rC.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "C";
-
- r = view2.CreateVisual(DrawLineWithLeftArrow).LayoutRect;
- r.AnchorTopBottom(rC, 0, 0);
- r.SetLeft(rG, AnchorParam.Right);
- r.SetRight(rC, AnchorParam.Left);
-
- surf.Render(g);
- }
-
- // Figure 6: Horizontal chain with weighted widths.
- static void DrawSample3(GcGraphics g, Size _)
- {
- g.Transform = Matrix3x2.CreateScale(2);
-
- var surf = new Surface();
-
- var view = surf.CreateView(350, 120).Translate(30, 40);
- var v = view.CreateVisual(DrawView);
- v.Tag = new FigureCaption(6, "A horizontal chain with two rectangles having weighted\nwidths and a fixed space between them:",
- "rA.SetLeft(null, AnchorParam.Left, 60);\n" +
- "rA.SetStarWidth(1);\n" +
- "rAB.SetLeftAndOpposite(rA, AnchorParam.Right);\n" +
- "rAB.SetWidth(50);\n" +
- "rB.SetLeftAndOpposite(rAB, AnchorParam.Right);\n" +
- "rB.SetStarWidth(2);\n" +
- "rB.SetRight(null, AnchorParam.Right, -60);");
- v.LayoutRect.AnchorExact(null);
-
- v = view.CreateVisual(DrawRect);
- var rA = v.LayoutRect;
- rA.SetHeight(40);
- rA.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "A";
-
- v = view.CreateVisual(DrawRect);
- var rB = v.LayoutRect;
- rB.SetHeight(40);
- rB.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "B";
-
- var rAB = view.CreateVisual(DrawLeftRightLines).LayoutRect;
- rAB.AnchorTopBottom(rA, 0, 0);
-
- // The SetStarWidth method sets the weight of width of that specific
- // rectangle relative to the width of other rectangles that belong
- // to the same chain and have the "star" width.
-
- // SetLeftAndOpposite method makes a chain of rectangles that affect
- // the position of each other in both directions.
-
- rA.SetLeft(null, AnchorParam.Left, 60);
- rA.SetStarWidth(1);
- rAB.SetLeftAndOpposite(rA, AnchorParam.Right);
- rAB.SetWidth(50);
- rB.SetLeftAndOpposite(rAB, AnchorParam.Right);
- rB.SetStarWidth(2);
- rB.SetRight(null, AnchorParam.Right, -60);
-
- var r = view.CreateVisual(DrawLineWithLeftArrow).LayoutRect;
- r.AnchorTopBottom(rA, 0, 0);
- r.SetLeft(null, AnchorParam.Left);
- r.SetRight(rA, AnchorParam.Left);
-
- r = view.CreateVisual(DrawLineWithRightArrow).LayoutRect;
- r.AnchorTopBottom(rB, 0, 0);
- r.SetLeft(rB, AnchorParam.Right);
- r.SetRight(null, AnchorParam.Right);
-
- surf.Render(g);
- }
-
- // Figure 7: Horizontal chain with evenly distributed rectangles and margins.
- static void DrawSample4(GcGraphics g, Size _)
- {
- g.Transform = Matrix3x2.CreateScale(1.8f);
-
- var surf = new Surface();
-
- var view = surf.CreateView(430, 120).Translate(30, 40);
- var v = view.CreateVisual(DrawView);
- v.Tag = new FigureCaption(7, "A horizontal chain with three evenly distributed rectangles\nafter margins are accounted for:",
- "rA.SetLeft(null, AnchorParam.Left, 60);\n" +
- "rA.SetWidth(70);\n" +
- "rAB.SetLeftAndOpposite(rA, AnchorParam.Right);\n" +
- "rAB.SetStarWidth(1);\n" +
- "rAB.SetRightAndOpposite(rB, AnchorParam.Left);\n" +
- "rB.SetWidth(70);\n" +
- "rBC.SetLeftAndOpposite(rB, AnchorParam.Right);\n" +
- "rBC.SetStarWidth(1);\n" +
- "rC.SetLeftAndOpposite(rBC, AnchorParam.Right);\n" +
- "rC.SetWidth(70);\n" +
- "rC.SetRight(null, AnchorParam.Right, -60);");
- v.LayoutRect.AnchorExact(null);
-
- v = view.CreateVisual(DrawRect);
- var rA = v.LayoutRect;
- rA.SetHeight(40);
- rA.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "A";
-
- v = view.CreateVisual(DrawRect);
- var rB = v.LayoutRect;
- rB.SetHeight(40);
- rB.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "B";
-
- v = view.CreateVisual(DrawRect);
- var rC = v.LayoutRect;
- rC.SetHeight(40);
- rC.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "C";
-
- var rAB = view.CreateVisual(DrawLeftRightLines).LayoutRect;
- rAB.AnchorTopBottom(rA, 0, 0);
-
- var rBC = view.CreateVisual(DrawLeftRightLines).LayoutRect;
- rBC.AnchorTopBottom(rB, 0, 0);
-
- rA.SetLeft(null, AnchorParam.Left, 60);
- rA.SetWidth(70);
- rAB.SetLeftAndOpposite(rA, AnchorParam.Right);
- rAB.SetStarWidth(1);
- rAB.SetRightAndOpposite(rB, AnchorParam.Left);
- rB.SetWidth(70);
- rBC.SetLeftAndOpposite(rB, AnchorParam.Right);
- rBC.SetStarWidth(1);
- rC.SetLeftAndOpposite(rBC, AnchorParam.Right);
- rC.SetWidth(70);
- rC.SetRight(null, AnchorParam.Right, -60);
-
- var r = view.CreateVisual(DrawLineWithLeftArrow).LayoutRect;
- r.AnchorTopBottom(rA, 0, 0);
- r.SetLeft(null, AnchorParam.Left);
- r.SetRight(rA, AnchorParam.Left);
-
- r = view.CreateVisual(DrawLineWithRightArrow).LayoutRect;
- r.AnchorTopBottom(rC, 0, 0);
- r.SetLeft(rC, AnchorParam.Right);
- r.SetRight(null, AnchorParam.Right);
-
- surf.Render(g);
- }
-
- // Figure 8: Horizontal chain with evenly distributed rectangles, no margins.
- static void DrawSample5(GcGraphics g, Size _)
- {
- g.Transform = Matrix3x2.CreateScale(2);
-
- var surf = new Surface();
-
- var view = surf.CreateView(340, 120).Translate(30, 40);
- var v = view.CreateVisual(DrawView);
- v.Tag = new FigureCaption(8, "Same as Figure 7, without accounting for the margins:",
- "rA.SetLeft(null, AnchorParam.Left);\n" +
- "rA.SetWidth(70);\n" +
- "rA.SetRightAndOpposite(rAB, AnchorParam.Left);\n" +
- "rAB.SetStarWidth(1);\n" +
- "rB.SetLeftAndOpposite(rAB, AnchorParam.Right);\n" +
- "rB.SetWidth(70);\n" +
- "rB.SetRightAndOpposite(rBC, AnchorParam.Left);\n" +
- "rBC.SetStarWidth(1);\n" +
- "rC.SetLeftAndOpposite(rBC, AnchorParam.Right);\n" +
- "rC.SetWidth(70);\n" +
- "rC.SetRight(null, AnchorParam.Right);");
- v.LayoutRect.AnchorExact(null);
-
- v = view.CreateVisual(DrawRect);
- var rA = v.LayoutRect;
- rA.SetHeight(40);
- rA.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "A";
-
- v = view.CreateVisual(DrawRect);
- var rB = v.LayoutRect;
- rB.SetHeight(40);
- rB.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "B";
-
- v = view.CreateVisual(DrawRect);
- var rC = v.LayoutRect;
- rC.SetHeight(40);
- rC.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "C";
-
- var rAB = view.CreateVisual(DrawLeftRightLines).LayoutRect;
- rAB.AnchorTopBottom(rA, 0, 0);
-
- var rBC = view.CreateVisual(DrawLeftRightLines).LayoutRect;
- rBC.AnchorTopBottom(rB, 0, 0);
-
- rA.SetLeft(null, AnchorParam.Left);
- rA.SetWidth(70);
- rA.SetRightAndOpposite(rAB, AnchorParam.Left);
- rAB.SetStarWidth(1);
- rB.SetLeftAndOpposite(rAB, AnchorParam.Right);
- rB.SetWidth(70);
- rB.SetRightAndOpposite(rBC, AnchorParam.Left);
- rBC.SetStarWidth(1);
- rC.SetLeftAndOpposite(rBC, AnchorParam.Right);
- rC.SetWidth(70);
- rC.SetRight(null, AnchorParam.Right);
-
- surf.Render(g);
- }
-
- // Figure 9: Weighted horizontal chain without margins.
- static void DrawSample6(GcGraphics g, Size _)
- {
- g.Transform = Matrix3x2.CreateScale(2);
-
- var surf = new Surface();
-
- var view = surf.CreateView(340, 120).Translate(30, 40);
- var v = view.CreateVisual(DrawView);
- v.Tag = new FigureCaption(9, "A weighted horizontal chain without margins:",
- "rA.SetLeft(null, AnchorParam.Left);\n" +
- "rA.SetStarWidth(1);\n" +
- "rA.SetRightAndOpposite(rB, AnchorParam.Left);\n" +
- "rB.SetStarWidth(2);\n" +
- "rB.SetRightAndOpposite(rC, AnchorParam.Left);\n" +
- "rC.SetStarWidth(2);\n" +
- "rC.SetRight(null, AnchorParam.Right);");
- v.LayoutRect.AnchorExact(null);
-
- v = view.CreateVisual(DrawRect);
- var rA = v.LayoutRect;
- rA.SetHeight(40);
- rA.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "A";
-
- v = view.CreateVisual(DrawRect);
- var rB = v.LayoutRect;
- rB.SetHeight(40);
- rB.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "B";
-
- v = view.CreateVisual(DrawRect);
- var rC = v.LayoutRect;
- rC.SetHeight(40);
- rC.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "C";
-
- rA.SetLeft(null, AnchorParam.Left);
- rA.SetStarWidth(1);
- rA.SetRightAndOpposite(rB, AnchorParam.Left);
- rB.SetStarWidth(2);
- rB.SetRightAndOpposite(rC, AnchorParam.Left);
- rC.SetStarWidth(2);
- rC.SetRight(null, AnchorParam.Right);
-
- surf.Render(g);
- }
-
- // Figure 10: Horizontal chain with weighted margins and packed rectangles.
- static void DrawSample7(GcGraphics g, Size _)
- {
- g.Transform = Matrix3x2.CreateScale(2);
-
- var surf = new Surface();
-
- var view = surf.CreateView(370, 120).Translate(30, 40);
- var v = view.CreateVisual(DrawView);
- v.Tag = new FigureCaption(10, "Rectangles are packed together after margins with weights\nare accounted for:",
- "rBeforeA.SetLeft(null, AnchorParam.Left);\n" +
- "rBeforeA.SetStarWidth(3);\n" +
- "rA.SetLeftAndOpposite(rBeforeA, AnchorParam.Right);\n" +
- "rA.SetWidth(70);\n" +
- "rB.SetLeftAndOpposite(rA, AnchorParam.Right);\n" +
- "rB.SetWidth(70);\n" +
- "rC.SetLeftAndOpposite(rB, AnchorParam.Right);\n" +
- "rC.SetWidth(70);\n" +
- "rAfterC.SetLeftAndOpposite(rC, AnchorParam.Right);\n" +
- "rAfterC.SetStarWidth(1);\n" +
- "rAfterC.SetRight(null, AnchorParam.Right);");
- v.LayoutRect.AnchorExact(null);
-
- v = view.CreateVisual(DrawRect);
- var rA = v.LayoutRect;
- rA.SetHeight(40);
- rA.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "A";
-
- v = view.CreateVisual(DrawRect);
- var rB = v.LayoutRect;
- rB.SetHeight(40);
- rB.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "B";
-
- v = view.CreateVisual(DrawRect);
- var rC = v.LayoutRect;
- rC.SetHeight(40);
- rC.SetVerticalCenter(null, AnchorParam.VerticalCenter);
- v.Tag = "C";
-
- var rBeforeA = view.CreateVisual(DrawLineWithLeftArrow).LayoutRect;
- rBeforeA.AnchorTopBottom(rA, 0, 0);
-
- var rAfterC = view.CreateVisual(DrawLineWithRightArrow).LayoutRect;
- rAfterC.AnchorTopBottom(rC, 0, 0);
-
- rBeforeA.SetLeft(null, AnchorParam.Left);
- rBeforeA.SetStarWidth(3);
- rA.SetLeftAndOpposite(rBeforeA, AnchorParam.Right);
- rA.SetWidth(70);
- rB.SetLeftAndOpposite(rA, AnchorParam.Right);
- rB.SetWidth(70);
- rC.SetLeftAndOpposite(rB, AnchorParam.Right);
- rC.SetWidth(70);
- rAfterC.SetLeftAndOpposite(rC, AnchorParam.Right);
- rAfterC.SetStarWidth(1);
- rAfterC.SetRight(null, AnchorParam.Right);
-
- surf.Render(g);
- }
-
- // Text flow in and around non-rectangular contours.
- static void DrawSample8(GcGraphics g, Size pageSize)
- {
- g.FillRectangle(new RectangleF(0, 0, pageSize.Width, pageSize.Height), Color.White);
-
- var surf = new Surface();
-
- // Contour objects can be referenced in constraints defined for text rectangles.
- CreateFigure1(surf, out Contour c1_outer);
- CreateFigure2(surf, out Contour c2_outer, out Contour c2_inner);
-
- const float rowHeight = 24f;
- const float lineSpacing = 5f;
- const float paragraphSpacing = 10f;
- const float fontSize = 18f;
-
- // The main View object that displays horizontal text.
- var view = surf.CreateView(pageSize.Width, pageSize.Height);
- var rcMargin = view.CreateSpace().LayoutRect;
- rcMargin.AnchorDeflate(null, 20);
-
- var tf = new TextFormat
- {
- Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "calibri.ttf")),
- FontSizeInGraphicUnits = true,
- FontSize = fontSize,
- FontFeatures = new FontFeature[] { new FontFeature(FeatureTag.liga, false) }
- };
- var noRects = new List<ObjectRect>();
-
- TextLayout tl = null;
-
- var tso = new TextSplitOptions
- {
- RestObjectRects = noRects,
- AllowMovingAllToRest = true
- };
-
- LayoutRect rcPrevTop = null;
- LayoutRect rcPrevLeft = null;
- bool paragraphStarted = false;
-
- while (true)
- {
- var r0 = view.CreateVisual(DrawTextFragment).LayoutRect;
- if (rcPrevLeft != null)
- r0.SetTop(rcPrevLeft, AnchorParam.Top);
- else if (rcPrevTop != null)
- r0.SetTop(rcPrevTop, AnchorParam.Bottom, paragraphStarted ? lineSpacing : paragraphSpacing);
- else
- r0.SetTop(rcMargin, AnchorParam.Top);
- if (rcPrevLeft is null)
- r0.SetLeft(rcMargin, AnchorParam.Left);
- else
- r0.SetLeft(rcPrevLeft, AnchorParam.Right);
-
- r0.SetHeight(rowHeight);
- r0.AppendMaxRight(rcMargin, AnchorParam.Right);
-
- var r1 = view.CreateSpace().LayoutRect;
- r1.SetTop(r0, AnchorParam.Top);
- r1.SetHeight(rowHeight);
- r1.SetLeft(r0, AnchorParam.Right);
- r1.AppendMaxRight(rcMargin, AnchorParam.Right);
-
- r0.AppendMaxRight(c1_outer, ContourPosition.FirstInOutside);
- r0.AppendMaxRight(c2_outer, ContourPosition.FirstInOutside);
-
- r1.AppendMaxRight(c1_outer, ContourPosition.NextOutOutside);
- r1.AppendMaxRight(c2_outer, ContourPosition.NextOutOutside);
-
- surf.PerformLayout();
-
- if (!paragraphStarted)
- {
- // It is important to have the ObjectRects property set
- // to a not null value (an empty list works well) and
- // the AllowOverhangingWords property set to true.
-
- tl = g.CreateTextLayout();
- tl.ObjectRects = noRects;
- tl.TextAlignment = TextAlignment.Justified;
- tl.AllowOverhangingWords = true;
- tl.FirstLineIndent = 40f;
- tl.JustifiedTextExtension = 0.1f;
-
- tl.Append(Common.Util.LoremIpsum(1), tf);
-
- tl.MaxWidth = r0.Width;
- tl.MaxHeight = r0.Height;
- ((Visual)r0.Tag).Tag = tl;
-
- if (!tl.PerformLayout())
- {
- paragraphStarted = true;
- }
- }
- else
- {
- tso.RestMaxWidth = r0.Width;
- tso.RestMaxHeight = r0.Height;
- var res = tl.Split(tso, out TextLayout rest);
- if (res != SplitResult.CannotSplit)
- {
- tl = rest;
- ((Visual)r0.Tag).Tag = rest;
- if (tl.PerformLayout())
- {
- paragraphStarted = false;
- }
- }
- }
-
- if (paragraphStarted && r1.Width > 0f)
- rcPrevLeft = r1;
- else
- {
- ((Space)r1.Tag).Detach();
- var spacing = paragraphStarted ? lineSpacing : paragraphSpacing;
- if (rcMargin.P2Y - r0.P2Y < spacing + rowHeight)
- {
- break;
- }
- rcPrevLeft = null;
- rcPrevTop = r0;
- }
- }
-
- tl.Truncate(TrimmingGranularity.Word);
-
- // The second View showing text in the ellipse.
- var view2 = surf.CreateView(pageSize.Width / 3, pageSize.Height / 2).Translate(520, 260).Rotate(15);
-
- tf = new TextFormat(tf)
- {
- ForeColor = Color.Purple,
- FontSize = 14,
- };
- tl = g.CreateTextLayout();
- tl.ObjectRects = noRects;
- tl.TextAlignment = TextAlignment.Center;
- tl.AllowOverhangingWords = true;
-
- tl.Append(Common.Util.LoremIpsum(1), tf);
-
- rcPrevTop = null;
- paragraphStarted = false;
-
- while (true)
- {
- var r0 = view2.CreateSpace().LayoutRect;
- if (rcPrevTop != null)
- r0.SetTop(rcPrevTop, AnchorParam.Bottom, 4);
- else
- r0.SetTop(null, AnchorParam.Top);
- r0.SetLeft(null, AnchorParam.Left);
-
- r0.SetHeight(18);
- r0.AppendMaxRight(null, AnchorParam.Right);
-
- var r1 = view2.CreateVisual(DrawTextFragment).LayoutRect;
- r1.SetTop(r0, AnchorParam.Top);
- r1.SetHeight(18);
- r1.SetLeft(r0, AnchorParam.Right);
- r1.AppendMaxRight(null, AnchorParam.Right);
-
- r0.AppendMaxRight(c2_inner, ContourPosition.FirstInInside);
- r1.AppendMaxRight(c2_inner, ContourPosition.NextOutInside);
-
- surf.PerformLayout();
- if (r1.Width == 0f)
- {
- ((Space)r1.Tag).Detach();
- if (paragraphStarted)
- {
- break;
- }
- }
- else if (!paragraphStarted)
- {
- tl.MaxWidth = r1.Width;
- tl.MaxHeight = r1.Height;
- ((Visual)r1.Tag).Tag = tl;
- if (tl.PerformLayout())
- {
- break;
- }
- paragraphStarted = true;
- }
- else
- {
- tso.RestMaxWidth = r1.Width;
- tso.RestMaxHeight = r1.Height;
- var res = tl.Split(tso, out TextLayout rest);
- if (res == SplitResult.FitAll)
- {
- ((Space)r1.Tag).Detach();
- break;
- }
- if (res == SplitResult.Split)
- {
- ((Visual)r1.Tag).Tag = rest;
- tl = rest;
- }
- }
- rcPrevTop = r0;
- }
-
- tl.Truncate(TrimmingGranularity.Word);
-
- surf.Render(g);
- }
-
- //
- // Common utility classes and methods.
- //
-
- class FigureCaption
- {
- public FigureCaption(int number, string description, string code = null)
- {
- Number = number;
- Description = description;
- Code = code;
- }
- public int Number { get; }
- public string Description { get; }
- public string Code { get; }
- }
-
- static void DrawTextFragment(GcGraphics g, Visual v)
- {
- if (v.Tag is TextLayout tl)
- {
- g.DrawTextLayout(tl, new PointF(0, 0));
- }
- }
-
- static void CreateFigure1(Surface surf, out Contour c_outer)
- {
- // A View for the yellow polygon.
- var view = surf.CreateView(0, 0).Translate(120, -40).Rotate(40);
- var lv = view.LayoutView;
-
- var c = lv.CreateContour();
-
- var v = view.CreateVisual(c, true, (g, v) =>
- {
- g.FillPolygon(v.Points, Color.LemonChiffon);
- g.DrawPolygon(v.Points, Color.Green, 3);
- });
- var rect = v.LayoutRect;
- rect.AnchorTopLeft(null, 100, 150, 170, 70);
-
- c.AddPoints(new AnchorPoint[]
- {
- rect.CreatePoint(0, 0, -20, -20),
- rect.CreatePoint(1, 0, 20, -20),
- rect.CreatePoint(1, 0, 20, -120),
- rect.CreatePoint(1, 0, 120, -120),
- rect.CreatePoint(1, 1, 120, 20),
- rect.CreatePoint(0, 1, -20, 20)
- });
-
- surf.PerformLayout();
-
- var points = c.MapToView(lv);
-
- // To make the outer offset from the Contour we convert
- // the Contour to a GraphicsPath, then apply the Widen
- // method with a thick pen. The resulting figure is
- // used for creating the outer Contour.
- var gp = new GraphicsPath(new FreeFormPolygon(points));
- var gp2 = gp.Widen(new GCDRAW.Pen(Color.White, 7 * 2));
-
- var fig_outer = gp2.Figures[0];
-
- fig_outer.Flatten();
- var outer_points = fig_outer.TransformedPoints;
-
- c_outer = lv.CreateContour();
- for (int i = 0; i < outer_points.Length; i++)
- {
- var p = outer_points[i];
- c_outer.AddPoint(lv.CreatePoint(0f, 0f, p.X, p.Y));
- }
- }
-
- static void CreateFigure2(Surface surf, out Contour c_outer, out Contour c_inner)
- {
- // A View for the rotated ellipse.
- var view = surf.CreateView(360, 150).Translate(450, 530).Rotate(-40);
- var lv = view.LayoutView;
-
- var c = lv.CreateContour();
-
- view.CreateVisual(c, false, (g, v) =>
- {
- g.DrawPolygon(v.Points, Color.DeepPink, 3);
- });
-
- // To make the inner and the outer offsets from the ellipse
- // we convert the elliptic figure to an array of points which
- // is used later for creating a GraphicsPath. Then, we call
- // the GraphicsPath.Widen method with a thick pen.
- // The resulting outer and inner figures can be converted
- // into new contours for later use in constraints.
- IFigure ef = new EllipticFigure(lv.AsRectF());
- ef.Flatten();
- var points = ef.TransformedPoints;
- int count = points.Length;
- var list = new List<AnchorPoint>(count);
- for (int i = 0; i < count; i++)
- {
- var p = points[i];
- list.Add(lv.CreatePoint(0, 0, p.X, p.Y));
- }
- c.AddPoints(list);
-
- var gp = new GraphicsPath(ef);
- var gp2 = gp.Widen(new GCDRAW.Pen(Color.White, 7 * 2));
-
- var fig_outer = gp2.Figures[0];
- var fig_inner = gp2.Figures[1];
-
- fig_outer.Flatten();
- var outer_points = fig_outer.TransformedPoints;
-
- c_outer = lv.CreateContour();
- for (int i = 0; i < outer_points.Length; i++)
- {
- var p = outer_points[i];
- c_outer.AddPoint(lv.CreatePoint(0f, 0f, p.X, p.Y));
- }
-
- fig_inner.Flatten();
- var inner_points = fig_inner.TransformedPoints;
-
- c_inner = lv.CreateContour();
- for (int i = 0; i < inner_points.Length; i++)
- {
- var p = inner_points[i];
- c_inner.AddPoint(lv.CreatePoint(0f, 0f, p.X, p.Y));
- }
- }
-
- static readonly TextFormat FormatBox = new TextFormat()
- {
- Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeui.ttf")),
- FontSize = 14,
- FontSizeInGraphicUnits = true,
- ForeColor = BoxColor
- };
-
- static readonly TextFormat FormatDesc = new TextFormat(FormatBox)
- {
- FontSize = 12,
- ForeColor = DescColor
- };
-
- static readonly TextFormat FormatCaption = new TextFormat(FormatDesc)
- {
- FontBold = true
- };
-
- static readonly TextFormat FormatCode = new TextFormat(FormatDesc)
- {
- Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "cour.ttf")),
- ForeColor = CodeColor
- };
-
- static void DrawView(GcGraphics g, Visual v)
- {
- var rect = v.AsRectF();
- g.FillRectangle(rect, Color.FromArgb(31, 82, 100));
- g.DrawRectangle(rect, new GCDRAW.Pen(Color.FromArgb(200, 200, 200), 1)
- {
- DashPattern = new float[] { 7, 3 }
- });
- if (v.Tag is FigureCaption fc)
- {
- var tl = g.CreateTextLayout();
- tl.Append($"Figure {fc.Number}. ", FormatCaption);
- tl.AppendLine(fc.Description, FormatDesc);
- if (fc.Code != null)
- {
- tl.Append(fc.Code, FormatCode);
- }
- g.DrawTextLayout(tl, new PointF(0, v.Height + 5));
- }
- }
-
- static void DrawVertGuideline(GcGraphics g, Visual v)
- {
- g.DrawLine(new PointF(0, 0), new PointF(0, v.Height), new GCDRAW.Pen(BoxColor, 1)
- {
- DashPattern = new float[] { 1, 2 }
- });
- if (v.Tag is string s)
- {
- var tl = g.CreateTextLayout();
- tl.Append(s, FormatDesc);
- tl.PerformLayout();
- var rect = tl.ContentRectangle;
- rect.X = -rect.Width * 0.5f;
- rect.Y = 10;
- rect.Inflate(3, 1);
- g.FillRoundRect(rect, 3, RectColor);
- g.DrawTextLayout(tl, new PointF(rect.X + 3, rect.Y + 1));
- }
- }
-
- static void DrawRect(GcGraphics g, Visual v)
- {
- var rect = v.AsRectF();
- g.FillRectangle(rect, RectColor);
- g.DrawRectangle(rect, new GCDRAW.Pen(BoxColor, 1));
- if (v.Tag is string s)
- {
- var tl = g.CreateTextLayout();
- tl.MaxWidth = v.Width;
- tl.MaxHeight = v.Height;
- tl.TextAlignment = TextAlignment.Center;
- tl.ParagraphAlignment = ParagraphAlignment.Center;
- tl.Append(s, FormatBox);
- g.DrawTextLayout(tl, new PointF(0, 0));
- }
- }
-
- static void DrawLineWithLeftArrow(GcGraphics g, Visual v)
- {
- var y = v.Height * 0.5f;
- g.DrawLine(new PointF(5, y), new PointF(v.Width, y), new GCDRAW.Pen(BoxColor, 0.7f));
- DrawLeftArrow(g, 0, y);
- }
-
- static void DrawLineWithRightArrow(GcGraphics g, Visual v)
- {
- var y = v.Height * 0.5f;
- g.DrawLine(new PointF(0, y), new PointF(v.Width - 5, y), new GCDRAW.Pen(BoxColor, 0.7f));
- DrawRightArrow(g, v.Width, y);
- }
-
- static void DrawLeftRightLines(GcGraphics g, Visual v)
- {
- var y = v.Height * 0.33f;
- g.DrawLine(new PointF(5, y), new PointF(v.Width, y), new GCDRAW.Pen(BoxColor, 0.7f));
- DrawLeftArrow(g, 0, y);
- y = v.Height * 0.66f;
- g.DrawLine(new PointF(0, y), new PointF(v.Width - 5, y), new GCDRAW.Pen(BoxColor, 0.7f));
- DrawRightArrow(g, v.Width, y);
- }
-
- static void DrawVertLineWithLeftArrow(GcGraphics g, Visual v)
- {
- var x = v.Width * 0.5f;
- g.DrawLines(new PointF[]
- {
- new PointF(5, 0),
- new PointF(x, 0),
- new PointF(x, v.Height),
- new PointF(v.Width, v.Height)
- }, new GCDRAW.Pen(BoxColor, 0.7f));
- DrawLeftArrow(g, 0, 0);
- }
-
- static void DrawLineWithUpArrow(GcGraphics g, Visual v)
- {
- var x = v.Width * 0.5f;
- g.DrawLine(new PointF(x, 5), new PointF(x, v.Height), new GCDRAW.Pen(BoxColor, 0.7f));
- DrawUpArrow(g, x, 0);
- }
-
- static void DrawLeftArrow(GcGraphics g, float x, float y)
- {
- var pts = new PointF[]
- {
- new PointF(x, y),
- new PointF(x + 8, y - 2.5f),
- new PointF(x + 8, y + 2.5f),
- };
- g.FillPolygon(pts, BoxColor);
- }
-
- static void DrawRightArrow(GcGraphics g, float x, float y)
- {
- var pts = new PointF[]
- {
- new PointF(x, y),
- new PointF(x - 8, y + 2.5f),
- new PointF(x - 8, y - 2.5f),
- };
- g.FillPolygon(pts, BoxColor);
- }
-
- static void DrawUpArrow(GcGraphics g, float x, float y)
- {
- var pts = new PointF[]
- {
- new PointF(x, y),
- new PointF(x + 2.5f, y + 8),
- new PointF(x - 2.5f, y + 8),
- };
- g.FillPolygon(pts, BoxColor);
- }
- }
- }
-