2016-11-18 10 views
3

私のアプリケーションのstatusiconにレンダリングしたいと思います。haskellアプリケーションでcairoを使用してgtk3ステータスシステムにレンダリングするにはどうすればよいですか?

statusIconPixbufを設定すると、statusiconディスプレイにpixbufを表示させることができます。

そして、pixbufNewで空のpixbufを作成し、それを単一の色で塗りつぶすようなことをすることができます。

しかし、どのようにそのpixbufにカイロを使ってレンダリングするのですか?

pixbufは使用するのに適切なものではありませんか? statusiconにレンダリングするより良い方法はありますか?

答えて

0

Pixbufを使用すると、レンダリングする方法が必要です。

次のソリューションは、render :: Render a レンダリングカイロ(四角)Pixbufの所望のXとYの寸法を取る(あなたは非正方形Pixbufsを作成する必要がある場合は、これを変更することができます。)

import qualified Foreign.Ptr as Pointer 
import qualified ByteString as B 

renderPixbuf :: Int -> Render a -> IO Pixbuf 
renderPixbuf size render = withImageSurface FormatARGB32 size size $ \surface -> do 
    renderWith surface render 
    stride <- imageSurfaceGetStride surface 
    surfaceData <- swapRB stride <$> imageSurfaceGetData surface 
    B.useAsCStringLen surfaceData $ \(pointer, _) -> do 
     let pointer' = Pointer.castPtr pointer 
     pixbufNewFromData pointer' ColorspaceRgb True 8 size size stride 

それは、 withImageSurfaceを使用してレンダリングするカイロのサーフェスを作成し、renderWithを呼び出してrenderで指定された実際のレンダリングを行います。

次の2行は、イメージストライド、つまり行のバイト数と実際のイメージデータをByteStringとして抽出します。

swapRBは、赤と青のチャンネルの順序が間違っているため、ByteStringを変換する関数です。これがどのように行われているかは以下を参照してください。

B.useAsCStringLenでは、低レベルの取得:それは延ByteString taks imageSurfaceGetDataによって返されたとpixbufNewFromDataを使用して新しいPIXBUFを作成するために、Ptr CUCharに変換します。

これだけです。次のように

swapRBが定義される:赤、緑、青のチャンネルのために1バイト毎:

import Data.Word (Word8) 
import Data.List (unfoldr) 

splitAtIfNotNull :: Int -> B.ByteString -> Maybe (B.ByteString,B.ByteString) 
splitAtIfNotNull i string 
    | B.null string = Nothing 
    | otherwise = Just $ B.splitAt i string 

mapChunks :: (B.ByteString -> B.ByteString) -> Int -> B.ByteString -> B.ByteString 
mapChunks mapper chunkSize = B.concat . map mapper . unfoldr (splitAtIfNotNull chunkSize) 

swapRB :: Int -> B.ByteString -> B.ByteString 
swapRB = mapChunks swapRBforLine 
    where swapRBforLine :: B.ByteString -> B.ByteString 
     swapRBforLine = mapChunks (B.pack . swapRBforPixel . B.unpack) 4 
     swapRBforPixel :: [Word8] -> [Word8] 
     swapRBforPixel [b,g,r,a] = [r,g,b,a] 
     swapRBforPixel other = other 

次に、各4バイトで構成される画素に行を分割し、行に画素データの延ByteStringを分割しますアルファ。最も内側のものは実際のスワッピングです。

swapRBforPixel [b,g,r,a] = [r,g,b,a] 
関連する問題