summaryrefslogtreecommitdiff
path: root/src/Graphics/Fountainhead/Dumper.hs
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2024-02-02 01:44:49 +0100
committerEugen Wissner <belka@caraus.de>2024-02-02 01:44:49 +0100
commit34d3ece99e438e5e81f4df6ca7a36de307e41b3e (patch)
tree27bbf00b10d8cc9fb43cf7462e46c4482505ee89 /src/Graphics/Fountainhead/Dumper.hs
parent1bcff4c5191cc6c016b8dce77e27ffa8ad46f40c (diff)
downloadfountainhead-34d3ece99e438e5e81f4df6ca7a36de307e41b3e.tar.gz
Dump compound glyph info
Diffstat (limited to 'src/Graphics/Fountainhead/Dumper.hs')
-rw-r--r--src/Graphics/Fountainhead/Dumper.hs83
1 files changed, 79 insertions, 4 deletions
diff --git a/src/Graphics/Fountainhead/Dumper.hs b/src/Graphics/Fountainhead/Dumper.hs
index 06756cb..adda06f 100644
--- a/src/Graphics/Fountainhead/Dumper.hs
+++ b/src/Graphics/Fountainhead/Dumper.hs
@@ -14,6 +14,7 @@
module Graphics.Fountainhead.Dumper
( DumpError(..)
, dumpCmap
+ , dumpGlyf
, dumpHead
, dumpHmtx
, dumpHhea
@@ -38,16 +39,20 @@ import qualified Data.Text.Encoding as Text
import qualified Data.Text.Lazy as Text.Lazy
import qualified Data.Text.Lazy.Builder as Text.Builder
import qualified Data.Text.Lazy.Builder.Int as Text.Builder
+import qualified Data.Text.Lazy.Builder.RealFloat as Text.Builder
import Data.Vector (Vector)
import qualified Data.Vector as Vector
import Data.Void
import GHC.Records (HasField(..))
import Graphics.Fountainhead.TrueType
( CmapTable(..)
+ , CompoundGlyphDefinition(..)
+ , ComponentGlyphPartDescription(..)
, FontDirectory(..)
, FontDirectionHint(..)
, GASPRange(..)
, GASPTable(..)
+ , GlyphArgument(..)
, HeadTable(..)
, HheaTable(..)
, HmtxTable(..)
@@ -61,6 +66,7 @@ import Graphics.Fountainhead.TrueType
, CmapSubtable(..)
, CmapFormat4Table(..)
, FontStyle(..)
+ , GlyphArgument(..)
, GlyphCoordinate(..)
, GlyphDefinition(..)
, GlyphDescription(..)
@@ -83,7 +89,9 @@ import Graphics.Fountainhead.TrueType
, Panose(..)
, SimpleGlyphDefinition(..)
, CVTable(..)
- , OutlineFlag (..)
+ , OutlineFlag(..)
+ , ComponentGlyphFlags(..)
+ , GlyphTransformationOption(..)
)
import qualified Text.Megaparsec as Megaparsec
import Graphics.Fountainhead.Parser
@@ -102,9 +110,14 @@ import Graphics.Fountainhead.Parser
, cvTableP
, glyfTableP
)
-import Graphics.Fountainhead.Type (Fixed32(..), succIntegral, ttfEpoch)
+import Graphics.Fountainhead.Type
+ ( Fixed32(..)
+ , succIntegral
+ , ttfEpoch
+ , fixed2Double
+ )
import Data.Foldable (Foldable(..), find)
-import Data.Maybe (fromMaybe)
+import Data.Maybe (fromMaybe, catMaybes)
import Data.Time (LocalTime(..), NominalDiffTime, diffLocalTime, midnight)
import Data.Bits (Bits(..), (.>>.))
import Data.Bifunctor (Bifunctor(first))
@@ -670,7 +683,69 @@ dumpGlyf (GlyfTable glyfDescriptions) = dumpCaption "'glyf' Table - Glyf data"
<> " Coordinates" <> newlineBuilder
<> " -----------" <> newlineBuilder
<> fst (Vector.ifoldl' foldCoordinate mempty coordinates)
- dumpGlyphDefinition _ = "" -- TODO
+ dumpGlyphDefinition (CompoundGlyph CompoundGlyphDefinition{..})
+ = foldMap (dumpCompoundGlyph $ Vector.length components) (Vector.indexed components)
+ <> newlineBuilder <> " Length of Instructions: "
+ <> Text.Builder.decimal (Vector.length instructions) <> newlineBuilder
+ dumpCompoundGlyph :: Int -> (Int, ComponentGlyphPartDescription) -> Text.Builder.Builder
+ dumpCompoundGlyph componentsLength (componentIndex, description) =
+ let moreComponents = succ componentIndex < componentsLength
+ compoundFlags = dumpCompoundFlags moreComponents description
+ ComponentGlyphPartDescription{..} = description
+ in " " <> Text.Builder.decimal componentIndex
+ <> ": Flags: 0x" <> compoundFlags <> newlineBuilder
+ <> " Glyf Index: " <> Text.Builder.decimal glyphIndex <> newlineBuilder
+ <> " X" <> dumpArgument argument1 <> newlineBuilder
+ <> " Y" <> dumpArgument argument2 <> newlineBuilder
+ <> dumpTransformationOption transformationOption
+ <> " Others: " <> dumpOtherFlags flags <> newlineBuilder
+ <> newlineBuilder -- TODO
+ dumpTransformationOption GlyphNoScale = ""
+ dumpTransformationOption (GlyphScale scale) =
+ " X,Y Scale: " <> Text.Builder.realFloat (fixed2Double scale) <> newlineBuilder
+ dumpTransformationOption (GlyphXyScale xScale yScale)
+ = " X Scale: " <> Text.Builder.realFloat (fixed2Double xScale) <> newlineBuilder
+ <> " Y Scale: " <> Text.Builder.realFloat (fixed2Double yScale) <> newlineBuilder
+ dumpTransformationOption (Glyph2By2Scale xScale scale01 scale10 yScale)
+ = " X Scale: " <> Text.Builder.realFloat (fixed2Double xScale) <> newlineBuilder
+ <> " X,Y Scale: " <> Text.Builder.realFloat (fixed2Double scale01) <> newlineBuilder
+ <> " Y,X Scale: " <> Text.Builder.realFloat (fixed2Double scale10) <> newlineBuilder
+ <> " Y Scale: " <> Text.Builder.realFloat (fixed2Double yScale) <> newlineBuilder
+ dumpOtherFlags ComponentGlyphFlags{..} =
+ let roundXyToGridText = if roundXyToGrid then "Round X,Y to Grid " else " "
+ useMyMetricsText = if useMyMetrics then "Use My Metrics " else " "
+ overlapCompoundText = if overlapCompound then "Overlap " else " "
+ in roundXyToGridText <> overlapCompoundText <> useMyMetricsText
+ dumpCompoundFlags :: Bool -> ComponentGlyphPartDescription -> Text.Builder.Builder
+ dumpCompoundFlags moreComponents ComponentGlyphPartDescription{..} =
+ let setBits = glyphArgumentBits argument1
+ <> componentFlagBits flags
+ <> transformationOptionBits transformationOption
+ setBits' = if moreComponents then 5 : setBits else setBits
+ in Text.Builder.hexadecimal
+ $ foldr (flip setBit) (zeroBits :: Word16) setBits'
+ dumpArgument (GlyphInt8Argument argument) =
+ " BOffset: " <> Text.Builder.decimal argument
+ dumpArgument (GlyphInt16Argument argument) =
+ " WOffset: " <> Text.Builder.decimal argument
+ dumpArgument (GlyphWord8Argument argument) =
+ " BPoint: " <> Text.Builder.decimal argument
+ dumpArgument (GlyphWord16Argument argument) =
+ " WPoint: " <> Text.Builder.decimal argument
+ glyphArgumentBits (GlyphInt16Argument _) = [0, 1]
+ glyphArgumentBits (GlyphWord16Argument _) = [0]
+ glyphArgumentBits (GlyphInt8Argument _) = [1]
+ glyphArgumentBits (GlyphWord8Argument _) = []
+ componentFlagBits ComponentGlyphFlags{..} = catMaybes
+ [ if roundXyToGrid then Just 2 else Nothing
+ , if weHaveInstructions then Just 8 else Nothing
+ , if useMyMetrics then Just 9 else Nothing
+ , if overlapCompound then Just 10 else Nothing
+ ]
+ transformationOptionBits GlyphScale{} = [3]
+ transformationOptionBits GlyphXyScale{} = [6]
+ transformationOptionBits Glyph2By2Scale{} = [7]
+ transformationOptionBits GlyphNoScale = []
dumpFlag lineValue coordinateIndex
= " " <> justifyNumber 2 coordinateIndex <> lineValue
foldFlag :: (Text.Builder.Builder, Int) -> OutlineFlag -> (Text.Builder.Builder, Int)