Как проверить, сохраняется ли состояние рендеринга в Gtk2hs Cairo, чтобы предотвратить масштабирование изображения при изменении размера окна в Haskell

Я пытаюсь нарисовать несколько простых изображений в gtk2hs cairo. Я знаю, что вы можете сохранить текущее состояние с помощью команды save и восстановить с помощью команды restore. Есть ли способ проверить, сохранено ли состояние в данный момент. Я не хочу, чтобы мое изображение масштабировалось при изменении размера окна, или лучше предотвратить изменение размера. Я не хочу пересчитывать изображение каждый раз при изменении размера окна.


person Ratan Senapathy    schedule 14.09.2016    source источник


Ответы (1)


Действия save и restore на самом деле не связаны с тем, пересчитывается ли изображение. Однако в gtk2hs включена демонстрация, которая показывает, как кэшировать результат выполнения действия Cairo, см. cairo/demo/Clock.hs, особенно строки 320-404 файла 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
person Daniel Wagner    schedule 14.09.2016