/collects/racket/draw/private/bitmap-dc.rkt

http://github.com/gmarceau/PLT · Racket · 196 lines · 163 code · 31 blank · 2 comment · 34 complexity · ee1dd5bb64ab4c7fff93d99e57230a3b MD5 · raw file

  1. #lang racket/base
  2. (require racket/class
  3. ffi/unsafe/atomic
  4. "syntax.rkt"
  5. "../unsafe/cairo.rkt"
  6. "color.rkt"
  7. "bitmap.rkt"
  8. "dc.rkt"
  9. "local.rkt")
  10. (provide bitmap-dc%
  11. bitmap-dc-backend%)
  12. (define bitmap-dc-backend%
  13. (class default-dc-backend%
  14. (init [(_bm bitmap) #f])
  15. (inherit reset-cr)
  16. (define c #f)
  17. (define bm #f)
  18. (define b&w? #f)
  19. (when _bm
  20. (do-set-bitmap _bm #f))
  21. (define/override (ok?) (and c #t))
  22. (define/private (do-set-bitmap v reset?)
  23. (when c
  24. (cairo_destroy c)
  25. (set! c #f))
  26. (set! bm v)
  27. (when (and bm (send bm ok?))
  28. (set! c (cairo_create (send bm get-cairo-surface)))
  29. (set! b&w? (not (send bm is-color?)))))
  30. (define/public (internal-set-bitmap v [direct? #f])
  31. (if direct?
  32. (do-set-bitmap v #t)
  33. (call-as-atomic
  34. (lambda ()
  35. (do-set-bitmap v #t)
  36. (when c (reset-cr c))))))
  37. (define/public (internal-get-bitmap) bm)
  38. (def/override (get-size)
  39. (let ([bm bm])
  40. (values (exact->inexact (send bm get-width))
  41. (exact->inexact (send bm get-height)))))
  42. (define/override (get-cr) c)
  43. (define/override (release-cr cr) (when bm (send bm drop-alpha-s)))
  44. (define/override (end-cr) (void))
  45. (define/override (dc-adjust-smoothing s)
  46. (if b&w?
  47. 'unsmoothed
  48. s))
  49. (define/override (install-color cr c a bg?)
  50. (if b&w?
  51. (begin
  52. (cairo_set_operator cr CAIRO_OPERATOR_SOURCE)
  53. (if (or (zero? a)
  54. (zero? (color-alpha c)))
  55. (super install-color cr c a bg?)
  56. (if (if bg?
  57. ;; Background: all non-black to white
  58. (not (and (= (color-red c) 0)
  59. (= (color-green c) 0)
  60. (= (color-blue c) 0)
  61. (= (color-alpha c) 1.0)))
  62. ;; Foreground: all non-white to black:
  63. (and (= (color-red c) 255)
  64. (= (color-green c) 255)
  65. (= (color-blue c) 255)
  66. (= (color-alpha c) 1.0)))
  67. (cairo_set_source_rgba cr 1.0 1.0 1.0 0.0)
  68. (cairo_set_source_rgba cr 0.0 0.0 0.0 1.0))))
  69. (super install-color cr c a bg?)))
  70. (define/override (collapse-bitmap-b&w?) b&w?)
  71. (define/override (get-clear-operator)
  72. (if (or b&w? (send bm has-alpha-channel?))
  73. CAIRO_OPERATOR_CLEAR
  74. CAIRO_OPERATOR_OVER))
  75. (super-new)))
  76. (define black (send the-color-database find-color "black"))
  77. (define bitmap-dc%
  78. (class (dc-mixin bitmap-dc-backend%)
  79. (inherit draw-bitmap-section
  80. internal-set-bitmap
  81. internal-get-bitmap
  82. get-size
  83. get-transformation
  84. set-transformation
  85. get-smoothing
  86. set-smoothing
  87. scale
  88. get-font)
  89. (super-new)
  90. (def/override (get-gl-context)
  91. (let ([bm (internal-get-bitmap)])
  92. (and bm
  93. (send bm get-bitmap-gl-context))))
  94. (def/public (set-bitmap [(make-or-false bitmap%) v])
  95. (internal-set-bitmap v))
  96. (def/public (get-bitmap)
  97. (internal-get-bitmap))
  98. (def/public (set-pixel [real? x][real? y][color% c])
  99. (let ([s (bytes 255 (color-red c) (color-green c) (color-blue c))])
  100. (set-argb-pixels x y 1 1 s)))
  101. (def/public (get-pixel [real? x][real? y][color% c])
  102. (let-values ([(w h) (get-size)])
  103. (let ([b (make-bytes 4)])
  104. (get-argb-pixels x y 1 1 b)
  105. (send c set (bytes-ref b 1) (bytes-ref b 2) (bytes-ref b 3))
  106. (and (<= 0 x w) (<= 0 y h)))))
  107. (def/public (set-argb-pixels [exact-nonnegative-integer? x]
  108. [exact-nonnegative-integer? y]
  109. [exact-nonnegative-integer? w]
  110. [exact-nonnegative-integer? h]
  111. [bytes? bstr]
  112. [any? [set-alpha? #f]]
  113. [any? [pre-mult? #f]])
  114. (let ([bm (internal-get-bitmap)])
  115. (when bm
  116. (send bm set-argb-pixels x y w h bstr set-alpha? pre-mult?))))
  117. (def/public (get-argb-pixels [exact-nonnegative-integer? x]
  118. [exact-nonnegative-integer? y]
  119. [exact-nonnegative-integer? w]
  120. [exact-nonnegative-integer? h]
  121. [bytes? bstr]
  122. [any? [get-alpha? #f]]
  123. [any? [pre-mult? #f]])
  124. (let ([bm (internal-get-bitmap)])
  125. (when bm
  126. (send bm get-argb-pixels x y w h bstr get-alpha? pre-mult?))))
  127. (def/public (draw-bitmap-section-smooth [bitmap% src]
  128. [real? dest-x]
  129. [real? dest-y]
  130. [nonnegative-real? dest-w]
  131. [nonnegative-real? dest-h]
  132. [real? src-x]
  133. [real? src-y]
  134. [nonnegative-real? src-w]
  135. [nonnegative-real? src-h]
  136. [(symbol-in solid opaque xor) [style 'solid]]
  137. [(make-or-false color%) [color black]]
  138. [(make-or-false bitmap%) [mask #f]])
  139. (let ([sx (if (zero? src-w) 1.0 (/ dest-w src-w))]
  140. [sy (if (zero? src-h) 1.0 (/ dest-h src-h))])
  141. (let ([t (get-transformation)]
  142. [s (get-smoothing)])
  143. (scale sx sy)
  144. (when (eq? s 'unsmoothed) (set-smoothing 'aligned))
  145. (begin0
  146. (draw-bitmap-section src (/ dest-x sx) (/ dest-y sy) src-x src-y src-w src-h style color mask)
  147. (when (eq? s 'unsmoothed) (set-smoothing 'unsmoothed))
  148. (set-transformation t)))))
  149. (def/override (get-char-width)
  150. (if (internal-get-bitmap)
  151. (super get-char-width)
  152. (send (get-temp-bitmap-dc) get-char-width)))
  153. (def/override (get-char-height)
  154. (if (internal-get-bitmap)
  155. (super get-char-height)
  156. (send (get-temp-bitmap-dc) get-char-height)))
  157. (define temp-dc #f)
  158. (define/private (get-temp-bitmap-dc)
  159. (let ([dc (or (and temp-dc (weak-box-value temp-dc))
  160. (let ([dc (make-object bitmap-dc% (make-object bitmap% 1 1))])
  161. (set! temp-dc (make-weak-box dc))
  162. dc))])
  163. (send dc set-font (get-font))
  164. dc))))
  165. (install-bitmap-dc-class! bitmap-dc%)