does this declare no longer work?
[Mojave, Xojo2019R1.1]
I have checked, and it is calling it with correct values, but still returns a solid line
does this declare no longer work?
[Mojave, Xojo2019R1.1]
I have checked, and it is calling it with correct values, but still returns a solid line
Could you post the declare? The API method is not deprecated. I would suspect a 32Bit style declare, using singles instead of CGFloats.
single is wrong!
CGFloat is only single on 32-bit.
Sorry, itās late.
CGFloat in C is CGFloat in Xojo. Have fun!
Yes, and the array of lengths should be an array of CGFloats too. If you change these, the declare should work again.
EDIT: And size_t is a variable size datatype too:
https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/64bitPorting/transition/transition.html
still doesnāt work in 64bit, but does in 32bit
#If TargetCocoa Then
#If Target32Bit /// **** ADDED THIS
Const sizeOfSingle = 4
#Else
Const sizeOfSingle = 8
#EndIf
// ************************** //
// ** Cocoa Pattern Line ** //
// ************************** //
'
Declare Sub CGContextSetLineDash Lib "Cocoa" ( context As Integer, phase As CGFloat, lengths As Ptr, count As UInt32) // *** CHANGED THIS TO CGFLOAT
'
x=g.penwidth
dash=x*3
dot=x
spc=dot
g.AntiAlias=False
Select Case pattern
Case DashStyleDot
lengths=Array(dot,spc) ' dotted line [.......]
Case DashStyleDash
lengths=Array(dash,spc) ' dashed line [- - - -]
End Select
//
lengthArray=New MemoryBlock(sizeOfSingle*(1 + UBound(lengths)))
For i = 0 To UBound(lengths)
lengthArray.SingleValue(offset) = lengths(i)
offset = offset + sizeOfSingle
Next
CGContextSetLineDash g.handle( g.HandleTypeCGContextRef ),0,lengthArray,lengths.Ubound+1
//
g.drawline x1,y1,x2,y2
//
CGContextSetLineDash g.handle( g.HandleTypeCGContextRef ),0,Nil,0 ' solid line
//
g.AntiAlias=aa_flag
Change Count to UInteger and
[quote=459280:@Dave S] lengthArray=New MemoryBlock(sizeOfSingle*(1 + UBound(lengths)))
For i = 0 To UBound(lengths)
lengthArray.SingleValue(offset) = lengths(i)
offset = offset + sizeOfSingle
Next[/quote]
Adapt this code to CGFloat (Doubles for 64 Bit) instead of singles.
Solved it⦠thanksā¦
Public Sub drawDashedLine(g as graphics, x1 as integer, y1 as integer, x2 as integer, y2 as integer, pattern as integer = 0, scale as integer = -1)
Const fake_it As Boolean=False
Const DashStyleSolid = 0
Const DashStyleDash = 1
Const DashStyleDot = 2
Dim dash As CGFloat
Dim spc As CGFloat
Dim i As Integer
Dim lengths(-1) As CGFloat
Dim lengthArray As MemoryBlock
Dim offset As Integer = 0
Dim aa_flag As Boolean=g.AntiAlias
If scale<1 Then scale=g.scaleX
x1=x1*scale
y1=y1*scale
x2=x2*scale
y2=y2*scale
If pattern<=DashStyleSolid Then
// ** Solid Line is same regardless of Platform ** /
g.drawline x1,y1,x2,y2
Exit Sub
Else
Select Case pattern ' dotted line [.......]
Case DashStyleDot
dash=1
spc=3
Case DashStyleDash 'lengths=Array(dash,spc) ' dashed line [- - - -]
dash=5
spc=5
End Select
//
//
#If TargetCocoa Then
Declare Sub CGContextSetLineDash Lib "Cocoa" ( context As Integer, phase As CGFloat, lengths As Ptr, count As UInt32)
#If Target32Bit
Const sizeOfSingle = 4
#Else
Const sizeOfSingle = 8
#EndIf
g.AntiAlias=False
lengths=Array(dash,spc)
//
lengthArray=New MemoryBlock(sizeOfSingle*(1 + UBound(lengths)))
For i = 0 To UBound(lengths)
#If Target32Bit
lengthArray.SingleValue(offset) = lengths(i)
#Else
lengthArray.DoubleValue(offset) = lengths(i)
#EndIf
offset = offset + sizeOfSingle
Next
//
CGContextSetLineDash g.handle( g.HandleTypeCGContextRef ),0,lengthArray,lengths.Ubound+1
//
g.drawline x1,y1,x2,y2
// return graphic context to original state
CGContextSetLineDash g.handle( g.HandleTypeCGContextRef ),0,Nil,0 ' solid line
g.AntiAlias=aa_flag
#EndIf
End If
End Sub
seems memoryblock needs a ā.CGFloatValue(offset)ā
well⦠it worked, but it didnāt
seems it drew the correct line styles⦠but it totally screwed any other routines that tried to draw on that same āgā⦠it pushed everything down 670 px. I comment out all calls to the above routine, and it works fine again
nope doesnāt work⦠even in 32bit now
once it gets called once⦠The āYā coodinate of any other calls is pushed down
I donĀt see how it could be doing this. But if it is the case, saving the graphics state and pulling it back when you leave the dash routine should fix it if there is no other influence on your drawing properties hidden somewhere.
me either⦠but it does, and I know it is the declare call, as commenting it out āfixesā that particular issue
The question here is⦠how to do that⦠as the āstateā isnāt something this is a standard Xojo property, at least not in this case, because if it were, then we would have been able to determine what happened
So from what you can see, I made ALL the required 64bit updates⦠although now it seems to fail in the same manner for 32bit too
I wonder if the drawing code in the call messes up the underlying CG context (or whatever it is that graphics.handle refers to in this case) So that then has follow on side effects
If so I doubt that saving Xojoās graphics properties will have any significant impact since none includes anything like a ācurrent drawing X and Yā
that said hereās mine
Module GraphicsExtensions
Class GraphicsSavedState
AntiAlias As boolean
AntiAliasMode As graphics.AntiAliasModes
Bold As boolean
CharacterSpacing As Integer
ForeColor As Color
Italic As boolean
PenHeight As Double
PenWidth As Double
ScaleX As Double
ScaleY As Double
TextFont As String
TextUnit As FontUnits
Underline As Boolean
End Class
Public Function State(extends g as Graphics) as GraphicsSavedState
Dim state As New GraphicsExtensions.GraphicsSavedState
state.AntiAlias = g.AntiAlias
state.AntiAliasMode = g.AntiAliasMode
state.bold = g.Bold
state.CharacterSpacing = g.CharacterSpacing
state.ForeColor = g.ForeColor
state.Italic = g.Italic
state.PenHeight = g.PenHeight
state.PenWidth = g.PenWidth
state.ScaleX = g.ScaleX
state.ScaleY = g.ScaleY
state.TextFont = g.TextFont
state.TextSize = g.TextSize
state.TextUnit = g.TextUnit
state.Underline = g.Underline
Return state
End Function
Public Sub State(extends g as Graphics, assigns savedState as GraphicsSavedState)
g.AntiAlias = savedState.AntiAlias
g.AntiAliasMode = savedState.AntiAliasMode
g.Bold = savedState.bold
g.CharacterSpacing = savedState.CharacterSpacing
g.ForeColor = savedState.ForeColor
g.Italic = savedState.Italic
g.PenHeight = savedState.PenHeight
g.PenWidth = savedState.PenWidth
g.ScaleX = savedState.ScaleX
g.ScaleY = savedState.ScaleY
g.TextFont = savedState.TextFont
g.TextSize = savedState.TextSize
g.TextUnit = savedState.TextUnit
g.Underline = savedState.Underline
End Sub
End Module
@Norman: I agree, an y offset sounds rather like the transform property not being identity.
@Dave: That would be https://developer.apple.com/documentation/coregraphics/1456156-cgcontextsavegstate and -restoregstate.
CG context save state and restore seems the right thing to do
However it didnāt help
#If TargetCocoa Then
Declare Sub CGContextSaveGState Lib "Cocoa" ( context As Integer)
Declare Sub CGContextRestoreGState Lib "Cocoa" ( context As Integer)
Declare Sub CGContextSetLineDash Lib "Cocoa" ( context As Integer, phase As CGFloat, lengths As Ptr, count As UInt32)
Dim context As Integer = g.handle( g.HandleTypeCGContextRef )
#If Target32Bit
Const sizeOfSingle = 4
#Else
Const sizeOfSingle = 8
#EndIf
g.AntiAlias=False
lengths=Array(dash,spc)
//
lengthArray=New MemoryBlock(sizeOfSingle*(1 + UBound(lengths)))
For i = 0 To UBound(lengths)
#If Target32Bit
lengthArray.SingleValue(offset) = lengths(i)
#Else
lengthArray.DoubleValue(offset) = lengths(i)
#EndIf
offset = offset + sizeOfSingle
Next
//
CGContextSaveGState context
CGContextSetLineDash context,0,lengthArray,lengths.Ubound+1
//
g.drawline x1,y1,x2,y2
// return graphic context to original state
CGContextRestoreGState context
//CGContextSetLineDash context,0,Nil,0 ' solid line
g.AntiAlias=aa_flag
#EndIf
The issue is actually caused by THIS LINE
Dim context As Integer = g.handle( g.HandleTypeCGContextRef )
This is what is SHOULD LOOK LIKE
This is what I get if the CGContext lines are active
Note the first call to the declare happens right after that FIRST white box is drawn
Also⦠ONLY on an RETINA screen⦠moving the window to a NON-RETINA screen restores it properly
I remember some problems when mixing CGContext calls with Xojo graphics methods Ā some API calls seem to be overwritten by Xojo draw commands.
I cannot guarantee for it, but I would try to use CGContextStrokeLinesegments (which is a lot faster than single drawlines) or a similar CGContext line drawing command. Remember to invert the y axis before.
Thanks Ulrich⦠but the issue seems to stem from just getting the CONTEXT pointer
if I comment all but this
Dim context As Integer = g.handle( g.HandleTypeCGContextRef )
if still fails
#If TargetCocoa Then
Dim context As Integer = g.handle( g.HandleTypeCGContextRef )
g.AntiAlias=False
g.drawline x1,y1,x2,y2
g.AntiAlias=aa_flag
#EndIf
IĀm out. Not that I wouldnĀt believe you or would not like to help you. Just donĀt have any idea how that could mess up things. Sorry!