D2PathGeometry, D2GeometrySink and D2Sink_FillMode

Requires: Direct2D.lg32

Purpose

Creates a path geometry Direct2D object and a geometry sink to populate the geometry.

Syntax

Set geoObj = D2PathGeometry()
Set geoSink = D2GeometrySink(geoObj [,fFillWinding])
D2Sink_FillMode geoSink, fillMode

geoObj, geoSink: Object
fFillWinding: bool exp
fillMode: iexp

Description

Direct2D geometries enable you to describe two-dimensional figures, cache them and lateron draw them using D2DrawGeometry and/or D2FillGeometry. The D2PathGeometry function creates a path geometry to collect a series of figures that describe the geometry. To populate a path geometry a geometry sink (ID2D1GeometrySink) is created by passing in the geometry object:

Set geoSink = D2GeometrySink(geoObj)

An ID2D1GeometrySink consists of one or more figures and describes a geometric path that can contain lines, arcs, cubic Bezier curves, and quadratic Bezier curves. The D2GeometrySink function is used to open a sink for the geometry and (usually) these functions are used in pairs. The fill mode of the sink defaults to D2D1_FILL_MODE_ALTERNATE. To set the fill mode, specify True for the optional parameter fFillWinding, or call D2Sink_FillMode before the first call to D2Sink_BeginFigure. The fill mode specifies the method used to determine which points are inside the geometry described by this geometry sink and which points are outside.

To create a figure the application needs to a call a series of D2Sink_* commands. Call the D2Sink_BeginFigure command, passing in the figure's starting point, and then use the D2Sink_Add* commands (such as D2Sink_AddLine(s) and D2Sink_AddBezier) to add segments. When you are finished adding segments, call the D2Sink_EndFigure command. You can repeat this sequence to create additional figures. When you are finished creating figures, call the D2Sink_Close command.

The example shows the GFA-BASIC 32 implementation of the SDK mountain-scenery example found at: Path Geometries Overview - Win32 apps | Microsoft Docs.

Example

'

' D2PathGeometry sample (dpi-unaware)

' GB32 implementation of

' https://docs.microsoft.com/en-us/windows/win32/direct2d/path-geometries-overview

'

$Library "direct2d"

Global Object Win1RT

OpenW 1, 0, 0, 720, 460, ~15

Set Win1RT = D2GetRT()   ' DC render target

' Create the geometry's for scenery

Global Object LeftMountainGeometry, RightMountainGeometry, _

SunGeometry, RiverGeometry, _

RadialGradientBrush

DefScenery()

Do

Sleep

Until Me Is Nothing

 

Sub Win_1_Paint

D2BeginDraw Win1RT, D2C_Wheat

' Draw sun

D2FillGeometry SunGeometry, RadialGradientBrush

D2DrawGeometry SunGeometry

' Draw left mountain

D2DefFill D2C_OliveDrab

D2FillGeometry LeftMountainGeometry

D2DrawGeometry LeftMountainGeometry

' Draw river

D2DefFill D2C_LightSkyBlue

D2FillGeometry RiverGeometry

D2DrawGeometry RiverGeometry

' Draw right mountain

D2DefFill D2C_YellowGreen

D2FillGeometry RightMountainGeometry

D2DrawGeometry RightMountainGeometry

D2EndDraw

EndSub

 

Sub Win_1_ReSize

D2ResizeRT Win1RT, _X, _Y

EndSub

 

Procedure DefScenery()

Local Object Sink          ' released when it goes out-of-scope

Local points(0 .. 6) As D2D1_POINT_2F

Local arcSeg As D2D1_ARC_SEGMENT

Local bezier As D2D1_BEZIER_SEGMENT

' Left mountain

Set LeftMountainGeometry = D2PathGeometry()

Set Sink = D2GeometrySink(LeftMountainGeometry)

D2Sink_FillMode Sink, D2D1_FILL_MODE_WINDING

