如何检查Gtk2hs Cairo中是否保存渲染状态以防止在Haskell中调整大小窗口时缩放图像

时间:2016-09-14 17:23:47

标签: haskell cairo gtk2hs

我想在gtk2hs cairo中绘制一些简单的图像。我知道您可以使用save命令保存当前状态,并使用restore命令进行恢复。你是一种检查方式,目前是保存状态。我不希望在调整窗口大小时缩放图像,或者更好地防止调整大小。每次重新调整窗口大小时,我都不想重新计算图像。

1 个答案:

答案 0 :(得分:1)

saverestore操作与图像是否重新计算无关。但是,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