module Graphics.UI.WXCore.Draw
(
drawLines, drawPolygon, getTextExtent, getFullTextExtent, dcClearRect
, withPaintDC, withClientDC, dcDraw
, withSVGFileDC, withSVGFileDCWithSize, withSVGFileDCWithSizeAndResolution
, DrawState, dcEncapsulate, dcGetDrawState, dcSetDrawState, drawStateDelete
, dcBuffer, dcBufferWithRef, dcBufferWithRefEx
, dcBufferWithRefExGcdc
, windowGetViewStart, windowGetViewRect, windowCalcUnscrolledPosition
, FontStyle(..), FontFamily(..), FontShape(..), FontWeight(..)
, fontDefault, fontSwiss, fontSmall, fontItalic, fontFixed
, withFontStyle, dcWithFontStyle
, dcSetFontStyle, dcGetFontStyle
, fontCreateFromStyle, fontGetFontStyle
, BrushStyle(..), BrushKind(..)
, HatchStyle(..)
, brushDefault, brushSolid, brushTransparent
, dcSetBrushStyle, dcGetBrushStyle
, withBrushStyle, dcWithBrushStyle, dcWithBrush
, brushCreateFromStyle, brushGetBrushStyle
, PenStyle(..), PenKind(..), CapStyle(..), JoinStyle(..), DashStyle(..)
, penDefault, penColored, penTransparent
, dcSetPenStyle, dcGetPenStyle
, withPenStyle, dcWithPenStyle, dcWithPen
, penCreateFromStyle, penGetPenStyle
) where
import Graphics.UI.WXCore.WxcTypes
import Graphics.UI.WXCore.WxcDefs
import Graphics.UI.WXCore.WxcClasses
import Graphics.UI.WXCore.WxcClassInfo
import Graphics.UI.WXCore.Types
import Graphics.UI.WXCore.Defines
import Foreign.Storable
import Foreign.Marshal.Alloc
dcDraw :: DC a -> IO b -> IO b
dcDraw dc io
= bracket_ (do dcSetPenStyle dc penDefault
dcSetBrushStyle dc brushDefault)
(do dcSetPen dc nullPen
dcSetBrush dc nullBrush)
io
withPaintDC :: Window a -> (PaintDC () -> IO b) -> IO b
withPaintDC window draw
= bracket (paintDCCreate window) (paintDCDelete) (\dc -> dcDraw dc (draw dc))
withClientDC :: Window a -> (ClientDC () -> IO b) -> IO b
withClientDC window draw
= bracket (clientDCCreate window) (clientDCDelete) (\dc -> dcDraw dc (draw dc))
withSVGFileDC :: FilePath -> (SVGFileDC () -> IO b) -> IO b
withSVGFileDC fname draw
= bracket (svgFileDCCreate fname) (svgFileDCDelete) (\dc -> dcDraw dc (draw dc))
withSVGFileDCWithSize :: FilePath -> Size -> (SVGFileDC () -> IO b) -> IO b
withSVGFileDCWithSize fname size draw
= bracket (svgFileDCCreateWithSize fname size) (svgFileDCDelete) (\dc -> dcDraw dc (draw dc))
withSVGFileDCWithSizeAndResolution :: FilePath -> Size -> Float -> (SVGFileDC () -> IO b) -> IO b
withSVGFileDCWithSizeAndResolution fname size dpi draw
= bracket (svgFileDCCreateWithSizeAndResolution fname size dpi) (svgFileDCDelete) (\dc -> dcDraw dc (draw dc))
dcClearRect :: DC a -> Rect -> IO ()
dcClearRect dc r
= bracket (dcGetBackground dc)
(brushDelete)
(\brush -> dcWithBrush dc brush $
dcWithPenStyle dc penTransparent $
dcDrawRectangle dc r)
windowGetViewRect :: Window a -> IO Rect
windowGetViewRect window
= do size <- windowGetClientSize window
org <- windowGetViewStart window
return (rect org size)
windowGetViewStart :: Window a -> IO Point
windowGetViewStart window
= do isScrolled <- objectIsScrolledWindow window
if (isScrolled)
then do let scrolledWindow = objectCast window
(Point sx sy) <- scrolledWindowGetViewStart scrolledWindow
(Point w h) <- scrolledWindowGetScrollPixelsPerUnit scrolledWindow
return (Point (w*sx) (h*sy))
else return pointZero
windowCalcUnscrolledPosition :: Window a -> Point -> IO Point
windowCalcUnscrolledPosition window p
= do isScrolled <- objectIsScrolledWindow window
if (isScrolled)
then do let scrolledWindow = objectCast window
scrolledWindowCalcUnscrolledPosition scrolledWindow p
else return p
data FontStyle
= FontStyle{ _fontSize :: !Int
, _fontFamily :: !FontFamily
, _fontShape :: !FontShape
, _fontWeight :: !FontWeight
, _fontUnderline :: !Bool
, _fontFace :: !String
, _fontEncoding :: !Int
}
deriving (Eq,Show)
fontDefault :: FontStyle
fontDefault
= FontStyle 10 FontDefault ShapeNormal WeightNormal False "" wxFONTENCODING_DEFAULT
fontSwiss :: FontStyle
fontSwiss
= fontDefault{ _fontFamily = FontSwiss }
fontSmall :: FontStyle
fontSmall
= fontDefault{ _fontSize = 8 }
fontItalic :: FontStyle
fontItalic
= fontDefault{ _fontShape = ShapeItalic }
fontFixed :: FontStyle
fontFixed
= fontDefault{ _fontFamily = FontModern }
data FontFamily
= FontDefault
| FontDecorative
| FontRoman
| FontScript
| FontSwiss
| FontModern
| FontTeletype
deriving (Eq,Show)
data FontShape
= ShapeNormal
| ShapeItalic
| ShapeSlant
deriving (Eq,Show)
data FontWeight
= WeightNormal
| WeightBold
| WeightLight
deriving (Eq,Show)
withFontStyle :: FontStyle -> (Font () -> IO a) -> IO a
withFontStyle fontStyle f
= do (font,delete) <- fontCreateFromStyle fontStyle
finally (f font) delete
dcWithFontStyle :: DC a -> FontStyle -> IO b -> IO b
dcWithFontStyle dc fontStyle io
= withFontStyle fontStyle $ \font ->
bracket (do oldFont <- dcGetFont dc
dcSetFont dc font
return oldFont)
(\oldFont ->
do dcSetFont dc oldFont
fontDelete oldFont)
(const io)
dcSetFontStyle :: DC a -> FontStyle -> IO ()
dcSetFontStyle dc info
= do (font,del) <- fontCreateFromStyle info
finalize del $
do dcSetFont dc font
dcGetFontStyle :: DC a -> IO FontStyle
dcGetFontStyle dc
= do font <- dcGetFont dc
finalize (fontDelete font) $
do fontGetFontStyle font
fontCreateFromStyle :: FontStyle -> IO (Font (),IO ())
fontCreateFromStyle (FontStyle size family style weight underline face encoding)
= do font <- fontCreate size cfamily cstyle cweight underline face encoding
return (font,when (font /= objectNull) (fontDelete font))
where
cfamily
= case family of
FontDefault -> wxFONTFAMILY_DEFAULT
FontDecorative -> wxFONTFAMILY_DECORATIVE
FontRoman -> wxFONTFAMILY_ROMAN
FontScript -> wxFONTFAMILY_SCRIPT
FontSwiss -> wxFONTFAMILY_SWISS
FontModern -> wxFONTFAMILY_MODERN
FontTeletype -> wxFONTFAMILY_TELETYPE
cstyle
= case style of
ShapeNormal -> wxFONTSTYLE_NORMAL
ShapeItalic -> wxFONTSTYLE_ITALIC
ShapeSlant -> wxFONTSTYLE_SLANT
cweight
= case weight of
WeightNormal -> wxFONTWEIGHT_NORMAL
WeightBold -> wxFONTWEIGHT_BOLD
WeightLight -> wxFONTWEIGHT_LIGHT
fontGetFontStyle :: Font () -> IO FontStyle
fontGetFontStyle font
= if (objectIsNull font)
then return fontDefault
else do ok <- fontIsOk font
if not ok
then return fontDefault
else do size <- fontGetPointSize font
cfamily <- fontGetFamily font
cstyle <- fontGetStyle font
cweight <- fontGetWeight font
cunderl <- fontGetUnderlined font
face <- fontGetFaceName font
enc <- fontGetEncoding font
return (FontStyle size (toFamily cfamily) (toStyle cstyle)
(toWeight cweight)
(cunderl /= 0) face enc)
where
toFamily f
| f == wxFONTFAMILY_DECORATIVE = FontDecorative
| f == wxFONTFAMILY_ROMAN = FontRoman
| f == wxFONTFAMILY_SCRIPT = FontScript
| f == wxFONTFAMILY_SWISS = FontSwiss
| f == wxFONTFAMILY_MODERN = FontModern
| f == wxFONTFAMILY_TELETYPE = FontTeletype
| otherwise = FontDefault
toStyle s
| s == wxFONTSTYLE_ITALIC = ShapeItalic
| s == wxFONTSTYLE_SLANT = ShapeSlant
| otherwise = ShapeNormal
toWeight w
| w == wxFONTWEIGHT_BOLD = WeightBold
| w == wxFONTWEIGHT_LIGHT = WeightLight
| otherwise = WeightNormal
data PenStyle
= PenStyle { _penKind :: !PenKind
, _penColor :: !Color
, _penWidth :: !Int
, _penCap :: !CapStyle
, _penJoin :: !JoinStyle
}
deriving (Eq,Show)
data PenKind
= PenTransparent
| PenSolid
| PenDash { _penDash :: !DashStyle }
| PenHatch { _penHatch :: !HatchStyle }
| PenStipple{ _penBitmap :: !(Bitmap ())}
deriving (Eq,Show)
penDefault :: PenStyle
penDefault
= PenStyle PenSolid black 1 CapRound JoinRound
penColored :: Color -> Int -> PenStyle
penColored color width
= penDefault{ _penColor = color, _penWidth = width }
penTransparent :: PenStyle
penTransparent
= penDefault{ _penKind = PenTransparent }
data DashStyle
= DashDot
| DashLong
| DashShort
| DashDotShort
deriving (Eq,Show)
data CapStyle
= CapRound
| CapProjecting
| CapButt
deriving (Eq,Show)
data JoinStyle
= JoinRound
| JoinBevel
| JoinMiter
deriving (Eq,Show)
data HatchStyle
= HatchBDiagonal
| HatchCrossDiag
| HatchFDiagonal
| HatchCross
| HatchHorizontal
| HatchVertical
deriving (Eq,Show)
data BrushStyle
= BrushStyle { _brushKind :: !BrushKind, _brushColor :: !Color }
deriving (Eq,Show)
data BrushKind
= BrushTransparent
| BrushSolid
| BrushHatch { _brushHatch :: !HatchStyle }
| BrushStipple{ _brushBitmap :: !(Bitmap ())}
deriving (Eq,Show)
dcWithPenStyle :: DC a -> PenStyle -> IO b -> IO b
dcWithPenStyle dc penStyle io
= withPenStyle penStyle $ \pen ->
dcWithPen dc pen io
dcWithPen :: DC a -> Pen p -> IO b -> IO b
dcWithPen dc pen io
= bracket (do oldPen <- dcGetPen dc
dcSetPen dc pen
return oldPen)
(\oldPen ->
do dcSetPen dc oldPen
penDelete oldPen)
(const io)
dcSetPenStyle :: DC a -> PenStyle -> IO ()
dcSetPenStyle dc penStyle
= withPenStyle penStyle (dcSetPen dc)
dcGetPenStyle :: DC a -> IO PenStyle
dcGetPenStyle dc
= do pen <- dcGetPen dc
finalize (penDelete pen) $
do penGetPenStyle pen
withPenStyle :: PenStyle -> (Pen () -> IO a) -> IO a
withPenStyle penStyle f
= do (pen,delete) <- penCreateFromStyle penStyle
finally (f pen) delete
penCreateFromStyle :: PenStyle -> IO (Pen (),IO ())
penCreateFromStyle penStyle
= case penStyle of
PenStyle PenTransparent _color _width _cap _join
-> do pen <- penCreateFromStock 5
return (pen,return ())
PenStyle (PenDash DashShort) color 1 CapRound JoinRound | color == black
-> do pen <- penCreateFromStock 6
return (pen,return ())
PenStyle PenSolid color 1 CapRound JoinRound
-> case lookup color stockPens of
Just idx -> do pen <- penCreateFromStock idx
return (pen,return ())
Nothing -> colorPen color 1 wxPENSTYLE_SOLID
PenStyle PenSolid color width _cap _join
-> colorPen color width wxPENSTYLE_SOLID
PenStyle (PenDash dash) color width _cap _join
-> case dash of
DashDot -> colorPen color width wxPENSTYLE_DOT
DashLong -> colorPen color width wxPENSTYLE_LONG_DASH
DashShort -> colorPen color width wxPENSTYLE_SHORT_DASH
DashDotShort -> colorPen color width wxPENSTYLE_DOT_DASH
PenStyle (PenStipple bitmap) _color width _cap _join
-> do pen <- penCreateFromBitmap bitmap width
setCap pen
setJoin pen
return (pen,penDelete pen)
PenStyle (PenHatch hatch) color width _cap _join
-> case hatch of
HatchBDiagonal -> colorPen color width wxPENSTYLE_BDIAGONAL_HATCH
HatchCrossDiag -> colorPen color width wxPENSTYLE_CROSSDIAG_HATCH
HatchFDiagonal -> colorPen color width wxPENSTYLE_FDIAGONAL_HATCH
HatchCross -> colorPen color width wxPENSTYLE_CROSS_HATCH
HatchHorizontal -> colorPen color width wxPENSTYLE_HORIZONTAL_HATCH
HatchVertical -> colorPen color width wxPENSTYLE_VERTICAL_HATCH
where
colorPen color width style
= do pen <- penCreateFromColour color width style
setCap pen
setJoin pen
return (pen,penDelete pen)
setCap pen
= case _penCap penStyle of
CapRound -> return ()
CapProjecting -> penSetCap pen wxCAP_PROJECTING
CapButt -> penSetCap pen wxCAP_BUTT
setJoin pen
= case _penJoin penStyle of
JoinRound -> return ()
JoinBevel -> penSetJoin pen wxJOIN_BEVEL
JoinMiter -> penSetJoin pen wxJOIN_MITER
stockPens
= [(red,0),(cyan,1),(green,2)
,(black,3),(white,4)
,(grey,7),(lightgrey,9)
,(mediumgrey,8)
]
penGetPenStyle :: Pen a -> IO PenStyle
penGetPenStyle pen
= if (objectIsNull pen)
then return penDefault
else do ok <- penIsOk pen
if not ok
then return penDefault
else do stl <- penGetStyle pen
toPenStyle stl
where
toPenStyle stl
| stl == wxPENSTYLE_TRANSPARENT = return penTransparent
| stl == wxPENSTYLE_SOLID = toPenStyleWithKind PenSolid
| stl == wxPENSTYLE_DOT = toPenStyleWithKind (PenDash DashDot)
| stl == wxPENSTYLE_LONG_DASH = toPenStyleWithKind (PenDash DashLong)
| stl == wxPENSTYLE_SHORT_DASH = toPenStyleWithKind (PenDash DashShort)
| stl == wxPENSTYLE_DOT_DASH = toPenStyleWithKind (PenDash DashDotShort)
| stl == wxPENSTYLE_STIPPLE = do stipple <- penGetStipple pen
toPenStyleWithKind (PenStipple stipple)
| stl == wxPENSTYLE_BDIAGONAL_HATCH = toPenStyleWithKind (PenHatch HatchBDiagonal)
| stl == wxPENSTYLE_CROSSDIAG_HATCH = toPenStyleWithKind (PenHatch HatchCrossDiag)
| stl == wxPENSTYLE_FDIAGONAL_HATCH = toPenStyleWithKind (PenHatch HatchFDiagonal)
| stl == wxPENSTYLE_CROSS_HATCH = toPenStyleWithKind (PenHatch HatchCross)
| stl == wxPENSTYLE_HORIZONTAL_HATCH = toPenStyleWithKind (PenHatch HatchHorizontal)
| stl == wxPENSTYLE_VERTICAL_HATCH = toPenStyleWithKind (PenHatch HatchVertical)
| otherwise = toPenStyleWithKind PenSolid
toPenStyleWithKind kind
= do width <- penGetWidth pen
color <- penGetColour pen
cap <- penGetCap pen
join <- penGetJoin pen
return (PenStyle kind color width (toCap cap) (toJoin join))
toCap cap
| cap == wxCAP_PROJECTING = CapProjecting
| cap == wxCAP_BUTT = CapButt
| otherwise = CapRound
toJoin join
| join == wxJOIN_MITER = JoinMiter
| join == wxJOIN_BEVEL = JoinBevel
| otherwise = JoinRound
brushDefault :: BrushStyle
brushDefault
= BrushStyle BrushTransparent black
brushSolid :: Color -> BrushStyle
brushSolid color
= BrushStyle BrushSolid color
brushTransparent :: BrushStyle
brushTransparent
= BrushStyle BrushTransparent white
dcWithBrushStyle :: DC a -> BrushStyle -> IO b -> IO b
dcWithBrushStyle dc brushStyle io
= withBrushStyle brushStyle $ \brush ->
dcWithBrush dc brush io
dcWithBrush :: DC b -> Brush a -> IO c -> IO c
dcWithBrush dc brush io
= bracket (do oldBrush <- dcGetBrush dc
dcSetBrush dc brush
return oldBrush)
(\oldBrush ->
do dcSetBrush dc oldBrush
brushDelete oldBrush)
(const io)
dcSetBrushStyle :: DC a -> BrushStyle -> IO ()
dcSetBrushStyle dc brushStyle
= withBrushStyle brushStyle (dcSetBrush dc)
dcGetBrushStyle :: DC a -> IO BrushStyle
dcGetBrushStyle dc
= do brush <- dcGetBrush dc
finalize (brushDelete brush) $
do brushGetBrushStyle brush
withBrushStyle :: BrushStyle -> (Brush () -> IO a) -> IO a
withBrushStyle brushStyle f
= do (brush,delete) <- brushCreateFromStyle brushStyle
finalize delete $
do f brush
brushCreateFromStyle :: BrushStyle -> IO (Brush (), IO ())
brushCreateFromStyle brushStyle
= case brushStyle of
BrushStyle BrushTransparent color
-> do brush <- if (wxToolkit == WxMac)
then brushCreateFromColour color wxBRUSHSTYLE_TRANSPARENT
else brushCreateFromStock 7
return (brush,return ())
BrushStyle BrushSolid color
-> case lookup color stockBrushes of
Just idx -> do brush <- brushCreateFromStock idx
return (brush,return ())
Nothing -> colorBrush color wxBRUSHSTYLE_SOLID
BrushStyle (BrushHatch HatchBDiagonal) color -> colorBrush color wxBRUSHSTYLE_BDIAGONAL_HATCH
BrushStyle (BrushHatch HatchCrossDiag) color -> colorBrush color wxBRUSHSTYLE_CROSSDIAG_HATCH
BrushStyle (BrushHatch HatchFDiagonal) color -> colorBrush color wxBRUSHSTYLE_FDIAGONAL_HATCH
BrushStyle (BrushHatch HatchCross) color -> colorBrush color wxBRUSHSTYLE_CROSS_HATCH
BrushStyle (BrushHatch HatchHorizontal) color -> colorBrush color wxBRUSHSTYLE_HORIZONTAL_HATCH
BrushStyle (BrushHatch HatchVertical) color -> colorBrush color wxBRUSHSTYLE_VERTICAL_HATCH
BrushStyle (BrushStipple bitmap) _color -> do brush <- brushCreateFromBitmap bitmap
return (brush, brushDelete brush)
where
colorBrush color style
= do brush <- brushCreateFromColour color style
return (brush, brushDelete brush )
stockBrushes
= [(blue,0),(green,1),(white,2)
,(black,3),(grey,4),(lightgrey,6)
,(cyan,8),(red,9)
,(mediumgrey,5)
]
brushGetBrushStyle :: Brush a -> IO BrushStyle
brushGetBrushStyle brush
= if (objectIsNull brush)
then return brushDefault
else do ok <- brushIsOk brush
if not ok
then return brushDefault
else do stl <- brushGetStyle brush
kind <- toBrushKind stl
color <- brushGetColour brush
return (BrushStyle kind color)
where
toBrushKind stl
| stl == wxBRUSHSTYLE_TRANSPARENT = return BrushTransparent
| stl == wxBRUSHSTYLE_SOLID = return BrushSolid
| stl == wxBRUSHSTYLE_STIPPLE = do stipple <- brushGetStipple brush
return (BrushStipple stipple)
| stl == wxBRUSHSTYLE_BDIAGONAL_HATCH = return (BrushHatch HatchBDiagonal)
| stl == wxBRUSHSTYLE_CROSSDIAG_HATCH = return (BrushHatch HatchCrossDiag)
| stl == wxBRUSHSTYLE_FDIAGONAL_HATCH = return (BrushHatch HatchFDiagonal)
| stl == wxBRUSHSTYLE_CROSS_HATCH = return (BrushHatch HatchCross)
| stl == wxBRUSHSTYLE_HORIZONTAL_HATCH = return (BrushHatch HatchHorizontal)
| stl == wxBRUSHSTYLE_VERTICAL_HATCH = return (BrushHatch HatchVertical)
| otherwise = return BrushTransparent
data DrawState = DrawState (Pen ()) (Brush ()) (Font ()) Color Color
dcEncapsulate :: DC a -> IO b -> IO b
dcEncapsulate dc io
= bracket (dcGetDrawState dc)
(\drawState ->
do dcSetDrawState dc drawState
drawStateDelete drawState)
(const io)
dcGetDrawState :: DC a -> IO DrawState
dcGetDrawState dc
= do pen <- dcGetPen dc
brush <- dcGetBrush dc
font <- dcGetFont dc
textc <- dcGetTextForeground dc
backc <- dcGetTextBackground dc
return (DrawState pen brush font textc backc)
dcSetDrawState :: DC a -> DrawState -> IO ()
dcSetDrawState dc (DrawState pen brush font textc backc)
= do dcSetPen dc pen
dcSetBrush dc brush
dcSetFont dc font
dcSetTextBackground dc backc
dcSetTextForeground dc textc
drawStateDelete :: DrawState -> IO ()
drawStateDelete (DrawState pen brush font _ _)
= do penDelete pen
brushDelete brush
fontDelete font
drawLines :: DC a -> [Point] -> IO ()
drawLines _dc [] = return ()
drawLines dc ps
= withArray xs $ \pxs ->
withArray ys $ \pys ->
dcDrawLines dc n pxs pys (pt 0 0)
where
n = length ps
xs = map pointX ps
ys = map pointY ps
drawPolygon :: DC a -> [Point] -> IO ()
drawPolygon _dc [] = return ()
drawPolygon dc ps
= withArray xs $ \pxs ->
withArray ys $ \pys ->
dcDrawPolygon dc n pxs pys (pt 0 0) wxODDEVEN_RULE
where
n = length ps
xs = map pointX ps
ys = map pointY ps
getTextExtent :: DC a -> String -> IO Size
getTextExtent dc txt
= do (sz',_,_) <- getFullTextExtent dc txt
return sz'
getFullTextExtent :: DC a -> String -> IO (Size,Int,Int)
getFullTextExtent dc txt
= alloca $ \px ->
alloca $ \py ->
alloca $ \pd ->
alloca $ \pe ->
do dcGetTextExtent dc txt px py pd pe objectNull
x <- peek px
y <- peek py
d <- peek pd
e <- peek pe
return (sz (fromCInt x) (fromCInt y), fromCInt d, fromCInt e)
dcBuffer :: WindowDC a -> Rect -> (DC () -> IO ()) -> IO ()
dcBuffer dc r draw
= dcBufferWithRef dc Nothing r draw
dcBufferWithRef :: WindowDC a -> Maybe (Var (Bitmap ())) -> Rect -> (DC () -> IO ()) -> IO ()
dcBufferWithRef dc mbVar viewArea draw
= dcBufferWithRefEx dc (\dc' -> dcClearRect dc' viewArea) mbVar viewArea draw
dcBufferWithRefEx :: WindowDC a -> (DC () -> IO ()) -> Maybe (Var (Bitmap ()))
-> Rect -> (DC () -> IO ()) -> IO ()
dcBufferWithRefEx = dcBufferedAux simpleDraw simpleDraw
where simpleDraw dc draw = draw $ downcastDC dc
dcBufferWithRefExGcdc :: WindowDC a -> (DC () -> IO ()) -> Maybe (Var (Bitmap ()))
-> Rect -> (GCDC () -> IO b) -> IO ()
dcBufferWithRefExGcdc =
dcBufferedAux (withGC gcdcCreate) (withGC gcdcCreateFromMemory)
where withGC create dc_ draw = do
dc <- create dc_
_ <- draw dc
gcdcDelete dc
dcBufferedAux :: (WindowDC a -> f -> IO ()) -> (MemoryDC c -> f -> IO ())
-> WindowDC a -> (DC () -> IO ()) -> Maybe (Var (Bitmap ()))
-> Rect -> f -> IO ()
dcBufferedAux _ _ _ _ _ view _
| rectSize view == sizeZero = return ()
dcBufferedAux withWinDC withMemoryDC dc clear mbVar view draw
= bracket (initBitmap)
(doneBitmap)
(\bitmap ->
if (bitmap==objectNull)
then drawUnbuffered
else bracket (do p <- memoryDCCreateCompatible dc; return (objectCast p))
(\memdc -> when (memdc/=objectNull) (memoryDCDelete memdc))
(\memdc -> if (memdc==objectNull)
then drawUnbuffered
else do memoryDCSelectObject memdc bitmap
drawBuffered memdc
memoryDCSelectObject memdc nullBitmap))
where
initBitmap
= case mbVar of
Nothing -> bitmapCreateEmpty (rectSize view) (1)
Just v -> do bitmap <- varGet v
size <- if (bitmap==objectNull)
then return sizeZero
else do bw <- bitmapGetWidth bitmap
bh <- bitmapGetHeight bitmap
return (Size bw bh)
if (sizeEncloses size (rectSize view) && bitmap /= objectNull)
then return bitmap
else do when (bitmap/=objectNull) (bitmapDelete bitmap)
varSet v objectNull
let (Size w h) = rectSize view
neww = div (w*105) 100
newh = div (h*105) 100
if (w > 0 && h > 0) then
do bm <- bitmapCreateEmpty (sz neww newh) (1)
varSet v bm
return bm
else return objectNull
doneBitmap bitmap
= case mbVar of
Nothing -> when (bitmap/=objectNull) (bitmapDelete bitmap)
Just _v -> return ()
drawUnbuffered
= do clear (downcastDC dc)
withWinDC dc draw
drawBuffered memdc
= do
dcSetDeviceOrigin memdc (pointFromVec (vecNegate (vecFromPoint (rectTopLeft view))))
dcSetClippingRegion memdc view
bracket (dcGetBackground dc)
(\brush -> do dcSetBrush memdc nullBrush
brushDelete brush)
(\brush -> do
dcSetBackground memdc brush
if (wxToolkit == WxMac)
then withBrushStyle brushTransparent (dcSetBrush memdc)
else dcSetBrush memdc brush
clear (downcastDC memdc)
withMemoryDC memdc draw
)
_ <- dcBlit dc view memdc (rectTopLeft view) wxCOPY False
return ()