forked from dagit/freetype2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain.hs
120 lines (106 loc) · 3.96 KB
/
Main.hs
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
module Main where
import Control.Monad
import System.Environment
import Graphics.Rendering.FreeType.Internal as FT
import Graphics.Rendering.FreeType.Internal.Matrix as M
import Graphics.Rendering.FreeType.Internal.Vector as V
import Graphics.Rendering.FreeType.Internal.GlyphSlot as GS
import Graphics.Rendering.FreeType.Internal.PrimitiveTypes as PT
import Graphics.Rendering.FreeType.Internal.Face as F
import Graphics.Rendering.FreeType.Internal.Bitmap as B
import Foreign
import Foreign.Marshal
import Foreign.C.String
import System.Exit
import Data.Array.IO as A
runFreeType :: IO FT_Error -> IO ()
runFreeType m = do
r <- m
unless (r == 0) $ fail $ "FreeType Error:" ++ show r
main :: IO ()
main = do
let display_width = 640
display_height = 480
angle = (25 / 360) * pi * 2
matrix <- mallocForeignPtr
pen <- mallocForeignPtr
withForeignPtr matrix $ \p-> poke p (FT_Matrix
{ xx = round $ cos angle * 0x10000
, xy = round $ -(sin angle * 0x10000)
, yx = round $ sin angle * 0x10000
, yy = round $ cos angle * 0x10000
})
withForeignPtr pen $ \p -> poke p (FT_Vector
{ x = 300 * 64
, y = (display_height - 200) * 64
})
(filename:text:_) <- getArgs
putStrLn $ concat ["Loading file: ", filename]
putStrLn $ concat ["Drawing text: ", text]
library <- alloca $ \libraryptr -> do
putStr "Library ptr: "
print libraryptr
runFreeType $ ft_Init_FreeType libraryptr
peek libraryptr
face <- alloca $ \faceptr -> do
putStr "Face ptr: "
print faceptr
withCString filename $ \str -> do
runFreeType $ ft_New_Face library str 0 faceptr
peek faceptr
image <- A.newArray
((0,0), (fromIntegral display_height - 1, fromIntegral display_width - 1)) 0
:: IO (IOUArray (Int, Int) Int)
runFreeType $ ft_Set_Char_Size face (50*64) 0 100 0
forM_ text $ \c -> do
withForeignPtr matrix $ \mp ->
withForeignPtr pen $ \pp -> do
ft_Set_Transform face mp pp
slot <- peek $ glyph face
runFreeType $
ft_Load_Char face (fromIntegral . fromEnum $ c) ft_LOAD_RENDER
numFaces <- peek $ num_faces face
putStrLn $ "face->num_faces = " ++ show numFaces
v <- peek $ advance slot
putStrLn $ "advance: " ++ show v
numGlyphs <- peek $ num_glyphs face
putStrLn $ "numGlyphs = " ++ show numGlyphs
pen' <- peek pp
poke pp $ FT_Vector { x = x v + x pen'
, y = y v + y pen' }
b <- peek $ bitmap slot
left <- peek $ bitmap_left slot
top <- peek $ bitmap_top slot
let b_top = fromIntegral display_height - top
b_right = left + width b
b_bottom = fromIntegral . fromEnum $ b_top + rows b
unless (b_right >= display_width || b_bottom >= display_height) $
drawBitmap b image left b_top
showImage image
runFreeType $ ft_Done_Face face
runFreeType $ ft_Done_FreeType library
drawBitmap :: FT_Bitmap -> IOUArray (Int, Int) Int
-> FT_Int -> FT_Int -> IO ()
drawBitmap bitmap image x y = do
let xMax = x + width bitmap
yMax = y + rows bitmap
forM_ (zip [ x .. xMax - 1] [0 .. ]) $ \(i,p) ->
forM_ (zip [ y .. yMax - 1] [0 .. ]) $ \(j,q) -> do
let index = q * width bitmap + p
v <- readArray image (fromIntegral j, fromIntegral i) :: IO Int
b <- peek $ (buffer bitmap) `plusPtr` fromIntegral index
writeArray image (fromIntegral j, fromIntegral i) $ v .|. b
showImage :: IOUArray (Int, Int) Int -> IO ()
showImage image = do
((hmin,wmin), (hmax,wmax)) <- getBounds image
forM_ [ hmin .. hmax - 1 ] $ \i -> do
forM_ [ wmin .. wmax - 1 ] $ \j -> do
v <- readArray image (i,j)
putc v
putChar '\n'
where
putc :: Int -> IO ()
putc c
| c == 0 = putChar '0'
| c < 128 = putChar '+'
| otherwise = putChar '*'