Swift : pass clip area from a CGContext

I have a UIView with a Draw(rect) function. inside that function I need to select a smaller rectangle area and pass it to another routine (think cellBackgroundPaint in a Listbox)

I can pass the CGContext of the entire UIView, but I’d like to “clip” an area and pass a smaller context
The problem is the upper left corner is relative to the entire view unless I can do this… which makes things a bit more difficult for the end -user

So if the area from the main view is (100,100,500,50) then I’d like the other routine to be able to treat it as (0,0,500,50)

CGContextClip (or one of the others)
but then it seems you want a new context from that clipped path so 0,0 is top left ?

all those “clip” functions do is limit the area that is affected during “Draw”… the upper/left coordinate of the clip area is still relative to the whole area…

My work around is to pass one more argument (the actual “clip” rect) so the user can adjust things as required

  if parent.cellBackgroundPaint(g:context,rect:r, row: yRow, column: xCol)==false {

Exactly why I noted in my reply

but then it seems you want a new context from that clipped path so 0,0 is top left ?

but I have no idea how you would do that or if its possible

@samRowlands might

Use a transform and a clip

Ok… still not seeing as how that can work… Clip does NOT make a new context…

if you have a view of 0,0,1000,1000 and clip (100,100,100,100)
then draw a line from 0,0,1000,1000 the line only appears within the clip area.

but 0,0 is not INSIDE, and there is nothing to “transform”

unless I am really missing something here

transform

basically you can “move” the clip area so its top left is 0,0
do a bunch of drawing - all relative to 0,0
then transform it back

ok… THIS seems to work… if anyone can improve upon it, PLEASE :slight_smile:

values known going into this code

xCol,yRow : coordinates of cell within datastore
xPos,yPos : coordinates of cell within drawing area
w,h : Size of cell in pixels

// get cell contents at [xCol,yRow]
let cell = getCell(at:cellPos(x:xCol,y: yRow))

// create a Rect of the cell SIZE
let r = CGRect(origin: CGPoint.zero, size: CGSize(width:w,height:h))

context.saveGState() // save current graphic state
context.translateBy(x: xPos, y: yPos) // move the origin of context to cell postion
context.clip(to:r) // clip drawing area to only the area covered by the cell
//
// do the drawing [system and/or user defined]
//
if parent.cellBackgroundPaint(g:context, row: yRow, column: xCol)==false {}
if parent.cellTextPaint(g:context, rect:r,row: yRow, column: xCol)==false {
    displayText(r,cell.text,textFont,textColor: zTextColor,align: cellAlign(yRow, xCol))
}
//
//
//
context.resetClip() // remove clip constratnts
context.restoreGState() // restore previous state (which undoes translate)

only issue is the user code must do this

let r=g.boundingBoxOfClipPath

in order to get the cell size from the “g” context

this solves the user have to determine size


extension CGContext {
    var size   : CGSize { return self.boundingBoxOfClipPath.size }
    var width  : CGFloat { return size.width }
    var height : CGFloat { return size.height }
}

CGContext cannot be subclassed, but it seems it CAN be extended