~alcinnz/harfbuzz-pure

27013b25cfe0eadb5661d7fbb910792d797e5e5c — Adrian Cochrane 2 years ago c0f7026
Correctly decode Harfbuzz output structs.

I didn't consider the presence of private-fields before!
1 files changed, 46 insertions(+), 4 deletions(-)

M Data/Text/Glyphize/Buffer.hs
M Data/Text/Glyphize/Buffer.hs => Data/Text/Glyphize/Buffer.hs +46 -4
@@ 299,7 299,7 @@ foreign import ccall "hb_buffer_guess_segment_properties" hb_buffer_guess_segmen
data GlyphInfo = GlyphInfo {
    codepoint :: Word32,
    -- ^ Glyph index (or unicode codepoint)
    cluster :: Word32
    cluster :: Word32,
    -- ^ The index of the character in the original text that corresponds to
    -- this `GlyphInfo`. More than one `GlyphInfo` may have the same `cluster`
    -- value if they resulted from the same character, & when more than one


@@ 308,8 308,34 @@ data GlyphInfo = GlyphInfo {
    -- By default some characters are merged into the same cluster even when
    -- they are seperate glyphs, `Buffer`'s `clusterLevel` property allows
    -- selecting more fine grained cluster handling.
} deriving (Show, Read, Eq, Generic)
instance GStorable GlyphInfo
    unsafeToBreak :: Bool,
    unsafeToConcat :: Bool,
    safeToInsertTatweel :: Bool
} deriving (Show, Read, Eq)
instance Storable GlyphInfo where
    sizeOf _ = sizeOf (undefined :: Word32) * 5
    alignment _ = alignment (undefined :: Word32)
    peek ptr = do
        let ptr' :: Ptr Word32
            ptr' = castPtr ptr
        -- Ignore private fields.
        codepoint' <- ptr' `peekElemOff` 0
        mask <- ptr' `peekElemOff` 1
        cluster' <- ptr' `peekElemOff` 2
        return $ GlyphInfo codepoint' cluster' (mask `testBit` 1) (mask `testBit` 2) (mask `testBit` 3)
    poke ptr (GlyphInfo codepoint' cluster' flag1 flag2 flag3) = do
        -- Zero private fields.
        let ptr' :: Ptr Word32
            ptr' = castPtr ptr
        pokeElemOff ptr' 0 codepoint'
        pokeElemOff ptr' 1 $ Prelude.foldl (.|.) 0 [
            if flag1 then 1 else 0,
            if flag2 then 2 else 0,
            if flag3 then 4 else 0
          ]
        pokeElemOff ptr' 2 cluster'
        pokeElemOff ptr' 3 0
        pokeElemOff ptr' 4 0
glyphInfos buf' = do
    arr <- hb_buffer_get_glyph_infos buf' nullPtr
    length <- hb_buffer_get_length buf'


@@ 335,7 361,23 @@ data GlyphPos = GlyphPos {
    -- ^ How much the glyph moves on the Y-axis before drawing it, this should
    -- not effect how much the line advances.
} deriving (Show, Read, Eq, Generic)
instance GStorable GlyphPos
instance Storable GlyphPos where
    sizeOf _ = sizeOf (undefined :: Int32) * 5
    alignment _ = alignment (undefined :: Int32)
    peek ptr = let ptr' = castPtr ptr in do
        x_advance' <- ptr' `peekElemOff` 0
        y_advance' <- ptr' `peekElemOff` 1
        x_offset' <- ptr' `peekElemOff` 2
        y_offset' <- ptr' `peekElemOff` 3
        return $ GlyphPos x_advance' y_advance' x_offset' y_offset'
    poke ptr (GlyphPos x_advance' y_advance' x_offset' y_offset') = do
        let ptr' :: Ptr Int32
            ptr' = castPtr ptr
        pokeElemOff ptr' 0 x_advance'
        pokeElemOff ptr' 1 y_advance'
        pokeElemOff ptr' 2 x_offset'
        pokeElemOff ptr' 3 y_offset'
        pokeElemOff ptr' 4 0 -- Zero private field.
glyphsPos buf' = do
    arr <- hb_buffer_get_glyph_positions buf' nullPtr
    length <- hb_buffer_get_length buf'