1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
{-# LANGUAGE GADTs #-}
-----------------------------------------------------------------------------
-- |
-- Module : Graphics.Rendering.Chart.Backend.Impl
-- Copyright : (c) Tim Docker 2014
-- License : BSD-style (see chart/COPYRIGHT)
--
-- This module provides the implementation details common to all 'ChartBackend's.
module Graphics.Rendering.Chart.Backend.Impl where
import Control.Monad.Reader
import Control.Monad.Operational
import Graphics.Rendering.Chart.Geometry
import Graphics.Rendering.Chart.Backend.Types
-- -----------------------------------------------------------------------
-- Rendering Backend Class
-- -----------------------------------------------------------------------
-- | The abstract drawing operation generated when using the
-- the chart drawing API.
--
-- See the documentation of the different function for the correct semantics
-- of each instruction:
--
-- * 'strokePath', 'fillPath'
--
-- * 'drawText', 'textSize'
--
-- * 'getPointAlignFn', 'getCoordAlignFn', 'AlignmentFns'
--
-- * 'withTransform', 'withClipRegion'
--
-- * 'withLineStyle', 'withFillStyle', 'withFontStyle'
--
data ChartBackendInstr a where
StrokePath :: Path -> ChartBackendInstr ()
FillPath :: Path -> ChartBackendInstr ()
GetTextSize :: String -> ChartBackendInstr TextSize
DrawText :: Point -> String -> ChartBackendInstr ()
GetAlignments :: ChartBackendInstr AlignmentFns
WithTransform :: Matrix -> Program ChartBackendInstr a -> ChartBackendInstr a
WithFontStyle :: FontStyle -> Program ChartBackendInstr a -> ChartBackendInstr a
WithFillStyle :: FillStyle -> Program ChartBackendInstr a -> ChartBackendInstr a
WithLineStyle :: LineStyle -> Program ChartBackendInstr a -> ChartBackendInstr a
WithClipRegion :: Rect -> Program ChartBackendInstr a -> ChartBackendInstr a
-- | A 'ChartBackend' provides the capability to render a chart somewhere.
--
-- The coordinate system of the backend has its initial origin (0,0)
-- in the top left corner of the drawing plane. The x-axis points
-- towards the top right corner and the y-axis points towards
-- the bottom left corner. The unit used by coordinates, the font size,
-- and lengths is the always the same, but depends on the backend.
-- All angles are measured in radians.
--
-- The line, fill and font style are set to their default values
-- initially.
--
-- Information about the semantics of the instructions can be
-- found in the documentation of 'ChartBackendInstr'.
type ChartBackend a = Program ChartBackendInstr a
-- | Stroke the outline of the given path using the
-- current 'LineStyle'. This function does /not/ perform
-- alignment operations on the path. See 'Path' for the exact semantic
-- of paths.
strokePath :: Path -> ChartBackend ()
strokePath p = singleton (StrokePath p)
-- | Fill the given path using the current 'FillStyle'.
-- The given path will be closed prior to filling.
-- This function does /not/ perform
-- alignment operations on the path.
-- See 'Path' for the exact semantic of paths.
fillPath :: Path -> ChartBackend ()
fillPath p = singleton (FillPath p)
-- | Calculate a 'TextSize' object with rendering information
-- about the given string without actually rendering it.
textSize :: String -> ChartBackend TextSize
textSize text = singleton (GetTextSize text)
-- | Draw a single-line textual label anchored by the baseline (vertical)
-- left (horizontal) point. Uses the current 'FontStyle' for drawing.
drawText :: Point -> String -> ChartBackend ()
drawText p text = singleton (DrawText p text)
-- | Apply the given transformation in this local
-- environment when drawing. The given transformation
-- is applied after the current transformation. This
-- means both are combined.
withTransform :: Matrix -> ChartBackend a -> ChartBackend a
withTransform t p = singleton (WithTransform t p)
-- | Use the given font style in this local
-- environment when drawing text.
--
-- An implementing backend is expected to guarentee
-- to support the following font families: @serif@, @sans-serif@ and @monospace@;
--
-- If the backend is not able to find or load a given font
-- it is required to fall back to a custom fail-safe font
-- and use it instead.
withFontStyle :: FontStyle -> ChartBackend a -> ChartBackend a
withFontStyle fs p = singleton (WithFontStyle fs p)
-- | Use the given fill style in this local
-- environment when filling paths.
withFillStyle :: FillStyle -> ChartBackend a -> ChartBackend a
withFillStyle fs p = singleton (WithFillStyle fs p)
-- | Use the given line style in this local
-- environment when stroking paths.
withLineStyle :: LineStyle -> ChartBackend a -> ChartBackend a
withLineStyle ls p = singleton (WithLineStyle ls p)
-- | Use the given clipping rectangle when drawing
-- in this local environment. The new clipping region
-- is intersected with the given clip region. You cannot
-- escape the clip!
withClipRegion :: Rect -> ChartBackend a -> ChartBackend a
withClipRegion c p = singleton (WithClipRegion c p)
-- -----------------------------------------------------------------------
-- Rendering Utility Functions
-- -----------------------------------------------------------------------
-- | Get the point alignment function
getPointAlignFn :: ChartBackend (Point->Point)
getPointAlignFn = liftM afPointAlignFn (singleton GetAlignments)
-- | Get the coordinate alignment function
getCoordAlignFn :: ChartBackend (Point->Point)
getCoordAlignFn = liftM afCoordAlignFn (singleton GetAlignments)
|