Dash Dot Line

How can i draw a dashdot line ??

what platform?
Somewhere I have declares for doing this in Cocoa for OSX

of course the “easy” way is to draw your own pattern using FOR/NEXT and short drawlines
but the doesn’t work well for curves

The platform is Windows and Mac

I can’t remember who it was that gave me the following code but it seems to work fine (for Mac):

[code]SUB myLineStyle(g as graphics,pattern_id as integer=0)

Dim lengths(-1) As Double
Dim x As Integer = g.penwidth
Dim lengthArray As MemoryBlock
Declare Sub CGContextSetLineDash Lib “Cocoa” ( context As Integer, phase As Single, lengths As Ptr, count As UInt32)

Select Case pattern_id
case -1
lengths=Array(x4.,x4.) ’ for lasso
Case 1
lengths=Array(Ceil(x/2.),x2.) ’ dotted line […]
Case 2
8.,x4.) ’ dashed line [- - - -]
Case 3
6.,x3.,Ceil(x/2.),x3.) ’ dashed dot dash line [- . -]
case 4
lengths=Array(x6.,x3.,Ceil(x/2.),x3.,Ceil(x/2.),x3.) ’ dashed dot dot line [-…-…]
End Select

If UBound(lengths) > -1 Then
lengthArray= CFloatArray(lengths)
If lengthArray Is Nil Then exit sub
CGContextSetLineDash g.handle( g.HandleTypeCGContextRef ), 0,lengthArray,lengths.Ubound+1
CGContextSetLineDash g.handle( g.HandleTypeCGContextRef ),0, Nil, 0 ’ solid line
End If


’ Supporting function

FUNCTION CFLoatArray(theList() as double) as MemoryBlock

If theList.UBound = -1 Then Return Nil

Const sizeOfSingle = 4
Dim theArray As New MemoryBlock(sizeOfSingle*(1 + UBound(theList)))
Dim offset As Integer = 0

For i As Integer = 0 To UBound(theList)
theArray.SingleValue(offset) = theList(i)
offset = offset + sizeOfSingle

Return theArray

I don’t know the declares for Windows, sorry.


I can tell you exactly who gave that to you :slight_smile:
It was me.

Sorry Dave. It was a while ago and I stored it in my Dash Snippets.

Thank you, it does work.


Thanks Dave and Simon,
i wil try out.

[quote=231585:@Simon Berridge]Sorry Dave. It was a while ago and I stored it in my Dash Snippets.

Thank you, it does work.

No worries… If I thought it was propriatey I wouldn’t have published it in the first place :smiley:


In theory, the same approach can be taken in Windows, but using different declares, if using GDI+

MSDN has this:

[i]GDI+ provides several dash styles that are listed in the DashStyle enumeration. If those standard dash styles do not suit your needs, you can create a custom dash pattern.

To draw a custom dashed line, put the lengths of the dashes and spaces in an array and assign the array as the value of the DashPattern property of a Pen object. The following example draws a custom dashed line based on the array {5, 2, 15, 4}. If you multiply the elements of the array by the pen width of 5, you get {25, 10, 75, 20}. The displayed dashes alternate in length between 25 and 75, and the spaces alternate in length between 10 and 20.
The following illustration shows the resulting dashed line. Note that the final dash has to be shorter than 25 units so that the line can end at (405, 5).[/i]

Dim dashValues As Single() = {5, 2, 15, 4} Dim blackPen As New Pen(Color.Black, 5) blackPen.DashPattern = dashValues e.Graphics.DrawLine(blackPen, New Point(5, 5), New Point(405, 5))

I havent dug out the declares for this yet…

I cannot find a “Pen” object.

I don’t think it is possible to operate the code you posted.


I have some code that works and does not use declares so should be Xplatform . It goes back to 2009. Over the years I kind of went overboard on it feature wise .

I updated it to work in the current version of Xojo earlier this year and branded the demo with the intention to release it as open source… But the code needs to be cleaned up and documentation updated/finished.

You can see what it does here:

if interested I can send it to you it as is.

  • Karen

I would also be interested in your code Karen, if you don’t mind?

Me, too, Karen, please.

[quote]I cannot find a “Pen” object.
I don’t think it is possible to operate the code you posted.[/quote]

Thats not Xojo code.
It all relies on objects and declares from Windows API.

I’m also interested in your code.

Thanks in advance.

