1
- {-# LANGUAGE GeneralizedNewtypeDeriving #-}
1
+ {-# LANGUAGE CPP, GeneralizedNewtypeDeriving #-}
2
2
{-|
3
3
Module : SDL.Cairo.Canvas
4
4
Copyright : Copyright (c) 2015 Anton Pirogov
@@ -24,7 +24,7 @@ import SDL.Cairo.Canvas
24
24
25
25
main :: IO ()
26
26
main = do
27
- initialize [InitEverything]
27
+ initializeAll
28
28
window <- createWindow "SDL2 Cairo Canvas" defaultWindow
29
29
renderer <- createRenderer window (-1) defaultRenderer
30
30
texture <- createCairoTexture' renderer window
@@ -52,7 +52,7 @@ module SDL.Cairo.Canvas (
52
52
Color , Byte , gray , red , green , blue , rgb , (!@) ,
53
53
stroke , fill , noStroke , noFill , strokeWeight , strokeJoin , strokeCap ,
54
54
-- * Coordinates
55
- Dim (.. ), toD , centered , corners ,
55
+ Dim (.. ), toD , Anchor ( .. ), aligned , centered , corners ,
56
56
-- * Primitives
57
57
background , point , line , triangle , rect , polygon , shape , ShapeMode (.. ),
58
58
-- * Arcs and Curves
@@ -62,15 +62,18 @@ module SDL.Cairo.Canvas (
62
62
-- * Images
63
63
Image (imageSize ), createImage , loadImagePNG , saveImagePNG , image , image' , blend , grab ,
64
64
-- * Text
65
- Font (.. ), textFont , textSize , text , textC , textR ,
65
+ Font (.. ), textFont , textSize , text , text' ,
66
66
-- * Math
67
67
mapRange , radians , degrees ,
68
68
-- * Misc
69
69
randomSeed , random , getTime , Time (.. ),
70
70
module Graphics.Rendering.Cairo
71
71
) where
72
72
73
+ #if __GLASGOW_HASKELL__ < 710
73
74
import Control.Applicative
75
+ #endif
76
+
74
77
import Data.Monoid
75
78
import Control.Monad.State
76
79
import Data.Word (Word8 )
@@ -83,7 +86,6 @@ import System.Random (mkStdGen,setStdGen,randomRIO,Random)
83
86
84
87
import Linear.V2 (V2 (.. ))
85
88
import Linear.V4 (V4 (.. ))
86
- import Linear.Affine (Point (.. ))
87
89
88
90
import SDL (Texture ,TextureInfo (.. ),queryTexture )
89
91
import qualified Graphics.Rendering.Cairo as C
@@ -113,12 +115,16 @@ getCanvasSize = gets csSize
113
115
newtype Canvas a = Canvas { unCanvas :: StateT CanvasState IO a }
114
116
deriving (Functor , Applicative , Monad , MonadIO , MonadState CanvasState )
115
117
118
+ -- instance Monad Canvas where
119
+ -- f >>= g = undefined
120
+ -- --TODO
121
+
116
122
-- | draw on a SDL texture using the 'Canvas' monad
117
123
withCanvas :: Texture -> Canvas a -> IO a
118
124
withCanvas t c = withCairoTexture' t $ \ s -> do
119
125
(TextureInfo _ _ w h) <- queryTexture t
120
126
(ret, result) <- runStateT (unCanvas $ defaults >> c)
121
- CanvasState { csSize = V2 (fromIntegral w) (fromIntegral h)
127
+ CanvasState { csSize = V2 (fromIntegral w) (fromIntegral h)
122
128
, csSurface = s
123
129
, csFG = Just $ gray 0
124
130
, csBG = Just $ gray 255
@@ -181,14 +187,32 @@ strokeCap l = renderCairo $ C.setLineCap l
181
187
182
188
----
183
189
184
- -- | position and size representation (X Y W H)
190
+ -- | position (canonically, top-left corner) and size representation (X Y W H)
185
191
data Dim = D Double Double Double Double deriving (Show ,Eq )
186
192
193
+ -- | type indicating where the position coordinate is referring to
194
+ data Anchor = NW | N | NE | E | SE | S | SW | W | Center | Baseline deriving (Show ,Eq )
195
+
187
196
-- | create dimensions from position and size vector
188
197
toD (V2 a b) (V2 c d) = D a b c d
189
198
199
+ -- | given dimensions with position coordinate not referring to the top-left corner,
200
+ -- normalize to top-left corner coordinate
201
+ aligned :: Anchor -> Dim -> Dim
202
+ aligned NW dim = dim
203
+ aligned NE (D x y w h) = D (x- w) y w h
204
+ aligned SW (D x y w h) = D x (y- h) w h
205
+ aligned SE (D x y w h) = D (x- w) (y- h) w h
206
+ aligned Baseline dim = aligned SW dim
207
+ aligned N (D x y w h) = D (x- w/ 2 ) y w h
208
+ aligned W (D x y w h) = D x (y- h/ 2 ) w h
209
+ aligned S (D x y w h) = D (x- w/ 2 ) (y- h) w h
210
+ aligned E (D x y w h) = D (x- w) (y- h/ 2 ) w h
211
+ aligned Center (D x y w h) = D (x- w/ 2 ) (y- h/ 2 ) w h
212
+
190
213
-- | takes dimensions with centered position, returns normalized (left corner)
191
- centered (D cx cy w h) = D (cx- w/ 2 ) (cy- h/ 2 ) w h
214
+ centered = aligned Center
215
+
192
216
-- | takes dimensions with bottom-right corner instead of size, returns normalized (with size)
193
217
corners (D xl yl xh yh) = D xl yl (xh- xl) (yh- yl)
194
218
@@ -273,6 +297,7 @@ shape (ShapeRegular closed) ((V2 x y):ps) = drawShape $ do
273
297
C. moveTo x y
274
298
forM_ ps $ \ (V2 x' y') -> C. lineTo x' y'
275
299
when closed $ C. closePath
300
+ shape (ShapeRegular _) _ = return ()
276
301
shape ShapePoints ps = forM_ ps point
277
302
shape ShapeLines (p1: p2: ps) = do
278
303
line p1 p2
@@ -366,7 +391,7 @@ getTime = do
366
391
367
392
----
368
393
369
- data Image = Image { imageSurface :: C. Surface , imageSize :: ( V2 Int ) , imageFormat :: Format }
394
+ data Image = Image { imageSurface :: C. Surface , imageSize :: V2 Int , imageFormat :: Format }
370
395
371
396
-- | create a new empty image of given size
372
397
createImage :: V2 Int -> Canvas Image
@@ -399,20 +424,20 @@ image img@(Image _ (V2 w h) _) (V2 x y) =
399
424
400
425
-- | Render complete image inside given dimensions
401
426
image' :: Image -> Dim -> Canvas ()
402
- image' img@ (Image s (V2 ow oh) _) =
427
+ image' img@ (Image _ (V2 ow oh) _) =
403
428
blend OperatorSource img (D 0 0 (fromIntegral ow) (fromIntegral oh))
404
429
405
430
-- | Copy given part of image to given part of screen, using given blending
406
431
-- operator and resizing when necessary. Use 'OperatorSource' to copy without
407
432
-- blending effects. (Processing: @copy(),blend()@)
408
433
blend :: Operator -> Image -> Dim -> Dim -> Canvas ()
409
- blend op (Image s ( V2 ow oh) _) sdim ddim = do
434
+ blend op (Image s _ _) sdim ddim = do
410
435
surf <- gets csSurface
411
436
renderCairo $ copyFromToSurface op s sdim surf ddim
412
437
413
438
-- | get a copy of the image from current window (Processing: @get()@)
414
439
grab :: Dim -> Canvas Image
415
- grab dim@ (D x y w h) = do
440
+ grab dim@ (D _ _ w h) = do
416
441
surf <- gets csSurface
417
442
i@ (Image s _ _) <- createImage (V2 (round w) (round h))
418
443
renderCairo $ copyFromToSurface OperatorSource surf dim s (D 0 0 w h)
@@ -441,24 +466,21 @@ textSize s = gets csSurface >>= \cs -> do
441
466
442
467
-- | render text left-aligned (coordinate is top-left corner)
443
468
text :: String -> V2 Double -> Canvas ()
444
- text str (V2 x y) = ifColor csFG $ \ c -> do
445
- (C. TextExtents _ yb _ h _ _) <- C. textExtents str
446
- setColor c
469
+ text str (V2 x y) = ifColor csFG $ \ _ -> do
470
+ (C. TextExtents _ yb _ _ _ _) <- C. textExtents str
471
+ -- setColor c
447
472
C. moveTo x (y- yb)
448
473
C. showText str
449
474
450
- -- | render text right-aligned (coordinate is top-right corner)
451
- textR :: String -> V2 Double -> Canvas ()
452
- textR str (V2 x y) = do
453
- (V2 w h) <- textSize str
454
- text str $ V2 (x- w) y
455
-
456
- -- | render text centered (coordinate is central)
457
- textC :: String -> V2 Double -> Canvas ()
458
- textC str (V2 x y) = do
459
- (V2 w h) <- textSize str
460
- text str $ V2 (x- (w/ 2 )) (y- (h/ 2 ))
461
-
475
+ -- | render text with specified alignment. returns x and y advancement
476
+ text' :: String -> Anchor -> V2 Double -> Canvas () -- (V2 Double)
477
+ text' str a pos = ifColor csFG $ \ _ -> do
478
+ (C. TextExtents xb yb w h xa ya) <- C. textExtents str
479
+ let (D x' y' _ _) = aligned a $ toD pos $ V2 w h
480
+ -- setColor c
481
+ C. moveTo x' y'
482
+ C. showText str
483
+ -- return $ V2 xa ya
462
484
463
485
-- helpers --
464
486
@@ -480,7 +502,7 @@ ifColor cf m = get >>= \cs -> case cf cs of
480
502
481
503
-- | convert from 256-value RGBA to Double representation, set color
482
504
setColor :: Color -> Render ()
483
- setColor c @ (V4 r g b a) = C. setSourceRGBA (conv r) (conv g) (conv b) (conv a)
505
+ setColor (V4 r g b a) = C. setSourceRGBA (conv r) (conv g) (conv b) (conv a)
484
506
where conv = ((1.0 / 256 )* ). fromIntegral
485
507
486
508
-- | Add to garbage collection list
@@ -507,8 +529,6 @@ createScaledSurface s (V2 w h) = do
507
529
-- | helper: returns new surface with only part of original content. does NOT cleanup!
508
530
createTrimmedSurface :: C. Surface -> Dim -> Render C. Surface
509
531
createTrimmedSurface s (D x y w h) = do
510
- ow <- C. imageSurfaceGetWidth s
511
- oh <- C. imageSurfaceGetHeight s
512
532
s' <- liftIO $ C. createSimilarSurface s C. ContentColorAlpha (round w) (round h)
513
533
C. renderWith s' $ do
514
534
C. setSourceSurface s (- x) (- y)
@@ -521,7 +541,7 @@ copyFromToSurface :: Operator -> C.Surface -> Dim -> C.Surface -> Dim -> Render
521
541
copyFromToSurface op src sdim@ (D sx sy sw sh) dest (D x y w h) = do
522
542
ow <- C. imageSurfaceGetWidth src
523
543
oh <- C. imageSurfaceGetHeight src
524
- let needsTrim = sx/= 0 || sy/= 0 || round sw/= oh || round sh/= oh
544
+ let needsTrim = sx/= 0 || sy/= 0 || round sw/= ow || round sh/= oh
525
545
needsRescale = round sw/= round w || round sh/= round h
526
546
s' <- if needsTrim then createTrimmedSurface src sdim else return src
527
547
s'' <- if needsRescale then createScaledSurface s' (V2 w h) else return s'
@@ -542,4 +562,3 @@ setFont (Font face sz bold italic) = do
542
562
(if italic then C. FontSlantItalic else C. FontSlantNormal )
543
563
(if bold then C. FontWeightBold else C. FontWeightNormal )
544
564
C. setFontSize sz
545
-
0 commit comments