D2Sink_BeginFigure Sink, 346, 255  ' first point, D2FillGeometry will fill

points(0).x = 267, points(0).y = 177

points(1).x = 236, points(1).y = 192

points(2).x = 212, points(2).y = 160

points(3).x = 156, points(3).y = 255

points(4).x = 346, points(4).y = 255

D2Sink_AddLines Sink, points(), 5

D2Sink_EndFigure Sink, D2D1_FIGURE_END_CLOSED

D2Sink_Close Sink

' Right mountain

Set RightMountainGeometry = D2PathGeometry()

Set Sink = D2GeometrySink(RightMountainGeometry)

D2Sink_FillMode Sink, D2D1_FILL_MODE_WINDING

D2Sink_BeginFigure Sink, 575, 263 ' first point, D2FillGeometry will fill

points(0).x = 481, points(0).y = 146

points(1).x = 449, points(1).y = 181

points(2).x = 433, points(2).y = 159

points(3).x = 401, points(3).y = 214

points(4).x = 381, points(4).y = 199

points(5).x = 323, points(5).y = 263

points(6).x = 575, points(6).y = 263

D2Sink_AddLines Sink, points(), 7

D2Sink_EndFigure Sink, D2D1_FIGURE_END_CLOSED

D2Sink_Close Sink

' Sun with flares

Set SunGeometry = D2PathGeometry()

Set Sink = D2GeometrySink(SunGeometry)

D2Sink_FillMode Sink, D2D1_FILL_MODE_WINDING

' Sun

D2Sink_BeginFigure Sink, 270, 255 ' first point, D2FillGeometry will fill

arcSeg.point.x = 440, arcSeg.point.y = 255

arcSeg.size.width = 85, arcSeg.size.height = 85

arcSeg.rotationAngle = 0.0

arcSeg.sweepDirection = D2D1_SWEEP_DIRECTION_CLOCKWISE

arcSeg.arcSize = D2D1_ARC_SIZE_SMALL

D2Sink_AddArc Sink, arcSeg

D2Sink_EndFigure Sink, D2D1_FIGURE_END_CLOSED

' Flares

D2Sink_BeginFigure Sink, 299, 182, D2D1_FIGURE_BEGIN_HOLLOW

bezier.point1.x = 299, bezier.point1.y = 182

bezier.point2.x = 294, bezier.point2.y = 176

bezier.point3.x = 285, bezier.point3.y = 178

D2Sink_AddBezier Sink, bezier

bezier.point1.x = 276, bezier.point1.y = 179

bezier.point2.x = 272, bezier.point2.y = 173

bezier.point3.x = 272, bezier.point3.y = 173

D2Sink_AddBezier Sink, bezier

D2Sink_EndFigure Sink

D2Sink_BeginFigure Sink, 354, 156, D2D1_FIGURE_BEGIN_HOLLOW

bezier.point1.x = 354, bezier.point1.y = 156

bezier.point2.x = 358, bezier.point2.y = 149

bezier.point3.x = 354, bezier.point3.y = 142

D2Sink_AddBezier Sink, bezier

bezier.point1.x = 349, bezier.point1.y = 134

bezier.point2.x = 354, bezier.point2.y = 127

bezier.point3.x = 354, bezier.point3.y = 127

D2Sink_AddBezier Sink, bezier

D2Sink_EndFigure Sink

D2Sink_BeginFigure Sink, 322, 164, D2D1_FIGURE_BEGIN_HOLLOW

bezier.point1.x = 322, bezier.point1.y = 164

bezier.point2.x = 322, bezier.point2.y = 156

bezier.point3.x = 314, bezier.point3.y = 152

D2Sink_AddBezier Sink, bezier

bezier.point1.x = 306, bezier.point1.y = 149

bezier.point2.x = 305, bezier.point2.y = 141

bezier.point3.x = 305, bezier.point3.y = 141

D2Sink_AddBezier Sink, bezier

D2Sink_EndFigure Sink

