我正试图在gtk2hs-cairo中绘制一些简单的图像。我知道您可以使用save
命令保存当前状态,并使用restore
命令恢复。是否有一种方法可以检查当前是否保存了状态。我不希望我的图像在调整窗口大小时缩放,或者有更好的方法来防止调整大小。我不想每次调整窗口大小时都重新计算图像。
save
和restore
操作实际上与图像是否重新计算无关。然而,gtk2hs中包含了一个演示,展示了如何缓存执行Cairo
操作的结果,请参阅cairo/demo/Clock.hs,尤其是main
:的第320-404行
let redrawStaticLayers = do
(width, height) <- widgetGetSize window
drawWin <- widgetGetDrawWindow window
background <- createImageSurface FormatARGB32 width height
foreground <- createImageSurface FormatARGB32 width height
let clear = do
save
setOperator OperatorClear
paint
restore
renderWith background $ do
clear
drawClockBackground True width height
renderWith foreground $ do
clear
drawClockForeground True width height
writeIORef backgroundRef (Just background)
writeIORef foregroundRef (Just foreground)
onRealize window redrawStaticLayers
sizeRef <- newIORef (initialSize, initialSize)
timeoutHandlerRef <- newIORef Nothing
window `on` configureEvent $ do
(w,h) <- eventSize
liftIO $ do
size <- readIORef sizeRef
writeIORef sizeRef (w,h)
when (size /= (w,h)) $ do
background <- readIORef backgroundRef
foreground <- readIORef foregroundRef
maybe (return ()) surfaceFinish background
maybe (return ()) surfaceFinish foreground
writeIORef backgroundRef Nothing
writeIORef foregroundRef Nothing
timeoutHandler <- readIORef timeoutHandlerRef
maybe (return ()) timeoutRemove timeoutHandler
handler <- timeoutAddFull (do
writeIORef timeoutHandlerRef Nothing
redrawStaticLayers
widgetQueueDraw window
return False
) priorityDefaultIdle 300
writeIORef timeoutHandlerRef (Just handler)
return False
window `on` exposeEvent $ do
drawWin <- eventWindow
exposeRegion <- eventRegion
liftIO $ do
(width, height) <- drawableGetSize drawWin
background <- readIORef backgroundRef
foreground <- readIORef foregroundRef
renderWithDrawable drawWin $ do
region exposeRegion
clip
save
setOperator OperatorSource
setSourceRGBA 0 0 0 0
paint
restore
case background of
Nothing -> drawClockBackground False width height
Just background -> do
setSourceSurface background 0 0
paint
drawClockHands (isJust background) width height
case foreground of
Nothing -> drawClockForeground False width height
Just foreground -> do
setSourceSurface foreground 0 0
paint
return True