wumpus-basic-0.13.0: src/Wumpus/Basic/Graphic/GlyphMetrics.hs
{-# LANGUAGE RankNTypes #-}
{-# OPTIONS -Wall #-}
--------------------------------------------------------------------------------
-- |
-- Module : Wumpus.Basic.Graphic.GlyphMetrics
-- Copyright : (c) Stephen Tetley 2010
-- License : BSD3
--
-- Maintainer : Stephen Tetley <stephen.tetley@gmail.com>
-- Stability : highly unstable
-- Portability : GHC
--
-- Data types representing glyph metrics loaded from font files.
--
--------------------------------------------------------------------------------
module Wumpus.Basic.Graphic.GlyphMetrics
(
FontName
, CodePoint
, GlyphMetricsTable(..)
, GlyphMetrics(..)
, buildMetrics
, BaseGlyphMetrics
, monospace_metrics
) where
import Wumpus.Core -- package: wumpus-core
import qualified Data.IntMap as IntMap
import qualified Data.Map as Map
type FontName = String
-- | A Unicode code-point.
--
type CodePoint = Int
-- | NOTE - GlyphMetrics table is parametric on @cu@ -
-- /Character unit/ and not on the usual @u@.
--
data GlyphMetricsTable cu = GlyphMetricsTable
{ glyph_bounding_box :: BoundingBox cu
, glyph_default_adv_vec :: Vec2 cu
, glyph_adv_vecs :: IntMap.IntMap (Vec2 cu)
, glyph_cap_height :: cu
}
-- unit_scale_fun :: PtSize -> cu -> u
--
-- afmValue :: FromPtSize u => AfmUnit -> PtSize -> u
--
data GlyphMetrics = GlyphMetrics
{ get_bounding_box :: forall u. FromPtSize u => PtSize -> BoundingBox u
, get_av_lookup :: forall u. FromPtSize u => PtSize -> (CodePoint -> Vec2 u)
, get_cap_height :: forall u. FromPtSize u => PtSize -> u
}
type BaseGlyphMetrics = Map.Map FontName GlyphMetrics
-- | This ignores the Char code lookup and just returns the
-- default advance vector.
--
monospace_metrics :: GlyphMetrics
monospace_metrics = GlyphMetrics
{ get_bounding_box = \sz -> BBox (lowerLeft sz) (upperRight sz)
, get_av_lookup = \sz _ -> hvec (upscale sz width_vec)
, get_cap_height = \sz -> upscale sz cap_height
}
where
llx = (-23) / 1000
lly = (-250) / 1000
urx = 715 / 1000
ury = 805 / 1000
width_vec = 600 / 1000
cap_height = 562 / 1000
upscale sz d = fromPtSize $ sz * d
lowerLeft sz = P2 (upscale sz llx) (upscale sz lly)
upperRight sz = P2 (upscale sz urx) (upscale sz ury)
buildMetrics :: (cu -> PtSize) -> GlyphMetricsTable cu -> GlyphMetrics
buildMetrics fn (GlyphMetricsTable (BBox ll ur) (V2 vx vy)
vec_table cap_height) =
GlyphMetrics
{ get_bounding_box = \sz -> BBox (scalePt sz ll) (scalePt sz ur)
, get_av_lookup = \sz i ->
maybe (defaultAV sz) (scaleVec sz) $ IntMap.lookup i vec_table
, get_cap_height = \sz -> upscale sz (fn cap_height)
}
where
upscale sz d = fromPtSize $ sz * d
defaultAV sz = V2 (upscale sz $ fn vx) (upscale sz $ fn vy)
scalePt sz (P2 cx cy) = P2 (upscale sz $ fn cx) (upscale sz $ fn cy)
scaleVec sz (V2 cx cy) = V2 (upscale sz $ fn cx) (upscale sz $ fn cy)