A few words of warning. I’m not sure i should have offered it…

First for the type of styles that you can get wit declares, using declares will always look better and be faster…

You also need to use the supplied editors to create and save any line style, even simple ones (unless you add a method for that)…so I suspect most would not find it convenient to use.

The styles need to be saved as files or copied to the clipboard to be put into a string constant to assign in code. They editing dialog can be include in your apps if need be.

The documentation is very partial, was never completed and in some parts may be outdated…

All the support for creating and saving hierarchical line style pallets works… but is not documented.

The demo code is reasonable extensive but was written for testing rather than clarity… and I have not tested this in 64bit.

I wanted to get all that into good shape before releasing it… I put the page on my website with that in mind… But I never seem to find the time…

As I don’t know when I can get back t it to do it right, if people still want to with all those caveats, I can put it up on my website sometime in the next day or two.

  • karen

Here’s my Bezo class for drawing bezier curves of any number of control points, with a dash pattern, and optionally a dashed polygon. All Xojo so cross platform. The polygon drawing is stand alone so that’s pasted below.

Call it like this. Should be easy to modify parameters to suit and/or make a drawDashedLine.

g.PenWidth = 3 dim pntsX() As Double = Array(50.0, 200, 180, 50) dim pntsY() As Double = Array(50.0, 50, 300, 150) dim dashes() As Double = Array(20.0, 10, 30, 10, 20, 10) drawDashedPolygon(g, pntsX, pntsY, dashes)

[code]Shared Sub drawDashedPolygon(g As Graphics, xpos() As double, ypos() As double, dashes() As Double)
#pragma DisableBackgroundTasks
#pragma DisableBoundsChecking
#pragma NilObjectChecking false
#pragma StackOverflowChecking false

if dashes.Ubound = -1 then dashes = Array(100.0, 0.0) //fix dashes() if no elements

//tracking vars
dim dashIsOn As boolean = true //treat first dashes() element as dash ON
dim curDashIdx As integer = 0 //current index into dashes()
dim dashCount As integer = dashes.Ubound + 1 //for wrapping curDashIdx
dim x0, y0, x1, y1, vx, vy, tx0, ty0, tx1, ty1 As double //endpoints and vectors
dim xDiff, yDiff, segDist As double //temps
dim dashSum As Double = dashes(curDashIdx)

x0 = xpos(0)
y0 = ypos(0)

for i As integer = 1 to xpos.Ubound

x1 = xpos(i)
y1 = ypos(i)

xDiff = x1 - x0   //measure and sum distance
yDiff = y1 - y0
segDist = Sqrt(xDiff * xDiff + yDiff * yDiff)

if dashSum > segDist then   //whole segment is a single dash
  if dashIsOn then g.DrawLine(x0, y0, x1, y1)   //draw if on
  dashSum = dashSum - segDist   //remove the expanse of dash 'drawn'
else     //draw dash portions along this segment
  vx = (x1 - x0) / segDist   //get unit vector from p0 to p1
  vy = (y1 - y0) / segDist
  tx0 = x0
  ty0 = y0
  while dashSum < segDist
    tx1 = x0 + vx * dashSum   //calc endpoint of dash
    ty1 = y0 + vy * dashSum
    if dashIsOn then g.DrawLine(tx0, ty0, tx1, ty1)
    curDashIdx = (curDashIdx + 1) mod dashCount   //step to next dash 1
    dashIsOn = not dashIsOn   //step to next dash 2
    dashSum = dashSum + dashes(curDashIdx)   //step to next dash 3
    tx0 = tx1
    ty0 = ty1
  //at dash that spans the segment endpoint (ie dashSum > segDist)
  if dashIsOn then g.DrawLine(tx0, ty0, x1, y1)
  dashSum = dashSum - segDist   //remove segDist from dashSum for next segment

x0 = x1 //roll coords
y0 = y1


End Sub[/code]

Will, would you mind if use your code in the open source DrawSVG project?

All the basics for drawing SVG images are now in place, and I’m getting to the more advanced stuff like dashed lines now, so your code couldn’t have come at a better time.

I will give you full credit where I use your code.

I am still interested Karen, even with the caveats.

What interest me most about your code is how you drew the end-points of the lines. That is something I need to implement in the above mentioned SVG project, and your code would be a great help. Would you mind if I used some of your code in the SVG project. Like Will, I will give you full credit where I do.