@@ 3,6 3,7 @@
module Graphics.Text.Font.Render where
import Data.Map (Map)
+import Data.Int (Int32)
import Data.IntMap (IntMap)
import qualified Data.IntMap as IM
import Linear.V2 (V2(..))
@@ 10,6 11,7 @@ import Linear.V (toV, dim, Finite, Size)
import FreeType.Core.Base (FT_Library, FT_Face,
FT_GlyphSlotRec(..), FT_Glyph_Metrics(..))
import FreeType.Core.Types (FT_Bitmap(..))
+import Data.Text.Glyphize (GlyphInfo(..), GlyphPos(..))
import Graphics.GL as GL
import qualified Graphics.GL.Core32 as GL
@@ 34,10 36,7 @@ import qualified Data.Vector.Unboxed as UV
data GlyphMetrics = GlyphMetrics {
glyphTexBB :: (V2 Int, V2 Int),
glyphTexSize :: V2 Int,
- glyphSize :: V2 Int,
- glyphHoriBearing :: V2 Int,
- glyphVertBearing :: V2 Int,
- glyphAdvance :: V2 Int
+ glyphSize :: V2 Int
} deriving (Show, Eq)
data Atlas = Atlas {
@@ 62,7 61,7 @@ emptyAM = AM 0 (V2 1 1) 0 mempty
spacing :: Int
spacing = 1
-measure cb maxw am@AM{..} glyph
+measure cb maxw am@AM{..} (GlyphInfo {codepoint = glyph}, _)
| Just _ <- IM.lookup (fromEnum glyph) amMap = return am
| otherwise = do
let V2 x y = amXY
@@ 84,7 83,7 @@ measure cb maxw am@AM{..} glyph
}
return am
-texturize cb xymap atlas@Atlas{..} glyph
+texturize cb xymap atlas@Atlas{..} (GlyphInfo {codepoint = glyph}, _)
| Just pos@(V2 x y) <- IM.lookup (fromIntegral $ fromEnum glyph) xymap = do
(bmp, metrics) <- cb glyph
glTexSubImage2D GL.GL_TEXTURE_2D 0
@@ 101,10 100,7 @@ texturize cb xymap atlas@Atlas{..} glyph
mtrcs = GlyphMetrics {
glyphTexBB = (pos, pos + vecwh),
glyphTexSize = vecwh,
- glyphSize = vecsz,
- glyphHoriBearing = vecxb,
- glyphVertBearing = vecyb,
- glyphAdvance = vecad
+ glyphSize = vecsz
}
return atlas { atlasMetrics = IM.insert (fromEnum glyph) mtrcs atlasMetrics }
| otherwise = do
@@ 139,34 135,45 @@ allocAtlas cb glyphs = do
freeAtlas a = with (atlasTexture a) $ \ptr -> glDeleteTextures 1 ptr
-makeCharQuad Atlas {..} (penx, mLast) glyph = do
+type Quads = (Float, Float, [(V2 Float, V2 Float)])
+makeCharQuad :: Atlas -> Quads -> (GlyphInfo, GlyphPos) -> IO Quads
+makeCharQuad Atlas {..} (penx, peny, mLast) (GlyphInfo {codepoint=glyph}, GlyphPos {..}) = do
let iglyph = fromEnum glyph
case IM.lookup iglyph atlasMetrics of
- Nothing -> return (penx, mLast)
+ Nothing -> return (penx, peny, mLast)
Just GlyphMetrics {..} -> do
- -- TODO incorporate Harfbuzz positioning.
- let V2 dx dy = fromIntegral <$> glyphHoriBearing
- x = (fromIntegral penx) + dx
- y = -dy
- V2 w h = fromIntegral <$> glyphSize
- V2 aszW aszH = fromIntegral <$> atlasTextureSize
- V2 texL texT = fromIntegral <$> fst glyphTexBB
- V2 texR texB = fromIntegral <$> snd glyphTexBB
+ let x = penx + f x_offset
+ y = peny + f y_offset
+ V2 w h = f' <$> glyphSize
+ V2 aszW aszH = f' <$> atlasTextureSize
+ V2 texL texT = f' <$> fst glyphTexBB
+ V2 texR texB = f' <$> snd glyphTexBB
tl = (V2 (x) y, V2 (texL/aszW) (texT/aszH))
tr = (V2 (x+w) y, V2 (texR/aszW) (texT/aszH))
br = (V2 (x+w) (y+h), V2 (texR/aszW) (texB/aszH))
bl = (V2 (x) (y+h), V2 (texL/aszW) (texB/aszH))
- let V2 ax _ = glyphAdvance
-
- return (penx + ax, mLast ++ [tl, tr, br, tl, br, bl])
-
-stringTris atlas = foldM (makeCharQuad atlas) (0, [])
+ return (penx + f x_advance, peny + f y_advance,
+ mLast ++ [tl, tr, br, tl, br, bl])
+ where
+ f :: Int32 -> Float
+ f = fromIntegral
+ f' :: Int -> Float
+ f' = fromIntegral
+
+stringTris :: Atlas -> [(GlyphInfo, GlyphPos)] -> IO Quads
+stringTris atlas = foldM (makeCharQuad atlas) (0, 0, [])
+stringTris' :: Atlas -> [(GlyphInfo, GlyphPos)] -> IO [(V2 Float, V2 Float)]
+stringTris' atlas glyphs = do
+ (_, _, ret) <- stringTris atlas glyphs
+ return ret
+
+drawGlyphs :: Atlas -> [(GlyphInfo, GlyphPos)] -> IO ()
drawGlyphs atlas@Atlas {..} glyphs = do
glBindTexture GL.GL_TEXTURE_2D atlasTexture
- (geom', texcoords') <- unzip <$> snd <$> stringTris atlas glyphs
+ (geom', texcoords') <- unzip <$> stringTris' atlas glyphs
geom <- newBuffer
texcoords <- newBuffer
bufferGeometry 0 geom $ UV.fromList geom'
@@ 177,6 184,7 @@ drawGlyphs atlas@Atlas {..} glyphs = do
--- OpenGL Utilities
------
+newBuffer :: IO GLuint
newBuffer = do
[b] <- allocaArray 1 $ \ptr -> do
glGenBuffers 1 ptr
@@ 60,7 60,7 @@ library
-- other-extensions:
-- Other library packages from which modules are imported.
- build-depends: base >=4.12 && <4.13, linear, containers, freetype2, gl, vector
+ build-depends: base >=4.12 && <4.13, linear, containers, freetype2, gl, vector, harfbuzz-pure
-- Directories containing source files.
hs-source-dirs: src