Re: [Haskell-cafe] Drawing an existing image into a cairo surface?

2008-09-21 Thread Austin Seipp
Excerpts from Rafal Kolanski's message of Sun Sep 21 07:28:37 -0500 2008:
 The best I can find is withImageSurfaceFromPNG, but I can't
 make it work.

Why not? Seems to me all you need to do is:

 withImageSurfaceFromPNG blah.png $ \surface - do
...

Lots of code is written this way (create a resource, pass it to a
function and then release it after the function is over.)

 I tried playing around with unsafePerformIO but that just gets me into:

Without further context as to what you are doing, I really see no
reason why you would have to use unsafePerformIO at all.

Austin
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Drawing an existing image into a cairo surface?

2008-09-21 Thread Rafal Kolanski



Austin Seipp wrote:

Excerpts from Rafal Kolanski's message of Sun Sep 21 07:28:37 -0500 2008:

The best I can find is withImageSurfaceFromPNG, but I can't
make it work.


Why not? Seems to me all you need to do is:

 withImageSurfaceFromPNG blah.png $ \surface - do
...

Lots of code is written this way (create a resource, pass it to a
function and then release it after the function is over.)


Well, but withImageSurfaceFromPNG only lets you work within that scope
and wipes out the surface straight afterwards ...


I tried playing around with unsafePerformIO but that just gets me into:


Without further context as to what you are doing, I really see no
reason why you would have to use unsafePerformIO at all.


The context is, I want to render a multi-page PDF with a variety of
things on it, so I have something like (very simplified):

main :: IO ()
main = do
withPDFSurface outputFile pdfWidth pdfHeight renderer

renderer s = renderWith s renderPresentation

renderPresentation = do
myDraw1
showPage
myDraw2
showPage

myDraw1 = do
setSourceRGB 1 0 0
setLineWidth 1
moveTo 0 0
lineTo 100 100
stroke

so renderPresentation will have type Render ()

Now lets say I want to draw an image on page 2, that will only appear on
page 2 ... with one image, your technique makes sense to me, but with
multiple images on multiple pages, I don't understand how to make it scale.

Perhaps this code is very naive, but I'm kinda new to the pure world of
Haskell.

Sincerely,

Rafal Kolanski.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Drawing an existing image into a cairo surface?

2008-09-21 Thread Rafal Kolanski
I finally came up with a solution that suits my context. For those 
interested, I'm supplying it here.


Safely get a surface containing your .png image (note that the surface 
has to be freed when you're done with it using surfaceFinish)


imageSurfaceCreateFromPNG :: FilePath - IO Surface
imageSurfaceCreateFromPNG file =
withImageSurfaceFromPNG file $ \png - do
w - renderWith png $ imageSurfaceGetWidth png
h - renderWith png $ imageSurfaceGetHeight png
surf - createImageSurface FormatRGB24 w h
renderWith surf $ do
setSourceSurface png 0 0
paint
return surf

Now the unsafe part (hack until I have an associative list storing my 
images to pull into relevant pages for rendering):


unsafeLoadPNG file = unsafePerformIO $ imageSurfaceCreateFromPNG file

This allows drawing an image directly in a Render () context:

paintImage :: FilePath - Double - Double - Render ()
paintImage file x y = do
surf - return $ unsafeLoadPNG file
setSourceSurface surf x y
paint

Looking at this irc log from 2005:
  http://www.cse.unsw.edu.au/~dons/code/irc-logs/05.11.20
someone's had this problem before, and although they did not show their 
solution, I think it might've been similar to mine.


Hope this helps the next person to get stuck.

Sincerely,

Rafal Kolanski.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re[2]: [Haskell-cafe] Drawing an existing image into a cairo surface?

2008-09-21 Thread Bulat Ziganshin
Hello Rafal,

Sunday, September 21, 2008, 5:43:14 PM, you wrote:

  withImageSurfaceFromPNG file $ \png - do
  w - renderWith png $ imageSurfaceGetWidth png
  h - renderWith png $ imageSurfaceGetHeight png

this is very idiomatic Haskell, consider it as a sort of RAII. you may
even omit additional tab here:

  withImageSurfaceFromPNG file $ \png - do
  w - renderWith png $ imageSurfaceGetWidth png
  h - renderWith png $ imageSurfaceGetHeight png
  ...

afair, Render is a super-IO monad so you can just lift any IO
operation to Render:

x - liftIO$ imageSurfaceCreateFromPNG file



-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Drawing an existing image into a cairo surface?

2008-09-21 Thread Rafal Kolanski


Bulat Ziganshin wrote:

afair, Render is a super-IO monad so you can just lift any IO
operation to Render:

x - liftIO$ imageSurfaceCreateFromPNG file


You are indeed correct.

I feel really silly now, using unsafePerformIO in the IO monad. D'oh!

Thank you very much!

Rafal Kolanski.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Drawing an existing image into a cairo surface?

2008-09-21 Thread Jefferson Heard
Sorry.  In a hurry, and I don't have a lot of time to read the
message, so if I'm offering a lot of info you already have, I
apologize.  The best thing to do is to allocate either a pixmap or
Gtk.DrawingArea -- you can then use widgetGetDrawable to get the
drawing context from it and newGC to take drawing context and get a
graphics context.  After you have a drawing and graphics context, you
can use drawPixbuf to draw or update any image you want, then use the
same DrawngArea for Cairo after you've drawing the image.

If you need more help with it, let me know, and I can send some code
that will do it later today.

-- Jeff

On Sun, Sep 21, 2008 at 10:09 AM, Rafal Kolanski [EMAIL PROTECTED] wrote:

 Bulat Ziganshin wrote:

 afair, Render is a super-IO monad so you can just lift any IO
 operation to Render:

 x - liftIO$ imageSurfaceCreateFromPNG file

 You are indeed correct.

 I feel really silly now, using unsafePerformIO in the IO monad. D'oh!

 Thank you very much!

 Rafal Kolanski.
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe




-- 
I try to take things like a crow; war and chaos don't always ruin a
picnic, they just mean you have to be careful what you swallow.

-- Jessica Edwards
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Drawing an existing image into a cairo surface?

2008-09-21 Thread Rafal Kolanski



Jefferson Heard wrote:

Sorry.  In a hurry, and I don't have a lot of time to read the
message, so if I'm offering a lot of info you already have, I
apologize.  The best thing to do is to allocate either a pixmap or
Gtk.DrawingArea -- you can then use widgetGetDrawable to get the
drawing context from it and newGC to take drawing context and get a
graphics context.  After you have a drawing and graphics context, you
can use drawPixbuf to draw or update any image you want, then use the
same DrawngArea for Cairo after you've drawing the image.

If you need more help with it, let me know, and I can send some code
that will do it later today.


I'd be very much interested, as I also want to load SVG files and my 
version of Gtk2Hs (Ubuntu Hardy) doesn't have 
Graphics.Rendering.Cairo.SVG ...


Your method can get around this problem I think.

Sincerely,

Rafal Kolanski.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe