'''' This code is part of Document Solutions for Imaging demos.'' Copyright (c) MESCIUS inc. All rights reserved.''Imports System.DrawingImports System.IOImports System.NumericsImports GrapeCity.Documents.DrawingImports GrapeCity.Documents.TextImports GrapeCity.Documents.ImagingImports GrapeCity.Documents.LayoutImports GrapeCity.Documents.Layout.CompositionImports GCTEXT = GrapeCity.Documents.TextImports GCDRAW = GrapeCity.Documents.Drawing
'' 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 Private Shared ReadOnly PageColor As Color = Color.FromArgb(39, 41, 43) Private Shared ReadOnly BoxColor As Color = Color.FromArgb(230, 230, 230) Private Shared ReadOnly CodeColor As Color = Color.FromArgb(132, 211, 232) Private Shared ReadOnly RectColor As Color = Color.FromArgb(64, 126, 148) Private Shared ReadOnly DescColor As Color = Color.White
Private Delegate Sub DrawLayoutSample(g As GcGraphics, pageSize As Size)
Private Shared ReadOnly c_samples As Dictionary(Of String, DrawLayoutSample) = New Dictionary(Of String, DrawLayoutSample) From { {"DrawSample1", AddressOf DrawSample1}, {"DrawSample2", AddressOf DrawSample2}, {"DrawSample3", AddressOf DrawSample3}, {"DrawSample4", AddressOf DrawSample4}, {"DrawSample5", AddressOf DrawSample5}, {"DrawSample6", AddressOf DrawSample6}, {"DrawSample7", AddressOf DrawSample7}, {"DrawSample8", AddressOf DrawSample8} }
Public Function GenerateImage( ByVal pixelSize As Size, ByVal dpi As Single, ByVal opaque As Boolean, Optional ByVal sampleParams As String() = Nothing) As GcBitmap
Dim drawSample As DrawLayoutSample = Nothing If Not c_samples.TryGetValue(sampleParams(3), drawSample) Then Throw New Exception($"Unknown parameterized sample: {sampleParams(3)}") End If
Dim bmp = New GcBitmap(pixelSize.Width, pixelSize.Height, opaque, dpi, dpi) Using g = bmp.CreateGraphics(PageColor) drawSample(g, pixelSize) End Using Return bmp End Function
'' Strings are name, description, info. Rest are arbitrary strings: Public Shared Function GetSampleParamsList() As List(Of String()) Return New List(Of String()) From { New String() {"Figures 1-4", "Figures 1-4: horizontal, vertical, alignment constraint and guidelines", Nothing, "DrawSample1"}, New String() {"Figure 5", "Figure 5: Barrier constraint anchored to two visuals", Nothing, "DrawSample2"}, New String() {"Figure 6", "Figure 6: Horizontal chain with weighted widths", Nothing, "DrawSample3"}, New String() {"Figure 7", "Figure 7: Horizontal chain with evenly distributed rectangles and margins", Nothing, "DrawSample4"}, New String() {"Figure 8", "Figure 8: Horizontal chain with evenly distributed rectangles, no margins", Nothing, "DrawSample5"}, New String() {"Figure 9", "Figure 9: Weighted horizontal chain without margins", Nothing, "DrawSample6"}, New String() {"Figure 10", "Figure 10: Horizontal chain with weighted margins and packed rectangles", Nothing, "DrawSample7"}, New String() {"Text Flow", "Text flow in and around non-rectangular contours", Nothing, "DrawSample8"} } End Function
'' Figures 1-4: horizontal, vertical, alignment constraint and guidelines. Private Shared Sub DrawSample1(g As GcGraphics, pageSize As Size) g.Transform = Matrix3x2.CreateScale(1.4F)
'' The Surface object can layout Visuals and draw them on the graphics. Dim surf = New Surface()
'' view1
'' The View object represents a group of Visuals with a transformation matrix. Dim 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. Dim v = view1.CreateVisual(AddressOf DrawView) v.Tag = New FigureCaption(1, "A horizontal constraint to the parent:", "rA.SetLeft(null, AnchorParam.Left, 90);") v.LayoutRect.AnchorExact(Nothing)
v = view1.CreateVisual(AddressOf DrawRect) Dim rA = v.LayoutRect rA.SetLeft(Nothing, AnchorParam.Left, 90) rA.SetWidth(70) rA.SetHeight(40) rA.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "A"
Dim r = view1.CreateVisual(AddressOf DrawLineWithLeftArrow).LayoutRect r.AnchorTopBottom(rA, 0, 0) r.SetLeft(Nothing, AnchorParam.Left) r.SetRight(rA, AnchorParam.Left)
'' view2 Dim view2 = surf.CreateView(250, 150).Translate(350, 40) v = view2.CreateVisual(AddressOf DrawView) v.Tag = New FigureCaption(2, "An offset horizontal alignment constraint:", "rB.SetLeft(rA, AnchorParam.Left, 40);") v.LayoutRect.AnchorExact(Nothing)
v = view2.CreateVisual(AddressOf DrawRect) rA = v.LayoutRect rA.AnchorTopLeft(Nothing, 15, 70, 110, 60) v.Tag = "A"
v = view2.CreateVisual(AddressOf DrawRect) Dim 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(AddressOf DrawVertLineWithLeftArrow).LayoutRect r.SetTop(rA, AnchorParam.VerticalCenter) r.SetBottom(rB, AnchorParam.VerticalCenter) r.SetLeft(rA, AnchorParam.Left) r.SetRight(rB, AnchorParam.Left)
'' view3 Dim view3 = surf.CreateView(250, 150).Translate(50, 260) v = view3.CreateVisual(AddressOf DrawView) v.Tag = New FigureCaption(3, "Horizontal and vertical constraints:", "rB.SetLeft(rA, AnchorParam.Right, 50);" & vbLf & "rC.SetTop(rA, AnchorParam.Bottom, 40);") v.LayoutRect.AnchorExact(Nothing)
v = view3.CreateVisual(AddressOf DrawRect) rA = v.LayoutRect rA.AnchorTopLeft(Nothing, 15, 30, 70, 40) v.Tag = "A"
v = view3.CreateVisual(AddressOf 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(AddressOf DrawRect) Dim 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(AddressOf DrawLineWithLeftArrow).LayoutRect r.AnchorTopBottom(rA, 0, 0) r.SetLeft(rA, AnchorParam.Right) r.SetRight(rB, AnchorParam.Left)
r = view3.CreateVisual(AddressOf DrawLineWithUpArrow).LayoutRect r.AnchorLeftRight(rA, 0, 0) r.SetTop(rA, AnchorParam.Bottom) r.SetBottom(rC, AnchorParam.Top)
'' view4 Dim view4 = surf.CreateView(250, 150).Translate(350, 260) Dim layoutView = view4.LayoutView v = view4.CreateVisual(AddressOf DrawView) v.Tag = New FigureCaption(4, "A rectangle constrained to a guideline:", "var anchorPoint = layoutView.CreatePoint(0.25f, 0);" & vbLf & "rA.SetLeft(anchorPoint, 60);") v.LayoutRect.AnchorExact(Nothing)
'' An anchor point can work as the guideline on the X or the Y axes. Dim anchorPoint = layoutView.CreatePoint(0.25F, 0)
v = view4.CreateVisual(AddressOf DrawVertGuideline) Dim rG = v.LayoutRect rG.SetLeft(anchorPoint) rG.AnchorVerticalLine(Nothing) v.Tag = "25 %"
v = view4.CreateVisual(AddressOf DrawRect) rA = v.LayoutRect rA.SetLeft(anchorPoint, 60) rA.SetWidth(70) rA.SetHeight(40) rA.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "A"
r = view4.CreateVisual(AddressOf DrawLineWithLeftArrow).LayoutRect r.AnchorTopBottom(rA, 0, 0) r.SetLeft(rG, AnchorParam.Left) r.SetRight(rA, AnchorParam.Left)
surf.Render(g) End Sub
'' Figure 5: Barrier constraint anchored to two visuals. Private Shared Sub DrawSample2(g As GcGraphics, pageSize As Size) g.Transform = Matrix3x2.CreateScale(2)
Dim surf = New Surface()
'' View1 Dim view1 = surf.CreateView(350, 160).Translate(30, 30) view1.CreateVisual(AddressOf DrawView).LayoutRect.AnchorExact(Nothing)
Dim v = view1.CreateVisual(AddressOf DrawRect) Dim rA = v.LayoutRect rA.AnchorTopLeft(Nothing, 30, 50, 60, 40) v.Tag = "A"
v = view1.CreateVisual(AddressOf DrawRect) Dim rB = v.LayoutRect rB.AnchorTopLeft(Nothing, 90, 50, 90, 40) v.Tag = "B"
v = view1.CreateVisual(AddressOf DrawVertGuideline) Dim 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(Nothing)
v = view1.CreateVisual(AddressOf DrawRect) Dim rC = v.LayoutRect rC.AppendMinLeft(rA, AnchorParam.Right, 50) rC.AppendMinLeft(rB, AnchorParam.Right, 50) rC.SetWidth(70) rC.SetHeight(40) rC.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "C"
Dim r = view1.CreateVisual(AddressOf DrawLineWithLeftArrow).LayoutRect r.AnchorTopBottom(rC, 0, 0) r.SetLeft(rG, AnchorParam.Right) r.SetRight(rC, AnchorParam.Left)
'' View2 Dim view2 = surf.CreateView(350, 160).Translate(30, 210) v = view2.CreateVisual(AddressOf DrawView) v.Tag = New FigureCaption(5, "C is constrained to a barrier, which moves based on" & vbLf & "the position and size of both A and B:", "rC.AppendMinLeft(rA, AnchorParam.Right, 50);" & vbLf & "rC.AppendMinLeft(rB, AnchorParam.Right, 50);") v.LayoutRect.AnchorExact(Nothing)
v = view2.CreateVisual(AddressOf DrawRect) rA = v.LayoutRect rA.AnchorTopLeft(Nothing, 30, 50, 130, 40) v.Tag = "A"
v = view2.CreateVisual(AddressOf DrawRect) rB = v.LayoutRect rB.AnchorTopLeft(Nothing, 90, 50, 90, 40) v.Tag = "B"
v = view2.CreateVisual(AddressOf DrawVertGuideline) rG = v.LayoutRect rG.AppendMinLeft(rA, AnchorParam.Right) rG.AppendMinLeft(rB, AnchorParam.Right) rG.AnchorVerticalLine(Nothing)
v = view2.CreateVisual(AddressOf DrawRect) rC = v.LayoutRect rC.AppendMinLeft(rA, AnchorParam.Right, 50) rC.AppendMinLeft(rB, AnchorParam.Right, 50) rC.SetWidth(70) rC.SetHeight(40) rC.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "C"
r = view2.CreateVisual(AddressOf DrawLineWithLeftArrow).LayoutRect r.AnchorTopBottom(rC, 0, 0) r.SetLeft(rG, AnchorParam.Right) r.SetRight(rC, AnchorParam.Left)
surf.Render(g) End Sub
'' Figure 6: Horizontal chain with weighted widths. Private Shared Sub DrawSample3(g As GcGraphics, pageSize As Size) g.Transform = Matrix3x2.CreateScale(2)
Dim surf = New Surface()
Dim view = surf.CreateView(350, 120).Translate(30, 40) Dim v = view.CreateVisual(AddressOf DrawView) v.Tag = New FigureCaption(6, "A horizontal chain with two rectangles having weighted" & vbLf & "widths and a fixed space between them:", "rA.SetLeft(null, AnchorParam.Left, 60);" & vbLf & "rA.SetStarWidth(1);" & vbLf & "rAB.SetLeftAndOpposite(rA, AnchorParam.Right);" & vbLf & "rAB.SetWidth(50);" & vbLf & "rB.SetLeftAndOpposite(rAB, AnchorParam.Right);" & vbLf & "rB.SetStarWidth(2);" & vbLf & "rB.SetRight(null, AnchorParam.Right, -60);") v.LayoutRect.AnchorExact(Nothing)
v = view.CreateVisual(AddressOf DrawRect) Dim rA = v.LayoutRect rA.SetHeight(40) rA.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "A"
v = view.CreateVisual(AddressOf DrawRect) Dim rB = v.LayoutRect rB.SetHeight(40) rB.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "B"
Dim rAB = view.CreateVisual(AddressOf 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(Nothing, AnchorParam.Left, 60) rA.SetStarWidth(1) rAB.SetLeftAndOpposite(rA, AnchorParam.Right) rAB.SetWidth(50) rB.SetLeftAndOpposite(rAB, AnchorParam.Right) rB.SetStarWidth(2) rB.SetRight(Nothing, AnchorParam.Right, -60)
Dim r = view.CreateVisual(AddressOf DrawLineWithLeftArrow).LayoutRect r.AnchorTopBottom(rA, 0, 0) r.SetLeft(Nothing, AnchorParam.Left) r.SetRight(rA, AnchorParam.Left)
r = view.CreateVisual(AddressOf DrawLineWithRightArrow).LayoutRect r.AnchorTopBottom(rB, 0, 0) r.SetLeft(rB, AnchorParam.Right) r.SetRight(Nothing, AnchorParam.Right)
surf.Render(g) End Sub
'' Figure 7: Horizontal chain with evenly distributed rectangles and margins. Private Shared Sub DrawSample4(g As GcGraphics, pageSize As Size) g.Transform = Matrix3x2.CreateScale(1.8F)
Dim surf = New Surface()
Dim view = surf.CreateView(430, 120).Translate(30, 40) Dim v = view.CreateVisual(AddressOf DrawView) v.Tag = New FigureCaption(7, "A horizontal chain with three evenly distributed rectangles" & vbLf & "after margins are accounted for:", "rA.SetLeft(null, AnchorParam.Left, 60);" & vbLf & "rA.SetWidth(70);" & vbLf & "rAB.SetLeftAndOpposite(rA, AnchorParam.Right);" & vbLf & "rAB.SetStarWidth(1);" & vbLf & "rAB.SetRightAndOpposite(rB, AnchorParam.Left);" & vbLf & "rB.SetWidth(70);" & vbLf & "rBC.SetLeftAndOpposite(rB, AnchorParam.Right);" & vbLf & "rBC.SetStarWidth(1);" & vbLf & "rC.SetLeftAndOpposite(rBC, AnchorParam.Right);" & vbLf & "rC.SetWidth(70);" & vbLf & "rC.SetRight(null, AnchorParam.Right, -60);") v.LayoutRect.AnchorExact(Nothing)
v = view.CreateVisual(AddressOf DrawRect) Dim rA = v.LayoutRect rA.SetHeight(40) rA.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "A"
v = view.CreateVisual(AddressOf DrawRect) Dim rB = v.LayoutRect rB.SetHeight(40) rB.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "B"
v = view.CreateVisual(AddressOf DrawRect) Dim rC = v.LayoutRect rC.SetHeight(40) rC.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "C"
Dim rAB = view.CreateVisual(AddressOf DrawLeftRightLines).LayoutRect rAB.AnchorTopBottom(rA, 0, 0)
Dim rBC = view.CreateVisual(AddressOf DrawLeftRightLines).LayoutRect rBC.AnchorTopBottom(rB, 0, 0)
rA.SetLeft(Nothing, 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(Nothing, AnchorParam.Right, -60)
Dim r = view.CreateVisual(AddressOf DrawLineWithLeftArrow).LayoutRect r.AnchorTopBottom(rA, 0, 0) r.SetLeft(Nothing, AnchorParam.Left) r.SetRight(rA, AnchorParam.Left)
r = view.CreateVisual(AddressOf DrawLineWithRightArrow).LayoutRect r.AnchorTopBottom(rC, 0, 0) r.SetLeft(rC, AnchorParam.Right) r.SetRight(Nothing, AnchorParam.Right)
surf.Render(g) End Sub
'' Figure 8: Horizontal chain with evenly distributed rectangles, no margins. Private Shared Sub DrawSample5(g As GcGraphics, pageSize As Size) g.Transform = Matrix3x2.CreateScale(2)
Dim surf = New Surface()
Dim view = surf.CreateView(340, 120).Translate(30, 40) Dim v = view.CreateVisual(AddressOf DrawView) v.Tag = New FigureCaption(8, "Same as Figure 7, without accounting for the margins:", "rA.SetLeft(null, AnchorParam.Left);" & vbLf & "rA.SetWidth(70);" & vbLf & "rA.SetRightAndOpposite(rAB, AnchorParam.Left);" & vbLf & "rAB.SetStarWidth(1);" & vbLf & "rB.SetLeftAndOpposite(rAB, AnchorParam.Right);" & vbLf & "rB.SetWidth(70);" & vbLf & "rB.SetRightAndOpposite(rBC, AnchorParam.Left);" & vbLf & "rBC.SetStarWidth(1);" & vbLf & "rC.SetLeftAndOpposite(rBC, AnchorParam.Right);" & vbLf & "rC.SetWidth(70);" & vbLf & "rC.SetRight(null, AnchorParam.Right);") v.LayoutRect.AnchorExact(Nothing)
v = view.CreateVisual(AddressOf DrawRect) Dim rA = v.LayoutRect rA.SetHeight(40) rA.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "A"
v = view.CreateVisual(AddressOf DrawRect) Dim rB = v.LayoutRect rB.SetHeight(40) rB.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "B"
v = view.CreateVisual(AddressOf DrawRect) Dim rC = v.LayoutRect rC.SetHeight(40) rC.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "C"
Dim rAB = view.CreateVisual(AddressOf DrawLeftRightLines).LayoutRect rAB.AnchorTopBottom(rA, 0, 0)
Dim rBC = view.CreateVisual(AddressOf DrawLeftRightLines).LayoutRect rBC.AnchorTopBottom(rB, 0, 0)
rA.SetLeft(Nothing, 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(Nothing, AnchorParam.Right)
surf.Render(g) End Sub
'' Figure 9: Weighted horizontal chain without margins. Private Shared Sub DrawSample6(g As GcGraphics, pageSize As Size) g.Transform = Matrix3x2.CreateScale(2)
Dim surf = New Surface()
Dim view = surf.CreateView(340, 120).Translate(30, 40) Dim v = view.CreateVisual(AddressOf DrawView) v.Tag = New FigureCaption(9, "A weighted horizontal chain without margins:", "rA.SetLeft(null, AnchorParam.Left);" & vbLf & "rA.SetStarWidth(1);" & vbLf & "rA.SetRightAndOpposite(rB, AnchorParam.Left);" & vbLf & "rB.SetStarWidth(2);" & vbLf & "rB.SetRightAndOpposite(rC, AnchorParam.Left);" & vbLf & "rC.SetStarWidth(2);" & vbLf & "rC.SetRight(null, AnchorParam.Right);") v.LayoutRect.AnchorExact(Nothing)
v = view.CreateVisual(AddressOf DrawRect) Dim rA = v.LayoutRect rA.SetHeight(40) rA.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "A"
v = view.CreateVisual(AddressOf DrawRect) Dim rB = v.LayoutRect rB.SetHeight(40) rB.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "B"
v = view.CreateVisual(AddressOf DrawRect) Dim rC = v.LayoutRect rC.SetHeight(40) rC.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "C"
rA.SetLeft(Nothing, AnchorParam.Left) rA.SetStarWidth(1) rA.SetRightAndOpposite(rB, AnchorParam.Left) rB.SetStarWidth(2) rB.SetRightAndOpposite(rC, AnchorParam.Left) rC.SetStarWidth(2) rC.SetRight(Nothing, AnchorParam.Right)
surf.Render(g) End Sub
'' Figure 10: Horizontal chain with weighted margins and packed rectangles. Private Shared Sub DrawSample7(g As GcGraphics, pageSize As Size) g.Transform = Matrix3x2.CreateScale(2)
Dim surf = New Surface()
Dim view = surf.CreateView(370, 120).Translate(30, 40) Dim v = view.CreateVisual(AddressOf DrawView) v.Tag = New FigureCaption(10, "Rectangles are packed together after margins with weights" & vbLf & "are accounted for:", "rBeforeA.SetLeft(null, AnchorParam.Left);" & vbLf & "rBeforeA.SetStarWidth(3);" & vbLf & "rA.SetLeftAndOpposite(rBeforeA, AnchorParam.Right);" & vbLf & "rA.SetWidth(70);" & vbLf & "rB.SetLeftAndOpposite(rA, AnchorParam.Right);" & vbLf & "rB.SetWidth(70);" & vbLf & "rC.SetLeftAndOpposite(rB, AnchorParam.Right);" & vbLf & "rC.SetWidth(70);" & vbLf & "rAfterC.SetLeftAndOpposite(rC, AnchorParam.Right);" & vbLf & "rAfterC.SetStarWidth(1);" & vbLf & "rAfterC.SetRight(null, AnchorParam.Right);") v.LayoutRect.AnchorExact(Nothing)
v = view.CreateVisual(AddressOf DrawRect) Dim rA = v.LayoutRect rA.SetHeight(40) rA.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "A"
v = view.CreateVisual(AddressOf DrawRect) Dim rB = v.LayoutRect rB.SetHeight(40) rB.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "B"
v = view.CreateVisual(AddressOf DrawRect) Dim rC = v.LayoutRect rC.SetHeight(40) rC.SetVerticalCenter(Nothing, AnchorParam.VerticalCenter) v.Tag = "C"
Dim rBeforeA = view.CreateVisual(AddressOf DrawLineWithLeftArrow).LayoutRect rBeforeA.AnchorTopBottom(rA, 0, 0)
Dim rAfterC = view.CreateVisual(AddressOf DrawLineWithRightArrow).LayoutRect rAfterC.AnchorTopBottom(rC, 0, 0)
rBeforeA.SetLeft(Nothing, 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(Nothing, AnchorParam.Right)
surf.Render(g) End Sub
'' Text flow in and around non-rectangular contours. Private Shared Sub DrawSample8(g As GcGraphics, pageSize As Size) g.FillRectangle(New RectangleF(0, 0, pageSize.Width, pageSize.Height), Color.White)
Dim surf = New Surface()
'' Contour objects can be referenced in constraints defined for text rectangles. Dim c1_outer As Contour = Nothing CreateFigure1(surf, c1_outer) Dim c2_outer As Contour = Nothing Dim c2_inner As Contour = Nothing CreateFigure2(surf, c2_outer, c2_inner)
Const rowHeight As Single = 24F Const lineSpacing As Single = 5F Const paragraphSpacing As Single = 10F Const fontSize As Single = 18F
'' The main View object that displays horizontal text. Dim view = surf.CreateView(pageSize.Width, pageSize.Height) Dim rcMargin = view.CreateSpace().LayoutRect rcMargin.AnchorDeflate(Nothing, 20)
Dim tf = New TextFormat() With { .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeSans.ttf")), .FontSizeInGraphicUnits = True, .FontSize = fontSize, .FontFeatures = New FontFeature() {New FontFeature(FeatureTag.liga, False)} } Dim noRects = New List(Of ObjectRect)()
Dim tl As TextLayout = Nothing
Dim tso = New TextSplitOptions() With { .RestObjectRects = noRects, .AllowMovingAllToRest = True }
Dim rcPrevTop As LayoutRect = Nothing Dim rcPrevLeft As LayoutRect = Nothing Dim paragraphStarted = False
While True Dim r0 = view.CreateVisual(AddressOf DrawTextFragment).LayoutRect If rcPrevLeft IsNot Nothing Then r0.SetTop(rcPrevLeft, AnchorParam.Top) ElseIf rcPrevTop IsNot Nothing Then r0.SetTop(rcPrevTop, AnchorParam.Bottom, If(paragraphStarted, lineSpacing, paragraphSpacing)) Else r0.SetTop(rcMargin, AnchorParam.Top) End If If rcPrevLeft Is Nothing Then r0.SetLeft(rcMargin, AnchorParam.Left) Else r0.SetLeft(rcPrevLeft, AnchorParam.Right) End If
r0.SetHeight(rowHeight) r0.AppendMaxRight(rcMargin, AnchorParam.Right)
Dim 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 Not paragraphStarted Then '' 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(Util.LoremIpsum(1), tf)
tl.MaxWidth = r0.Width tl.MaxHeight = r0.Height CType(r0.Tag, Visual).Tag = tl
If Not tl.PerformLayout() Then paragraphStarted = True End If Else tso.RestMaxWidth = r0.Width tso.RestMaxHeight = r0.Height Dim rest As TextLayout = Nothing Dim res = tl.Split(tso, rest) If res <> SplitResult.CannotSplit Then tl = rest CType(r0.Tag, Visual).Tag = rest If tl.PerformLayout() Then paragraphStarted = False End If End If End If
If paragraphStarted AndAlso r1.Width > 0F Then rcPrevLeft = r1 Else CType(r1.Tag, Space).Detach() Dim spacing = If(paragraphStarted, lineSpacing, paragraphSpacing) If rcMargin.P2Y - r0.P2Y < spacing + rowHeight Then Exit While End If rcPrevLeft = Nothing rcPrevTop = r0 End If End While
tl.Truncate(TrimmingGranularity.Word)
'' The second View showing text in the ellipse. Dim view2 = surf.CreateView(pageSize.Width \ 3, pageSize.Height \ 2).Translate(520, 260).Rotate(15)
tf = New TextFormat(tf) With { .ForeColor = Color.Purple, .FontSize = 14 } tl = g.CreateTextLayout() tl.ObjectRects = noRects tl.TextAlignment = TextAlignment.Center tl.AllowOverhangingWords = True
tl.Append(Util.LoremIpsum(1), tf)
rcPrevTop = Nothing paragraphStarted = False
While True Dim r0 = view2.CreateSpace().LayoutRect If rcPrevTop IsNot Nothing Then r0.SetTop(rcPrevTop, AnchorParam.Bottom, 4) Else r0.SetTop(Nothing, AnchorParam.Top) End If r0.SetLeft(Nothing, AnchorParam.Left)
r0.SetHeight(18) r0.AppendMaxRight(Nothing, AnchorParam.Right)
Dim r1 = view2.CreateVisual(AddressOf DrawTextFragment).LayoutRect r1.SetTop(r0, AnchorParam.Top) r1.SetHeight(18) r1.SetLeft(r0, AnchorParam.Right) r1.AppendMaxRight(Nothing, AnchorParam.Right)
r0.AppendMaxRight(c2_inner, ContourPosition.FirstInInside) r1.AppendMaxRight(c2_inner, ContourPosition.NextOutInside)
surf.PerformLayout() If r1.Width = 0F Then CType(r1.Tag, Space).Detach() If paragraphStarted Then Exit While End If ElseIf Not paragraphStarted Then tl.MaxWidth = r1.Width tl.MaxHeight = r1.Height CType(r1.Tag, Visual).Tag = tl If tl.PerformLayout() Then Exit While End If paragraphStarted = True Else tso.RestMaxWidth = r1.Width tso.RestMaxHeight = r1.Height Dim rest As TextLayout = Nothing Dim res = tl.Split(tso, rest) If res = SplitResult.FitAll Then CType(r1.Tag, Space).Detach() Exit While End If If res = SplitResult.Split Then CType(r1.Tag, Visual).Tag = rest tl = rest End If End If rcPrevTop = r0 End While
tl.Truncate(TrimmingGranularity.Word)
surf.Render(g) End Sub
'' '' Common utility classes and methods. ''
Private Class FigureCaption Public ReadOnly Property Number As Integer Public ReadOnly Property Description As String Public ReadOnly Property Code As String
Public Sub New(number As Integer, description As String, Optional code As String = Nothing) Me.Number = number Me.Description = description Me.Code = code End Sub End Class
Private Shared Sub DrawTextFragment(g As GcGraphics, v As Visual) Dim tl = TryCast(v.Tag, TextLayout) If tl IsNot Nothing Then g.DrawTextLayout(tl, New PointF(0, 0)) End If End Sub
Private Shared Sub CreateFigure1(surf As Surface, ByRef c_outer As Contour) '' A View for the yellow polygon. Dim view = surf.CreateView(0, 0).Translate(120, -40).Rotate(40) Dim lv = view.LayoutView
Dim c = lv.CreateContour()
Dim v = view.CreateVisual(c, True, Sub(gr As GcGraphics, vis As Visual) gr.FillPolygon(vis.Points, Color.LemonChiffon) gr.DrawPolygon(vis.Points, Color.Green, 3) End Sub) Dim rect = v.LayoutRect rect.AnchorTopLeft(Nothing, 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()
Dim 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. Dim gp = New GraphicsPath(New FreeFormPolygon(points)) Dim gp2 = gp.Widen(New GCDRAW.Pen(Color.White, 7 * 2))
Dim fig_outer = gp2.Figures(0)
fig_outer.Flatten() Dim outer_points = fig_outer.TransformedPoints
c_outer = lv.CreateContour() For i = 0 To outer_points.Length - 1 Dim p = outer_points(i) c_outer.AddPoint(lv.CreatePoint(0F, 0F, p.X, p.Y)) Next End Sub
Private Shared Sub CreateFigure2(surf As Surface, ByRef c_outer As Contour, ByRef c_inner As Contour) '' A View for the rotated ellipse. Dim view = surf.CreateView(360, 150).Translate(450, 530).Rotate(-40) Dim lv = view.LayoutView
Dim c = lv.CreateContour()
view.CreateVisual(c, False, Sub(gr As GcGraphics, vis As Visual) gr.DrawPolygon(vis.Points, Color.DeepPink, 3) End Sub)
'' 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. Dim ef As IFigure = New EllipticFigure(lv.AsRectF()) ef.Flatten() Dim points = ef.TransformedPoints Dim count = points.Length Dim list = New List(Of AnchorPoint)(count) For i = 0 To count - 1 Dim p = points(i) list.Add(lv.CreatePoint(0, 0, p.X, p.Y)) Next c.AddPoints(list)
Dim gp = New GraphicsPath(ef) Dim gp2 = gp.Widen(New GCDRAW.Pen(Color.White, 7 * 2))
Dim fig_outer = gp2.Figures(0) Dim fig_inner = gp2.Figures(1)
fig_outer.Flatten() Dim outer_points = fig_outer.TransformedPoints
c_outer = lv.CreateContour() For i = 0 To outer_points.Length - 1 Dim p = outer_points(i) c_outer.AddPoint(lv.CreatePoint(0F, 0F, p.X, p.Y)) Next
fig_inner.Flatten() Dim inner_points = fig_inner.TransformedPoints
c_inner = lv.CreateContour() For i = 0 To inner_points.Length - 1 Dim p = inner_points(i) c_inner.AddPoint(lv.CreatePoint(0F, 0F, p.X, p.Y)) Next End Sub
Private Shared ReadOnly FormatBox As TextFormat = New TextFormat() With { .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeSans.ttf")), .FontSize = 14, .FontSizeInGraphicUnits = True, .ForeColor = BoxColor }
Private Shared ReadOnly FormatDesc As TextFormat = New TextFormat(FormatBox) With { .FontSize = 12, .ForeColor = DescColor }
Private Shared ReadOnly FormatCaption As TextFormat = New TextFormat(FormatDesc) With { .FontBold = True }
Private Shared ReadOnly FormatCode As TextFormat = New TextFormat(FormatDesc) With { .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeMono.ttf")), .ForeColor = CodeColor }
Private Shared Sub DrawView(g As GcGraphics, v As Visual) Dim rect = v.AsRectF() g.FillRectangle(rect, Color.FromArgb(31, 82, 100)) g.DrawRectangle(rect, New GCDRAW.Pen(Color.FromArgb(200, 200, 200), 1) With { .DashPattern = New Single() {7, 3} }) Dim fc = TryCast(v.Tag, FigureCaption) If fc IsNot Nothing Then Dim tl = g.CreateTextLayout() tl.Append($"Figure {fc.Number}. ", FormatCaption) tl.AppendLine(fc.Description, FormatDesc) If fc.Code IsNot Nothing Then tl.Append(fc.Code, FormatCode) End If g.DrawTextLayout(tl, New PointF(0, v.Height + 5)) End If End Sub
Private Shared Sub DrawVertGuideline(g As GcGraphics, v As Visual) g.DrawLine(New PointF(0, 0), New PointF(0, v.Height), New GCDRAW.Pen(BoxColor, 1) With { .DashPattern = New Single() {1, 2} }) Dim s = TryCast(v.Tag, String) If s IsNot Nothing Then Dim tl = g.CreateTextLayout() tl.Append(s, FormatDesc) tl.PerformLayout() Dim 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)) End If End Sub
Private Shared Sub DrawRect(g As GcGraphics, v As Visual) Dim rect = v.AsRectF() g.FillRectangle(rect, RectColor) g.DrawRectangle(rect, New GCDRAW.Pen(BoxColor, 1)) Dim s = TryCast(v.Tag, String) If s IsNot Nothing Then Dim 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)) End If End Sub
Private Shared Sub DrawLineWithLeftArrow(g As GcGraphics, v As Visual) Dim 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) End Sub
Private Shared Sub DrawLineWithRightArrow(g As GcGraphics, v As Visual) Dim 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) End Sub
Private Shared Sub DrawLeftRightLines(g As GcGraphics, v As Visual) Dim 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) End Sub
Private Shared Sub DrawVertLineWithLeftArrow(g As GcGraphics, v As Visual) Dim 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) End Sub
Private Shared Sub DrawLineWithUpArrow(g As GcGraphics, v As Visual) Dim 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) End Sub
Private Shared Sub DrawLeftArrow(g As GcGraphics, x As Single, y As Single) Dim 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) End Sub
Private Shared Sub DrawRightArrow(g As GcGraphics, x As Single, y As Single) Dim 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) End Sub
Private Shared Sub DrawUpArrow(g As GcGraphics, x As Single, y As Single) Dim 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) End SubEnd Class