D2Sink_BeginFigure Sink, 385, 164, D2D1_FIGURE_BEGIN_HOLLOW

bezier.point1.x = 385, bezier.point1.y = 164

bezier.point2.x = 392, bezier.point2.y = 161

bezier.point3.x = 394, bezier.point3.y = 152

D2Sink_AddBezier Sink, bezier

bezier.point1.x = 395, bezier.point1.y = 144

bezier.point2.x = 402, bezier.point2.y = 141

bezier.point3.x = 402, bezier.point3.y = 142

D2Sink_AddBezier Sink, bezier

D2Sink_EndFigure Sink

D2Sink_BeginFigure Sink, 408, 182, D2D1_FIGURE_BEGIN_HOLLOW

bezier.point1.x = 408, bezier.point1.y = 182

bezier.point2.x = 416, bezier.point2.y = 184

bezier.point3.x = 422, bezier.point3.y = 178

D2Sink_AddBezier Sink, bezier

bezier.point1.x = 428, bezier.point1.y = 171

bezier.point2.x = 435, bezier.point2.y = 173

bezier.point3.x = 435, bezier.point3.y = 173

D2Sink_AddBezier Sink, bezier

D2Sink_EndFigure Sink

D2Sink_Close Sink

' River

Set RiverGeometry = D2PathGeometry()

Set Sink = D2GeometrySink(RiverGeometry)

D2Sink_FillMode Sink, D2D1_FILL_MODE_WINDING

D2Sink_BeginFigure Sink, 183, 392

bezier.point1.x = 238, bezier.point1.y = 284

bezier.point2.x = 472, bezier.point2.y = 345

bezier.point3.x = 356, bezier.point3.y = 303

D2Sink_AddBezier Sink, bezier

bezier.point1.x = 237, bezier.point1.y = 261

bezier.point2.x = 333, bezier.point2.y = 256

bezier.point3.x = 333, bezier.point3.y = 256

D2Sink_AddBezier Sink, bezier

bezier.point1.x = 335, bezier.point1.y = 257

bezier.point2.x = 241, bezier.point2.y = 261

bezier.point3.x = 411, bezier.point3.y = 306

D2Sink_AddBezier Sink, bezier

bezier.point1.x = 574, bezier.point1.y = 350

bezier.point2.x = 288, bezier.point2.y = 324

bezier.point3.x = 296, bezier.point3.y = 392

D2Sink_AddBezier Sink, bezier

D2Sink_EndFigure Sink

D2Sink_Close Sink

' Create a GradientBrush for the sun geoemetry

Local GS(1 .. 2) As D2Gradient          ' the stop collection

GS(1).position = 0.0                    ' beginning of gradient is yellow

GS(1).argbcolor = D2C_Yellow

GS(2).position = 1.0                    ' end of gradient is orange

GS(2).argbcolor = D2C_Orange

' Create a gradientbrush that fits in the sun circle.

' axis's starting point is center (340,255) and offset (0, 20)

' opacity = 1 and radius of circle is 85, 85

Set RadialGradientBrush = D2BrushGradient(1, GS(), 2, 340, 255, 0, 20, 1, 85, 85)   ' gradient axis

EndProc

Remarks

For more information on Direct2D geometries go to Geometries - Win32 apps .

The D2GeometrySink function calls the ID2D1PathGeometry::Open method see: ID2D1PathGeometry::Open (d2d1.h) - Win32 apps .

More info on fill mode: ID2D1SimplifiedGeometrySink::SetFillMode (d2d1.h) - Win32 apps, an example can be found in D2Sink_AddLines topic.

See Also

D2DrawGeometry, D2FillGeometry, D2Sink_BeginFigure, D2Sink_EndFigure, D2Sink_Close, D2Sink_Fillmode, D2Sink_AddLines, D2Sink_AddArc, D2Sink_AddBezier, D2Sink_AddQuadraticBezier.

{Created by Sjouke Hamstra; Last updated: 11/03/2021 by James Gaite}