Dump segment character index mapping

This commit is contained in:
Eugen Wissner 2023-11-15 21:25:18 +01:00
parent e5ed4f1b96
commit 3414b4cab6

View File

@ -18,11 +18,13 @@ module Graphics.Fountainhead.Dumper
import Data.ByteString (ByteString)
import Data.Int (Int64)
import Data.Word (Word16)
import qualified Data.IntMap as IntMap
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 Data.Vector (Vector)
import qualified Data.Vector as Vector
import Data.Void
import GHC.Records (HasField(..))
@ -42,6 +44,7 @@ import Graphics.Fountainhead.Parser
, cmapTableP
)
import Data.Foldable (Foldable(..))
import Data.Maybe (fromMaybe)
type ParseErrorOrDump
= Either (Megaparsec.ParseErrorBundle ByteString Void) Text.Builder.Builder
@ -128,6 +131,7 @@ dumpCmap CmapTable{..}
(CmapFormat2 _) -> "Format 2"
(CmapFormat4 CmapFormat4Table{..}) ->
let segCount = Vector.length startCode
dumpSegment' = dumpSegment segCount glyphIndexArray
in "Format 4 - Segment mapping to delta values\n\
\ Length: 994\n\
\ Version: 0\n\
@ -140,14 +144,32 @@ dumpCmap CmapTable{..}
<> newlineBuilder <> " rangeShift: "
<> Text.Builder.decimal (segCount * 2 - fromIntegral searchRange)
<> newlineBuilder
<> fold (Vector.izipWith4 (dumpSegment segCount) startCode endCode idDelta idRangeOffset)
<> fold (Vector.izipWith4 (dumpSegmentSummary segCount) startCode endCode idDelta idRangeOffset)
<> " Number of glyphIndex "
<> Text.Builder.decimal (Vector.length glyphIndexArray) <> newlineBuilder
<> fold (Vector.imap dumpGlyphAtIndex glyphIndexArray)
<> fold (Vector.izipWith4 dumpSegment' startCode endCode idDelta idRangeOffset)
(CmapFormat6 _) -> "Format 6"
(CmapFormat8 _) -> "Format 8"
(CmapFormat10 _) -> "Format 10"
(CmapFormat12 _) -> "Format 12"
(CmapFormat13 _) -> "Format 13"
(CmapFormat14 _) -> "Format 14"
dumpSegment segCount index startCode' endCode' idDelta' idRangeOffset'
dumpSegment :: Int -> Vector Word16 -> Int -> Word16 -> Word16 -> Word16 -> Word16 -> Text.Builder.Builder
dumpSegment segCount glyphIndexArray' segmentIndex startCode' endCode' idDelta' idRangeOffset' =
let charRange = [startCode'..endCode']
dumpSegmentCharIndex' =
dumpSegmentCharIndex segCount glyphIndexArray' segmentIndex idDelta' idRangeOffset' startCode'
in "Segment " <> Text.Builder.decimal segmentIndex <> ":\n"
<> foldMap dumpSegmentCharIndex' charRange
dumpSegmentCharIndex segCount glyphIndexArray' segmentIndex idDelta' idRangeOffset' startCode' charCode =
let calculateGlyphIndex' =
calculateGlyphIndex charCode segmentIndex segCount glyphIndexArray' idRangeOffset' idDelta' startCode'
in " Char 0x"
<> halfPaddedHexadecimal charCode <> " -> Index "
<> Text.Builder.decimal calculateGlyphIndex'
<> newlineBuilder
dumpSegmentSummary segCount index startCode' endCode' idDelta' idRangeOffset'
= " Seg " <> justifyNumber 5 index
<> " : St = " <> halfPaddedHexadecimal startCode'
<> ", En = " <> halfPaddedHexadecimal endCode'
@ -155,9 +177,23 @@ dumpCmap CmapTable{..}
<> ", RO = " <> justifyNumber 6 idRangeOffset'
<> ", gId# = " <> dumpGlyphId index segCount idRangeOffset'
<> newlineBuilder
dumpGlyphId index segCount idRangeOffset'
| idRangeOffset' == 0 = "N/A"
| otherwise = Text.Builder.decimal $ index - segCount + (fromIntegral idRangeOffset' `div` 2)
dumpGlyphId segmentIndex segCount idRangeOffset'
= maybe "N/A" Text.Builder.decimal
$ calculateGlyphId segmentIndex segCount idRangeOffset'
calculateGlyphIndex :: Word16 -> Int -> Int -> Vector Word16 -> Word16 -> Word16 -> Word16 -> Int
calculateGlyphIndex c segmentIndex segCount glyphIndexArray' idRangeOffset' idDelta' startCode' =
let defaultIndex = fromIntegral $ c + idDelta'
addOffset = fromIntegral
. fromMaybe 0
. (glyphIndexArray' Vector.!?)
. (+ fromIntegral (c - startCode'))
in maybe defaultIndex addOffset
$ calculateGlyphId segmentIndex segCount idRangeOffset'
calculateGlyphId segmentIndex segCount idRangeOffset'
| idRangeOffset' == 0 = Nothing
| otherwise = Just $ segmentIndex - segCount + (fromIntegral idRangeOffset' `div` 2)
dumpGlyphAtIndex index element = " glyphIdArray[" <> Text.Builder.decimal index <> "] = "
<> Text.Builder.decimal element <> newlineBuilder
dumpTables
:: Megaparsec.State ByteString Void