Cocoa: canvas DC copy improvement

This commit is contained in:
Matthew Flatt 2015-11-24 15:01:25 -07:00
parent 3873064c80
commit 33395ae1cf
3 changed files with 28 additions and 28 deletions

View File

@ -29,6 +29,7 @@
(define-appserv CGContextAddRect (_fun _CGContextRef _NSRect -> _void))
(define-appserv CGContextAddLines (_fun _CGContextRef (v : (_vector i _NSPoint)) (_long = (vector-length v)) -> _void))
(define-appserv CGContextStrokePath (_fun _CGContextRef -> _void))
(define-appserv CGContextClipToRect (_fun _CGContextRef _NSRect -> _void))
(define-appserv CGContextClipToRects (_fun _CGContextRef (_vector i _NSRect) _size -> _void))
(define-appserv CGContextSetAlpha (_fun _CGContextRef _CGFloat -> _void))

View File

@ -211,13 +211,7 @@
(cairo_matrix_t-y0 m)))
(cairo_surface_flush s)
(define cg (cairo_quartz_surface_get_cg_context s))
(begin
;; A Cairo flush doesn't reset the clipping region. The
;; implementation of clipping is that there's a saved
;; GState that we can use to get back to the original
;; clipping region, so restore (and save again) that state:
(CGContextRestoreGState cg)
(CGContextSaveGState cg))
(reset-cairo-clipping cg)
(CGContextSaveGState cg)
(CGContextConcatCTM cg trans)
(let ([n (cairo_rectangle_list_t-num_rectangles rs)])
@ -251,28 +245,29 @@
(define cg (cairo_quartz_surface_get_cg_context s))
(define orig-size (CGLayerGetSize layer))
(atomically
(begin
;; A Cairo flush doesn't reset the clipping region. The
;; implementation of clipping is that there's a saved
;; GState that we can use to get back to the original
;; clipping region, so restore (and save again) that state:
(CGContextRestoreGState cg)
(CGContextSaveGState cg))
(define new-layer (CGLayerCreateWithContext cg (make-NSSize w h) #f))
(define new-cg (CGLayerGetContext new-layer))
(CGContextTranslateCTM new-cg 0 h)
(CGContextScaleCTM new-cg 1 -1)
(CGContextScaleCTM cg bs bs)
(CGContextDrawLayerAtPoint new-cg
(make-NSPoint (- x) (- (- (NSSize-height orig-size) y h)))
layer)
(reset-cairo-clipping cg)
(CGContextSaveGState cg)
(CGContextScaleCTM cg bs (- bs))
(define sz (CGLayerGetSize layer))
(define lh (NSSize-height sz))
(CGContextTranslateCTM cg 0 (- lh))
(CGContextClipToRect cg (make-NSRect
(make-NSPoint x2 (- lh (+ y2 h)))
(make-NSSize w h)))
(CGContextDrawLayerAtPoint cg
(make-NSPoint x2 y2)
new-layer)
(CGContextScaleCTM cg (/ bs) (/ bs))
(CGLayerRelease new-layer)
(make-NSPoint (- x2 x) (- y y2))
layer)
(CGContextRestoreGState cg)
(cairo_surface_mark_dirty s))
#t)
(define/private (reset-cairo-clipping cg)
;; A Cairo flush doesn't reset the clipping region. The
;; implementation of clipping is that there's a saved
;; GState that we can use to get back to the original
;; clipping region, so restore (and save again) that state:
(CGContextRestoreGState cg)
(CGContextSaveGState cg))
(define s-bm #f)
(define/override (get-cairo-surface)

View File

@ -988,16 +988,19 @@
[(and (new-fy . < . old-fy)
(old-fy . < . (+ new-fy vh)))
(let ([dc (get-dc)])
(begin-refresh-sequence)
(send dc copy
xmargin ymargin
vw (- (+ new-fy vh) old-fy)
xmargin (+ ymargin (- old-fy new-fy)))
(redraw vx vy
vw (- old-fy new-fy)
#t))]
#t)
(end-refresh-sequence))]
[(and (old-fy . < . new-fy)
(new-fy . < . (+ old-fy vh)))
(let ([dc (get-dc)])
(begin-refresh-sequence)
(send dc copy
xmargin (+ ymargin (- new-fy old-fy))
vw (- (+ old-fy vh) new-fy)
@ -1005,7 +1008,8 @@
(let ([d (- (+ old-fy vh) new-fy)])
(redraw vx (+ vy d)
vw (- vh d)
#t)))]
#t))
(end-refresh-sequence))]
[else (repaint)])))
(repaint)))))