0

I am trying to draw some simple images in gtk2hs cairo. I know you can save the current state using save command and restore using restore command. Is thee a way to check is a state is currently saved. I do not want my image to scale when resizing the window or is there a better to prevent resizing. I do not want to recompute the image every time the window is resized.

Ratan Senapathy
  • 2,148
  • 2
  • 10
  • 14

1 Answers1

1

The save and restore actions are not really related to whether the image gets recomputed. However there is a demo included with gtk2hs that shows how to cache the result of executing a Cairo action, see cairo/demo/Clock.hs, especially lines 320-404 of main:

  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
Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380