diff options
| author | Eugen Wissner <belka@caraus.de> | 2023-12-27 16:19:21 +0100 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2023-12-27 16:19:21 +0100 |
| commit | 16d9fc384fa6180c8b7e875bd95065adce346c30 (patch) | |
| tree | 5096daddd5aff7d21dbed6085484297b1b8a6583 /src/Graphics/Fountainhead.hs | |
| parent | a841f138fc9055f4bc32db292a675f93f081b4e7 (diff) | |
| download | fountainhead-16d9fc384fa6180c8b7e875bd95065adce346c30.tar.gz | |
Decompress defalte compressed fonts
Diffstat (limited to 'src/Graphics/Fountainhead.hs')
| -rw-r--r-- | src/Graphics/Fountainhead.hs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/Graphics/Fountainhead.hs b/src/Graphics/Fountainhead.hs new file mode 100644 index 0000000..f965680 --- /dev/null +++ b/src/Graphics/Fountainhead.hs @@ -0,0 +1,50 @@ +{- This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. -} + +module Graphics.Fountainhead + ( parseFontDirectoryFromFile + ) where + +import qualified Codec.Compression.Zlib as Zlib +import Data.ByteString (ByteString) +import qualified Data.ByteString as ByteString +import qualified Data.ByteString.Lazy as ByteString.Lazy +import Data.Void (Void) +import Graphics.Fountainhead.Parser (ParseErrorBundle, fontDirectoryP) +import Graphics.Fountainhead.TrueType (FontDirectory(..)) +import qualified Text.Megaparsec as Megaparsec +import Text.Megaparsec (PosState(..), State(..)) +import System.IO (IOMode(..), SeekMode(..), hFileSize, hSeek, withBinaryFile) + +parseFontDirectoryFromFile :: String + -> IO (State ByteString Void, Either ParseErrorBundle FontDirectory) +parseFontDirectoryFromFile fontFile = + withBinaryFile fontFile ReadMode withFontHandle + where + withFontHandle fontHandle = doParsing + <$> readFontContents fontHandle + doParsing ttfContents = + let initialState = Megaparsec.State + { stateInput = ttfContents + , stateOffset = 0 + , statePosState = Megaparsec.PosState + { pstateInput = ttfContents + , pstateOffset = 0 + , pstateSourcePos = Megaparsec.initialPos fontFile + , pstateTabWidth = Megaparsec.defaultTabWidth + , pstateLinePrefix = "" + } + , stateParseErrors = [] + } + in Megaparsec.runParser' fontDirectoryP initialState + readFontContents fontHandle = do + firstBytes <- ByteString.unpack <$> ByteString.hGet fontHandle 2 + hSeek fontHandle AbsoluteSeek 0 + fileSize <- fromIntegral <$> hFileSize fontHandle + case firstBytes of + 0x78 : [secondByte] + | secondByte `elem` [0x01, 0x9c, 0x5e, 0xda] -> + ByteString.Lazy.toStrict . Zlib.decompress + <$> ByteString.Lazy.hGet fontHandle fileSize + _ -> ByteString.hGetContents fontHandle |
