summaryrefslogtreecommitdiff
path: root/lib/Graphics/Fountainhead/Dumper.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Graphics/Fountainhead/Dumper.hs')
-rw-r--r--lib/Graphics/Fountainhead/Dumper.hs102
1 files changed, 67 insertions, 35 deletions
diff --git a/lib/Graphics/Fountainhead/Dumper.hs b/lib/Graphics/Fountainhead/Dumper.hs
index c3ba277..d3e2eec 100644
--- a/lib/Graphics/Fountainhead/Dumper.hs
+++ b/lib/Graphics/Fountainhead/Dumper.hs
@@ -14,6 +14,7 @@
module Graphics.Fountainhead.Dumper
( DumpError(..)
, dumpCmap
+ , dumpGASP
, dumpGlyf
, dumpHead
, dumpHmtx
@@ -23,6 +24,7 @@ module Graphics.Fountainhead.Dumper
, dumpMaxp
, dumpOs2
, dumpPost
+ , dumpTable
, dumpTables
, dumpTrueType
, dumpOffsetTable
@@ -95,7 +97,9 @@ import Graphics.Fountainhead.TrueType
)
import qualified Text.Megaparsec as Megaparsec
import Graphics.Fountainhead.Parser
- ( fontDirectoryP
+ ( ParseErrorBundle
+ , ParseState
+ , fontDirectoryP
, parseTable
, cmapTableP
, headTableP
@@ -128,6 +132,7 @@ import Prelude hiding (repeat)
data DumpError
= DumpParseError (Megaparsec.ParseErrorBundle ByteString Void)
| DumpRequiredTableMissingError String
+ | DumpRequestedTableMissingError String
deriving Eq
instance Show DumpError
@@ -135,6 +140,8 @@ instance Show DumpError
show (DumpParseError errorBundle) = Megaparsec.errorBundlePretty errorBundle
show (DumpRequiredTableMissingError tableName) =
"Required table " <> tableName <> " is missing."
+ show (DumpRequestedTableMissingError tableName) =
+ "Requested table " <> tableName <> " is missing."
data RequiredTables = RequiredTables
{ hheaTable :: HheaTable
@@ -785,53 +792,78 @@ dumpGlyf (GlyfTable glyfDescriptions) = dumpCaption "'glyf' Table - Glyf data"
= "(" <> justifyNumber 7 coordinateX <> ", "
<> justifyNumber 7 coordinateY <> ")"
+dumpTable
+ :: String
+ -> ParseState
+ -> FontDirectory
+ -> Either DumpError Text.Builder.Builder
+dumpTable needle processedState FontDirectory{..}
+ | Just neededTable <- find ((needle ==) . Char8.unpack . getField @"tag") tableDirectory
+ = parseRequired processedState tableDirectory
+ >>= maybe (pure mempty) (first DumpParseError)
+ . dumpSubTable processedState neededTable
+ | otherwise = Left $ DumpRequestedTableMissingError needle
+
dumpTables
- :: Megaparsec.State ByteString Void
+ :: ParseState
-> FontDirectory
-> Either DumpError Text.Builder.Builder
dumpTables processedState directory@FontDirectory{..}
- = parseRequired >>= traverseDirectory
+ = parseRequired processedState tableDirectory >>= traverseDirectory
where
traverseDirectory parsedRequired =
let initial = Right $ dumpOffsetTable directory
in foldl' (go parsedRequired) initial tableDirectory
- parseRequired = do
- requiredHhea <- findRequired "hhea" hheaTableP
- requiredHead@HeadTable{ indexToLocFormat } <-
- findRequired "head" headTableP
- requiredLoca <- findRequired "loca" (locaTableP indexToLocFormat)
- pure $ RequiredTables
- { hheaTable = requiredHhea
- , headTable = requiredHead
- , locaTable = requiredLoca
- }
- findRequired tableName parser =
- let missingError = Left $ DumpRequiredTableMissingError tableName
- parseFound tableEntry = parseTable tableEntry parser processedState
- in maybe missingError (first DumpParseError . parseFound)
- $ find ((== Char8.pack tableName) . getField @"tag") tableDirectory
go _ (Left accumulator) _ = Left accumulator
go parsedRequired (Right accumulator) tableEntry
= maybe (Right accumulator) (concatDump accumulator . first DumpParseError)
- $ dumpSubTable parsedRequired tableEntry
+ $ dumpSubTable processedState tableEntry parsedRequired
concatDump accumulator builderDump = ((accumulator <> newlineBuilder) <>)
<$> builderDump
- dumpSubTable RequiredTables{..} tableEntry =
- case getField @"tag" tableEntry of
- "cmap" -> Just $ dumpCmap <$> parseTable tableEntry cmapTableP processedState
- "head" -> Just $ Right $ dumpHead headTable
- "hhea" -> Just $ Right $ dumpHhea hheaTable
- "hmtx" -> Just $ dumpHmtx
- <$> parseTable tableEntry (hmtxTableP $ getField @"numOfLongHorMetrics" hheaTable) processedState
- "loca" -> Just $ Right $ dumpLoca locaTable
- "maxp" -> Just $ dumpMaxp <$> parseTable tableEntry maxpTableP processedState
- "name" -> Just $ dumpName <$> parseTable tableEntry nameTableP processedState
- "post" -> Just $ dumpPost <$> parseTable tableEntry postTableP processedState
- "OS/2" -> Just $ dumpOs2 <$> parseTable tableEntry os2TableP processedState
- "cvt " -> Just $ dumpCVTable <$> parseTable tableEntry cvTableP processedState
- "gasp" -> Just $ dumpGASP <$> parseTable tableEntry gaspTableP processedState
- "glyf" -> Just $ dumpGlyf <$> parseTable tableEntry (glyfTableP locaTable) processedState
- _ -> Nothing
+
+parseRequired
+ :: (Foldable t)
+ => ParseState
+ -> t TableDirectory
+ -> Either DumpError RequiredTables
+parseRequired processedState tableDirectory = do
+ requiredHhea <- findRequired "hhea" hheaTableP
+ requiredHead@HeadTable{ indexToLocFormat } <-
+ findRequired "head" headTableP
+ requiredLoca <- findRequired "loca" (locaTableP indexToLocFormat)
+ pure $ RequiredTables
+ { hheaTable = requiredHhea
+ , headTable = requiredHead
+ , locaTable = requiredLoca
+ }
+ where
+ findRequired tableName parser =
+ let missingError = Left $ DumpRequiredTableMissingError tableName
+ parseFound tableEntry = parseTable tableEntry parser processedState
+ in maybe missingError (first DumpParseError . parseFound)
+ $ find ((== Char8.pack tableName) . getField @"tag") tableDirectory
+
+dumpSubTable
+ :: ParseState
+ -> TableDirectory
+ -> RequiredTables
+ -> Maybe (Either ParseErrorBundle Text.Builder.Builder)
+dumpSubTable processedState tableEntry RequiredTables{..} =
+ case getField @"tag" tableEntry of
+ "cmap" -> Just $ dumpCmap <$> parseTable tableEntry cmapTableP processedState
+ "head" -> Just $ Right $ dumpHead headTable
+ "hhea" -> Just $ Right $ dumpHhea hheaTable
+ "hmtx" -> Just $ dumpHmtx
+ <$> parseTable tableEntry (hmtxTableP $ getField @"numOfLongHorMetrics" hheaTable) processedState
+ "loca" -> Just $ Right $ dumpLoca locaTable
+ "maxp" -> Just $ dumpMaxp <$> parseTable tableEntry maxpTableP processedState
+ "name" -> Just $ dumpName <$> parseTable tableEntry nameTableP processedState
+ "post" -> Just $ dumpPost <$> parseTable tableEntry postTableP processedState
+ "OS/2" -> Just $ dumpOs2 <$> parseTable tableEntry os2TableP processedState
+ "cvt " -> Just $ dumpCVTable <$> parseTable tableEntry cvTableP processedState
+ "gasp" -> Just $ dumpGASP <$> parseTable tableEntry gaspTableP processedState
+ "glyf" -> Just $ dumpGlyf <$> parseTable tableEntry (glyfTableP locaTable) processedState
+ _ -> Nothing
dumpTrueType :: ByteString -> FilePath -> Either DumpError Text.Builder.Builder
dumpTrueType ttfContents fontFile =